This commit is contained in:
Home Assistant Version Control
2026-08-22 14:33:12 +00:00
parent 66fc59e9a7
commit eddec8ffd7
67 changed files with 11380 additions and 2569 deletions
+144 -10
View File
@@ -33,6 +33,8 @@ from homeassistant.helpers import device_registry as dr
from .const import (
DOMAIN,
CONFIG_ENTRY_MINOR_VERSION,
CONFIG_ENTRY_VERSION,
SERVICE_SUBMIT_FEEDBACK,
CONF_LINKED_DEVICE,
CONF_MIN_POWER,
@@ -103,9 +105,12 @@ from .const import (
DEVICE_TYPE_OTHER,
DEFAULT_START_DURATION_THRESHOLD,
CONF_START_DURATION_THRESHOLD,
resolve_watchdog_interval_default,
resolve_start_duration_default,
CONF_RUNNING_DEAD_ZONE,
)
from .log_utils import DeviceLoggerAdapter
from .options_utils import strip_null_options
_LOGGER = logging.getLogger(__name__)
@@ -132,13 +137,13 @@ async def async_migrate_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
version = entry.version or 1
minor_version = entry.minor_version or 1
if version > 3:
if version > CONFIG_ENTRY_VERSION:
_log.error(
"Refusing to migrate unsupported future schema %s.%s", version, minor_version
)
return False
if version == 3 and minor_version >= 8:
if version == CONFIG_ENTRY_VERSION and minor_version >= CONFIG_ENTRY_MINOR_VERSION:
return True
# 3.6 → 3.7: remove initial_profile stub key from entry.data.
@@ -160,7 +165,81 @@ async def async_migrate_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
minor_version = 8
_log.debug("Migrated WashData entry from 3.7 to 3.8 (removed running_dead_zone)")
if version == 3 and minor_version >= 8:
# 3.8 → 3.9: drop options persisted as null. A never-saved setting has no
# entry in options, so the per-setting Revert used to send the changelog's
# `old` (null) and ws_set_options stored it verbatim - and a stored None
# survives options.get(key, DEFAULT), so the numeric casts that build
# CycleDetectorConfig raised TypeError and the entry could never be set up
# again without hand-editing .storage (#389). ws_set_options and the import
# path now strip on write; this heals entries already carrying one. Healing
# here rather than on a setup failure keeps it deterministic, covers the
# crash classes a null produces outside a numeric cast (a null power_sensor
# raises AttributeError inside hass.states.get(None)), and never rewrites the
# entry mid-setup.
if version == 3 and minor_version == 8:
new_opts = strip_null_options(entry.options)
dropped = sorted(set(entry.options) - set(new_opts))
hass.config_entries.async_update_entry(
entry, options=new_opts, minor_version=9
)
minor_version = 9
if dropped:
_log.warning(
"Migrated WashData entry from 3.8 to 3.9: dropped option(s) %s "
"stored as null so the compiled defaults apply again",
dropped,
)
else:
_log.debug("Migrated WashData entry from 3.8 to 3.9 (no null options)")
# 3.9 → 3.10: heal cadence defaults that violate the panel's own conflict rules
# (#396). The pre-3.9 legacy migration seeded watchdog_interval=30 and
# start_duration_threshold=5 into options. With sampling_interval now resolved
# per device type, those seeded values fall below the watchdog>=2*sampling and
# start_duration>=sampling gates on the coarse (30 s) sampling device types.
# Replace them with the device-resolved default ONLY where they still equal the
# old scalar default (30 / 5) - i.e. a value the migration seeded, never a
# deliberate user choice (both violated the rule). A never-seeded (absent) key
# is left absent so the runtime device-resolved default applies.
if version == 3 and minor_version == 9:
new_opts = dict(entry.options)
# `or` (not `.get(..., default)`) so a present-but-null device type also falls
# through to the data value / DEFAULT_DEVICE_TYPE: a null would otherwise resolve
# to the coarse scalar defaults and wrongly heal a washing-machine-equivalent
# entry's 30/5 up to 61/30.
_dt = (
new_opts.get(CONF_DEVICE_TYPE)
or entry.data.get(CONF_DEVICE_TYPE)
or DEFAULT_DEVICE_TYPE
)
_healed = []
if new_opts.get(CONF_WATCHDOG_INTERVAL) == 30:
_resolved = resolve_watchdog_interval_default(_dt)
if _resolved != 30:
new_opts[CONF_WATCHDOG_INTERVAL] = _resolved
_healed.append(CONF_WATCHDOG_INTERVAL)
if new_opts.get(CONF_START_DURATION_THRESHOLD) == 5:
_resolved = resolve_start_duration_default(_dt)
if _resolved != 5:
new_opts[CONF_START_DURATION_THRESHOLD] = _resolved
_healed.append(CONF_START_DURATION_THRESHOLD)
# LITERAL 10, not CONFIG_ENTRY_MINOR_VERSION, like every other step. These
# blocks form a chain - each advances minor_version to exactly N+1 so the next
# block picks it up - so a step that wrote "whatever is current" would, after a
# future bump to 11, jump a 3.9 entry straight to 11 and skip the new 3.10->3.11
# step entirely. Only the one-pass legacy write at the end means "land on
# current" and uses the constant.
hass.config_entries.async_update_entry(
entry, options=new_opts, minor_version=10
)
minor_version = 10
_log.debug(
"Migrated WashData entry from 3.9 to 3.10 (healed seeded cadence "
"defaults: %s)",
_healed or "none",
)
if version == CONFIG_ENTRY_VERSION and minor_version >= CONFIG_ENTRY_MINOR_VERSION:
return True
data: dict[str, Any] = dict(entry.data)
@@ -207,7 +286,17 @@ async def async_migrate_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
options.setdefault(
CONF_DEVICE_TYPE, data.get(CONF_DEVICE_TYPE, DEFAULT_DEVICE_TYPE)
)
options.setdefault(CONF_START_DURATION_THRESHOLD, DEFAULT_START_DURATION_THRESHOLD)
# setdefault does not replace a present-but-null value; a null device type would
# then miss the per-type maps and fall through to the coarse scalar defaults (30/61)
# instead of the washing-machine defaults DEFAULT_DEVICE_TYPE stands for (5/30).
# Coerce it here (an explicit type is truthy and preserved) so both resolvers below
# see a real device type.
if not options.get(CONF_DEVICE_TYPE):
options[CONF_DEVICE_TYPE] = DEFAULT_DEVICE_TYPE
options.setdefault(
CONF_START_DURATION_THRESHOLD,
resolve_start_duration_default(options[CONF_DEVICE_TYPE]),
)
options.setdefault(CONF_PROFILE_MATCH_INTERVAL, DEFAULT_PROFILE_MATCH_INTERVAL)
options.setdefault(
@@ -223,7 +312,10 @@ async def async_migrate_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
options.setdefault(
CONF_MAX_FULL_TRACES_UNLABELED, DEFAULT_MAX_FULL_TRACES_UNLABELED
)
options.setdefault(CONF_WATCHDOG_INTERVAL, DEFAULT_WATCHDOG_INTERVAL)
options.setdefault(
CONF_WATCHDOG_INTERVAL,
resolve_watchdog_interval_default(options[CONF_DEVICE_TYPE]),
)
options.setdefault(
CONF_AUTO_TUNE_NOISE_EVENTS_THRESHOLD, DEFAULT_AUTO_TUNE_NOISE_EVENTS_THRESHOLD
)
@@ -294,15 +386,20 @@ async def async_migrate_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
# (covers entries that migrate straight from v1/v2/early-v3 in one pass).
options.pop(CONF_RUNNING_DEAD_ZONE, None)
# Same for an option persisted as null (3.8 -> 3.9), so a one-pass legacy
# migration lands on the current schema rather than needing a second call.
options = strip_null_options(options)
hass.config_entries.async_update_entry(
entry,
data=data,
options=options,
version=3,
minor_version=8,
version=CONFIG_ENTRY_VERSION,
minor_version=CONFIG_ENTRY_MINOR_VERSION,
)
_log.info(
"Migrated WashData entry from version %s.%s to 3.8", version, minor_version
"Migrated WashData entry from version %s.%s to %s.%s",
version, minor_version, CONFIG_ENTRY_VERSION, CONFIG_ENTRY_MINOR_VERSION,
)
return True
@@ -355,6 +452,29 @@ async def _migrate_online_to_global(hass: HomeAssistant, entry: ConfigEntry, man
pass
async def _async_preload_ml_modules(hass: HomeAssistant) -> None:
"""Import the ML modules off the event loop (issue #328).
``ml.engine.resolve_scorer`` / ``resolve_regressor`` are called from the event
loop (live matching, end detection, quality gating), and Home Assistant flags
the lazy ``importlib.import_module`` they used to do there as a blocking call.
Warming the module cache once per setup in the import executor makes every
later resolution a ``sys.modules`` lookup. Best effort: a failure here only
means ML stays inert, so it must never block setup.
"""
def _preload() -> None:
# pylint: disable=import-outside-toplevel
from .ml.engine import preload_models
preload_models()
try:
await hass.async_add_import_executor_job(_preload)
except Exception: # pylint: disable=broad-exception-caught
_LOGGER.debug("ML module preload failed", exc_info=True)
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Set up WashData from a config entry."""
_log = DeviceLoggerAdapter(_LOGGER, entry.title)
@@ -367,6 +487,9 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
hass.data.setdefault(DOMAIN, {})
# Warm the ML module cache before anything can score in the event loop.
await _async_preload_ml_modules(hass)
# Migration: Remove old auto_maintenance switch entity (now in settings)
# pylint: disable=import-outside-toplevel
from homeassistant.helpers import entity_registry as er
@@ -894,8 +1017,14 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
if key in entry_data:
new_data[key] = entry_data[key]
# Update all options from import
# Update all options from import, then strip any option persisted as
# null: an export taken from an already-broken entry (or a hand-edited
# file) can carry a `null`, which `.get()` hands back verbatim and the
# numeric casts that build CycleDetectorConfig then raise on - the #389
# bricked-setup failure. The WS import paths already do this; the legacy
# import_config service is the last writer that did not.
new_options.update(entry_options)
new_options = strip_null_options(new_options)
hass.config_entries.async_update_entry(
entry,
@@ -1094,9 +1223,14 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
await asyncio.gather(*_cancelled_tasks, return_exceptions=True)
# Release the per-entry write lock so it doesn't block the next setup.
from .ws_api import _WS_WRITE_LOCKS_KEY
from .ws_api import _WS_WRITE_LOCKS_KEY, async_clear_history_import
hass.data.get(_WS_WRITE_LOCKS_KEY, {}).pop(entry.entry_id, None)
# Drop any staged history import (uploaded CSV text or a finished scan's
# traces). Nothing else owns that memory, so without this an abandoned upload
# would live for the lifetime of the process.
async_clear_history_import(hass, entry.entry_id)
# When the last WashData entry is removed, tear down the shared panel/sidebar
# so no stale registration flags or sidebar entry linger.
if not hass.data.get(DOMAIN):
+213 -26
View File
@@ -41,6 +41,11 @@ from .const import (
MATCH_MAE_PEAK_FLOOR,
MATCH_MAE_REF_PEAK,
MATCH_MAE_SCALE,
MAX_ALIGN_GRID_POINTS,
SMART_TERM_PREFIX_MAX_CANDIDATES,
SMART_TERM_PREFIX_MIN_COVERAGE,
SMART_TERM_PREFIX_MIN_POINTS,
SMART_TERM_PREFIX_MIN_RATIO,
STAGE4_INTEGRATED_ENERGY_DEVICE_TYPES,
)
@@ -322,6 +327,51 @@ def _dtw_component_score(
return scale / (scale + scaled)
def _stage3_dtw_score(
curr_arr: np.ndarray,
sample_arr: np.ndarray,
current_peak: float,
*,
dtw_mode: str,
dtw_bandwidth: float,
l1_scale: float,
ddtw_scale: float,
ensemble_w: float,
curr_resampled: np.ndarray | None = None,
) -> tuple[float, float]:
"""``(dtw_score, norm_dist)`` for one candidate: the four-way ``dtw_mode``
branch of the Stage-3 refinement.
Lifted verbatim out of ``compute_matches_worker`` so the Stage-3 loop and the
Stage-6 prefix pass (#364) share one implementation and cannot drift apart.
Behaviour-identical to the inlined version, including ``legacy`` mode's
``dtw_dist / len(curr_arr)`` normalisation and its ``norm_dist`` bookkeeping.
"""
if dtw_mode == "legacy":
# Original behaviour: raw sequences, distance / len(current),
# fixed absolute-watt scale (not peak-relative).
dtw_dist = compute_dtw_lite(curr_arr, sample_arr, band_width_ratio=dtw_bandwidth)
n_points = len(curr_arr)
norm_dist = (dtw_dist / n_points) if n_points > 0 else 999.0
return 1.0 / (1.0 + norm_dist / MATCH_DTW_DIST_SCALE), norm_dist
if dtw_mode == "ensemble":
# Blend the level-based (L1) and shape-based (derivative) DTW
# scores; they are complementary signals.
s_l1 = _dtw_component_score(curr_arr, sample_arr, current_peak, dtw_bandwidth, False, l1_scale, curr_resampled=curr_resampled)
s_dd = _dtw_component_score(curr_arr, sample_arr, current_peak, dtw_bandwidth, True, ddtw_scale, curr_resampled=curr_resampled)
# composite; per-component distance not meaningful
return ensemble_w * s_l1 + (1.0 - ensemble_w) * s_dd, 0.0
# "scaled" (default) or "ddtw": resample both onto one grid so the
# band and normalisation are consistent, then express the distance
# relative to the current peak (behaviour-neutral at
# MATCH_MAE_REF_PEAK), mirroring the Stage-2 MAE treatment.
use_deriv = dtw_mode == "ddtw"
scale = ddtw_scale if use_deriv else l1_scale
return _dtw_component_score(
curr_arr, sample_arr, current_peak, dtw_bandwidth, use_deriv, scale, curr_resampled=curr_resampled
), 0.0
def compute_matches_worker(
current_power: list[float],
current_duration: float,
@@ -368,6 +418,10 @@ def compute_matches_worker(
"profile_duration": profile_duration,
"current": current_power,
"sample": sample_power,
# True wall-clock span of `sample`, for prefix truncation (#364).
# Falls back to profile_duration so the other snapshot builders
# (devtools, matching_tuner, playground) keep working unchanged.
"sample_span_s": float(item.get("sample_span_s") or profile_duration or 0.0),
"offset": offset
})
@@ -391,31 +445,17 @@ def compute_matches_worker(
for cand in to_refine:
sample_arr = np.array(cand["sample"])
if dtw_mode == "legacy":
# Original behaviour: raw sequences, distance / len(current),
# fixed absolute-watt scale (not peak-relative).
dtw_dist = compute_dtw_lite(curr_arr, sample_arr, band_width_ratio=dtw_bandwidth)
n_points = len(curr_arr)
norm_dist = (dtw_dist / n_points) if n_points > 0 else 999.0
dtw_score = 1.0 / (1.0 + norm_dist / MATCH_DTW_DIST_SCALE)
elif dtw_mode == "ensemble":
# Blend the level-based (L1) and shape-based (derivative) DTW
# scores; they are complementary signals.
s_l1 = _dtw_component_score(curr_arr, sample_arr, current_peak, dtw_bandwidth, False, l1_scale, curr_resampled=curr_resampled)
s_dd = _dtw_component_score(curr_arr, sample_arr, current_peak, dtw_bandwidth, True, ddtw_scale, curr_resampled=curr_resampled)
dtw_score = ensemble_w * s_l1 + (1.0 - ensemble_w) * s_dd
norm_dist = 0.0 # composite; per-component distance not meaningful
else:
# "scaled" (default) or "ddtw": resample both onto one grid so the
# band and normalisation are consistent, then express the distance
# relative to the current peak (behaviour-neutral at
# MATCH_MAE_REF_PEAK), mirroring the Stage-2 MAE treatment.
use_deriv = dtw_mode == "ddtw"
scale = ddtw_scale if use_deriv else l1_scale
dtw_score = _dtw_component_score(
curr_arr, sample_arr, current_peak, dtw_bandwidth, use_deriv, scale, curr_resampled=curr_resampled
)
norm_dist = 0.0
dtw_score, norm_dist = _stage3_dtw_score(
curr_arr,
sample_arr,
current_peak,
dtw_mode=dtw_mode,
dtw_bandwidth=dtw_bandwidth,
l1_scale=l1_scale,
ddtw_scale=ddtw_scale,
ensemble_w=ensemble_w,
curr_resampled=curr_resampled,
)
cand["original_score"] = float(cand["score"])
cand["score"] = float(blend * cand["score"] + (1.0 - blend) * dtw_score)
@@ -461,8 +501,134 @@ def compute_matches_worker(
)
candidates.sort(key=lambda x: x["score"], reverse=True)
# Stage 6 (#364): prefix scores for the few candidates materially LONGER than
# the winner. Purely additive - it writes `prefix_score` and never touches
# `score`, so ranking is provably unchanged. Must run after the Stage-4
# re-sort because the anchor is the winner's duration.
annotate_prefix_scores(candidates, curr_arr, current_duration, config)
return candidates
def _prefix_point_count(
n_points: int, current_duration: float, sample_span_s: float
) -> int:
"""Leading template samples that cover ``current_duration`` seconds.
0 when the span is unknown/non-positive, when the elapsed time already covers
the whole template (then it is not a prefix), or when too few points remain to
judge. Fraction-of-array is the right operator because every snapshot flavour
is uniform in time over its own span (envelope: np.linspace; sample cycle:
resample_uniform at a fixed dt; group aggregate: np.interp onto 200 points).
"""
if n_points < SMART_TERM_PREFIX_MIN_POINTS or sample_span_s <= 0 or current_duration <= 0:
return 0
k = int(round(n_points * (current_duration / sample_span_s)))
if k < SMART_TERM_PREFIX_MIN_POINTS or k >= n_points:
return 0
return k
def prefix_shape_score(
curr_arr: np.ndarray,
sample: list[float] | np.ndarray,
current_duration: float,
sample_span_s: float,
current_peak: float,
config: dict[str, Any],
) -> float | None:
"""Score the live trace against ``sample`` TRUNCATED to ``current_duration``.
The #288 landscape guard asks whether a longer candidate has a decent shape
score against its **whole** curve - which a part-way-through trace cannot
have. This asks the question that actually matters: does the trace look like
the *beginning* of that longer programme? (#364)
Same scale as ``shape_score`` by construction: identical Stage-2 formula
(``find_best_alignment``) and identical Stage-3 DTW blend, only the reference
array differs. Returns None when the template cannot be truncated meaningfully.
NB prefix scoring normalizes on the shared resample ``grid`` (both series are
resampled to it), so it does not support the non-default ``dtw_mode="legacy"``
absolute-watt/length normalization - under which cross-candidate prefix scores of
differing native length would not be comparable. This is inert in production: the
default is ``"ensemble"`` and the live ProfileStore path never sets ``dtw_mode``;
``"legacy"`` exists only for the devtools re-sweep harness.
"""
arr = np.asarray(sample, dtype=float)
k = _prefix_point_count(arr.size, current_duration, sample_span_s)
if k == 0:
return None
prefix = arr[:k]
# Put both series on one grid so index offset equals time offset regardless of
# the template's native cadence, and honour the #388 OOM cap.
grid = int(min(curr_arr.size, k, MAX_ALIGN_GRID_POINTS))
if grid < SMART_TERM_PREFIX_MIN_POINTS:
return None
a = _resample_to(curr_arr, grid)
b = _resample_to(prefix, grid)
corr_weight = float(config.get("corr_weight", MATCH_CORR_WEIGHT))
score, _metrics, _offset = find_best_alignment(a, b, 1.0, corr_weight=corr_weight)
dtw_bandwidth = float(config.get("dtw_bandwidth", 0.1))
if dtw_bandwidth > 0.0:
dtw_score, _ = _stage3_dtw_score(
a,
b,
current_peak,
dtw_mode=str(config.get("dtw_mode", DEFAULT_DTW_MODE)),
dtw_bandwidth=dtw_bandwidth,
l1_scale=float(config.get("dtw_l1_scale", MATCH_DTW_DIST_SCALE)),
ddtw_scale=float(config.get("dtw_ddtw_scale", MATCH_DDTW_DIST_SCALE)),
ensemble_w=float(config.get("dtw_ensemble_w", MATCH_DTW_ENSEMBLE_W)),
)
blend = float(config.get("dtw_blend", MATCH_DTW_BLEND))
return float(blend * score + (1.0 - blend) * dtw_score)
return float(score)
def annotate_prefix_scores(
candidates: list[dict[str, Any]],
curr_arr: np.ndarray,
current_duration: float,
config: dict[str, Any],
) -> None:
"""Stage 6 (#364): write ``prefix_score`` on the few non-winning candidates
that are materially longer than the winner.
Mutates in place and never touches ``score``/``shape_score``, so candidate
ranking is unaffected - this only feeds the Smart-Termination prefix guard.
Every test before the first array touch is a scalar compare, so the common
case (no candidate is materially longer) costs nothing.
"""
if current_duration <= 0 or len(candidates) < 2 or curr_arr.size == 0:
return
best_dur = float(candidates[0].get("profile_duration") or 0.0)
if best_dur <= 0:
return
min_dur = best_dur * SMART_TERM_PREFIX_MIN_RATIO
current_peak = float(np.max(curr_arr))
scored = 0
for cand in candidates[1:]:
prof_dur = float(cand.get("profile_duration") or 0.0)
if prof_dur <= min_dur:
continue # not a longer look-alike
if prof_dur <= current_duration:
continue # we already outlasted it, so we are not inside its prefix
span = float(cand.get("sample_span_s") or prof_dur)
if span < prof_dur * SMART_TERM_PREFIX_MIN_COVERAGE:
continue # gap-truncated template: may not start at the programme's start
score = prefix_shape_score(
curr_arr, cand.get("sample") or [], current_duration, span, current_peak, config
)
if score is None:
continue
cand["prefix_score"] = float(score)
scored += 1
if scored >= SMART_TERM_PREFIX_MAX_CANDIDATES:
break
def _dtw_cost_matrix_scalar(
x: np.ndarray, y: np.ndarray, n: int, m: int, w: int
) -> np.ndarray:
@@ -537,6 +703,20 @@ def compute_dtw_path(
if n == 0 or m == 0:
return []
# Pre-flight memory guard: the cost matrix is (n+1)x(m+1) float64. An
# uncapped call from a 1 Hz long cycle can request >1 GB here. If the
# allocation would exceed ~80 MB, skip DTW and return an empty path so
# the caller falls back to linear interpolation (graceful degrade rather
# than OOM-killing Home Assistant — issue #388).
_DTW_CELL_BUDGET = 10_000_000 # 10 M cells x 8 B ≈ 80 MB
if (n + 1) * (m + 1) > _DTW_CELL_BUDGET:
_LOGGER.warning(
"DTW cost matrix %dx%d would need %.0f MB — skipping DTW refinement "
"(cap compute_envelope_worker inputs via MAX_ALIGN_GRID_POINTS to prevent this)",
n, m, (n + 1) * (m + 1) * 8 / 1e6,
)
return []
w = max(1, int(min(n, m) * band_width_ratio))
try:
cost_matrix = _dtw_cost_matrix_vectorized(x, y, n, m, w)
@@ -701,6 +881,9 @@ def compute_envelope_worker(
align_dt = avg_sample_rate
num_points = max(50, int(target_duration / align_dt))
if num_points > MAX_ALIGN_GRID_POINTS:
num_points = MAX_ALIGN_GRID_POINTS
align_dt = target_duration / num_points # re-derive so per-cycle grids inherit the cap
time_grid = np.linspace(0.0, target_duration, num_points)
# Robust reference curve: the pointwise MEDIAN across all cycles resampled
@@ -733,7 +916,11 @@ def compute_envelope_worker(
for offsets, values, dur in normalized_curves:
this_dur = dur
this_num_points = max(10, int(this_dur / align_dt))
# Cap this grid too, not just the reference one: a cycle far longer than the
# median would otherwise size its own grid past the cap and push the cost
# matrix over compute_dtw_path's budget, which silently drops the outlier
# back to plain interpolation. Capping keeps DTW alignment available for it.
this_num_points = min(MAX_ALIGN_GRID_POINTS, max(10, int(this_dur / align_dt)))
this_grid = np.linspace(0.0, this_dur, this_num_points)
this_array = np.interp(this_grid, offsets, values)
+5 -2
View File
@@ -29,6 +29,8 @@ from homeassistant.helpers import selector
from .const import (
DOMAIN,
CONFIG_ENTRY_MINOR_VERSION,
CONFIG_ENTRY_VERSION,
CONF_POWER_SENSOR,
CONF_MIN_POWER,
CONF_DEVICE_TYPE,
@@ -146,8 +148,9 @@ STEP_USER_DATA_SCHEMA = vol.Schema(
class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): # pylint: disable=abstract-method
"""Handle a config flow for WashData."""
VERSION = 3
MINOR_VERSION = 8
# Single source in const.py; the migration blocks in __init__.py read the same two.
VERSION = CONFIG_ENTRY_VERSION
MINOR_VERSION = CONFIG_ENTRY_MINOR_VERSION
def __init__(self) -> None:
"""Initialize the config flow."""
+241 -2
View File
@@ -137,6 +137,7 @@ CONF_ANTI_WRINKLE_MAX_DURATION = "anti_wrinkle_max_duration" # Seconds to treat
CONF_ANTI_WRINKLE_EXIT_POWER = "anti_wrinkle_exit_power" # W threshold for true-off exit
CONF_ANTI_WRINKLE_IDLE_TIMEOUT = "anti_wrinkle_idle_timeout" # Seconds below exit power before anti-wrinkle ends
CONF_DISHWASHER_END_SPIKE_QUIET_RELEASE = "dishwasher_end_spike_quiet_release" # Dishwasher: sustained-quiet seconds after expected duration that release the end-of-cycle drain wait early (#379)
CONF_SMART_TERMINATION_DURATION_RATIO = "smart_termination_duration_ratio" # Fraction of the matched profile's expected (mean) duration that Smart Termination requires before it may fire (#393)
CONF_DELAY_START_DETECT_ENABLED = "delay_start_detect_enabled" # Enable delayed-start detection
CONF_DELAY_CONFIRM_SECONDS = "delay_confirm_seconds" # Seconds power must stay in standby band before DELAY_WAIT engages
CONF_DELAY_TIMEOUT_HOURS = "delay_timeout_hours" # Safety timeout (hours) while waiting to start
@@ -297,7 +298,8 @@ DEFAULT_PROFILE_MATCH_MAX_DURATION_RATIO = 1.5
DEFAULT_MAX_PAST_CYCLES = 200
DEFAULT_MAX_FULL_TRACES_PER_PROFILE = 20
DEFAULT_MAX_FULL_TRACES_UNLABELED = 20
DEFAULT_WATCHDOG_INTERVAL = 30 # Derived: 2 * sampling_interval + 1
DEFAULT_WATCHDOG_INTERVAL = 30 # Floor; effective default is resolved per device
# as max(this, 2*sampling_interval + 1) - see resolve_watchdog_interval_default (#396).
DEFAULT_MATCH_PERSISTENCE = 3
DEFAULT_END_REPEAT_COUNT = 1 # 1 = current behavior (no repeat required)
@@ -487,6 +489,13 @@ DEFAULT_DTW_MODE = "ensemble"
MATCH_DTW_RESAMPLE_N = 200 # common grid length for "scaled"/"ddtw" DTW
MATCH_DDTW_DIST_SCALE = 30.0 # half-saturation for derivative-DTW distance
MATCH_DTW_ENSEMBLE_W = 0.7 # weight on L1 vs DDTW in "ensemble" mode
# Envelope alignment grid cap: maximum number of time-grid points used by
# compute_envelope_worker. The DTW cost matrix is (n+1)x(m+1)x8 B float64;
# both n and m derive from this cap, so memory is bounded to roughly
# MAX_ALIGN_GRID_POINTS² x 8 B ≈ 32 MB at 2000 — regardless of cycle duration
# or recording density. Without this cap a 4 h cycle at 1 Hz asks for 1.81 GB
# in a single np.full, which OOM-kills Home Assistant (issue #388).
MAX_ALIGN_GRID_POINTS = 2000
# Ambiguity: top1-top2 score gap below this flags the match as ambiguous.
MATCH_AMBIGUITY_MARGIN = 0.05
# Smart Termination landscape guard: when a non-winning candidate is at least this
@@ -499,6 +508,70 @@ MATCH_AMBIGUITY_MARGIN = 0.05
SMART_TERM_LANDSCAPE_RATIO = 1.5 # candidate must be >= 1.5× the matched duration
SMART_TERM_LANDSCAPE_MIN_SHAPE = 0.40 # minimum shape score (pre-Stage-4) to qualify
# Issue #364: the landscape guard above has three structural false negatives, all
# reproduced by field reports on a multi-programme Miele washer:
# (1) it needs a longer profile to EXIST in the candidate pool, so an untrained
# longer programme is uncatchable;
# (2) it qualifies the longer candidate on its shape score against its FULL
# envelope, but a trace that is only part-way through a longer programme
# scores poorly against that programme's whole curve;
# (3) the 1.5 ratio is knife-edge - on a real 13-programme washer the observed
# neighbour ratios are 1.12-1.48, so the guard never fires at all.
#
# Two independent additions, both shorten-only (they can only ever BLOCK an early
# finish, never end a cycle sooner).
#
# (a) Prefix scoring (fixes 2 + 3). A longer candidate is re-scored against its own
# curve TRUNCATED to the elapsed duration, which is an apples-to-apples comparison
# and lands on the same 0-1 scale as `shape_score` (same find_best_alignment, same
# DTW blend). Because it compares equal-length series over the whole overlap it
# reads systematically higher than the full-envelope score, so it gets its OWN
# threshold rather than reusing SMART_TERM_LANDSCAPE_MIN_SHAPE. The load-bearing
# term is the MARGIN over the winner ("the longer programme explains this trace at
# least this much better than the short one does"), which is scale-free; the floor
# only rejects candidates that fit nothing. Measured on 20 real cycles + 7
# envelopes (37 prefix-cut positives vs 17 genuine-cycle negatives): margin 0.15
# catches 26/37 splits for 1/17 false blocks, while simply lowering the ratio to
# 1.35/1.15 costs 2/17 and 4/17 false blocks for no measured gain.
SMART_TERM_PREFIX_MARGIN = 0.15 # prefix score must beat the winner by this
SMART_TERM_PREFIX_MIN_SHAPE = 0.40 # absolute floor on the prefix score
SMART_TERM_PREFIX_MIN_RATIO = 1.10 # noise guard: ignore near-equal durations
SMART_TERM_PREFIX_MAX_CANDIDATES = 3 # cap prefix scorings per match (cost control)
SMART_TERM_PREFIX_MIN_POINTS = 12 # mirrors the matcher's >=12-sample floor
SMART_TERM_PREFIX_MIN_COVERAGE = 0.90 # template span must cover >=90% of its duration
# (b) Power plausibility (fixes 1, the untrained case, which no candidate-pool guard
# can reach). Both Smart-Termination paths key on `elapsed >= 0.98 * expected` and
# neither checks whether the appliance is still WORKING, so a mis-matched shorter
# profile finalises a cycle mid-wash. Compare the trailing mean power against what
# the matched profile itself draws at its own end: if we are drawing several times
# that, this is not the end of anything.
#
# The two windows must cover the same FRACTION of the run, or the comparison is not
# like-for-like. A fixed 300 s trailing window is 4% of a cotton wash but a third
# of a 15-minute "Spin & Drain", whose trailing mean is then the spin itself while
# its profile tail is the quiet moment after the pump stops - ratios of 45-310x on
# perfectly normal cycle ends. So the trailing window is
# `expected_duration * SMART_TERM_TAIL_WINDOW_FRAC`, clamped; that alone is strictly
# better at every threshold (e.g. at 4.0x: false blocks 5% -> 3%).
#
# Swept with devtools/prefix_guard_eval.py over the whole cycle_data corpus (19
# devices, 225 labelled cycles, leave-one-out): 114 folds where a shorter profile
# is winning mid-cycle (the #364 split condition) vs 165 genuine cycle ends.
# ratio caught false-blocked
# 3.0 27% 8%
# 3.5 25% 4% <- shipped, the knee
# 4.0 20% 3%
# 3.0 -> 3.5 halves the false blocks for 2pp of catch, and the reported cases sit
# at 4-8x so they stay caught. A false block only costs a later finish (the
# power-based fallback timeout still ends the cycle); a miss costs a split cycle.
# ~1 in 5 of the remaining false blocks had a wrong top-1 anyway, where blocking is right.
SMART_TERM_TAIL_MAX_RATIO = 3.5 # block while trailing mean > this x profile tail
SMART_TERM_TAIL_WINDOW_S = 300.0 # upper clamp on the trailing window
SMART_TERM_TAIL_WINDOW_MIN_S = 60.0 # lower clamp (short programmes)
SMART_TERM_TAIL_MIN_POINTS = 3 # too few samples -> no opinion, do not block
SMART_TERM_TAIL_WINDOW_FRAC = 0.05 # both windows = last 5% of the run
# Number of points in the compact reference-profile curve exposed on the
# `_program` sensor (`profile_store.reference_curve`). Chosen so the resulting
# `[[offset_s, watts], ...]` attribute stays comfortably under ~1 KB regardless
@@ -773,6 +846,20 @@ STARTING_PAUSED_TRUE_OFF_TIMEOUT_SECONDS = 300.0
# a washer's longest legitimate mid-cycle soak trough while capping the pathology.
WASHER_SMART_TERMINATION_DEBOUNCE_MAX_SECONDS = 600.0
# Fraction of the matched profile's expected (mean) duration that Smart Termination
# requires before it may fire (#393). self._expected_duration is the profile's
# outlier-filtered ARITHMETIC MEAN, so a fixed 0.98 gate against a mean is
# structurally unreachable for appliances whose runtime depends on load, fill level
# or inlet temperature - about half of those cycles are shorter than their own mean
# by construction and can never take the fast path. Exposed as the per-device
# CONF_SMART_TERMINATION_DURATION_RATIO option (range 0.50-1.00; empty = default).
# The default is device-type-resolved: dishwashers keep the conservative 0.99
# (their programs are fixed, so the spread is small) while everything else keeps
# 0.98. The dishwasher pump-out relief (0.90 once the terminal pump-out spike is
# confirmed) is combined with the configured value via min(), so the option can
# only ever LOOSEN the gate, never tighten it.
DEFAULT_SMART_TERMINATION_DURATION_RATIO = 0.98
DEFAULT_OFF_DELAY_BY_DEVICE = {
DEVICE_TYPE_DISHWASHER: 1800, # 30 min (Drying)
DEVICE_TYPE_BREAD_MAKER: 300, # 5 min (Keep-warm phase after baking)
@@ -842,11 +929,71 @@ DEFAULT_SAMPLING_INTERVAL_BY_DEVICE = {
DEVICE_TYPE_PUMP: 10.0, # 10s - pump cycles can be <30 s; 30s default would miss them
}
def resolve_sampling_interval_default(device_type: str) -> float:
"""Device-resolved default sampling interval (#396).
Single source of truth for the sampling default, so the manager, the panel
(via ws_get_options) and the config migration all agree. Wet appliances
sample fast (2 s) to capture the rapid 0<->150 W oscillation; everything else
keeps the coarse 30 s scalar.
"""
return DEFAULT_SAMPLING_INTERVAL_BY_DEVICE.get(device_type, DEFAULT_SAMPLING_INTERVAL)
def resolve_watchdog_interval_default(device_type: str) -> int:
"""Device-resolved watchdog tick default (#396).
The panel enforces watchdog_interval >= 2*sampling_interval (a publish-on-change
sensor can skip a sample, so the staleness tick must be coarser than the
sampling gap). Derived as max(DEFAULT_WATCHDOG_INTERVAL, 2*sampling+1): 30 for
the fast/pump types (30 already clears 2*2 / 2*10), 61 for the 30 s-sampling
types. Never smaller than the 30 s floor so a fast-sampling device does not get
an over-aggressive watchdog.
"""
sampling = resolve_sampling_interval_default(device_type)
return int(max(DEFAULT_WATCHDOG_INTERVAL, 2.0 * sampling + 1.0))
def resolve_start_duration_default(device_type: str) -> float:
"""Device-resolved start-debounce default (#396).
The panel enforces start_duration_threshold >= sampling_interval (a debounce
shorter than one sample lets a single spike open a cycle). Derived as
max(DEFAULT_START_DURATION_THRESHOLD, sampling): 5 s for the fast types, the
sampling interval for the coarser ones.
"""
sampling = resolve_sampling_interval_default(device_type)
return max(DEFAULT_START_DURATION_THRESHOLD, sampling)
# Default profile match min duration ratio by device type
DEFAULT_PROFILE_MATCH_MIN_DURATION_RATIO_BY_DEVICE = {
DEVICE_TYPE_DISHWASHER: 0.10,
}
# Default Smart-Termination duration ratio by device type (#393). Dishwashers run
# fixed programs (measured spread +4%/+17% around the mean), so the conservative
# 0.99 gate is defensible there; every other type keeps the scalar
# DEFAULT_SMART_TERMINATION_DURATION_RATIO (0.98). Resolved in the config builder,
# never in the gate, so playground.effective_settings() always sees a real float.
DEFAULT_SMART_TERMINATION_DURATION_RATIO_BY_DEVICE = {
DEVICE_TYPE_DISHWASHER: 0.99,
}
def resolve_smart_termination_duration_ratio_default(device_type: str) -> float:
"""Device-resolved Smart-Termination duration ratio default (#393).
Single source of truth shared by the manager (config build/reload), the
Playground fallback config and the panel (via ws_get_options), so the value
the panel pre-populates always matches the one the detector actually uses:
0.99 for dishwashers (fixed programs), 0.98 for everything else.
"""
return DEFAULT_SMART_TERMINATION_DURATION_RATIO_BY_DEVICE.get(
device_type, DEFAULT_SMART_TERMINATION_DURATION_RATIO
)
# Profile groups (Stage 5): the matcher only collapses a group into one
# aggregate candidate when its members' minimum pairwise shape similarity is at
# least this. Similarity is DTW/Sakoe-Chiba on peak-normalised envelopes, so it
@@ -872,9 +1019,24 @@ GROUP_MIN_COHESION = 0.80
# v11 is a marker-only bump: per-phase profiles (envelope["phase_profile"]) are
# derived cache populated by async_rebuild_envelope, so no data migration is
# needed - they self-populate on the next envelope rebuild.
STORAGE_VERSION = 11
# v12: initialize `backfill_cycles`, the third cycle list (issue #344). Cycles
# recovered from raw power history predating the integration are auto-detected and
# unverified, so they belong in neither `past_cycles` (which feeds lifetime stats, ML
# training labels and the feedback queue, and is retention-evicted oldest-first) nor
# `reference_cycles` (curated community-store templates, golden by construction).
# Additive `setdefault`, so it is idempotent and loses nothing.
STORAGE_VERSION = 12
STORAGE_KEY = "ha_washdata"
# ─── Config-entry schema version (NOT the storage version above) ───────────────
# Single source for the config-entry schema: `ConfigFlow.VERSION`/`MINOR_VERSION`, every
# stepwise block in `async_migrate_entry`, and the `minor_version=` the one-pass legacy
# migration writes all read from here. They must move together - a bump that misses one
# leaves an entry a version short, which then re-migrates on every start - and repeating
# the literals in three places is what made that easy to do.
CONFIG_ENTRY_VERSION = 3
CONFIG_ENTRY_MINOR_VERSION = 10
# Notification events
EVENT_CYCLE_STARTED = "ha_washdata_cycle_started"
EVENT_CYCLE_ENDED = "ha_washdata_cycle_ended"
@@ -1066,3 +1228,80 @@ PLAYGROUND_STRESS_MAX_IDLE_W: float = 100000.0 # upper bound for a manual
# value to entry.options is always an explicit, per-setting user action.
PLAYGROUND_PRESET_MAX: int = 30 # per-device cap (keeps the store small)
PLAYGROUND_PRESET_NAME_MAX: int = 60 # preset name length cap
# ─── Which cycle categories count as evidence for a profile ────────────────────
# A profile's envelope (its average curve + duration/energy spread) and the matching
# template are built from stored cycles. By default all three categories count. Untick a
# category and it stops shaping profiles - useful when you do not trust imported data -
# without deleting anything: the cycles remain stored, listed and deletable.
#
# This gates *evidence* only (`ProfileStore.iter_evidence_cycles`), never
# `iter_stored_cycles`/`find_stored_cycle`. Profile garbage collection and sample repair
# delete or re-point a profile whose sample cycle resolves to nothing, so they must keep
# seeing every stored cycle: a cycle excluded from evidence is still a stored cycle, and
# gating those lookups would destroy a backfill-only profile the moment someone unticked
# imported history.
CONF_PROFILE_EVIDENCE_SOURCES = "profile_evidence_sources"
EVIDENCE_REAL_CYCLES = "real_cycles"
EVIDENCE_REFERENCE_CYCLES = "reference_cycles"
EVIDENCE_BACKFILL_CYCLES = "backfill_cycles"
# `real_cycles`/`reference_cycles` match the export taxonomy (`_EXPORT_CATEGORIES`); the
# evidence view adds `backfill_cycles`, which the selective-export wizard does not yet
# enumerate (whole-store export still round-trips it).
PROFILE_EVIDENCE_SOURCES = (
EVIDENCE_REAL_CYCLES,
EVIDENCE_REFERENCE_CYCLES,
EVIDENCE_BACKFILL_CYCLES,
)
# All three: the pre-setting behaviour, so an upgrade changes nothing.
DEFAULT_PROFILE_EVIDENCE_SOURCES = list(PROFILE_EVIDENCE_SOURCES)
# ─── Historical power-data import (issue #344) ─────────────────────────────────
# An HA history export (or a recorder read) is a *change-based* stream: a steady
# 0 W emits no rows at all, so it cannot be fed to the detector as-is (doing so
# produces multi-day `force_stopped` blobs). `history_import.py` pre-segments the
# stream into activity blocks first; these constants govern that pre-pass.
HISTORY_IMPORT_MAX_BYTES: int = 32 * 1024 * 1024 # staged upload cap (~32 MiB of CSV text)
HISTORY_IMPORT_MAX_ROWS: int = 500_000 # parsed-row cap (≈ a month at 5 s)
HISTORY_IMPORT_CHUNK_BYTES: int = 512 * 1024 # per-WS-message upload chunk (frame cap is 4 MiB)
HISTORY_IMPORT_CHUNK_SAMPLES: int = 4000 # samples replayed per executor job
HISTORY_IMPORT_MIN_BLOCK_SAMPLES: int = 20 # floor for the per-block sample gate
HISTORY_IMPORT_MAX_MEDIAN_INTERVAL_S: float = 120.0 # floor for the per-block cadence gate; the
# effective gate is
# max(this, 4 x sampling_interval) so a plug
# that legitimately reports every 60 s is not
# rejected
HISTORY_IMPORT_EDGE_GAP_S: float = 60.0 # leading samples this far from the block body
# are hourly-average debris and are trimmed
# (leading edge ONLY - trimming the trailing
# edge eats a real cycle's low-power tail)
HISTORY_IMPORT_MAX_BLOCK_SPAN_S: float = 12 * 3600.0 # a block longer than this can only produce the
# detector's 8 h `force_stopped` blob, so it is
# reported rather than replayed
HISTORY_IMPORT_DENSIFY_STEP_S: float = 30.0 # cadence of the synthetic samples inserted into
# a carried-forward *quiet* gap, so the
# detector's gap-free quiet tally can accrue
# exactly as it does live
HISTORY_IMPORT_TAIL_STEP_S: float = 30.0 # synthetic quiet-tail cadence used to close the
# last cycle of a block
HISTORY_IMPORT_MAX_SEGMENTS: int = 60 # candidates surfaced by one scan
HISTORY_IMPORT_MAX_TOTAL_CYCLES: int = 200 # total backfilled cycles kept per device
# (`backfill_cycles` has no retention pass and
# the whole store blob is rewritten on every
# throttled active-cycle save)
HISTORY_IMPORT_RECORDER_MAX_DAYS: int = 3700 # ~10 years. HA's default `purge_keep_days`
# is 10, but a recorder configured to keep
# full-resolution states for years is a real
# setup and must not be capped out of reach.
# Reaching past what the recorder holds simply
# returns fewer rows; the real guard is
# HISTORY_IMPORT_MAX_ROWS, which stops the
# day-by-day read as soon as enough accrues.
HISTORY_IMPORT_RECORDER_EMPTY_DAY_STOP: int = 30 # consecutive empty days that end the walk.
# Within the retention window a day always
# yields at least the carried start-time state,
# so a run of truly empty days means the
# recorder has been purged past this point -
# without this, a 10-year request would issue
# thousands of pointless queries.
HISTORY_IMPORT_SOURCE: str = "history_import" # `meta.source` marker on imported cycles
+247 -28
View File
@@ -48,10 +48,16 @@ from .const import (
DEVICE_TYPE_WASHER_DRYER,
DEFAULT_MAX_DEFERRAL_SECONDS,
DEFAULT_DEFER_FINISH_CONFIDENCE,
DEFAULT_SMART_TERMINATION_DURATION_RATIO,
DISHWASHER_END_SPIKE_MIN_PROGRESS,
DISHWASHER_END_SPIKE_QUIET_RELEASE_SECONDS,
DISHWASHER_END_SPIKE_WAIT_SECONDS,
DISHWASHER_SMART_TERMINATION_DEBOUNCE_SECONDS,
SMART_TERM_TAIL_MAX_RATIO,
SMART_TERM_TAIL_MIN_POINTS,
SMART_TERM_TAIL_WINDOW_FRAC,
SMART_TERM_TAIL_WINDOW_MIN_S,
SMART_TERM_TAIL_WINDOW_S,
WASHER_SMART_TERMINATION_DEBOUNCE_MAX_SECONDS,
STARTING_PAUSED_TRUE_OFF_TIMEOUT_SECONDS,
DISHWASHER_MATCH_FREEZE_QUIET_SECONDS,
@@ -129,6 +135,13 @@ class CycleDetectorConfig:
start_threshold_w: float = 2.0
stop_threshold_w: float = 2.0
min_duration_ratio: float = 0.8 # Default deferred finish ratio
# Minimum live-match confidence for a match to be trusted by Smart Termination
# and the anti-crease gate. Fed from the `profile_match_threshold` option, which
# up to 0.5.5 was stored and never read - so raising it (the workaround the #288
# reporter documented) silently did nothing. Default matches the value that was
# hard-coded at those two sites, so behaviour is unchanged unless the user has
# deliberately tuned the option.
match_confidence_threshold: float = 0.4
# Power-based Off detection (issue #284). Carried on the config so the manager
# (the single owner of the terminal -> Off transition) can read them live; the
# detector itself does not act on them. 0 = disabled.
@@ -146,6 +159,13 @@ class CycleDetectorConfig:
# the shipped constant; per-device configurable so a machine with a long silent
# passive-drying phase before its final drain can absorb profile drift.
dishwasher_end_spike_quiet_release: float = DISHWASHER_END_SPIKE_QUIET_RELEASE_SECONDS
# Fraction of the matched profile's expected (mean) duration Smart Termination
# requires before it may fire (#393). Device-type-resolved in the manager's
# config builder (0.99 dishwasher / 0.98 other), so this field always carries a
# real float - never None - which is what playground.effective_settings() relies
# on. The dishwasher pump-out relief is combined via min(), so a configured value
# can only loosen the gate.
smart_termination_duration_ratio: float = DEFAULT_SMART_TERMINATION_DURATION_RATIO
delay_detect_enabled: bool = False
# Sustained seconds power must stay in the standby band (between
# stop_threshold_w and start_threshold_w) before DELAY_WAIT engages.
@@ -311,6 +331,14 @@ class CycleDetector:
self._end_spike_duration: float = 0.0 # cycle duration (s) when _end_spike_seen was last set
self._match_ambiguous: bool = False # last live match was ambiguous (gates predictive end)
self._match_prefix_ambiguous: bool = False # longer candidate with good shape exists (prefix guard)
# The narrower #288-only half of the flag above. #364 widened
# _match_prefix_ambiguous with prefix scoring, which is safe for the ENDING
# Smart-Termination gate but must NOT reach the anti-crease finalize (see
# _anticrease_gate_open) where blocking can re-hang a cycle (#296).
self._match_prefix_ambiguous_full_shape: bool = False
# Mean power the matched profile draws over the last few % of its own run
# (profile_store.profile_tail_power). None = no opinion, guard stays inert.
self._matched_tail_power: float | None = None
self._last_smart_term_block_reason: str | None = None # #346 diagnostic throttle
# Anti-wrinkle tracking (dryers only)
@@ -494,6 +522,110 @@ class CycleDetector:
return self._SANITIZE_INVALID_SENTINEL
return value
@staticmethod
def _sanitize_tail_power(raw: Any) -> float | None:
"""Coerce ``raw`` into a finite, positive float, else None (#364).
None means "no opinion": ``_smart_term_power_plausible`` then leaves both
Smart-Termination paths exactly as they behaved before the guard existed.
"""
if raw is None:
return None
try:
value = float(raw)
except (TypeError, ValueError):
return None
if not math.isfinite(value) or value <= 0:
return None
return value
def _trailing_mean_power(self, timestamp: datetime, window_s: float) -> float | None:
"""Time-weighted mean power over the trailing ``window_s``, or None when
there are too few samples to judge.
Time-weighted (not a plain sample mean) so an irregular reporting cadence -
a plug that only pushes on change, so quiet stretches are sparse - cannot
bias the result toward whichever regime happened to sample more often.
"""
window: list[tuple[datetime, float]] = []
for ts, power in reversed(self._power_readings):
if (timestamp - ts).total_seconds() > window_s:
break
window.append((ts, float(power)))
window.reverse()
# Explicit gap handling (energy-integration rule): a reading held across an
# unobserved outage would dominate the trapezoid - e.g. a stale 2000 W sample
# 290 s before a 284 s dropout, then 5 W, integrates to ~1000 W though every
# observed recent reading is 5 W, wrongly blocking termination. So drop
# everything up to and including the most recent outage-sized gap and judge
# only the clean contiguous tail, the same ceiling the standby / anti-crease
# window scans reject a holed window with.
if len(window) >= 2:
# O(1) ceiling from the maintained p95 cadence (mirrors energy_gap_threshold_s
# = clip(10x cadence, 60, 3600)), NOT _outage_threshold_s() which rebuilds a
# NumPy array from every reading - this runs on the per-reading ENDING /
# anti-crease path, same reasoning as the gap-free tally at L1006.
max_gap = min(3600.0, max(60.0, 10.0 * self._p95_dt))
cut = 0
for i in range(1, len(window)):
if (window[i][0] - window[i - 1][0]).total_seconds() > max_gap:
cut = i
window = window[cut:]
if len(window) < SMART_TERM_TAIL_MIN_POINTS:
return None
span = (window[-1][0] - window[0][0]).total_seconds()
if span <= 0:
return None
energy = 0.0
for (t0, p0), (t1, p1) in zip(window, window[1:]):
energy += (p0 + p1) / 2.0 * (t1 - t0).total_seconds()
return energy / span
def _smart_term_power_plausible(self, timestamp: datetime) -> bool:
"""Whether the appliance looks like it is actually FINISHING (#364).
Both Smart-Termination paths fire at ``elapsed >= 0.98 * expected`` and
neither asks whether the machine is still working. When the matcher has
locked onto a shorter look-alike profile that anchor lands mid-wash, the
cycle is cut in half and the remainder is recorded as a second cycle.
The test: compare the trailing mean power against what the matched profile
itself draws at its own end. Drawing several times that level is proof we
are not at the end of anything - whatever the clock says. Unlike the
prefix-landscape guard this needs no longer profile to exist in the pool,
so it also covers the reported case where the programme actually running
was never trained.
Shorten-only and fail-open: any missing input returns True, leaving
behaviour identical to before the guard. A False can only ever *block* an
early finish - the power-based fallback timeout still ends the cycle.
"""
tail_power = self._matched_tail_power
if tail_power is None or tail_power <= 0:
return True
mean_power = self._trailing_mean_power(timestamp, self._tail_window_s())
if mean_power is None:
return True
return mean_power <= tail_power * SMART_TERM_TAIL_MAX_RATIO
def _tail_window_s(self) -> float:
"""Trailing window that covers the same FRACTION of the run as the profile
tail it is compared against.
A fixed window is not comparable across programme lengths: 300 s is 4% of a
cotton wash but a third of a 15-minute spin-and-drain, whose trailing mean
would then be the spin itself while its profile tail is the quiet moment
after the pump stops. Measured on the full corpus, making this proportional
is strictly better at every threshold.
"""
expected = self._expected_duration
if expected <= 0:
return SMART_TERM_TAIL_WINDOW_S
return min(
SMART_TERM_TAIL_WINDOW_S,
max(SMART_TERM_TAIL_WINDOW_MIN_S, expected * SMART_TERM_TAIL_WINDOW_FRAC),
)
def update_match(self, result: tuple[Any, ...] | list[Any] | Any) -> None: # type: ignore[misc]
"""Process a match result (synchronously).
@@ -586,6 +718,20 @@ class CycleDetector:
self._last_match_confidence = confidence or 0.0
self._match_ambiguous = ambiguous
self._match_prefix_ambiguous = bool(result_seq[6]) if len(result_seq) >= 7 else False
# Element 8 (#364): the narrower legacy verdict. A shorter tuple
# (Playground, older callers, most tests) falls back to the widened
# value, which reproduces pre-#364 behaviour exactly.
self._match_prefix_ambiguous_full_shape = (
bool(result_seq[7]) if len(result_seq) >= 8 else self._match_prefix_ambiguous
)
# Element 9 (#364): the matched profile's own tail power level. Absent
# or non-finite leaves the power-plausibility guard inert - so a shorter
# tuple (Playground, older callers, most tests) must CLEAR it, not keep
# the previous match's value: retaining it would let the guard compare
# the live tail against the wrong profile and block a valid termination.
self._matched_tail_power = (
self._sanitize_tail_power(result_seq[8]) if len(result_seq) >= 9 else None
)
else:
# Assume MatchResult object or similar (future proofing)
# But for now wrapper returns tuple
@@ -596,6 +742,8 @@ class CycleDetector:
self._matched_profile = None
self._match_ambiguous = False
self._match_prefix_ambiguous = False
self._match_prefix_ambiguous_full_shape = False
self._matched_tail_power = None
elif match_name:
# If sanitization rejected the expected_duration, treat the match
@@ -647,6 +795,8 @@ class CycleDetector:
self._last_match_confidence = 0.0
self._match_ambiguous = False
self._match_prefix_ambiguous = False
self._match_prefix_ambiguous_full_shape = False
self._matched_tail_power = None
# Per-cycle diagnostic throttle (#346): the "Smart Termination not applied"
# line only logs when the reason CHANGES. Carrying the previous cycle's
# reason across a reset swallows the new cycle's very first diagnostic
@@ -713,14 +863,15 @@ class CycleDetector:
is_confident: bool,
ambiguous: bool,
prefix_ambiguous: bool,
power_plausible: bool = True,
) -> str | None:
"""Why the Smart-Termination fast end-path did NOT fire, for diagnostics.
Returns None when the gate would pass, or when no expected duration is known
yet (nothing meaningful to report). Mirrors the gate's four conditions in
order so the first blocking reason is surfaced. Pure and side-effect-free;
the detector logs the result (throttled to reason changes) - no behaviour
change (#346).
yet (nothing meaningful to report). Mirrors the gate's conditions in order so
the first blocking reason is surfaced. Pure and side-effect-free; the
detector logs the result (throttled to reason changes) - no behaviour
change (#346, extended with "still_active" for #364).
"""
if expected <= 0:
return None
@@ -732,8 +883,48 @@ class CycleDetector:
return "match_ambiguous"
if prefix_ambiguous:
return "prefix_ambiguous"
if not power_plausible:
return "still_active"
return None
@staticmethod
def _resolve_smart_ratio(
device_type: str,
configured_ratio: float,
end_spike_seen: bool,
end_spike_duration: float,
expected_duration: float,
) -> float:
"""Resolve the Smart-Termination duration-ratio gate (#393).
``configured_ratio`` is the per-device option, already resolved in the
config builder to the device-type default (0.99 dishwasher / 0.98 other)
unless the user tuned it - so it is always a real float here.
For a dishwasher whose most-recent in-ENDING spike landed at >=90% of the
expected duration, that spike is the terminal pump-out (not a mid-cycle
rinse drain): once it is confirmed the gate is loosened to the 0.90
pump-out relief, because individual cycles can be a few % shorter than the
rolling average and still terminate cleanly. Keeping the configured gate
for spikes at <90% prevents premature closes during the passive Dry phase
that follows the pre-final-rinse drain. The relief is combined with the
configured value via ``min()`` so a configured ratio can only ever LOOSEN
the gate, never tighten it. Pure and side-effect-free (unit-testable).
"""
# Clamp to the documented [0.50, 1.00] range (the WS write path clamps, but a
# value persisted by an import or an older schema is read here unclamped): a
# 0.0 would drop the duration floor entirely and let Smart Termination fire the
# moment its other conditions pass.
configured_ratio = min(1.0, max(0.5, configured_ratio))
if (
device_type == "dishwasher"
and end_spike_seen
and expected_duration > 0
and end_spike_duration >= expected_duration * 0.90
):
return min(configured_ratio, 0.90)
return configured_ratio
def process_reading(self, power: float, timestamp: datetime) -> None:
"""Process a new power reading using robust dt-aware logic."""
@@ -1373,30 +1564,27 @@ class CycleDetector:
# 1. Require higher duration ratio for Smart path
# 2. Require debounce to be measured FROM entry into ENDING state
if self._config.device_type == "dishwasher":
# If the most-recent in-ENDING spike occurred at ≥90% of
# expected, it is the terminal pump-out, not a mid-cycle
# rinse drain. Once that pump-out is confirmed, we don't
# need to wait for 99% of the rolling avg — individual
# cycles can be up to ~7% shorter than avg_duration and
# still terminate cleanly. Keeping the 0.99 gate for
# spikes at <90% prevents premature closes during the
# passive Dry phase that follows the pre-final-rinse drain.
_esp_dur = getattr(self, "_end_spike_duration", 0.0)
if (
getattr(self, "_end_spike_seen", False)
and self._expected_duration > 0
and _esp_dur >= self._expected_duration * 0.90
):
smart_ratio = 0.90 # pump-out confirmed near end
else:
smart_ratio = 0.99 # conservative: wait for expected duration
else:
smart_ratio = 0.98
# Per-appliance configurable gate (#393): the ratio is resolved
# in the config builder to the device-type default (0.99
# dishwasher / 0.98 other) unless the user tuned it, and the
# dishwasher pump-out relief is folded in via a pure helper so
# the gate logic stays unit-testable (see _resolve_smart_ratio).
smart_ratio = self._resolve_smart_ratio(
self._config.device_type,
self._config.smart_termination_duration_ratio,
getattr(self, "_end_spike_seen", False),
getattr(self, "_end_spike_duration", 0.0),
self._expected_duration,
)
is_confident_match = (
getattr(self, "_last_match_confidence", 0.0) >= 0.4
getattr(self, "_last_match_confidence", 0.0)
>= self._config.match_confidence_threshold
)
# Compute the #364 power-plausibility once per reading and reuse it
# for the diagnostic reason and the gate below - the helper walks the
# trailing window, so calling it two/three times per reading is waste.
_power_plausible = self._smart_term_power_plausible(timestamp)
# Gate the predictive end on match certainty.
# _match_ambiguous: top-1 vs top-2 score gap is too small to
@@ -1421,19 +1609,22 @@ class CycleDetector:
is_confident_match,
self._match_ambiguous,
self._match_prefix_ambiguous,
_power_plausible,
)
if _block_reason != self._last_smart_term_block_reason:
self._last_smart_term_block_reason = _block_reason
if _block_reason is not None:
self._logger.debug(
"Smart Termination not applied (%s): dur=%.0fs/%.0fs conf=%.2f "
"ambiguous=%s prefix_ambiguous=%s",
"ambiguous=%s prefix_ambiguous=%s trailing_power=%s profile_tail=%s",
_block_reason,
current_duration,
self._expected_duration * smart_ratio,
getattr(self, "_last_match_confidence", 0.0),
self._match_ambiguous,
self._match_prefix_ambiguous,
self._trailing_mean_power(timestamp, self._tail_window_s()),
self._matched_tail_power,
)
if (
@@ -1441,6 +1632,11 @@ class CycleDetector:
and is_confident_match
and not self._match_ambiguous
and not self._match_prefix_ambiguous
# #364: the clock says "done", but if we are still drawing
# several times what this profile draws at its own end, the
# match is a shorter look-alike and we are mid-wash. Block;
# the power-based fallback timeout decides instead.
and _power_plausible
):
# Dynamic confirmation window
if self._config.device_type == "dishwasher":
@@ -1950,18 +2146,31 @@ class CycleDetector:
return False
if not (self._matched_profile and self._expected_duration > 0):
return False
if self._last_match_confidence < 0.4:
if self._last_match_confidence < self._config.match_confidence_threshold:
return False
if self._match_ambiguous or self._match_prefix_ambiguous:
# Deliberately the NARROW #288-only verdict, not the #364-widened flag: a
# false block here disables the finalise AND the match freeze, and because
# the tumble bursts recur faster than off_delay neither the fallback timeout
# nor ENDING_HARD_FINALIZE can close the cycle - that is the #296 hang.
if self._match_ambiguous or self._match_prefix_ambiguous_full_shape:
return False
if self._cycle_max_power <= float(self._config.anti_wrinkle_max_power):
return False # never a hot/energetic cycle - leave low-power programs alone
# Cheap clock test first, so the trailing-power scan below is skipped for the
# whole mid-wash phase (it only matters once we are past-expected).
start = self._current_cycle_start
if start is None:
return False
current_duration = (timestamp - start).total_seconds()
if current_duration < self._expected_duration * ANTI_CREASE_FINALIZE_RATIO:
return False
# #364: "past expected" only means "past the wash" when expected belongs to
# the RIGHT profile. A whole washer wash phase sits below
# anti_wrinkle_max_power, so with a mis-matched shorter profile this gate
# would open mid-wash. Requiring the trailing power to look like this
# profile's own tail restores the guarantee the ratio alone used to give.
if not self._smart_term_power_plausible(timestamp):
return False
return True
def _in_anticrease_freeze(self, timestamp: datetime) -> bool:
@@ -2441,6 +2650,8 @@ class CycleDetector:
"end_spike_duration": self._end_spike_duration,
"match_ambiguous": self._match_ambiguous,
"match_prefix_ambiguous": self._match_prefix_ambiguous,
"match_prefix_ambiguous_full_shape": self._match_prefix_ambiguous_full_shape,
"matched_tail_power": self._matched_tail_power,
"ml_defer_start_duration": self._ml_defer_start_duration,
}
@@ -2503,6 +2714,14 @@ class CycleDetector:
self._end_spike_duration = float(snapshot.get("end_spike_duration", 0.0))
self._match_ambiguous = snapshot.get("match_ambiguous", False)
self._match_prefix_ambiguous = snapshot.get("match_prefix_ambiguous", False)
# A pre-#364 snapshot has no narrow flag: fall back to the widened
# value so a restart cannot loosen the anti-crease gate.
self._match_prefix_ambiguous_full_shape = snapshot.get(
"match_prefix_ambiguous_full_shape", self._match_prefix_ambiguous
)
self._matched_tail_power = self._sanitize_tail_power(
snapshot.get("matched_tail_power")
)
self._ml_defer_start_duration = snapshot.get("ml_defer_start_duration")
# Restore state enter time and recompute time_in_state from it
@@ -82,8 +82,14 @@ async def async_get_config_entry_diagnostics(
entry_options=dict(entry.options),
)
from .frontend import served_asset_report
return {
"entry": _redact(entry.as_dict()),
# Which panel/card variant is actually being served. Both are served at the
# same URL by design, so without this a bug report cannot tell us whether the
# reporter was running the minified bundle or the readable fallback.
"frontend_assets": served_asset_report(),
"manager_state": {
"current_state": manager.check_state(),
"current_program": manager.current_program,
+258 -53
View File
@@ -31,6 +31,18 @@ CARD_NAME = "ha-washdata-card.js"
INTEGRATION_URL = f"/{LOCAL_SUBDIR}/{CARD_NAME}"
CARD_REGISTERED = "registered"
# Minified build artifacts produced by devtools/build_panel.mjs, and the manifest
# recording which source each was built from. These are an optimisation only:
# every asset is ALWAYS served at its readable-source URL, and _resolve_asset()
# falls back to the readable source whenever the artifact is missing, stale, or
# hand-edited. So a forgotten rebuild degrades to a bigger download, never to
# wrong code -- which is why the URL must not encode which variant was chosen.
BUILD_MANIFEST_NAME = "build-manifest.json"
# source name -> {"serving", "minified", "bytes"} for whatever was last registered.
# Module level (not per-entry): the frontend assets are registered once per HA start.
_SERVED_ASSETS: dict[str, dict] = {}
# Full-screen panel constants
PANEL_JS_NAME = "ha-washdata-panel.js"
PANEL_JS_URL = f"/{LOCAL_SUBDIR}/{PANEL_JS_NAME}"
@@ -63,70 +75,235 @@ class LovelaceResourceItem(TypedDict, total=False):
res_type: str
def get_cache_buster(filename: str = CARD_NAME) -> str:
"""Generate a stable cache buster based on a www asset's mtime.
def _sha256_file(path: Path) -> str:
"""SHA-256 of a file, streamed so a large asset never lands in memory twice."""
import hashlib
Also considers the translations/panel/ directory mtime so that
translation-only releases (e.g. GitLocalize merges) still bust the
browser cache for both the panel JS and the per-language JSON files.
digest = hashlib.sha256()
with open(path, "rb") as handle:
for chunk in iter(lambda: handle.read(1024 * 256), b""):
digest.update(chunk)
return digest.hexdigest()
def _resolve_asset(source_name: str, www: Path | None = None) -> Path:
"""Return the file to serve for ``source_name``: minified build, or source.
The minified artifact is used only when the manifest proves it was built from
exactly the bytes currently on disk AND has not been modified since. Any doubt
-- no manifest, no artifact, changed source, tampered artifact, unreadable
anything -- resolves to the readable source. Blocking I/O; call in an executor.
``www`` overrides the asset directory (tests only); production always uses the
integration's own www/.
"""
import json
if www is None:
www = Path(__file__).parent / "www"
source = www / source_name
try:
base = Path(__file__).parent
src_mtime = os.path.getmtime(base / "www" / filename)
manifest = json.loads((www / BUILD_MANIFEST_NAME).read_text())
entry = manifest["assets"][source_name]
artifact = www / entry["artifact"]
if not artifact.is_file():
return source
if _sha256_file(source) != entry["source_sha256"]:
_LOGGER.debug(
"%s changed since the last panel build; serving readable source "
"(run devtools/build_panel.mjs to refresh the minified build)",
source_name,
)
return source
if _sha256_file(artifact) != entry["artifact_sha256"]:
_LOGGER.warning(
"Minified asset %s does not match its build manifest; serving "
"readable source instead",
entry["artifact"],
)
return source
return artifact
except Exception as exc: # pylint: disable=broad-exception-caught
_LOGGER.debug(
"No usable minified build for %s (%s); serving readable source",
source_name,
exc,
)
return source
def _ensure_gzip(path: Path) -> None:
"""Keep a fresh ``<path>.gz`` beside ``path`` so aiohttp can serve it.
aiohttp's FileResponse transparently serves a pre-compressed sibling when the
client sends a matching Accept-Encoding, which cuts these assets by ~75% -- but
it only checks that the sibling EXISTS, never that it is current. A stale .gz
would therefore be served as if it were the real file (and cached for a month),
so the sibling is unconditionally rebuilt from the exact file being served.
Rebuilding unconditionally rather than comparing mtimes is deliberate: the .gz
is not shipped, so it is written at install time, while an update can restore
an *older* source mtime from the release archive (the same mtime-preservation
``get_cache_buster`` works around). "Newer .gz" therefore does not imply "current
.gz", and the cost of being sure is ~25 ms for the panel and ~1 ms for the card,
once per HA start, in an executor. Best-effort: a read-only install just serves
uncompressed.
If the rebuild fails, any existing sibling is removed rather than left behind:
aiohttp would keep serving it, which is the stale-content case this function
exists to prevent. Losing compression is the safe half of that trade.
"""
import gzip
import shutil
import tempfile
gz = path.with_suffix(path.suffix + ".gz")
try:
# Compress to a temp file in the same directory, then atomically replace, so
# a concurrent request can never observe a half-written .gz.
fd, tmp_name = tempfile.mkstemp(dir=str(path.parent), suffix=".gz.tmp")
os.close(fd)
tmp = Path(tmp_name)
try:
with open(path, "rb") as src, gzip.open(str(tmp), "wb", compresslevel=9) as dst:
shutil.copyfileobj(src, dst)
os.replace(tmp, gz)
except BaseException:
tmp.unlink(missing_ok=True)
raise
_LOGGER.debug("Wrote compressed asset %s", gz.name)
except Exception as exc: # pylint: disable=broad-exception-caught
_LOGGER.debug("Could not pre-compress %s (%s); serving uncompressed", path, exc)
try:
gz.unlink(missing_ok=True)
except OSError: # read-only dir: nothing was ever written there either
pass
def _prepare_asset(source_name: str, www: Path | None = None) -> Path:
"""Resolve the best variant of an asset and make sure its .gz is current.
Also records the outcome so it can be reported without a browser: because both
variants are served at the SAME url, the only ways to tell from outside are the
response size and its hash, which is awkward to ask of a bug reporter. See
``served_asset_report``.
"""
served = _resolve_asset(source_name, www)
_ensure_gzip(served)
# Stat once and reuse: a second, unguarded stat()/is_file() below could raise if
# the file vanished between the two calls and fail the whole registration, even
# though the asset was resolved and compressed fine.
try:
size = served.stat().st_size
except OSError:
size = None
if size is not None:
_SERVED_ASSETS[source_name] = {
"serving": served.name,
"minified": served.name != source_name,
"bytes": size,
}
_LOGGER.info(
"Serving %s as %s (%s, %.1f KB)",
source_name,
served.name,
"minified build" if served.name != source_name else "readable source",
(size / 1024) if size is not None else 0.0,
)
return served
def served_asset_report() -> dict[str, dict]:
"""Which variant of each frontend asset is actually being served.
Populated by :func:`_prepare_asset` at registration time. Surfaced in
diagnostics so "is the minified panel live?" is answerable from a diagnostics
download instead of from browser devtools and a hash comparison.
"""
return {k: dict(v) for k, v in _SERVED_ASSETS.items()}
def get_cache_buster(filename: str = CARD_NAME) -> str:
"""Generate a stable cache buster for a www asset.
Folds in the manifest.json version string so that every release produces a
different URL even when the package manager (e.g. HACS) preserves original
file mtimes from the release archive. The mtime path is kept as a secondary
signal so translation-only GitLocalize merges still bust the cache.
Timestamps are read in nanoseconds (``st_mtime_ns``): ``getmtime()`` returns
float seconds, and truncating that to whole seconds made two rebuilds inside
the same second - which is a normal development cycle - produce the same
token, leaving the browser on the immutably-cached previous artifact.
"""
import hashlib
import json
base = Path(__file__).parent
try:
manifest_version = json.loads((base / "manifest.json").read_text())["version"]
except Exception: # pylint: disable=broad-exception-caught
manifest_version = ""
try:
src_mtime = os.stat(base / "www" / filename).st_mtime_ns
try:
panel_dir = base / "translations" / "panel"
trans_mtime = max(
(os.path.getmtime(f) for f in panel_dir.iterdir() if f.is_file()),
default=0.0,
(os.stat(f).st_mtime_ns for f in panel_dir.iterdir() if f.is_file()),
default=0,
)
except OSError:
trans_mtime = 0.0
return str(int(max(src_mtime, trans_mtime)))
trans_mtime = 0
# A rebuild changes the minified artifact and the manifest but not the
# source, so fold both in: otherwise switching between the readable and
# minified variant would reuse a URL the browser has already cached.
try:
build_mtime = max(
os.stat(base / "www" / BUILD_MANIFEST_NAME).st_mtime_ns,
os.stat(_resolve_asset(filename)).st_mtime_ns,
)
except OSError:
build_mtime = 0
mtime_part = str(max(src_mtime, trans_mtime, build_mtime))
except OSError:
# Deterministic fallback when file is unavailable.
return "1"
mtime_part = "1"
raw = f"{manifest_version}:{mtime_part}"
# Not a security primitive - just a short, stable URL token - so tell Ruff (S324).
return hashlib.sha1(raw.encode(), usedforsecurity=False).hexdigest()[:10]
def _register_static_path(hass: HomeAssistant, url_path: str, path: str) -> None:
"""Register a static path with the HA HTTP component, compatible with multiple HA versions."""
try:
# pylint: disable=import-outside-toplevel
from homeassistant.components.http import StaticPathConfig
def _register_static_path(hass: HomeAssistant, url_path: str, path: str) -> bool:
"""Register a static path through the legacy sync HA HTTP helper.
if hasattr(hass.http, "async_register_static_paths"):
Only reached from :func:`_async_register_path` when the modern
``async_register_static_paths`` API is unavailable, which no supported Home
Assistant hits (hacs.json floors the requirement at 2026.5.0, and the sync
helper was removed upstream well before that).
async def _safe_register():
try:
await hass.http.async_register_static_paths(
[StaticPathConfig(url_path, path, True)]
)
except Exception as exc: # pylint: disable=broad-exception-caught
_LOGGER.debug(
"Failed to async register static path %s -> %s: %s",
url_path,
path,
exc,
)
hass.async_create_task(_safe_register())
return
except Exception as exc: # pylint: disable=broad-exception-caught
_LOGGER.debug(
"Async static path registration not available; falling back to "
"sync registration for %s -> %s (%s)",
url_path,
path,
exc,
)
# Fallback for older HA
Returns True only when a registration actually happened. Reporting the
outcome is the point: a route that was never registered but is treated as
success leaves the Lovelace resource pointing at a permanently 404ing URL,
which is issue #384 in its silent form.
"""
try:
http_obj = cast(Any, hass.http)
register_static_path = getattr(http_obj, "register_static_path", None)
if callable(register_static_path):
register_static_path(url_path, path, cache_headers=True)
except Exception: # pylint: disable=broad-exception-caught
_LOGGER.debug("Failed to register static path %s -> %s", url_path, path)
if not callable(register_static_path):
_LOGGER.debug(
"No usable static-path API for %s -> %s (neither "
"async_register_static_paths nor register_static_path)",
url_path,
path,
)
return False
register_static_path(url_path, path, cache_headers=True)
return True
except Exception as exc: # pylint: disable=broad-exception-caught
_LOGGER.debug("Failed to register static path %s -> %s (%s)", url_path, path, exc)
return False
async def _init_resource(hass: HomeAssistant, url: str, ver: str) -> bool:
@@ -207,7 +384,28 @@ class WashDataCardRegistration:
_LOGGER.warning("Card file not found: %s", src)
return CARD_FAILED
_register_static_path(self.hass, INTEGRATION_URL, str(src))
# Serve the minified build when it is provably current. The URL stays
# INTEGRATION_URL either way, so the Lovelace resource never has to be
# migrated and dashboards cannot end up pointing at a variant that moved.
src = await self.hass.async_add_executor_job(_prepare_asset, CARD_NAME)
# The static route MUST exist before the Lovelace resource is published:
# the resource is what makes every browser fetch this URL, and a fetch
# that lands before the route is registered 404s, so the module never
# runs its customElements.define() and the dashboard reports
# "Custom element not found: ha-washdata-card". Awaiting here (rather
# than the old fire-and-forget task) both orders the two steps and
# surfaces a genuine registration failure instead of swallowing it.
try:
await _async_register_path(self.hass, INTEGRATION_URL, str(src))
except Exception as exc: # pylint: disable=broad-exception-caught
_LOGGER.warning(
"Failed to register card static path %s -> %s: %s",
INTEGRATION_URL,
src,
exc,
)
return CARD_FAILED
version = await self.hass.async_add_executor_job(get_cache_buster)
@@ -281,16 +479,20 @@ async def _async_register_path(hass: HomeAssistant, url_path: str, path: str) ->
back to the legacy sync helper only when that API is absent — not on a
genuine registration failure. An already-registered path is treated as
success (benign on integration reload); any other exception propagates so
the caller can decide whether to report failure.
the caller can decide whether to report failure. A legacy fallback that
could not register either propagates as well: silently returning would
publish a Lovelace resource for a URL that 404s (issue #384).
"""
try:
from homeassistant.components.http import StaticPathConfig # pylint: disable=import-outside-toplevel
except ImportError:
_register_static_path(hass, url_path, path)
if not _register_static_path(hass, url_path, path):
raise
return
if not hasattr(hass.http, "async_register_static_paths"):
_register_static_path(hass, url_path, path)
if not _register_static_path(hass, url_path, path):
raise RuntimeError(f"no usable static-path API to serve {url_path}")
return
try:
@@ -313,7 +515,10 @@ async def _do_register_panel(hass: HomeAssistant, src: Path) -> bool:
# ── Phase 1: static paths ────────────────────────────────────────────────
try:
# Panel JS (primary asset — must be available before the sidebar fires).
await _async_register_path(hass, PANEL_JS_URL, str(src))
# Served at PANEL_JS_URL regardless of which variant won, so the sidebar's
# module_url never has to change and a stale build cannot strand the panel.
served = await hass.async_add_executor_job(_prepare_asset, PANEL_JS_NAME)
await _async_register_path(hass, PANEL_JS_URL, str(served))
# Per-language translation files.
trans_src = Path(__file__).parent / "translations" / PANEL_TRANSLATIONS_DIRNAME
+11 -3
View File
@@ -294,8 +294,9 @@ async def _localized_templates(
English base first, then the language's base subtag, then the full tag (so
``pt-BR`` overrides ``pt`` overrides ``en``). File reads are offloaded to the
executor when the hass supports it, with a synchronous fallback (minimal test
hass). Falls back to :data:`DEFAULT_TEMPLATES` on any failure.
executor when the hass supports it, with a synchronous fallback for a hass that
has no executor (the minimal test stand-in). Falls back to
:data:`DEFAULT_TEMPLATES` on any failure.
"""
templates = dict(DEFAULT_TEMPLATES)
lang = language or "en"
@@ -305,8 +306,15 @@ async def _localized_templates(
continue
try:
loaded = await hass.async_add_executor_job(_load_intent_file, lg)
except Exception: # noqa: BLE001 - minimal test hass has no executor
except (AttributeError, TypeError):
# Only a hass without a usable executor (the minimal test stand-in)
# reads on the loop. A broad except here would also catch a real
# executor failure - e.g. "cannot schedule new futures after
# shutdown" - and then do the blocking open() on the event loop,
# which is exactly what the offload exists to prevent.
loaded = _load_intent_file(lg)
except Exception: # noqa: BLE001 - a real executor failure keeps English
loaded = {}
for key, value in (loaded or {}).items():
if isinstance(value, str) and value:
templates[key] = value
+141 -8
View File
@@ -54,6 +54,7 @@ from homeassistant.helpers import translation
from .const import (
DOMAIN,
CONF_POWER_SENSOR,
CONF_PROFILE_EVIDENCE_SOURCES,
CONF_MIN_POWER,
CONF_OFF_DELAY,
CONF_NOTIFY_SERVICE,
@@ -113,6 +114,9 @@ from .const import (
CONF_ANTI_WRINKLE_IDLE_TIMEOUT,
CONF_DISHWASHER_END_SPIKE_QUIET_RELEASE,
DISHWASHER_END_SPIKE_QUIET_RELEASE_SECONDS,
CONF_SMART_TERMINATION_DURATION_RATIO,
DEFAULT_SMART_TERMINATION_DURATION_RATIO,
DEFAULT_SMART_TERMINATION_DURATION_RATIO_BY_DEVICE,
CONF_DELAY_START_DETECT_ENABLED,
CONF_DELAY_CONFIRM_SECONDS,
CONF_DELAY_TIMEOUT_HOURS,
@@ -142,6 +146,7 @@ from .const import (
DEFAULT_SAMPLING_INTERVAL,
DEFAULT_PROGRESS_RESET_DELAY,
DEFAULT_POWER_OFF_THRESHOLD_W,
DEFAULT_PROFILE_EVIDENCE_SOURCES,
DEFAULT_POWER_OFF_DELAY,
DEFAULT_LEARNING_CONFIDENCE,
DEFAULT_DURATION_TOLERANCE,
@@ -223,6 +228,10 @@ from .const import (
DEFAULT_MAX_FULL_TRACES_UNLABELED,
DEFAULT_DTW_BANDWIDTH,
DEFAULT_WATCHDOG_INTERVAL,
resolve_sampling_interval_default,
resolve_watchdog_interval_default,
resolve_start_duration_default,
resolve_smart_termination_duration_ratio_default,
CONF_MATCH_PERSISTENCE,
DEFAULT_MATCH_PERSISTENCE,
DEFAULT_MATCH_REVERT_RATIO,
@@ -593,6 +602,11 @@ class WashDataManager:
# Stage-4 energy discriminator: integrated energy for WM/washer-dryer,
# mean power elsewhere (see analysis.stage4_energy_mode).
self.profile_store.energy_mode = analysis.stage4_energy_mode(self.device_type)
# Which cycle categories may shape a profile. The store cannot read entry
# options, so the manager pushes this in (same as energy_mode above).
self.profile_store.evidence_sources = config_entry.options.get(
CONF_PROFILE_EVIDENCE_SOURCES, DEFAULT_PROFILE_EVIDENCE_SOURCES
)
self.learning_manager = LearningManager(
hass, self.entry_id, self.profile_store, self.device_type,
device_name=config_entry.title,
@@ -707,7 +721,8 @@ class WashDataManager:
start_duration_threshold = float(
config_entry.options.get(
CONF_START_DURATION_THRESHOLD, DEFAULT_START_DURATION_THRESHOLD
CONF_START_DURATION_THRESHOLD,
resolve_start_duration_default(self.device_type),
)
)
end_repeat_count = int(
@@ -779,6 +794,16 @@ class WashDataManager:
CONF_PROFILE_MATCH_INTERVAL, DEFAULT_PROFILE_MATCH_INTERVAL
)
),
# `profile_match_threshold` was stored on the ProfileStore and never read
# anywhere, so the #288 workaround (raise it so near-duplicate profiles
# stop being trusted mid-cycle) silently did nothing. Wire it to the gate
# it was always documented to control; the default is the value that used
# to be hard-coded there, so nothing changes unless it was tuned.
match_confidence_threshold=float(
config_entry.options.get(
CONF_PROFILE_MATCH_THRESHOLD, DEFAULT_PROFILE_MATCH_THRESHOLD
)
),
anti_wrinkle_enabled=bool(
config_entry.options.get(
CONF_ANTI_WRINKLE_ENABLED, DEFAULT_ANTI_WRINKLE_ENABLED
@@ -810,6 +835,15 @@ class WashDataManager:
DISHWASHER_END_SPIKE_QUIET_RELEASE_SECONDS,
)
),
# #393: resolve the device-type default HERE (not in the gate) so the
# field always carries a real float - playground.effective_settings()
# skips a None-valued field, which would desync the sim from the detector.
smart_termination_duration_ratio=float(
config_entry.options.get(
CONF_SMART_TERMINATION_DURATION_RATIO,
resolve_smart_termination_duration_ratio_default(self.device_type),
)
),
delay_detect_enabled=bool(
config_entry.options.get(
CONF_DELAY_START_DETECT_ENABLED, DEFAULT_DELAY_START_DETECT_ENABLED
@@ -903,13 +937,19 @@ class WashDataManager:
self._remove_external_trigger_listener = None # External cycle end trigger
self._remove_watchdog = None
self._watchdog_interval = int(
config_entry.options.get(CONF_WATCHDOG_INTERVAL, DEFAULT_WATCHDOG_INTERVAL)
config_entry.options.get(
CONF_WATCHDOG_INTERVAL,
resolve_watchdog_interval_default(self.device_type),
)
)
self._match_persistence = int(
config_entry.options.get(CONF_MATCH_PERSISTENCE, DEFAULT_MATCH_PERSISTENCE)
)
self._sampling_interval = float(
config_entry.options.get(CONF_SAMPLING_INTERVAL, DEFAULT_SAMPLING_INTERVAL)
config_entry.options.get(
CONF_SAMPLING_INTERVAL,
resolve_sampling_interval_default(self.device_type),
)
)
self._noise_events_threshold = int(
config_entry.options.get(
@@ -1427,10 +1467,15 @@ class WashDataManager:
# Push updates to detector
self.detector.set_verified_pause(verified_pause)
# Element 8 is the narrow #288-only prefix verdict and element 9 the
# matched profile's own tail power level, both for the #364 guards. The
# detector tolerates shorter tuples, so other callers stay valid.
self.detector.update_match(
(profile_name, confidence, matched_duration, phase_name,
result.is_confident_mismatch, result.is_ambiguous,
result.is_prefix_ambiguous)
result.is_prefix_ambiguous,
result.is_prefix_ambiguous_full_shape,
self.profile_store.profile_tail_power(profile_name) if profile_name else None)
)
# --- LOGGING (Unified) ---
@@ -2093,12 +2138,36 @@ class WashDataManager:
CONF_PROFILE_MATCH_INTERVAL, DEFAULT_PROFILE_MATCH_INTERVAL
)
)
# Keep the detector's copy in sync so a panel edit takes effect without a
# restart, exactly like min_duration_ratio below.
self.detector.config.match_confidence_threshold = float(
config_entry.options.get(
CONF_PROFILE_MATCH_THRESHOLD, DEFAULT_PROFILE_MATCH_THRESHOLD
)
)
self.profile_store.dtw_bandwidth = float(
config_entry.options.get(CONF_DTW_BANDWIDTH, DEFAULT_DTW_BANDWIDTH)
)
# Stage-4 energy discriminator: integrated energy for WM/washer-dryer,
# mean power elsewhere (see analysis.stage4_energy_mode).
self.profile_store.energy_mode = analysis.stage4_energy_mode(self.device_type)
# Which cycle categories may shape a profile. Changing it changes every
# profile's curve, so rebuild them all now: envelopes are otherwise only rebuilt
# on a cycle end or a label change, so the user would tick the box and see
# nothing happen for days.
_prev_evidence = self.profile_store.evidence_sources
self.profile_store.evidence_sources = config_entry.options.get(
CONF_PROFILE_EVIDENCE_SOURCES, DEFAULT_PROFILE_EVIDENCE_SOURCES
)
if self.profile_store.evidence_sources != _prev_evidence:
self._logger.info(
"Profile evidence sources changed %s -> %s; rebuilding all envelopes",
list(_prev_evidence), list(self.profile_store.evidence_sources),
)
# Tracked, not fire-and-forget: this writes to the ProfileStore, so a
# reload/unload mid-rebuild must be able to cancel it before the store is
# swapped out (see _spawn_tracked).
self._spawn_tracked(self.profile_store.async_rebuild_all_envelopes())
# Device default
dev_def = DEVICE_COMPLETION_THRESHOLDS.get(
@@ -2110,7 +2179,8 @@ class WashDataManager:
new_start_threshold = float(
config_entry.options.get(
CONF_START_DURATION_THRESHOLD, DEFAULT_START_DURATION_THRESHOLD
CONF_START_DURATION_THRESHOLD,
resolve_start_duration_default(self.device_type),
)
)
new_end_repeat_count = int(
@@ -2180,6 +2250,12 @@ class WashDataManager:
DISHWASHER_END_SPIKE_QUIET_RELEASE_SECONDS,
)
)
new_smart_termination_duration_ratio = float(
config_entry.options.get(
CONF_SMART_TERMINATION_DURATION_RATIO,
resolve_smart_termination_duration_ratio_default(self.device_type),
)
)
new_delay_detect_enabled = bool(
config_entry.options.get(
CONF_DELAY_START_DETECT_ENABLED, DEFAULT_DELAY_START_DETECT_ENABLED
@@ -2219,6 +2295,7 @@ class WashDataManager:
self.detector.config.anti_wrinkle_exit_power = new_anti_wrinkle_exit_power
self.detector.config.anti_wrinkle_idle_timeout = new_anti_wrinkle_idle_timeout
self.detector.config.dishwasher_end_spike_quiet_release = new_dishwasher_end_spike_quiet_release
self.detector.config.smart_termination_duration_ratio = new_smart_termination_duration_ratio
self.detector.config.delay_detect_enabled = new_delay_detect_enabled
self.detector.config.delay_confirm_seconds = new_delay_confirm_seconds
self.detector.config.delay_timeout_seconds = new_delay_timeout_seconds
@@ -2414,7 +2491,10 @@ class WashDataManager:
# Update sampling interval
old_sampling = self._sampling_interval
new_sampling = float(
config_entry.options.get(CONF_SAMPLING_INTERVAL, DEFAULT_SAMPLING_INTERVAL)
config_entry.options.get(
CONF_SAMPLING_INTERVAL,
resolve_sampling_interval_default(self.device_type),
)
)
if old_sampling != new_sampling:
self._sampling_interval = new_sampling
@@ -2422,6 +2502,26 @@ class WashDataManager:
"Updated sampling interval: %.1fs -> %.1fs", old_sampling, new_sampling
)
# Watchdog cadence: like sampling above, this was only read at construction, so a
# changed CONF_WATCHDOG_INTERVAL (or a device-type change selecting a new default)
# otherwise kept the old cadence until the manager was recreated. Re-arm an active
# watchdog so the new interval takes effect mid-cycle.
old_watchdog = self._watchdog_interval
new_watchdog = int(
config_entry.options.get(
CONF_WATCHDOG_INTERVAL,
resolve_watchdog_interval_default(self.device_type),
)
)
if old_watchdog != new_watchdog:
self._watchdog_interval = new_watchdog
self._logger.info(
"Updated watchdog interval: %ds -> %ds", old_watchdog, new_watchdog
)
if self._remove_watchdog: # active cycle: cancel and re-register at the new cadence
self._stop_watchdog()
self._start_watchdog()
# RESTORE STATE (only if recent enough, otherwise treat as stale)
await self._attempt_state_restoration()
@@ -3218,8 +3318,24 @@ class WashDataManager:
):
return
# Track observed power readings for learning
self.learning_manager.process_power_reading(power, now, self._last_reading_time)
# Track observed power readings for learning - only while a cycle is
# active (#394). An appliance is idle ~98% of the time; running the 5-min
# auto-tune pass and training the sample-interval cadence model on the
# standby heartbeat is constant background work (a store rewrite every few
# minutes) that buys nothing AND skews every operational suggestion, since
# the idle publish-on-change heartbeat is not the in-cycle sampling
# cadence those suggestions are sized from. The detector below still
# receives EVERY reading, so the next cycle's start is never missed - only
# the learning call is gated.
if self.detector.state in (
STATE_STARTING,
STATE_RUNNING,
STATE_PAUSED,
STATE_ENDING,
):
self.learning_manager.process_power_reading(
power, now, self._last_reading_time
)
self._last_reading_time = now
self._last_real_reading_time = now # Track real update
self._current_power = power
@@ -3635,6 +3751,20 @@ class WashDataManager:
if not self._last_reading_time:
return
# Refresh the remaining-time / progress estimate on the watchdog cadence
# (sampling-derived: max(30, 2*sampling+1)s), independently of incoming power
# events. A publish-on-change plug emits nothing during a flat low-power tail
# (e.g. a dishwasher's ~30 min drying phase at 0 W), so the event-driven
# _update_remaining_only never runs and the displayed countdown freezes at
# whatever value it last showed. The estimate is wall-clock based
# (net_elapsed_seconds), so this tick advances it correctly with zero new
# readings; it no-ops until a profile is matched. Kept ahead of the
# keepalive/force-end branches below so even a verified-pause drying tail
# (which skips those branches) still ticks down.
if self.detector.state in (STATE_RUNNING, STATE_PAUSED, STATE_ENDING):
self._update_remaining_only()
self._notify_update()
time_since_any_update = (now - self._last_reading_time).total_seconds()
# Calculate time since REAL update (if available, else fallback to any update)
@@ -6742,6 +6872,9 @@ class WashDataManager:
current_duration,
profile_name,
self._logger,
quiet_threshold_w=float(
getattr(self.detector.config, "stop_threshold_w", 0.0) or 0.0
),
)
def _notify_update(self) -> None:
+1 -1
View File
@@ -21,5 +21,5 @@
"requirements": [
"numpy"
],
"version": "0.5.4"
"version": "0.5.5"
}
+2 -83
View File
@@ -1,84 +1,3 @@
# WashData ML subsystem (experimental, gated)
# WashData ML Subsystem
Compact, **NumPy-only** models plus the runtime that trains and consumes them.
No new dependencies (NumPy is already in `manifest.json`). Everything here is
gated by flags in `const.py` and is inert until enabled, so the proven
detection/matching/ETA code paths are unchanged by default.
## Feature flags (const.py)
- `SHOW_ML_LAB` - show the ML Lab panel tab (shadow-mode comparison + review).
- `ENABLE_ML_SUGGESTIONS` - surface ML-calibrated setting suggestions alongside
the classic ones (`MLSuggestionEngine`).
- `ENABLE_ML_TRAINING` - allow the scheduled/manual on-device training loop.
- `CONF_ENABLE_ML_MODELS` (per-device option) - opt-in gate (via
`ml_models_enabled(options)`) for feeding ML signals into runtime decisions;
default off so callers keep existing behavior. (No runtime consumer wires this
yet - the live ML paths below run under their own flags.)
## What ships here
- `promoted_manifest.json` + `<name>_model.py` - the embedded **baseline** models
(the broad-corpus models trained offline in `/root/ml_washdata`). Each module
is self-contained and exposes `score()`, `predict()`, `FEATURE_COLUMNS`,
`THRESHOLD`, `MODEL_METRICS`. `<name>_feature_contract.json` documents the live
data each feature comes from; `<name>_parity.json` are golden feature→score
cases the tests assert against.
- `feature_extraction.py` - NumPy-only runtime feature extractors
(`latest_end_event_features`, `live_match_features`, `quality_features`,
`profile_expectation`, energy integration) matching the models' `FEATURE_COLUMNS`.
- `engine.py` - `resolve_scorer(capability, store)`, the single bridge that
returns a **classifier** scoring callable preferring an on-device trained spec
over the embedded baseline (`"on_device"` vs `"baseline"`); `resolve_regressor(
capability, store)` is its **regression** twin for `standardized_linear` heads
that have no shipped baseline (returns `(None, None)` until one is promoted),
plus `ml_models_enabled` (opt-in gate) and `available_models` (manifest provenance).
- `trainer.py` - NumPy-only training for two spec kinds: logistic classifiers
(`fit_logistic`, `select_threshold`, `binary_metrics`, `auc`, `build_spec`/
`score_spec` - byte-compatible with the embedded `score()` math) and ridge
**regressors** (`fit_ridge`, `regression_metrics`, `build_regression_spec`/
`predict_value_spec` - standardized features + standardized target).
- `training_task.py` - on-device orchestration: derives labels from the device's
own cycles (end events from trace geometry; quality from status + ML-Lab review
labels; live_match from match-ranking-history snapshots), synthesises
completion-fraction examples for the regression capabilities, trains, and
promotes a classifier only when its held-out AUC is within margin of the
baseline (a regressor only when its held-out MAE beats the naive elapsed/
expected projection).
- `matching_tuner.py` - `tune_matching_config(cycles)`: NumPy-only, executor-safe
leave-one-out tuning of the matcher's bounded scoring weights (`corr_weight`,
`duration_weight`, `energy_weight`, `dtw_ensemble_w`) over the device's own
labelled cycles. Same promotion discipline as the models (gate on a held-out
split by a margin); it only ever changes the emphasis between shape/level/energy,
never structural matching behaviour.
Models (all standardized-logistic; only models that beat their baseline are shipped):
- `hybrid_curve_quality_model` - P(finished cycle is a problem).
- `live_match_commit_model` - P(top-1 live program match is correct).
- `cycle_end_detector_model` - P(a low-power event is the true end vs a pause).
(No regression baseline is shipped: the `remaining_time` and `total_energy`
completion-fraction regressors did not beat the `expected_duration - elapsed`
heuristic on the broad corpus, so they stay inert until on-device training
promotes a per-device spec that beats that naive projection.)
## How trained models reach inference
`resolve_scorer(capability, store)` is used by the ML Lab shadow comparison
(`ws_api._compute_ml_comparison`) and by `MLSuggestionEngine`. If the profile
store holds an on-device spec for that capability (trained by `training_task` and
persisted under `ml_model_versions`), it is used; otherwise the embedded baseline
module is used. The shipped baseline is a broad-corpus model - per-user accuracy
gains come from on-device training, not from replacing the baseline.
## Regenerating the embedded baseline (offline lab only)
```bash
cd /root/ml_washdata
./ml.sh experiment # retrain + verify the determinism gate
python promote_to_integration.py --target <this directory> # reads output/promoted/
```
`promote_to_integration.py` refuses to copy any model whose encode/decode round
trip is not deterministic. On-device training never touches these baseline files;
it writes trained specs into the profile store instead.
Documentation has moved to the [ML Subsystem wiki page](https://github.com/3dg1luk43/ha_washdata/wiki/ML-Subsystem).
@@ -24,6 +24,7 @@ from .engine import (
CONF_ENABLE_ML_MODELS,
available_models,
ml_models_enabled,
preload_models,
resolve_regressor,
resolve_scorer,
)
@@ -32,6 +33,7 @@ __all__ = [
"CONF_ENABLE_ML_MODELS",
"available_models",
"ml_models_enabled",
"preload_models",
"resolve_regressor",
"resolve_scorer",
]
+103 -24
View File
@@ -39,7 +39,7 @@ import importlib
import json
import logging
from pathlib import Path
from typing import Mapping
from typing import Any, Mapping
_LOGGER = logging.getLogger(__name__)
@@ -52,6 +52,73 @@ _MODEL_MODULES = {
"end": "cycle_end_detector_model",
}
# Modules the live ML paths import lazily besides the baselines themselves.
_SIBLING_MODULES = ("trainer", "feature_extraction")
# Imported baseline model modules, keyed by module name. Importing a module is a
# blocking call Home Assistant forbids inside the event loop, and every
# resolve_scorer() consumer (live matching, end detection, quality gating) runs
# there - so the modules are imported once from an import executor at setup
# (:func:`preload_models`) and every later resolution is a dict lookup. A failed
# import is cached as ``None`` so a broken install warns once instead of retrying
# the import on every inference.
_MODULE_CACHE: dict[str, object | None] = {}
def _load_model_module(module_name: str) -> Any | None:
"""Return the embedded model module, importing it at most once.
Safe to call from the event loop *after* :func:`preload_models` has run (the
import is then already satisfied from ``sys.modules``); the first call should
happen in an executor thread.
"""
if module_name in _MODULE_CACHE:
return _MODULE_CACHE[module_name]
try:
module = importlib.import_module(f"{__package__}.{module_name}")
except Exception as exc: # noqa: BLE001 - a missing model must not break setup
_LOGGER.warning(
"Failed to load embedded model module %r: %s", module_name, exc
)
module = None
_MODULE_CACHE[module_name] = module
return module
def _sibling_attr(module_name: str, attr: str) -> Any | None:
"""Fetch ``attr`` from an embedded sibling module via the cache, or None.
Resolution paths run in the event loop, so they must never re-import: this hits
the ``_MODULE_CACHE`` warmed by :func:`preload_models` (which stores ``None`` on a
failed import). A missing module or attribute returns None, and the caller falls
back to the baseline / inert path rather than triggering a blocking loop import.
"""
module = _load_model_module(module_name)
return getattr(module, attr, None) if module is not None else None
def preload_models() -> None:
"""Import everything the live ML paths touch. Call from an executor thread.
``resolve_scorer`` / ``resolve_regressor`` are called from the event loop, so
the imports they need (the embedded baselines plus ``trainer`` /
``feature_extraction``) must already be in ``sys.modules`` by then - Home
Assistant flags a blocking ``importlib.import_module`` in the loop (issue
#328). Also warms the manifest cache, which reads a file. Never raises;
idempotent, so calling it once per config entry is cheap.
"""
for module_name in _MODEL_MODULES.values():
_load_model_module(module_name)
# Cache the siblings too (module-or-None), so a failed import is recorded once
# here and the event-loop resolvers read it from the cache instead of retrying
# a blocking import (issue #328).
for sibling in _SIBLING_MODULES:
_load_model_module(sibling)
# No guard needed: available_models() carries its own outer try/except and caches
# [] on every failure path, so it cannot raise here (and a try/except/pass around it
# would be unreachable code that Ruff flags as S110/SIM105).
available_models()
def ml_models_enabled(options: Mapping[str, object] | None) -> bool:
"""True when the user has opted into experimental ML models."""
@@ -73,20 +140,16 @@ def resolve_scorer(capability: str, store: object | None):
def _baseline():
"""Resolve the shipped embedded baseline scorer for this capability.
Kept as a lazily-invoked helper so the baseline module is only imported
when the on-device spec is absent *or* fails at call time - preserving the
original "baseline only loaded when needed" semantics.
Kept as a lazily-invoked helper so the baseline module is only looked up
when the on-device spec is absent *or* fails at call time. The lookup hits
the module cache warmed by :func:`preload_models`, so no import happens in
the event loop.
"""
module_name = _MODEL_MODULES.get(capability)
if module_name is None:
return (None, None)
try:
module = importlib.import_module(f"{__package__}.{module_name}")
except Exception as exc: # noqa: BLE001
_LOGGER.warning(
"Failed to load embedded baseline for capability %r: %s",
capability, exc,
)
module = _load_model_module(module_name)
if module is None:
return (None, None)
def _baseline_score(feats, _m=module):
@@ -125,7 +188,7 @@ def resolve_scorer(capability: str, store: object | None):
module_name = _MODEL_MODULES.get(capability)
if module_name is not None:
try:
_bm = importlib.import_module(f"{__package__}.{module_name}")
_bm = _load_model_module(module_name)
_expected = list(getattr(_bm, "FEATURE_COLUMNS", []))
_stored = list(spec.get("feature_columns") or [])
if _expected and _stored and _stored != _expected:
@@ -138,7 +201,9 @@ def resolve_scorer(capability: str, store: object | None):
except Exception: # noqa: BLE001 - schema check must not break inference
pass
from .trainer import score_spec
score_spec = _sibling_attr("trainer", "score_spec")
if score_spec is None:
return _baseline()
def _on_device_score(feats, _s=spec):
# A malformed / dimensionally-incompatible promoted spec must
@@ -189,8 +254,8 @@ def resolve_regressor(capability: str, store: object | None):
if isinstance(spec, dict) and spec.get("kind") == "standardized_linear":
# Feature-column schema guard for regression specs.
try:
from .feature_extraction import PROGRESS_FEATURE_COLUMNS
_expected_r = list(PROGRESS_FEATURE_COLUMNS)
_prog_cols = _sibling_attr("feature_extraction", "PROGRESS_FEATURE_COLUMNS")
_expected_r = list(_prog_cols or [])
_stored_r = list(spec.get("feature_columns") or [])
if _expected_r and _stored_r and _stored_r != _expected_r:
_LOGGER.warning(
@@ -202,7 +267,9 @@ def resolve_regressor(capability: str, store: object | None):
except Exception: # noqa: BLE001 - schema check must not break inference
pass
from .trainer import predict_value_spec
predict_value_spec = _sibling_attr("trainer", "predict_value_spec")
if predict_value_spec is None:
return (None, None)
def _on_device_predict(feats, _s=spec):
# A malformed / incompatible promoted regression spec must never
@@ -240,14 +307,26 @@ def available_models() -> list[dict[str, object]]:
global _MANIFEST_MODELS_CACHE
if _MANIFEST_MODELS_CACHE is not None:
return _MANIFEST_MODELS_CACHE
manifest = Path(__file__).resolve().parent / "promoted_manifest.json"
if not manifest.exists():
return []
# Outer guard so EVERY failure caches a result: an unhandled exception here (from
# warm-up in preload_models, whose caller swallows it) would leave the cache cold,
# and the next event-loop caller would retry Path.exists()/read_text() - re-creating
# the blocking-call warning preload exists to prevent (#328).
try:
payload = json.loads(manifest.read_text(encoding="utf-8"))
except (OSError, ValueError):
return []
models = payload.get("models")
result = models if isinstance(models, list) else []
manifest = Path(__file__).resolve().parent / "promoted_manifest.json"
# A missing manifest is cached as [] too: this is a shipped file that cannot
# appear at runtime, and the read is a blocking open() some callers make on
# the event loop.
if not manifest.exists():
result: list[dict[str, object]] = []
else:
payload = json.loads(manifest.read_text(encoding="utf-8"))
# A manifest decoding to a list/scalar would make .get() raise; keep only
# dict model entries so the return honours its list[dict] contract even for
# a malformed manifest like {"models": [null]}.
models = payload.get("models") if isinstance(payload, dict) else None
result = [m for m in models if isinstance(m, dict)] if isinstance(models, list) else []
except Exception as exc: # noqa: BLE001 - never raise / never leave the cache cold
_LOGGER.debug("Could not read the promoted model manifest (%s); caching empty", exc)
result = []
_MANIFEST_MODELS_CACHE = result
return result
@@ -34,7 +34,6 @@ Label sources (no manual labelling required to start):
"""
from __future__ import annotations
import importlib
import logging
from typing import Any
@@ -542,11 +541,14 @@ def _holdout_split(
def _embedded_module(capability: str):
"""Embedded baseline module for a capability, via the shared engine cache."""
module_name = _CAPABILITIES.get(capability, (None, None))[0]
if module_name is None:
return None
try:
return importlib.import_module(f"{__package__}.{module_name}")
from .engine import _load_model_module
return _load_model_module(module_name)
except Exception: # pylint: disable=broad-exception-caught
return None
+79 -12
View File
@@ -54,6 +54,7 @@ from .const import (
CONF_ANTI_WRINKLE_EXIT_POWER,
CONF_ANTI_WRINKLE_IDLE_TIMEOUT,
CONF_DISHWASHER_END_SPIKE_QUIET_RELEASE,
CONF_SMART_TERMINATION_DURATION_RATIO,
CONF_ANTI_WRINKLE_MAX_DURATION,
CONF_ANTI_WRINKLE_MAX_POWER,
CONF_COMPLETION_MIN_SECONDS,
@@ -115,7 +116,11 @@ from .const import (
TerminationReason,
)
from .cycle_detector import CycleDetector, CycleDetectorConfig
from .profile_store import _ambiguity_from_candidates, decompress_power_data
from .profile_store import (
_ambiguity_from_candidates,
_match_prefix_ambiguity,
decompress_power_data,
)
_LOGGER = logging.getLogger(__name__)
@@ -168,6 +173,7 @@ _OVERRIDE_FIELD_MAP: dict[str, tuple[str, Callable[[Any], Any]]] = {
CONF_ANTI_WRINKLE_EXIT_POWER: ("anti_wrinkle_exit_power", float),
CONF_ANTI_WRINKLE_IDLE_TIMEOUT: ("anti_wrinkle_idle_timeout", float),
CONF_DISHWASHER_END_SPIKE_QUIET_RELEASE: ("dishwasher_end_spike_quiet_release", float),
CONF_SMART_TERMINATION_DURATION_RATIO: ("smart_termination_duration_ratio", float),
CONF_OFF_DELAY: ("off_delay", int),
CONF_MIN_OFF_GAP: ("min_off_gap", int),
CONF_COMPLETION_MIN_SECONDS: ("completion_min_seconds", int),
@@ -411,13 +417,34 @@ def _build_match_snapshots(
snapshots: list[dict[str, Any]] = []
try:
data = getattr(store, "_data", {}) or {}
profiles = data.get("profiles", {}) or {}
# Include imported reference cycles: an import-only profile samples from
# reference_cycles, so without them it would be dropped as a candidate and
# the Playground auto-detect would never match a downloaded profile.
past = data.get("past_cycles", []) or []
refs = data.get("reference_cycles", []) or []
by_id = {c.get("id"): c for c in (list(past) + list(refs)) if isinstance(c, dict)}
# Snapshot the profiles dict before iterating: this runs in an executor thread
# (ws_api dispatches _build_match_snapshots via async_add_executor_job) while the
# event loop may add/remove a profile (cycle-end creation, GC, auto-label), and a
# live `.items()` walk would raise "dictionary changed size during iteration" -
# the same race get_export_inventory was moved on-loop to avoid. dict() is a cheap
# shallow copy of the top-level mapping (values are read-only here). iter_evidence_
# cycles() below returns a fresh list, so its .extend() is already snapshot-safe.
profiles = dict(data.get("profiles", {}) or {})
# Include every cycle the live matcher would consider, via the store's own
# evidence view: an import-only profile samples from reference_cycles or
# backfill_cycles, so a snapshot pool built from past_cycles alone would drop it
# as a candidate and the Playground's auto-detect would never match a downloaded
# or backfilled profile - silently reporting it as unmatched. Reading the same
# gated view the matcher reads also keeps the sandbox honest when the user has
# excluded a category from shaping profiles.
try:
pool = store.iter_evidence_cycles()
except Exception: # pylint: disable=broad-exception-caught
# Older store without the evidence view: fall back to the raw lists. Include
# backfill_cycles too (the evidence view does), else a profile whose sample
# lives only in imported history has no snapshot and the sim reports it
# unmatched though live matching can use it.
pool = (
list(data.get("past_cycles", []) or [])
+ list(data.get("reference_cycles", []) or [])
+ list(data.get("backfill_cycles", []) or [])
)
by_id = {c.get("id"): c for c in pool if isinstance(c, dict)}
for name, profile in profiles.items():
if not isinstance(profile, dict):
continue
@@ -437,6 +464,11 @@ def _build_match_snapshots(
"name": name,
"avg_duration": float(avg_dur),
"sample_power": [p for _, p in sample_p],
# The trace's own time span, which is NOT avg_duration (a trimmed
# mean across cycles). `analysis._prefix_point_count` converts
# elapsed time to an index with it, so omitting it made the sim
# truncate the prefix at a different point than production.
"sample_span_s": float(sample_p[-1][0] - sample_p[0][0]),
}
)
except Exception as exc: # pylint: disable=broad-exception-caught
@@ -872,10 +904,17 @@ class _DetailSim:
members = self.group_members.get(gkey, [])
if members and self.store is not None:
try:
member_name, _, _ = self.store._stage5_pick_member( # noqa: SLF001
member_name, _, member_dur = self.store._stage5_pick_member( # noqa: SLF001
list(powers), duration, members, self.member_snaps or {}
)
candidates[0] = dict(candidates[0], name=member_name)
# Carry the member's duration as well, exactly as
# `async_match_profile` relabels the winner: leaving the group's
# aggregate duration here fed the wrong expected value to the
# detector AND to the #364 prefix guard below.
resolved = dict(candidates[0], name=member_name)
if member_dur:
resolved["profile_duration"] = float(member_dur)
candidates[0] = resolved
except Exception: # pylint: disable=broad-exception-caught
pass
best = candidates[0]
@@ -915,7 +954,31 @@ class _DetailSim:
# The DETECTOR still receives the RAW top-1, so detection / smart-termination
# behaviour is byte-identical to before this reporting change.
return (raw_name, raw_conf, raw_expected, None, False, bool(is_ambiguous))
# Elements 7-9 (#364): without them the prefix-landscape and power-plausibility
# guards were never exercised in a simulation, so the exact failure the
# Playground exists to reproduce was invisible here.
full_shape_hit, prefix_fit_hit = _match_prefix_ambiguity(candidates, raw_expected)
# Guard the store call like iter_evidence_cycles above: on an older store or a
# partial test double without profile_tail_power the AttributeError would
# bubble through _try_profile_match, which drops the match at debug - so EVERY
# match in the sim would be silently reported as unmatched.
tail_power = None
if self.store is not None and raw_name:
try:
tail_power = self.store.profile_tail_power(raw_name)
except Exception: # pylint: disable=broad-exception-caught
tail_power = None
return (
raw_name,
raw_conf,
raw_expected,
None,
False,
bool(is_ambiguous),
bool(full_shape_hit or prefix_fit_hit),
bool(full_shape_hit),
tail_power,
)
def _sample(self, ts: datetime) -> None:
if not self.compute_series:
@@ -947,7 +1010,10 @@ class _DetailSim:
phase_result = None
if len(trace) >= 10 and program != "detecting...":
phase_result = progress_mod.estimate_phase_progress(
self.store, trace, offset, program
self.store, trace, offset, program,
quiet_threshold_w=float(
getattr(self.detector.config, "stop_threshold_w", 0.0) or 0.0
),
)
ml_pct = progress_mod.ml_progress_percent(
self.store, self.options, matched_dur, trace, program, self._end_exp_fn
@@ -1356,6 +1422,7 @@ def _sim_config_summary(config: CycleDetectorConfig) -> dict[str, Any]:
"anti_wrinkle_exit_power": getattr(config, "anti_wrinkle_exit_power", None),
"anti_wrinkle_idle_timeout": getattr(config, "anti_wrinkle_idle_timeout", None),
"dishwasher_end_spike_quiet_release": getattr(config, "dishwasher_end_spike_quiet_release", None),
"smart_termination_duration_ratio": getattr(config, "smart_termination_duration_ratio", None),
}
+496 -130
View File
@@ -58,11 +58,19 @@ from .const import (
SHAREABLE_SETTING_KEYS,
SMART_TERM_LANDSCAPE_RATIO,
SMART_TERM_LANDSCAPE_MIN_SHAPE,
SMART_TERM_PREFIX_MARGIN,
SMART_TERM_PREFIX_MIN_RATIO,
SMART_TERM_PREFIX_MIN_SHAPE,
SMART_TERM_TAIL_WINDOW_FRAC,
STORAGE_KEY,
STORAGE_VERSION,
DEFAULT_MAX_PAST_CYCLES,
DEFAULT_MAX_FULL_TRACES_PER_PROFILE,
DEFAULT_MAX_FULL_TRACES_UNLABELED,
EVIDENCE_BACKFILL_CYCLES,
EVIDENCE_REAL_CYCLES,
EVIDENCE_REFERENCE_CYCLES,
PROFILE_EVIDENCE_SOURCES,
DEFAULT_DTW_BANDWIDTH,
)
from .features import compute_signature
@@ -106,6 +114,15 @@ _TRIM_SNAP_TOLERANCE_S = 1.0
JSONDict: TypeAlias = dict[str, Any]
CycleDict: TypeAlias = dict[str, Any]
# Label sources that mean "the matcher guessed this", as opposed to a user confirming it.
# Consulted before overwriting a label, so the original guess is preserved exactly once.
# `auto_label_backfill` is the #344 import's own marker: an auto-labelled backfilled cycle
# feeds its profile's envelope immediately, so a wrong guess shifts what later cycles match
# against and has to stay distinguishable from a confirmed label.
_AUTO_LABEL_SOURCES = (
"auto_match", "auto_label_post", "auto_label_service", "auto_label_backfill",
)
def _is_recorded_cycle(cycle: dict[str, Any]) -> bool:
"""True when a cycle was produced by the manual recorder.
@@ -346,6 +363,12 @@ class MatchResult:
is_confident_mismatch: bool = False
mismatch_reason: str | None = None
is_prefix_ambiguous: bool = False
# The LEGACY (#288-only, full-envelope shape) half of the verdict above.
# `is_prefix_ambiguous` is widened by #364's prefix scoring, which is safe for
# the ENDING Smart-Termination gate (a false fire only delays the finish) but
# NOT for the anti-crease finalize, where blocking can re-hang a cycle the way
# #296 described. That consumer reads this narrower flag instead.
is_prefix_ambiguous_full_shape: bool = False
def to_dict(self) -> dict[str, Any]:
"""Convert to dictionary with JSON-serializable types, excluding heavy arrays."""
@@ -836,6 +859,15 @@ class WashDataStore(Store[JSONDict]):
_LOGGER.info("Migrating storage from v%s to v11 (phase-profile cache marker)",
old_major_version)
if old_major_version < 12:
# Cycles recovered from raw power history that predates the integration
# (issue #344) get their own list. They are auto-detected and unverified, so
# they belong in neither past_cycles (lifetime stats, ML training labels, the
# feedback queue, retention eviction) nor reference_cycles (curated
# community-store templates, golden by construction). Additive + idempotent.
_LOGGER.info("Migrating storage from v%s to v12", old_major_version)
old_data.setdefault("backfill_cycles", [])
return old_data
def _ambiguity_from_candidates(candidates: list[dict]) -> tuple[float, bool]:
@@ -851,6 +883,67 @@ def _ambiguity_from_candidates(candidates: list[dict]) -> tuple[float, bool]:
return margin, margin < MATCH_AMBIGUITY_MARGIN
def _match_prefix_ambiguity(
candidates: list[dict], best_duration: float
) -> tuple[bool, bool]:
"""``(full_shape_hit, prefix_fit_hit)`` for the prefix-landscape guard.
Both terms answer the same question - "might this trace be a *prefix* of a
longer programme rather than a complete short one?" - by two different routes,
and either one blocks Smart Termination:
* ``full_shape_hit`` (#288, unchanged): a non-winning candidate is at least
``SMART_TERM_LANDSCAPE_RATIO`` longer than the winner and still scored
``SMART_TERM_LANDSCAPE_MIN_SHAPE`` against its **full** envelope.
* ``prefix_fit_hit`` (#364): a longer candidate's score against its curve
**truncated to the elapsed duration** (``prefix_score``, computed in
``analysis.annotate_prefix_scores``) beats the winner's own score by
``SMART_TERM_PREFIX_MARGIN``. The margin is the load-bearing term - it is
scale-free, and asks whether the longer programme explains the trace
materially better than the short one does. The absolute floor only rejects
candidates that fit nothing.
The full-envelope term alone has three structural false negatives on real
devices (see the #364 block in const.py); the prefix term exists because a
trace part-way through a longer programme cannot score well against that
programme's whole curve. Returned separately because the widened verdict is
only safe for the ENDING gate - see ``MatchResult.is_prefix_ambiguous_full_shape``.
Pure function, no I/O. ``prefix_score`` absent (Stage 4 skipped, a mocked
executor, an older snapshot) degrades to the legacy term alone, so this can
never fire *less* often than the #288 predicate did.
"""
if best_duration <= 0 or len(candidates) < 2:
return False, False
# Compare against the winner's SHAPE score, not its blended final score: prefix_score
# is a shape-scale value (Stage-2 + Stage-3, no Stage-4 duration/energy agreement), so
# measuring the margin against the blended score mixed scales and made 0.15 too strict.
# Fall back to the blended score only when shape_score is absent (older snapshot).
_best_shape = candidates[0].get("shape_score")
best_score = float(
(_best_shape if _best_shape is not None else candidates[0].get("score")) or 0.0
)
full_shape_hit = False
prefix_fit_hit = False
for cand in candidates[1:]:
prof_dur = float(cand.get("profile_duration") or 0)
if prof_dur > best_duration * SMART_TERM_LANDSCAPE_RATIO and float(
cand.get("shape_score", cand.get("score", 0))
) >= SMART_TERM_LANDSCAPE_MIN_SHAPE:
full_shape_hit = True
prefix_score = cand.get("prefix_score")
if (
prefix_score is not None
and prof_dur > best_duration * SMART_TERM_PREFIX_MIN_RATIO
and float(prefix_score) >= SMART_TERM_PREFIX_MIN_SHAPE
and float(prefix_score) >= best_score + SMART_TERM_PREFIX_MARGIN
):
prefix_fit_hit = True
if full_shape_hit and prefix_fit_hit:
break
return full_shape_hit, prefix_fit_hit
# ── Selective export/import taxonomy ────────────────────────────────────────────
# One canonical description of the store's top-level data kinds, grouped into the
# user-facing categories offered by the export/import wizard. A single walker
@@ -1071,6 +1164,8 @@ def unwrap_import_payload(payload: Any) -> tuple[dict[str, Any], dict[str, Any]]
data_dict["past_cycles"] = []
if not isinstance(data_dict.get("reference_cycles"), list):
data_dict["reference_cycles"] = []
if not isinstance(data_dict.get("backfill_cycles"), list):
data_dict["backfill_cycles"] = []
data_dict.setdefault("envelopes", {})
fingerprint = payload.get("device_fingerprint")
@@ -1228,6 +1323,10 @@ class ProfileStore:
# from the device type via analysis.stage4_energy_mode. Default "mean"
# keeps behaviour byte-identical until wired.
self.energy_mode: str = "mean"
# Which cycle categories may shape a profile (see CONF_PROFILE_EVIDENCE_SOURCES).
# Pushed in by the manager from entry options, the way energy_mode is; the store
# has no access to them itself. Defaults to all three, i.e. pre-setting behaviour.
self._evidence_sources: tuple[str, ...] = tuple(PROFILE_EVIDENCE_SOURCES)
self._save_debug_traces = save_debug_traces
# Cache for resampled sample segments: key=(cycle_id, dt)
@@ -1258,6 +1357,8 @@ class ProfileStore:
"profiles": {},
"past_cycles": [],
"reference_cycles": [], # Imported store cycles: envelope/matcher only, never usage stats
"backfill_cycles": [], # Cycles recovered from raw history (#344): unverified,
# envelope/matcher only, never stats/ML/shareable
"envelopes": {}, # Cached statistical envelopes per profile
"auto_adjustments": [], # Log of automatic setting changes
"suggestions": {}, # Suggested settings (do NOT change user options)
@@ -1731,6 +1832,96 @@ class ProfileStore:
return cast(list[CycleDict], raw)
return []
def get_backfill_cycles(self) -> list[CycleDict]:
"""Return the cycles recovered from raw power history (issue #344).
A third list, deliberately neither of the other two. Like ``reference_cycles``
these shape the envelope and can serve as a matching template once labelled, and
never touch usage/energy/count stats. Unlike them they are **not** curated: they
were auto-detected by replaying a history export, nothing has verified them, so
they are never golden, never shareable, and never training data.
"""
raw = self._data.setdefault("backfill_cycles", [])
if isinstance(raw, list):
return cast(list[CycleDict], raw)
return []
def iter_stored_cycles(self) -> list[CycleDict]:
"""Every stored cycle, from all three lists.
The single source for "find a cycle by id" and "is this id still real?". Profile
garbage collection and sample repair delete a profile whose ``sample_cycle_id``
resolves to nothing, so a read path that forgets one of the lists silently
destroys an import-only profile. Route those lookups through here rather than
open-coding the union.
"""
return [
*self.get_past_cycles(),
*self.get_reference_cycles(),
*self.get_backfill_cycles(),
]
@property
def evidence_sources(self) -> tuple[str, ...]:
"""Categories currently allowed to shape a profile."""
return self._evidence_sources
@evidence_sources.setter
def evidence_sources(self, value: Any) -> None:
"""Accept a user selection, falling back to all categories.
An empty or unrecognised selection is treated as "all": with nothing allowed
every envelope would be empty and every profile unmatchable, which is worse than
ignoring the setting. Unknown names are dropped rather than trusted.
"""
wanted = tuple(
name for name in PROFILE_EVIDENCE_SOURCES
if isinstance(value, (list, tuple, set, frozenset)) and name in value
)
if not wanted:
if value:
self._logger.warning(
"Ignoring profile-evidence selection %s: no known category left, "
"falling back to all", value,
)
wanted = tuple(PROFILE_EVIDENCE_SOURCES)
self._evidence_sources = wanted
def iter_evidence_cycles(self) -> list[CycleDict]:
"""Stored cycles the user allows to shape a profile.
The gated twin of :meth:`iter_stored_cycles`. Use this for the envelope, the
matcher's snapshot pool and the matching template - anything that answers "what
does this profile look like". Never use it for a lookup by id or a validity check:
an excluded cycle still exists, and profile garbage collection reading this view
would delete a profile whose only cycles the user had merely stopped trusting.
"""
allowed = self._evidence_sources
out: list[CycleDict] = []
if EVIDENCE_REAL_CYCLES in allowed:
out.extend(self.get_past_cycles())
if EVIDENCE_REFERENCE_CYCLES in allowed:
out.extend(self.get_reference_cycles())
if EVIDENCE_BACKFILL_CYCLES in allowed:
out.extend(self.get_backfill_cycles())
return out
def find_stored_cycle(self, cycle_id: str) -> tuple[CycleDict | None, str]:
"""Locate a cycle by id, returning it with the name of the list holding it.
The origin is what decides capability: ``past`` cycles are fully editable,
``reference`` and ``backfill`` cycles can be labelled but not trimmed or split.
"""
for origin, cycles in (
("past", self.get_past_cycles()),
("reference", self.get_reference_cycles()),
("backfill", self.get_backfill_cycles()),
):
match = next((c for c in cycles if c.get("id") == cycle_id), None)
if match is not None:
return match, origin
return None, ""
def get_shareable_cycles(self) -> list[dict[str, Any]]:
"""Recorded/golden reference cycles eligible to share to the community store.
@@ -2017,6 +2208,7 @@ class ProfileStore:
n = 200
agg_curves: dict[str, list[np.ndarray]] = {}
agg_durs: dict[str, list[float]] = {}
agg_spans: dict[str, list[float]] = {}
member_snaps: dict[str, dict[str, Any]] = {}
out: list[dict[str, Any]] = []
for s in snapshots:
@@ -2031,15 +2223,21 @@ class ProfileStore:
agg_curves.setdefault(g, []).append(
np.interp(np.linspace(0, 1, n), np.linspace(0, 1, arr.size), arr)
)
agg_durs.setdefault(g, []).append(float(s.get("avg_duration") or 0.0))
_dur = float(s.get("avg_duration") or 0.0)
agg_durs.setdefault(g, []).append(_dur)
# Members are resampled onto a normalized 0..1 axis above, so the
# aggregate's own time span is the mean of its members' (#364).
agg_spans.setdefault(g, []).append(float(s.get("sample_span_s") or _dur))
group_members: dict[str, list[str]] = {}
for g, curves in agg_curves.items():
key = f"__group__{g}"
durs = [d for d in agg_durs[g] if d > 0]
spans = [v for v in agg_spans.get(g, []) if v > 0]
out.append({
"name": key,
"avg_duration": float(np.mean(durs)) if durs else 0.0,
"sample_power": np.mean(np.array(curves), axis=0).tolist(),
"sample_span_s": float(np.mean(spans)) if spans else 0.0,
})
group_members[key] = [m for m in member_to_group if member_to_group[m] == g and m in member_snaps]
return out, group_members, member_snaps
@@ -3453,16 +3651,15 @@ class ProfileStore:
profiles: dict[str, dict[str, Any]] = self._data.get("profiles", {}) or {}
cycles: list[dict[str, Any]] = self._data.get("past_cycles", []) or []
ref_cycles: list[dict[str, Any]] = self._data.get("reference_cycles", []) or []
if not profiles or not cycles:
return stats
# Sample validity must recognise imported reference cycles: an import-only
# profile legitimately points its sample at a reference cycle. Without this,
# such a sample looks "missing" and the repair below would steal an unrelated
# unlabeled real cycle into the imported profile.
# Sample validity must recognise imported and backfilled cycles: an import-only
# profile legitimately points its sample at one of those. Without this, such a
# sample looks "missing" and the repair below would steal an unrelated unlabeled
# real cycle into the imported profile.
by_id: dict[str, dict[str, Any]] = {
c["id"]: c for c in list(cycles) + list(ref_cycles) if c.get("id")
c["id"]: c for c in self.iter_stored_cycles() if c.get("id")
}
def newest_unlabeled_with_power_data() -> dict[str, Any] | None:
@@ -3850,13 +4047,10 @@ class ProfileStore:
def cleanup_orphaned_profiles(self) -> int:
"""Remove profiles that reference non-existent cycles.
Returns number of profiles removed."""
# Imported reference cycles are valid sample targets too (an import-only
# profile points its sample there), so include them or such profiles would
# be wrongly deleted as orphans.
cycle_ids = {c["id"] for c in self._data.get("past_cycles", [])}
cycle_ids |= {
c["id"] for c in self._data.get("reference_cycles", []) if c.get("id")
}
# Imported reference cycles and backfilled history cycles are valid sample
# targets too (an import-only profile points its sample at one), so every list
# counts here or such profiles would be wrongly deleted as orphans.
cycle_ids = {c["id"] for c in self.iter_stored_cycles() if c.get("id")}
orphaned: list[str] = []
for name, profile in self._data["profiles"].items():
ref = profile.get("sample_cycle_id")
@@ -4228,7 +4422,7 @@ class ProfileStore:
not chosen). Returns a cycle id, or None if there are no usable cycles.
"""
cands = [
c for c in list(self._data.get("past_cycles", [])) + list(self._data.get("reference_cycles", []))
c for c in self.iter_evidence_cycles()
if c.get("profile_name") == profile_name
and c.get("status") in ("completed", "force_stopped")
and isinstance(c.get("power_data"), list) and len(c["power_data"]) >= 3
@@ -4351,11 +4545,23 @@ class ProfileStore:
and c.get("duration", 0) > 60
]
# Real cycles drive usage stats (energy/count). Imported reference cycles
# additionally shape the curves + matching duration, but never usage stats.
# Real cycles drive usage stats (energy/count). Imported reference cycles and
# backfilled history cycles additionally shape the curves + matching duration,
# but never usage stats.
#
# Which of the three may shape the curve is the user's choice
# (CONF_PROFILE_EVIDENCE_SOURCES); usage stats are not evidence and keep counting
# real cycles either way, so unticking "real cycles" removes them from the curve
# without making the profile claim it has never run.
allowed = self._evidence_sources
real_cycles = _eligible(self._data["past_cycles"])
ref_cycles = _eligible(self._data.get("reference_cycles", []))
shape_cycles = real_cycles + ref_cycles
shape_real = real_cycles if EVIDENCE_REAL_CYCLES in allowed else []
ref_cycles: list[CycleDict] = []
if EVIDENCE_REFERENCE_CYCLES in allowed:
ref_cycles += _eligible(self._data.get("reference_cycles", []))
if EVIDENCE_BACKFILL_CYCLES in allowed:
ref_cycles += _eligible(self._data.get("backfill_cycles", []))
shape_cycles = shape_real + ref_cycles
if not shape_cycles:
if profile_name in self._data.get("envelopes", {}):
@@ -4721,6 +4927,64 @@ class ProfileStore:
return 0.0
return float(curves[0][-1])
def profile_tail_power(
self,
profile_name: str,
window_frac: float = SMART_TERM_TAIL_WINDOW_FRAC,
) -> float | None:
"""Mean power (W) a profile draws over the last ``window_frac`` of its own
run, or None when the profile has no usable trace. Never raises.
This is the reference level the Smart-Termination power-plausibility guard
compares the live trailing power against (#364). Both Smart-Termination
paths key on ``elapsed >= 0.98 * expected``; when the matcher has locked onto
a *shorter* look-alike profile that anchor lands mid-wash, and neither path
asks whether the appliance is still working. "Several times what this
programme draws at its own end" is the signal that it is.
Prefers the profile's envelope average curve; falls back to the sample
cycle's raw trace, because a thinly-trained profile (one labelled cycle, so
no envelope) is still a match candidate and would otherwise get no guard at
all. Pure statistics, no ML - same never-raises contract as
``compute_envelope_conformance``.
"""
try:
frac = min(max(float(window_frac), 0.01), 1.0)
curves = self._envelope_time_power(self.get_envelope(profile_name))
if curves and len(curves[0]) >= 2:
env_time, env_power = curves
cutoff = float(env_time[-1]) * (1.0 - frac)
tail = [p for t, p in zip(env_time, env_power) if t >= cutoff]
if tail:
return float(np.mean(tail))
profile = self.get_profiles().get(profile_name)
if not isinstance(profile, dict):
return None
sample_id = profile.get("sample_cycle_id")
if not sample_id:
return None
cycle, _ = self.find_stored_cycle(str(sample_id))
if not cycle:
return None
# Through decompress_power_data, not raw power_data: a legacy cycle stores
# (iso_string, power) pairs, and float() on the ISO string would raise into
# the broad except below, silently leaving the #364 guard inert for that
# profile. The isinstance check does not catch it - [iso_str, power] is a list.
points = decompress_power_data(cycle)
if len(points) < 2:
return None
offsets = [float(pt[0]) for pt in points]
powers = [float(pt[1]) for pt in points]
cutoff = offsets[-1] * (1.0 - frac)
tail = [p for t, p in zip(offsets, powers) if t >= cutoff]
if not tail:
return None
return float(np.mean(tail))
except Exception: # noqa: BLE001
return None
def reference_curve(
self, profile_name: str, n: int = REFERENCE_PROFILE_CURVE_POINTS
) -> JSONDict | None:
@@ -5178,9 +5442,11 @@ class ProfileStore:
current_power_list = current_seg.power.tolist()
# Prepare Snapshots. Imported reference cycles are eligible as matching
# templates alongside real cycles (so an import-only profile can match).
all_cycles = list(self._data["past_cycles"]) + list(self._data.get("reference_cycles", []))
# Prepare Snapshots. Imported reference cycles and backfilled history
# cycles are eligible as matching templates alongside real cycles (so an
# import-only profile can match) - subject to the user's evidence choice, so
# the pool and the envelope always agree about what a profile looks like.
all_cycles = self.iter_evidence_cycles()
# Precompute per-profile lookups ONCE so the loop below is O(profiles),
# not O(profiles x cycles). Rescanning all_cycles with next()/any() for
# every profile made matching quadratic and stalled low-power hosts on
@@ -5259,6 +5525,12 @@ class ProfileStore:
"name": name,
"avg_duration": float(avg_duration),
"sample_power": avg_y,
# True wall-clock span of `sample_power` (#364). NOT the same
# as avg_duration, which prefers target_duration / the
# profile's rolling mean - so index fraction only equals time
# fraction against this. Needed to truncate the curve to an
# elapsed duration for prefix scoring.
"sample_span_s": float(_env_ts_duration or avg_duration),
})
continue
@@ -5301,7 +5573,12 @@ class ProfileStore:
"name": name,
"avg_duration": float(avg_dur),
"sample_power": sample_seg.power.tolist(),
"sample_dt": used_dt
"sample_dt": used_dt,
# True wall-clock span of `sample_power` (#364). _get_cached_sample_segment
# keeps only the LONGEST gap-free segment, so a cycle with an internal
# outage yields a curve covering less than avg_dur - truncating by a
# fraction of avg_dur would then cut the wrong place.
"sample_span_s": float(_seg_ts_duration or avg_dur),
})
if skipped_profiles:
@@ -5396,12 +5673,10 @@ class ProfileStore:
# current trace may be a prefix of that longer program, not a complete
# short cycle. Signal cycle_detector to block Smart Termination; the
# power-based fallback timeout will decide instead.
best_dur = best_duration or 0.0
is_prefix_ambiguous = best_dur > 0 and any(
float(c.get("profile_duration") or 0) > best_dur * SMART_TERM_LANDSCAPE_RATIO
and float(c.get("shape_score", c.get("score", 0))) >= SMART_TERM_LANDSCAPE_MIN_SHAPE
for c in candidates[1:]
full_shape_hit, prefix_fit_hit = _match_prefix_ambiguity(
candidates, best_duration or 0.0
)
is_prefix_ambiguous = full_shape_hit or prefix_fit_hit
return MatchResult(
best_name,
@@ -5413,6 +5688,7 @@ class ProfileStore:
margin,
ranking=candidates[:5], # populate ranking (consumed for training snapshots)
is_prefix_ambiguous=is_prefix_ambiguous,
is_prefix_ambiguous_full_shape=full_shape_hit,
)
async def async_verify_alignment(
@@ -5532,10 +5808,19 @@ class ProfileStore:
async def create_profile(self, name: str, source_cycle_id: str) -> None:
"""Create a new profile from a past cycle."""
cycle = next(
(c for c in self._data["past_cycles"] if c["id"] == source_cycle_id), None
)
"""Create a new profile from a cycle, real or imported.
``reference_cycles`` are searched too: an imported cycle (community store, or a
historical import per issue #344) is a legitimate source for a brand-new profile,
and for a history import it is the *primary* one - the whole point is to name the
programs found in months of past data. Looking only in ``past_cycles`` made
"Label -> Create new profile..." fail outright on those cycles.
The envelope is rebuilt here rather than left for the next match or maintenance
pass, so the profile is usable the moment it is created (mirroring
:meth:`assign_profile_to_cycle`).
"""
cycle, _origin = self.find_stored_cycle(source_cycle_id)
if not cycle:
raise ValueError("Cycle not found")
@@ -5546,36 +5831,29 @@ class ProfileStore:
"sample_cycle_id": source_cycle_id,
}
await self.async_rebuild_envelope(name)
# Save to persist the label
await self.async_save()
@property
def has_real_profiles(self) -> bool:
"""True if at least one stored profile is backed by a real cycle.
"""True if at least one stored profile is backed by a cycle that counts as evidence.
A profile counts as "real" when it has a labelled cycle in ``past_cycles``
OR an imported ``reference_cycle`` (store-adopted templates that the matcher
treats as eligible snapshots see the snapshot builder in async_match). An
import-only install has zero past_cycles but is fully matchable, so it must
pass this gate too, otherwise matching and the setup notifications are
skipped for it entirely.
A profile with no cycle behind it cannot be matched, so this gates matching and
the setup notifications. Imported reference cycles and backfilled history cycles
count: an import-only install has zero `past_cycles` and is still fully matchable.
Evidence-gated, so a profile whose only cycles the user has excluded reads as not
matchable - which is what excluding them means.
"""
profile_names = self._data.get("profiles", {}).keys()
if not profile_names:
return False
assigned = {
c.get("profile_name")
for c in self._data.get("past_cycles", [])
for c in self.iter_evidence_cycles()
if c.get("profile_name")
}
if assigned.intersection(profile_names):
return True
ref_assigned = {
c.get("profile_name")
for c in self._data.get("reference_cycles", [])
if c.get("profile_name")
}
return bool(ref_assigned.intersection(profile_names))
return bool(assigned.intersection(profile_names))
def list_profiles(self) -> list[dict[str, Any]]:
"""List all profiles with metadata."""
@@ -5651,6 +5929,13 @@ class ProfileStore:
"total_cost": total_cost,
"signature_curve": sig_curve,
"is_imported": self.profile_has_reference_cycles(name),
# Cycles recovered from imported history (#344). Reported separately
# from cycle_count, which counts only real observed cycles, so a
# profile built purely from backfilled history does not look empty.
"backfill_count": sum(
1 for c in self.get_backfill_cycles()
if c.get("profile_name") == name
),
}
)
return sorted(profiles, key=lambda p: profile_sort_key(p.get("name", "")))
@@ -5670,7 +5955,7 @@ class ProfileStore:
profile_data: JSONDict = {}
if reference_cycle_id:
cycle = next(
(c for c in self._data["past_cycles"] if c["id"] == reference_cycle_id),
(c for c in self.iter_stored_cycles() if c.get("id") == reference_cycle_id),
None,
)
if cycle:
@@ -5741,12 +6026,9 @@ class ProfileStore:
# Update cycles and feedback if renamed
count = 0
if renamed:
# 1. Update past + imported reference cycles (imports carry profile_name
# 1. Update every stored cycle (imports and backfills carry profile_name
# too; leaving them under the old name orphans them from the matcher).
for cycle in (
list(self._data.get("past_cycles", []))
+ list(self._data.get("reference_cycles", []))
):
for cycle in self.iter_stored_cycles():
if cycle.get("profile_name") == old_name:
cycle["profile_name"] = new_name
count += 1
@@ -5792,13 +6074,11 @@ class ProfileStore:
# Delete profile
del self._data["profiles"][name]
# Handle cycles (past + imported reference; both carry profile_name, so an
# imported cycle would otherwise keep a dangling label for a deleted profile).
# Handle cycles from every list: imported and backfilled cycles carry
# profile_name too, so they would otherwise keep a dangling label for a
# deleted profile.
count = 0
for cycle in (
list(self._data.get("past_cycles", []))
+ list(self._data.get("reference_cycles", []))
):
for cycle in self.iter_stored_cycles():
if cycle.get("profile_name") == name:
if unlabel_cycles:
cycle["profile_name"] = None
@@ -5813,6 +6093,7 @@ class ProfileStore:
"""Clear all profiles, cycle data, and derived state."""
self._data["past_cycles"] = []
self._data["reference_cycles"] = []
self._data["backfill_cycles"] = []
self._data["profiles"] = {}
self._data["envelopes"] = {}
self._data["suggestions"] = {}
@@ -5848,20 +6129,16 @@ class ProfileStore:
) -> None:
"""Assign an existing profile to a cycle. Rebuilds envelope."""
old_profile = None
cycle = next(
(c for c in self._data["past_cycles"] if c["id"] == cycle_id), None
)
if not cycle:
# Imported reference recording (separate list, never in usage stats):
# relabelling just moves which profile's template it seeds.
ref = next(
(c for c in self.get_reference_cycles() if c.get("id") == cycle_id),
None,
)
if ref is not None:
await self._assign_reference_cycle_profile(ref, profile_name)
return
found, origin = self.find_stored_cycle(cycle_id)
if found is None:
raise ValueError(f"Cycle {cycle_id} not found")
if origin != "past":
# An imported store recording or a backfilled history cycle (separate lists,
# never in usage stats): relabelling just moves which profile's template it
# seeds.
await self._assign_reference_cycle_profile(found, profile_name)
return
cycle = found
# Track old profile for envelope rebuild
old_profile = cycle.get("profile_name")
@@ -5872,7 +6149,7 @@ class ProfileStore:
# Preserve original auto-assigned label before first manual relabeling
if profile_name and old_profile and not cycle.get("original_auto_label"):
orig_src = cycle.get("label_source", "")
if orig_src in ("auto_match", "auto_label_post", "auto_label_service"):
if orig_src in _AUTO_LABEL_SOURCES:
cycle["original_auto_label"] = old_profile
# Update cycle
@@ -5899,40 +6176,73 @@ class ProfileStore:
# Trigger smart processing to potentially merge now-labeled cycle
await self.async_smart_process_history()
async def _assign_reference_cycle_profile(
def _relabel_non_real_cycle(
self, ref: CycleDict, profile_name: str | None
) -> None:
"""Reassign an imported reference recording to a different profile.
) -> set[str]:
"""Move a non-real cycle onto a profile, returning the envelopes to rebuild.
The cycle stays in ``reference_cycles`` (out of usage stats); only which
profile envelope it seeds changes. Rebuilds the old and new envelopes.
``profile_name=None`` clears the label (the recording then seeds nothing).
The bookkeeping half of :meth:`_assign_reference_cycle_profile`, split out so a
bulk caller (:meth:`auto_label_cycles`) can apply it to many cycles and then
rebuild and save **once** instead of per cycle - the same batching the real-cycle
path uses, and the difference between one store write and one per imported cycle.
Synchronous and self-contained: it validates the target, moves the label, clears a
stale ``sample_cycle_id`` on the profile the cycle is leaving, and drops that
profile outright when nothing is left in it (mirrors `_delete_non_real_cycle`;
without it a sampleless profile would later be re-populated by sample repair
stealing an unrelated real cycle). Returns the names whose envelope the caller
must rebuild - a profile this dropped is deliberately absent from that set.
"""
if profile_name and profile_name not in self._data.get("profiles", {}):
raise ValueError(f"Profile '{profile_name}' not found. Create it first.")
old_profile = ref.get("profile_name")
ref_id = ref.get("id")
ref["profile_name"] = profile_name if profile_name else None
touched: set[str] = set()
if old_profile and old_profile != profile_name:
# The moved cycle may have been the old profile's sample. Clear that
# stale pointer so the old profile can't resolve the moved trace (now
# another profile's) by id, and drop the old profile if it is now empty
# (mirrors _delete_reference_cycle; prevents repair adopting a real cycle).
op = self._data.get("profiles", {}).get(old_profile)
if op is not None and op.get("sample_cycle_id") == ref_id:
op["sample_cycle_id"] = None
old_has_cycles = any(
c.get("profile_name") == old_profile
for c in list(self._data.get("past_cycles", []))
+ list(self._data.get("reference_cycles", []))
for c in self.iter_stored_cycles()
)
if old_has_cycles:
await self.async_rebuild_envelope(old_profile)
touched.add(old_profile)
else:
self._data.get("profiles", {}).pop(old_profile, None)
self._data.get("envelopes", {}).pop(old_profile, None)
if profile_name:
await self.async_rebuild_envelope(profile_name)
touched.add(profile_name)
return touched
async def _assign_reference_cycle_profile(
self, ref: CycleDict, profile_name: str | None
) -> None:
"""Reassign a non-real cycle - an imported store recording or a backfilled
history cycle - to a different profile.
The cycle stays in its own list (out of usage stats); only which profile envelope
it seeds changes. Rebuilds the old and new envelopes. ``profile_name=None`` clears
the label (the cycle then seeds nothing).
This is the *manual* (user-driven) relabel path, so it stamps provenance exactly
like the real-cycle path in ``assign_profile_to_cycle``: preserve the original
auto-guess once, then mark the label ``manual``. Without the manual stamp a later
``auto_label_cycles(overwrite=True)`` would still see an auto ``label_source`` on a
backfilled cycle and silently overwrite the user's correction.
"""
old_profile = ref.get("profile_name")
# Preserve the original auto-assigned label before the first manual relabel.
if profile_name and old_profile and not ref.get("original_auto_label"):
if ref.get("label_source", "") in _AUTO_LABEL_SOURCES:
ref["original_auto_label"] = old_profile
touched = self._relabel_non_real_cycle(ref, profile_name)
# _relabel_non_real_cycle only moves profile_name (it is shared with the auto
# bulk path, which sets its own source); stamp the manual provenance here.
ref["label_source"] = "manual" if profile_name else None
for name in touched:
await self.async_rebuild_envelope(name)
await self.async_save()
self._logger.info(
"Reassigned imported reference cycle %s to profile '%s'",
@@ -5949,20 +6259,52 @@ class ProfileStore:
overwrite: If True, re-evaluates already labeled cycles.
Returns stats: {labeled: int, relabeled: int, skipped: int, total: int}
Covers **backfilled history cycles** (#344) as well as real ones. Nobody remembers
which wash was Eco 40 six months later, so an import that left dozens of unnamed
cycles to hand-label would be barely better than no import at all. The gate is the
same for both (``confidence >= threshold`` and not ambiguous), but a backfilled
cycle is written through :meth:`_relabel_non_real_cycle` rather than mutated like a
real one, because moving one off a profile has to clear a stale sample pointer and
may leave that profile empty.
A label applied here is stamped ``auto_label_backfill``, distinct from the
real-cycle ``auto_label_service``. That distinction matters: an auto-labelled
backfill cycle immediately feeds its profile's envelope, so a wrong guess shifts
what later cycles match against, and the marker is what makes that recoverable -
by the user or by a later pass - rather than indistinguishable from a confirmed
label.
NB on a fresh install with no profiles there is nothing to match against, so the
real sequence is "hand-label a couple, then auto-label the rest": each label
strengthens the envelope the next batch matches against. There is no
self-matching circularity - with ``overwrite=False`` only unlabelled cycles are
touched, and an unlabelled cycle is in no envelope yet.
"""
stats = {"labeled": 0, "relabeled": 0, "skipped": 0, "total": 0}
cycles = self._data.get("past_cycles", [])
# Filter down if not overwriting
# (cycle, is_backfill) so the write path can differ while the gate does not.
candidates: list[tuple[CycleDict, bool]] = [
*((c, False) for c in self._data.get("past_cycles", [])),
*((c, True) for c in self.get_backfill_cycles()),
]
if not overwrite:
target_cycles = [c for c in cycles if not c.get("profile_name")]
else:
target_cycles = cycles
candidates = [(c, b) for c, b in candidates if not c.get("profile_name")]
stats["total"] = len(target_cycles)
stats["total"] = len(candidates)
# Envelopes are rebuilt once at the end, not per cycle: this is a bulk pass and
# `_assign_reference_cycle_profile`'s per-call rebuild+save would mean one whole
# store write per imported cycle.
touched: set[str] = set()
for cycle, is_backfill in candidates:
# Never overwrite a user's manual label, even with overwrite=True: a manual
# correction is exactly the ground truth this pass should defer to (real and
# non-real alike - the non-real manual relabel now stamps this too).
if cycle.get("label_source") == "manual":
stats["skipped"] += 1
continue
for cycle in target_cycles:
# Reconstruct power data for matching
power_data = decompress_power_data(cycle)
if not power_data or len(power_data) < 10:
@@ -5985,19 +6327,46 @@ class ProfileStore:
for c in (getattr(result, "ranking", []) or [])[:5]
]
label_source = "auto_label_backfill" if is_backfill else "auto_label_service"
def _apply(
target: CycleDict = cycle,
backfill: bool = is_backfill,
match: MatchResult = result,
source: str = label_source,
ranking: list[dict[str, Any]] = ranking_top5,
) -> None:
"""Move the label, then stamp the provenance the mover does not.
`_relabel_non_real_cycle` only moves `profile_name`, so without this
an auto-labelled imported cycle would carry no confidence for the
Cycles list to show and no marker saying the matcher guessed it.
EVERY loop value it reads is bound as a default, not closed over: the
call happens in the same iteration today, but a later change that
defers it (collect the callables, run them after the loop) would
otherwise silently apply the LAST iteration's match to every cycle.
"""
if backfill:
touched.update(
self._relabel_non_real_cycle(target, match.best_profile)
)
else:
target["profile_name"] = match.best_profile
target["match_confidence"] = float(match.confidence)
target["label_source"] = source
if ranking:
target["match_ranking_top5"] = ranking
# If overwriting, check if new match is different and better/valid
if current_label:
if current_label != result.best_profile:
# Preserve original label before first auto-service relabeling
if not cycle.get("original_auto_label"):
orig_src = cycle.get("label_source", "")
if orig_src in ("auto_match", "auto_label_post", "auto_label_service"):
if orig_src in _AUTO_LABEL_SOURCES:
cycle["original_auto_label"] = current_label
cycle["profile_name"] = result.best_profile
cycle["match_confidence"] = float(result.confidence)
cycle["label_source"] = "auto_label_service"
if ranking_top5:
cycle["match_ranking_top5"] = ranking_top5
_apply()
stats["relabeled"] += 1
self._logger.info(
"Relabeled cycle %s: '%s' -> '%s' (confidence: %.2f)",
@@ -6007,11 +6376,7 @@ class ProfileStore:
result.confidence,
)
else:
cycle["profile_name"] = result.best_profile
cycle["match_confidence"] = float(result.confidence)
cycle["label_source"] = "auto_label_service"
if ranking_top5:
cycle["match_ranking_top5"] = ranking_top5
_apply()
stats["labeled"] += 1
self._logger.info(
"Auto-labeled cycle %s as '%s' (confidence: %.2f)",
@@ -6023,6 +6388,11 @@ class ProfileStore:
stats["skipped"] += 1
if stats["labeled"] > 0 or stats["relabeled"] > 0:
# A labelled backfill cycle exists only to shape its profile's envelope, so
# rebuild what changed before saving - otherwise the import accomplishes
# nothing until some unrelated later trigger.
for name in touched:
await self.async_rebuild_envelope(name)
await self.async_save()
# Trigger smart processing after bulk labeling
await self.async_smart_process_history()
@@ -6648,9 +7018,9 @@ class ProfileStore:
initial_len = len(cycles)
cycle_to_delete = next((c for c in cycles if c.get("id") == cycle_id), None)
if not cycle_to_delete:
# Not a real cycle -- it may be an imported store recording, which
# lives in the separate reference_cycles list (never in usage stats).
return await self._delete_reference_cycle(cycle_id)
# Not a real cycle -- it may be an imported store recording or a backfilled
# history cycle, which live in their own lists (never in usage stats).
return await self._delete_non_real_cycle(cycle_id)
profile_name = cycle_to_delete.get("profile_name")
self._data["past_cycles"] = [c for c in cycles if c.get("id") != cycle_id]
@@ -6673,19 +7043,23 @@ class ProfileStore:
return True
return False
async def _delete_reference_cycle(self, cycle_id: str) -> bool:
"""Delete a single imported store recording from ``reference_cycles``.
async def _delete_non_real_cycle(self, cycle_id: str) -> bool:
"""Delete a single imported store recording or backfilled history cycle.
Rebuilds the affected profile's envelope so removing a bad import
immediately stops influencing the matcher template. Returns False when
no reference cycle carries that id.
Rebuilds the affected profile's envelope so removing a bad import immediately
stops influencing the matcher template. Returns False when neither list carries
that id.
"""
refs = cast(list[CycleDict], self._data.get("reference_cycles", []))
cycle = next((c for c in refs if c.get("id") == cycle_id), None)
cycle: CycleDict | None = None
for key in ("reference_cycles", "backfill_cycles"):
items = cast(list[CycleDict], self._data.get(key, []))
cycle = next((c for c in items if c.get("id") == cycle_id), None)
if cycle is not None:
self._data[key] = [c for c in items if c.get("id") != cycle_id]
break
if cycle is None:
return False
profile_name = cycle.get("profile_name")
self._data["reference_cycles"] = [c for c in refs if c.get("id") != cycle_id]
# Clear any profile that sampled this now-deleted reference cycle, mirroring
# the real-cycle path in delete_cycle, so no sample id is left dangling.
for _p_name, p_data in self.get_profiles().items():
@@ -6698,8 +7072,7 @@ class ProfileStore:
# async_repair_profile_samples stealing an unlabeled real cycle into it.
remaining = any(
c.get("profile_name") == profile_name
for c in list(self._data.get("past_cycles", []))
+ list(self._data.get("reference_cycles", []))
for c in self.iter_stored_cycles()
)
if remaining:
await self.async_rebuild_envelope(profile_name)
@@ -6714,16 +7087,9 @@ class ProfileStore:
Returns an empty list if the cycle is not found or has no power data.
"""
cycle = next(
(c for c in self.get_past_cycles() if c.get("id") == cycle_id), None
)
if cycle is None:
# Imported store recordings live in a separate list; the panel opens
# them from the same Cycles table, so look them up here too.
cycle = next(
(c for c in self.get_reference_cycles() if c.get("id") == cycle_id),
None,
)
# Imported and backfilled cycles live in their own lists; the panel opens them
# from the same Cycles table, so all three are searched.
cycle, _origin = self.find_stored_cycle(cycle_id)
if cycle is None:
return []
return decompress_power_data(cycle)
+63 -6
View File
@@ -227,12 +227,21 @@ def estimate_phase_progress(
current_duration: float,
profile_name: str,
logger: logging.Logger | None = None,
quiet_threshold_w: float = 0.0,
) -> tuple[float, float] | None:
"""Estimate cycle progress by analyzing which phase we're in.
Uses cached statistical envelope built from ALL cycles labeled with this
profile, normalized by TIME to account for different sampling rates. Returns
``(progress_pct, variance_watts)`` or ``None`` if estimation fails.
``quiet_threshold_w`` is the detector's own off-noise floor
(``CycleDetectorConfig.stop_threshold_w``, itself derived from the configured
minimum power). A window that never rises above it is *not* the appliance
doing something, so it carries no phase information and the scan declines
rather than guessing (#386); a dead-flat window declines for the same reason
at any power level. The default 0.0 leaves only the flatness rule for callers
that do not know the floor.
"""
logger = logger or _LOGGER
# Get cached envelope (fast - already computed and stored)
@@ -314,6 +323,56 @@ def estimate_phase_progress(
logger.debug("Insufficient data in current window for phase estimation")
return None
# Two window shapes carry no information the scan can align on, and both
# mislocate badly when it tries anyway (#386): the correlation term is dead or
# is noise on the plug's last reported digit, the MAE/bounds terms then score
# every similar stretch of the envelope alike, and the only term left that
# knows the clock is the time penalty - which is capped at 40%.
# * BELOW THE OFF FLOOR. The appliance is not drawing anything the detector
# would call active, so there is nothing to locate. Catches a quiet tail
# whatever jitter the plug puts on its last digit.
# * DEAD FLAT. No shape at any power level, e.g. a steady plateau reported
# by a plug that re-reports unchanged values. Replay says these mislocate
# too (a late offset wins on level alone), and the cost of declining is
# within noise, so a plateau defers to the clock as well.
# Declining hands the caller its linear (clock) estimate, which is what ran
# before phase-aware progress existed.
quiet_w = float(quiet_threshold_w or 0.0)
window_max = float(np.max(current_window_values))
window_flat = float(np.std(current_window_values)) == 0.0
if window_max <= quiet_w or window_flat:
logger.debug(
"Uninformative current window (max=%.2fW, off-floor=%.2fW, flat=%s), "
"skipping phase estimation",
window_max,
quiet_w,
window_flat,
)
return None
# The envelope's trailing all-zero stretch is an artefact of averaging cycles
# that ended at different times (real dishwasher envelopes carry 30+ min of
# it). It is a perfect fit for any quiet window of any length, while the true
# region scores 0 on bounds because the drain pump smears across cycles and
# keeps the envelope's own min above zero - so a near-zero reading is drawn to
# the pad and progress collapses to the 99% clamp (#386). Offsets inside the
# pad are not candidate alignments: the scan stops at the last offset where
# the envelope is still active.
active_offsets = np.flatnonzero(envelope_arrays["max"] > 0.0)
active_len = int(active_offsets[-1]) + 1 if active_offsets.size else 0
# A malformed envelope can carry bands of differing length; never index past
# the shortest of the three the scan slices in lockstep.
active_len = min(
active_len,
len(envelope_arrays["avg"]),
len(envelope_arrays["min"]),
len(envelope_arrays["max"]),
)
scan_n = min(len(time_grid) - 1, active_len)
if scan_n <= 0:
logger.debug("Envelope has no active offsets, cannot estimate phase")
return None
# Slide the current window across the whole envelope grid and keep the
# best-scoring alignment. The scalar form below is the reference; the
# vectorized form computes the identical per-offset score in bulk (the grid is
@@ -325,12 +384,10 @@ def estimate_phase_progress(
b_score = -1.0
b_in_bounds = False
b_tws: float | None = None
for i in range(len(time_grid) - 1):
for i in range(scan_n):
time_window_start = float(time_grid[i])
envelope_window_start = i
envelope_window_end = min(
i + len(current_window_values), len(envelope_arrays["avg"])
)
envelope_window_end = min(i + len(current_window_values), active_len)
if envelope_window_end <= envelope_window_start:
continue
avg_window = envelope_arrays["avg"][envelope_window_start:envelope_window_end]
@@ -383,8 +440,8 @@ def estimate_phase_progress(
avg_arr = envelope_arrays["avg"]
min_arr = envelope_arrays["min"]
max_arr = envelope_arrays["max"]
length = len(avg_arr)
n = len(time_grid) - 1
length = active_len
n = scan_n
if n <= 0 or w == 0:
return _scan_scalar()
+49 -19
View File
@@ -30,7 +30,7 @@ from homeassistant.core import HomeAssistant
from . import store_account
from .const import QC_EDITED, QC_MANUAL, QC_RECORDING
from .store_client import StoreClient, device_id, profile_id, trace_hash
from .store_client import device_id, get_client, profile_id, trace_hash
_LOGGER = logging.getLogger(__name__)
@@ -158,7 +158,10 @@ class StoreBridge:
def __init__(self, hass: Any, profile_store: Any) -> None:
self._hass = hass
self._ps = profile_store
self._client = StoreClient(hass)
# One client for the whole install, not one per appliance: the catalog it reads is
# public and device-agnostic, so a per-bridge client made an N-appliance install
# issue N cold-cache copies of the same brand/device queries. See get_client.
self._client = get_client(hass)
def _fire_download_telemetry(self, cycle_ids: list[str]) -> None:
"""Fire best-effort download/adoption telemetry as a detached background task.
@@ -182,7 +185,12 @@ class StoreBridge:
async def connect(self, refresh_token: str, uid: str, name: str | None) -> dict[str, Any]:
# Validate the refresh token by exchanging it once before persisting.
if not await self._client.ensure_id_token(refresh_token):
# ensure_id_token writes the client-wide _last_error slot on failure, so it
# takes the same lock the upload paths use: otherwise a sign-in failing here
# could overwrite the reason a concurrent share is about to report.
async with self._client.write_lock:
token = await self._client.ensure_id_token(refresh_token)
if not token:
return {"error": "token_invalid"}
await store_account.async_set_account(self._hass, {"refresh_token": refresh_token, "uid": uid, "name": name})
return store_account.get_identity(self._hass)
@@ -204,6 +212,22 @@ class StoreBridge:
brand, appliance_type, model_query=model_query, include_pending=include_pending,
)
async def catalog_entry(self, brand: str, model: str, appliance_type: str) -> dict[str, Any]:
"""The catalog identity of one appliance -- its brand + device documents, resolved
by deterministic id, for the settings form's status badges.
The badges used to be a by-product of the pickers' full brand/device *lists*, which
meant simply opening the Settings tab downloaded the catalog. Two point reads answer
the same question, so the lists are now only fetched when the user actually opens a
picker. Maps the HA device type to the catalog type first.
"""
return await self._client.catalog_entry(brand, model, store_appliance_type(appliance_type))
def refresh_catalog(self) -> dict[str, Any]:
"""Drop the cached catalog so the next read is fresh (panel "refresh" action)."""
self._client.refresh_catalog()
return {"ok": True}
async def get_profiles(self, device_id: str) -> list[dict[str, Any]]:
return await self._client.get_profiles(device_id)
@@ -224,14 +248,16 @@ class StoreBridge:
acct = store_account.get_account(self._hass)
if not acct.get("refresh_token"):
return {"error": "not_connected"}
res = await self._client.confirm_device(acct["refresh_token"], acct.get("uid", ""), device_id)
async with self._client.write_lock: # writes _last_error; see connect()
res = await self._client.confirm_device(acct["refresh_token"], acct.get("uid", ""), device_id)
return res if res else {"error": "confirm_failed"}
async def rate_device(self, device_id: str, rating: int) -> dict[str, Any]:
acct = store_account.get_account(self._hass)
if not acct.get("refresh_token"):
return {"error": "not_connected"}
ok = await self._client.rate_device(acct["refresh_token"], acct.get("uid", ""), device_id, rating)
async with self._client.write_lock: # writes _last_error; see connect()
ok = await self._client.rate_device(acct["refresh_token"], acct.get("uid", ""), device_id, rating)
return {"ok": True} if ok else {"error": "rate_failed"}
# ── import / share (target this device's ProfileStore) ───────────────────────
@@ -293,12 +319,15 @@ class StoreBridge:
downsampled = await self._hass.async_add_executor_job(
_downsample, [[p[0], p[1]] for p in pts]
)
new_id = await self._client.upload_reference_cycle(
acct["refresh_token"], acct.get("uid", ""), acct.get("name"),
meta, downsampled, stats, derive_qc(cyc),
)
if not new_id:
return {"error": "upload_failed", "detail": self._client.last_error()}
# The client is shared install-wide, and last_error() is a single slot, so the
# write and the read that interprets it have to be one critical section.
async with self._client.write_lock:
new_id = await self._client.upload_reference_cycle(
acct["refresh_token"], acct.get("uid", ""), acct.get("name"),
meta, downsampled, stats, derive_qc(cyc),
)
if not new_id:
return {"error": "upload_failed", "detail": self._client.last_error()}
return {"store_cycle_id": new_id}
async def share_device(
@@ -366,14 +395,15 @@ class StoreBridge:
# to the allow-list by the WS layer, which owns entry.options).
if isinstance(settings, dict) and settings:
device_meta["settings"] = dict(settings)
res = await self._client.upload_device_bundle(
acct["refresh_token"], acct.get("uid", ""), acct.get("name"), device_meta, bundle_items,
)
# Return the raw bundle result ({ok, cycle_ids, errors}) so the caller can
# tell a partial upload (some cycle_ids present) from a total failure.
# Only a pre-flight gate short-circuits with an {"error": ...} marker above.
if not res.get("ok") and not res.get("cycle_ids"):
res = {**res, "detail": self._client.last_error()}
async with self._client.write_lock: # see share_cycle
res = await self._client.upload_device_bundle(
acct["refresh_token"], acct.get("uid", ""), acct.get("name"), device_meta, bundle_items,
)
# Return the raw bundle result ({ok, cycle_ids, errors}) so the caller can
# tell a partial upload (some cycle_ids present) from a total failure.
# Only a pre-flight gate short-circuits with an {"error": ...} marker above.
if not res.get("ok") and not res.get("cycle_ids"):
res = {**res, "detail": self._client.last_error()}
return res
async def download_device(self, device_id_: str, device_type: str = "") -> dict[str, Any]:
+311 -58
View File
@@ -34,12 +34,14 @@ import time
import unicodedata
from collections.abc import Callable
from typing import Any
from urllib.parse import quote
from homeassistant.core import HomeAssistant
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.util import dt as dt_util
from .const import (
DOMAIN,
SHAREABLE_SETTING_KEYS,
STORE_API_KEY,
STORE_PROJECT_ID,
@@ -53,12 +55,72 @@ _APPLIANCE_TYPES = {"washer", "dryer", "dishwasher", "washer_dryer"}
# Max concurrent per-cycle rating aggregations when listing a profile's cycles.
_RATING_FANOUT_LIMIT = 8
# Max profiles hydrated concurrently when downloading a whole-device bundle. Each
# profile's get_cycles adds its own (rating) fan-out, so the effective ceiling is
# roughly this x (1 + _RATING_FANOUT_LIMIT); kept small to stay well under the
# Max profiles hydrated concurrently when downloading a whole-device bundle. One query
# each (the bundle skips the per-cycle rating fan-out), kept small to stay well under the
# store's rate limiter on devices that carry many profiles.
_BUNDLE_HYDRATE_LIMIT = 4
# Upper bound for a Firestore "starts with" range on a string field: U+F8FF sits above
# every character that realistically appears in a brand name, so [p, p + _PREFIX_MAX]
# selects exactly the values beginning with p. Written as an escape on purpose -- the
# literal glyph is invisible in an editor and trivially lost to a copy/paste.
_PREFIX_MAX = "\uf8ff"
# Field projections for the catalog list queries (Firestore `select`). A projection does
# NOT reduce the billed document count -- Firestore bills per document read regardless --
# but it does cut the wire payload substantially, which matters because these lists are
# relayed verbatim to the panel over the HA WebSocket. Measured on the live catalog: the
# brand list drops 64.7 KB -> 33 KB, and a single brand's device list 54.4 KB -> 17 KB
# (device docs carry a ~25-key `settings` map that no list view reads; the whole-device
# bundle fetches the full doc via get_device instead).
#
# These are ALLOW-lists: a field missing here is absent from the decoded row, so keep
# them in sync with what the panel + StoreBridge actually consume. `id` is derived from
# the document name and is always present.
_BRAND_LIST_FIELDS = ("brand", "brand_lc", "status")
_DEVICE_LIST_FIELDS = (
"brand", "brand_lc", "model", "model_lc", "applianceType", "status",
"confirmCount", "favoriteCount", "manualUrl", "createdByName",
# Content markers for the Store browse list. Only ~30% of catalog entries carry any
# shared program (168 of 564 measured), so "does this entry actually have anything?"
# is the most useful thing a row can say. NB these are contributor-maintained
# counters and are known to under-report where a best-effort increment was denied,
# so the UI shows a chip when the count is positive and says nothing when it is
# zero/absent -- never "this is empty", which a stale zero would make a lie.
"profileCount", "cycleCount",
)
# Domain-scoped key for the process-wide shared client (see get_client).
_CLIENT_KEY = f"{DOMAIN}_store_client"
def get_client(hass: HomeAssistant) -> "StoreClient":
"""The one shared StoreClient for this HA install.
The community catalog is public, device-agnostic data, but a StoreBridge is created
per config entry -- so a per-bridge client made an N-appliance install pay N times
over for the exact same brand/device lists, each with its own cold cache. Hanging a
single instance off ``hass.data`` collapses that to one, and (unlike a bridge) it is
deliberately NOT removed on unload so the read cache also survives an entry reload.
Mirrors the global-state pattern in ``store_account``.
"""
client = hass.data.get(_CLIENT_KEY)
if not isinstance(client, StoreClient):
client = StoreClient(hass)
hass.data[_CLIENT_KEY] = client
return client
def _seg(value: Any) -> str:
"""Percent-encode one REST path segment.
Store document ids are raw user text: ``brand_id`` is just ``brand.lower()`` with no
normalisation, so the live catalog really does contain ids like ``aeg lavamat``,
``fisher & paykel`` and ``ok.``. Interpolating those into a URL unencoded produces a
malformed request rather than a 404, so every id-in-path must go through this.
"""
return quote(str(value if value is not None else ""), safe="")
# ── deterministic ids (must match the store's lib/ids.js exactly) ──────────────
@@ -173,10 +235,17 @@ class StoreClient:
# store's Firebase free tier (50k document reads/day) that brand-list query alone was
# the single largest read source. Cache these reads in memory for a short TTL so a
# burst of panel opens collapses to at most one Firestore query per key per window.
# The client is a long-lived singleton (one per manager) so the cache survives panel
# reloads. Writes that add brands/devices invalidate it (see _commit_create) so a
# freshly-contributed entry still appears immediately for the user who added it.
_CATALOG_CACHE_TTL_S = 900.0 # brands + device searches (15 min)
# The client is a process-wide singleton (see get_client) so the cache survives panel
# reloads AND config-entry reloads, and is shared by every appliance. Writes that add
# brands/devices invalidate it (see _commit_create) so a freshly-contributed entry
# still appears immediately for the user who added it.
# The catalog changes a few times a week (a contributor adds a brand, an admin
# approves one), so a 15-minute window was re-reading a near-static ~650-document
# catalog dozens of times a day. An hour keeps a browsing session on one query while
# staying fresh enough to notice someone else's contribution, and it is not the only
# freshness path: a local create invalidates immediately (_commit_create) and
# refresh_catalog() force-drops everything on demand.
_CATALOG_CACHE_TTL_S = 3600.0 # brands + device searches (1 h)
_CONFIG_CACHE_TTL_S = 3600.0 # config/site (maintenance flag + confirm threshold)
# Hard cap on distinct cached read keys. Device searches key on the brand term, so a
# long-lived session that issues many distinct searches would otherwise accumulate an
@@ -212,10 +281,30 @@ class StoreClient:
# invalidation is not joined by a post-invalidation caller (which would receive a
# pre-write snapshot); such a caller starts a fresh query instead.
self._inflight: dict[str, "tuple[int, asyncio.Future[list[dict[str, Any]]]]"] = {}
# Guards the write-then-read-_last_error sequence; see the write_lock property.
self._write_lock = asyncio.Lock()
def last_error(self) -> str | None:
return self._last_error
@property
def write_lock(self) -> asyncio.Lock:
"""Serialises a write with the ``last_error()`` read that interprets it.
``_last_error`` is a single slot cleared at the start of each upload, and this
client is shared by every appliance in the install (see get_client), so two
concurrent shares could otherwise interleave clear/set and make one device report
the other's failure reason. Holding this across the whole upload-then-read
sequence keeps that attribution correct; it also naturally rate-limits concurrent
uploads, which the store's free tier appreciates.
Every caller that can reach a ``_last_error`` writer must hold it, not just the
ones that read it back: ``ensure_id_token`` also writes the slot, so connect /
confirm / rate take it too (see ``store.WashDataStore``). It is NOT reentrant --
take it around a client call, never inside one.
"""
return self._write_lock
def _sess(self) -> Any:
if self._session is None:
self._session = async_get_clientsession(self._hass)
@@ -245,11 +334,26 @@ class StoreClient:
def _invalidate_catalog_cache(self) -> None:
"""Drop cached brand/device catalog reads (call after a create/upload/promote write so
a just-contributed or newly-approved entry appears immediately, not after the TTL)."""
a just-contributed or newly-approved entry appears immediately, not after the TTL).
Covers both the list queries (``brands:``/``devices:``) and the single-document
lookups behind the identity badges (``brand:``/``device:``) -- a create writes the
very document those resolve, so a stale hit there would show "not in the catalog"
for an entry the user just added.
"""
self._cache_gen += 1
for key in [k for k in self._read_cache if k.startswith(("brands:", "devices:"))]:
for key in [
k for k in self._read_cache
if k.startswith(("brands:", "devices:", "brand:", "device:"))
]:
self._read_cache.pop(key, None)
def refresh_catalog(self) -> None:
"""Force the next catalog read to hit Firestore (public wrapper for the panel's
"refresh catalog" action). With a 1-hour TTL a user who is told by a friend that a
brand was just approved needs a way to see it without waiting out the window."""
self._invalidate_catalog_cache()
# ── auth ──────────────────────────────────────────────────────────────────
async def ensure_id_token(self, refresh_token: str) -> str | None:
@@ -368,6 +472,37 @@ class StoreClient:
}}
return self._field_filter("status", "EQUAL", "approved")
@staticmethod
def _approved_only(rows: list[dict[str, Any]]) -> list[dict[str, Any]]:
"""Narrow a pending-inclusive result to the approved rows, in memory."""
return [r for r in rows if str(r.get("status") or "") == "approved"]
def _serve_from_superset(
self, superset_key: str, include_pending: bool, page_size: int
) -> list[dict[str, Any]] | None:
"""A warm pending-inclusive cache entry already contains every approved row, so an
approved-only caller can be served from it instead of issuing a second, narrower
query for a strict subset of rows we are already holding. Returns None when the
request wants pending rows anyway, or when the superset is not cached.
This is why ``include_pending`` stays in the cache key rather than being collapsed
into one always-pending-inclusive fetch: upgrading an approved-only request to the
superset query would *raise* its read count (on the live catalog, approved devices
of one appliance type number ~6 against ~140 pending-inclusive). Sharing downwards
is free; sharing upwards is not.
"""
if include_pending:
return None
cached = self._cache_get(superset_key)
if cached is None:
return None
# A result capped at page_size may be missing approved rows past the cap, so it
# cannot answer a narrower question. Mirrors the same guard in
# _cached_brand_superset.
if len(cached) >= page_size:
return None
return self._approved_only(cached)
async def search_devices(
self, brand: str | None = None, appliance_type: str | None = None,
model_query: str | None = None, *, include_pending: bool = False, page_size: int = 500,
@@ -378,7 +513,18 @@ class StoreClient:
# was fetched, so caching a truncated list would hide models past the limit for the
# whole TTL. A query reads only the docs that exist, so the high ceiling adds no reads
# for today's catalog while staying complete as it grows.
key = f"devices:{(brand or '').lower()}:{appliance_type or ''}:{int(include_pending)}:{page_size}"
base = f"devices:{(brand or '').lower()}:{appliance_type or ''}"
key = f"{base}:{int(include_pending)}:{page_size}"
def _finish(rows: list[dict[str, Any]]) -> list[dict[str, Any]]:
if model_query:
p = model_query.lower()
rows = [r for r in rows if str(r.get("model_lc", "")).startswith(p)]
return rows
shared = self._serve_from_superset(f"{base}:1:{page_size}", include_pending, page_size)
if shared is not None:
return _finish(shared)
def _build() -> dict[str, Any]:
filters = [self._status_filter(include_pending)]
@@ -388,49 +534,149 @@ class StoreClient:
filters.append(self._field_filter("brand_lc", "EQUAL", brand.lower()))
return {
"from": [{"collectionId": "devices"}],
"select": {"fields": [{"fieldPath": f} for f in _DEVICE_LIST_FIELDS]},
"where": self._where(filters),
"orderBy": [{"field": {"fieldPath": "favoriteCount"}, "direction": "DESCENDING"}],
"limit": page_size,
}
rows = await self._cached_catalog_query(key, _build)
if model_query:
p = model_query.lower()
rows = [r for r in rows if str(r.get("model_lc", "")).startswith(p)]
return rows
return _finish(await self._cached_catalog_query(key, _build))
def _cached_brand_superset(self, q: str, include_pending: bool, page_size: int) -> list[dict[str, Any]] | None:
"""Find a cached brand result that provably contains every match for prefix ``q``.
Checked in order of breadth: the pending-inclusive full list, the same-status full
list, then the longest cached prefix that is itself a prefix of ``q`` (a result set
for "bo" contains every brand starting with "bos"). A cached entry is only reusable
when it was not truncated at ``page_size`` -- a capped result may be missing rows
that a narrower query would have returned.
"""
candidates = [f"brands:1:{page_size}"]
if not include_pending:
candidates.append(f"brands:0:{page_size}")
# Longest usable prefix first: fewer rows to filter, same answer.
candidates += [
f"brands:p:{int(include_pending)}:{q[:n]}:{page_size}"
for n in range(len(q), 0, -1)
]
for cand in candidates:
cached = self._cache_get(cand)
if cached is not None and len(cached) < page_size:
return cached if include_pending else self._approved_only(cached)
return None
async def list_brands(
self, q: str | None = None, *, include_pending: bool = True, page_size: int = 500,
) -> list[dict[str, Any]]:
"""Brands for the picker. With ``q``, resolved server-side as a prefix range query
unless a broad-enough cached result can answer it in memory.
Downloading all ~84 brand documents to render a filtered dropdown was the single
largest read source in the store. A ``brand_lc`` range query rides the existing
(status, brand_lc) composite index and reads only the matching documents -- a
2-character prefix costs single digits against 84 -- and because a prefix result is
cached, every subsequent keystroke narrowing that prefix is answered from memory.
The unfiltered list (no ``q``) still fetches everything: it is the "show me the
dropdown" case, and truncating it would make brands past the cap unfindable.
"""
prefix = (q or "").strip().lower()
select = {"fields": [{"fieldPath": f} for f in _BRAND_LIST_FIELDS]}
order = [{"field": {"fieldPath": "brand_lc"}, "direction": "ASCENDING"}]
if prefix:
cached = self._cached_brand_superset(prefix, include_pending, page_size)
if cached is not None:
return [r for r in cached if str(r.get("brand_lc", "")).startswith(prefix)]
key = f"brands:p:{int(include_pending)}:{prefix}:{page_size}"
rows = await self._cached_catalog_query(key, lambda: {
"from": [{"collectionId": "brands"}],
"select": select,
"where": self._where([
self._status_filter(include_pending),
self._field_filter("brand_lc", "GREATER_THAN_OR_EQUAL", prefix),
self._field_filter("brand_lc", "LESS_THAN_OR_EQUAL", prefix + _PREFIX_MAX),
]),
"orderBy": order,
"limit": page_size,
})
# The range is inclusive of exactly the prefix matches, so no further filter is
# needed -- but stay defensive in case a cached entry pre-dates this path.
return [r for r in rows if str(r.get("brand_lc", "")).startswith(prefix)]
async def list_brands(self, q: str | None = None, *, include_pending: bool = True, page_size: int = 500) -> list[dict[str, Any]]:
# Cache the unfiltered brand list (the q prefix filter is applied in memory below),
# so one Firestore query serves every search prefix for this key. The limit is a
# full-catalog ceiling (not a UI page size): the in-memory prefix filter can only
# match what was fetched, so a low cap would make brands past it unsearchable for
# the whole cache TTL. The brand collection is small with tiny docs, and a query
# only reads the docs that exist, so this ceiling does not add reads for today's
# catalog while staying correct as it grows.
key = f"brands:{int(include_pending)}:{page_size}"
rows = await self._cached_catalog_query(key, lambda: {
shared = self._serve_from_superset(f"brands:1:{page_size}", include_pending, page_size)
if shared is not None:
return shared
return await self._cached_catalog_query(key, lambda: {
"from": [{"collectionId": "brands"}],
"select": select,
"where": self._where([self._status_filter(include_pending)]),
"orderBy": [{"field": {"fieldPath": "brand_lc"}, "direction": "ASCENDING"}],
"orderBy": order,
"limit": page_size,
})
if q:
p = q.lower()
rows = [r for r in rows if str(r.get("brand_lc", "")).startswith(p)]
return rows
async def get_device(self, device_id: str) -> dict[str, Any] | None:
async def _get_doc(self, path: str, *, cache_key: str | None = None) -> dict[str, Any] | None:
"""Fetch one document by path. ``None`` for missing/forbidden or on any failure.
A point read costs exactly one document, so resolving a known id this way is
vastly cheaper than the list query that used to be used to find it. Only
successful lookups are cached (a miss may simply mean "not contributed yet",
which flips as soon as the user contributes it).
"""
if cache_key is not None:
cached = self._cache_get(cache_key)
if cached is not None:
return cached
# Capture the generation BEFORE the request: if an invalidation lands while this
# read is in flight, caching its result would re-pin a pre-write document for the
# full TTL. Same discipline as _fetch_and_cache.
gen = self._cache_gen
try:
async with self._sess().get(f"{self._base}/devices/{device_id}", timeout=15) as resp:
if resp.status in (403, 404):
return None
async with self._sess().get(f"{self._base}/{path}", timeout=15) as resp:
if resp.status != 200:
if resp.status not in (403, 404):
_LOGGER.debug("Store get %s HTTP %s", path, resp.status)
return None
doc = await resp.json()
except Exception as exc: # noqa: BLE001
_LOGGER.debug("Store get_device error: %s", exc)
_LOGGER.debug("Store get %s error: %s", path, exc)
return None
return _decode_doc(doc)
out = _decode_doc(doc)
if cache_key is not None and gen == self._cache_gen:
self._cache_put(cache_key, out, self._CATALOG_CACHE_TTL_S)
return out
async def get_device(self, device_id: str) -> dict[str, Any] | None:
return await self._get_doc(f"devices/{_seg(device_id)}", cache_key=f"device:{device_id}")
async def get_brand(self, brand: str) -> dict[str, Any] | None:
"""The brand document for a brand name (doc id is the lowercased name)."""
b_id = brand_id(brand)
if not b_id:
return None
return await self._get_doc(f"brands/{_seg(b_id)}", cache_key=f"brand:{b_id}")
async def catalog_entry(
self, brand: str, model: str, appliance_type: str,
) -> dict[str, Any]:
"""Resolve just the catalog *identity* of one appliance: its brand and device
documents, by deterministic id.
This backs the brand/model status badges in the settings form, which previously
forced a download of the entire brand list plus that brand's whole device list
(measured: 128 documents, 119 KB) purely to locate two rows the caller could
already name. Two point reads answer it exactly, and they are issued
concurrently so the round-trip cost is one request deep, not two.
"""
async def _brand() -> dict[str, Any] | None:
return await self.get_brand(brand) if brand else None
async def _device() -> dict[str, Any] | None:
return await self.get_device(dev_id) if dev_id else None
dev_id = device_id(appliance_type, brand, model) if (brand and model and appliance_type) else ""
brand_doc, device_doc = await asyncio.gather(_brand(), _device())
return {"device_id": dev_id, "brand": brand_doc, "device": device_doc}
async def get_config(self) -> dict[str, Any]:
"""Public config/site (maintenance flag + confirmThreshold). {} on failure.
@@ -487,11 +733,11 @@ class StoreClient:
async def get_device_quality(self, device_id: str) -> dict[str, Any]:
"""count + average of the device's 5-star quality ratings (info only)."""
return await self._rating_agg(f"devices/{device_id}")
return await self._rating_agg(f"devices/{_seg(device_id)}")
async def cycle_rating(self, cycle_id: str) -> dict[str, Any]:
"""count + average of a reference cycle's 5-star ratings (info only)."""
return await self._rating_agg(f"cycles/{cycle_id}")
return await self._rating_agg(f"cycles/{_seg(cycle_id)}")
async def get_profiles(self, dev_id: str, include_pending: bool = False, page_size: int = 100) -> list[dict[str, Any]]:
sq = {
@@ -515,17 +761,21 @@ class StoreClient:
async def get_device_bundle(self, dev_id: str, include_pending: bool = True) -> dict[str, Any]:
"""Whole-device package for download: the device's shareable ``settings`` (from
the device doc) + its profiles, each with its reference cycles nested under
``cycles`` (hydrated + rating-summarised by get_cycles). One device GET + one
profiles query + one cycles query per profile. Never raises.
``cycles`` (hydrated by get_cycles). One device GET + one profiles query + one
cycles query per profile. Never raises.
Star ratings are deliberately skipped here. They are browse-only decoration and
the adopt path (``StoreBridge.download_device``) never reads them, but they cost
one aggregation request *per cycle*: a 15-profile device turned a ~17-request
download into ~60, all on the user's critical path.
"""
device = await self.get_device(dev_id) or {}
settings = device.get("settings") if isinstance(device.get("settings"), dict) else {}
profiles = await self.get_profiles(dev_id, include_pending=include_pending)
# Bound the per-profile fan-out: each get_cycles issues one query plus a
# rating fan-out, so an unbounded gather over a device with many profiles
# could burst hundreds of concurrent requests and trip the store's rate
# limiter. A shared semaphore caps how many profiles hydrate at once.
# Bound the per-profile fan-out: an unbounded gather over a device with many
# profiles could burst hundreds of concurrent requests and trip the store's rate
# limiter. A shared semaphore caps how many profiles hydrate at once.
sem = asyncio.Semaphore(_BUNDLE_HYDRATE_LIMIT)
async def _cycles_for(p: dict[str, Any]) -> list[dict[str, Any]]:
@@ -533,7 +783,7 @@ class StoreClient:
if not pid:
return []
async with sem:
return await self.get_cycles(pid, include_pending=include_pending)
return await self.get_cycles(pid, include_pending=include_pending, include_ratings=False)
# Fetch profiles' cycles concurrently (bounded) rather than one at a time.
cycle_lists = await asyncio.gather(*(_cycles_for(p) for p in profiles))
@@ -542,14 +792,17 @@ class StoreClient:
return {"device_id": dev_id, "settings": settings, "profiles": profiles}
async def get_cycles(
self, prof_id: str, include_pending: bool = True, page_size: int = 50
self, prof_id: str, include_pending: bool = True, page_size: int = 50,
*, include_ratings: bool = True,
) -> list[dict[str, Any]]:
"""Reference cycles for a profile, most-recent-first.
``include_pending`` (default True) also returns still-awaiting-approval
recordings so they can be browsed/imported before the community votes them
in (they are publicly readable, shown with an "awaiting approval" tag).
Each cycle gets a ``rating`` = ``{"avg", "count"}`` summary attached.
Each cycle gets a ``rating`` = ``{"avg", "count"}`` summary attached, unless
``include_ratings`` is False -- one extra aggregation request per cycle that
only the browse UI displays (see get_device_bundle).
"""
sq = {
"from": [{"collectionId": "cycles"}],
@@ -561,6 +814,8 @@ class StoreClient:
"limit": page_size,
}
cycles = [self._with_decoded_trace(c) for c in (await self._run_query(sq) or [])]
if not include_ratings:
return cycles
# Attach each cycle's 5-star rating summary (info-only; the aggregation lives
# in a subcollection so it can't ride the list query). Bound concurrency with
# a semaphore so a large page can't fan out into dozens of simultaneous
@@ -578,18 +833,10 @@ class StoreClient:
return cycles
async def get_cycle(self, cycle_id: str) -> dict[str, Any] | None:
try:
async with self._sess().get(f"{self._base}/cycles/{cycle_id}", timeout=15) as resp:
if resp.status in (403, 404):
return None
if resp.status != 200:
_LOGGER.debug("Store get_cycle HTTP %s", resp.status)
return None
doc = await resp.json()
except Exception as exc: # noqa: BLE001
_LOGGER.debug("Store get_cycle error: %s", exc)
return None
return self._with_decoded_trace(_decode_doc(doc))
# Not cached: cycle documents carry the full trace, so they are the one read here
# worth fetching fresh rather than pinning in memory.
doc = await self._get_doc(f"cycles/{_seg(cycle_id)}")
return None if doc is None else self._with_decoded_trace(doc)
@staticmethod
def _with_decoded_trace(cycle: dict[str, Any]) -> dict[str, Any]:
@@ -901,6 +1148,12 @@ class StoreClient:
if not ok and "ALREADY_EXISTS" not in body and "FAILED_PRECONDITION" not in body:
_LOGGER.warning("Store confirm_device failed: %s", body[:200])
return None
# This write just changed the very document the next line reads, and get_device
# is a CACHED point read that the settings badge has almost certainly already
# warmed. Without dropping it here the read-back returns the pre-increment doc,
# so the count shown is one behind and `count >= threshold` never becomes true --
# community auto-promotion would silently never fire.
self._invalidate_catalog_cache()
dev = await self.get_device(device_id) or {}
count = int(dev.get("confirmCount") or 0)
status = dev.get("status")
@@ -21,6 +21,7 @@ from __future__ import annotations
import copy
import logging
import math
from decimal import ROUND_CEILING, ROUND_FLOOR, Decimal
from datetime import datetime
from typing import Any, TYPE_CHECKING, cast
@@ -484,9 +485,23 @@ def reconcile_suggestions(
"""True if at least one key is already in the suggestion map (original or cascade)."""
return any(isinstance(out.get(k), dict) for k in keys)
def adjust(key: str, new_value: float, why: str) -> None:
"""Set a suggestion value; cascade-creates an entry when the key is absent."""
rounded = round(new_value, 2)
def adjust(key: str, new_value: float, why: str, round_dir: str = "nearest") -> None:
"""Set a suggestion value; cascade-creates an entry when the key is absent.
``round_dir`` controls the 2-dp rounding so a strict inequality survives it:
``"up"`` (ceil) when *raising* a value to clear a lower bound, ``"down"``
(floor) when *lowering* one to a ceiling. Nearest-rounding could otherwise land
back on the value that violated the constraint (e.g. raising auto to 0.901 would
round to 0.90 and stay below a match of 0.901). Default ``"nearest"`` keeps every
non-ladder rule byte-identical.
"""
if round_dir == "up":
# Decimal(str(x)) so binary FP can't nudge e.g. 0.07 to 0.0700001 and ceil to 0.08.
rounded = float(Decimal(str(new_value)).quantize(Decimal("0.01"), rounding=ROUND_CEILING))
elif round_dir == "down":
rounded = float(Decimal(str(new_value)).quantize(Decimal("0.01"), rounding=ROUND_FLOOR))
else:
rounded = round(new_value, 2)
entry = out.get(key)
if isinstance(entry, dict):
if _num(entry.get("value")) == rounded:
@@ -564,17 +579,43 @@ def reconcile_suggestions(
if sampling is not None and start_dur is not None and start_dur < sampling and in_out(CONF_SAMPLING_INTERVAL, CONF_START_DURATION_THRESHOLD):
adjust(CONF_START_DURATION_THRESHOLD, sampling, "the sampling interval")
# ── Rule 5: learning_confidence <= match_threshold <= auto_label ──────
# Reconcile top-down (match<=auto first) so a lower fix cannot re-break
# the ordering already set above.
# ── Rule 5: match_threshold <= learning_confidence, match <= auto_label ─
# The confidence ladder is unmatch < match < learning < auto_label (#396):
# the verify-band floor (learning) sits AT OR ABOVE the live match-trust
# gate (match), which itself sits at or below the auto-label ceiling.
# Reconcile match<=auto first so a later fix cannot re-break the ordering.
match_thr = eff(CONF_PROFILE_MATCH_THRESHOLD)
auto = eff(CONF_AUTO_LABEL_CONFIDENCE)
if match_thr is not None and auto is not None and match_thr > auto and in_out(CONF_PROFILE_MATCH_THRESHOLD, CONF_AUTO_LABEL_CONFIDENCE):
adjust(CONF_PROFILE_MATCH_THRESHOLD, auto, "the auto-label confidence")
match_thr = eff(CONF_PROFILE_MATCH_THRESHOLD)
# Anchor on whichever the engine actually proposed, like every other
# two-sided rule. match_threshold now drives detection (it is
# CycleDetectorConfig.match_confidence_threshold), so when the engine
# deliberately RAISED it, lift the auto-label ceiling to keep it rather
# than silently undoing the raise; only cascade it downward when it was
# not the proposed key.
if is_original(CONF_PROFILE_MATCH_THRESHOLD):
# raise the ceiling to (>=) match: ceil so 2-dp rounding can't drop it back under
adjust(CONF_AUTO_LABEL_CONFIDENCE, match_thr, "the profile match threshold", "up")
auto = eff(CONF_AUTO_LABEL_CONFIDENCE)
else:
# lower match to (<=) auto: floor so it stays at/below the ceiling
adjust(CONF_PROFILE_MATCH_THRESHOLD, auto, "the auto-label confidence", "down")
match_thr = eff(CONF_PROFILE_MATCH_THRESHOLD)
learn = eff(CONF_LEARNING_CONFIDENCE)
if learn is not None and match_thr is not None and learn > match_thr and in_out(CONF_LEARNING_CONFIDENCE, CONF_PROFILE_MATCH_THRESHOLD):
adjust(CONF_LEARNING_CONFIDENCE, match_thr, "the profile match threshold")
if learn is not None and match_thr is not None and learn < match_thr and in_out(CONF_LEARNING_CONFIDENCE, CONF_PROFILE_MATCH_THRESHOLD):
# raise learning to (>=) match: ceil
adjust(CONF_LEARNING_CONFIDENCE, match_thr, "the profile match threshold", "up")
# Top of the ladder: learning <= auto. `_add_confidence_suggestions` derives the
# two independently (learning from p05 of manual labels, auto from p15 of
# uncorrected auto-labels), so a device with few high-confidence manual labels can
# yield learning > auto. Cascade-RAISE the auto ceiling to the verify floor (the
# conservative direction — never lower the verify band); keeps the full declared
# ordering intact instead of enforcing only its middle two rungs.
learn = eff(CONF_LEARNING_CONFIDENCE)
auto = eff(CONF_AUTO_LABEL_CONFIDENCE)
if learn is not None and auto is not None and learn > auto and in_out(CONF_LEARNING_CONFIDENCE, CONF_AUTO_LABEL_CONFIDENCE):
# raise the auto ceiling to (>=) learning: ceil
adjust(CONF_AUTO_LABEL_CONFIDENCE, learn, "the learning confidence", "up")
# ── Rule 6: profile_unmatch_threshold < profile_match_threshold ────────
unmatch = eff(CONF_PROFILE_UNMATCH_THRESHOLD)
@@ -231,7 +231,7 @@
},
"trim_cycle": {
"name": "Podrezivanje ciklusa",
"description": "Skratite podatke o snazi prošlog ciklusa na određeni vremenski prozor.",
"description": "Skratite podatke o snazi prošlog ciklusa na određeni vremenski prozor.",
"fields": {
"device_id": {
"name": "Uređaj",
@@ -205,7 +205,7 @@
},
"notes": {
"name": "Huomautuksia",
"description": "Valinnaisia huomautuksia tästä syklistä."
"description": "Valinnaisia huomautuksia tästä syklistä."
}
}
},
@@ -231,7 +231,7 @@
},
"trim_cycle": {
"name": "Ciklus podrezivanja",
"description": "Skratite podatke o snazi prošlog ciklusa na određeni vremenski prozor.",
"description": "Skratite podatke o snazi prošlog ciklusa na određeni vremenski prozor.",
"fields": {
"device_id": {
"name": "Uređaj",
@@ -414,7 +414,7 @@
"message": "Ciklus nije pronađen ili nema podataka o snazi."
},
"trim_failed_empty_window": {
"message": "Podrezivanje nije uspjelo - ciklus nije pronađen, nema podataka o snazi ili je rezultirajući prozor prazan."
"message": "Podrezivanje nije uspjelo - ciklus nije pronađen, nema podataka o snazi ili je rezultirajući prozor prazan."
},
"trim_invalid_range": {
"message": "trim_end_s mora biti veći od trim_start_s."
@@ -78,9 +78,12 @@
"awaiting": "Изчаква одобрение",
"imported_tip": "Импортирано от магазина на общността. Използва се само за съпоставяне, не се брои в статистиката.",
"not_importable": "неприложимо",
"exists": "съществува"
"exists": "съществува",
"backfilled_tip": "Открито в импортирана история на мощността. Влияе само на съпоставянето на програми, не се брои в статистиката."
},
"btn": {
"set_brand_model": "Задаване на марка и модел",
"refresh_catalog": "Опресняване на каталога",
"add_device": "+ Добавяне на устройство",
"add_device_tip": "Добавете друго устройство WashData",
"add_maintenance": "Добавяне на събитие за поддръжка",
@@ -90,7 +93,7 @@
"apply_label": "Прилагане на етикет",
"apply_set_b": "Прилагане на набор B",
"apply_split": "Приложете Разделяне",
"apply_trim": "Нанесете Trim",
"apply_trim": "Приложете изрязването",
"auto_detect_split": "Автоматично откриване",
"auto_label_cycles": "Цикли на автоматично етикетиране",
"auto_label_cycles_tip": "Автоматично присвоява имена на профили на немаркирани цикли, чиято степен на достоверност на съвпадение надвишава прага",
@@ -211,8 +214,8 @@
"stop": "Спри",
"submit_correction": "Изпратете корекция",
"train_now": "Тренирайте сега",
"trim": "Подстригване",
"trim_split": "Подстригване / Разделяне",
"trim": "Изрязване",
"trim_split": "Изрязване / Разделяне",
"undo": "Отмяна",
"use": "Използвайте",
"wipe_all": "Изтриване на всички данни",
@@ -234,14 +237,19 @@
"download_device": "Изтегли настройките на устройството",
"share_device": "Сподели настройките на устройството",
"share_device_tip": "Споделете програмите и настройките на това устройство с общността",
"share_n": "Сподели {n} програм{s}",
"share_n": "Споделяне на цикли ({n})",
"export_selected": "Експорт (избор на данни)",
"export_all": "Бърз експорт на всичко",
"import_raw": "Разширено: замяна на всичко от JSON",
"download_export": "Изтегляне на експорта",
"analyze_import": "Анализ на файл",
"import_selected": "Импортиране на избраното",
"back": "Назад"
"back": "Назад",
"import_power_history": "Импортиране на историята на мощността",
"hist_read_recorder": "Прочитане от Home Assistant",
"hist_scan": "Търсене на цикли",
"hist_import_n": "Импортиране на цикли ({n})",
"hist_goto_cycles": "Покажи циклите"
},
"conflict": {
"anti_wrinkle_exit": {
@@ -253,14 +261,14 @@
"start": "Трябва да е под Макс. Мощност Против Бръчки ({max} Вт)"
},
"attn_sub": "Поправете конфликтите преди запазване",
"attn_title": "{n} конфликт{s} в настройките",
"settings_banner": "{n} конфликт{s} в настройките проверете маркираните раздели и поправете преди запазване.",
"attn_title": "Конфликти в настройките: {n}",
"settings_banner": "Конфликти в настройките: {n}. Проверете маркираните раздели и ги поправете преди запазване.",
"settings_banner_btn": "Към първия",
"confidence": {
"auto": "Трябва да е на или над Праг на Съвпадение ({match})",
"learning": "Трябва да е на или под Праг на Съвпадение ({match})",
"learning": "Трябва да е на или над Праг на Съвпадение ({match})",
"match_for_auto": "Трябва да е на или под Доверие в Авто-Маркирането ({alc})",
"match_for_learning": "Трябва да е на или над Доверие в Обучението ({lc})"
"match_for_learning": "Трябва да е на или под Доверие в Обучението ({lc})"
},
"duration_ratio": {
"max": "Трябва да е по-голям от Мин. Съотношение на Продължителност ({min})",
@@ -298,7 +306,7 @@
"match": "Трябва да е над Праг на Несъвпадение ({un})",
"unmatch": "Трябва да е под Праг на Съвпадение ({match}); иначе потвърденото съвпадение веднага се губи"
},
"cascade_toast": "Автоматично бяха коригирани и {n} параметър{s} за последователност.",
"cascade_toast": "Други настройки, коригирани за последователност: {n}",
"suggestion_resolves": "Активирайте чакащото предложение ({val}) по-долу, за да поправите това",
"use_fix": "Използвай {val}",
"watchdog": {
@@ -356,7 +364,8 @@
"pg_outcome": "Резултат от симулацията",
"pg_across_cycles": "За всички ваши цикли",
"community_store": "Магазин на общността",
"online_account": "Магазин на общността и онлайн функции"
"online_account": "Магазин на общността и онлайн функции",
"import_power_history": "Импортиране на историята на мощността"
},
"health": {
"fair": "Приемливо качество на съвпадение",
@@ -364,6 +373,7 @@
"poor": "⚠ Лошо качество на съвпадение"
},
"lbl": {
"drag_to_resize": "Плъзнете за преоразмеряване",
"actions": "Действия",
"activity": "активност",
"administrators": "Администратори",
@@ -435,7 +445,7 @@
"from": "От",
"gap_s": "Празнина (и)",
"group_name": "Име на групата",
"head_trim": "Подстригване на главата",
"head_trim": "Изрязване в началото (с)",
"health": "здраве",
"hide_tabs": "Скриване на раздели за неадминистратори",
"in_use": "В употреба",
@@ -451,7 +461,7 @@
"metric": "Показател",
"mode_existing_profile": "Добавяне към съществуващ профил",
"mode_new_profile": "Създаване на нов профил",
"models_fine_tuned": "({count} модел{plural} доуточнени)",
"models_fine_tuned": "(фино настроени модели: {count})",
"n_classic_suggestions": "{n} класически",
"n_ml_suggestions": "{n} ML",
"n_selected": "{n} избрани",
@@ -533,7 +543,7 @@
"stage3": "Етап 3 DTW",
"stage4": "Етап 4 – съответствие",
"status": "Статус",
"tail_trim": "Подстригване на опашката",
"tail_trim": "Изрязване в края (с)",
"timer_auto_pause": "Автоматична пауза",
"timer_min": "мин",
"timer_msg_placeholder": "Съобщение (по избор, {device}/{program}/{minutes})",
@@ -677,7 +687,26 @@
"conflict_resolution": "Конфликти на имена",
"conflict_import_copy": "Импортиране като копие",
"conflict_keep_mine": "Запази моите",
"conflict_overwrite": "Презапис"
"conflict_overwrite": "Презапис",
"hist_csv_data": "CSV данни",
"hist_from_recorder": "Или го прочетете от Home Assistant",
"days": "дни",
"hist_keep": "Запази този цикъл",
"hist_looks_complete": "завършен",
"peak_power_short": "Пик",
"shape": "Форма",
"hist_skip_idle": "нищо не е работило",
"hist_skip_sparse": "показанията са прекалено разредени",
"hist_skip_short": "твърде малко показания",
"hist_skip_long": "няма достатъчно дълга пауза за разделяне",
"hist_reason_short": "по-кратък от най-краткия реален цикъл на този уред",
"hist_reason_no_end": "никога не завърши коректно",
"hist_since": "От",
"task_history_import": "Сканиране на историята на мощността",
"task_history_import_apply": "Импортиране на цикли",
"evidence_real_cycles": "Цикли, изпълнени от тази машина",
"evidence_reference_cycles": "Изтеглени от магазина на общността",
"evidence_backfill_cycles": "Намерени в импортирана история на мощността"
},
"log": {
"all_levels": "Всички нива",
@@ -756,9 +785,15 @@
"store_share": "Споделяне в магазина на общността",
"store_share_device": "Сподели настройките на устройството",
"export_select": "Експорт - избор на данни",
"import_wizard": "Импорт - избор на данни"
"import_wizard": "Импорт - избор на данни",
"history_import": "Импортиране на историята на мощността"
},
"msg": {
"tail_trim_hint": "Премахнете толкова секунди от края",
"store_sibling_hint": "Няма нищо споделено за точния ви модел? Близък модел от същата марка обикновено е добра отправна точка.",
"store_declare_appliance": "Кажете на WashData кой уред притежавате и този раздел ще показва конфигурациите, които други хора са споделили за него. Можете също да въведете марка по-горе, за да разгледате каталога.",
"refresh_catalog_hint": "Списъците с марки и уреди на общността се кешират, за да остане магазинът на общността в рамките на дневния си лимит. Опреснете, за да видите записите, добавени или одобрени от други.",
"head_trim_hint": "Премахнете толкова секунди от началото",
"appliance_monitor": "Монитор на уреди",
"artifact_dip_detail": "Падна под обичайния диапазон на мощността за ~{n} сек.",
"artifact_footer": "Подчертано на графиката по-горе. Това са преходни артефакти (напр. вратата се отвори по средата на цикъла), а не непременно проблеми.",
@@ -769,7 +804,7 @@
"automations_intro": "WashData задейства събития {start} / {end} и предоставя обекти, затова известията и действията най-добре се изграждат като обикновени автоматизации на Home Assistant. По-долу са показани автоматизациите, използващи това устройство.",
"cleanup_intro": "Всеки етикетиран цикъл е насложен. Отбележете отклоненията и изтрийте, за да почистите профила.",
"clear_debug_hint": "Премахнете съхранените данни за отстраняване на грешки, за да освободите място.",
"collecting_data": "Събиране на данни – нужни са още {need} цикъл{plural} преди да може да започне прецизната настройка ({current}/{min}).",
"collecting_data": "Събиране на данни. Цикли, необходими преди да започне фината настройка: {need} ({current}/{min}).",
"compare_overlay_profiles": "Профили на наслагване (бледи)",
"compare_profiles_tip": "Наслагнете други профилни пликове върху диаграмата по-горе, за да видите кой най-добре пасва на този цикъл.",
"compare_selected_cycles": "Избрани цикли (плътни) – показване / скриване",
@@ -779,7 +814,7 @@
"cycles_deleted": "Изтрити цикли: {count}",
"enough_data": "Достатъчно данни за обучение ({current}/{min} цикъла).",
"export_description": "Изберете точно кои профили, цикли, настройки и други да се експортират в JSON, или анализирайте файл и импортирайте само желаните части.",
"feedback_cycles_pending": "{n} цикъл{s} за преглед",
"feedback_cycles_pending": "За преглед: {n}",
"feedback_prompt": "Потвърдете, че е правилно, коригирайте програмата или игнорирайте.",
"feedback_relabel_hint": "Преетикетирането на този цикъл също го разрешава.",
"filter_by_profile": "Филтриране по профил…",
@@ -856,7 +891,6 @@
"pg_stress_synthetic": "тук започва симулацията на готовност",
"pg_sweep_intro": "Какво ако {param} беше различен? Тествайте {steps} стойности върху последните ви {cycles} цикъла, за да намерите настройката, при която най-много цикли съвпадат правилно.",
"pg_sweep_step": "Стъпка {done} / {total}",
"pg_undetected": "{n} неоткрит цикъл{s}",
"pg_verdict_bad": "Изисква внимание: много цикли остават неоткрити.",
"pg_verdict_good": "Добре настроено: повечето цикли се откриват и съвпадат правилно.",
"pg_verdict_ok": "Приемливо: някои цикли са пропуснати. Опитайте да намалите прага за стартиране.",
@@ -888,6 +922,7 @@
"review_recorded_tip": "Маркирайте това като ръчно избран референтен цикъл за неговата програма - същата роля като ръчно записан цикъл. Референтните цикли винаги се запазват, зареждат съответстващия шаблон и никога не се изтриват от почистване. (Това е „златният“/записан флаг; и двете са едно и също нещо.)",
"review_tags_tip": "Незадължителни флагове, описващи какво се е объркало с този цикъл, така че обучението и почистването могат да го обяснят.",
"review_to_cycles": "Отворете опашката за преглед на Cycles",
"samples_decimated": "Показани {shown} от {total} проби (разредени за показване; пиковете са запазени). Широка празнина тук е разреждане, а не липсващи данни.",
"saving_triggers_reload": "Запазването задейства презареждане на интеграцията. Обектите на HA може за кратко да се показват като неналични.",
"search_placeholder": "Настройки за търсене...",
"see_recorder": "Вижте джаджа за записващо устройство по-долу",
@@ -991,12 +1026,12 @@
"share_consent": "Споделяте реални данни от вашия уред. Не споделяйте, ако моделите ви на използване са лични.",
"share_device_none": "Все още няма настроени устройства. Първо добавете устройство.",
"share_guideline_naming": "Използвайте ясни имена на програмите (напр. 'Cotton 40', 'Eco 60'), за да могат другите да ги разпознаят",
"share_guideline_quality": "Споделяйте само профили с ⭐ референтни цикли или поне {n} потвърдени стартирания",
"share_guideline_quality": "Споделяйте само цикли, завършили нормално -- без прекъсвания по време на цикъла, отваряне на вратата или трептения в захранването.",
"share_guideline_review": "Прегледайте профилите си преди споделяне -- премахнете тези, които изглеждат грешни",
"share_guidelines_title": "Преди споделяне",
"store_download_device_intro": "Изтеглете настройките на устройство от общността и ги приложете към ново или съществуващо устройство",
"store_share_device_intro": "Споделете програмите на вашето устройство (профили + референтни цикли) с общността. Настройките са незадължителни.",
"share_profile_no_cycles": "Профилът '{p}' няма референтни цикли -- ще бъде пропуснат, освен ако нямате {n}+ потвърдени стартирания",
"store_share_device_intro": "Качете {brand} {model} с референтните цикли, които изберете. Други със същия уред могат да приемат вашите програми. Публикациите се преглеждат, преди да станат публични.",
"share_profile_no_cycles": "Няма референтни цикли - маркирайте цикъл със ⭐ в раздела Цикли, за да включите този профил",
"advisory_phase_inconsistent": "Изглежда, че '{name}' смесва различни програми или температури - циклите му загряват за много различно време. Разделянето му на отделни профили (напр. по температура) ще подобри съпоставянето и оценките на времето.",
"advisory_phase_inconsistent_title": "⚠ Възможно смесени програми",
"export_select_intro": "Отбележете какво точно да се включи. Изборът на профили без техните цикли пак експортира разпознаваема програма (научената ѝ форма се пренася заедно с нея).",
@@ -1006,7 +1041,29 @@
"merge_hint": "Импортираните елементи се добавят; нищо локално не се губи. Конфликтите на имена се разрешават по-долу.",
"replace_warn": "Всяка отбелязана категория се изтрива и заменя от файла. Неотбелязаните категории остават непроменени.",
"dest_reference_hint": "Импортираните цикли само подобряват разпознаването на програми и никога не влияят на статистиката за използване/енергия.",
"dest_real_history_hint": "Импортираните цикли се броят като собствена история на това устройство и захранват статистиката за енергия/използване. Използвайте за преместване на един уред към нова инсталация."
"dest_real_history_hint": "Импортираните цикли се броят като собствена история на това устройство и захранват статистиката за енергия/използване. Използвайте за преместване на един уред към нова инсталация.",
"import_history_description": "Имали сте умен контакт още преди WashData? Качете експорт на историята на неговия сензор за мощност или я прочетете направо от Home Assistant, и обичайното откриване минава по нея, така че миналите цикли се появяват в списъка „Цикли“ готови за наименуване.",
"hist_input_hint": "Качете CSV файл, изтеглен от панела „История“ (обект, състояние, последна промяна), или оставете WashData да прочете историята на сензора директно. След това откриването минава по нея точно както в реално време, а вие избирате кои от намерените цикли да запазите.",
"hist_recorder_hint": "Чете данните от избраната дата до сега. По подразбиране Home Assistant пази подробна история 10 дни, а след това само средни стойности на час, които са прекалено груби за откриване на цикли - избирайте по-ранна дата само ако вашият recorder е настроен да пази повече.",
"hist_scanning": "Историята ви се възпроизвежда през детектора. Това се изпълнява във фонов режим - можете да затворите този диалог и да се върнете по-късно.",
"hist_imported_count": "Импортирани цикли: {n}.",
"hist_duplicates": "Вече импортирани и пропуснати: {n}.",
"hist_capped": "Достигнат е лимитът на импортирани цикли за устройството; останалите не бяха запазени.",
"hist_next_step": "Те са в списъка „Цикли“, отбелязани като импортирана история. Отворете един и използвайте „Етикет“, за да посочите програмата му.",
"hist_rows_read": "Прочетени показания: {n}",
"hist_breaks": "Пропуски, при които сензорът е бил недостъпен: {n}",
"hist_other_entity": "Пропуснати показания на други обекти: {n}",
"hist_entity_substituted": "Прочетено {used} (това устройство е настроено за {wanted})",
"hist_skipped_spans": "Пропуснати участъци",
"hist_settings_used": "Открито с текущите настройки на това устройство (Минимална мощност {w} Вт, Закъснение при изключване {s} с).",
"hist_none_found": "В тази история не можаха да бъдат открити цикли.",
"hist_found": "Намерени цикли: {n}. Махнете отметката от всичко, което не изглежда като истинско пускане - нищо не се запазва, докато не импортирате.",
"hist_scan_capped": "Показани са само първите кандидати (намерени: {n}).",
"hist_recorder_empty": "Home Assistant няма подробна история за този сензор в този период.",
"hist_scan_failed": "Сканирането е неуспешно.",
"hist_scan_expired": "Това сканиране вече не е налично. Моля, сканирайте отново.",
"hist_import_failed": "Импортирането е неуспешно.",
"imported_history_readonly": "Открито в импортирана история на мощността. Влияе на съпоставянето на програми, но не се брои във вашата статистика и не може да се изрязва или разделя. Използвайте „Етикет“, за да посочите програмата."
},
"phase_desc": {
"anti_crease": "Случайни кратки движения след завършване за намаляване на бръчките.",
@@ -1471,6 +1528,10 @@
"show_contributor": {
"doc": "Покажи името на сътрудника в профилите, изтеглени от магазина на общността"
},
"smart_termination_duration_ratio": {
"doc": "Колко навътре в очакваната продължителност на съпоставената програма трябва да е навлязъл цикълът, преди Интелигентното прекратяване да може да го завърши предсрочно при спадане на мощността. Очакваната продължителност е средната за програмата, затова при уреди със силно променливо време на работа - перални при студена зимна и топла лятна входяща вода, сушилни с датчик за влажност, програми, зависещи от натоварването - около половината от всички пускания завършват по-кратко от тази средна стойност и никога не получават бързото завършване, приключвайки само чрез резервния таймаут с минути закъснение. Намалете тази стойност (напр. 0.85) при такива машини, за да се задейства все пак ранното завършване; повишете я към 1.0 за по-предпазливо поведение. Оставете празно за стойността по подразбиране (0.98 или 0.99 за съдомиялни). Може само да завърши цикъл по-рано, никога по-късно, и никога не се задейства при нееднозначно или несигурно съпоставяне.",
"label": "Коефициент на интелигентно прекратяване"
},
"enable_phase_matching": {
"label": "Оставащо време съобразено с фазите",
"doc": "Разделя всеки активен цикъл на фази (нагряване, пране, центрофугиране) и разпределя оставащото време по фази, съчетано с класическата оценка - като разчита на разпределението по фази в началото на цикъла и на класическата оценка към края. Това персонализира обратното броене спрямо това колко всъщност загрява и работи вашата машина, което е най-осезаемо през първата половина на цикъла. Изключено = само класическата оценка. Засяга се само показването на оставащото време; съпоставянето на програми и откриването на цикли остават непроменени."
@@ -1522,6 +1583,10 @@
"door_end_dwell_seconds": {
"label": "Изчакване при отворена врата",
"doc": "Колко дълго трябва вратата да остане отворена, преди WashData да приключи цикъла, когато \"Вратата се отваря автоматично в края\" е включено. Достатъчно дълго, за да игнорира бързото добавяне на съд (по подразбиране 60 с), достатъчно кратко, за да приключи бързо, когато машината отвори вратата."
},
"profile_evidence_sources": {
"label": "Цикли, които оформят програмата",
"doc": "Кои цикли се използват за изграждане на кривата на мощността на всяка програма и за съпоставяне на завършен цикъл с нея. Ако махнете отметката на даден вид, той спира да оформя програмите ви, без нищо да се изтрива - циклите остават в списъка Цикли и все още могат да бъдат маркирани или премахнати. Полезно, ако не се доверявате на импортираните данни. Статистиката не се влияе: в нея винаги се броят само циклите, които тази машина наистина е изпълнила. Махането на всички отметки се игнорира, защото програма без нито един цикъл никога не би могла да съвпадне."
}
},
"setting_group": {
@@ -1605,6 +1670,9 @@
},
"basic_configuration": {
"label": "Основна конфигурация"
},
"profile_evidence": {
"label": "Основа на профила"
}
},
"status": {
@@ -1626,10 +1694,11 @@
"analyzing": "Анализиране…",
"resetting": "Нулиране…",
"reverting": "Връщане…",
"trimming": "Подрязване…",
"trimming": "Изрязване…",
"splitting": "Разделяне…",
"deleting": "Изтриване…",
"imported": "Импортирано"
"imported": "Импортирано",
"preparing": "Подготовка…"
},
"tab": {
"advanced": "Разширено",
@@ -1659,6 +1728,7 @@
"wrong_profile": "Грешен профил"
},
"toast": {
"catalog_refreshed": "Каталогът на общността е опреснен",
"access_saved": "Контролът на достъпа е запазен",
"all_wiped": "Всички данни са изтрити",
"analysis_complete_none": "Анализът е завършен: няма нови предложения",
@@ -1670,7 +1740,7 @@
"cycle_labelled": "Цикъл с етикет",
"cycle_paused": "Цикълът на пауза",
"cycle_resumed": "Цикълът е възобновен",
"cycle_trimmed": "Цикъл подрязан",
"cycle_trimmed": "Цикълът е изрязан",
"cycles_merged": "Обединени цикли",
"envelope_rebuilt": "Преустроен плик",
"envelopes_rebuilt": "Пликове преустроени",
@@ -1752,19 +1822,21 @@
"rating_saved": "Оценката за качество е запазена",
"brand_added": "Марката е добавена, изчаква одобрение",
"profile_added": "Профилът е добавен, изчаква одобрение",
"saved_except_conflicts": "Настройките са запазени -- {n} настройка{s} пропусната поради конфликти",
"saved_except_conflicts": "Запазено. Поправете маркираните конфликти, за да запазите останалото.",
"share_device_none_sel": "Изберете поне една програма за споделяне",
"store_device_downloaded": "Настройките на устройството са изтеглени: {created} профил{c} създаден, {dup} вече съществуваше",
"store_device_downloaded_phases": "Настройките на устройството са изтеглени: {created} профил{c} създаден, {dup} вече съществуваше, картата на фазите е приложена",
"store_device_downloaded_settings": "Настройките на устройството са изтеглени: {created} профил{c} създаден, {dup} вече съществуваше, настройките са приложени",
"store_device_shared": "Настройките на устройството са споделени: {n} програм{s} качена",
"store_device_shared_all_dup": "Няма нищо ново за споделяне -- всички програми вече съществуват в магазина",
"store_device_shared_partial": "Частично споделяне: {n} програм{s} качена, {failed} пропуснати",
"store_device_shared_some_dup": "Настройките на устройството са споделени: {n} програм{s} качена ({dup} вече съществуваше)",
"store_device_downloaded": "Добавено: програми {p}, записи {c}",
"store_device_downloaded_phases": "Добавено: програми {p}, записи {c}, карти на фазите {ph}",
"store_device_downloaded_settings": "Добавено: програми {p}, записи {c}, карти на фазите {ph}, настройки {s}",
"store_device_shared": "Цикли, споделени в магазина на общността: {n}. Предстои преглед.",
"store_device_shared_all_dup": "Всички цикли ({n}) вече бяха в магазина на общността.",
"store_device_shared_partial": "Споделени цикли: {n}; неуспешно качени: {failed}.",
"store_device_shared_some_dup": "Споделени цикли: {created}; вече бяха в магазина: {dup}.",
"store_download_failed": "Грешка при изтегляне: {error}",
"store_download_nothing": "Няма какво да се изтегля -- всички профили вече съществуват на това устройство",
"export_selective_done": "Експортът е изтеглен",
"import_selective_done": "Импортирани са {profiles} профил(а) и {cycles} цикъл(а)"
"import_selective_done": "Импортирани са {profiles} профил(а) и {cycles} цикъл(а)",
"hist_csv_required": "Първо заредете CSV файл или поставете съдържанието му",
"file_read_failed": "Файлът не можа да бъде прочетен"
},
"suggestion": {
"both_agree": "WashData препоръчва",
@@ -1860,7 +1932,7 @@
"thr_batch": "Задържано точно над най-ниската работна мощност p05 за {cycles} цикъла ({p05}W), за да се улови стартът възможно най-рано и прагът на спиране да остане под най-ниската работна мощност на машината.",
"tol_per_profile": "p75 на дисперсията на продължителността по профил за {profiles} профила ({cycles} цикъла); стриктните профили не се санкционират.",
"tol_pooled": "Въз основа на обединената дисперсия на продължителността на {cycles} скорошни етикетирани цикъла (p95 отклонение={dev}).",
"watchdog": "Задържано възможно най-ниско при запазена безопасност (малко над интервала на обновяване p95 от {p95}s, мин. 30s), за да се улавят бързо блокиранията без фалшиви спирания."
"watchdog": "Задържано възможно най-ниско при запазена безопасност (малко над интервала на обновяване p95 от {p95}s и поне 2x интервала на вземане на проби от {median}s, мин. 30s), за да се улавят бързо блокиранията без фалшиви спирания."
},
"exclusions": {
"summary": "Изключени са {total} грешно открити цикъла: {parts}.",
@@ -1892,6 +1964,7 @@
},
"pg_desc": {
"dishwasher_end_spike_quiet_release": "Съдомиялна машина: секунди неактивност след очакваната продължителност, преди да се освободи изчакването за източване в края на цикъла",
"smart_termination_duration_ratio": "Дял от очакваната продължителност на съпоставената програма, който цикълът трябва да достигне, преди Интелигентното прекратяване да може да го завърши предсрочно; намалете го за машини, зависещи от натоварването или температурата",
"completion_min_seconds": "Най-краткото изпълнение, което се счита за истински цикъл",
"end_repeat_count": "Ниски отчитания поред преди приключване",
"interrupted_min_seconds": "Кратки цикли се отбелязват като прекъснати",
@@ -1955,6 +2028,10 @@
"finished": "Цикълът достигна крайно състояние и приключи."
},
"store": {
"your_model_tip": "Това е уредът, който сте задали в настройките",
"your_model": "Ваш",
"search_brand_ph": "Търсене по марка…",
"programs_count": "Програми: {n}",
"browse": "Разглеждане",
"device": "Уред",
"favorites": "Любими",
@@ -78,9 +78,12 @@
"awaiting": "Čeka odobrenje",
"imported_tip": "Uvezeno iz zajedničke trgovine. Koristi se samo za podudaranje, ne broji se u statistiku.",
"not_importable": "nije dostupno",
"exists": "postoji"
"exists": "postoji",
"backfilled_tip": "Otkriveno u uvezenoj historiji snage. Utiče samo na podudaranje programa, ne broji se u statistiku."
},
"btn": {
"set_brand_model": "Postavi marku i model",
"refresh_catalog": "Osvježi katalog",
"add_device": "+ Dodaj uređaj",
"add_device_tip": "Dodajte još jedan WashData uređaj",
"add_maintenance": "Dodaj događaj održavanja",
@@ -234,14 +237,19 @@
"download_device": "Preuzmi postavke uređaja",
"share_device": "Podijeli postavke uređaja",
"share_device_tip": "Podijelite programe i postavke ovog uređaja sa zajednicom",
"share_n": "Podijeli {n} program{s}",
"share_n": "Podijeli cikluse ({n})",
"export_selected": "Izvoz (odaberi podatke)",
"export_all": "Brzi izvoz svega",
"import_raw": "Napredno: zamijeni sve iz JSON datoteke",
"download_export": "Preuzmi izvoz",
"analyze_import": "Analiziraj datoteku",
"import_selected": "Uvezi odabrano",
"back": "Nazad"
"back": "Nazad",
"import_power_history": "Uvezi historiju snage",
"hist_read_recorder": "Pročitaj iz Home Assistant",
"hist_scan": "Potraži cikluse",
"hist_import_n": "Uvezi cikluse: {n}",
"hist_goto_cycles": "Prikaži cikluse"
},
"conflict": {
"anti_wrinkle_exit": {
@@ -253,12 +261,12 @@
"start": "Mora biti ispod Maks. snage anti-gužvanja ({max} W)"
},
"attn_sub": "Ispravite konflikte prije pohrane",
"attn_title": "{n} konflikt{s} postavki",
"attn_title": "Konflikti postavki: {n}",
"confidence": {
"auto": "Mora biti na razini ili iznad Praga podudaranja ({match})",
"learning": "Mora biti na razini ili ispod Praga podudaranja ({match})",
"learning": "Mora biti na razini ili iznad Praga podudaranja ({match})",
"match_for_auto": "Mora biti na razini ili ispod Pouzdanosti automatskog označavanja ({alc})",
"match_for_learning": "Mora biti na razini ili iznad Pouzdanosti učenja ({lc})"
"match_for_learning": "Mora biti na razini ili ispod Pouzdanosti učenja ({lc})"
},
"duration_ratio": {
"max": "Mora biti veće od Min. omjera trajanja ({min})",
@@ -296,14 +304,14 @@
"match": "Mora biti iznad Praga nepodudaranja ({un})",
"unmatch": "Mora biti ispod Praga podudaranja ({match}); inače se potvrđeno podudaranje odmah poništava"
},
"cascade_toast": "Radi dosljednosti, automatski je podešeno još {n} postavki.",
"cascade_toast": "Druge postavke prilagođene radi dosljednosti: {n}",
"suggestion_resolves": "Primijenite prijedlog na čekanju ({val}) ispod za rješavanje ovog sukoba",
"use_fix": "Koristite {val}",
"watchdog": {
"interval": "Treba biti najmanje 2× Interval uzorkovanja ({si} s)",
"sampling": "Interval uzorkovanja treba biti najviše polovina Intervala čuvara ({wi} s)"
},
"settings_banner": "{n} konflikt{s} postavki provjerite istaknute sekcije i ispravite prije pohrane.",
"settings_banner": "Konflikti postavki: {n}. Provjerite istaknute sekcije i ispravite ih prije pohrane.",
"settings_banner_btn": "Idi na prvi"
},
"hdr": {
@@ -356,7 +364,8 @@
"pg_outcome": "Ishod simulacije",
"pg_across_cycles": "Kroz sve vaše cikluse",
"community_store": "Zajednička trgovina",
"online_account": "Zajednička trgovina i online funkcije"
"online_account": "Zajednička trgovina i online funkcije",
"import_power_history": "Uvoz historije snage"
},
"health": {
"fair": "Prihvatljiva kvaliteta podudaranja",
@@ -364,6 +373,7 @@
"poor": "⚠ Loša kvaliteta podudaranja"
},
"lbl": {
"drag_to_resize": "Prevucite za promjenu veličine",
"actions": "Akcije",
"activity": "Aktivnost",
"administrators": "Administratori",
@@ -435,7 +445,7 @@
"from": "Od",
"gap_s": "jaz (s)",
"group_name": "Naziv grupe",
"head_trim": "Trim (s) glave",
"head_trim": "Skraćivanje početka (s)",
"health": "Zdravlje",
"hide_tabs": "Sakrij kartice za neadministratore",
"in_use": "U upotrebi",
@@ -451,7 +461,7 @@
"metric": "Metrika",
"mode_existing_profile": "Dodaj postojećem profilu",
"mode_new_profile": "Kreirajte novi profil",
"models_fine_tuned": "({count} modela fino podešenih)",
"models_fine_tuned": "(fino podešeni modeli: {count})",
"n_classic_suggestions": "{n} klasičan",
"n_ml_suggestions": "{n} ML",
"n_selected": "{n} odabrano",
@@ -533,7 +543,7 @@
"stage3": "Faza 3 DTW",
"stage4": "Faza 4 slaganje",
"status": "Status",
"tail_trim": "Obrub repa (s)",
"tail_trim": "Skraćivanje kraja (s)",
"timer_auto_pause": "Automatska pauza",
"timer_min": "min",
"timer_msg_placeholder": "Poruka (opcionalno, {device}/{program}/{minutes})",
@@ -651,7 +661,7 @@
"show_contributor": "Prikaži doprinositelja",
"task_pg_detail": "Simuliraj ciklus",
"task_split": "Dijeljenje ciklusa",
"task_trim": "Obrezivanje ciklusa",
"task_trim": "Skraćivanje ciklusa",
"task_merge": "Spajanje ciklusa",
"task_rebuild": "Ponovna izgradnja omotača",
"cat_profiles": "Profili (programi)",
@@ -677,7 +687,26 @@
"conflict_resolution": "Sukobi naziva",
"conflict_import_copy": "Uvezi kao kopiju",
"conflict_keep_mine": "Zadrži moje",
"conflict_overwrite": "Prepiši"
"conflict_overwrite": "Prepiši",
"hist_csv_data": "CSV podaci",
"hist_from_recorder": "Ili je pročitajte iz Home Assistant",
"days": "dana",
"hist_keep": "Zadrži ovaj ciklus",
"hist_looks_complete": "završen",
"peak_power_short": "Vrh",
"shape": "Oblik",
"hist_skip_idle": "uređaj nije radio",
"hist_skip_sparse": "očitanja predaleko jedno od drugog",
"hist_skip_short": "nedovoljno očitanja",
"hist_skip_long": "nema dovoljno duge pauze za razdvajanje",
"hist_reason_short": "kraći od najkraćeg stvarnog ciklusa ovog uređaja",
"hist_reason_no_end": "nikada se nije pravilno završio",
"hist_since": "Od",
"task_history_import": "Pretraživanje historije snage",
"task_history_import_apply": "Uvoz ciklusa",
"evidence_real_cycles": "Ciklusi koje je izvršila ova mašina",
"evidence_reference_cycles": "Preuzeti iz zajedničke trgovine",
"evidence_backfill_cycles": "Pronađeni u uvezenoj historiji snage"
},
"log": {
"all_levels": "Svi nivoi",
@@ -756,9 +785,15 @@
"store_share": "Podijeli u zajedničku trgovinu",
"store_share_device": "Podijeli postavke uređaja",
"export_select": "Izvoz - odaberi podatke",
"import_wizard": "Uvoz - odaberi podatke"
"import_wizard": "Uvoz - odaberi podatke",
"history_import": "Uvoz historije snage"
},
"msg": {
"tail_trim_hint": "Uklonite ovoliko sekundi sa kraja",
"store_sibling_hint": "Nema ničega podijeljenog za vaš tačan model? Blisko srodan model iste marke obično je dobra početna tačka.",
"store_declare_appliance": "Recite integraciji WashData koji uređaj posjedujete i ova kartica prikazat će konfiguracije koje su drugi podijelili za njega. Možete i upisati marku iznad kako biste pregledali katalog.",
"refresh_catalog_hint": "Liste marki i uređaja zajednice privremeno se čuvaju kako bi zajednička trgovina ostala u okviru svog dnevnog ograničenja. Osvježite da preuzmete unose koje su drugi dodali ili odobrili.",
"head_trim_hint": "Uklonite ovoliko sekundi sa početka",
"appliance_monitor": "Monitor uređaja",
"artifact_dip_detail": "Pao ispod uobičajenog pojasa snage za ~{n}s.",
"artifact_footer": "Istaknuto na grafikonu iznad. To su prolazni artefakti (npr. vrata se otvaraju usred ciklusa), ne nužno problemi.",
@@ -769,7 +804,7 @@
"automations_intro": "WashData pokreće događaje {start} / {end} i izlaže entitete, pa je obavijesti i radnje najbolje graditi kao normalne automatizacije Home Assistanta. Automatizacije koje koriste ovaj uređaj prikazane su ispod.",
"cleanup_intro": "Svaki označeni ciklus se preklapa. Označite nedostatke i izbrišite da biste očistili profil.",
"clear_debug_hint": "Uklonite pohranjene podatke za otklanjanje grešaka kako biste oslobodili prostor.",
"collecting_data": "Prikupljanje podataka: još {need} ciklusa do početka finog podešavanja ({current}/{min}).",
"collecting_data": "Prikupljanje podataka. Još potrebnih ciklusa prije početka finog podešavanja: {need} ({current}/{min}).",
"compare_overlay_profiles": "Profili preklapanja (slabi)",
"compare_profiles_tip": "Prekrijte druge koverte profila na gornjoj tabeli da vidite koja najbolje odgovara ovom ciklusu.",
"compare_selected_cycles": "Odabrani ciklusi (puni) prikaži / sakrij",
@@ -779,7 +814,7 @@
"cycles_deleted": "Izbrisano ciklusa: {count}",
"enough_data": "Dovoljno podataka za učenje ({current}/{min} ciklusa).",
"export_description": "Odaberite tačno koje profile, cikluse, postavke i ostalo želite izvesti u JSON datoteku ili analizirajte datoteku i uvezite samo željene dijelove.",
"feedback_cycles_pending": "{n} ciklus{s} za pregled",
"feedback_cycles_pending": "Za pregled: {n}",
"feedback_prompt": "Potvrdite da je ispravno, ispravite program ili zanemarite.",
"feedback_relabel_hint": "Ponovno označavanje ovog ciklusa takođe ga rješava.",
"filter_by_profile": "Filtriraj po profilu…",
@@ -793,7 +828,7 @@
"loading_curve": "Učitavanje krivulje…",
"loading_settings": "Učitavanje postavki…",
"log_buffer_hint": "Najnovije prvo · baferuje poslednjih 500 ha_washdata zapisa od ponovnog pokretanja · prevucite donju ivicu da promenite veličinu.",
"maintenance_advisory": "Povećanje trajanja/energije može ukazivati da je potrebno održavanje uređaja (npr. uklanjanje kamenca, čišćenje filtera).",
"maintenance_advisory": "Povećanje trajanja/energije može ukazivati da je potrebno održavanje uređaja (npr. uklanjanje kamenca, čišćenje filtera).",
"maintenance_due": "Održavanje dospijeva: {items}",
"maintenance_intro": "Zabilježite servis koji obavljate na ovom uređaju i budite podsjećeni kada svaki zadatak ponovo dospije.",
"maintenance_load_error": "Nije moguće učitati podatke o održavanju: {error}",
@@ -830,7 +865,7 @@
"no_split_points": "Još nema podijeljenih bodova.",
"no_suggestions": "Nema aktivnih prijedloga.",
"notify_services_hint": "Koristite ID-ove servisa {entity} (odvojene zarezima za više). Varijable predloška: {vars}.",
"old_actions_warning": "Konfigurisano sa starim uređivačem akcija (sada uklonjeno). I dalje se aktiviraju na događaje ciklusa, ali se više ne mogu uređivati ovdje. Pretvorite ih u normalnu automatizaciju ili ih uklonite.",
"old_actions_warning": "Konfigurisano sa starim uređivačem akcija (sada uklonjeno). I dalje se aktiviraju na događaje ciklusa, ali se više ne mogu uređivati ovdje. Pretvorite ih u normalnu automatizaciju ili ih uklonite.",
"onboarding_progress": "{n} / 3 ciklusa promatrano",
"onboarding_watching": "Pustite uređaj da radi normalno WashData prati. Nakon 3 ciklusa počinje podudaranje programa.",
"pending_feedback": "Čeka se povratna informacija o detekciji",
@@ -856,7 +891,6 @@
"pg_stress_synthetic": "simulacija mirovanja počinje ovdje",
"pg_sweep_intro": "Šta ako bi {param} bio drugačiji? Testirajte {steps} vrijednosti na vaših posljednjih {cycles} ciklusa da pronađete postavku pri kojoj se najviše ciklusa ispravno podudara.",
"pg_sweep_step": "Korak {done} / {total}",
"pg_undetected": "{n} neotkrivenih ciklusa",
"pg_verdict_bad": "Zahtijeva pažnju: mnogi ciklusi ostaju neotkriveni.",
"pg_verdict_good": "Dobro podešeno: većina ciklusa se ispravno prepoznaje i podudara.",
"pg_verdict_ok": "Prihvatljivo: neki ciklusi su propušteni. Pokušajte smanjiti prag pokretanja.",
@@ -888,6 +922,7 @@
"review_recorded_tip": "Označite ovo kao ručno odabran referentni ciklus za njegov program - ista uloga kao i ručno snimljeni ciklus. Referentni ciklusi se uvijek čuvaju, postavljaju podudarni predložak i nikada se ne ispuštaju čišćenjem. (Ovo je \"zlatna\"/snimljena zastava; obje su ista stvar.)",
"review_tags_tip": "Opcione zastavice koje opisuju šta je pošlo po zlu s ovim ciklusom, tako da obuka i čišćenje mogu to objasniti.",
"review_to_cycles": "Otvorite red za pregled ciklusa",
"samples_decimated": "Prikazano {shown} od {total} uzoraka (prorijeđeno za prikaz; vrhovi zadržani). Široki razmak ovdje znači prorjeđivanje, a ne podatke koji nedostaju.",
"saving_triggers_reload": "Spremanje pokreće ponovno učitavanje integracije. HA entiteti se mogu nakratko prikazati kao nedostupni.",
"search_placeholder": "Postavke pretraživanja…",
"see_recorder": "Pogledajte widget snimača ispod",
@@ -991,12 +1026,12 @@
"share_consent": "Dijelite stvarne podatke sa svog uređaja. Ne dijelite ako su vaši obrasci korištenja privatni.",
"share_device_none": "Još nema postavljenih uređaja. Prvo dodajte uređaj.",
"share_guideline_naming": "Koristite jasna imena programa (npr. 'Cotton 40', 'Eco 60') kako bi ih drugi mogli prepoznati",
"share_guideline_quality": "Dijelite samo profile sa ⭐ referentnim ciklusima ili najmanje {n} potvrđenih pokretanja",
"share_guideline_quality": "Dijelite samo cikluse koji su normalno završili -- bez prekida usred ciklusa, otvaranja vrata ili skokova napajanja.",
"share_guideline_review": "Pregledajte profile prije dijeljenja -- uklonite one koji izgledaju pogrešno",
"share_guidelines_title": "Prije dijeljenja",
"store_download_device_intro": "Preuzmite postavke uređaja iz zajednice i primijenite ih na novi ili postojeći uređaj",
"store_share_device_intro": "Podijelite programe svog uređaja (profile + referentne cikluse) sa zajednicom. Postavke su opcione.",
"share_profile_no_cycles": "Profil '{p}' nema referentnih ciklusa -- bit će preskočen osim ako nemate {n}+ potvrđenih pokretanja",
"store_share_device_intro": "Otpremite {brand} {model} s referentnim ciklusima koje odaberete. Drugi s istim uređajem mogu preuzeti vaše programe. Unosi se pregledaju prije nego što postanu javni.",
"share_profile_no_cycles": "Nema referentnih ciklusa - označite ciklus sa ⭐ u kartici Ciklusi da uključite ovaj profil",
"advisory_phase_inconsistent": "Čini se da '{name}' miješa različite programe ili temperature - njegovi ciklusi se griju vrlo različito dugo. Podjela na zasebne profile (npr. po temperaturi) poboljšat će podudaranje i procjene vremena.",
"advisory_phase_inconsistent_title": "⚠ Možda pomiješani programi",
"export_select_intro": "Označite tačno šta treba uključiti. Odabir profila bez njihovih ciklusa i dalje izvozi prepoznatljiv program (njegov naučeni oblik prenosi se s njim).",
@@ -1006,7 +1041,29 @@
"merge_hint": "Uvezene stavke se dodaju; ništa lokalno se ne gubi. Sukobi naziva rješavaju se u nastavku.",
"replace_warn": "Svaka označena kategorija briše se i zamjenjuje podacima iz datoteke. Neoznačene kategorije ostaju nepromijenjene.",
"dest_reference_hint": "Uvezeni ciklusi samo poboljšavaju prepoznavanje programa i nikada ne utiču na statistiku potrošnje/energije.",
"dest_real_history_hint": "Uvezeni ciklusi računaju se kao vlastita historija ovog uređaja i doprinose statistici energije/potrošnje. Koristite pri premještanju jednog uređaja na novu instalaciju."
"dest_real_history_hint": "Uvezeni ciklusi računaju se kao vlastita historija ovog uređaja i doprinose statistici energije/potrošnje. Koristite pri premještanju jednog uređaja na novu instalaciju.",
"import_history_description": "Imali ste pametni utikač i prije WashData? Učitajte izvoz historije njegovog senzora snage ili je pročitajte direktno iz Home Assistant, a obično otkrivanje proći će kroz te podatke, pa će se stari ciklusi pojaviti na vašoj listi Ciklusi, spremni za imenovanje.",
"hist_input_hint": "Učitajte CSV preuzet s panela Historija (entitet, stanje, posljednja promjena) ili pustite WashData da direktno pročita historiju senzora. Otkrivanje se onda izvodi isto kao i uživo, a vi birate koje od pronađenih ciklusa ćete zadržati.",
"hist_recorder_hint": "Čita podatke od izabranog datuma do sada. Home Assistant standardno čuva detaljnu historiju 10 dana, a nakon toga samo satne prosjeke, koji su previše grubi za otkrivanje ciklusa - raniji datum birajte samo ako je vaš recorder postavljen na duže čuvanje.",
"hist_scanning": "Vašu historiju ponovo provodimo kroz detektor. Ovo se izvodi u pozadini - možete zatvoriti ovaj dijalog i vratiti se kasnije.",
"hist_imported_count": "Uvezeni ciklusi: {n}.",
"hist_duplicates": "Već ranije uvezeno i preskočeno: {n}.",
"hist_capped": "Dostignuto je ograničenje uvezenih ciklusa po uređaju; ostatak nije sačuvan.",
"hist_next_step": "Nalaze se na vašoj listi Ciklusi, obilježeni kao uvezena historija. Otvorite jedan i tasterom Označi mu dodijelite naziv programa kojem pripada.",
"hist_rows_read": "Pročitana očitanja: {n}",
"hist_breaks": "Praznine u kojima senzor nije bio dostupan: {n}",
"hist_other_entity": "Zanemarena očitanja drugih entiteta: {n}",
"hist_entity_substituted": "Očitano {used} (ovaj uređaj je postavljen na {wanted})",
"hist_skipped_spans": "Preskočeni dijelovi",
"hist_settings_used": "Otkriveno s trenutnim postavkama ovog uređaja (minimalna snaga {w} W, kašnjenje isključivanja {s} s).",
"hist_none_found": "U toj historiji nije bilo moguće otkriti nijedan ciklus.",
"hist_found": "Pronađeni ciklusi: {n}. Odznačite sve što ne izgleda kao stvarni rad - ništa se ne čuva dok ne uvezete.",
"hist_scan_capped": "Prikazani su samo prvi kandidati (pronađeno je {n}).",
"hist_recorder_empty": "Home Assistant nema detaljnu historiju za ovaj senzor u tom periodu.",
"hist_scan_failed": "Pretraživanje nije uspjelo.",
"hist_scan_expired": "To pretraživanje više nije dostupno. Pokrenite ga ponovo.",
"hist_import_failed": "Uvoz nije uspio.",
"imported_history_readonly": "Otkriveno u uvezenoj historiji snage. Utiče na podudaranje programa, ali se ne broji u vašu statistiku i ne može se skratiti ni podijeliti. Označite ga da mu dodijelite program."
},
"phase_desc": {
"anti_crease": "Povremena kratka spuštanja nakon završetka za smanjenje bora.",
@@ -1173,7 +1230,7 @@
"label": "Broj ponavljanja kraja"
},
"energy_price_entity": {
"doc": "Senzor sa trenutnom cijenom električne energije po kWh (npr. dinamička tarifa). Ima prednost nad statičnom cijenom ispod. Svaki ciklus zamrzava cijenu koja je na snazi kada se završi.",
"doc": "Senzor sa trenutnom cijenom električne energije po kWh (npr. dinamička tarifa). Ima prednost nad statičnom cijenom ispod. Svaki ciklus zamrzava cijenu koja je na snazi kada se završi.",
"label": "Entitet cijene energije"
},
"energy_price_static": {
@@ -1392,6 +1449,10 @@
"doc": "Sačuvajte puni trag napajanja i odgovarajuće podatke za otklanjanje grešaka za svaki ciklus. Korisno za rješavanje problema, ali povećava veličinu skladišta.",
"label": "Sačuvati tragove otklanjanja grešaka"
},
"smart_termination_duration_ratio": {
"doc": "Koliko daleko u očekivanom trajanju podudarajućeg programa ciklus mora biti prije nego što ga Pametni završetak može ranije završiti nakon pada snage. Očekivano trajanje je prosjek programa, pa kod uređaja čije vrijeme rada jako varira - mašine za pranje rublja s hladnom dovodnom vodom zimi u odnosu na toplu ljeti, sušilice sa senzorskim sušenjem, programi ovisni o količini rublja - otprilike polovina svih pokretanja završi kraće od tog prosjeka i nikada ne dobije brzo završavanje, već završi tek putem rezervnog vremenskog ograničenja, nekoliko minuta kasnije. Kod takvih mašina smanjite ovu vrijednost (npr. 0,85) kako bi se ranije završavanje ipak pokrenulo; povećajte je prema 1,0 za oprezniji pristup. Ostavite prazno za zadanu vrijednost (0,98, ili 0,99 za mašine za pranje posuđa). Ciklus može uvijek samo ranije završiti, nikada kasnije, i nikada se ne pokreće kod nejasnog podudaranja ili podudaranja niske pouzdanosti.",
"label": "Omjer pametnog završetka"
},
"smoothing_window": {
"doc": "Koliko je signal sirove snage izglađen. Niska (2) je odzivna, ali bučna; high (5) izglađuje šiljke, ali dodaje zaostajanje.",
"label": "Prozor izglađivanja"
@@ -1522,6 +1583,10 @@
"door_end_dwell_seconds": {
"label": "Zadržavanje otvorenih vrata za završetak",
"doc": "Koliko dugo vrata moraju ostati otvorena prije nego WashData završi ciklus, kada je uključena postavka \"Vrata se automatski otvaraju na kraju\". Dovoljno dugo da se ignorira brzo dodavanje posuđa (zadano 60 s), dovoljno kratko za brz završetak kad mašina otvori vrata."
},
"profile_evidence_sources": {
"label": "Ciklusi koji formiraju program",
"doc": "Koji se ciklusi koriste za izgradnju krivulje snage svakog programa i za podudaranje završenog ciklusa s njom. Kada odznačite neku vrstu, ona više ne utiče na vaše programe, ali se ništa ne briše - ciklusi ostaju na listi Ciklusi i još uvijek se mogu označiti ili izbrisati. Korisno ako ne vjerujete uvezenim podacima. Na statistiku to ne utiče: uvijek se računaju samo ciklusi koje je ova mašina zaista izvršila. Odznačavanje svega se ignoriše jer se program bez ikakvih ciklusa nikada ne bi mogao podudariti."
}
},
"setting_group": {
@@ -1605,6 +1670,9 @@
},
"basic_configuration": {
"label": "Osnovna konfiguracija"
},
"profile_evidence": {
"label": "Podloga profila"
}
},
"status": {
@@ -1626,10 +1694,11 @@
"analyzing": "Analiziranje…",
"resetting": "Resetovanje…",
"reverting": "Vraćanje…",
"trimming": "Obrezivanje…",
"trimming": "Skraćivanje…",
"splitting": "Dijeljenje…",
"deleting": "Brisanje…",
"imported": "Uvezeno"
"imported": "Uvezeno",
"preparing": "Priprema…"
},
"suggestion": {
"both_agree": "WashData preporučuje",
@@ -1725,7 +1794,7 @@
"thr_batch": "Zadržano tik iznad najniže radne snage p05 kroz {cycles} ciklusa ({p05}W) kako bi se početak uhvatio što ranije, a prag zaustavljanja ostao ispod najniže radne snage mašine.",
"tol_per_profile": "p75 varijanse trajanja po profilu kroz {profiles} profila ({cycles} ciklusa); dosljedni profili nisu kažnjeni.",
"tol_pooled": "Na osnovu objedinjene varijanse trajanja {cycles} novijih označenih ciklusa (p95 odstupanje={dev}).",
"watchdog": "Zadržano što nižim uz sigurnost (tik iznad razmaka ažuriranja p95 od {p95}s, najmanje 30s) kako bi se zastoji brzo uhvatili bez lažnih zaustavljanja."
"watchdog": "Zadržano što nižim uz sigurnost (tik iznad razmaka ažuriranja p95 od {p95}s i najmanje 2× intervala uzorkovanja od {median}s, najmanje 30s) kako bi se zastoji brzo uhvatili bez lažnih zaustavljanja."
},
"exclusions": {
"summary": "Isključeno {total} pogrešno otkrivenih ciklusa: {parts}.",
@@ -1772,6 +1841,7 @@
"wrong_profile": "Pogrešan profil"
},
"toast": {
"catalog_refreshed": "Katalog zajednice je osvježen",
"access_saved": "Kontrola pristupa je sačuvana",
"all_wiped": "Svi podaci su izbrisani",
"analysis_complete_none": "Analiza završena: nema novih prijedloga",
@@ -1865,19 +1935,21 @@
"rating_saved": "Ocjena kvaliteta sačuvana",
"brand_added": "Marka dodana, čeka odobrenje",
"profile_added": "Profil dodan, čeka odobrenje",
"saved_except_conflicts": "Postavke sačuvane -- {n} postavka{s} preskočena zbog konflikata",
"saved_except_conflicts": "Sačuvano. Ispravite istaknute konflikte da sačuvate ostalo.",
"share_device_none_sel": "Odaberite barem jedan program za dijeljenje",
"store_device_downloaded": "Postavke uređaja preuzete: {created} profil{c} kreiran, {dup} već postoji",
"store_device_downloaded_phases": "Postavke uređaja preuzete: {created} profil{c} kreiran, {dup} već postoji, mapa faza primijenjena",
"store_device_downloaded_settings": "Postavke uređaja preuzete: {created} profil{c} kreiran, {dup} već postoji, postavke primijenjene",
"store_device_shared": "Postavke uređaja podijeljene: {n} program{s} učitan",
"store_device_shared_all_dup": "Nema ničeg novog za dijeljenje -- svi programi već postoje u prodavnici",
"store_device_shared_partial": "Djelimično dijeljenje: {n} program{s} učitan, {failed} preskočeno",
"store_device_shared_some_dup": "Postavke uređaja podijeljene: {n} program{s} učitan ({dup} već postoji)",
"store_device_downloaded": "Dodano: programi {p}, snimci {c}",
"store_device_downloaded_phases": "Dodano: programi {p}, snimci {c}, mape faza {ph}",
"store_device_downloaded_settings": "Dodano: programi {p}, snimci {c}, mape faza {ph}, postavke {s}",
"store_device_shared": "Ciklusi podijeljeni u zajedničku trgovinu: {n}. Čeka se pregled.",
"store_device_shared_all_dup": "Svi ciklusi ({n}) su već bili u zajedničkoj trgovini.",
"store_device_shared_partial": "Podijeljeni ciklusi: {n}; nije otpremljeno: {failed}.",
"store_device_shared_some_dup": "Podijeljeni ciklusi: {created}; već u trgovini: {dup}.",
"store_download_failed": "Preuzimanje nije uspjelo: {error}",
"store_download_nothing": "Nema ništa za preuzimanje -- svi profili već postoje na ovom uređaju",
"export_selective_done": "Izvoz preuzet",
"import_selective_done": "Uvezeno {profiles} profila i {cycles} ciklusa"
"import_selective_done": "Uvezeno {profiles} profila i {cycles} ciklusa",
"hist_csv_required": "Prvo učitajte CSV fajl ili zalijepite njegov sadržaj",
"file_read_failed": "Nije bilo moguće pročitati taj fajl"
},
"trend": {
"down": "Opadajući trend",
@@ -1892,6 +1964,7 @@
},
"pg_desc": {
"dishwasher_end_spike_quiet_release": "Mašina za pranje posuđa: sekunde tišine nakon očekivanog trajanja prije nego što se otpusti čekanje na završno ispumpavanje vode",
"smart_termination_duration_ratio": "Udio očekivanog trajanja podudarajućeg programa koji ciklus mora dostići prije nego što ga Pametni završetak može ranije završiti; smanjite ga za mašine ovisne o količini rublja ili temperaturi",
"anti_wrinkle_enabled": "Upij impulse bubnja nakon glavne faze, a ne čitaj ih kao nove cikluse",
"anti_wrinkle_exit_power": "Snaga mora pasti ispod ove vrijednosti između impulsa da bi anti-gužvanje ostalo aktivno",
"anti_wrinkle_idle_timeout": "Dozvoljeno vrijeme mirovanja između dva impulsa bubnja prije nego što se anti-gužvanje završi",
@@ -1955,6 +2028,10 @@
"finished": "Ciklus je dostigao završno stanje i završio."
},
"store": {
"your_model_tip": "Ovo je uređaj koji ste naveli u Postavkama",
"your_model": "Vaš",
"search_brand_ph": "Pretraži po marki…",
"programs_count": "Programi: {n}",
"browse": "Pregledaj",
"device": "Uređaj",
"favorites": "Favoriti",
@@ -1993,6 +2070,7 @@
"add_profile": "Dodajte profil za ovaj uređaj na web-stranici zajednice"
},
"task": {
"cancelling": "Otkazivanje...",
"reprocess": {
"matching": "Ponovna obrada: podudaranje ciklusa",
"golden": "Ponovna obrada: popunjavanje referentnih",
@@ -2010,7 +2088,7 @@
"apply": "Dijeljenje ciklusa"
},
"trim": {
"apply": "Obrezivanje ciklusa"
"apply": "Skraćivanje ciklusa"
},
"merge": {
"apply": "Spajanje ciklusa"
@@ -78,9 +78,12 @@
"awaiting": "Čeká na schválení",
"imported_tip": "Importováno z komunitního obchodu. Používá se pouze pro porovnávání, nezapočítává se do statistik.",
"not_importable": "nedostupné",
"exists": "existuje"
"exists": "existuje",
"backfilled_tip": "Detekováno v importované historii výkonu. Ovlivňuje pouze přiřazování programů, nezapočítává se do statistik."
},
"btn": {
"set_brand_model": "Nastavit značku a model",
"refresh_catalog": "Obnovit katalog",
"add_device": "+ Přidat zařízení",
"add_device_tip": "Přidejte další zařízení WashData",
"add_maintenance": "Přidat údržbovou událost",
@@ -234,14 +237,19 @@
"download_device": "Stáhnout nastavení zařízení",
"share_device": "Sdílet nastavení zařízení",
"share_device_tip": "Sdílet programy a nastavení tohoto zařízení s komunitou",
"share_n": "Sdílet {n} program{s}",
"share_n": "Sdílet cykly: {n}",
"export_selected": "Export (vybrat data)",
"export_all": "Rychlý export všeho",
"import_raw": "Pokročilé: nahradit vše ze souboru JSON",
"download_export": "Stáhnout export",
"analyze_import": "Analyzovat soubor",
"import_selected": "Importovat vybrané",
"back": "Zpět"
"back": "Zpět",
"import_power_history": "Importovat historii výkonu",
"hist_read_recorder": "Načíst z Home Assistant",
"hist_scan": "Vyhledat cykly",
"hist_import_n": "Importovat cykly: {n}",
"hist_goto_cycles": "Zobrazit cykly"
},
"conflict": {
"anti_wrinkle_exit": {
@@ -253,12 +261,12 @@
"start": "Musí být pod Max. výkonem ochrany před zmačkáním ({max} W)"
},
"attn_sub": "Před uložením opravte konflikty",
"attn_title": "{n} konflikt{s} nastavení",
"attn_title": "Konflikty nastavení: {n}",
"confidence": {
"auto": "Musí být na nebo nad Prahem shody ({match})",
"learning": "Musí být na nebo pod Prahem shody ({match})",
"learning": "Musí být na nebo nad Prahem shody ({match})",
"match_for_auto": "Musí být na nebo pod Důvěrou auto-označení ({alc})",
"match_for_learning": "Musí být na nebo nad Důvěrou učení ({lc})"
"match_for_learning": "Musí být na nebo pod Důvěrou učení ({lc})"
},
"duration_ratio": {
"max": "Musí být větší než Min. poměr délky ({min})",
@@ -296,14 +304,14 @@
"match": "Musí být nad Prahem neshody ({un})",
"unmatch": "Musí být pod Prahem shody ({match}); jinak potvrzená shoda se okamžitě zruší"
},
"cascade_toast": "Bylo také upraveno {n} nastavení pro zachování konzistence.",
"cascade_toast": "Další nastavení upravena pro zachování konzistence: {n}",
"suggestion_resolves": "Uplatněte níže čekající návrh ({val}) pro vyřešení tohoto konfliktu",
"use_fix": "Použít {val}",
"watchdog": {
"interval": "Měl by být alespoň 2× Interval vzorkování ({si} s)",
"sampling": "Interval vzorkování by měl být nejvýše polovina Intervalu hlídače ({wi} s)"
},
"settings_banner": "{n} konflikt{s} nastavení zkontrolujte zvýrazněné sekce a opravte před uložením.",
"settings_banner": "Konflikty nastavení: {n}. Zkontrolujte zvýrazněné sekce a opravte je před uložením.",
"settings_banner_btn": "Přejít na první"
},
"hdr": {
@@ -356,7 +364,8 @@
"pg_outcome": "Výsledek simulace",
"pg_across_cycles": "Napříč vašimi cykly",
"community_store": "Komunitní obchod",
"online_account": "Komunitní obchod a online funkce"
"online_account": "Komunitní obchod a online funkce",
"import_power_history": "Import historie výkonu"
},
"health": {
"fair": "Přijatelná shoda",
@@ -364,6 +373,7 @@
"poor": "⚠ Špatná shoda"
},
"lbl": {
"drag_to_resize": "Přetažením změníte velikost",
"actions": "Akce",
"activity": "Aktivita",
"administrators": "Správci",
@@ -435,7 +445,7 @@
"from": "Od",
"gap_s": "mezera (y)",
"group_name": "Název skupiny",
"head_trim": "Obložení hlavy (y)",
"head_trim": "Oříznutí začátku (s)",
"health": "Zdraví",
"hide_tabs": "Skrýt karty pro neadministrátory",
"in_use": "Používá se",
@@ -451,7 +461,7 @@
"metric": "Metrika",
"mode_existing_profile": "Přidat do stávajícího profilu",
"mode_new_profile": "Vytvořit nový profil",
"models_fine_tuned": "({count} modelů doladěno)",
"models_fine_tuned": "(doladěné modely: {count})",
"n_classic_suggestions": "{n} klasický",
"n_ml_suggestions": "{n} ML",
"n_selected": "{n} vybráno",
@@ -533,7 +543,7 @@
"stage3": "Fáze 3 DTW",
"stage4": "Fáze 4 shoda",
"status": "Stav",
"tail_trim": "Trimování ocasu (y)",
"tail_trim": "Oříznutí konce (s)",
"timer_auto_pause": "Automatická pauza",
"timer_min": "min",
"timer_msg_placeholder": "Zpráva (volitelné, {device}/{program}/{minutes})",
@@ -677,7 +687,26 @@
"conflict_resolution": "Konflikty názvů",
"conflict_import_copy": "Importovat jako kopii",
"conflict_keep_mine": "Ponechat moje",
"conflict_overwrite": "Přepsat"
"conflict_overwrite": "Přepsat",
"hist_csv_data": "Data CSV",
"hist_from_recorder": "Nebo ji načtěte z Home Assistant",
"days": "dní",
"hist_keep": "Zachovat tento cyklus",
"hist_looks_complete": "dokončený",
"peak_power_short": "Špička",
"shape": "Tvar",
"hist_skip_idle": "nic neběželo",
"hist_skip_sparse": "měření příliš daleko od sebe",
"hist_skip_short": "příliš málo měření",
"hist_skip_long": "žádná dost dlouhá pauza pro rozdělení",
"hist_reason_short": "kratší než nejkratší skutečný cyklus tohoto spotřebiče",
"hist_reason_no_end": "nikdy řádně neskončil",
"hist_since": "Od",
"task_history_import": "Prohledávání historie výkonu",
"task_history_import_apply": "Import cyklů",
"evidence_real_cycles": "Cykly, které tento spotřebič provedl",
"evidence_reference_cycles": "Stažené z komunitního obchodu",
"evidence_backfill_cycles": "Nalezené v importované historii výkonu"
},
"log": {
"all_levels": "Všechny úrovně",
@@ -756,9 +785,15 @@
"store_share": "Sdílet do komunitního obchodu",
"store_share_device": "Sdílet nastavení zařízení",
"export_select": "Export - vybrat data",
"import_wizard": "Import - vybrat data"
"import_wizard": "Import - vybrat data",
"history_import": "Import historie výkonu"
},
"msg": {
"tail_trim_hint": "Kolik sekund odstranit z konce",
"store_sibling_hint": "Pro váš konkrétní model není nic nasdíleno? Velmi podobný model od stejné značky je obvykle dobrý výchozí bod.",
"store_declare_appliance": "Řekněte WashData, jaký spotřebič máte, a tato karta zobrazí nastavení, která pro něj nasdíleli ostatní uživatelé. Můžete také zadat značku výše a jen se rozhlédnout.",
"refresh_catalog_hint": "Seznamy značek a spotřebičů z komunity se ukládají do mezipaměti, aby sdílený obchod nepřekročil svůj denní limit dotazů. Obnovením načtete položky, které ostatní přidali nebo schválili.",
"head_trim_hint": "Kolik sekund odstranit ze začátku",
"appliance_monitor": "Monitor spotřebiče",
"artifact_dip_detail": "Klesl pod obvyklé pásmo výkonu po dobu ~{n} s.",
"artifact_footer": "Zvýrazněno na grafu výše. Jedná se o přechodné artefakty (např. dveře otevřené uprostřed cyklu), ne nutně problémy.",
@@ -769,7 +804,7 @@
"automations_intro": "WashData vyvolává události {start} / {end} a zpřístupňuje entity. Oznámení a akce se nejlépe nastavují jako standardní automatizace Home Assistant. Automatizace používající toto zařízení se zobrazují níže.",
"cleanup_intro": "Každý označený cyklus se překrývá. Zaškrtnutím odlehlých hodnot a odstraněním se profil vyčistí.",
"clear_debug_hint": "Odstraňte uložená ladicí data, abyste uvolnili místo.",
"collecting_data": "Shromažďování dat: ještě {need} cyklů do zahájení jemného doladění ({current}/{min}).",
"collecting_data": "Shromažďování dat. Zbývající cykly do zahájení doladění: {need} ({current}/{min}).",
"compare_overlay_profiles": "Překryvné profily (slabé)",
"compare_profiles_tip": "Překryjte další obálky profilu na výše uvedené tabulce a zjistěte, která z nich nejlépe vyhovuje tomuto cyklu.",
"compare_selected_cycles": "Vybrané cykly (plné) zobrazit / skrýt",
@@ -779,7 +814,7 @@
"cycles_deleted": "Smazáno cyklů: {count}",
"enough_data": "Dostatek dat k učení ({current}/{min} cyklů).",
"export_description": "Vyberte přesně, které profily, cykly, nastavení a další data exportovat do souboru JSON, nebo analyzujte soubor a importujte jen ty části, které chcete.",
"feedback_cycles_pending": "{n} cyklus{s} ke kontrole",
"feedback_cycles_pending": "Ke kontrole: {n}",
"feedback_prompt": "Potvrďte, že to bylo správné, opravte program nebo jej ignorujte.",
"feedback_relabel_hint": "Přeznačení tohoto cyklu jej také vyřeší.",
"filter_by_profile": "Filtrovat podle profilu…",
@@ -856,7 +891,6 @@
"pg_stress_synthetic": "simulace nečinnosti začíná zde",
"pg_sweep_intro": "Co kdyby {param} byl jiný? Otestujte {steps} hodnot na vašich posledních {cycles} cyklech a najděte nastavení, při kterém je správně spárováno nejvíce cyklů.",
"pg_sweep_step": "Krok {done} / {total}",
"pg_undetected": "{n} nedetekovaných cyklů",
"pg_verdict_bad": "Vyžaduje pozornost: mnoho cyklů zůstává nedetekováno.",
"pg_verdict_good": "Dobře vyladěno: většina cyklů je správně rozpoznána a spárována.",
"pg_verdict_ok": "Přijatelné: některé cykly nebyly zachyceny. Zkuste snížit práh spuštění.",
@@ -888,6 +922,7 @@
"review_recorded_tip": "Označte to jako ručně vybraný referenční cyklus pro svůj program stejná role jako ručně zaznamenaný cyklus. Referenční cykly jsou vždy zachovány, nasazují odpovídající šablonu a při čištění se nikdy nevynechají. (Toto je \"zlatá\" / zaznamenaná vlajka; obě jsou totéž.)",
"review_tags_tip": "Volitelné příznaky popisující, co se v tomto cyklu pokazilo, takže za to může školení a čištění.",
"review_to_cycles": "Otevřete frontu kontroly cyklů",
"samples_decimated": "Zobrazeno {shown} z {total} vzorků (prořídnuto pro zobrazení; špičky zachovány). Široká mezera zde znamená prořídnutí, nikoli chybějící data.",
"saving_triggers_reload": "Uložení spustí opětovné načtení integrace. Entity HA se mohou krátce zobrazit jako nedostupné.",
"search_placeholder": "Vyhledávání nastavení…",
"see_recorder": "Viz widget rekordéru níže",
@@ -991,12 +1026,12 @@
"share_consent": "Sdílíte skutečná data ze svého spotřebiče. Nesdílejte, pokud jsou vaše vzorce používání soukromé.",
"share_device_none": "Zatím nejsou nastavena žádná zařízení. Nejprve přidejte zařízení.",
"share_guideline_naming": "Používejte srozumitelné názvy programů (např. 'Cotton 40', 'Eco 60'), aby je ostatní mohli identifikovat",
"share_guideline_quality": "Sdílejte pouze profily s ⭐ referenčními cykly nebo alespoň {n} potvrzeného spuštění",
"share_guideline_quality": "Sdílejte pouze cykly, které proběhly normálně: bez přerušení uprostřed cyklu, otevření dvířek nebo krátkých výpadků napáje.",
"share_guideline_review": "Před sdílením zkontrolujte své profily -- odstraňte ty, které vypadají špatně",
"share_guidelines_title": "Před sdílením",
"store_download_device_intro": "Stáhnout nastavení zařízení komunity a použít ho na nové nebo stávající zařízení",
"store_share_device_intro": "Sdílet programy vašeho zařízení (profily + referenční cykly) s komunitou. Nastavení jsou volitelná.",
"share_profile_no_cycles": "Profil '{p}' nemá žádné referenční cykly -- bude přeskočen, pokud nemáte {n}+ potvrzených spuštění",
"store_share_device_intro": "Nahrajte {brand} {model} s referenčními cykly, které vyberete. Ostatní se stejným spotřebičem mohou vaše programy přijmout. Záznamy jsou před zveřejněním zkontrolovány.",
"share_profile_no_cycles": "Žádné referenční cykly. Chcete-li tento profil zahrnout, označte cyklus jako ⭐ na kartě Cykly",
"advisory_phase_inconsistent": "Zdá se, že '{name}' míchá různé programy nebo teploty - jeho cykly se ohřívají po velmi různě dlouhou dobu. Rozdělení na samostatné profily (např. podle teploty) zlepší shodu i odhady času.",
"advisory_phase_inconsistent_title": "⚠ Možná smíšené programy",
"export_select_intro": "Zaškrtněte přesně to, co má být zahrnuto. Výběr profilů bez jejich cyklů stále exportuje rozpoznatelný program (jeho naučená křivka se přenese s ním).",
@@ -1006,7 +1041,29 @@
"merge_hint": "Importované položky se přidají; nic místního se neztratí. Konflikty názvů se řeší níže.",
"replace_warn": "Každá zaškrtnutá kategorie se vymaže a nahradí daty ze souboru. Nezaškrtnuté kategorie zůstanou beze změny.",
"dest_reference_hint": "Importované cykly pouze zlepšují rozpoznávání programů a nikdy neovlivňují statistiky spotřeby/energie.",
"dest_real_history_hint": "Importované cykly se počítají jako vlastní historie tohoto zařízení a přispívají do statistik energie/spotřeby. Použijte při přesunu jednoho spotřebiče do nové instalace."
"dest_real_history_hint": "Importované cykly se počítají jako vlastní historie tohoto zařízení a přispívají do statistik energie/spotřeby. Použijte při přesunu jednoho spotřebiče do nové instalace.",
"import_history_description": "Měli jste chytrou zástrčku už před WashData? Nahrajte export historie jejího snímače výkonu nebo ji načtěte přímo z Home Assistant a proběhne nad ní běžná detekce, takže se dřívější cykly objeví v seznamu Cykly připravené k pojmenování.",
"hist_input_hint": "Nahrajte CSV stažené z panelu Historie (entita, stav, poslední změna), nebo nechte WashData načíst historii snímače přímo. Detekce pak proběhne úplně stejně jako naživo a vy vyberete, které z nalezených cyklů zachovat.",
"hist_recorder_hint": "Načte data od zvoleného data až do teď. Home Assistant ve výchozím nastavení uchovává podrobnou historii 10 dní a poté už jen hodinové průměry, které jsou pro detekci cyklů příliš hrubé - dřívější datum volte jen tehdy, pokud máte recorder nastavený na delší uchovávání.",
"hist_scanning": "Přehráváme vaši historii přes detektor. Běží to na pozadí - tento dialog můžete zavřít a vrátit se k němu později.",
"hist_imported_count": "Importované cykly: {n}.",
"hist_duplicates": "Již dříve importováno a přeskočeno: {n}.",
"hist_capped": "Byl dosažen limit importovaných cyklů na zařízení; zbytek nebyl uložen.",
"hist_next_step": "Najdete je v seznamu Cykly, označené jako importovaná historie. Otevřete některý z nich a tlačítkem Označit pojmenujte program, ke kterému patří.",
"hist_rows_read": "Přečtená měření: {n}",
"hist_breaks": "Mezery, kdy byl snímač nedostupný: {n}",
"hist_other_entity": "Ignorovaná měření jiných entit: {n}",
"hist_entity_substituted": "Načteno {used} (toto zařízení má nastavené {wanted})",
"hist_skipped_spans": "Přeskočené úseky",
"hist_settings_used": "Detekováno s aktuálním nastavením tohoto zařízení (minimální výkon {w} W, zpoždění vypnutí {s} s).",
"hist_none_found": "V této historii se nepodařilo detekovat žádné cykly.",
"hist_found": "Nalezené cykly: {n}. Odškrtněte vše, co nevypadá jako skutečný běh - dokud neprovedete import, nic se neuloží.",
"hist_scan_capped": "Zobrazují se jen první kandidáti (nalezeno bylo {n}).",
"hist_recorder_empty": "Home Assistant nemá pro tento snímač v daném období žádnou podrobnou historii.",
"hist_scan_failed": "Vyhledávání se nezdařilo.",
"hist_scan_expired": "Toto vyhledávání už není dostupné. Spusťte je prosím znovu.",
"hist_import_failed": "Import se nezdařil.",
"imported_history_readonly": "Detekováno v importované historii výkonu. Ovlivňuje přiřazování programů, ale nezapočítává se do vašich statistik a nelze jej oříznout ani rozdělit. Označením mu přiřaďte program."
},
"phase_desc": {
"anti_crease": "Občasné krátké otáčení bubnu po dokončení cyklu pro prevenci mačkání.",
@@ -1392,6 +1449,10 @@
"doc": "Ukládejte plný záznam příkonu a ladicí data párování pro každý cyklus. Užitečné pro odstraňování problémů, ale zvyšuje velikost úložiště.",
"label": "Uložit ladící stopy"
},
"smart_termination_duration_ratio": {
"doc": "Jak daleko v očekávané době trvání přiřazeného programu musí cyklus být, než jej Chytré ukončení může po poklesu příkonu ukončit dříve. Očekávaná doba trvání je průměr programu, takže u spotřebičů, jejichž doba běhu hodně kolísá - pračky se studenou přiváděnou vodou v zimě oproti teplé v létě, sušičky se senzorovým sušením, programy závislé na náplni - skončí zhruba polovina všech běhů dříve než tento průměr a nikdy se rychlého ukončení nedočká, takže skončí až o několik minut později přes záložní časový limit. U takových strojů tuto hodnotu snižte (např. 0,85), aby se dřívější ukončení přesto spustilo; pro opatrnější chování ji zvyšte směrem k 1,0. Ponechte prázdné pro výchozí hodnotu (0,98, u myček nádobí 0,99). Cyklus může vždy jen ukončit dříve, nikdy později, a nikdy se nespustí u nejednoznačné shody nebo shody s nízkou spolehlivostí.",
"label": "Poměr chytrého ukončení"
},
"smoothing_window": {
"doc": "Míra vyhlazení nezpracovaného signálu příkonu. Nízká hodnota (2) je citlivá, ale hlučná; vysoká (5) vyhlazuje špičky, ale přidává zpozdění.",
"label": "Okno vyhlazení"
@@ -1522,6 +1583,10 @@
"door_end_dwell_seconds": {
"label": "Čekání na otevření dveří pro ukončení",
"doc": "Jak dlouho musí dveře zůstat otevřené, než WashData ukončí cyklus, pokud je zapnuta funkce \"Dveře se na konci automaticky otevřou\". Dostatečně dlouhé k ignorování rychlého přidání nádobí (výchozí 60 s), dostatečně krátké pro rychlé ukončení po otevření dveří spotřebičem."
},
"profile_evidence_sources": {
"label": "Cykly tvořící program",
"doc": "Které cykly se používají k sestavení křivky výkonu každého programu a k přiřazení dokončeného cyklu k ní. Když některý druh odškrtnete, přestane ovlivňovat vaše programy, ale nic se nesmaže - cykly zůstanou v seznamu Cykly a stále je lze označit nebo odstranit. Užitečné, pokud nedůvěřujete importovaným datům. Statistiky to neovlivní: vždy počítají jen cykly, které tento spotřebič skutečně provedl. Odškrtnutí všech možností se ignoruje, protože program bez cyklů by nikdy nemohl být přiřazen."
}
},
"setting_group": {
@@ -1605,6 +1670,9 @@
},
"basic_configuration": {
"label": "Základní konfigurace"
},
"profile_evidence": {
"label": "Podklady profilu"
}
},
"status": {
@@ -1629,7 +1697,8 @@
"trimming": "Ořezávání…",
"splitting": "Rozdělování…",
"deleting": "Mazání…",
"imported": "Importováno"
"imported": "Importováno",
"preparing": "Příprava…"
},
"suggestion": {
"both_agree": "WashData doporučuje",
@@ -1725,7 +1794,7 @@
"thr_batch": "Ponecháno těsně nad nejnižším činným výkonem p05 napříč {cycles} cykly ({p05}W), aby byl start zachycen co nejdříve a práh zastavení zůstal pod nejnižším provozním výkonem stroje.",
"tol_per_profile": "p75 rozptylu délky podle profilu napříč {profiles} profily ({cycles} cyklů); konzistentní profily nejsou penalizovány.",
"tol_pooled": "Na základě sloučeného rozptylu délky {cycles} nedávných označených cyklů (odchylka p95={dev}).",
"watchdog": "Ponecháno co nejnižší při zachování bezpečnosti (těsně nad intervalem aktualizace p95 ve výši {p95}s, min. 30s), aby byla zaseknutí rychle odhalena bez falešných zastavení."
"watchdog": "Ponecháno co nejnižší při zachování bezpečnosti (těsně nad intervalem aktualizace p95 ve výši {p95}s a alespoň 2x nad intervalem vzorkování {median}s, min. 30s), aby byla zaseknutí rychle odhalena bez falešných zastavení."
},
"exclusions": {
"summary": "Vyloučeno {total} chybně detekovaných cyklů: {parts}.",
@@ -1772,6 +1841,7 @@
"wrong_profile": "Špatný profil"
},
"toast": {
"catalog_refreshed": "Katalog komunity obnoven",
"access_saved": "Řízení přístupu bylo uloženo",
"all_wiped": "Všechna data vymazána",
"analysis_complete_none": "Analýza dokončena: žádné nové návrhy",
@@ -1865,19 +1935,21 @@
"rating_saved": "Hodnocení kvality uloženo",
"brand_added": "Značka přidána, čeká na schválení",
"profile_added": "Profil přidán, čeká na schválení",
"saved_except_conflicts": "Nastavení uložena -- {n} položka{s} přeskočena kvůli konfliktům",
"saved_except_conflicts": "Uloženo. Opravte zvýrazněné konflikty, aby se uložil zbytek.",
"share_device_none_sel": "Vyberte alespoň jeden program ke sdílení",
"store_device_downloaded": "Nastavení zařízení staženo: {created} profil{c} vytvořen, {dup} již existovalo",
"store_device_downloaded_phases": "Nastavení zařízení staženo: {created} profil{c} vytvořen, {dup} již existovalo, mapa fází použita",
"store_device_downloaded_settings": "Nastavení zařízení staženo: {created} profil{c} vytvořen, {dup} již existovalo, nastavení použita",
"store_device_shared": "Nastavení zařízení sdíleno: {n} program{s} nahrán",
"store_device_shared_all_dup": "Nic nového ke sdílení -- všechny programy v obchodě již existují",
"store_device_shared_partial": "Částečné sdílení: {n} program{s} nahrán, {failed} přeskočeno",
"store_device_shared_some_dup": "Nastavení zařízení sdíleno: {n} program{s} nahrán ({dup} již existovalo)",
"store_device_downloaded": "Přidáno programů: {p}, záznamů: {c}",
"store_device_downloaded_phases": "Přidáno programů: {p}, záznamů: {c}, map fází: {ph}",
"store_device_downloaded_settings": "Přidáno programů: {p}, záznamů: {c}, map fází: {ph}, nastavení: {s}",
"store_device_shared": "Sdíleno do komunitního obchodu (cyklů: {n}), čeká na kontrolu.",
"store_device_shared_all_dup": "Všechny vybrané cykly ({n}) už v komunitním obchodě jsou.",
"store_device_shared_partial": "Sdíleno cyklů: {n}; {failed} se nepodařilo nahrát.",
"store_device_shared_some_dup": "Sdíleno cyklů: {created}; již v obchodě: {dup}.",
"store_download_failed": "Stahování selhalo: {error}",
"store_download_nothing": "Nic ke stažení -- všechny profily na tomto zařízení již existují",
"export_selective_done": "Export stažen",
"import_selective_done": "Importováno {profiles} profilů a {cycles} cyklů"
"import_selective_done": "Importováno {profiles} profilů a {cycles} cyklů",
"hist_csv_required": "Nejprve načtěte soubor CSV nebo vložte jeho obsah",
"file_read_failed": "Tento soubor se nepodařilo přečíst"
},
"trend": {
"down": "Klesající trend",
@@ -1892,6 +1964,7 @@
},
"pg_desc": {
"dishwasher_end_spike_quiet_release": "Myčka: tiché sekundy po očekávané době trvání, než se uvolní čekání na závěrečné odčerpání vody",
"smart_termination_duration_ratio": "Zlomek očekávané doby trvání přiřazeného programu, kterého musí cyklus dosáhnout, než jej Chytré ukončení může ukončit dříve; snižte jej u strojů závislých na náplni nebo teplotě",
"anti_wrinkle_enabled": "Pohltit impulzy bubnu po hlavní fázi místo čtení jako nové cykly",
"anti_wrinkle_exit_power": "Výkon musí mezi impulzy klesnout pod tuto hodnotu, aby ochrana před zmačkáním zůstala aktivní",
"anti_wrinkle_idle_timeout": "Povolený klid mezi dvěma impulzy bubnu, než ochrana před zmačkáním skončí",
@@ -1955,6 +2028,10 @@
"finished": "Cyklus dosáhl koncového stavu a skončil."
},
"store": {
"your_model_tip": "Toto je spotřebič, který jste zadali v Nastavení",
"your_model": "Vaše",
"search_brand_ph": "Hledat podle značky…",
"programs_count": "Programy: {n}",
"browse": "Procházet",
"device": "Zařízení",
"favorites": "Oblíbené",
@@ -78,9 +78,12 @@
"awaiting": "Afventer godkendelse",
"imported_tip": "Importeret fra fællesskabsbutikken. Bruges kun til matchning, tælles ikke med i statistikken.",
"not_importable": "ikke her",
"exists": "findes"
"exists": "findes",
"backfilled_tip": "Registreret i importeret effekthistorik. Påvirker kun programmatchning, tælles ikke med i statistikken."
},
"btn": {
"set_brand_model": "Angiv mærke og model",
"refresh_catalog": "Opdater katalog",
"add_device": "+ Tilføj enhed",
"add_device_tip": "Tilføj en anden WashData-enhed",
"add_maintenance": "Tilføj vedligeholdelseshændelse",
@@ -90,7 +93,7 @@
"apply_label": "Påfør etiket",
"apply_set_b": "Anvend sæt B",
"apply_split": "Påfør Split",
"apply_trim": "Påfør Trim",
"apply_trim": "Anvend beskæring",
"auto_detect_split": "Automatisk registrering",
"auto_label_cycles": "Auto-label cyklusser",
"auto_label_cycles_tip": "Tildel automatisk profilnavne til umærkede cyklusser, hvis matchkonfidens overstiger tærsklen",
@@ -209,8 +212,8 @@
"stop": "Stop",
"submit_correction": "Send rettelse",
"train_now": "Træn nu",
"trim": "Trim",
"trim_split": "Trim / Split",
"trim": "Beskær",
"trim_split": "Beskær / Opdel",
"undo": "Fortryd",
"use": "Brug",
"wipe_all": "Slet alle data",
@@ -241,7 +244,12 @@
"import_selected": "Importér valgte",
"back": "Tilbage",
"mute_suggestion": "Stop med at foreslå denne indstilling",
"reset_muted": "Nulstil undertrykte forslag"
"reset_muted": "Nulstil undertrykte forslag",
"import_power_history": "Importér effekthistorik",
"hist_read_recorder": "Læs fra Home Assistant",
"hist_scan": "Scan efter cyklusser",
"hist_import_n": "Importér {n} cyklusser",
"hist_goto_cycles": "Vis mig cyklusserne"
},
"conflict": {
"anti_wrinkle_exit": {
@@ -253,12 +261,12 @@
"start": "Skal være under antikrøl-maksimumeffekten ({max} W)"
},
"attn_sub": "Ret konflikter inden du gemmer",
"attn_title": "{n} indstillingskonflikt{s}",
"attn_title": "Indstillingskonflikter: {n}",
"confidence": {
"auto": "Skal være på eller over matchningstærsklen ({match})",
"learning": "Skal være på eller under matchningstærsklen ({match})",
"learning": "Skal være på eller over matchningstærsklen ({match})",
"match_for_auto": "Skal være på eller under auto-label-konfidensniveauet ({alc})",
"match_for_learning": "Skal være på eller over læringskonfidensniveauet ({lc})"
"match_for_learning": "Skal være på eller under læringskonfidensniveauet ({lc})"
},
"duration_ratio": {
"max": "Skal være større end den minimale varighedsratio ({min})",
@@ -296,14 +304,14 @@
"match": "Skal være over ikke-matchningstærsklen ({un})",
"unmatch": "Skal være under matchningstærsklen ({match}); ellers ophæves en bekræftet matchning øjeblikkeligt"
},
"cascade_toast": "Desuden {n} indstilling{s} justeret for konsistens.",
"cascade_toast": "Andre indstillinger justeret for konsistens: {n}",
"suggestion_resolves": "Anvend forslaget nedenfor ({val}) for at løse dette",
"use_fix": "Brug {val}",
"watchdog": {
"interval": "Bør være mindst 2x samplingsintervallet ({si} s)",
"sampling": "Samplingsinterval bør højst være halvdelen af watchdog-intervallet ({wi} s)"
},
"settings_banner": "{n} indstillingskonflikt{s} tjek de fremhævede sektioner og ret dem inden du gemmer.",
"settings_banner": "Indstillingskonflikter: {n}. Tjek de fremhævede sektioner og ret dem, inden du gemmer.",
"settings_banner_btn": "Gå til første"
},
"hdr": {
@@ -356,7 +364,8 @@
"pg_outcome": "Simuleringsresultat",
"pg_across_cycles": "På tværs af dine cyklusser",
"community_store": "Fællesskabsbutik",
"online_account": "Fællesskabsbutik og onlinefunktioner"
"online_account": "Fællesskabsbutik og onlinefunktioner",
"import_power_history": "Importér effekthistorik"
},
"health": {
"fair": "Acceptabel matchkvalitet",
@@ -364,6 +373,7 @@
"poor": "⚠ Dårlig matchkvalitet"
},
"lbl": {
"drag_to_resize": "Træk for at ændre størrelse",
"actions": "Handlinger",
"activity": "Aktivitet",
"administrators": "Administratorer",
@@ -450,7 +460,7 @@
"metric": "Metrik",
"mode_existing_profile": "Føj til eksisterende profil",
"mode_new_profile": "Opret ny profil",
"models_fine_tuned": "({count} model{plural} finjusteret)",
"models_fine_tuned": "(finjusterede modeller: {count})",
"n_classic_suggestions": "{n} klassisk",
"n_ml_suggestions": "{n} ML",
"n_selected": "{n} valgt",
@@ -677,7 +687,26 @@
"conflict_keep_mine": "Behold mine",
"conflict_overwrite": "Overskriv",
"pg_anti_wrinkle": "Anti-rynke",
"font_size": "Panel-skriftstørrelse"
"font_size": "Panel-skriftstørrelse",
"hist_csv_data": "CSV-data",
"hist_from_recorder": "Eller læs den fra Home Assistant",
"hist_since": "Siden",
"days": "dage",
"hist_keep": "Behold denne cyklus",
"hist_looks_complete": "komplet",
"peak_power_short": "Spids",
"shape": "Form",
"hist_skip_idle": "intet kørte",
"hist_skip_sparse": "aflæsninger for langt fra hinanden",
"hist_skip_short": "for få aflæsninger",
"hist_skip_long": "ingen pause lang nok at opdele på",
"hist_reason_short": "kortere end dette apparats korteste rigtige cyklus",
"hist_reason_no_end": "sluttede aldrig rent",
"task_history_import": "Scanner effekthistorik",
"task_history_import_apply": "Importerer cyklusser",
"evidence_real_cycles": "Cyklusser, denne maskine har kørt",
"evidence_reference_cycles": "Hentet fra fællesskabsbutikken",
"evidence_backfill_cycles": "Fundet i importeret effekthistorik"
},
"log": {
"all_levels": "Alle niveauer",
@@ -756,9 +785,15 @@
"store_share": "Del i fællesskabsbutikken",
"store_share_device": "Del dette apparat",
"export_select": "Eksport - vælg data",
"import_wizard": "Import - vælg data"
"import_wizard": "Import - vælg data",
"history_import": "Importér effekthistorik"
},
"msg": {
"tail_trim_hint": "Fjern så mange sekunder fra slutningen",
"store_sibling_hint": "Er der intet delt til netop din model? En nært beslægtet model fra samme mærke er normalt et godt udgangspunkt.",
"store_declare_appliance": "Fortæl WashData, hvilket apparat du har, så viser denne fane de opsætninger, andre har delt til det. Du kan også skrive et mærke ovenfor for at se dig omkring.",
"refresh_catalog_hint": "Fællesskabets lister over mærker og apparater gemmes i cachen, så fællesskabsbutikken holder sig inden for sin daglige grænse. Opdater for at hente bidrag, som andre har tilføjet eller godkendt.",
"head_trim_hint": "Fjern så mange sekunder fra starten",
"appliance_monitor": "Apparat monitor",
"artifact_dip_detail": "Faldt under det normale effektbånd i ~{n}s.",
"artifact_footer": "Fremhævet på grafen ovenfor. Disse er forbigående artefakter (f.eks. døren åbnet midt i cyklussen), ikke nødvendigvis problemer.",
@@ -769,7 +804,7 @@
"automations_intro": "WashData udløser {start} / {end}-hændelser og stiller entiteter til rådighed, så notifikationer og handlinger bedst bygges som normale Home Assistant-automatiseringer. Automatiseringer, der bruger denne enhed, vises nedenfor.",
"cleanup_intro": "Hver mærket cyklus overlejret. Sæt kryds ved afvigelser og slet for at rydde op i profilen.",
"clear_debug_hint": "Fjern gemte fejlretningsdata for at frigøre plads.",
"collecting_data": "Indsamler data: {need} cyklus{plural} mere, før finjustering kan starte ({current}/{min}).",
"collecting_data": "Indsamler data. Cyklusser der stadig mangler, før finjustering kan starte: {need} ({current}/{min}).",
"compare_overlay_profiles": "Overlejringsprofiler (svage)",
"compare_profiles_tip": "Overlæg andre profilkonvolutter på skemaet ovenfor for at se, hvilken der passer bedst til denne cyklus.",
"compare_selected_cycles": "Valgte cyklusser (fast) vis/skjul",
@@ -779,7 +814,7 @@
"cycles_deleted": "{count} cyklus(ser) slettet",
"enough_data": "Nok data til at lære af ({current}/{min} cyklusser).",
"export_description": "Vælg præcis hvilke profiler, cyklusser, indstillinger og mere der skal eksporteres til JSON, eller analysér en fil og importér kun de dele, du vil have.",
"feedback_cycles_pending": "{n} cyklus{s} til gennemgang",
"feedback_cycles_pending": "Til gennemgang: {n}",
"feedback_prompt": "Bekræft, at det var rigtigt, ret programmet, eller ignorer.",
"feedback_relabel_hint": "At mærke denne cyklus om løser også gennemgangen.",
"filter_by_profile": "Filtrer efter profil…",
@@ -856,7 +891,6 @@
"pg_stress_synthetic": "inaktiv simulering begynder her",
"pg_sweep_intro": "Hvad hvis {param} var anderledes? Test {steps} værdier på tværs af dine seneste {cycles} cyklusser for at finde indstillingen, hvor flest cyklusser matches korrekt.",
"pg_sweep_step": "Trin {done} / {total}",
"pg_undetected": "{n} cyklus{s} ikke registreret",
"pg_verdict_bad": "Kræver opmærksomhed: mange cyklusser bliver ikke registreret.",
"pg_verdict_good": "Godt indstillet: de fleste cyklusser identificeres og matches korrekt.",
"pg_verdict_ok": "Acceptabelt: nogle cyklusser blev overset. Prøv at sænke starttærsklen.",
@@ -887,6 +921,7 @@
"review_recorded_tip": "Marker dette som en håndplukket referencecyklus for dets program - samme rolle som en manuelt optaget cyklus. Referencecyklusser opbevares altid, danner grundlag for matchskabelonen og droppes aldrig ved oprydning. (Dette er det \"gyldne\"/optagede flag; begge er det samme.)",
"review_tags_tip": "Valgfrie flag, der beskriver, hvad der gik galt med denne cyklus, så træning og oprydning kan forklare det.",
"review_to_cycles": "Åbn køen Cycles review",
"samples_decimated": "Viser {shown} af {total} prøver (udtyndet til visning; spidser bevares). Et bredt hul her er udtynding, ikke manglende data.",
"saving_triggers_reload": "Gemning udløser en genindlæsning af integration. HA-enheder kan kortvarigt vises som utilgængelige.",
"search_placeholder": "Søgeindstillinger...",
"see_recorder": "Se optager-widget nedenfor",
@@ -925,7 +960,7 @@
"trend_energy_up": "Energitrends op ({pct} %/cyklus) seneste gennemsnit {avg}",
"trim_destructive_confirm": "Dermed bevares kun {pct}% af cyklussen. Dette kan ikke fortrydes. Fortsæt?",
"trim_intro": "Træk i de røde håndtag, eller indtast værdier. Alt uden for vinduet fjernes.",
"tuning_suggestions_available": "{count} indstillingsforslag tilgængeligt fra observerede cyklusser. De vises ved siden af de relevante felter.",
"tuning_suggestions_available": "{count} indstillingsforslag tilgængeligt fra observerede cyklusser. De vises ved siden af de relevante felter.",
"unsure_detected_prefix": "WashData er usikker på, om det er registreret",
"updated": "Opdateret",
"warmup_badge": "Lærer stadig ({done}/{needed} cyklusser)",
@@ -1006,10 +1041,33 @@
"sug_mute_failed": "Kunne ikke undertrykke forslaget",
"sug_unmuted_all": "Undertrykte forslag nulstillet",
"n_suggestions_muted": "{count} undertrykt; autotuner vil ikke foreslå disse.",
"font_size_hint": "Gør alt i dette panel større eller mindre. Gælder for din konto på denne enhed."
"font_size_hint": "Gør alt i dette panel større eller mindre. Gælder for din konto på denne enhed.",
"import_history_description": "Havde du allerede et smartstik, før du fik WashData? Upload en historikeksport fra dets effektsensor, eller lad den blive læst direkte fra Home Assistant, og den normale registrering kører hen over den, så tidligere cyklusser dukker op i din Cykler-liste, klar til at få navn.",
"hist_input_hint": "Upload en CSV-fil hentet fra Historik-panelet (entitet, tilstand, sidst ændret), eller lad WashData læse sensorens historik direkte. Registreringen kører derefter hen over den præcis som live, og du vælger, hvilke af de fundne cyklusser du vil beholde.",
"hist_recorder_hint": "Læser fra den dato, du vælger, og frem til nu. Home Assistant gemmer som standard detaljeret historik i 10 dage og derefter kun timegennemsnit, som er for grove at registrere cyklusser ud fra - vælg kun en dato længere tilbage, hvis din recorder er sat til at gemme mere.",
"hist_scanning": "Din historik spilles igennem registreringen. Dette kører i baggrunden - du kan lukke denne dialog og vende tilbage til den senere.",
"hist_imported_count": "{n} cyklusser importeret.",
"hist_duplicates": "{n} var allerede importeret og blev sprunget over.",
"hist_capped": "Grænsen pr. enhed for importerede cyklusser blev nået; resten blev ikke gemt.",
"hist_next_step": "De ligger i din Cykler-liste, mærket som importeret historik. Åbn en, og brug Mærk til at give det tilhørende program navn.",
"hist_rows_read": "{n} aflæsninger læst",
"hist_entity_substituted": "læste {used} (denne enhed er konfigureret til {wanted})",
"hist_breaks": "{n} huller hvor sensoren var utilgængelig",
"hist_other_entity": "{n} aflæsninger for andre entiteter ignoreret",
"hist_skipped_spans": "Udeladte strækninger",
"hist_settings_used": "Registreret med denne enheds nuværende indstillinger (minimumseffekt {w} W, slukkeforsinkelse {s} s).",
"hist_none_found": "Der kunne ikke registreres nogen cyklusser i den historik.",
"hist_found": "Fandt {n} cyklusser. Fjern fluebenet ved alt, der ikke ser ud som en rigtig kørsel - der gemmes intet, før du importerer.",
"hist_scan_capped": "Kun de første kandidater vises ({n} blev fundet).",
"hist_recorder_empty": "Home Assistant har ingen detaljeret historik for denne sensor i det vindue.",
"hist_scan_failed": "Scanningen mislykkedes.",
"hist_scan_expired": "Den scanning er ikke længere tilgængelig. Scan igen.",
"hist_import_failed": "Importen mislykkedes.",
"imported_history_readonly": "Registreret i importeret effekthistorik. Den påvirker programmatchning, men tælles ikke med i din statistik og kan ikke beskæres eller opdeles. Mærk den for at give programmet navn."
},
"pg_desc": {
"dishwasher_end_spike_quiet_release": "Opvaskemaskine: stille sekunder efter den forventede varighed, før ventetiden på udpumpning ved cyklusslut frigives",
"smart_termination_duration_ratio": "Andel af det genkendte programs forventede varighed, som en cyklus skal nå, før smart afslutning må afslutte den tidligt; sænk den for belastnings- eller temperaturafhængige maskiner",
"completion_min_seconds": "Korteste kørsel, der tæller som en rigtig cyklus",
"end_repeat_count": "Lave målinger i træk før afslutning",
"interrupted_min_seconds": "Korte cyklusser markeres som afbrudt",
@@ -1166,7 +1224,7 @@
"label": "Minimum cyklusvarighed"
},
"delay_confirm_seconds": {
"doc": "Strømmen skal forblive i standby-båndet så længe, før apparatet behandles som ventende på at starte i stedet for at køre.",
"doc": "Strømmen skal forblive i standby-båndet så længe, før apparatet behandles som ventende på at starte i stedet for at køre.",
"label": "Bekræftelsessekunder"
},
"delay_start_detect_enabled": {
@@ -1194,7 +1252,7 @@
"label": "Anvend smarte modeller under en cyklus"
},
"end_energy_threshold": {
"doc": "Under nedtællingen af slukket forsinkelse sammenlignes akkumuleret energi (watt x tid) med denne tærskel. Hvis det overskrides, nulstilles nedtællingen - ved at holde anti-krøl tumblere og opvaskemaskinens tørrehaler fastgjort til cyklussen i stedet for at afkorte dem. Hæv den, hvis cyklusser slutter for tidligt under nedkøling; sænk den, hvis detektionen er træg.",
"doc": "Under nedtællingen af slukket forsinkelse sammenlignes akkumuleret energi (watt x tid) med denne tærskel. Hvis det overskrides, nulstilles nedtællingen - ved at holde anti-krøl tumblere og opvaskemaskinens tørrehaler fastgjort til cyklussen i stedet for at afkorte dem. Hæv den, hvis cyklusser slutter for tidligt under nedkøling; sænk den, hvis detektionen er træg.",
"label": "Slutenergi"
},
"end_repeat_count": {
@@ -1222,7 +1280,7 @@
"label": "Ekstern udløserenhed"
},
"external_end_trigger_enabled": {
"doc": "Lad en ekstern binær sensor signalere slutningen af en cyklus, ud over den indbyggede strømbaserede detektering.",
"doc": "Lad en ekstern binær sensor signalere slutningen af en cyklus, ud over den indbyggede strømbaserede detektering.",
"label": "Aktivér ekstern slutudløser"
},
"external_end_trigger_inverted": {
@@ -1242,7 +1300,7 @@
"label": "Minimum slukket mellemrum"
},
"min_power": {
"doc": "Absolut minimumseffekt anses for aktiv. Aflæsninger under dette behandles som 0 W (standby), hvilket frafiltrerer fantombelastningen af smarte stik og standby-LED'er.",
"doc": "Absolut minimumseffekt anses for aktiv. Aflæsninger under dette behandles som 0 W (standby), hvilket frafiltrerer fantombelastningen af smarte stik og standby-LED'er.",
"label": "Minimumseffekt"
},
"ml_training_enabled": {
@@ -1402,7 +1460,7 @@
"label": "Fejlmatchtærskel"
},
"progress_reset_delay": {
"doc": "Når du er færdig, skal du holde status på 100 % så længe, så fuldført er synlig på dashboards, før du nulstiller til inaktiv.",
"doc": "Når du er færdig, skal du holde status på 100 % så længe, så fuldført er synlig på dashboards, før du nulstiller til inaktiv.",
"label": "Forsinkelse ved nulstilling af fremskridt"
},
"pump_stuck_duration": {
@@ -1410,7 +1468,7 @@
"label": "Varighed for fastklemt pumpe"
},
"running_dead_zone": {
"doc": "Efter en cyklus starter, ignoreres strømfald i dette vindue. Vaskemaskiner fyldes med koldt vand (falder i nærheden af 0 W før opvarmning) - uden denne beskyttelse ligner påfyldningsfasen en cyklusafslutning. Dette springer IKKE data over: sporet med fuld effekt registreres fra T=0. Forslagsmotoren måler din maskines faktiske opstartsmønster og størrelser dette automatisk.",
"doc": "Efter en cyklus starter, ignoreres strømfald i dette vindue. Vaskemaskiner fyldes med koldt vand (falder i nærheden af 0 W før opvarmning) - uden denne beskyttelse ligner påfyldningsfasen en cyklusafslutning. Dette springer IKKE data over: sporet med fuld effekt registreres fra T=0. Forslagsmotoren måler din maskines faktiske opstartsmønster og størrelser dette automatisk.",
"label": "Kørende dødzone"
},
"sampling_interval": {
@@ -1421,6 +1479,10 @@
"doc": "Gem fuld effektsporing og matchende fejlretningsdata for hver cyklus. Nyttig til fejlfinding, men øger lagerstørrelsen.",
"label": "Gem fejlretningsspor"
},
"smart_termination_duration_ratio": {
"doc": "Hvor langt en cyklus skal være inde i det genkendte programs forventede varighed, før smart afslutning må afslutte den tidligt, når effekten falder. Den forventede varighed er programmets gennemsnit, så på apparater med stærkt varierende køretid - vaskemaskiner med koldt vinter- kontra varmt sommerindløbsvand, tørretumblere med fugtsensor, belastningsafhængige programmer - slutter omkring halvdelen af alle kørsler kortere end dette gennemsnit og får aldrig den hurtige afslutning, men slutter først minutter senere via reserve-timeoutet. Sænk denne værdi (f.eks. 0,85) på sådanne maskiner, så den tidlige afslutning stadig udløses; hæv den mod 1,0 for at være mere forsigtig. Lad feltet stå tomt for standarden (0,98 eller 0,99 for opvaskemaskiner). Den kan kun afslutte en cyklus tidligere, aldrig senere, og udløses aldrig ved en tvetydig eller usikker genkendelse.",
"label": "Forhold for smart afslutning"
},
"smoothing_window": {
"doc": "Hvor meget råeffektsignalet udjævnes. Lav (2) er lydhør, men støjende; høj (5) udglatter pigge, men tilføjer forsinkelse.",
"label": "Glatningsvindue"
@@ -1438,7 +1500,7 @@
"label": "Starttærskel"
},
"stop_threshold_w": {
"doc": "Strømmen skal falde til under dette niveau, før nedtællingen af slukket forsinkelse begynder. Indstil den under starttærsklen - mellemrummet mellem dem er hysteresebåndet, der forhindrer flimmer. Hvis den er indstillet for højt, vil laveffektfaser (skyllestop, anti-krøl) fejlagtigt udløse slutsekvensen.",
"doc": "Strømmen skal falde til under dette niveau, før nedtællingen af slukket forsinkelse begynder. Indstil den under starttærsklen - mellemrummet mellem dem er hysteresebåndet, der forhindrer flimmer. Hvis den er indstillet for højt, vil laveffektfaser (skyllestop, anti-krøl) fejlagtigt udløse slutsekvensen.",
"label": "Stoptærskel"
},
"switch_entity": {
@@ -1551,6 +1613,10 @@
"door_end_dwell_seconds": {
"label": "Dørens åbningstid ved afslutning",
"doc": "Hvor længe døren skal forblive åben, før WashData afslutter cyklussen, når \"Dør åbner automatisk ved afslutning\" er aktiveret. Lang nok til at ignorere hurtig tilføjelse af en tallerken (standard 60 s), kort nok til at afslutte hurtigt, når maskinen springer døren op."
},
"profile_evidence_sources": {
"label": "Cyklusser, der former et program",
"doc": "Hvilke cyklusser der bruges til at opbygge hvert programs effektkurve og til at matche en afsluttet cyklus mod den. Fravælger du en type, former den ikke længere dine programmer, uden at noget slettes - cyklusserne bliver i din Cykler-liste og kan stadig mærkes eller fjernes. Nyttigt, hvis du ikke stoler på importerede data. Statistikken påvirkes ikke: den tæller altid kun de cyklusser, som denne maskine faktisk har kørt. At fravælge alt ignoreres, da et program uden cyklusser bag sig aldrig kunne matche."
}
},
"setting_group": {
@@ -1634,6 +1700,9 @@
},
"basic_configuration": {
"label": "Grundlæggende konfiguration"
},
"profile_evidence": {
"label": "Profilgrundlag"
}
},
"status": {
@@ -1658,7 +1727,8 @@
"trimming": "Beskærer…",
"splitting": "Opdeler…",
"deleting": "Sletter…",
"imported": "Importeret"
"imported": "Importeret",
"preparing": "Forbereder…"
},
"suggestion": {
"both_agree": "WashData anbefaler",
@@ -1754,7 +1824,7 @@
"thr_batch": "Holdt lige over den laveste aktive effekt ved p05 på tværs af {cycles} cyklusser ({p05}W), så en start fanges så tidligt som muligt, og stoptærsklen forbliver under maskinens laveste driftseffekt.",
"tol_per_profile": "p75 for varighedsvariansen pr. profil på tværs af {profiles} profiler ({cycles} cyklusser); stramme profiler straffes ikke.",
"tol_pooled": "Baseret på samlet varighedsvarians for {cycles} seneste mærkede cyklusser (p95 afvigelse={dev}).",
"watchdog": "Holdt så lavt som forsvarligt (lige over p95-opdateringsmellemrummet på {p95}s, min 30s), så stilstande fanges hurtigt uden falske stop."
"watchdog": "Holdt så lavt som forsvarligt (lige over p95-opdateringsmellemrummet på {p95}s og mindst 2x samplingintervallet på {median}s, min. 30s), så stilstande fanges hurtigt uden falske stop."
},
"exclusions": {
"summary": "{total} fejldetekterede cyklus(ser) udelukket: {parts}.",
@@ -1801,6 +1871,7 @@
"wrong_profile": "Forkert profil"
},
"toast": {
"catalog_refreshed": "Fællesskabskataloget er opdateret",
"access_saved": "Adgangskontrol gemt",
"all_wiped": "Alle data slettet",
"analysis_complete_none": "Analyse færdig: ingen nye forslag",
@@ -1812,7 +1883,7 @@
"cycle_labelled": "Cyklus mærket",
"cycle_paused": "Cyklus sat på pause",
"cycle_resumed": "Cyklus genoptaget",
"cycle_trimmed": "Cyklus trimmet",
"cycle_trimmed": "Cyklus beskåret",
"cycles_merged": "Cykler slået sammen",
"envelope_rebuilt": "Konvolut genopbygget",
"envelopes_rebuilt": "Konvolutter genopbygget",
@@ -1906,7 +1977,9 @@
"store_download_failed": "Download mislykkedes: {error}",
"store_download_nothing": "Intet nyt at downloade -- denne opsætning er allerede på dit apparat.",
"export_selective_done": "Eksport downloadet",
"import_selective_done": "Importerede {profiles} profil(er) og {cycles} cyklus(ser)"
"import_selective_done": "Importerede {profiles} profil(er) og {cycles} cyklus(ser)",
"hist_csv_required": "Indlæs først en CSV-fil eller indsæt dens indhold",
"file_read_failed": "Kunne ikke læse den fil"
},
"trend": {
"down": "Trend nedad",
@@ -1955,6 +2028,10 @@
"finished": "Cyklussen nåede en sluttilstand og stoppede."
},
"store": {
"your_model_tip": "Dette er det apparat, du har angivet i Indstillinger",
"your_model": "Dit apparat",
"search_brand_ph": "Søg efter mærke…",
"programs_count": "Programmer: {n}",
"browse": "Gennemse",
"device": "Enhed",
"favorites": "Favoritter",
@@ -78,9 +78,12 @@
"awaiting": "Warten auf Freigabe",
"imported_tip": "Aus dem Community-Store importiert. Wird nur für den Abgleich verwendet, zählt nicht in die Statistik.",
"not_importable": "hier n. v.",
"exists": "vorhanden"
"exists": "vorhanden",
"backfilled_tip": "Im importierten Leistungsverlauf erkannt. Beeinflusst nur die Programmzuordnung, zählt nicht in die Statistik."
},
"btn": {
"set_brand_model": "Marke und Modell festlegen",
"refresh_catalog": "Katalog aktualisieren",
"add_device": "+ Gerät hinzufügen",
"add_device_tip": "Fügen Sie ein weiteres WashData-Gerät hinzu",
"add_maintenance": "Wartungsereignis hinzufügen",
@@ -90,7 +93,7 @@
"apply_label": "Etikett anwenden",
"apply_set_b": "Set B anwenden",
"apply_split": "Teilung anwenden",
"apply_trim": "Trimmen anwenden",
"apply_trim": "Zuschnitt anwenden",
"auto_detect_split": "Automatische Erkennung",
"auto_label_cycles": "Auto-Label-Zyklen",
"auto_label_cycles_tip": "Weist unbeschrifteten Zyklen, deren Übereinstimmungskonfidens den Schwellenwert überschreitet, automatisch Profilnamen zu",
@@ -209,8 +212,8 @@
"stop": "Stopp",
"submit_correction": "Korrektur einreichen",
"train_now": "Trainiere jetzt",
"trim": "Trimmen",
"trim_split": "Trimmen / Teilen",
"trim": "Zuschneiden",
"trim_split": "Zuschneiden / Teilen",
"undo": "Rückgängig",
"use": "Verwenden",
"wipe_all": "Alle Daten löschen",
@@ -241,7 +244,12 @@
"import_selected": "Auswahl importieren",
"back": "Zurück",
"mute_suggestion": "Diese Einstellung nicht mehr vorschlagen",
"reset_muted": "Stummschaltungen zurücksetzen"
"reset_muted": "Stummschaltungen zurücksetzen",
"import_power_history": "Leistungsverlauf importieren",
"hist_read_recorder": "Aus Home Assistant lesen",
"hist_scan": "Nach Zyklen suchen",
"hist_import_n": "{n} Zyklen importieren",
"hist_goto_cycles": "Zeig mir die Zyklen"
},
"conflict": {
"anti_wrinkle_exit": {
@@ -253,12 +261,12 @@
"start": "Muss unter der maximalen Knitterschutz-Leistung ({max} W) liegen"
},
"attn_sub": "Konflikte vor dem Speichern beheben",
"attn_title": "{n} Einstellungskonflikt{s}",
"attn_title": "Einstellungskonflikte: {n}",
"confidence": {
"auto": "Muss beim oder über dem Übereinstimmungsschwellenwert ({match}) liegen",
"learning": "Muss beim oder unter dem Übereinstimmungsschwellenwert ({match}) liegen",
"learning": "Muss beim oder über dem Übereinstimmungsschwellenwert ({match}) liegen",
"match_for_auto": "Muss beim oder unter der Auto-Label-Konfidenz ({alc}) liegen",
"match_for_learning": "Muss beim oder über der Lernkonfidenz ({lc}) liegen"
"match_for_learning": "Muss beim oder unter der Lernkonfidenz ({lc}) liegen"
},
"duration_ratio": {
"max": "Muss größer als das minimale Dauerverhältnis ({min}) sein",
@@ -296,14 +304,14 @@
"match": "Muss über dem Nicht-Übereinstimmungs-Schwellenwert ({un}) liegen",
"unmatch": "Muss unter dem Übereinstimmungsschwellenwert ({match}) liegen; andernfalls wird eine bestätigte Übereinstimmung sofort aufgehoben"
},
"cascade_toast": "Außerdem {n} Einstellung{s} zur Konsistenz angepasst.",
"cascade_toast": "Andere Einstellungen zur Konsistenz angepasst: {n}",
"suggestion_resolves": "Unten den ausstehenden Vorschlag ({val}) übernehmen, um dies zu beheben",
"use_fix": "Verwende {val}",
"watchdog": {
"interval": "Sollte mindestens das 2-fache des Abtastintervalls ({si} s) betragen",
"sampling": "Abtastintervall sollte höchstens die Hälfte des Watchdog-Intervalls ({wi} s) betragen"
},
"settings_banner": "{n} Einstellungskonflikt{s} markierte Abschnitte prüfen und vor dem Speichern beheben.",
"settings_banner": "Einstellungskonflikte: {n}. Prüfen Sie die markierten Abschnitte und beheben Sie sie vor dem Speichern.",
"settings_banner_btn": "Zum ersten"
},
"hdr": {
@@ -356,7 +364,8 @@
"pg_outcome": "Simulationsergebnis",
"pg_across_cycles": "Über deine Zyklen hinweg",
"community_store": "Community-Store",
"online_account": "Community-Store und Onlinefunktionen"
"online_account": "Community-Store und Onlinefunktionen",
"import_power_history": "Leistungsverlauf importieren"
},
"health": {
"fair": "Akzeptable Übereinstimmungsqualität",
@@ -364,6 +373,7 @@
"poor": "⚠ Schlechte Übereinstimmungsqualität"
},
"lbl": {
"drag_to_resize": "Zum Ändern der Größe ziehen",
"actions": "Aktionen",
"activity": "Aktivität",
"administrators": "Administratoren",
@@ -450,7 +460,7 @@
"metric": "Metrik",
"mode_existing_profile": "Zum vorhandenen Profil hinzufügen",
"mode_new_profile": "Neues Profil erstellen",
"models_fine_tuned": "({count} Modell{plural} feinabgestimmt)",
"models_fine_tuned": "(feinabgestimmte Modelle: {count})",
"n_classic_suggestions": "{n} klassisch",
"n_ml_suggestions": "{n} ML",
"n_selected": "{n} ausgewählt",
@@ -677,7 +687,26 @@
"conflict_keep_mine": "Meine behalten",
"conflict_overwrite": "Überschreiben",
"pg_anti_wrinkle": "Knitterschutz",
"font_size": "Panel-Schriftgröße"
"font_size": "Panel-Schriftgröße",
"hist_csv_data": "CSV-Daten",
"hist_from_recorder": "Oder aus Home Assistant lesen",
"hist_since": "Seit",
"days": "Tage",
"hist_keep": "Diesen Zyklus behalten",
"hist_looks_complete": "vollständig",
"peak_power_short": "Spitze",
"shape": "Form",
"hist_skip_idle": "nichts in Betrieb",
"hist_skip_sparse": "Messwerte zu weit auseinander",
"hist_skip_short": "zu wenige Messwerte",
"hist_skip_long": "keine Pause lang genug zum Aufteilen",
"hist_reason_short": "kürzer als der kürzeste echte Zyklus dieses Geräts",
"hist_reason_no_end": "wurde nie sauber beendet",
"task_history_import": "Leistungsverlauf wird durchsucht",
"task_history_import_apply": "Zyklen werden importiert",
"evidence_real_cycles": "Zyklen, die diese Maschine ausgeführt hat",
"evidence_reference_cycles": "Aus dem Community-Store heruntergeladen",
"evidence_backfill_cycles": "Im importierten Leistungsverlauf gefunden"
},
"log": {
"all_levels": "Alle Ebenen",
@@ -756,9 +785,15 @@
"store_share": "Im Community-Store teilen",
"store_share_device": "Dieses Gerät teilen",
"export_select": "Export - Daten wählen",
"import_wizard": "Import - Daten wählen"
"import_wizard": "Import - Daten wählen",
"history_import": "Leistungsverlauf importieren"
},
"msg": {
"tail_trim_hint": "So viele Sekunden vom Ende entfernen",
"store_sibling_hint": "Für Ihr genaues Modell ist nichts geteilt? Ein nah verwandtes Modell derselben Marke ist meist ein guter Ausgangspunkt.",
"store_declare_appliance": "Teilen Sie WashData mit, welches Gerät Sie besitzen, dann zeigt dieser Tab die Setups, die andere dafür geteilt haben. Sie können oben auch eine Marke eingeben, um sich umzusehen.",
"refresh_catalog_hint": "Die Marken- und Gerätelisten der Community werden zwischengespeichert, damit der Community-Store sein Tageslimit einhält. Aktualisieren Sie, um Einträge zu übernehmen, die andere hinzugefügt oder freigegeben haben.",
"head_trim_hint": "So viele Sekunden vom Anfang entfernen",
"appliance_monitor": "Gerätemonitor",
"artifact_dip_detail": "Sank unter das übliche Leistungsband für ~{n}s.",
"artifact_footer": "In der Grafik oben hervorgehoben. Hierbei handelt es sich um vorübergehende Artefakte (z. B. das Öffnen der Tür mitten im Zyklus), nicht unbedingt um Probleme.",
@@ -769,7 +804,7 @@
"automations_intro": "WashData löst {start} / {end}-Ereignisse aus und stellt Entitäten bereit, sodass Benachrichtigungen und Aktionen am besten als normale Home Assistant-Automatisierungen eingerichtet werden. Automatisierungen, die dieses Gerät verwenden, werden unten angezeigt.",
"cleanup_intro": "Jeder beschriftete Zyklus überlagert. Markieren Sie Ausreißer und löschen Sie sie, um das Profil zu bereinigen.",
"clear_debug_hint": "Entfernen Sie gespeicherte Debug-Daten, um Speicherplatz freizugeben.",
"collecting_data": "Daten werden gesammelt: noch {need} Zyklus{plural} bis zum Start der Feinabstimmung ({current}/{min}).",
"collecting_data": "Daten werden gesammelt. Noch benötigte Zyklen bis zum Start der Feinabstimmung: {need} ({current}/{min}).",
"compare_overlay_profiles": "Overlay-Profile (schwach)",
"compare_profiles_tip": "Überlagern Sie andere Profilumschläge in der Tabelle oben, um zu sehen, welcher am besten zu diesem Zyklus passt.",
"compare_selected_cycles": "Ausgewählte Zyklen (durchgehend) ein-/ausblenden",
@@ -856,7 +891,6 @@
"pg_stress_synthetic": "Leerlaufsimulation beginnt hier",
"pg_sweep_intro": "Was wäre, wenn {param} anders wäre? Testen Sie {steps} Werte über Ihre letzten {cycles} Zyklen, um die Einstellung zu finden, bei der die meisten Zyklen korrekt zugeordnet werden.",
"pg_sweep_step": "Schritt {done} / {total}",
"pg_undetected": "{n} Zyklus{s} nicht erkannt",
"pg_verdict_bad": "Erfordert Aufmerksamkeit: viele Zyklen bleiben unerkannt.",
"pg_verdict_good": "Gut abgestimmt: die meisten Zyklen werden korrekt erkannt und zugeordnet.",
"pg_verdict_ok": "Akzeptabel: einige Zyklen wurden verpasst. Versuchen Sie, den Startschwellenwert zu senken.",
@@ -887,6 +921,7 @@
"review_recorded_tip": "Markieren Sie dies als handverlesenen Referenzzyklus für sein Programm die gleiche Rolle wie ein manuell aufgezeichneter Zyklus. Referenzzyklen bleiben immer erhalten, setzen die passende Vorlage als Seed und werden bei der Bereinigung niemals gelöscht. (Dies ist die „goldene“/aufgezeichnete Flagge; beide sind dasselbe.)",
"review_tags_tip": "Optionale Flags, die beschreiben, was bei diesem Zyklus schief gelaufen ist, damit Training und Bereinigung dafür verantwortlich sein können.",
"review_to_cycles": "Öffnen Sie die Cycles-Bewertungswarteschlange",
"samples_decimated": "Es werden {shown} von {total} Messwerten angezeigt (für die Anzeige ausgedünnt; Spitzen bleiben erhalten). Eine breite Lücke hier ist Ausdünnung, keine fehlenden Daten.",
"saving_triggers_reload": "Durch das Speichern wird ein Neuladen der Integration ausgelöst. HA-Entitäten werden möglicherweise kurzzeitig als nicht verfügbar angezeigt.",
"search_placeholder": "Einstellungen durchsuchen…",
"see_recorder": "Siehe Rekorder-Widget unten",
@@ -1006,10 +1041,33 @@
"sug_mute_failed": "Einstellung konnte nicht stummgeschaltet werden",
"sug_unmuted_all": "Stummgeschaltete Vorschläge zurückgesetzt",
"n_suggestions_muted": "{count} stummgeschaltet; der Autotuner schlägt diese nicht mehr vor.",
"font_size_hint": "Alles in diesem Panel vergrößern oder verkleinern. Gilt für Ihr Konto auf diesem Gerät."
"font_size_hint": "Alles in diesem Panel vergrößern oder verkleinern. Gilt für Ihr Konto auf diesem Gerät.",
"import_history_description": "Hatten Sie schon vor WashData einen Smart Plug? Laden Sie einen Verlaufsexport seines Leistungssensors hoch oder lassen Sie ihn direkt aus Home Assistant lesen: Die normale Erkennung läuft darüber, sodass vergangene Zyklen in Ihrer Zyklusliste auftauchen und dort benannt werden können.",
"hist_input_hint": "Laden Sie eine CSV-Datei aus dem Verlaufs-Panel hoch (Entität, Status, Letzte Änderung), oder lassen Sie WashData den Verlauf des Sensors direkt lesen. Die Erkennung läuft dann genau so darüber wie im Livebetrieb, und Sie wählen aus, welche der gefundenen Zyklen behalten werden.",
"hist_recorder_hint": "Liest ab dem gewählten Datum bis jetzt. Home Assistant speichert detaillierte Verlaufsdaten standardmäßig 10 Tage lang und danach nur noch Stundenmittelwerte, die für die Zykluserkennung zu grob sind - wählen Sie nur dann ein weiter zurückliegendes Datum, wenn Ihr Recorder auf eine längere Aufbewahrung eingestellt ist.",
"hist_scanning": "Ihr Verlauf wird durch die Erkennung abgespielt. Das läuft im Hintergrund - Sie können diesen Dialog schließen und später zurückkommen.",
"hist_imported_count": "{n} Zyklen importiert.",
"hist_duplicates": "{n} waren bereits importiert und wurden übersprungen.",
"hist_capped": "Das Limit pro Gerät für importierte Zyklen wurde erreicht; der Rest wurde nicht gespeichert.",
"hist_next_step": "Sie liegen in Ihrer Zyklusliste, gekennzeichnet als importierter Verlauf. Öffnen Sie einen und benennen Sie über \"Beschriften\" das zugehörige Programm.",
"hist_rows_read": "{n} Messwerte gelesen",
"hist_entity_substituted": "{used} gelesen (dieses Gerät ist für {wanted} konfiguriert)",
"hist_breaks": "{n} Lücken, in denen der Sensor nicht verfügbar war",
"hist_other_entity": "{n} Messwerte für andere Entitäten ignoriert",
"hist_skipped_spans": "Übersprungene Abschnitte",
"hist_settings_used": "Erkannt mit den aktuellen Einstellungen dieses Geräts (Mindestleistung {w} W, Abschaltverzögerung {s} s).",
"hist_none_found": "In diesem Verlauf konnten keine Zyklen erkannt werden.",
"hist_found": "{n} Zyklen gefunden. Entfernen Sie das Häkchen bei allem, was nicht wie ein echter Lauf aussieht - bis zum Import wird nichts gespeichert.",
"hist_scan_capped": "Es werden nur die ersten Kandidaten angezeigt ({n} wurden gefunden).",
"hist_recorder_empty": "Home Assistant hat für diesen Sensor in diesem Zeitraum keine detaillierten Verlaufsdaten.",
"hist_scan_failed": "Suche fehlgeschlagen.",
"hist_scan_expired": "Diese Suche ist nicht mehr verfügbar. Bitte erneut suchen.",
"hist_import_failed": "Import fehlgeschlagen.",
"imported_history_readonly": "Im importierten Leistungsverlauf erkannt. Er beeinflusst die Programmzuordnung, zählt aber nicht in Ihre Statistik und kann nicht zugeschnitten oder geteilt werden. Beschriften Sie ihn, um das Programm zu benennen."
},
"pg_desc": {
"dishwasher_end_spike_quiet_release": "Geschirrspüler: Ruhesekunden nach der erwarteten Dauer, bevor die Wartezeit auf das Abpumpen am Zyklusende freigegeben wird",
"smart_termination_duration_ratio": "Anteil der erwarteten Dauer des zugeordneten Programms, den ein Zyklus erreichen muss, bevor die intelligente Beendigung ihn vorzeitig beenden darf; bei last- oder temperaturabhängigen Geräten senken",
"completion_min_seconds": "Kürzester Lauf, der als echter Zyklus zählt",
"end_repeat_count": "Aufeinanderfolgende niedrige Messwerte vor dem Ende",
"interrupted_min_seconds": "Kurze Zyklen werden als unterbrochen markiert",
@@ -1417,6 +1475,10 @@
"doc": "Speichern Sie für jeden Zyklus die vollständige Leistungsverfolgung und die entsprechenden Debug-Daten. Nützlich zur Fehlerbehebung, erhöht jedoch die Speichergröße.",
"label": "Debug-Traces speichern"
},
"smart_termination_duration_ratio": {
"doc": "Wie weit ein Zyklus in die erwartete Dauer des zugeordneten Programms fortgeschritten sein muss, bevor die intelligente Beendigung ihn bei einem Leistungsabfall vorzeitig beenden darf. Die erwartete Dauer ist der Durchschnitt des Programms; bei Geräten mit stark schwankender Laufzeit - Waschmaschinen bei kaltem Winter- gegenüber warmem Sommer-Zulaufwasser, Trockner mit Feuchtesensor, lastabhängige Programme - endet daher etwa die Hälfte aller Läufe kürzer als dieser Durchschnitt und erhält nie die schnelle Beendigung, sondern endet erst Minuten später über den Rückfall-Timeout. Senken Sie diesen Wert (z. B. 0,85) bei solchen Geräten, damit die vorzeitige Beendigung dennoch auslöst; erhöhen Sie ihn Richtung 1,0, um vorsichtiger zu sein. Leer lassen für den Standard (0,98 bzw. 0,99 für Geschirrspüler). Er kann einen Zyklus nur früher beenden, niemals später, und löst nie bei einer mehrdeutigen oder unsicheren Zuordnung aus.",
"label": "Verhältnis für intelligente Beendigung"
},
"smoothing_window": {
"doc": "Wie stark wird das Rohleistungssignal geglättet? Niedrig (2) reagiert, ist aber laut; Hoch (5) glättet Spitzen, fügt aber Verzögerung hinzu.",
"label": "Glättungsfenster"
@@ -1551,6 +1613,10 @@
"door_end_dwell_seconds": {
"label": "Türöffnungs-Endverweildauer",
"doc": "Wie lange die Tür geöffnet bleiben muss, bevor WashData den Zyklus beendet, wenn \"Tür öffnet sich am Ende automatisch\" aktiv ist. Lang genug, um ein kurzes Öffnen zum Nachlegen eines Geschirrteils zu ignorieren (Standard 60 s), kurz genug, um den Zyklus zügig zu beenden, sobald die Maschine die Tür aufspringt."
},
"profile_evidence_sources": {
"label": "Zyklen, die ein Programm prägen",
"doc": "Welche Zyklen zum Aufbau der Leistungskurve jedes Programms und zum Abgleich eines abgeschlossenen Zyklus damit verwendet werden. Wird eine Art abgewählt, prägt sie Ihre Programme nicht mehr, ohne dass etwas gelöscht wird - die Zyklen bleiben in Ihrer Zyklusliste und können weiterhin beschriftet oder entfernt werden. Nützlich, wenn Sie importierten Daten nicht vertrauen. Die Statistik ist davon nicht betroffen: Sie zählt immer nur die Zyklen, die diese Maschine wirklich ausgeführt hat. Alles abzuwählen wird ignoriert, da ein Programm ohne Zyklen dahinter nie zugeordnet werden könnte."
}
},
"setting_group": {
@@ -1634,6 +1700,9 @@
},
"basic_configuration": {
"label": "Grundkonfiguration"
},
"profile_evidence": {
"label": "Profilgrundlage"
}
},
"status": {
@@ -1658,7 +1727,8 @@
"trimming": "Wird zugeschnitten…",
"splitting": "Wird geteilt…",
"deleting": "Wird gelöscht…",
"imported": "Importiert"
"imported": "Importiert",
"preparing": "Wird vorbereitet…"
},
"suggestion": {
"both_agree": "WashData empfiehlt",
@@ -1754,7 +1824,7 @@
"thr_batch": "Knapp über der p05-niedrigsten aktiven Leistung über {cycles} Zyklen ({p05}W) gehalten, damit ein Start so früh wie möglich erkannt wird und die Stopp-Schwelle unter der niedrigsten Betriebsleistung der Maschine bleibt.",
"tol_per_profile": "p75 der Dauervarianz pro Profil über {profiles} Profile ({cycles} Zyklen); enge Profile werden nicht benachteiligt.",
"tol_pooled": "Basierend auf der zusammengefassten Dauervarianz von {cycles} kürzlich gelabelten Zyklen (p95-Abweichung={dev}).",
"watchdog": "So niedrig wie sicher gehalten (knapp über der p95-Aktualisierungslücke von {p95}s, min 30s), damit Hänger schnell erkannt werden, ohne Fehl-Stopps auszulösen."
"watchdog": "So niedrig wie sicher gehalten (knapp über der p95-Aktualisierungslücke von {p95}s und mindestens 2x dem Abtastintervall von {median}s, min. 30s), damit Hänger schnell erkannt werden, ohne Fehl-Stopps auszulösen."
},
"exclusions": {
"summary": "{total} falsch erkannte Zyklen ausgeschlossen: {parts}.",
@@ -1801,6 +1871,7 @@
"wrong_profile": "Falsches Profil"
},
"toast": {
"catalog_refreshed": "Community-Katalog aktualisiert",
"access_saved": "Zugangskontrolle gespeichert",
"all_wiped": "Alle Daten gelöscht",
"analysis_complete_none": "Analyse abgeschlossen: keine neuen Vorschläge",
@@ -1812,7 +1883,7 @@
"cycle_labelled": "Zyklus beschriftet",
"cycle_paused": "Zyklus pausiert",
"cycle_resumed": "Der Zyklus wurde fortgesetzt",
"cycle_trimmed": "Zyklus getrimmt",
"cycle_trimmed": "Zyklus zugeschnitten",
"cycles_merged": "Zyklen verschmolzen",
"envelope_rebuilt": "Umschlag neu aufgebaut",
"envelopes_rebuilt": "Umschläge neu aufgebaut",
@@ -1906,7 +1977,9 @@
"store_download_failed": "Download fehlgeschlagen: {error}",
"store_download_nothing": "Nichts Neues zum Herunterladen -- dieses Setup ist bereits auf Ihrem Gerät.",
"export_selective_done": "Export heruntergeladen",
"import_selective_done": "{profiles} Profil(e) und {cycles} Zyklus/Zyklen importiert"
"import_selective_done": "{profiles} Profil(e) und {cycles} Zyklus/Zyklen importiert",
"hist_csv_required": "Laden Sie zuerst eine CSV-Datei oder fügen Sie deren Inhalt ein",
"file_read_failed": "Diese Datei konnte nicht gelesen werden"
},
"trend": {
"down": "Abwärtstrend",
@@ -1955,6 +2028,10 @@
"finished": "Der Zyklus hat einen Endzustand erreicht und wurde beendet."
},
"store": {
"your_model_tip": "Dies ist das Gerät, das Sie in den Einstellungen angegeben haben",
"your_model": "Ihr Gerät",
"search_brand_ph": "Nach Marke suchen…",
"programs_count": "Programme: {n}",
"browse": "Durchsuchen",
"device": "Gerät",
"favorites": "Favoriten",
@@ -78,9 +78,12 @@
"awaiting": "Αναμονή έγκρισης",
"imported_tip": "Εισαγωγή από το κοινοτικό κατάστημα. Χρησιμοποιείται μόνο για αντιστοίχιση, δεν προσμετράται στα στατιστικά.",
"not_importable": "μη διαθέσιμο εδώ",
"exists": "υπάρχει"
"exists": "υπάρχει",
"backfilled_tip": "Ανιχνεύθηκε σε εισαγόμενο ιστορικό ισχύος. Διαμορφώνει μόνο την αντιστοίχιση προγραμμάτων, δεν προσμετράται στα στατιστικά."
},
"btn": {
"set_brand_model": "Ορισμός μάρκας και μοντέλου",
"refresh_catalog": "Ανανέωση καταλόγου",
"add_device": "+ Προσθήκη συσκευής",
"add_device_tip": "Προσθέστε μια άλλη συσκευή WashData",
"add_maintenance": "Προσθήκη συμβάντος συντήρησης",
@@ -241,7 +244,12 @@
"import_selected": "Εισαγωγή επιλεγμένων",
"back": "Πίσω",
"mute_suggestion": "Διακοπή πρότασης αυτής της ρύθμισης",
"reset_muted": "Επαναφορά αποσιωπημένων"
"reset_muted": "Επαναφορά αποσιωπημένων",
"import_power_history": "Εισαγωγή ιστορικού ισχύος",
"hist_read_recorder": "Ανάγνωση από το Home Assistant",
"hist_scan": "Σάρωση για κύκλους",
"hist_import_n": "Εισαγωγή {n} κύκλων",
"hist_goto_cycles": "Εμφάνιση κύκλων"
},
"conflict": {
"anti_wrinkle_exit": {
@@ -253,14 +261,14 @@
"start": "Πρέπει να είναι κάτω από τη Μέγιστη Ισχύ Αντί-Τσακίσματος ({max} W)"
},
"attn_sub": "Διορθώστε τις συγκρούσεις πριν αποθηκεύσετε",
"attn_title": "{n} σύγκρουση{s} ρυθμίσεων",
"settings_banner": "{n} σύγκρουση{s} ρυθμίσεων ελέγξτε τα επισημασμένα τμήματα και διορθώστε πριν αποθηκεύσετε.",
"attn_title": "Συγκρούσεις ρυθμίσεων: {n}",
"settings_banner": "Συγκρούσεις ρυθμίσεων: {n}. Ελέγξτε τα επισημασμένα τμήματα και διορθώστε τα πριν την αποθήκευση.",
"settings_banner_btn": "Μετάβαση στο πρώτο",
"confidence": {
"auto": "Πρέπει να είναι μεγαλύτερο ή ίσο με το Κατώφλι Αντιστοίχισης ({match})",
"learning": "Πρέπει να είναι μικρότερο ή ίσο με το Κατώφλι Αντιστοίχισης ({match})",
"learning": "Πρέπει να είναι μεγαλύτερο ή ίσο με το Κατώφλι Αντιστοίχισης ({match})",
"match_for_auto": "Πρέπει να είναι μικρότερο ή ίσο με την Εμπιστοσύνη Αυτόματης Ετικέτας ({alc})",
"match_for_learning": "Πρέπει να είναι μεγαλύτερο ή ίσο με την Εμπιστοσύνη Μάθησης ({lc})"
"match_for_learning": "Πρέπει να είναι μικρότερο ή ίσο με την Εμπιστοσύνη Μάθησης ({lc})"
},
"duration_ratio": {
"max": "Πρέπει να είναι μεγαλύτερο από τον Ελάχιστο Λόγο Διάρκειας ({min})",
@@ -298,7 +306,7 @@
"match": "Πρέπει να είναι πάνω από το Κατώφλι Αποαντιστοίχισης ({un})",
"unmatch": "Πρέπει να είναι κάτω από το Κατώφλι Αντιστοίχισης ({match})· διαφορετικά μια επιβεβαιωμένη αντιστοίχιση ακυρώνεται αμέσως"
},
"cascade_toast": "Προσαρμόστηκαν επίσης {n} ρύθμιση{s} για συνέπεια.",
"cascade_toast": "Άλλες ρυθμίσεις που προσαρμόστηκαν για συνέπεια: {n}",
"suggestion_resolves": "Εφαρμόστε την εκκρεμή πρόταση ({val}) παρακάτω για να διορθώσετε αυτό",
"use_fix": "Χρήση {val}",
"watchdog": {
@@ -356,7 +364,8 @@
"pg_outcome": "Αποτέλεσμα προσομοίωσης",
"pg_across_cycles": "Σε όλους τους κύκλους σας",
"community_store": "Κοινοτικό Κατάστημα",
"online_account": "Κοινοτικό Κατάστημα & διαδικτυακές λειτουργίες"
"online_account": "Κοινοτικό Κατάστημα & διαδικτυακές λειτουργίες",
"import_power_history": "Εισαγωγή ιστορικού ισχύος"
},
"health": {
"fair": "Αποδεκτή ποιότητα αντιστοίχισης",
@@ -364,6 +373,7 @@
"poor": "⚠ Κακή ποιότητα αντιστοίχισης"
},
"lbl": {
"drag_to_resize": "Σύρετε για αλλαγή μεγέθους",
"actions": "Ενέργειες",
"activity": "Δραστηριότητα",
"administrators": "Διαχειριστές",
@@ -434,7 +444,7 @@
"from": "Από",
"gap_s": "Κενό (δευτ.)",
"group_name": "Όνομα ομάδας",
"head_trim": "Περικοπή κεφαλής (δευτ.)",
"head_trim": "Περικοπή αρχής (δευτ.)",
"health": "Υγεία",
"hide_tabs": "Απόκρυψη καρτελών για μη διαχειριστές",
"in_use": "Σε χρήση",
@@ -450,7 +460,7 @@
"metric": "Μετρική",
"mode_existing_profile": "Προσθήκη στο υπάρχον προφίλ",
"mode_new_profile": "Δημιουργία Νέου Προφίλ",
"models_fine_tuned": "({count} μοντέλο{plural} βελτιστοποιημένο)",
"models_fine_tuned": "(βελτιστοποιημένα μοντέλα: {count})",
"n_classic_suggestions": "{n} κλασικά",
"n_ml_suggestions": "{n} ML",
"n_selected": "{n} επιλεγμένα",
@@ -532,7 +542,7 @@
"stage3": "Στάδιο 3 DTW",
"stage4": "Στάδιο 4 – συμφωνία",
"status": "Κατάσταση",
"tail_trim": "Περικοπή ουράς (δευτ.)",
"tail_trim": "Περικοπή τέλους (δευτ.)",
"timer_auto_pause": "Αυτόματη παύση",
"timer_min": "λεπτά",
"timer_msg_placeholder": "Μήνυμα (προαιρετικό, {device}/{program}/{minutes})",
@@ -677,7 +687,26 @@
"conflict_import_copy": "Εισαγωγή ως αντίγραφο",
"conflict_keep_mine": "Διατήρηση δικών μου",
"conflict_overwrite": "Αντικατάσταση",
"font_size": "Μέγεθος γραμματοσειράς πίνακα"
"font_size": "Μέγεθος γραμματοσειράς πίνακα",
"hist_csv_data": "Δεδομένα CSV",
"hist_from_recorder": "Ή διαβάστε το από το Home Assistant",
"hist_since": "Από",
"days": "ημέρες",
"hist_keep": "Διατήρηση αυτού του κύκλου",
"hist_looks_complete": "πλήρης",
"peak_power_short": "Αιχμή",
"shape": "Σχήμα",
"hist_skip_idle": "καμία λειτουργία",
"hist_skip_sparse": "μετρήσεις πολύ αραιές",
"hist_skip_short": "πολύ λίγες μετρήσεις",
"hist_skip_long": "δεν υπάρχει αρκετά μεγάλο κενό για διαχωρισμό",
"hist_reason_short": "μικρότερος από τον συντομότερο πραγματικό κύκλο αυτής της συσκευής",
"hist_reason_no_end": "δεν ολοκληρώθηκε ποτέ καθαρά",
"task_history_import": "Σάρωση ιστορικού ισχύος",
"task_history_import_apply": "Εισαγωγή κύκλων",
"evidence_real_cycles": "Κύκλοι που εκτέλεσε αυτό το μηχάνημα",
"evidence_reference_cycles": "Λήψη από το κοινοτικό κατάστημα",
"evidence_backfill_cycles": "Βρέθηκαν σε εισαγόμενο ιστορικό ισχύος"
},
"log": {
"all_levels": "Όλα τα επίπεδα",
@@ -756,9 +785,15 @@
"store_share": "Κοινοποίηση στο κοινοτικό κατάστημα",
"store_share_device": "Κοινοποίηση αυτής της συσκευής",
"export_select": "Εξαγωγή - επιλογή δεδομένων",
"import_wizard": "Εισαγωγή - επιλογή δεδομένων"
"import_wizard": "Εισαγωγή - επιλογή δεδομένων",
"history_import": "Εισαγωγή ιστορικού ισχύος"
},
"msg": {
"tail_trim_hint": "Αφαιρέστε τόσα δευτερόλεπτα από το τέλος",
"store_sibling_hint": "Δεν υπάρχει τίποτα κοινοποιημένο για το ακριβές μοντέλο σας; Ένα στενά συγγενικό μοντέλο της ίδιας μάρκας είναι συνήθως καλή αφετηρία.",
"store_declare_appliance": "Δηλώστε στο WashData ποια συσκευή έχετε και αυτή η καρτέλα θα εμφανίσει τις διαμορφώσεις που έχουν κοινοποιήσει άλλοι για αυτήν. Μπορείτε επίσης να γράψετε μια μάρκα παραπάνω για να δείτε τον κατάλογο.",
"refresh_catalog_hint": "Οι λίστες μαρκών και συσκευών της κοινότητας αποθηκεύονται προσωρινά, ώστε το κοινοτικό κατάστημα να παραμένει μέσα στο ημερήσιο όριό του. Ανανεώστε για να εμφανιστούν καταχωρίσεις που πρόσθεσαν ή ενέκριναν άλλοι.",
"head_trim_hint": "Αφαιρέστε τόσα δευτερόλεπτα από την αρχή",
"appliance_monitor": "Οθόνη συσκευής",
"artifact_dip_detail": "Έπεσε κάτω από το συνηθισμένο εύρος ισχύος για ~{n}s.",
"artifact_footer": "Επισημαίνεται στο παραπάνω γράφημα. Αυτά είναι παροδικά τεχνουργήματα (π.χ. η πόρτα άνοιξε στα μέσα του κύκλου), όχι απαραίτητα προβλήματα.",
@@ -769,7 +804,7 @@
"automations_intro": "Το WashData ενεργοποιεί συμβάντα {start} / {end} και εκθέτει οντότητες, οπότε οι ειδοποιήσεις και οι ενέργειες κατασκευάζονται καλύτερα ως κανονικοί αυτοματισμοί του Home Assistant. Οι αυτοματισμοί που χρησιμοποιούν αυτή τη συσκευή εμφανίζονται παρακάτω.",
"cleanup_intro": "Κάθε κύκλος με ετικέτα επικαλύπτεται. Σημειώστε ακραίες τιμές και διαγράψτε για να καθαρίσετε το προφίλ.",
"clear_debug_hint": "Καταργήστε τα αποθηκευμένα δεδομένα εντοπισμού σφαλμάτων για να ελευθερώσετε χώρο.",
"collecting_data": "Συλλογή δεδομένων: απαιτούνται ακόμη {need} κύκλος{plural} πριν ξεκινήσει η βελτιστοποίηση ({current}/{min}).",
"collecting_data": "Συλλογή δεδομένων. Κύκλοι που απαιτούνται ακόμη πριν ξεκινήσει η βελτιστοποίηση: {need} ({current}/{min}).",
"compare_overlay_profiles": "Προφίλ επικάλυψης (ασθενώς)",
"compare_profiles_tip": "Επικαλύψτε άλλους φακέλους προφίλ στο παραπάνω γράφημα για να δείτε ποιος ταιριάζει καλύτερα σε αυτόν τον κύκλο.",
"compare_selected_cycles": "Επιλεγμένοι κύκλοι (συμπαγής) – εμφάνιση / απόκρυψη",
@@ -779,7 +814,7 @@
"cycles_deleted": "Διαγράφηκαν {count} κύκλοι",
"enough_data": "Αρκετά δεδομένα για εκμάθηση ({current}/{min} κύκλοι).",
"export_description": "Επιλέξτε ακριβώς ποια προφίλ, κύκλους, ρυθμίσεις και άλλα θα εξαχθούν σε JSON, ή αναλύστε ένα αρχείο και εισάγετε μόνο τα μέρη που θέλετε.",
"feedback_cycles_pending": "{n} κύκλος{s} για αξιολόγηση",
"feedback_cycles_pending": "Για αξιολόγηση: {n}",
"feedback_prompt": "Επιβεβαιώστε ότι ήταν σωστό, διορθώστε το πρόγραμμα ή αγνοήστε.",
"feedback_relabel_hint": "Η επανεπισήμανση αυτού του κύκλου τον επιλύει επίσης.",
"filter_by_profile": "Φιλτράρισμα κατά προφίλ…",
@@ -856,7 +891,6 @@
"pg_stress_synthetic": "η προσομοίωση αδράνειας ξεκινά εδώ",
"pg_sweep_intro": "Τι θα γινόταν αν το {param} ήταν διαφορετικό; Δοκιμάστε {steps} τιμές στους τελευταίους {cycles} κύκλους για να βρείτε τη ρύθμιση όπου αντιστοιχίζονται σωστά οι περισσότεροι κύκλοι.",
"pg_sweep_step": "Βήμα {done} / {total}",
"pg_undetected": "{n} μη εντοπισμένος κύκλος{s}",
"pg_verdict_bad": "Χρειάζεται προσοχή: πολλοί κύκλοι δεν εντοπίζονται.",
"pg_verdict_good": "Καλά ρυθμισμένο: οι περισσότεροι κύκλοι αναγνωρίζονται και αντιστοιχίζονται σωστά.",
"pg_verdict_ok": "Αποδεκτό: ορισμένοι κύκλοι χάθηκαν. Δοκιμάστε να μειώσετε το κατώφλι εκκίνησης.",
@@ -887,6 +921,7 @@
"review_recorded_tip": "Επισημάνετε αυτό ως έναν επιλεγμένο από το χέρι κύκλο αναφοράς για το πρόγραμμά του - τον ίδιο ρόλο με έναν μη αυτόματα εγγεγραμμένο κύκλο. Οι κύκλοι αναφοράς διατηρούνται πάντα, εισάγονται το αντίστοιχο πρότυπο και δεν απορρίπτονται ποτέ με εκκαθάριση. (Αυτή είναι η \"χρυσή\"/ηχογραφημένη σημαία· και τα δύο είναι το ίδιο πράγμα.)",
"review_tags_tip": "Προαιρετικές σημαίες που περιγράφουν τι πήγε στραβά με αυτόν τον κύκλο, οπότε η εκπαίδευση και ο καθαρισμός μπορούν να το εξηγήσουν.",
"review_to_cycles": "Ανοίξτε την ουρά ελέγχου Κύκλων",
"samples_decimated": "Εμφάνιση {shown} από {total} δείγματα (αραιωμένα για προβολή· διατηρούνται οι αιχμές). Ένα μεγάλο κενό εδώ είναι αραίωση, όχι δεδομένα που λείπουν.",
"saving_triggers_reload": "Η αποθήκευση ενεργοποιεί μια εκ νέου φόρτωση ενσωμάτωσης. Οι οντότητες HA ενδέχεται να εμφανίζονται για λίγο ως μη διαθέσιμες.",
"search_placeholder": "Ρυθμίσεις αναζήτησης…",
"see_recorder": "Δείτε παρακάτω το γραφικό στοιχείο εγγραφής",
@@ -1006,7 +1041,29 @@
"sug_mute_failed": "Αποτυχία σίγασης πρότασης",
"sug_unmuted_all": "Οι αποσιωπημένες προτάσεις επαναφέρθηκαν",
"n_suggestions_muted": "{count} αποσιωπημένες· ο αυτόματος ρυθμιστής δεν θα τις προτείνει.",
"font_size_hint": "Κάντε τα πάντα σε αυτόν τον πίνακα μεγαλύτερα ή μικρότερα. Ισχύει για τον λογαριασμό σας σε αυτήν τη συσκευή."
"font_size_hint": "Κάντε τα πάντα σε αυτόν τον πίνακα μεγαλύτερα ή μικρότερα. Ισχύει για τον λογαριασμό σας σε αυτήν τη συσκευή.",
"import_history_description": "Είχατε ήδη έξυπνο βύσμα πριν από το WashData; Ανεβάστε μια εξαγωγή ιστορικού του αισθητήρα ισχύος του, ή διαβάστε το απευθείας από το Home Assistant, και η κανονική ανίχνευση θα εκτελεστεί πάνω σε αυτό, ώστε οι παλιοί κύκλοι να εμφανιστούν στη λίστα Κύκλοι έτοιμοι για ονομασία.",
"hist_input_hint": "Ανεβάστε ένα CSV που κατεβάσατε από το πάνελ Ιστορικού (entity, state, last changed), ή αφήστε το WashData να διαβάσει απευθείας το ιστορικό του αισθητήρα. Στη συνέχεια η ανίχνευση εκτελείται πάνω σε αυτό ακριβώς όπως και σε ζωντανή λειτουργία, και εσείς επιλέγετε ποιους από τους κύκλους που βρέθηκαν θα διατηρήσετε.",
"hist_recorder_hint": "Διαβάζει από την ημερομηνία που επιλέγετε έως τώρα. Το Home Assistant διατηρεί από προεπιλογή αναλυτικό ιστορικό για 10 ημέρες και μόνο ωριαίους μέσους όρους μετά από αυτό, οι οποίοι είναι πολύ χονδροειδείς για την ανίχνευση κύκλων - επιλέξτε παλαιότερη ημερομηνία μόνο αν ο recorder είναι ρυθμισμένος να διατηρεί περισσότερα.",
"hist_scanning": "Το ιστορικό σας αναπαράγεται μέσα από τον ανιχνευτή. Αυτό εκτελείται στο παρασκήνιο - μπορείτε να κλείσετε αυτό το παράθυρο και να επιστρέψετε αργότερα.",
"hist_imported_count": "Εισήχθησαν {n} κύκλοι.",
"hist_duplicates": "{n} είχαν εισαχθεί ήδη και παραλείφθηκαν.",
"hist_capped": "Συμπληρώθηκε το όριο εισαγόμενων κύκλων ανά συσκευή· οι υπόλοιποι δεν αποθηκεύτηκαν.",
"hist_next_step": "Βρίσκονται στη λίστα Κύκλοι, με σήμανση ως εισαγόμενο ιστορικό. Ανοίξτε έναν και χρησιμοποιήστε την Επισήμανση για να ορίσετε το πρόγραμμα στο οποίο ανήκει.",
"hist_rows_read": "Διαβάστηκαν {n} μετρήσεις",
"hist_entity_substituted": "διαβάστηκε το {used} (αυτή η συσκευή είναι ρυθμισμένη για {wanted})",
"hist_breaks": "{n} κενά όπου ο αισθητήρας ήταν μη διαθέσιμος",
"hist_other_entity": "Παραλείφθηκαν {n} μετρήσεις άλλων οντοτήτων",
"hist_skipped_spans": "Διαστήματα που παραλείφθηκαν",
"hist_settings_used": "Ανιχνεύθηκε με τις τρέχουσες ρυθμίσεις αυτής της συσκευής (ελάχιστη ισχύς {w} W, καθυστέρηση απενεργοποίησης {s} δευτ.).",
"hist_none_found": "Δεν ανιχνεύθηκε κανένας κύκλος σε αυτό το ιστορικό.",
"hist_found": "Βρέθηκαν {n} κύκλοι. Αποεπιλέξτε ό,τι δεν μοιάζει με πραγματική λειτουργία - τίποτα δεν αποθηκεύεται πριν από την εισαγωγή.",
"hist_scan_capped": "Εμφανίζονται μόνο οι πρώτοι υποψήφιοι (βρέθηκαν {n}).",
"hist_recorder_empty": "Το Home Assistant δεν έχει αναλυτικό ιστορικό για αυτόν τον αισθητήρα σε εκείνο το διάστημα.",
"hist_scan_failed": "Η σάρωση απέτυχε.",
"hist_scan_expired": "Αυτή η σάρωση δεν είναι πλέον διαθέσιμη. Κάντε ξανά σάρωση.",
"hist_import_failed": "Η εισαγωγή απέτυχε.",
"imported_history_readonly": "Ανιχνεύθηκε σε εισαγόμενο ιστορικό ισχύος. Διαμορφώνει την αντιστοίχιση προγραμμάτων, αλλά δεν προσμετράται στα στατιστικά σας και δεν μπορεί να περικοπεί ή να διαχωριστεί. Επισημάνετέ τον για να ορίσετε το πρόγραμμα."
},
"phase_desc": {
"anti_crease": "Περιστασιακά σύντομες ανατροπές μετά την ολοκλήρωση για μείωση των ρυτίδων.",
@@ -1388,6 +1445,10 @@
"doc": "Αποθηκεύστε το πλήρες ίχνος ισχύος και τα αντίστοιχα δεδομένα εντοπισμού σφαλμάτων για κάθε κύκλο. Χρήσιμο για την αντιμετώπιση προβλημάτων, αλλά αυξάνει το μέγεθος του αποθηκευτικού χώρου.",
"label": "Αποθήκευση Ιχνών Αποσφαλμάτωσης"
},
"smart_termination_duration_ratio": {
"doc": "Πόσο μέσα στην αναμενόμενη διάρκεια του αντιστοιχισμένου προγράμματος πρέπει να έχει προχωρήσει ένας κύκλος προτού ο Έξυπνος Τερματισμός μπορέσει να τον τερματίσει νωρίς μόλις πέσει η ισχύς. Η αναμενόμενη διάρκεια είναι ο μέσος όρος του προγράμματος, οπότε σε συσκευές των οποίων ο χρόνος λειτουργίας ποικίλλει πολύ (πλυντήρια ρούχων με κρύο νερό παροχής τον χειμώνα έναντι ζεστού το καλοκαίρι, στεγνωτήρια με αισθητήρα στεγνώματος, προγράμματα που εξαρτώνται από το φορτίο) περίπου οι μισές από όλες τις εκτελέσεις τελειώνουν συντομότερα από αυτόν τον μέσο όρο και δεν λαμβάνουν ποτέ τον γρήγορο τερματισμό, τελειώνοντας μόνο μέσω του εφεδρικού χρονικού ορίου με καθυστέρηση λεπτών. Χαμηλώστε αυτή την τιμή (π.χ. 0,85) σε αυτά τα μηχανήματα ώστε ο πρόωρος τερματισμός να εξακολουθεί να ενεργοποιείται. Αυξήστε την προς το 1,0 για να είστε πιο συντηρητικοί. Αφήστε το κενό για την προεπιλογή (0,98, ή 0,99 για πλυντήρια πιάτων). Μπορεί μόνο να τερματίσει έναν κύκλο νωρίτερα, ποτέ αργότερα, και δεν ενεργοποιείται ποτέ σε μια ασαφή αντιστοίχιση ή αντιστοίχιση χαμηλής εμπιστοσύνης.",
"label": "Αναλογία Έξυπνου Τερματισμού"
},
"smoothing_window": {
"doc": "Πόσο εξομαλύνεται το πρωτογενές σήμα ισχύος. Το Low (2) ανταποκρίνεται αλλά είναι θορυβώδες. υψηλό (5) εξομαλύνει τις αιχμές αλλά προσθέτει υστέρηση.",
"label": "Παράθυρο Εξομάλυνσης"
@@ -1522,6 +1583,10 @@
"dishwasher_end_spike_quiet_release": {
"label": "Απελευθέρωση σε ήσυχο παθητικό στέγνωμα",
"doc": "Μόλις ο κύκλος ξεπεράσει την αναμενόμενη διάρκειά του, για πόσο χρόνο πρέπει το πλυντήριο πιάτων να παραμείνει ήσυχο (κάτω από το Κατώφλι Τερματισμού) πριν το WashData σταματήσει να περιμένει μια τελική αποστράγγιση και τερματίσει τον κύκλο. Αυξήστε το αν το μηχάνημά σας έχει μια μακρά, αθόρυβη φάση στεγνώματος πριν από μια καθυστερημένη τελική αποστράγγιση που δεν εντοπίζεται - ένα ευρύτερο παράθυρο επιτρέπει στη μαθημένη διάρκεια να ακολουθεί την εποχική μεταβολή (πιο κρύο νερό παροχής = μεγαλύτεροι κύκλοι) αντί να κλειδώνει στον παλιό μέσο όρο. Μπορεί μόνο να μειώσει την αναμονή σε σχέση με το εσωτερικό όριο των 30 λεπτών για την τελική αιχμή, ποτέ να την επεκτείνει."
},
"profile_evidence_sources": {
"label": "Κύκλοι που διαμορφώνουν ένα πρόγραμμα",
"doc": "Ποιοι κύκλοι χρησιμοποιούνται για τη δημιουργία της καμπύλης ισχύος κάθε προγράμματος και για την αντιστοίχιση ενός ολοκληρωμένου κύκλου με αυτήν. Αν αφαιρέσετε την επιλογή ενός είδους, αυτό σταματά να διαμορφώνει τα προγράμματά σας χωρίς να διαγράφεται τίποτα - οι κύκλοι παραμένουν στη λίστα Κύκλοι και μπορείτε ακόμη να τους επισημάνετε ή να τους αφαιρέσετε. Χρήσιμο αν δεν εμπιστεύεστε τα εισαγόμενα δεδομένα. Τα στατιστικά δεν επηρεάζονται: μετρούν πάντα μόνο τους κύκλους που εκτέλεσε πραγματικά αυτό το μηχάνημα. Η αφαίρεση όλων των επιλογών αγνοείται, καθώς ένα πρόγραμμα χωρίς κύκλους πίσω του δεν θα μπορούσε ποτέ να αντιστοιχιστεί."
}
},
"setting_group": {
@@ -1605,6 +1670,9 @@
},
"basic_configuration": {
"label": "Βασική διαμόρφωση"
},
"profile_evidence": {
"label": "Πηγές Προφίλ"
}
},
"status": {
@@ -1629,7 +1697,8 @@
"trimming": "Περικοπή…",
"splitting": "Διαίρεση…",
"deleting": "Διαγραφή…",
"imported": "Εισηγμένο"
"imported": "Εισηγμένο",
"preparing": "Προετοιμασία…"
},
"tab": {
"advanced": "Για προχωρημένους",
@@ -1659,6 +1728,7 @@
"wrong_profile": "Λάθος προφίλ"
},
"toast": {
"catalog_refreshed": "Ο κατάλογος της κοινότητας ανανεώθηκε",
"access_saved": "Ο έλεγχος πρόσβασης αποθηκεύτηκε",
"all_wiped": "Όλα τα δεδομένα διαγράφηκαν",
"analysis_complete_none": "Η ανάλυση ολοκληρώθηκε: δεν υπάρχουν νέες προτάσεις",
@@ -1670,7 +1740,7 @@
"cycle_labelled": "Κύκλος με ετικέτα",
"cycle_paused": "Ο κύκλος σταμάτησε",
"cycle_resumed": "Ο κύκλος συνεχίστηκε",
"cycle_trimmed": "Κύκλος κομμένο",
"cycle_trimmed": "Ο κύκλος περικόπηκε",
"cycles_merged": "Οι κύκλοι συγχωνεύτηκαν",
"envelope_rebuilt": "Φάκελος ανακατασκευασμένος",
"envelopes_rebuilt": "Φάκελοι ανακατασκευασμένοι",
@@ -1764,7 +1834,9 @@
"store_download_failed": "Η λήψη απέτυχε: {error}",
"store_download_nothing": "Δεν υπάρχει τίποτα νέο για λήψη - αυτή η ρύθμιση βρίσκεται ήδη στη συσκευή σας.",
"export_selective_done": "Η εξαγωγή λήφθηκε",
"import_selective_done": "Εισήχθησαν {profiles} προφίλ και {cycles} κύκλοι"
"import_selective_done": "Εισήχθησαν {profiles} προφίλ και {cycles} κύκλοι",
"hist_csv_required": "Φορτώστε πρώτα ένα αρχείο CSV ή επικολλήστε το περιεχόμενό του",
"file_read_failed": "Δεν ήταν δυνατή η ανάγνωση του αρχείου"
},
"suggestion": {
"both_agree": "Το WashData προτείνει",
@@ -1860,7 +1932,7 @@
"thr_batch": "Διατηρείται λίγο πάνω από τη χαμηλότερη ενεργό ισχύ p05 σε {cycles} κύκλους ({p05}W) ώστε μια έναρξη να εντοπίζεται όσο το δυνατόν νωρίτερα και το κατώφλι διακοπής να παραμένει κάτω από τη χαμηλότερη ισχύ λειτουργίας της μηχανής.",
"tol_per_profile": "p75 της διακύμανσης διάρκειας ανά προφίλ σε {profiles} προφίλ ({cycles} κύκλοι)· τα σταθερά προφίλ δεν επιβαρύνονται.",
"tol_pooled": "Βάσει της συγκεντρωτικής διακύμανσης διάρκειας {cycles} πρόσφατων κύκλων με ετικέτα (απόκλιση p95={dev}).",
"watchdog": "Διατηρείται όσο το δυνατόν χαμηλότερο με ασφάλεια (λίγο πάνω από το κενό ενημέρωσης p95 των {p95}s, ελάχ. 30s) ώστε οι διακοπές να εντοπίζονται γρήγορα χωρίς ψευδείς διακοπές."
"watchdog": "Διατηρείται όσο το δυνατόν χαμηλότερο με ασφάλεια (λίγο πάνω από το κενό ενημέρωσης p95 των {p95}s και τουλάχιστον 2× το διάστημα δειγματοληψίας των {median}s, ελάχ. 30s) ώστε οι διακοπές να εντοπίζονται γρήγορα χωρίς ψευδείς διακοπές."
},
"exclusions": {
"summary": "Εξαιρέθηκαν {total} εσφαλμένα εντοπισμένοι κύκλοι: {parts}.",
@@ -1917,7 +1989,8 @@
"dtw_refine_top_n": "Στάδιο 3: υποψήφιοι που επαναβαθμολογεί η DTW; αυξήστε σε 7-9 αν το σωστό προφίλ βρίσκεται στη 4η-5η θέση (προεπιλογή 5)",
"duration_scale": "Στάδιο 4: λόγος λογαρίθμου όπου η συμφωνία διάρκειας υποδιπλασιάζεται; μικρότερος = αυστηρότερη ποινή (προεπιλογή 0.175)",
"energy_scale": "Στάδιο 4: λόγος λογαρίθμου όπου η συμφωνία ενέργειας υποδιπλασιάζεται; μικρότερος = αυστηρότερη ποινή (προεπιλογή 0.25)",
"dishwasher_end_spike_quiet_release": "Πλυντήριο πιάτων: δευτερόλεπτα ησυχίας μετά την αναμενόμενη διάρκεια πριν απελευθερωθεί η αναμονή αποστράγγισης τέλους κύκλου"
"dishwasher_end_spike_quiet_release": "Πλυντήριο πιάτων: δευτερόλεπτα ησυχίας μετά την αναμενόμενη διάρκεια πριν απελευθερωθεί η αναμονή αποστράγγισης τέλους κύκλου",
"smart_termination_duration_ratio": "Κλάσμα της αναμενόμενης διάρκειας του αντιστοιχισμένου προγράμματος που πρέπει να φτάσει ένας κύκλος προτού ο Έξυπνος Τερματισμός μπορέσει να τον τερματίσει νωρίς· χαμηλώστε το για μηχανήματα που εξαρτώνται από το φορτίο ή τη θερμοκρασία"
},
"col": {
"profile_tip": "Όνομα αντιστοιχισμένου προγράμματος. Χωρίς ετικέτα σημαίνει ότι κανένα προφίλ δεν αντιστοιχίστηκε στο τέλος του κύκλου.",
@@ -1955,6 +2028,10 @@
"finished": "Ο κύκλος έφτασε σε τελική κατάσταση και ολοκληρώθηκε."
},
"store": {
"your_model_tip": "Αυτή είναι η συσκευή που δηλώσατε στις Ρυθμίσεις",
"your_model": "Δική σας",
"search_brand_ph": "Αναζήτηση κατά μάρκα…",
"programs_count": "Προγράμματα: {n}",
"browse": "Περιήγηση",
"device": "Συσκευή",
"favorites": "Αγαπημένα",
@@ -54,6 +54,7 @@
"awaiting": "Awaiting approval",
"awaiting_n": "Awaiting approval · {n} confirmed",
"awaiting_tip": "Awaiting community approval",
"backfilled_tip": "Detected in imported power history. Shapes program matching only, not counted in stats.",
"built_in_tag": "built-in",
"declining": "↘ declining",
"energy_low": "Lower energy than usual",
@@ -120,21 +121,6 @@
"discard_tip": "Discard the recorded trace without saving",
"disconnect": "Disconnect",
"dismiss": "Dismiss",
"mute_suggestion": "Stop suggesting this setting",
"pg_load_calibrated": "Load Calibrated (ML) ({n})",
"pg_load_calibrated_tip": "Stage ML-calibrated settings as Playground overrides",
"pg_load_live": "Load live settings",
"pg_load_live_tip": "Re-read the integration's current settings and drop every Playground edit",
"pg_load_suggested": "Load suggested ({n})",
"pg_load_suggested_tip": "Stage the auto-tuner's current suggestions as Playground overrides",
"pg_preset_delete": "Delete preset",
"pg_preset_load": "Load preset",
"pg_preset_load_tip": "Replace the Playground values with this preset (live settings are untouched)",
"pg_preset_save": "Save as preset",
"pg_preset_save_tip": "Save every value below as a named preset for this device",
"pg_publish_all": "Publish {n} to integration",
"pg_publish_one": "Publish {label} to the integration",
"reset_muted": "Reset muted",
"done": "Done",
"download_device": "Download this setup",
"download_export": "Download export",
@@ -147,10 +133,15 @@
"force_stop_tip": "Immediately end the current cycle and mark it as force-stopped",
"from_template": "From template ▾",
"group_suggest": "Group {n}: {members}",
"hist_goto_cycles": "Show me the cycles",
"hist_import_n": "Import {n} cycles",
"hist_read_recorder": "Read from Home Assistant",
"hist_scan": "Scan for cycles",
"ignore": "Ignore",
"import": "Import",
"import_json": "Import from JSON",
"import_overwrite": "Import (overwrites data)",
"import_power_history": "Import power history",
"import_raw": "Advanced: replace all from JSON",
"import_selected": "Import selected",
"inspect": "Inspect",
@@ -159,6 +150,7 @@
"load_more": "Load more",
"manage": "Manage",
"merge": "Merge",
"mute_suggestion": "Stop suggesting this setting",
"new_automation": " New Automation",
"new_group": "+ New Group",
"new_group_tip": "Group near-identical profiles (same shape/duration, different temperature or spin) so the matcher reliably picks between them",
@@ -173,6 +165,19 @@
"pg_apply_to_settings": "Save to settings",
"pg_apply_to_settings_tip": "Copy the values you edited here into this device's live settings",
"pg_autofill": "Auto-fill",
"pg_load_calibrated": "Load Calibrated (ML) ({n})",
"pg_load_calibrated_tip": "Stage ML-calibrated settings as Playground overrides",
"pg_load_live": "Load live settings",
"pg_load_live_tip": "Re-read the integration's current settings and drop every Playground edit",
"pg_load_suggested": "Load suggested ({n})",
"pg_load_suggested_tip": "Stage the auto-tuner's current suggestions as Playground overrides",
"pg_preset_delete": "Delete preset",
"pg_preset_load": "Load preset",
"pg_preset_load_tip": "Replace the Playground values with this preset (live settings are untouched)",
"pg_preset_save": "Save as preset",
"pg_preset_save_tip": "Save every value below as a named preset for this device",
"pg_publish_all": "Publish {n} to integration",
"pg_publish_one": "Publish {label} to the integration",
"play": "Play",
"process": "Process",
"process_history": "Process Now",
@@ -186,6 +191,7 @@
"rec_stop_tip": "Stop recording and hold the captured trace for review",
"record": "Start Recording",
"refresh": "Refresh",
"refresh_catalog": "Refresh catalog",
"refresh_diag_tip": "Reload storage statistics",
"refresh_logs_tip": "Reload the latest log records",
"refresh_settings_tip": "Reload settings from the server",
@@ -194,6 +200,7 @@
"remove_timer": "Delete",
"reset": "Reset",
"reset_ml_models_tip": "Discard the fine-tuned models and go back to the built-in ones. WashData can re-learn them later.",
"reset_muted": "Reset muted",
"reset_to_builtin": "Reset to built-in models",
"reset_to_defaults": "Reset to defaults",
"resume_cycle": "Resume cycle",
@@ -225,6 +232,7 @@
"select_all": "Select all",
"select_last20": "Last 20",
"select_none": "Clear",
"set_brand_model": "Set brand & model",
"share": "Share",
"share_device": "⬆ Share this device",
"share_device_tip": "Share this appliance and its recorded reference cycles to the community store so others with the same machine can adopt them",
@@ -252,14 +260,14 @@
"start": "Must be below Anti-Wrinkle Max Power ({max} W)"
},
"attn_sub": "Fix conflicts before saving",
"attn_title": "{n} setting conflict{s}",
"settings_banner": "{n} setting conflict{s} check the highlighted sections and fix before saving.",
"attn_title": "Setting conflicts: {n}",
"settings_banner": "Setting conflicts: {n}. Check the highlighted sections and fix them before saving.",
"settings_banner_btn": "Go to first",
"confidence": {
"auto": "Must be at or above Match Threshold ({match})",
"learning": "Must be at or below Match Threshold ({match})",
"learning": "Must be at or above Match Threshold ({match})",
"match_for_auto": "Must be at or below Auto-Label Confidence ({alc})",
"match_for_learning": "Must be at or above Learning Confidence ({lc})"
"match_for_learning": "Must be at or below Learning Confidence ({lc})"
},
"duration_ratio": {
"max": "Must be greater than Min Duration Ratio ({min})",
@@ -297,7 +305,7 @@
"match": "Must be above Unmatch Threshold ({un})",
"unmatch": "Must be below Match Threshold ({match}); otherwise a committed match un-matches instantly"
},
"cascade_toast": "Also adjusted {n} setting{s} for consistency.",
"cascade_toast": "Other settings adjusted for consistency: {n}",
"suggestion_resolves": "Stage the pending suggestion ({val}) below to fix this",
"use_fix": "Use {val}",
"watchdog": {
@@ -315,12 +323,14 @@
"automation_review_this_cycle": "Review this cycle",
"automations": "Automations",
"clear_debug": "Clear Debug Traces",
"community_store": "Community Store",
"cycle_simulator": "Cycle Simulator",
"diagnostics_pref": "Diagnostics",
"display": "Display",
"dtw_inspector": "DTW Inspector",
"export_import": "Export / Import",
"getting_started": "Getting started",
"import_power_history": "Import power history",
"live_power": "Live Power",
"logs": "Logs",
"logs_diagnostics": "Diagnostics",
@@ -335,12 +345,15 @@
"ml_smart_learning": "Smart Learning",
"my_preferences": "My Preferences",
"no_automations": "No automations reference this device yet.",
"online_account": "Community Store & online features",
"panel_settings": "Panel Settings",
"param_sweep": "Parameter sweep",
"pg_across_cycles": "Across your cycles",
"pg_settings_source": "Settings source",
"phase_catalog": "Phase Catalog",
"playground": "Playground",
"process_history": "Process History",
"recommendations": "Recommendations ({n})",
"settings_history": "Settings history",
"status": "Status",
"status_graph": "Status Graph",
@@ -348,11 +361,7 @@
"test_history": "Test on history",
"toggle_sidebar": "Toggle Home Assistant sidebar",
"tools_and_data": "Tools & Data",
"wipe_history": "Wipe History",
"recommendations": "Recommendations ({n})",
"pg_across_cycles": "Across your cycles",
"community_store": "Community Store",
"online_account": "Community Store & online features"
"wipe_history": "Wipe History"
},
"health": {
"fair": "Acceptable profile quality",
@@ -429,12 +438,12 @@
"cycles_title": "Cycles ({n})",
"dashed": "dashed",
"date": "Date",
"days": "days",
"debug_traces": "Debug Traces",
"default": "Default",
"default_access_level": "Default level for users not listed below",
"default_other": "Default (other devices)",
"default_tab": "Default tab when opening the panel",
"font_size": "Panel font size",
"delta": "Δ",
"description": "Description",
"dest_real_history": "Real history (counts in stats)",
@@ -459,11 +468,15 @@
"eta_secs": "~{n}s left",
"event_timeline": "Event timeline",
"event_type": "Event type",
"evidence_backfill_cycles": "Found in imported power history",
"evidence_real_cycles": "Cycles this machine ran",
"evidence_reference_cycles": "Downloaded from the community store",
"expected": "Expected",
"expected_duration": "Expected Duration (min)",
"file_kb": "File (kB)",
"final_score": "Final score",
"flags": "Flags",
"font_size": "Panel font size",
"from": "From",
"from_start": "From start",
"gap_s": "Gap (s)",
@@ -472,6 +485,17 @@
"head_trim": "Head Trim (s)",
"health": "Health",
"hide_tabs": "Hide tabs for non-admins",
"hist_csv_data": "CSV data",
"hist_from_recorder": "Or read it from Home Assistant",
"hist_keep": "Keep this cycle",
"hist_looks_complete": "complete",
"hist_reason_no_end": "never ended cleanly",
"hist_reason_short": "shorter than this appliance's shortest real cycle",
"hist_since": "Since",
"hist_skip_idle": "nothing running",
"hist_skip_long": "no break long enough to split on",
"hist_skip_short": "too few readings",
"hist_skip_sparse": "readings too far apart",
"import_mode": "How to combine",
"in_use": "In use",
"include_phase_map": "Include phase map",
@@ -492,7 +516,7 @@
"mode_merge": "Merge (keep mine)",
"mode_new_profile": "Create New Profile",
"mode_replace": "Replace selected",
"models_fine_tuned": "({count} model{plural} fine-tuned)",
"models_fine_tuned": "(fine-tuned models: {count})",
"n_classic_suggestions": "{n} classic",
"n_imported_note": ", {n} imported",
"n_ml_suggestions": "{n} ML",
@@ -509,12 +533,14 @@
"panel_default_tab": "Default tab",
"panel_language": "Panel language",
"pct_match_confidence": "{pct}% match confidence",
"peak_power_short": "Peak",
"per_cycle_short": "cycle",
"pg_alert_indefinite": "Would run indefinitely",
"pg_alert_stress_cap": "Hit safety cap",
"pg_alert_stress_ok": "Idle termination: cycle stopped",
"pg_alert_stress_warn": "Idle draw above stop threshold",
"pg_alert_timeout_end": "Ended by timeout, not prediction",
"pg_anti_wrinkle": "Anti-wrinkle",
"pg_autofill_tip": "Auto-fill range from current value ({lo}{hi})",
"pg_best_marker": "Best: {v}",
"pg_best_value": "Best value found",
@@ -531,15 +557,6 @@
"pg_group_matching": "Program matching",
"pg_group_timing": "Timing rules",
"pg_idle": "Idle",
"pg_preset": "Playground preset",
"pg_preset_name": "New preset name",
"pg_preset_none": "Select a preset…",
"pg_stress_group": "Idle termination test",
"pg_stress_idle_auto": "Auto",
"pg_stress_idle_w": "Idle level (W)",
"pg_stress_idle_w_desc": "Override the auto-detected standby floor (leave blank for auto).",
"pg_stress_toggle": "Test idle termination",
"pg_stress_toggle_desc": "Simulates the appliance staying at its standby draw after recording ends -- shows if and when WashData stops the cycle.",
"pg_last_run": "Last run: {date}",
"pg_load_run": "Reload this run",
"pg_match_confidence": "Match confidence",
@@ -547,7 +564,16 @@
"pg_mode_optimize": "Optimize",
"pg_pct_of": "{p}% of {total}",
"pg_poor_match": "Poor match",
"pg_preset": "Playground preset",
"pg_preset_name": "New preset name",
"pg_preset_none": "Select a preset…",
"pg_recent_runs": "Recent runs",
"pg_stress_group": "Idle termination test",
"pg_stress_idle_auto": "Auto",
"pg_stress_idle_w": "Idle level (W)",
"pg_stress_idle_w_desc": "Override the auto-detected standby floor (leave blank for auto).",
"pg_stress_toggle": "Test idle termination",
"pg_stress_toggle_desc": "Simulates the appliance staying at its standby draw after recording ends -- shows if and when WashData stops the cycle.",
"pg_strong_match": "Strong match",
"pg_tile_ambiguous": "Ambiguous",
"pg_tile_ambiguous_tip": "Cycles with a near-tie between two programs",
@@ -595,6 +621,7 @@
"settings_basic": "Basic",
"settings_detail_level": "Settings detail level",
"settings_overrides": "Settings overrides",
"shape": "Shape",
"show_contributor": "Show contributor names",
"show_debug": "Show live match debug card on the Status page (confidence, ambiguity, top candidates)",
"show_expected": "Show expected curve overlay (matched profile, orange)",
@@ -609,6 +636,8 @@
"store_model": "Appliance model",
"tags": "Tags",
"tail_trim": "Tail Trim (s)",
"task_history_import": "Scanning power history",
"task_history_import_apply": "Importing cycles",
"task_merge": "Merging cycles",
"task_ml_training": "Learning",
"task_pg_detail": "Simulate cycle",
@@ -630,8 +659,7 @@
"unlabelled": "Unlabelled",
"unlabelled_paren": "(unlabelled)",
"warp_path": "Warp path",
"zoom_hint": "scroll to zoom · dblclick to reset",
"pg_anti_wrinkle": "Anti-wrinkle"
"zoom_hint": "scroll to zoom · dblclick to reset"
},
"log": {
"all_levels": "All levels",
@@ -699,6 +727,7 @@
"export_select": "Export - choose data",
"force_stop_msg": "Force-stop the active cycle now? The cycle will be saved as interrupted.",
"force_stop_title": "Force Stop Cycle",
"history_import": "Import power history",
"import_config": "Import Configuration",
"import_wizard": "Import - choose data",
"label_cycle": "Label Cycle",
@@ -739,7 +768,7 @@
"automations_intro": "WashData fires {start} / {end} events and exposes entities, so notifications and actions are best built as normal Home Assistant automations. Automations that use this device appear below.",
"cleanup_intro": "Every labelled cycle overlaid. Tick outliers and delete to clean up the profile.",
"clear_debug_hint": "Remove stored debug data to free space.",
"collecting_data": "Collecting data {need} more cycle{plural} before fine-tuning can start ({current}/{min}).",
"collecting_data": "Collecting data. Cycles still needed before fine-tuning can start: {need} ({current}/{min}).",
"compare_overlay_profiles": "Overlay profiles (faint)",
"compare_overlay_tip": "Overlay learned profile envelopes to see which program each cycle resembles.",
"compare_profiles_tip": "Overlay other profile envelopes on the chart above to see which one best fits this cycle.",
@@ -760,16 +789,39 @@
"enough_data": "Enough data to learn from ({current}/{min} cycles).",
"export_description": "Choose exactly which profiles, cycles, settings and more to export to JSON, or analyze a file and import only the parts you want.",
"export_select_intro": "Tick exactly what to include. Selecting profiles without their cycles still exports a matchable program (its learned shape travels along).",
"feedback_cycles_pending": "{n} cycle{s} to review",
"feedback_cycles_pending": "To review: {n}",
"feedback_prompt": "Confirm it was right, correct the program, or ignore.",
"feedback_relabel_hint": "Re-labelling this cycle resolves it too.",
"filter_by_profile": "Filter by profile…",
"font_size_hint": "Make everything in this panel larger or smaller. Applies to your account on this device.",
"group_modal_help": "Group programs with the same shape that differ in temperature/spin (durations may vary). Matching scores the group as one candidate, then picks the best-fitting member. Pick at least 2; the overlay shows how alike they are.",
"group_not_cohesive": "These profiles aren't similar enough to group reliably, so matching treats them individually until you remove the outlier or split the group.",
"group_preview_hint": "Tick 2+ members to preview and compare their power curves.",
"head_trim_hint": "Remove this many seconds from the start",
"hist_breaks": "{n} gaps where the sensor was unavailable",
"hist_capped": "The per-device limit for imported cycles was reached; the rest were not stored.",
"hist_duplicates": "{n} were already imported and were skipped.",
"hist_entity_substituted": "read {used} (this device is configured for {wanted})",
"hist_found": "Found {n} cycles. Untick anything that does not look like a real run - nothing is stored until you import.",
"hist_import_failed": "Import failed.",
"hist_imported_count": "{n} cycles imported.",
"hist_input_hint": "Upload a CSV downloaded from the History panel (entity, state, last changed), or let WashData read the sensor's history directly. Detection then runs over it exactly as it does live, and you choose which of the cycles it finds to keep.",
"hist_next_step": "They are in your Cycles list, tagged as imported history. Open one and use Label to name the program it belongs to.",
"hist_none_found": "No cycles could be detected in that history.",
"hist_other_entity": "{n} readings for other entities ignored",
"hist_recorder_empty": "Home Assistant has no detailed history for this sensor in that window.",
"hist_recorder_hint": "Reads from the date you pick up to now. Home Assistant keeps detailed history for 10 days by default and only hourly averages after that, which are too coarse to detect cycles from - pick a date further back only if your recorder is set to keep more.",
"hist_rows_read": "{n} readings read",
"hist_scan_capped": "Only the first candidates are shown ({n} were found).",
"hist_scan_expired": "That scan is no longer available. Please scan again.",
"hist_scan_failed": "Scanning failed.",
"hist_scanning": "Replaying your history through the detector. This runs in the background - you can close this dialog and come back to it.",
"hist_settings_used": "Detected using this device's current settings (minimum power {w} W, off delay {s} s).",
"hist_skipped_spans": "Skipped stretches",
"import_analyze_hint": "Load an exported file (or paste its JSON). WashData analyzes it and shows exactly what can be imported before anything changes.",
"import_history_description": "Already had a smart plug before WashData? Upload a history export of its power sensor, or read it straight from Home Assistant, and the normal detection runs over it so past cycles turn up in your Cycles list ready to name.",
"import_intro": "Load an exported file or paste a JSON payload below.",
"imported_history_readonly": "Detected in imported power history. It shapes program matching but is not counted in your statistics, and cannot be trimmed or split. Label it to name the program.",
"imported_readonly": "Imported from the community store. Shown for reference and matching. It is not counted in your stats and cannot be edited.",
"include_settings_hint": "Share this device's recognition and matching thresholds (not your notifications, entities or energy price). Adopters choose whether to apply them.",
"legacy_actions_title": "{count} legacy custom action still running",
@@ -794,6 +846,7 @@
"ml_loading": "loading ML…",
"ml_settings_intro": "Two independent switches: one applies the models while a cycle runs, the other lets WashData fine-tune them to your machine over time.",
"model_not_found": "Not in the catalog yet.",
"n_suggestions_muted": "{count} muted; the auto-tuner will not propose these.",
"name_first_program": "You have enough cycles name your first program to start matching.",
"near_duplicate_cluster": "near-duplicate profile cluster detected. Grouping lets matching reliably pick between look-alikes (e.g. same program at different temperature/spin).",
"no_cycles_match": "No cycles match the current filter.",
@@ -836,37 +889,36 @@
"pg_analysis_hint2": "Pick a cycle and press Run to load match analysis.",
"pg_apply_confirm": "Apply best value: {label} = {value}?",
"pg_apply_settings_confirm": "Save these {n} setting(s) to this device? {list}",
"pg_canvas_empty": "Select a cycle above, then press Load to see its power trace.",
"pg_canvas_empty2": "Pick a cycle above and press Run to simulate it. Then hover to read values, scroll to zoom, and drag to pan.",
"pg_chart_caption": "Detection/match rate across values of {param}",
"pg_ctrl_intro": "Values start from this device's live integration settings. Edits stay in the Playground until you publish them.",
"pg_history_intro2": "Replay your recent cycles through the real detector and matcher with the settings above. Click any row to load that cycle in the graph; edit a setting to see a before/after comparison.",
"pg_live_unavailable": "Live settings unavailable, showing defaults.",
"pg_load_live_confirm": "Discard {n} Playground edit(s) and reload the integration's current settings?",
"pg_match_rate": "{pct}% match rate on {total} cycles",
"pg_matches_live": "Matches live settings",
"pg_n_changed": "{n} changed vs live settings",
"pg_sugg_none": "All suggestions already match the current settings",
"pg_preset_delete_confirm": "Delete the preset \"{name}\"?",
"pg_preset_limit": "Preset limit reached ({n})",
"pg_preset_overwrite": "Overwrite the preset \"{name}\"?",
"pg_publish_one_confirm": "Save {label} = {value} to this device's settings?",
"pg_stress_terminated_detail": "Settled to ~{idle}W idle -- cycle ended {h}h {m}m later via {reason}.",
"pg_stress_above_threshold_detail": "Idle draw ~{idle}W is at or above the effective stop threshold ({stop}W) -- the cycle never registered as quiet. Raise stop_threshold_w to fix.",
"pg_stress_hit_cap_detail": "Cycle ran {h}h {m}m without stopping -- force-stopped by the safety cap. Idle draw {idle}W vs stop threshold {stop}W.",
"pg_canvas_empty": "Select a cycle above, then press Load to see its power trace.",
"pg_canvas_empty2": "Pick a cycle above and press Run to simulate it. Then hover to read values, scroll to zoom, and drag to pan.",
"pg_chart_caption": "Detection/match rate across values of {param}",
"pg_history_intro2": "Replay your recent cycles through the real detector and matcher with the settings above. Click any row to load that cycle in the graph; edit a setting to see a before/after comparison.",
"pg_match_rate": "{pct}% match rate on {total} cycles",
"pg_restart_note": "Restart Home Assistant to enable simulation tools.",
"pg_row_load_hint": "Load this cycle in the graph above",
"pg_stress_synthetic": "idle simulation starts here",
"pg_running_history": "Replaying your cycles…",
"pg_running_sweep": "Testing values across your cycles…",
"pg_select_cycle_hint": "Select a cycle and click ↺ to load",
"pg_sim_progress": "{done} / {total} cycles",
"pg_simulating": "Simulating cycle…",
"pg_starting": "Starting…",
"pg_stress_above_threshold_detail": "Idle draw ~{idle}W is at or above the effective stop threshold ({stop}W) -- the cycle never registered as quiet. Raise stop_threshold_w to fix.",
"pg_stress_hit_cap_detail": "Cycle ran {h}h {m}m without stopping -- force-stopped by the safety cap. Idle draw {idle}W vs stop threshold {stop}W.",
"pg_stress_synthetic": "idle simulation starts here",
"pg_stress_terminated_detail": "Settled to ~{idle}W idle -- cycle ended {h}h {m}m later via {reason}.",
"pg_sugg_none": "All suggestions already match the current settings",
"pg_sweep_intro": "What if {param} were different? Test {steps} values across your last {cycles} cycles to find the setting where the most cycles are correctly matched.",
"pg_sweep_progress": "Step {done} / {total}",
"pg_sweep_step": "Step {done} / {total}",
"pg_undetected": "{n} cycle{s} undetected",
"pg_verdict_bad": "Needs attention: many cycles are going undetected.",
"pg_verdict_good": "Well tuned: most cycles are correctly identified and matched.",
"pg_verdict_ok": "Acceptable: some cycles missed. Try lowering the start threshold.",
@@ -878,7 +930,6 @@
"preferences_admin": "Preferences, panel & access control",
"preferences_adv": "Preferences",
"prefs_personal": "These apply to your Home Assistant account only.",
"font_size_hint": "Make everything in this panel larger or smaller. Applies to your account on this device.",
"process_history_hint": "Re-run matching on all stored cycles, refresh tuning suggestions, retrain the ML models (if enabled), and recompute cycle health. Run this after a batch of reviews.",
"profile_deleted": "Profile deleted",
"profile_poor_health_detail": "Cycles assigned to this profile have inconsistent shapes or low confidence. Consider rebuilding the envelope or reviewing labelled cycles.",
@@ -886,6 +937,7 @@
"rbac_hint": "When off, every Home Assistant user has full access (the default). Administrators always have full access and can manage everyone.",
"recent_logs": "Recent ha_washdata records",
"recording_in_progress": "Recording in progress",
"refresh_catalog_hint": "The community brand and appliance lists are cached to keep the shared store within its daily budget. Refresh to pick up entries added or approved by others.",
"reminders_intro": "Show a reminder in the panel this many cycles after the last service. Leave blank or 0 to turn a reminder off.",
"replace_warn": "Each ticked category is wiped and replaced from the file. Unticked categories are left untouched.",
"restart_gap_footer": "Highlighted on the graph. Power data is missing for these intervals; matching used only real readings.",
@@ -900,6 +952,7 @@
"review_recorded_tip": "Mark this as a hand-picked reference cycle for its program - the same role as a manually recorded cycle. Reference cycles are always kept, seed the matching template, and are never dropped by cleanup. (This is the \"golden\"/recorded flag; both are the same thing.)",
"review_tags_tip": "Optional flags describing what went wrong with this cycle, so training and cleanup can account for it.",
"review_to_cycles": "Open the Cycles review queue",
"samples_decimated": "Showing {shown} of {total} samples (thinned for display; peaks kept). A wide gap here is thinning, not missing data.",
"saving_triggers_reload": "Saving triggers an integration reload. HA entities may briefly show as unavailable.",
"search_placeholder": "Search settings…",
"see_recorder": "See recorder widget below",
@@ -918,16 +971,17 @@
"showing_suggestions": "Showing {count} setting with suggestions.",
"split_intro": "Click the graph to add or remove a split point, or auto-detect by idle gaps. Each resulting segment can get its own profile.",
"storage_diagnostics": "Storage stats, maintenance, export/import",
"store_declare_appliance": "Tell WashData which appliance you own and this tab shows the setups other people have shared for it. You can also type a brand above to look around.",
"store_download_device_intro": "Adopt every shared program and its reference cycles onto your device. Your own recorded cycles and stats are not affected.",
"store_enable_hint": "Enable online features in Settings to browse and import community reference cycles.",
"store_picker_offline": "Enable online features in the settings gear to pick from the community catalog.",
"store_share_device_intro": "Upload {brand} {model} with the reference cycles you select. Others with the same appliance can adopt your programs. Entries are reviewed before appearing publicly.",
"store_share_intro": "Upload this reference cycle so others with the same appliance can use it. It is reviewed before appearing publicly.",
"sug_staged": "Set {key} = {val}. Save to apply.",
"sug_muted": "Won't suggest this setting again",
"store_sibling_hint": "Nothing shared for your exact model? A closely-related model from the same brand is usually a good starting point.",
"sug_mute_failed": "Could not mute suggestion",
"sug_muted": "Won't suggest this setting again",
"sug_staged": "Set {key} = {val}. Save to apply.",
"sug_unmuted_all": "Muted suggestions reset",
"n_suggestions_muted": "{count} muted; the auto-tuner will not propose these.",
"tail_trim_hint": "Remove this many seconds from the end",
"toast_auto_detect_enabled": "Auto-detect enabled",
"toast_auto_label_complete": "Auto-label complete",
@@ -988,6 +1042,7 @@
"energy_scale": "Stage 4: log-ratio where energy agreement halves; smaller = stricter penalty (default 0.25)",
"anti_wrinkle_idle_timeout": "Quiet time allowed between two tumble pulses before anti-wrinkle ends",
"dishwasher_end_spike_quiet_release": "Dishwasher: quiet seconds after expected duration before the end-of-cycle drain wait is released",
"smart_termination_duration_ratio": "Fraction of the matched program's expected duration a cycle must reach before Smart Termination may end it early; lower it for load- or temperature-dependent machines",
"anti_wrinkle_max_power": "A pulse above this ends anti-wrinkle and opens a new cycle",
"anti_wrinkle_enabled": "Absorb the tumble pulses after the main phase instead of reading them as new cycles",
"anti_wrinkle_max_duration": "A pulse longer than this ends anti-wrinkle and opens a new cycle",
@@ -1093,6 +1148,10 @@
"doc": "Power must fall below this between pulses for anti-wrinkle mode to stay active.",
"label": "Exit Power Threshold"
},
"anti_wrinkle_idle_timeout": {
"label": "Max Pulse Gap",
"doc": "How long the machine may stay quiet between two tumble pulses before anti-wrinkle mode ends. Set it above the longest gap your dryer leaves between pulses, otherwise every later pulse is read as a false start."
},
"anti_wrinkle_max_duration": {
"doc": "Pulses longer than this are treated as a real cycle rather than an anti-wrinkle tumble.",
"label": "Max Duration"
@@ -1113,6 +1172,10 @@
"doc": "Cycles shorter than this are discarded as ghost cycles (test runs, opening the door to add a sock).",
"label": "Min Cycle Duration"
},
"corr_weight": {
"label": "Shape vs Level Weight",
"doc": "Balance between curve shape and absolute power level when scoring a match. Higher favours shape; lower favours matching the power level."
},
"delay_confirm_seconds": {
"doc": "Power must stay in the standby band for this long before the appliance is treated as waiting-to-start rather than running.",
"label": "Confirm Seconds"
@@ -1133,18 +1196,58 @@
"doc": "Once the cycle passes its expected duration, how long the dishwasher must stay quiet (below the Stop Threshold) before WashData stops waiting for a final drain and ends the cycle. Raise it if your machine has a long silent drying phase before a late final drain that is being missed - a wider window lets the learned duration follow seasonal drift (colder inlet water = longer cycles) instead of locking to the old average. It only ever shortens the wait relative to the internal 30-minute end-spike cap, never extends it.",
"label": "Passive-Dry Quiet Release"
},
"door_end_dwell_seconds": {
"label": "Door-Open End Dwell",
"doc": "How long the door must stay open before WashData ends the cycle, when \"Door Opens Automatically At End\" is on. Long enough to ignore quickly adding a dish (default 60 s), short enough to end promptly once the machine pops the door."
},
"door_opens_at_end": {
"label": "Door Opens Automatically At End",
"doc": "For dishwashers that pop the door open at the end of the cycle to dry (AirDry and similar). With this on, a door-open on a running cycle no longer pauses it forever; instead, if the door stays open for the dwell below, WashData treats the cycle as finished. A brief open (adding an item) is ignored. Requires a Door Sensor Entity."
},
"door_sensor_entity": {
"doc": "Optional door binary sensor. Used to detect when the appliance has been opened/unloaded after a cycle.",
"label": "Door Sensor Entity"
},
"dtw_bandwidth": {
"label": "Shape Match Tolerance",
"doc": "How much the matcher may time-warp a cycle to fit a saved program's shape. Higher tolerates more speed variation; too high risks matching the wrong program."
},
"dtw_blend": {
"label": "Warp Blend",
"doc": "How much the time-warp (DTW) alignment score replaces the Stage 2 core score. 0 = use only the Stage 2 score, 1 = use only the DTW score, 0.5 (default) = equal blend. Raise it to rely more on warp alignment when programs have similar power levels but different timing patterns."
},
"dtw_ddtw_scale": {
"label": "Derivative Warp Scale",
"doc": "Half-saturation distance for derivative DTW scoring. The score halves when the DDTW distance equals this value. Smaller = more sensitive to shape differences. Default 30 is calibrated to typical appliance power traces. Only affects ensemble and ddtw DTW modes."
},
"dtw_ensemble_w": {
"label": "Warp Ensemble Mix",
"doc": "In ensemble DTW mode (the default), the weight on scaled L1 versus derivative DTW (DDTW). 1.0 = all scaled-L1, 0 = all DDTW, 0.7 = default. The scaled-L1 variant compares power levels; the derivative variant reacts to how power changes over time. Ensemble blends both."
},
"dtw_refine_top_n": {
"label": "Warp Refine Count",
"doc": "How many top Stage 2 candidates are re-scored by DTW. DTW is more expensive so it is only applied to the best N candidates. Default 5. Raise it (to 7-9) if the correct profile sometimes only reaches 4th or 5th place after Stage 2 - DTW can rescue it. Lowering speeds up matching slightly."
},
"duration_scale": {
"label": "Duration Sharpness",
"doc": "Sharpness of the Stage 4 duration agreement penalty. This is the log-ratio at which the agreement score halves. Smaller = stricter: a duration mismatch hurts more. Default 0.175 corresponds to roughly 18% duration tolerance at half-weight. Pair with Duration Weight."
},
"duration_tolerance": {
"doc": "Tolerance for time-remaining estimates (learning feedback, not matching). If the actual duration is within +/-X% of the estimate it counts as a good match.",
"label": "Estimate Tolerance"
},
"duration_weight": {
"label": "Duration Weight",
"doc": "How strongly a program whose typical run-length matches this cycle is preferred."
},
"enable_ml_models": {
"doc": "While a cycle runs, let the models refine the live results: a steadier time-remaining and energy/cost estimate, and an anti-premature-stop guard on end detection (it can only ever delay a finish, never end one early, and is bounded). Uses your fine-tuned models when available, otherwise the built-in ones. Off = the classic power-based logic only (still reliable).",
"label": "Apply smart models during a cycle"
},
"enable_phase_matching": {
"doc": "Break each running cycle into phases (heating, wash, spin) and budget the time remaining per phase, blended with the classic estimate - leaning on the phase budget early in the cycle and the classic estimate near the end. This personalises the countdown to how long your machine actually heats and runs, which is most noticeable in the first half of a cycle. Off = the classic estimate only. Only the time-remaining display is affected; program matching and cycle detection are unchanged.",
"label": "Phase-aware time remaining"
},
"end_energy_threshold": {
"doc": "During the off-delay countdown, accumulated energy (watts x time) is compared to this threshold. If exceeded, the countdown resets - keeping anti-crease tumbles and dishwasher drying tails attached to the cycle instead of cutting them short. Raise it if cycles end too early during cool-down; lower it if detection is sluggish.",
"label": "End Energy"
@@ -1161,10 +1264,18 @@
"doc": "Fixed price per kWh used for cost figures when no live price entity is set above.",
"label": "Static Energy Price (per kWh)"
},
"energy_scale": {
"label": "Energy Sharpness",
"doc": "Sharpness of the Stage 4 energy agreement penalty. Smaller = stricter: an energy mismatch hurts more. Default 0.25 is intentionally more forgiving than Duration Sharpness because energy varies with load. Pair with Energy Weight."
},
"energy_sensor": {
"doc": "Optional cumulative energy counter (total_increasing kWh/Wh, e.g. the plug's own lifetime meter). When set, each cycle's reported energy is taken from this counter's start-to-end delta, which avoids the under-counting you get from integrating a slow-reporting power sensor. Falls back to the integrated value if the reading is missing, its unit is unknown, or the delta is not positive. Leave blank to keep integrating the power sensor.",
"label": "Energy Meter Entity"
},
"energy_weight": {
"label": "Energy Weight",
"doc": "How strongly a program whose typical energy use matches this cycle is preferred."
},
"expose_debug_entities": {
"doc": "Publish extra diagnostic HA entities (match confidence, ambiguity, state internals). Off keeps the entity list clean for normal use.",
"label": "Expose Debug Entities"
@@ -1181,6 +1292,10 @@
"doc": "Treat the trigger sensor turning OFF (rather than ON) as the end-of-cycle signal.",
"label": "Invert External Trigger (trigger on OFF)"
},
"keep_min_score": {
"label": "Min Match Score",
"doc": "Minimum similarity score a candidate needs to stay in the match race. The default 0.1 is deliberately permissive - it admits even weak candidates and relies on later stages to find the best match. Raise it to prune unlikely profiles earlier; lower it to widen the initial candidate pool."
},
"learning_confidence": {
"doc": "If the match score falls between this and Auto-Label Confidence, a feedback notification asks you to verify the identified program. Below this score the match is too uncertain to surface. Must be kept below Auto-Label Confidence.",
"label": "Learning Confidence"
@@ -1257,6 +1372,10 @@
"doc": "Show a live-updating countdown timer in the notification (on platforms that support it) instead of a static estimate.",
"label": "Use Live Chronometer"
},
"notify_live_click_action": {
"label": "Live Notification Tap Target",
"doc": "Android only. Where a tap on the live-progress notification opens (e.g. /lovelace/laundry, or a full URL) instead of the app landing page. Leave blank for the default."
},
"notify_live_interval_seconds": {
"doc": "How often live-progress notifications are refreshed while a cycle runs.",
"label": "Live Update Interval"
@@ -1269,6 +1388,10 @@
"doc": "notify.* services called for live progress updates while a cycle runs. Leave empty to disable live-progress notifications.",
"label": "Live Progress Services"
},
"notify_live_sticky": {
"label": "Keep Live Notification On Tap",
"doc": "Android only. Make the live-progress notification persistent (sticky) so tapping it does not dismiss the ongoing thread. Off keeps the default behaviour where a tap dismisses it."
},
"notify_milestone_message": {
"doc": "Message for the milestone notification. Template variables: {device}, {cycle_count}.",
"label": "Milestone Message"
@@ -1349,6 +1472,10 @@
"doc": "Optional power-based Off detection. When above 0, once a cycle has finished and power stays below this level for the Power Off Delay, the machine is treated as switched off and the state returns to Off. Leave at 0 to disable (the default). Set it above the true switched-off floor and below the Stop Threshold and your machine's finished-but-on standby draw; if it is not below the Stop Threshold it is ignored. When enabled it replaces the Progress Reset Delay for returning to Off, so a finished machine stays in Finished/Clean until it is actually powered off.",
"label": "Power Off Threshold"
},
"power_profile_interval_min": {
"label": "Power Profile Interval",
"doc": "Bucket size for the per-profile power_profile sensor attribute (the flat per-slot average-watts array consumed by external planners such as EMHASS and tibber_prices). Smaller buckets keep short power spikes sharp; larger buckets smooth the shape. Default 15 min. Read-time only; does not affect detection."
},
"power_sensor": {
"doc": "The sensor entity reporting live power in watts for this appliance (e.g. sensor.washer_power). All cycle detection is based on this signal.",
"label": "Power Sensor"
@@ -1357,6 +1484,10 @@
"doc": "The +/- band around a profile average duration used during matching. 0.25 means a 60 min profile matches 45-75 min cycles.",
"label": "Profile Duration Tolerance"
},
"profile_evidence_sources": {
"label": "Cycles that shape a program",
"doc": "Which cycles are used to build each program's power curve, and to match a finished cycle against it. Unticking a kind stops it shaping your programs without deleting anything - the cycles stay in your Cycles list and can still be labelled or removed. Useful if you do not trust imported data. Statistics are unaffected: they always count only the cycles this machine actually ran. Unticking everything is ignored, since a program with no cycles behind it could never match."
},
"profile_match_interval": {
"doc": "How often to attempt profile matching during a running cycle. Default 300 s (5 minutes) balances detection speed and CPU.",
"label": "Match Interval"
@@ -1393,6 +1524,13 @@
"doc": "Store the full power trace and matching debug data for each cycle. Useful for troubleshooting but increases storage size.",
"label": "Save Debug Traces"
},
"show_contributor": {
"doc": "Show the \"by <contributor>\" attribution on community appliances and reference cycles."
},
"smart_termination_duration_ratio": {
"doc": "How far into the matched program's expected duration a cycle must be before Smart Termination may end it early once power drops. The expected duration is the program's average, so on appliances whose runtime varies a lot - washers on cold winter vs warm summer inlet water, sensor-dry dryers, load-dependent programs - about half of all runs finish shorter than that average and never get the fast finish, ending only via the fallback timeout minutes late. Lower this (e.g. 0.85) on those machines so the early finish still fires; raise it toward 1.0 to be more conservative. Leave empty for the default (0.98, or 0.99 for dishwashers). It can only ever end a cycle earlier, never later, and never fires on an ambiguous or low-confidence match.",
"label": "Smart Termination Ratio"
},
"smoothing_window": {
"doc": "How much the raw power signal is smoothed. Low (2) is responsive but noisy; high (5) smooths spikes but adds lag.",
"label": "Smoothing Window"
@@ -1413,30 +1551,6 @@
"doc": "Power must fall below this level before the off-delay countdown begins. Set it below the Start Threshold - the gap between them is the hysteresis band that prevents flicker. If set too high, low-power phases (rinse holds, anti-crease) falsely trigger the end sequence.",
"label": "Stop Threshold"
},
"switch_entity": {
"doc": "Optional switch toggled off on pause and back on when resuming, used together with \"Pause also cuts power\".",
"label": "Switch Entity"
},
"watchdog_interval": {
"doc": "How often the background watchdog checks for stalled sensors and elapsed timeouts. Default 30 s.",
"label": "Watchdog Interval"
},
"dtw_bandwidth": {
"label": "Shape Match Tolerance",
"doc": "How much the matcher may time-warp a cycle to fit a saved program's shape. Higher tolerates more speed variation; too high risks matching the wrong program."
},
"corr_weight": {
"label": "Shape vs Level Weight",
"doc": "Balance between curve shape and absolute power level when scoring a match. Higher favours shape; lower favours matching the power level."
},
"duration_weight": {
"label": "Duration Weight",
"doc": "How strongly a program whose typical run-length matches this cycle is preferred."
},
"energy_weight": {
"label": "Energy Weight",
"doc": "How strongly a program whose typical energy use matches this cycle is preferred."
},
"store_brand": {
"label": "Appliance Brand",
"doc": "Optional. The appliance brand, picked from the community catalog. Used to find and share matching reference recordings. Leave blank if you are not using online features."
@@ -1445,70 +1559,22 @@
"label": "Appliance Model",
"doc": "Optional. The appliance model, picked from the community catalog once a brand is set. If your model is not listed you can add it to the catalog."
},
"show_contributor": {
"doc": "Show the \"by <contributor>\" attribution on community appliances and reference cycles."
"switch_entity": {
"doc": "Optional switch toggled off on pause and back on when resuming, used together with \"Pause also cuts power\".",
"label": "Switch Entity"
},
"enable_phase_matching": {
"doc": "Break each running cycle into phases (heating, wash, spin) and budget the time remaining per phase, blended with the classic estimate - leaning on the phase budget early in the cycle and the classic estimate near the end. This personalises the countdown to how long your machine actually heats and runs, which is most noticeable in the first half of a cycle. Off = the classic estimate only. Only the time-remaining display is affected; program matching and cycle detection are unchanged.",
"label": "Phase-aware time remaining"
},
"keep_min_score": {
"label": "Min Match Score",
"doc": "Minimum similarity score a candidate needs to stay in the match race. The default 0.1 is deliberately permissive - it admits even weak candidates and relies on later stages to find the best match. Raise it to prune unlikely profiles earlier; lower it to widen the initial candidate pool."
},
"dtw_blend": {
"label": "Warp Blend",
"doc": "How much the time-warp (DTW) alignment score replaces the Stage 2 core score. 0 = use only the Stage 2 score, 1 = use only the DTW score, 0.5 (default) = equal blend. Raise it to rely more on warp alignment when programs have similar power levels but different timing patterns."
},
"dtw_ensemble_w": {
"label": "Warp Ensemble Mix",
"doc": "In ensemble DTW mode (the default), the weight on scaled L1 versus derivative DTW (DDTW). 1.0 = all scaled-L1, 0 = all DDTW, 0.7 = default. The scaled-L1 variant compares power levels; the derivative variant reacts to how power changes over time. Ensemble blends both."
},
"dtw_ddtw_scale": {
"label": "Derivative Warp Scale",
"doc": "Half-saturation distance for derivative DTW scoring. The score halves when the DDTW distance equals this value. Smaller = more sensitive to shape differences. Default 30 is calibrated to typical appliance power traces. Only affects ensemble and ddtw DTW modes."
},
"dtw_refine_top_n": {
"label": "Warp Refine Count",
"doc": "How many top Stage 2 candidates are re-scored by DTW. DTW is more expensive so it is only applied to the best N candidates. Default 5. Raise it (to 7-9) if the correct profile sometimes only reaches 4th or 5th place after Stage 2 - DTW can rescue it. Lowering speeds up matching slightly."
},
"duration_scale": {
"label": "Duration Sharpness",
"doc": "Sharpness of the Stage 4 duration agreement penalty. This is the log-ratio at which the agreement score halves. Smaller = stricter: a duration mismatch hurts more. Default 0.175 corresponds to roughly 18% duration tolerance at half-weight. Pair with Duration Weight."
},
"energy_scale": {
"label": "Energy Sharpness",
"doc": "Sharpness of the Stage 4 energy agreement penalty. Smaller = stricter: an energy mismatch hurts more. Default 0.25 is intentionally more forgiving than Duration Sharpness because energy varies with load. Pair with Energy Weight."
},
"anti_wrinkle_idle_timeout": {
"label": "Max Pulse Gap",
"doc": "How long the machine may stay quiet between two tumble pulses before anti-wrinkle mode ends. Set it above the longest gap your dryer leaves between pulses, otherwise every later pulse is read as a false start."
},
"power_profile_interval_min": {
"label": "Power Profile Interval",
"doc": "Bucket size for the per-profile power_profile sensor attribute (the flat per-slot average-watts array consumed by external planners such as EMHASS and tibber_prices). Smaller buckets keep short power spikes sharp; larger buckets smooth the shape. Default 15 min. Read-time only; does not affect detection."
},
"notify_live_sticky": {
"label": "Keep Live Notification On Tap",
"doc": "Android only. Make the live-progress notification persistent (sticky) so tapping it does not dismiss the ongoing thread. Off keeps the default behaviour where a tap dismisses it."
},
"notify_live_click_action": {
"label": "Live Notification Tap Target",
"doc": "Android only. Where a tap on the live-progress notification opens (e.g. /lovelace/laundry, or a full URL) instead of the app landing page. Leave blank for the default."
},
"door_opens_at_end": {
"label": "Door Opens Automatically At End",
"doc": "For dishwashers that pop the door open at the end of the cycle to dry (AirDry and similar). With this on, a door-open on a running cycle no longer pauses it forever; instead, if the door stays open for the dwell below, WashData treats the cycle as finished. A brief open (adding an item) is ignored. Requires a Door Sensor Entity."
},
"door_end_dwell_seconds": {
"label": "Door-Open End Dwell",
"doc": "How long the door must stay open before WashData ends the cycle, when \"Door Opens Automatically At End\" is on. Long enough to ignore quickly adding a dish (default 60 s), short enough to end promptly once the machine pops the door."
"watchdog_interval": {
"doc": "How often the background watchdog checks for stalled sensors and elapsed timeouts. Default 30 s.",
"label": "Watchdog Interval"
}
},
"setting_group": {
"auto_labeling": {
"label": "Auto-Labeling"
},
"basic_configuration": {
"label": "Basic configuration"
},
"cycle_end": {
"label": "Cycle End"
},
@@ -1524,6 +1590,9 @@
"debug": {
"label": "Debug"
},
"device_info": {
"label": "Device info"
},
"dishwasher_end": {
"label": "Dishwasher End"
},
@@ -1557,6 +1626,9 @@
"predictive_end": {
"label": "Predictive End"
},
"profile_evidence": {
"label": "Profile Evidence"
},
"quiet_hours_milestones": {
"label": "Quiet Hours & Milestones"
},
@@ -1580,37 +1652,32 @@
},
"watchdog": {
"label": "Watchdog"
},
"device_info": {
"label": "Device info"
},
"basic_configuration": {
"label": "Basic configuration"
}
},
"status": {
"active": "Active",
"all_statuses": "All statuses",
"ambiguous": "Ambiguous",
"analyzing": "Analyzing…",
"auto_detect": "Auto-detect",
"clear": "Clear",
"completed": "Completed",
"deleting": "Deleting…",
"fine_tuning": "fine-tuning now…",
"force_stopped": "Force stopped",
"idle": "Idle",
"imported": "Imported",
"interrupted": "Interrupted",
"preparing": "Preparing…",
"ready": "Ready to process",
"recording": "Recording",
"training": "Training…",
"saving": "Saving…",
"rebuilding": "Rebuilding…",
"analyzing": "Analyzing",
"recording": "Recording",
"resetting": "Resetting…",
"reverting": "Reverting…",
"trimming": "Trimming…",
"saving": "Saving…",
"splitting": "Splitting…",
"deleting": "Deleting…",
"imported": "Imported"
"training": "Training…",
"trimming": "Trimming…"
},
"suggestion": {
"both_agree": "WashData recommends",
@@ -1757,6 +1824,7 @@
"auto_label_complete": "Auto-label complete",
"automation_deleted": "Automation deleted",
"brand_added": "Brand added - awaiting approval",
"catalog_refreshed": "Community catalog refreshed",
"correction_submitted": "Correction submitted",
"cycle_deleted": "Cycle deleted",
"cycle_force_stopped": "Cycle force-stopped",
@@ -1775,9 +1843,11 @@
"feedback_all_dismissed": "All feedbacks dismissed",
"feedback_confirmed": "Feedback confirmed",
"feedback_dismissed": "Feedback dismissed",
"file_read_failed": "Could not read that file",
"group_deleted": "Group deleted",
"group_name_required": "Group name is required",
"group_saved": "Group saved",
"hist_csv_required": "Load a CSV file or paste its contents first",
"import_selective_done": "Imported {profiles} profile(s) and {cycles} cycle(s)",
"import_successful": "Import successful; integration reloading",
"json_required": "JSON data is required",
@@ -1798,9 +1868,9 @@
"pause_no_cycle": "No active cycle to pause",
"pg_preset_loaded": "Preset \"{name}\" loaded",
"pg_preset_saved": "Preset \"{name}\" saved",
"pg_run_gone": "That run is no longer available.",
"pg_sugg_loaded": "Staged {n} suggested value(s) - run the Playground to compare",
"pg_sugg_ml_loaded": "Staged {n} ML-calibrated value(s) - run the Playground to compare",
"pg_run_gone": "That run is no longer available.",
"phase_name_required": "Phase name is required",
"phase_updated": "Phase updated",
"phases_saved": "Phases saved",
@@ -1899,7 +1969,11 @@
"browse": "Browse",
"device": "Device",
"favorites": "Favourites",
"programs_count": "Programs: {n}",
"search_brand_ph": "Search by brand…",
"search_ph": "Search by brand or model…",
"your_model": "Yours",
"your_model_tip": "This is the appliance you declared in Settings",
"no_results": "No matching appliances found. Try a different search.",
"n_programs": "{n} programs",
"n_cycles": "{n} cycles",
@@ -30,9 +30,12 @@
"awaiting": "A la espera de aprobación",
"imported_tip": "Importado de la tienda de la comunidad. Se usa solo para la coincidencia, no cuenta en las estadísticas.",
"not_importable": "n/d aquí",
"exists": "ya existe"
"exists": "ya existe",
"backfilled_tip": "Detectado en un historial de potencia importado. Solo influye en la coincidencia de programas, no cuenta en las estadísticas."
},
"btn": {
"set_brand_model": "Definir marca y modelo",
"refresh_catalog": "Actualizar catálogo",
"add_device": "+ Agregar dispositivo",
"add_device_tip": "Agregue otro dispositivo WashData",
"add_maintenance": "Agregar evento de mantenimiento",
@@ -193,7 +196,12 @@
"import_selected": "Importar lo seleccionado",
"back": "Atrás",
"mute_suggestion": "Dejar de sugerir este ajuste",
"reset_muted": "Restablecer silenciados"
"reset_muted": "Restablecer silenciados",
"import_power_history": "Importar historial de potencia",
"hist_read_recorder": "Leer desde Home Assistant",
"hist_scan": "Buscar ciclos",
"hist_import_n": "Importar {n} ciclos",
"hist_goto_cycles": "Ver los ciclos"
},
"conflict": {
"anti_wrinkle_exit": {
@@ -205,14 +213,14 @@
"start": "Debe ser inferior a la Potencia máxima antiarrugas ({max} W)"
},
"attn_sub": "Corrige los conflictos antes de guardar",
"attn_title": "{n} conflicto{s} de ajustes",
"settings_banner": "{n} conflicto{s} de ajustes revisa las secciones resaltadas y corrígelos antes de guardar.",
"attn_title": "Conflictos de ajustes: {n}",
"settings_banner": "Conflictos de ajustes: {n}. Revisa las secciones resaltadas y corrígelos antes de guardar.",
"settings_banner_btn": "Ir al primero",
"confidence": {
"auto": "Debe ser mayor o igual al Umbral de coincidencia ({match})",
"learning": "Debe ser menor o igual al Umbral de coincidencia ({match})",
"learning": "Debe ser mayor o igual al Umbral de coincidencia ({match})",
"match_for_auto": "Debe ser menor o igual a la Confianza de etiquetado automático ({alc})",
"match_for_learning": "Debe ser mayor o igual a la Confianza de aprendizaje ({lc})"
"match_for_learning": "Debe ser menor o igual a la Confianza de aprendizaje ({lc})"
},
"duration_ratio": {
"max": "Debe ser mayor que el Ratio de duración mínimo ({min})",
@@ -250,7 +258,7 @@
"match": "Debe ser superior al Umbral de no coincidencia ({un})",
"unmatch": "Debe ser inferior al Umbral de coincidencia ({match}); de lo contrario, una coincidencia confirmada se deshace instantáneamente"
},
"cascade_toast": "También se ajustaron {n} ajuste{s} por coherencia.",
"cascade_toast": "Otros ajustes modificados por coherencia: {n}",
"suggestion_resolves": "Aplique la sugerencia pendiente ({val}) abajo para corregir esto",
"use_fix": "Usar {val}",
"watchdog": {
@@ -308,7 +316,8 @@
"pg_outcome": "Resultado de la simulación",
"pg_across_cycles": "En todos tus ciclos",
"community_store": "Tienda de la comunidad",
"online_account": "Tienda de la comunidad y funciones en línea"
"online_account": "Tienda de la comunidad y funciones en línea",
"import_power_history": "Importar historial de potencia"
},
"health": {
"fair": "Calidad de perfil aceptable",
@@ -316,6 +325,7 @@
"poor": "⚠ Calidad de perfil deficiente"
},
"lbl": {
"drag_to_resize": "Arrastre para cambiar el tamaño",
"actions": "Comportamiento",
"activity": "Actividad",
"administrators": "Administradores",
@@ -402,7 +412,7 @@
"metric": "Métrica",
"mode_existing_profile": "Agregar al perfil existente",
"mode_new_profile": "Crear nuevo perfil",
"models_fine_tuned": "({count} modelo{plural} ajustado{plural})",
"models_fine_tuned": "(modelos ajustados: {count})",
"n_classic_suggestions": "{n} clásico",
"n_ml_suggestions": "{n} ML",
"n_selected": "{n} seleccionados",
@@ -629,7 +639,26 @@
"conflict_import_copy": "Importar como copia",
"conflict_keep_mine": "Conservar el mío",
"conflict_overwrite": "Sobrescribir",
"font_size": "Tamaño de fuente del panel"
"font_size": "Tamaño de fuente del panel",
"hist_csv_data": "Datos CSV",
"hist_from_recorder": "O léalo desde Home Assistant",
"hist_since": "Desde",
"days": "días",
"hist_keep": "Conservar este ciclo",
"hist_looks_complete": "completo",
"peak_power_short": "Pico",
"shape": "Forma",
"hist_skip_idle": "nada en funcionamiento",
"hist_skip_sparse": "lecturas demasiado separadas",
"hist_skip_short": "muy pocas lecturas",
"hist_skip_long": "ninguna pausa lo bastante larga para dividir",
"hist_reason_short": "más corto que el ciclo real más corto de este electrodoméstico",
"hist_reason_no_end": "nunca terminó de forma limpia",
"task_history_import": "Analizando el historial de potencia",
"task_history_import_apply": "Importando ciclos",
"evidence_real_cycles": "Ciclos que ejecutó esta máquina",
"evidence_reference_cycles": "Descargados de la tienda de la comunidad",
"evidence_backfill_cycles": "Encontrados en un historial de potencia importado"
},
"log": {
"all_levels": "Todos los niveles",
@@ -708,9 +737,15 @@
"store_share": "Compartir en la tienda de la comunidad",
"store_share_device": "Compartir este dispositivo",
"export_select": "Exportar - elegir datos",
"import_wizard": "Importar - elegir datos"
"import_wizard": "Importar - elegir datos",
"history_import": "Importar historial de potencia"
},
"msg": {
"tail_trim_hint": "Número de segundos que se eliminarán del final",
"store_sibling_hint": "¿No hay nada compartido para su modelo exacto? Un modelo muy parecido de la misma marca suele ser un buen punto de partida.",
"store_declare_appliance": "Indique a WashData qué electrodoméstico tiene y esta pestaña mostrará las configuraciones que otras personas han compartido para él. También puede escribir una marca arriba para echar un vistazo.",
"refresh_catalog_hint": "Las listas de marcas y electrodomésticos de la comunidad se guardan en caché para mantener la tienda compartida dentro de su cuota diaria. Actualice para incorporar las entradas añadidas o aprobadas por otros usuarios.",
"head_trim_hint": "Número de segundos que se eliminarán del inicio",
"appliance_monitor": "monitor de electrodomésticos",
"artifact_dip_detail": "Cayó por debajo de la banda de potencia habitual durante ~{n}s.",
"artifact_footer": "Destacado en el gráfico de arriba. Estos son artefactos transitorios (por ejemplo, la puerta se abrió a mitad del ciclo), no necesariamente problemas.",
@@ -721,7 +756,7 @@
"automations_intro": "WashData dispara los eventos {start} / {end} y expone entidades, por lo que las notificaciones y acciones se construyen mejor como automatizaciones normales de Home Assistant. Las automatizaciones que usan este dispositivo aparecen a continuación.",
"cleanup_intro": "Cada ciclo etiquetado se superpone. Marque los valores atípicos y elimínelos para limpiar el perfil.",
"clear_debug_hint": "Elimine los datos de depuración almacenados para liberar espacio.",
"collecting_data": "Recopilando datos - faltan {need} ciclo{plural} más antes de que pueda comenzar el ajuste fino ({current}/{min}).",
"collecting_data": "Recopilando datos. Ciclos que faltan para que pueda comenzar el ajuste fino: {need} ({current}/{min}).",
"compare_overlay_profiles": "Perfiles superpuestos (débil)",
"compare_profiles_tip": "Superponga otros sobres de perfil en el cuadro anterior para ver cuál se adapta mejor a este ciclo.",
"compare_selected_cycles": "Ciclos seleccionados (sólidos): mostrar/ocultar",
@@ -731,7 +766,7 @@
"cycles_deleted": "{count} ciclo(s) eliminado(s)",
"enough_data": "Suficientes datos para aprender ({current}/{min} ciclos).",
"export_description": "Elige exactamente qué perfiles, ciclos, ajustes y más exportar a JSON, o analiza un archivo e importa solo las partes que quieras.",
"feedback_cycles_pending": "{n} ciclo{s} por revisar",
"feedback_cycles_pending": "Para revisar: {n}",
"feedback_prompt": "Confirme que era correcto, corrija el programa o ignórelo.",
"feedback_relabel_hint": "Volver a etiquetar este ciclo también lo resuelve.",
"filter_by_profile": "Filtrar por perfil…",
@@ -765,7 +800,7 @@
"no_cycles_yet": "Aún no se han registrado ciclos.",
"no_device_selected": "Ningún dispositivo seleccionado.",
"no_devices": "Aún no hay dispositivos WashData configurados.",
"no_envelope": "Aún no hay sobre: reconstruir después de los ciclos de etiquetado.",
"no_envelope": "Aún no hay sobre: reconstruir después de los ciclos de etiquetado.",
"no_envelope_overlay": "No hay sobre disponible para superponer.",
"no_fine_tuned": "Aún no hay nada ajustado: WashData está utilizando sus modelos integrados.",
"no_logs": "Aún no hay registros almacenados en el búfer.",
@@ -808,7 +843,6 @@
"pg_stress_synthetic": "la simulación en reposo empieza aquí",
"pg_sweep_intro": "¿Y si {param} fuera diferente? Pruebe {steps} valores en sus últimos {cycles} ciclos para encontrar el ajuste con el que más ciclos se reconocen correctamente.",
"pg_sweep_step": "Paso {done} / {total}",
"pg_undetected": "{n} ciclo{s} no detectado{s}",
"pg_verdict_bad": "Necesita atención: muchos ciclos no se detectan.",
"pg_verdict_good": "Bien ajustado: la mayoría de los ciclos se identifican y reconocen correctamente.",
"pg_verdict_ok": "Aceptable: algunos ciclos no se detectaron. Pruebe a bajar el umbral de inicio.",
@@ -839,6 +873,7 @@
"review_recorded_tip": "Marque esto como un ciclo de referencia cuidadosamente seleccionado para su programa: la misma función que un ciclo registrado manualmente. Los ciclos de referencia siempre se mantienen, generan la plantilla coincidente y nunca se eliminan durante la limpieza. (Esta es la bandera \"dorada\"/grabada; ambas son lo mismo).",
"review_tags_tip": "Banderas opcionales que describen lo que salió mal en este ciclo, para que el entrenamiento y la limpieza puedan explicarlo.",
"review_to_cycles": "Abrir la cola de revisión de Ciclos",
"samples_decimated": "Mostrando {shown} de {total} muestras (reducidas para la visualización; se conservan los picos). Un hueco amplio aquí se debe a la reducción, no a datos faltantes.",
"saving_triggers_reload": "Al guardar se activa una recarga de integración. Las entidades HA pueden aparecer brevemente como no disponibles.",
"search_placeholder": "Configuración de búsqueda…",
"see_recorder": "Vea el widget de grabadora a continuación",
@@ -958,10 +993,33 @@
"sug_mute_failed": "No se pudo silenciar la sugerencia",
"sug_unmuted_all": "Sugerencias silenciadas restablecidas",
"n_suggestions_muted": "{count} silenciadas; el ajustador automático no propondrá estas.",
"font_size_hint": "Aumenta o reduce el tamaño de todo en este panel. Se aplica a tu cuenta en este dispositivo."
"font_size_hint": "Aumenta o reduce el tamaño de todo en este panel. Se aplica a tu cuenta en este dispositivo.",
"import_history_description": "¿Ya tenía un enchufe inteligente antes de WashData? Cargue una exportación del historial de su sensor de potencia, o léalo directamente desde Home Assistant: la detección normal se ejecuta sobre esos datos, así que los ciclos pasados aparecen en su lista de Ciclos listos para nombrar.",
"hist_input_hint": "Cargue un CSV descargado del panel Historial (entidad, estado, último cambio), o deje que WashData lea directamente el historial del sensor. Después la detección se ejecuta sobre él igual que en directo, y usted elige cuáles de los ciclos encontrados conservar.",
"hist_recorder_hint": "Lee desde la fecha que elija hasta ahora. Home Assistant guarda el historial detallado durante 10 días de forma predeterminada y, a partir de ahí, solo promedios por hora, demasiado imprecisos para detectar ciclos - elija una fecha más antigua solo si el recorder de Home Assistant está configurado para conservar más.",
"hist_scanning": "Se está reproduciendo su historial a través del detector. Esto se ejecuta en segundo plano: puede cerrar este diálogo y volver más tarde.",
"hist_imported_count": "{n} ciclos importados.",
"hist_duplicates": "{n} ya se habían importado y se omitieron.",
"hist_capped": "Se alcanzó el límite de ciclos importados por dispositivo; el resto no se guardó.",
"hist_next_step": "Están en su lista de Ciclos, marcados como historial importado. Abra uno y use Etiquetar para indicar el programa al que pertenece.",
"hist_rows_read": "{n} lecturas leídas",
"hist_breaks": "{n} huecos en los que el sensor no estaba disponible",
"hist_other_entity": "{n} lecturas de otras entidades ignoradas",
"hist_entity_substituted": "{used} leído (este dispositivo está configurado para {wanted})",
"hist_skipped_spans": "Tramos omitidos",
"hist_settings_used": "Detectado con los ajustes actuales de este dispositivo (potencia mínima {w} W, retardo de apagado {s} s).",
"hist_none_found": "No se pudo detectar ningún ciclo en ese historial.",
"hist_found": "Se encontraron {n} ciclos. Desmarque todo lo que no parezca un ciclo real: no se guarda nada hasta que importe.",
"hist_scan_capped": "Solo se muestran los primeros candidatos (se encontraron {n}).",
"hist_recorder_empty": "Home Assistant no tiene historial detallado de este sensor en ese periodo.",
"hist_scan_failed": "El análisis falló.",
"hist_scan_expired": "Ese análisis ya no está disponible. Vuelva a analizar el historial.",
"hist_import_failed": "La importación falló.",
"imported_history_readonly": "Detectado en un historial de potencia importado. Influye en la coincidencia de programas, pero no cuenta en sus estadísticas y no se puede recortar ni dividir. Etiquételo para indicar el programa."
},
"pg_desc": {
"dishwasher_end_spike_quiet_release": "Lavavajillas: segundos de silencio tras la duración esperada antes de liberar la espera del vaciado de fin de ciclo",
"smart_termination_duration_ratio": "Fracción de la duración esperada del programa coincidente que un ciclo debe alcanzar antes de que la Terminación inteligente pueda finalizarlo antes de tiempo; redúzcala para máquinas que dependen de la carga o la temperatura",
"anti_wrinkle_enabled": "Absorber los pulsos de volteo tras la fase principal en lugar de leerlos como nuevos ciclos",
"anti_wrinkle_exit_power": "La potencia debe caer por debajo de este valor entre pulsos para que el modo antiarrugas siga activo",
"anti_wrinkle_idle_timeout": "Tiempo de silencio permitido entre dos pulsos de volteo antes de que finalice el modo antiarrugas",
@@ -1198,7 +1256,7 @@
"label": "Potencia mínima"
},
"ml_training_enabled": {
"doc": "Estudie periódicamente los ciclos revisados durante la noche y ajuste los modelos a esta máquina específica. Un cambio sólo se mantiene cuando realmente obtiene una mejor puntuación en los ciclos prolongados, por lo que esto sólo puede ayudar o permanecer igual, nunca retroceder.",
"doc": "Estudie periódicamente los ciclos revisados durante la noche y ajuste los modelos a esta máquina específica. Un cambio sólo se mantiene cuando realmente obtiene una mejor puntuación en los ciclos prolongados, por lo que esto sólo puede ayudar o permanecer igual, nunca retroceder.",
"label": "Aprender de esta máquina"
},
"ml_training_hour": {
@@ -1373,6 +1431,10 @@
"doc": "Almacene el seguimiento de potencia total y los datos de depuración coincidentes para cada ciclo. Útil para solucionar problemas pero aumenta el tamaño de almacenamiento.",
"label": "Guardar trazas de depuración"
},
"smart_termination_duration_ratio": {
"doc": "Cuánto debe haber avanzado un ciclo dentro de la duración esperada del programa coincidente antes de que la Terminación inteligente pueda finalizarlo antes de tiempo una vez que la potencia cae. La duración esperada es el promedio del programa, por lo que en aparatos cuyo tiempo de funcionamiento varía mucho - lavadoras según el agua de entrada fría en invierno o templada en verano, secadoras con sensor de humedad, programas que dependen de la carga - cerca de la mitad de las ejecuciones terminan antes que ese promedio y nunca obtienen el final rápido, finalizando solo mediante el tiempo de espera de reserva con minutos de retraso. Baje este valor (p. ej. 0,85) en esas máquinas para que el final anticipado siga activándose; súbalo hacia 1,0 para ser más conservador. Déjelo vacío para el valor predeterminado (0,98, o 0,99 para lavavajillas). Solo puede finalizar un ciclo antes, nunca después, y nunca se activa en una coincidencia ambigua o de baja confianza.",
"label": "Proporción de terminación inteligente"
},
"smoothing_window": {
"doc": "Cuánto se suaviza la señal de potencia bruta. Bajo (2) responde pero es ruidoso; alto (5) suaviza los picos pero agrega retraso.",
"label": "Ventana de suavizado"
@@ -1503,6 +1565,10 @@
"door_end_dwell_seconds": {
"label": "Tiempo mínimo de puerta abierta para finalizar",
"doc": "Cuánto tiempo debe permanecer abierta la puerta antes de que WashData finalice el ciclo, cuando «La puerta se abre automáticamente al final» está activada. Lo suficientemente largo como para ignorar añadir un elemento rápidamente (predeterminado 60 s), y lo suficientemente corto como para terminar pronto una vez que la máquina abra la puerta."
},
"profile_evidence_sources": {
"label": "Ciclos que forman un programa",
"doc": "Qué ciclos se usan para construir la curva de potencia de cada programa y para comparar con ella un ciclo terminado. Al desmarcar un tipo, este deja de dar forma a sus programas sin que se borre nada - los ciclos siguen en su lista de Ciclos y aún se pueden etiquetar o eliminar. Útil si no confía en los datos importados. Las estadísticas no se ven afectadas: siempre cuentan solo los ciclos que esta máquina ejecutó realmente. Desmarcar todo se ignora, ya que un programa sin ciclos detrás nunca podría coincidir."
}
},
"setting_group": {
@@ -1586,6 +1652,9 @@
},
"basic_configuration": {
"label": "Configuración básica"
},
"profile_evidence": {
"label": "Base de los perfiles"
}
},
"status": {
@@ -1610,7 +1679,8 @@
"trimming": "Recortando…",
"splitting": "Dividiendo…",
"deleting": "Eliminando…",
"imported": "Importado"
"imported": "Importado",
"preparing": "Preparando…"
},
"tab": {
"advanced": "Avanzado",
@@ -1640,6 +1710,7 @@
"wrong_profile": "perfil equivocado"
},
"toast": {
"catalog_refreshed": "Catálogo de la comunidad actualizado",
"access_saved": "Control de acceso guardado",
"all_wiped": "Todos los datos borrados",
"analysis_complete_none": "Análisis completo: no hay nuevas sugerencias",
@@ -1745,7 +1816,9 @@
"store_download_failed": "Error al descargar: {error}",
"store_download_nothing": "Nada nuevo que descargar - esta configuración ya está en tu dispositivo.",
"export_selective_done": "Exportación descargada",
"import_selective_done": "Se importaron {profiles} perfil(es) y {cycles} ciclo(s)"
"import_selective_done": "Se importaron {profiles} perfil(es) y {cycles} ciclo(s)",
"hist_csv_required": "Cargue primero un archivo CSV o pegue su contenido",
"file_read_failed": "No se pudo leer ese archivo"
},
"suggestion": {
"both_agree": "WashData recomienda",
@@ -1841,7 +1914,7 @@
"thr_batch": "Se mantiene justo por encima de la potencia activa más baja en el p05 en {cycles} ciclos ({p05}W) para captar un arranque lo antes posible y que el umbral de parada quede por debajo de la potencia de funcionamiento más baja de la máquina.",
"tol_per_profile": "p75 de la varianza de duración por perfil en {profiles} perfiles ({cycles} ciclos); los perfiles ajustados no se penalizan.",
"tol_pooled": "Según la varianza de duración agrupada de {cycles} ciclos etiquetados recientes (desviación p95={dev}).",
"watchdog": "Se mantiene lo más bajo que resulta seguro (justo por encima del intervalo de actualización p95 de {p95}s, mín. 30s) para detectar rápido los bloqueos sin paradas falsas."
"watchdog": "Se mantiene lo más bajo que resulta seguro (justo por encima del intervalo de actualización p95 de {p95}s y al menos 2x el intervalo de muestreo de {median}s, mín. 30s) para detectar rápido los bloqueos sin paradas falsas."
},
"exclusions": {
"summary": "Excluido(s) {total} ciclo(s) mal detectado(s): {parts}.",
@@ -1907,6 +1980,10 @@
"finished": "El ciclo alcanzó un estado final y terminó."
},
"store": {
"your_model_tip": "Este es el electrodoméstico que declaró en Ajustes",
"your_model": "El suyo",
"search_brand_ph": "Buscar por marca…",
"programs_count": "Programas: {n}",
"browse": "Explorar",
"device": "Dispositivo",
"favorites": "Favoritos",
@@ -78,9 +78,12 @@
"awaiting": "Ootab heakskiitu",
"imported_tip": "Imporditud kogukonna poest. Kasutatakse ainult sobitamiseks, ei arvestata statistikas.",
"not_importable": "pole saadaval",
"exists": "on olemas"
"exists": "on olemas",
"backfilled_tip": "Tuvastatud imporditud võimsuse ajaloos. Mõjutab ainult programmide sobitamist, statistikas ei arvestata."
},
"btn": {
"set_brand_model": "Määra bränd ja mudel",
"refresh_catalog": "Värskenda kataloogi",
"add_device": "+ Lisa seade",
"add_device_tip": "Lisage veel üks WashData seade",
"add_maintenance": "Lisa hooldussündmus",
@@ -241,7 +244,12 @@
"import_selected": "Impordi valitud",
"back": "Tagasi",
"mute_suggestion": "Lõpeta selle seade soovitamine",
"reset_muted": "Lähtesta vaigistatud"
"reset_muted": "Lähtesta vaigistatud",
"import_power_history": "Impordi võimsuse ajalugu",
"hist_read_recorder": "Loe Home Assistantist",
"hist_scan": "Otsi tsükleid",
"hist_import_n": "Impordi tsüklid ({n})",
"hist_goto_cycles": "Näita tsükleid"
},
"conflict": {
"anti_wrinkle_exit": {
@@ -253,14 +261,14 @@
"start": "Peab olema alla kortsudevastase maksimaalse võimsuse ({max} W)"
},
"attn_sub": "Lahendage konfliktid enne salvestamist",
"attn_title": "{n} seadete konflikt{s}",
"settings_banner": "{n} seadete konflikt{s} kontrollige esile tõstetud sektsioone ja parandage enne salvestamist.",
"attn_title": "Seadete konfliktid: {n}",
"settings_banner": "Seadete konfliktid: {n}. Kontrollige esile tõstetud sektsioone ja parandage need enne salvestamist.",
"settings_banner_btn": "Mine esimesele",
"confidence": {
"auto": "Peab olema vähemalt vaste läve tasemel ({match})",
"learning": "Peab olema kuni vaste läve ({match})",
"learning": "Peab olema vähemalt vaste läve tasemel ({match})",
"match_for_auto": "Peab olema kuni automaatse sildi usalduse ({alc})",
"match_for_learning": "Peab olema vähemalt õppimise usalduse tasemel ({lc})"
"match_for_learning": "Peab olema kuni õppimise usalduse tasemel ({lc})"
},
"duration_ratio": {
"max": "Peab olema suurem kui minimaalse kestuse suhe ({min})",
@@ -298,7 +306,7 @@
"match": "Peab olema üle mitte-vaste läve ({un})",
"unmatch": "Peab olema alla vaste läve ({match}); muidu tühistatakse kinnitatud vaste kohe"
},
"cascade_toast": "Järjepidevuse tagamiseks kohandati automaatselt ka {n} seadistust.",
"cascade_toast": "Järjepidevuse tagamiseks kohandati muid seadeid: {n}",
"suggestion_resolves": "Rakendage allpool kuvatav ootel soovitus ({val}), et see parandada",
"use_fix": "Kasuta {val}",
"watchdog": {
@@ -356,7 +364,8 @@
"pg_outcome": "Simulatsiooni tulemus",
"pg_across_cycles": "Sinu tsüklite lõikes",
"community_store": "Kogukonna pood",
"online_account": "Kogukonna pood ja veebifunktsioonid"
"online_account": "Kogukonna pood ja veebifunktsioonid",
"import_power_history": "Võimsuse ajaloo import"
},
"health": {
"fair": "Rahuldav profiili kvaliteet",
@@ -364,6 +373,7 @@
"poor": "⚠ Kehv profiili kvaliteet"
},
"lbl": {
"drag_to_resize": "Lohistage suuruse muutmiseks",
"pg_anti_wrinkle": "Kortsudevastane",
"actions": "Tegevused",
"activity": "Tegevus",
@@ -435,7 +445,7 @@
"from": "Alates",
"gap_s": "Vahe(d)",
"group_name": "Rühma nimi",
"head_trim": "Pea trimm (id)",
"head_trim": "Kärbe algusest (s)",
"health": "Tervis",
"hide_tabs": "Peida vahekaardid mitteadministraatorite jaoks",
"in_use": "Kasutuses",
@@ -451,7 +461,7 @@
"metric": "Mõõdik",
"mode_existing_profile": "Lisa olemasolevale profiilile",
"mode_new_profile": "Loo uus profiil",
"models_fine_tuned": "({count} mudelit peenhäälestatud)",
"models_fine_tuned": "(peenhäälestatud mudelid: {count})",
"n_classic_suggestions": "{n} klassikaline",
"n_ml_suggestions": "{n} ML",
"n_selected": "{n} valitud",
@@ -532,7 +542,7 @@
"stage3": "Etapp 3 DTW",
"stage4": "Etapp 4 kokkulangevus",
"status": "Olek",
"tail_trim": "Saba trimm (id)",
"tail_trim": "Kärbe lõpust (s)",
"timer_auto_pause": "Automaatne paus",
"timer_min": "min",
"timer_msg_placeholder": "Sõnum (valikuline, {device}/{program}/{minutes})",
@@ -677,7 +687,26 @@
"conflict_import_copy": "Impordi koopiana",
"conflict_keep_mine": "Säilita minu omad",
"conflict_overwrite": "Kirjuta üle",
"font_size": "Paneeli fondi suurus"
"font_size": "Paneeli fondi suurus",
"hist_csv_data": "CSV-andmed",
"hist_from_recorder": "Või loe see Home Assistantist",
"hist_since": "Alates",
"days": "päeva",
"hist_keep": "Säilita see tsükkel",
"hist_looks_complete": "lõpetatud",
"peak_power_short": "Tipp",
"shape": "Kuju",
"hist_skip_idle": "miski ei töötanud",
"hist_skip_sparse": "näidud liiga hõredad",
"hist_skip_short": "liiga vähe näite",
"hist_skip_long": "pole piisavalt pikka pausi, kust jagada",
"hist_reason_short": "lühem kui selle seadme lühim tegelik tsükkel",
"hist_reason_no_end": "ei lõppenud korralikult",
"task_history_import": "Võimsuse ajaloo skannimine",
"task_history_import_apply": "Tsüklite importimine",
"evidence_real_cycles": "Selle seadme tehtud tsüklid",
"evidence_reference_cycles": "Kogukonna poest alla laaditud",
"evidence_backfill_cycles": "Leitud imporditud võimsuse ajaloos"
},
"log": {
"all_levels": "Kõik tasemed",
@@ -756,9 +785,15 @@
"store_share": "Jaga kogukonna poodi",
"store_share_device": "Jaga seda seadet",
"export_select": "Eksport - vali andmed",
"import_wizard": "Import - vali andmed"
"import_wizard": "Import - vali andmed",
"history_import": "Võimsuse ajaloo import"
},
"msg": {
"tail_trim_hint": "Mitu sekundit lõpust eemaldada",
"store_sibling_hint": "Sinu täpse mudeli jaoks pole midagi jagatud? Sama brändi lähedane mudel on tavaliselt hea lähtepunkt.",
"store_declare_appliance": "Ütle WashDatale, milline seade sul on, ja see vahekaart näitab teiste jagatud programme ja salvestisi selle seadme jaoks. Võid ka ülal brändi kirjutada ja lihtsalt ringi vaadata.",
"refresh_catalog_hint": "Kogukonna brändide ja seadmete loendid on vahemälus, et jagatud pood püsiks oma päevase päringulimiidi piires. Värskenda, et näha teiste lisatud või heaks kiidetud kirjeid.",
"head_trim_hint": "Mitu sekundit algusest eemaldada",
"appliance_monitor": "Seadmete monitor",
"artifact_dip_detail": "Langes alla tavapärase võimsusriba umbes {n}s jooksul.",
"artifact_footer": "Ülaltoodud graafikul esile tõstetud. Need on mööduvad artefaktid (nt uks avati tsükli keskel), mitte tingimata probleemid.",
@@ -769,7 +804,7 @@
"automations_intro": "WashData käivitab {start} / {end} sündmusi ja avaldab olemeid, seega on teated ja toimingud kõige paremini ehitada tavaliste Home Assistanti automaatikana. Seda seadet kasutavad automaatikad kuvatakse allpool.",
"cleanup_intro": "Iga märgistatud tsükkel on kaetud. Profiili puhastamiseks märkige kõrvalekalded ja kustutage.",
"clear_debug_hint": "Ruumi vabastamiseks eemaldage salvestatud silumisandmed.",
"collecting_data": "Andmete kogumine - {need} tsüklit veel enne peenhäälestuse alustamist ({current}/{min}).",
"collecting_data": "Andmete kogumine. Tsükleid on enne peenhäälestuse algust veel vaja: {need} ({current}/{min}).",
"compare_overlay_profiles": "Ülekatteprofiilid (nõrkjad)",
"compare_profiles_tip": "Katke ülaltoodud diagrammil teised profiiliümbrikud, et näha, milline neist selle tsükliga kõige paremini sobib.",
"compare_selected_cycles": "Valitud tsüklid (tahked) näita/peida",
@@ -779,7 +814,7 @@
"cycles_deleted": "{count} tsüklit kustutatud",
"enough_data": "Piisavalt andmeid õppimiseks ({current}/{min} tsüklit).",
"export_description": "Vali täpselt, millised profiilid, tsüklid, seaded ja muu JSON-i eksportida, või analüüsi fail ja impordi ainult soovitud osad.",
"feedback_cycles_pending": "{n} tsükkel{s} ülevaatamiseks",
"feedback_cycles_pending": "Ülevaatamiseks: {n}",
"feedback_prompt": "Kinnitage, et see oli õige, parandage programmi või ignoreerige.",
"feedback_relabel_hint": "Selle tsükli uuesti sildistamine lahendab ka selle.",
"filter_by_profile": "Filtreeri profiili järgi…",
@@ -804,7 +839,7 @@
"ml_intro": "WashData tarnitakse nutikate mudelitega, mis töötavad karbist välja.",
"ml_learned_intro": "Selle masina jaoks peenhäälestatud mudelid.",
"ml_loading": "ML laadimine…",
"ml_settings_intro": "Kaks sõltumatut lülitit: üks rakendab mudeleid tsükli töötamise ajal, teine võimaldab WashDatal neid aja jooksul teie masinale täpselt häälestada.",
"ml_settings_intro": "Kaks sõltumatut lülitit: üks rakendab mudeleid tsükli töötamise ajal, teine võimaldab WashDatal neid aja jooksul teie masinale täpselt häälestada.",
"name_first_program": "Sul on piisavalt tsükleid pane oma esimesele programmile nimi, et alustada sobitamist.",
"near_duplicate_cluster": "Tuvastati peaaegu duplikaatprofiili klaster. Rühmitamine võimaldab sobitamisel usaldusväärselt valida sarnasuste vahel (nt sama programm erineval temperatuuril/tsentrifuugimisel).",
"no_cycles_match": "Ükski tsükkel ei vasta praegusele filtrile.",
@@ -856,7 +891,6 @@
"pg_stress_synthetic": "tühikäigu simulatsioon algab siit",
"pg_sweep_intro": "Mis siis, kui {param} oleks teistsugune? Testi {steps} väärtust oma viimase {cycles} tsükli ulatuses, et leida seade, mille juures kõige rohkem tsükleid sobitatakse õigesti.",
"pg_sweep_step": "Samm {done} / {total}",
"pg_undetected": "{n} tsüklit tuvastamata",
"pg_verdict_bad": "Vajab tähelepanu: paljud tsüklid jäävad tuvastamata.",
"pg_verdict_good": "Hästi häälestatud: enamik tsükleid tuvastatakse ja sobitatakse õigesti.",
"pg_verdict_ok": "Vastuvõetav: mõned tsüklid jäid vahele. Proovi käivitusläve alandada.",
@@ -887,6 +921,7 @@
"review_recorded_tip": "Märkige see oma programmi jaoks käsitsi valitud võrdlustsükliks sama roll kui käsitsi salvestatud tsüklil. Võrdlustsüklid jäetakse alati alles, külvatakse sobiv mall ja neid ei jäeta kunagi puhastamise käigus maha. (See on \"kuldne\" / salvestatud lipp; mõlemad on samad.)",
"review_tags_tip": "Valikulised lipud, mis kirjeldavad, mis selle tsükliga valesti läks, nii et koolitus ja puhastamine võivad seda arvesse võtta.",
"review_to_cycles": "Avage tsüklite ülevaatuse järjekord",
"samples_decimated": "Kuvatakse {shown}/{total} näidet (kuvamiseks hõrendatud; tipud säilitatud). Lai vahe siin on hõrendamine, mitte puuduvad andmed.",
"saving_triggers_reload": "Salvestamine käivitab integratsiooni uuesti laadimise. HA olemid võivad hetkeks kuvada kui kättesaamatud.",
"search_placeholder": "Otsinguseaded…",
"see_recorder": "Vaadake salvesti vidinat allpool",
@@ -1006,10 +1041,33 @@
"sug_mute_failed": "Soovituse vaigistamine ebaõnnestus",
"sug_unmuted_all": "Vaigistatud soovitused lähtestatud",
"n_suggestions_muted": "{count} vaigistatud; automaatne häälestaja ei paku neid enam.",
"font_size_hint": "Muuda kõik selles paneelil suuremaks või väiksemaks. Kehtib sinu kontole sellel seadmel."
"font_size_hint": "Muuda kõik selles paneelil suuremaks või väiksemaks. Kehtib sinu kontole sellel seadmel.",
"import_history_description": "Kas nutipistik oli sul olemas juba enne WashDatat? Laadi üles selle võimsusanduri ajaloo eksport või loe see otse Home Assistantist, ja tavaline tuvastus töötab need andmed läbi, nii et möödunud tsüklid ilmuvad sinu Tsüklite loendisse ja neile saab nime anda.",
"hist_input_hint": "Laadi üles Ajaloo paneelilt alla laaditud CSV (olem, olek, viimane muutus) või lase WashDatal anduri ajalugu otse lugeda. Seejärel töötab tuvastus need andmed läbi täpselt nii nagu reaalajas ja sina valid, millised leitud tsüklid alles jäävad.",
"hist_recorder_hint": "Loeb valitud kuupäevast kuni praeguse hetkeni. Home Assistant hoiab üksikasjalikku ajalugu vaikimisi 10 päeva ja pärast seda ainult tunniseid keskmisi, mis on tsüklite tuvastamiseks liiga jämedad - vali varasem kuupäev ainult siis, kui sinu recorder on seatud rohkem säilitama.",
"hist_scanning": "Sinu ajalugu jooksutatakse detektorist läbi. See toimub taustal - võid selle akna sulgeda ja hiljem tagasi tulla.",
"hist_imported_count": "Imporditud tsükleid: {n}.",
"hist_duplicates": "Juba varem imporditud ja vahele jäetud: {n}.",
"hist_capped": "Seadme imporditud tsüklite piirmäär sai täis; ülejäänuid ei salvestatud.",
"hist_next_step": "Need on sinu Tsüklite loendis, märgitud imporditud ajaloona. Ava üks ja kasuta nuppu Sildista, et määrata selle programm.",
"hist_rows_read": "Loetud näite: {n}",
"hist_entity_substituted": "loeti {used} (see seade on seadistatud kasutama {wanted})",
"hist_breaks": "Katkestusi, kus andur ei olnud saadaval: {n}",
"hist_other_entity": "Eiratud muude olemite näite: {n}",
"hist_skipped_spans": "Vahele jäetud lõigud",
"hist_settings_used": "Tuvastatud selle seadme praeguste seadetega (Minimaalne Võimsus {w} W, Väljalülitumise Viivitus {s} s).",
"hist_none_found": "Sellest ajaloost ei õnnestunud ühtegi tsüklit tuvastada.",
"hist_found": "Leitud tsükleid: {n}. Eemalda linnuke kõigelt, mis ei tundu tegelik käitus - enne importimist ei salvestata midagi.",
"hist_scan_capped": "Kuvatakse ainult esimesed kandidaadid (leiti: {n}).",
"hist_recorder_empty": "Home Assistantil pole selle anduri kohta sellest ajavahemikust üksikasjalikku ajalugu.",
"hist_scan_failed": "Skannimine ebaõnnestus.",
"hist_scan_expired": "See skannimistulemus pole enam saadaval. Palun skanni uuesti.",
"hist_import_failed": "Import ebaõnnestus.",
"imported_history_readonly": "Tuvastatud imporditud võimsuse ajaloos. See mõjutab programmide sobitamist, kuid ei arvestata sinu statistikas ning seda ei saa kärpida ega poolitada. Kasuta nuppu Sildista, et määrata programm."
},
"pg_desc": {
"dishwasher_end_spike_quiet_release": "Nõudepesumasin: vaiksed sekundid pärast eeldatavat kestust, enne kui tsükli lõpu tühjenduse ootamine vabastatakse",
"smart_termination_duration_ratio": "Osa vastendatud programmi eeldatavast kestusest, milleni tsükkel peab jõudma, enne kui nutikas lõpetamine tohib selle ennetähtaegselt lõpetada; vähendage seda koormusest või temperatuurist sõltuvatel masinatel",
"anti_wrinkle_enabled": "Neelab pärast põhifaasi trummelimpulsid, selle asemel et lugeda neid uute tsüklitena",
"anti_wrinkle_exit_power": "Kortsudevastase režiimi aktiivsena püsimiseks peab võimsus impulsside vahel sellest allapoole langema",
"anti_wrinkle_idle_timeout": "Kahe trummelimpulsi vahel lubatud vaikuseaeg enne kortsudevastase režiimi lõppu",
@@ -1134,7 +1192,7 @@
"doc": "Kui tsükkel ületab oma eeldatava kestuse, siis kui kaua peab nõudepesumasin püsima vaikne (allpool Peatumise Lävi), enne kui WashData lõpetab lõpliku tühjenduse ootamise ja lõpetab tsükli. Suurendage seda, kui teie masinal on pikk vaikne kuivatusfaas enne hilist lõplikku tühjendust, mis jääb märkamata - laiem aken laseb õpitud kestusel järgida hooajalist triivi (külmem sissevoolav vesi = pikemad tsüklid), selle asemel et lukustuda vana keskmise külge. See saab ooteaega üksnes lühendada võrreldes sisemise 30-minutilise lõpupiigi ülempiiriga, mitte kunagi seda pikendada."
},
"anti_wrinkle_enabled": {
"doc": "Tuvastage lühikesed väikese võimsusega trummelimpulsid, mida kuivati pärast peamist kuumutusfaasi kiirgab, ja hoidke need valmis tsükliga ühendatud, selle asemel, et lugeda neid uute tsüklitena.",
"doc": "Tuvastage lühikesed väikese võimsusega trummelimpulsid, mida kuivati pärast peamist kuumutusfaasi kiirgab, ja hoidke need valmis tsükliga ühendatud, selle asemel, et lugeda neid uute tsüklitena.",
"label": "Luba Kortsudevastane Tuvastamine"
},
"anti_wrinkle_exit_power": {
@@ -1421,6 +1479,10 @@
"doc": "Salvestage iga tsükli täielik võimsusjälg ja vastavad silumisandmed. Kasulik tõrkeotsinguks, kuid suurendab salvestusruumi mahtu.",
"label": "Salvesta Silumise Jäljed"
},
"smart_termination_duration_ratio": {
"doc": "Kui kaugele vastendatud programmi eeldatavast kestusest peab tsükkel jõudma, enne kui nutikas lõpetamine tohib selle võimsuse langedes ennetähtaegselt lõpetada. Eeldatav kestus on programmi keskmine, seega seadmetel, mille tööaeg kõigub palju - pesumasinad külma talvise vs sooja suvise sissevoolava veega, andurkuivatusega kuivatid, koormusest sõltuvad programmid - lõpeb umbes pool kõigist tsüklitest sellest keskmisest lühemalt ega saa kunagi kiiret lõpetamist, lõppedes alles tagavara-aegumise kaudu minuteid hiljem. Vähendage seda (nt 0,85) neil masinatel, et varajane lõpetamine ikkagi käivituks; tõstke seda 1,0 poole, et olla ettevaatlikum. Jätke tühjaks vaikeväärtuse jaoks (0,98 või nõudepesumasinatel 0,99). See saab tsükli üksnes varem lõpetada, mitte kunagi hiljem, ega käivitu kunagi ebaselge või madala kindlusega vaste korral.",
"label": "Nutika lõpetamise suhe"
},
"smoothing_window": {
"doc": "Kui palju toorvõimsussignaali tasandatakse. Madal (2) on tundlik, kuid lärmakas; kõrge (5) silub naelu, kuid lisab mahajäämust.",
"label": "Silumisaken"
@@ -1551,6 +1613,10 @@
"door_end_dwell_seconds": {
"label": "Ukse avamise lõppviibimisaeg",
"doc": "Kui kaua uks peab jääma avatuks, enne kui WashData tsükli lõpetab, kui \"Uks avaneb automaatselt lõpus\" on sisse lülitatud. Piisavalt pikk, et kiire taldrikute lisamine ignoreeritaks (vaikimisi 60 s), piisavalt lühike, et lõpetada kiiresti, kui masin ukse avab."
},
"profile_evidence_sources": {
"label": "Programmi kujundavad tsüklid",
"doc": "Milliseid tsükleid kasutatakse iga programmi võimsuskõvera koostamiseks ja lõpetatud tsükli sellega sobitamiseks. Kui mõne liigi märke eemaldad, ei kujunda see enam sinu programme, kuid midagi ei kustutata - tsüklid jäävad Tsüklite loendisse ning neid saab endiselt sildistada või eemaldada. Kasulik, kui sa imporditud andmeid ei usalda. Statistikat see ei mõjuta: seal arvestatakse alati ainult neid tsükleid, mida see seade tegelikult käivitas. Kõigi märkide eemaldamist eiratakse, sest ilma ühegi tsüklita programm ei saaks kunagi sobituda."
}
},
"setting_group": {
@@ -1634,6 +1700,9 @@
},
"basic_configuration": {
"label": "Põhiseaded"
},
"profile_evidence": {
"label": "Profiili alusandmed"
}
},
"status": {
@@ -1658,7 +1727,8 @@
"trimming": "Kärpimine…",
"splitting": "Lõhestamine…",
"deleting": "Kustutamine…",
"imported": "Imporditud"
"imported": "Imporditud",
"preparing": "Ettevalmistamine…"
},
"tab": {
"advanced": "Täpsemalt",
@@ -1688,6 +1758,7 @@
"wrong_profile": "Vale profiil"
},
"toast": {
"catalog_refreshed": "Kogukonna kataloog on värskendatud",
"access_saved": "Juurdepääsukontroll on salvestatud",
"all_wiped": "Kõik andmed on kustutatud",
"analysis_complete_none": "Analüüs on lõpetatud: uusi ettepanekuid pole",
@@ -1793,7 +1864,9 @@
"store_download_failed": "Allalaadimine ebaõnnestus: {error}",
"store_download_nothing": "Midagi uut alla laadida pole - see seadistus on juba teie seadmel.",
"export_selective_done": "Eksport alla laaditud",
"import_selective_done": "Imporditud {profiles} profiili ja {cycles} tsüklit"
"import_selective_done": "Imporditud {profiles} profiili ja {cycles} tsüklit",
"hist_csv_required": "Laadi esmalt CSV-fail või kleebi selle sisu",
"file_read_failed": "Seda faili ei õnnestunud lugeda"
},
"suggestion": {
"both_agree": "WashData soovitab",
@@ -1889,7 +1962,7 @@
"thr_batch": "Hoitakse veidi üle madalaima aktiivvõimsuse p05 juures {cycles} tsükli lõikes ({p05}W), et käivitus tuvastataks võimalikult vara ja seiskamislävi jääks alla masina madalaima töövõimsuse.",
"tol_per_profile": "p75 profiilipõhisest kestuse dispersioonist {profiles} profiili lõikes ({cycles} tsüklit); kitsaid profiile ei karistata.",
"tol_pooled": "Põhineb {cycles} viimase märgistatud tsükli koondkestuse dispersioonil (p95 hälve={dev}).",
"watchdog": "Hoitakse nii madal kui ohutu (veidi üle p95 uuendusintervalli {p95}s, min 30s), et seiskumised tuvastataks kiiresti ilma valeseisakuteta."
"watchdog": "Hoitakse nii madal kui ohutu (veidi üle p95 uuendusintervalli {p95}s ja vähemalt 2x proovivõtu intervall {median}s, min 30s), et seiskumised tuvastataks kiiresti ilma valeseisakuteta."
},
"exclusions": {
"summary": "Välja jäetud {total} valesti tuvastatud tsüklit: {parts}.",
@@ -1955,6 +2028,10 @@
"finished": "Tsükkel jõudis lõppolekusse ja lõppes."
},
"store": {
"your_model_tip": "See on seade, mille sa seadetes määrasid",
"your_model": "Sinu oma",
"search_brand_ph": "Otsi brändi järgi…",
"programs_count": "Programmid: {n}",
"browse": "Sirvi",
"device": "Seade",
"favorites": "Lemmikud",
@@ -78,9 +78,12 @@
"awaiting": "Odottaa hyväksyntää",
"imported_tip": "Tuotu yhteisökaupasta. Käytetään vain täsmäytykseen, ei lasketa tilastoihin.",
"not_importable": "ei käytettävissä",
"exists": "on jo"
"exists": "on jo",
"backfilled_tip": "Tunnistettu tuodusta tehohistoriasta. Vaikuttaa vain ohjelmien täsmäytykseen, ei lasketa tilastoihin."
},
"btn": {
"set_brand_model": "Aseta merkki ja malli",
"refresh_catalog": "Päivitä luettelo",
"add_device": "+ Lisää laite",
"add_device_tip": "Lisää toinen WashData-laite",
"add_maintenance": "Lisää huoltotapahtuma",
@@ -241,7 +244,12 @@
"import_selected": "Tuo valitut",
"back": "Takaisin",
"mute_suggestion": "Lopeta tämän asetuksen ehdottaminen",
"reset_muted": "Palauta vaiennetut"
"reset_muted": "Palauta vaiennetut",
"import_power_history": "Tuo tehohistoria",
"hist_read_recorder": "Lue Home Assistantista",
"hist_scan": "Etsi syklejä",
"hist_import_n": "Tuo {n} sykliä",
"hist_goto_cycles": "Näytä syklit"
},
"conflict": {
"anti_wrinkle_exit": {
@@ -253,12 +261,12 @@
"start": "Täytyy olla alle ryppyjeneston enimmäistehon ({max} W)"
},
"attn_sub": "Korjaa ristiriidat ennen tallentamista",
"attn_title": "{n} asetusten ristiriita{s}",
"attn_title": "Asetusten ristiriitoja: {n}",
"confidence": {
"auto": "Täytyy olla vähintään täsmäytyskynnys ({match})",
"learning": "Täytyy olla enintään täsmäytyskynnys ({match})",
"learning": "Täytyy olla vähintään täsmäytyskynnys ({match})",
"match_for_auto": "Täytyy olla enintään automaattimerkinnän varmuus ({alc})",
"match_for_learning": "Täytyy olla vähintään oppimisen varmuus ({lc})"
"match_for_learning": "Täytyy olla enintään oppimisen varmuus ({lc})"
},
"duration_ratio": {
"max": "Täytyy olla yli vähimmäiskestosuhteen ({min})",
@@ -296,14 +304,14 @@
"match": "Täytyy olla yli eritäsmäytyskynnyksen ({un})",
"unmatch": "Täytyy olla alle täsmäytyskynnyksen ({match}); muuten vahvistettu vastaavuus purkautuu heti"
},
"cascade_toast": "Myös {n} asetusta muutettiin johdonmukaisuuden vuoksi.",
"cascade_toast": "Muita asetuksia muutettiin johdonmukaisuuden vuoksi: {n}",
"suggestion_resolves": "Ota alla oleva ehdotus ({val}) käyttöön tämän korjaamiseksi",
"use_fix": "Käytä {val}",
"watchdog": {
"interval": "Tulisi olla vähintään 2x näytteenottoväli ({si} s)",
"sampling": "Näytteenottovälin tulee olla enintään puolet tarkkailijavälistä ({wi} s)"
},
"settings_banner": "{n} asetusten ristiriita{s} tarkista korostetut osiot ja korjaa ne ennen tallentamista.",
"settings_banner": "Asetusten ristiriitoja: {n}. Tarkista korostetut osiot ja korjaa ne ennen tallentamista.",
"settings_banner_btn": "Siirry ensimmäiseen"
},
"hdr": {
@@ -356,7 +364,8 @@
"pg_outcome": "Simulaation tulos",
"pg_across_cycles": "Kaikissa jaksoissasi",
"community_store": "Yhteisökauppa",
"online_account": "Yhteisökauppa ja verkkotoiminnot"
"online_account": "Yhteisökauppa ja verkkotoiminnot",
"import_power_history": "Tuo tehohistoria"
},
"health": {
"fair": "Tyydyttävä profiililaatu",
@@ -364,6 +373,7 @@
"poor": "⚠ Heikko profiililaatu"
},
"lbl": {
"drag_to_resize": "Vedä muuttaaksesi kokoa",
"pg_anti_wrinkle": "Ryppyjenesto",
"actions": "Toiminnot",
"activity": "Toiminta",
@@ -435,7 +445,7 @@
"from": "Mistä",
"gap_s": "aukko (t)",
"group_name": "Ryhmän nimi",
"head_trim": "Pään leikkaus (s)",
"head_trim": "Leikkaus alusta (s)",
"health": "Terveys",
"hide_tabs": "Piilota välilehdet muille kuin järjestelmänvalvojille",
"in_use": "Käytössä",
@@ -451,7 +461,7 @@
"metric": "Mittari",
"mode_existing_profile": "Lisää olemassa olevaan profiiliin",
"mode_new_profile": "Luo uusi profiili",
"models_fine_tuned": "({count} mallia hienosäädetty)",
"models_fine_tuned": "(hienosäädetyt mallit: {count})",
"n_classic_suggestions": "{n} klassinen",
"n_ml_suggestions": "{n} ML",
"n_selected": "{n} valittu",
@@ -532,7 +542,7 @@
"stage3": "Vaihe 3 DTW",
"stage4": "Vaihe 4 vastaavuus",
"status": "Tila",
"tail_trim": "Hännän leikkaus (s)",
"tail_trim": "Leikkaus lopusta (s)",
"timer_auto_pause": "Automaattinen tauko",
"timer_min": "min",
"timer_msg_placeholder": "Viesti (valinnainen, {device}/{program}/{minutes})",
@@ -650,7 +660,7 @@
"show_contributor": "Näytä osallistujien nimet",
"task_pg_detail": "Simuloidaan sykliä",
"task_split": "Jaetaan sykliä",
"task_trim": "Rajataan sykliä",
"task_trim": "Leikataan sykliä",
"task_merge": "Yhdistetään syklejä",
"task_rebuild": "Rakennetaan tehoalueita uudelleen",
"cat_profiles": "Profiilit (ohjelmat)",
@@ -677,7 +687,26 @@
"conflict_import_copy": "Tuo kopiona",
"conflict_keep_mine": "Säilytä omat",
"conflict_overwrite": "Korvaa",
"font_size": "Paneelin fonttikoko"
"font_size": "Paneelin fonttikoko",
"hist_csv_data": "CSV-data",
"hist_from_recorder": "Tai lue se Home Assistantista",
"hist_since": "Alkaen",
"days": "päivää",
"hist_keep": "Säilytä tämä sykli",
"hist_looks_complete": "kokonainen",
"peak_power_short": "Huippu",
"shape": "Muoto",
"hist_skip_idle": "ei toimintaa",
"hist_skip_sparse": "lukemat liian kaukana toisistaan",
"hist_skip_short": "liian vähän lukemia",
"hist_skip_long": "ei tarpeeksi pitkää katkoa jakamiseen",
"hist_reason_short": "lyhyempi kuin tämän laitteen lyhyin todellinen sykli",
"hist_reason_no_end": "ei päättynyt siististi",
"task_history_import": "Tehohistorian läpikäynti",
"task_history_import_apply": "Syklien tuonti",
"evidence_real_cycles": "Tämän koneen ajamat syklit",
"evidence_reference_cycles": "Ladattu yhteisökaupasta",
"evidence_backfill_cycles": "Löydetty tuodusta tehohistoriasta"
},
"log": {
"all_levels": "Kaikki tasot",
@@ -756,9 +785,15 @@
"store_share": "Jaa yhteisökauppaan",
"store_share_device": "Jaa tämä laite",
"export_select": "Vienti - valitse tiedot",
"import_wizard": "Tuonti - valitse tiedot"
"import_wizard": "Tuonti - valitse tiedot",
"history_import": "Tuo tehohistoria"
},
"msg": {
"tail_trim_hint": "Kuinka monta sekuntia poistetaan lopusta",
"store_sibling_hint": "Eikö juuri sinun mallillesi ole jaettu mitään? Saman merkin läheinen malli on yleensä hyvä lähtökohta.",
"store_declare_appliance": "Kerro WashDatalle, mikä laite sinulla on, niin tämä välilehti näyttää muiden sille jakamat ohjelmat ja tallennukset. Voit myös kirjoittaa merkin nimen yläkenttään ja katsella ympärillesi.",
"refresh_catalog_hint": "Yhteisön merkki- ja laiteluettelot on tallennettu välimuistiin, jotta jaettu kauppa pysyy päivittäisen kyselykuotansa rajoissa. Päivitä nähdäksesi muiden lisäämät tai hyväksymät merkinnät.",
"head_trim_hint": "Kuinka monta sekuntia poistetaan alusta",
"appliance_monitor": "Laitteen näyttö",
"artifact_dip_detail": "Alitti tavallisen tehon alarajan noin {n} sekunnin ajan.",
"artifact_footer": "Korostettu yllä olevassa kaaviossa. Nämä ovat ohimeneviä esineitä (esim. ovi avautui kesken syklin), eivät välttämättä ongelmia.",
@@ -769,7 +804,7 @@
"automations_intro": "WashData laukaisee {start} / {end}-tapahtumat ja tarjoaa entiteetit, joten ilmoitukset ja toiminnot kannattaa rakentaa tavallisina Home Assistant -automaatioina. Tätä laitetta käyttävät automaatiot näkyvät alla.",
"cleanup_intro": "Jokainen merkitty sykli peitetään. Tyhjennä profiili valitsemalla poikkeamat ja poistamalla ne.",
"clear_debug_hint": "Poista tallennetut virheenkorjaustiedot vapauttaaksesi tilaa.",
"collecting_data": "Kerätään tietoja - vielä {need} sykliä tarvitaan ennen hienosäädön käynnistymistä ({current}/{min}).",
"collecting_data": "Kerätään tietoja. Syklejä tarvitaan vielä ennen hienosäädön aloittamista: {need} ({current}/{min}).",
"compare_overlay_profiles": "Päällekkäiset profiilit (himmeä)",
"compare_profiles_tip": "Aseta muut profiilikuoret yllä olevaan kaavioon nähdäksesi, mikä sopii parhaiten tähän jaksoon.",
"compare_selected_cycles": "Valitut jaksot (kiinteä) näytä/piilota",
@@ -779,12 +814,12 @@
"cycles_deleted": "{count} sykli(ä) poistettu",
"enough_data": "Tarpeeksi tietoja oppimiseen ({current}/{min} sykliä).",
"export_description": "Valitse tarkalleen, mitkä profiilit, jaksot, asetukset ja muut viedään JSON-tiedostoon, tai analysoi tiedosto ja tuo vain haluamasi osat.",
"feedback_cycles_pending": "{n} sykliä tarkistettavana",
"feedback_cycles_pending": "Tarkistettavana: {n}",
"feedback_prompt": "Vahvista, että se oli oikein, korjaa ohjelma tai jätä huomiotta.",
"feedback_relabel_hint": "Tämän syklin uudelleenmerkintä ratkaisee sen myös.",
"filter_by_profile": "Suodata profiilin mukaan…",
"group_modal_help": "Ryhmäohjelmat, joilla on sama muoto ja jotka eroavat lämpötilassa/linkouksessa (kesto voi vaihdella). Matching antaa ryhmän yhdeksi ehdokkaaksi ja valitsee sitten parhaiten sopivan jäsenen. Valitse vähintään 2; peittokuva osoittaa, kuinka samanlaisia ne ovat.",
"group_not_cohesive": "Nämä profiilit eivät ole riittävän samankaltaisia ryhmittelemään niitä luotettavasti, joten vastaavuudessa käsitellään niitä yksitellen, kunnes poistat poikkeaman tai jaat ryhmän.",
"group_modal_help": "Ryhmäohjelmat, joilla on sama muoto ja jotka eroavat lämpötilassa/linkouksessa (kesto voi vaihdella). Matching antaa ryhmän yhdeksi ehdokkaaksi ja valitsee sitten parhaiten sopivan jäsenen. Valitse vähintään 2; peittokuva osoittaa, kuinka samanlaisia ne ovat.",
"group_not_cohesive": "Nämä profiilit eivät ole riittävän samankaltaisia ryhmittelemään niitä luotettavasti, joten vastaavuudessa käsitellään niitä yksitellen, kunnes poistat poikkeaman tai jaat ryhmän.",
"group_preview_hint": "Valitse vähintään 2 jäsentä esikatsellaksesi ja vertaillaksesi tehokäyriä.",
"import_intro": "Lataa viety tiedosto tai liitä JSON-hyötykuorma alle.",
"legacy_actions_title": "{count} vanha muokattu toiminto on edelleen käynnissä",
@@ -856,7 +891,6 @@
"pg_stress_synthetic": "valmiustilan simulaatio alkaa tästä",
"pg_sweep_intro": "Entä jos {param} olisi erilainen? Testaa {steps} arvoa viimeisten {cycles} syklin perusteella löytääksesi asetuksen, jolla useimmat syklit täsmätään oikein.",
"pg_sweep_step": "Vaihe {done} / {total}",
"pg_undetected": "{n} sykliä tunnistamatta",
"pg_verdict_bad": "Vaatii huomiota: monet syklit jäävät tunnistamatta.",
"pg_verdict_good": "Hyvin viritetty: useimmat syklit tunnistetaan ja täsmätään oikein.",
"pg_verdict_ok": "Hyväksyttävä: osa sykleistä jäi huomaamatta. Kokeile laskea aloituskynnystä.",
@@ -887,6 +921,7 @@
"review_recorded_tip": "Merkitse tämä käsin valituksi referenssijaksoksi ohjelmaansa varten - sama rooli kuin manuaalisesti tallennetulla jaksolla. Vertailusyklit säilytetään aina, siemennä vastaava malli, eikä niitä koskaan pudoteta puhdistuksen yhteydessä. (Tämä on \"kultainen\" / tallennettu lippu; molemmat ovat sama asia.)",
"review_tags_tip": "Valinnaiset liput, jotka kuvaavat, mikä meni pieleen tässä syklissä, joten koulutus ja siivous voivat selittää sen.",
"review_to_cycles": "Avaa Cycles tarkistusjono",
"samples_decimated": "Näytetään {shown}/{total} näytettä (harvennettu näyttöä varten; huiput säilytetty). Leveä väli tässä johtuu harvennuksesta, ei puuttuvasta datasta.",
"saving_triggers_reload": "Tallentaminen käynnistää integroinnin uudelleenlatauksen. HA-entiteetit voivat hetken näkyä poissa käytöstä.",
"search_placeholder": "Hakuasetukset…",
"see_recorder": "Katso tallennin-widget alta",
@@ -924,7 +959,7 @@
"trend_energy_down": "Energia laskee ({pct} %/sykli)",
"trend_energy_up": "Energiatrendi nousussa ({pct} %/sykli) viimeaikainen keskiarvo {avg}",
"trim_destructive_confirm": "Tämä säilyttää vain {pct}% syklistä. Tätä ei voi kumota. Jatketaanko?",
"trim_intro": "Vedä punaisia kahvoja tai syötä arvot. Kaikki ikkunan ulkopuolella poistetaan.",
"trim_intro": "Vedä punaisia kahvoja tai syötä arvot. Kaikki ikkunan ulkopuolella oleva poistetaan.",
"tuning_suggestions_available": "{count} viritysehdotus saatavilla havaituista sykleistä. Ne näkyvät asianmukaisten kenttien vieressä.",
"unsure_detected_prefix": "WashData ei ole varma, onko se havaittu",
"updated": "Päivitetty",
@@ -1006,10 +1041,33 @@
"sug_mute_failed": "Ehdotuksen vaimennus epäonnistui",
"sug_unmuted_all": "Vaiennetut ehdotukset palautettu",
"n_suggestions_muted": "{count} vaimennettu; automaattinen virittäjä ei ehdota näitä.",
"font_size_hint": "Suurenna tai pienennä kaikkea tässä paneelissa. Koskee tiliäsi tällä laitteella."
"font_size_hint": "Suurenna tai pienennä kaikkea tässä paneelissa. Koskee tiliäsi tällä laitteella.",
"import_history_description": "Oliko sinulla älypistoke jo ennen WashDataa? Lataa sen tehoanturin historiavienti tai lue historia suoraan Home Assistantista, niin tavallinen tunnistus ajetaan sen yli ja menneet syklit ilmestyvät Syklit-luetteloon valmiina nimettäviksi.",
"hist_input_hint": "Lataa Historia-paneelista ladattu CSV (entity, state, last changed) tai anna WashDatan lukea anturin historia suoraan. Tunnistus ajetaan sen yli täsmälleen kuten reaaliajassa, ja sinä valitset, mitkä löytyneistä sykleistä säilytetään.",
"hist_recorder_hint": "Lukee valitsemastasi päivästä nykyhetkeen. Home Assistant säilyttää tarkan historian oletuksena 10 päivää ja sen jälkeen vain tuntikeskiarvot, jotka ovat liian karkeita syklien tunnistamiseen - valitse kauempana menneisyydessä oleva päivä vain, jos recorder on asetettu säilyttämään enemmän.",
"hist_scanning": "Historiaasi ajetaan uudelleen tunnistimen läpi. Tämä tapahtuu taustalla - voit sulkea tämän ikkunan ja palata siihen myöhemmin.",
"hist_imported_count": "{n} sykliä tuotu.",
"hist_duplicates": "{n} oli tuotu jo aiemmin ja ohitettiin.",
"hist_capped": "Laitekohtainen tuotujen syklien raja täyttyi; loppuja ei tallennettu.",
"hist_next_step": "Ne ovat Syklit-luettelossasi merkittynä tuoduksi historiaksi. Avaa sykli ja nimeä sen ohjelma Merkitse-toiminnolla.",
"hist_rows_read": "{n} lukemaa luettu",
"hist_entity_substituted": "luettiin {used} (tälle laitteelle on määritetty {wanted})",
"hist_breaks": "{n} katkoa, joissa anturi ei ollut saatavilla",
"hist_other_entity": "{n} muiden entiteettien lukemaa ohitettiin",
"hist_skipped_spans": "Ohitetut ajanjaksot",
"hist_settings_used": "Tunnistettu tämän laitteen nykyisillä asetuksilla (minimiteho {w} W, sammutusviive {s} s).",
"hist_none_found": "Kyseisestä historiasta ei löytynyt yhtään sykliä.",
"hist_found": "Löytyi {n} sykliä. Poista valinta kaikesta, mikä ei näytä todelliselta ajolta - mitään ei tallenneta ennen tuontia.",
"hist_scan_capped": "Vain ensimmäiset ehdokkaat näytetään ({n} löytyi).",
"hist_recorder_empty": "Home Assistantilla ei ole tarkkaa historiaa tälle anturille kyseiseltä ajanjaksolta.",
"hist_scan_failed": "Läpikäynti epäonnistui.",
"hist_scan_expired": "Kyseinen läpikäynti ei ole enää saatavilla. Tee läpikäynti uudelleen.",
"hist_import_failed": "Tuonti epäonnistui.",
"imported_history_readonly": "Tunnistettu tuodusta tehohistoriasta. Se vaikuttaa ohjelmien täsmäytykseen, mutta ei näy tilastoissasi, eikä sitä voi rajata tai jakaa. Nimeä ohjelma Merkitse-toiminnolla."
},
"pg_desc": {
"dishwasher_end_spike_quiet_release": "Astianpesukone: hiljaiset sekunnit odotetun keston jälkeen ennen kuin syklin lopun vedenpoiston odotus vapautetaan",
"smart_termination_duration_ratio": "Osuus täsmätyn ohjelman odotetusta kestosta, joka syklin on saavutettava ennen kuin älykäs lopetus voi päättää sen ennenaikaisesti; laske sitä kuormasta tai lämpötilasta riippuvilla koneilla",
"anti_wrinkle_enabled": "Sulauta päävaiheen jälkeiset rumpupulssit sen sijaan, että lukisit ne uusina sykleinä",
"anti_wrinkle_exit_power": "Tehon on laskettava tämän alle pulssien välillä, jotta ryppyjenesto pysyy aktiivisena",
"anti_wrinkle_idle_timeout": "Kahden rumpupulssin välillä sallittu hiljainen aika ennen kuin ryppyjenesto päättyy",
@@ -1190,7 +1248,7 @@
"label": "Arviotoleranssi"
},
"enable_ml_models": {
"doc": "Kun sykli on käynnissä, anna mallien tarkentaa reaaliaikaisia tuloksia: vakaampi jäljellä oleva aika- ja energia-/kustannusarvio ja ennenaikaisen pysäytyksen eston varoitus päätteen havaitsemisessa (se voi vain viivästyttää maalia, ei koskaan lopettaa yhtä aikaisin ja on rajallinen). Käyttää hienosäädettyjä mallejasi, kun niitä on saatavilla, muuten sisäänrakennettuja. Off = vain klassinen tehopohjainen logiikka (vielä luotettava).",
"doc": "Kun sykli on käynnissä, anna mallien tarkentaa reaaliaikaisia tuloksia: vakaampi jäljellä oleva aika- ja energia-/kustannusarvio ja ennenaikaisen pysäytyksen eston varoitus päätteen havaitsemisessa (se voi vain viivästyttää maalia, ei koskaan lopettaa yhtä aikaisin ja on rajallinen). Käyttää hienosäädettyjä mallejasi, kun niitä on saatavilla, muuten sisäänrakennettuja. Off = vain klassinen tehopohjainen logiikka (vielä luotettava).",
"label": "Käytä älykkäitä malleja syklin aikana"
},
"end_energy_threshold": {
@@ -1314,7 +1372,7 @@
"label": "Suoran yliajan % ennen hälytystä"
},
"notify_live_services": {
"doc": "notify.* -palvelut vaativat reaaliaikaisia edistymispäivityksiä syklin aikana. Jätä tyhjäksi, jos haluat poistaa live-edistymisilmoitukset käytöstä.",
"doc": "notify.* -palvelut vaativat reaaliaikaisia edistymispäivityksiä syklin aikana. Jätä tyhjäksi, jos haluat poistaa live-edistymisilmoitukset käytöstä.",
"label": "Suoran edistymisen palvelut"
},
"notify_only_when_home": {
@@ -1421,6 +1479,10 @@
"doc": "Tallenna täyden tehon jäljitys ja vastaavat virheenkorjaustiedot jokaiselle jaksolle. Hyödyllinen vianetsinnässä, mutta lisää tallennustilaa.",
"label": "Tallenna virheenkorjausjäljet"
},
"smart_termination_duration_ratio": {
"doc": "Kuinka pitkälle täsmätyn ohjelman odotettuun kestoon syklin on edettävä, ennen kuin älykäs lopetus voi päättää sen ennenaikaisesti tehon pudottua. Odotettu kesto on ohjelman keskiarvo, joten laitteilla, joiden ajoaika vaihtelee paljon - pesukoneet kylmällä talven tulovedellä vs. lämpimällä kesän tulovedellä, anturikuivaavat kuivausrummut, kuormasta riippuvat ohjelmat - noin puolet kaikista ajoista päättyy tätä keskiarvoa lyhyempinä eivätkä koskaan saa nopeaa lopetusta, vaan päättyvät vasta vara-aikakatkaisun kautta minuutteja myöhässä. Laske tätä (esim. 0,85) näissä koneissa, jotta ennenaikainen lopetus silti laukeaa; nosta sitä kohti arvoa 1,0 ollaksesi varovaisempi. Jätä tyhjäksi käyttääksesi oletusta (0,98, tai astianpesukoneilla 0,99). Se voi ainoastaan päättää syklin aiemmin, ei koskaan myöhemmin, eikä koskaan laukea epäselvässä tai matalan varmuuden täsmäyksessä.",
"label": "Älykkään lopetuksen suhde"
},
"smoothing_window": {
"doc": "Kuinka paljon raakatehosignaali tasoittuu. Matala (2) on herkkä, mutta meluisa; korkea (5) tasoittaa piikkejä, mutta lisää viivettä.",
"label": "Tasoitusikkuna"
@@ -1551,6 +1613,10 @@
"door_end_dwell_seconds": {
"label": "Oven avauksen loppuviive",
"doc": "Kuinka kauan oven on pysyttävä auki ennen kuin WashData päättää syklin, kun \"Ovi avautuu automaattisesti lopussa\" on käytössä. Tarpeeksi kauan ohittamaan lautasen lisäämisen (oletus 60 s), tarpeeksi lyhyt päättämään nopeasti kun kone avaa oven."
},
"profile_evidence_sources": {
"label": "Ohjelmaa muovaavat syklit",
"doc": "Mitä syklejä käytetään kunkin ohjelman tehokäyrän muodostamiseen ja valmistuneen syklin täsmäyttämiseen siihen. Valinnan poistaminen estää kyseisen tyypin vaikutuksen ohjelmiisi poistamatta mitään - syklit pysyvät Syklit-luettelossa, ja ne voi silti merkitä tai poistaa. Hyödyllinen, jos et luota tuotuun dataan. Tilastot eivät muutu: ne laskevat aina vain ne syklit, jotka tämä kone on todella ajanut. Kaikkien valintojen poistaminen ohitetaan, koska ohjelma ilman taustalla olevia syklejä ei voisi koskaan täsmätä."
}
},
"setting_group": {
@@ -1634,6 +1700,9 @@
},
"basic_configuration": {
"label": "Perusmääritykset"
},
"profile_evidence": {
"label": "Profiilin lähteet"
}
},
"status": {
@@ -1658,7 +1727,8 @@
"trimming": "Leikataan…",
"splitting": "Jaetaan…",
"deleting": "Poistetaan…",
"imported": "Tuotu"
"imported": "Tuotu",
"preparing": "Valmistellaan…"
},
"suggestion": {
"both_agree": "WashData suosittelee",
@@ -1754,7 +1824,7 @@
"thr_batch": "Pidetään juuri pienimmän aktiivisen tehon yläpuolella p05:ssä {cycles} jakson joukossa ({p05}W), jotta käynnistys havaitaan mahdollisimman aikaisin ja pysäytyskynnys pysyy koneen pienimmän käyntitehon alapuolella.",
"tol_per_profile": "p75 profiilikohtaisesta keston varianssista {profiles} profiilin joukossa ({cycles} jaksoa); tiiviitä profiileja ei rangaista.",
"tol_pooled": "Perustuu {cycles} viimeisimmän merkityn jakson yhdistettyyn keston varianssiin (p95 poikkeama={dev}).",
"watchdog": "Pidetään niin matalana kuin on turvallista (hieman yli p95-päivitysvälin {p95}s, väh. 30s), jotta pysähdykset havaitaan nopeasti ilman vääriä pysäytyksiä."
"watchdog": "Pidetään niin matalana kuin on turvallista (hieman yli p95-päivitysvälin {p95}s ja vähintään 2x näytteenottoväli {median}s, väh. 30s), jotta pysähdykset havaitaan nopeasti ilman vääriä pysäytyksiä."
},
"exclusions": {
"summary": "Suljettu pois {total} väärin tunnistettua sykliä: {parts}.",
@@ -1801,6 +1871,7 @@
"wrong_profile": "Väärä profiili"
},
"toast": {
"catalog_refreshed": "Yhteisön luettelo päivitetty",
"access_saved": "Kulunvalvonta tallennettu",
"all_wiped": "Kaikki tiedot pyyhitty",
"analysis_complete_none": "Analyysi valmis: ei uusia ehdotuksia",
@@ -1812,7 +1883,7 @@
"cycle_labelled": "Sykli merkitty",
"cycle_paused": "Jakso keskeytetty",
"cycle_resumed": "Kierto jatkui",
"cycle_trimmed": "Pyörä trimmattu",
"cycle_trimmed": "Sykli leikattu",
"cycles_merged": "Syklit yhdistettiin",
"envelope_rebuilt": "Kirjekuori uusittu",
"envelopes_rebuilt": "Kirjekuoret uusittu",
@@ -1906,7 +1977,9 @@
"store_download_failed": "Lataus epäonnistui: {error}",
"store_download_nothing": "Ei uutta ladattavaa - tämä asetus on jo laitteellasi.",
"export_selective_done": "Vienti ladattu",
"import_selective_done": "Tuotu {profiles} profiilia ja {cycles} jaksoa"
"import_selective_done": "Tuotu {profiles} profiilia ja {cycles} jaksoa",
"hist_csv_required": "Lataa ensin CSV-tiedosto tai liitä sen sisältö",
"file_read_failed": "Tiedostoa ei voitu lukea"
},
"trend": {
"down": "Trendikäs alaspäin",
@@ -1955,6 +2028,10 @@
"finished": "Jakso saavutti lopputilan ja päättyi."
},
"store": {
"your_model_tip": "Tämä on laite, jonka määritit asetuksissa",
"your_model": "Omasi",
"search_brand_ph": "Hae merkin mukaan…",
"programs_count": "Ohjelmat: {n}",
"browse": "Selaa",
"device": "Laite",
"favorites": "Suosikit",
@@ -2010,7 +2087,7 @@
"apply": "Jaetaan sykliä"
},
"trim": {
"apply": "Rajataan sykliä"
"apply": "Leikataan sykliä"
},
"merge": {
"apply": "Yhdistetään syklejä"
@@ -30,9 +30,12 @@
"awaiting": "En attente d'approbation",
"imported_tip": "Importé depuis la boutique communautaire. Utilisé uniquement pour la correspondance, non compté dans les statistiques.",
"not_importable": "n/a ici",
"exists": "existe déjà"
"exists": "existe déjà",
"backfilled_tip": "Détecté dans un historique de puissance importé. Influence uniquement la correspondance des programmes, non compté dans les statistiques."
},
"btn": {
"set_brand_model": "Définir la marque et le modèle",
"refresh_catalog": "Rafraîchir le catalogue",
"add_device": "+ Ajouter un appareil",
"add_device_tip": "Ajouter un autre appareil WashData",
"add_maintenance": "Ajouter un événement d'entretien",
@@ -193,7 +196,12 @@
"import_selected": "Importer la sélection",
"back": "Retour",
"mute_suggestion": "Ne plus suggérer ce paramètre",
"reset_muted": "Réinitialiser les suggestions masquées"
"reset_muted": "Réinitialiser les suggestions masquées",
"import_power_history": "Importer l'historique de puissance",
"hist_read_recorder": "Lire depuis Home Assistant",
"hist_scan": "Rechercher des cycles",
"hist_import_n": "Importer {n} cycles",
"hist_goto_cycles": "Voir les cycles"
},
"conflict": {
"anti_wrinkle_exit": {
@@ -205,14 +213,14 @@
"start": "Doit être inférieur à la Puissance max anti-froissage ({max} W)"
},
"attn_sub": "Corriger les conflits avant d'enregistrer",
"attn_title": "{n} conflit{s} de paramètres",
"settings_banner": "{n} conflit{s} de paramètres vérifiez les sections surlignées et corrigez avant d'enregistrer.",
"attn_title": "Conflits de paramètres : {n}",
"settings_banner": "Conflits de paramètres : {n}. Vérifiez les sections surlignées et corrigez-les avant d'enregistrer.",
"settings_banner_btn": "Aller au premier",
"confidence": {
"auto": "Doit être supérieur ou égal au Seuil de correspondance ({match})",
"learning": "Doit être inférieur ou égal au Seuil de correspondance ({match})",
"learning": "Doit être supérieur ou égal au Seuil de correspondance ({match})",
"match_for_auto": "Doit être inférieur ou égal à la Confiance d'étiquetage automatique ({alc})",
"match_for_learning": "Doit être supérieur ou égal à la Confiance d'apprentissage ({lc})"
"match_for_learning": "Doit être inférieur ou égal à la Confiance d'apprentissage ({lc})"
},
"duration_ratio": {
"max": "Doit être supérieur au Ratio de durée min ({min})",
@@ -250,7 +258,7 @@
"match": "Doit être supérieur au Seuil de non-correspondance ({un})",
"unmatch": "Doit être inférieur au Seuil de correspondance ({match}) ; sinon une correspondance confirmée est immédiatement annulée"
},
"cascade_toast": "Également {n} paramètre{s} mis à jour pour la cohérence.",
"cascade_toast": "Autres paramètres ajustés pour la cohérence : {n}",
"suggestion_resolves": "Appliquez la suggestion en attente ({val}) ci-dessous pour corriger ceci",
"use_fix": "Utiliser {val}",
"watchdog": {
@@ -308,7 +316,8 @@
"pg_outcome": "Résultat de la simulation",
"pg_across_cycles": "Sur l'ensemble de vos cycles",
"community_store": "Boutique communautaire",
"online_account": "Boutique communautaire et fonctionnalités en ligne"
"online_account": "Boutique communautaire et fonctionnalités en ligne",
"import_power_history": "Importer l'historique de puissance"
},
"health": {
"fair": "Qualité de profil acceptable",
@@ -316,6 +325,7 @@
"poor": "⚠ Qualité de profil médiocre"
},
"lbl": {
"drag_to_resize": "Faites glisser pour redimensionner",
"actions": "Actions",
"activity": "Activité",
"administrators": "Administrateurs",
@@ -402,7 +412,7 @@
"metric": "Métrique",
"mode_existing_profile": "Ajouter au profil existant",
"mode_new_profile": "Créer un nouveau profil",
"models_fine_tuned": "({count} modèle{plural} affiné{plural})",
"models_fine_tuned": "(modèles affinés : {count})",
"n_classic_suggestions": "{n} classique",
"n_ml_suggestions": "{n} ML",
"n_selected": "{n} sélectionné(s)",
@@ -629,7 +639,26 @@
"conflict_import_copy": "Importer comme copie",
"conflict_keep_mine": "Garder le mien",
"conflict_overwrite": "Écraser",
"font_size": "Taille de police du panneau"
"font_size": "Taille de police du panneau",
"hist_csv_data": "Données CSV",
"hist_from_recorder": "Ou le lire depuis Home Assistant",
"hist_since": "Depuis le",
"days": "jours",
"hist_keep": "Conserver ce cycle",
"hist_looks_complete": "complet",
"peak_power_short": "Crête",
"shape": "Forme",
"hist_skip_idle": "rien en fonctionnement",
"hist_skip_sparse": "mesures trop espacées",
"hist_skip_short": "trop peu de mesures",
"hist_skip_long": "aucune pause assez longue pour découper",
"hist_reason_short": "plus court que le cycle réel le plus court de cet appareil",
"hist_reason_no_end": "ne s'est jamais terminé proprement",
"task_history_import": "Analyse de l'historique de puissance",
"task_history_import_apply": "Importation des cycles",
"evidence_real_cycles": "Cycles effectués par cette machine",
"evidence_reference_cycles": "Téléchargés depuis la boutique communautaire",
"evidence_backfill_cycles": "Trouvés dans un historique de puissance importé"
},
"log": {
"all_levels": "Tous niveaux",
@@ -708,9 +737,15 @@
"store_share": "Partager sur la boutique communautaire",
"store_share_device": "Partager cet appareil",
"export_select": "Exporter - choisir les données",
"import_wizard": "Importer - choisir les données"
"import_wizard": "Importer - choisir les données",
"history_import": "Importer l'historique de puissance"
},
"msg": {
"tail_trim_hint": "Nombre de secondes à supprimer à la fin",
"store_sibling_hint": "Rien de partagé pour votre modèle exact ? Un modèle proche de la même marque constitue généralement un bon point de départ.",
"store_declare_appliance": "Indiquez à WashData l'appareil que vous possédez et cet onglet affichera les configurations que d'autres personnes ont partagées pour celui-ci. Vous pouvez aussi saisir une marque ci-dessus pour explorer.",
"refresh_catalog_hint": "Les listes de marques et d'appareils de la communauté sont mises en cache afin de maintenir la boutique partagée dans son quota quotidien. Rafraîchissez pour récupérer les entrées ajoutées ou approuvées par d'autres utilisateurs.",
"head_trim_hint": "Nombre de secondes à supprimer au début",
"appliance_monitor": "Moniteur d'appareils",
"artifact_dip_detail": "Est tombé en dessous de la bande de puissance habituelle pendant environ {n} s.",
"artifact_footer": "Mis en évidence sur le graphique ci-dessus. Il sagit dartefacts transitoires (par exemple la porte ouverte en cours de cycle), pas nécessairement de problèmes.",
@@ -721,7 +756,7 @@
"automations_intro": "WashData déclenche les événements {start} / {end} et expose des entités, les notifications et actions sont donc mieux construites comme des automatisations Home Assistant normales. Les automatisations utilisant cet appareil apparaissent ci-dessous.",
"cleanup_intro": "Chaque cycle étiqueté superposé. Cochez les valeurs aberrantes et supprimez-les pour nettoyer le profil.",
"clear_debug_hint": "Supprimez les données de débogage stockées pour libérer de l'espace.",
"collecting_data": "Collecte de données - encore {need} cycle{plural} avant que l'affinage puisse commencer ({current}/{min}).",
"collecting_data": "Collecte de données. Cycles encore nécessaires avant que l'affinage puisse commencer : {need} ({current}/{min}).",
"compare_overlay_profiles": "Profils de superposition (faible)",
"compare_profiles_tip": "Superposez d'autres enveloppes de profil sur le graphique ci-dessus pour voir laquelle correspond le mieux à ce cycle.",
"compare_selected_cycles": "Cycles sélectionnés (solides) afficher/masquer",
@@ -731,7 +766,7 @@
"cycles_deleted": "{count} cycle(s) supprimé(s)",
"enough_data": "Suffisamment de données pour apprendre ({current}/{min} cycles).",
"export_description": "Choisissez précisément quels profils, cycles, réglages et autres exporter vers un JSON, ou analysez un fichier pour n'importer que les éléments souhaités.",
"feedback_cycles_pending": "{n} cycle{s} à examiner",
"feedback_cycles_pending": "À réviser : {n}",
"feedback_prompt": "Confirmez que c'était correct, corrigez le programme ou ignorez-le.",
"feedback_relabel_hint": "Réétiqueter ce cycle le résout également.",
"filter_by_profile": "Filtrer par profil…",
@@ -808,7 +843,6 @@
"pg_stress_synthetic": "la simulation de repos commence ici",
"pg_sweep_intro": "Et si {param} était différent ? Testez {steps} valeurs sur vos {cycles} derniers cycles pour trouver le réglage où le plus de cycles sont correctement reconnus.",
"pg_sweep_step": "Étape {done} / {total}",
"pg_undetected": "{n} cycle{s} non détecté{s}",
"pg_verdict_bad": "Nécessite une attention: de nombreux cycles ne sont pas détectés.",
"pg_verdict_good": "Bien réglé: la plupart des cycles sont correctement identifiés et reconnus.",
"pg_verdict_ok": "Acceptable: certains cycles manqués. Essayez d'abaisser le seuil de démarrage.",
@@ -839,6 +873,7 @@
"review_recorded_tip": "Marquez-le comme un cycle de référence trié sur le volet pour son programme - le même rôle qu'un cycle enregistré manuellement. Les cycles de référence sont toujours conservés, amorcent le modèle correspondant et ne sont jamais supprimés lors du nettoyage. (C'est le drapeau « doré »/enregistré ; les deux sont la même chose.)",
"review_tags_tip": "Indicateurs facultatifs décrivant ce qui n'a pas fonctionné avec ce cycle, afin que la formation et le nettoyage puissent en tenir compte.",
"review_to_cycles": "Ouvrir la file d'attente de révision des cycles",
"samples_decimated": "Affichage de {shown} sur {total} échantillons (réduits pour l'affichage ; pics conservés). Un grand écart ici est dû à la réduction, pas à des données manquantes.",
"saving_triggers_reload": "L'enregistrement déclenche un rechargement de l'intégration. Les entités HA peuvent apparaître brièvement comme indisponibles.",
"search_placeholder": "Paramètres de recherche…",
"see_recorder": "Voir le widget enregistreur ci-dessous",
@@ -958,10 +993,33 @@
"sug_mute_failed": "Impossible de masquer la suggestion",
"sug_unmuted_all": "Les suggestions masquées ont été réinitialisées",
"n_suggestions_muted": "{count} masquée(s) ; le réglage automatique ne proposera plus ces suggestions.",
"font_size_hint": "Agrandir ou réduire tout le contenu de ce panneau. S'applique à votre compte sur cet appareil."
"font_size_hint": "Agrandir ou réduire tout le contenu de ce panneau. S'applique à votre compte sur cet appareil.",
"import_history_description": "Vous aviez déjà une prise connectée avant WashData ? Chargez un export de l'historique de son capteur de puissance, ou lisez-le directement depuis Home Assistant : la détection habituelle s'applique à ces données, si bien que vos cycles passés apparaissent dans votre liste Cycles, prêts à être nommés.",
"hist_input_hint": "Chargez un CSV téléchargé depuis le panneau Historique (entité, état, dernière modification), ou laissez WashData lire directement l'historique du capteur. La détection s'exécute ensuite exactement comme en direct, et vous choisissez lesquels des cycles trouvés conserver.",
"hist_recorder_hint": "Lit depuis la date que vous choisissez jusqu'à maintenant. Home Assistant conserve l'historique détaillé pendant 10 jours par défaut, puis seulement des moyennes horaires, trop grossières pour y détecter des cycles - ne choisissez une date plus ancienne que si le recorder de Home Assistant est configuré pour en conserver davantage.",
"hist_scanning": "Votre historique est rejoué dans le détecteur. Cela s'exécute en arrière-plan : vous pouvez fermer cette fenêtre et y revenir plus tard.",
"hist_imported_count": "{n} cycles importés.",
"hist_duplicates": "{n} avaient déjà été importés et ont été ignorés.",
"hist_capped": "La limite de cycles importés par appareil a été atteinte ; le reste n'a pas été enregistré.",
"hist_next_step": "Ils sont dans votre liste Cycles, marqués comme historique importé. Ouvrez-en un et utilisez Étiqueter pour nommer le programme auquel il correspond.",
"hist_rows_read": "{n} mesures lues",
"hist_breaks": "{n} coupures où le capteur était indisponible",
"hist_other_entity": "{n} mesures d'autres entités ignorées",
"hist_entity_substituted": "{used} lu (cet appareil est configuré pour {wanted})",
"hist_skipped_spans": "Plages ignorées",
"hist_settings_used": "Détecté avec les réglages actuels de cet appareil (puissance minimale {w} W, délai d'arrêt {s} s).",
"hist_none_found": "Aucun cycle n'a pu être détecté dans cet historique.",
"hist_found": "{n} cycles trouvés. Décochez tout ce qui ne ressemble pas à un cycle réel : rien n'est enregistré avant l'importation.",
"hist_scan_capped": "Seuls les premiers candidats sont affichés ({n} ont été trouvés).",
"hist_recorder_empty": "Home Assistant n'a pas d'historique détaillé pour ce capteur sur cette période.",
"hist_scan_failed": "L'analyse a échoué.",
"hist_scan_expired": "Cette analyse n'est plus disponible. Veuillez relancer l'analyse.",
"hist_import_failed": "L'importation a échoué.",
"imported_history_readonly": "Détecté dans un historique de puissance importé. Il influence la correspondance des programmes mais n'est pas compté dans vos statistiques, et ne peut être ni rogné ni divisé. Étiquetez-le pour nommer le programme."
},
"pg_desc": {
"dishwasher_end_spike_quiet_release": "Lave-vaisselle : secondes de silence après la durée prévue avant de libérer l'attente de vidange de fin de cycle",
"smart_termination_duration_ratio": "Fraction de la durée prévue du programme correspondant qu'un cycle doit atteindre avant que la Terminaison intelligente puisse le terminer plus tôt ; abaissez-la pour les machines dépendant de la charge ou de la température",
"anti_wrinkle_enabled": "Absorber les impulsions de culbutage après la phase principale au lieu de les lire comme de nouveaux cycles",
"anti_wrinkle_exit_power": "La puissance doit tomber sous ce seuil entre les impulsions pour que l'anti-froissement reste actif",
"anti_wrinkle_idle_timeout": "Temps de silence autorisé entre deux impulsions de culbutage avant la fin de l'anti-froissement",
@@ -1158,7 +1216,7 @@
"label": "Entité de prix de l'énergie"
},
"energy_price_static": {
"doc": "Prix fixe par kWh utilisé pour les chiffres de coût lorsqu'aucune entité de prix en direct n'est définie ci-dessus.",
"doc": "Prix fixe par kWh utilisé pour les chiffres de coût lorsqu'aucune entité de prix en direct n'est définie ci-dessus.",
"label": "Prix de l'énergie statique (par kWh)"
},
"energy_sensor": {
@@ -1373,6 +1431,10 @@
"doc": "Stockez la trace de puissance complète et les données de débogage correspondantes pour chaque cycle. Utile pour le dépannage mais augmente la taille du stockage.",
"label": "Enregistrer les traces de débogage"
},
"smart_termination_duration_ratio": {
"doc": "À quel point un cycle doit avoir progressé dans la durée prévue du programme correspondant avant que la Terminaison intelligente puisse le terminer plus tôt une fois la puissance retombée. La durée prévue est la moyenne du programme ; ainsi, sur les appareils dont le temps de fonctionnement varie beaucoup - lave-linge selon l'eau d'arrivée froide en hiver ou tiède en été, sèche-linge à sonde d'humidité, programmes dépendant de la charge - environ la moitié des cycles se terminent plus tôt que cette moyenne et ne bénéficient jamais de la fin rapide, s'achevant seulement via le délai de secours avec plusieurs minutes de retard. Abaissez cette valeur (p. ex. 0,85) sur ces machines pour que la fin anticipée se déclenche quand même ; augmentez-la vers 1,0 pour être plus prudent. Laissez vide pour la valeur par défaut (0,98, ou 0,99 pour les lave-vaisselle). Elle ne peut que terminer un cycle plus tôt, jamais plus tard, et ne se déclenche jamais sur une correspondance ambiguë ou peu fiable.",
"label": "Ratio de terminaison intelligente"
},
"smoothing_window": {
"doc": "Dans quelle mesure le signal de puissance brute est lissé. Low (2) est réactif mais bruyant ; high (5) lisse les pointes mais ajoute du décalage.",
"label": "Fenêtre de lissage"
@@ -1504,6 +1566,10 @@
"door_end_dwell_seconds": {
"label": "Durée d'attente porte ouverte",
"doc": "Durée pendant laquelle la porte doit rester ouverte avant que WashData ne termine le cycle, lorsque « La porte s'ouvre automatiquement en fin de cycle » est activé. Assez longue pour ignorer l'ajout rapide d'un article (par défaut 60 s), assez courte pour terminer rapidement une fois que la machine ouvre la porte."
},
"profile_evidence_sources": {
"label": "Cycles qui façonnent un programme",
"doc": "Quels cycles servent à construire la courbe de puissance de chaque programme et à y comparer un cycle terminé. Décocher un type l'empêche de façonner vos programmes sans rien supprimer - les cycles restent dans votre liste Cycles et peuvent toujours être étiquetés ou supprimés. Utile si vous ne faites pas confiance aux données importées. Les statistiques ne sont pas concernées : elles ne comptent toujours que les cycles que cette machine a réellement effectués. Décocher tout est ignoré, car un programme sans aucun cycle derrière lui ne pourrait jamais correspondre."
}
},
"setting_group": {
@@ -1587,6 +1653,9 @@
},
"basic_configuration": {
"label": "Configuration de base"
},
"profile_evidence": {
"label": "Base des profils"
}
},
"status": {
@@ -1611,7 +1680,8 @@
"trimming": "Rognage…",
"splitting": "Fractionnement…",
"deleting": "Suppression…",
"imported": "Importé"
"imported": "Importé",
"preparing": "Préparation…"
},
"tab": {
"advanced": "Avancé",
@@ -1641,6 +1711,7 @@
"wrong_profile": "Mauvais profil"
},
"toast": {
"catalog_refreshed": "Catalogue de la communauté rafraîchi",
"access_saved": "Contrôle d'accès enregistré",
"all_wiped": "Toutes les données effacées",
"analysis_complete_none": "Analyse terminée : aucune nouvelle suggestion",
@@ -1652,7 +1723,7 @@
"cycle_labelled": "Cycle labellisé",
"cycle_paused": "Cycle en pause",
"cycle_resumed": "Cycle repris",
"cycle_trimmed": "Cycle coupé",
"cycle_trimmed": "Cycle rogné",
"cycles_merged": "Cycles fusionnés",
"envelope_rebuilt": "Enveloppe reconstruite",
"envelopes_rebuilt": "Enveloppes reconstruites",
@@ -1746,7 +1817,9 @@
"store_download_failed": "Échec du téléchargement : {error}",
"store_download_nothing": "Rien de nouveau à télécharger -- cette configuration est déjà sur votre appareil.",
"export_selective_done": "Export téléchargé",
"import_selective_done": "{profiles} profil(s) et {cycles} cycle(s) importés"
"import_selective_done": "{profiles} profil(s) et {cycles} cycle(s) importés",
"hist_csv_required": "Chargez d'abord un fichier CSV ou collez son contenu",
"file_read_failed": "Impossible de lire ce fichier"
},
"suggestion": {
"both_agree": "WashData recommande",
@@ -1842,7 +1915,7 @@
"thr_batch": "Maintenu juste au-dessus de la puissance active la plus basse au p05 sur {cycles} cycles ({p05}W) pour qu'un démarrage soit détecté le plus tôt possible et que le seuil d'arrêt reste sous la puissance de fonctionnement la plus basse de la machine.",
"tol_per_profile": "p75 de la variance de durée par profil sur {profiles} profils ({cycles} cycles) ; les profils resserrés ne sont pas pénalisés.",
"tol_pooled": "D'après la variance de durée regroupée de {cycles} cycles récemment étiquetés (écart p95={dev}).",
"watchdog": "Maintenu aussi bas que possible en toute sécurité (juste au-dessus de l'écart de mise à jour p95 de {p95}s, min 30s) pour détecter rapidement les blocages sans faux arrêts."
"watchdog": "Maintenu aussi bas que possible en toute sécurité (juste au-dessus de l'écart de mise à jour p95 de {p95}s et au moins 2x l'intervalle d'échantillonnage de {median}s, min 30s) pour détecter rapidement les blocages sans faux arrêts."
},
"exclusions": {
"summary": "{total} cycle(s) mal détecté(s) exclu(s) : {parts}.",
@@ -1908,6 +1981,10 @@
"finished": "Le cycle a atteint son état final et s'est terminé."
},
"store": {
"your_model_tip": "C'est l'appareil que vous avez déclaré dans les Paramètres",
"your_model": "Le vôtre",
"search_brand_ph": "Rechercher par marque…",
"programs_count": "Programmes : {n}",
"browse": "Parcourir",
"device": "Appareil",
"favorites": "Favoris",
@@ -78,9 +78,12 @@
"awaiting": "Čeka odobrenje",
"imported_tip": "Uvezeno iz zajedničke trgovine. Koristi se samo za podudaranje, ne broji se u statistiku.",
"not_importable": "nije dostupno",
"exists": "postoji"
"exists": "postoji",
"backfilled_tip": "Otkriveno u uvezenoj povijesti snage. Utječe samo na podudaranje programa, ne broji se u statistiku."
},
"btn": {
"set_brand_model": "Postavi marku i model",
"refresh_catalog": "Osvježi katalog",
"add_device": "+ Dodaj uređaj",
"add_device_tip": "Dodajte još jedan WashData uređaj",
"add_maintenance": "Dodaj događaj održavanja",
@@ -234,14 +237,19 @@
"download_device": "Preuzmi postavke uređaja",
"share_device": "Podijeli postavke uređaja",
"share_device_tip": "Podijelite programe i postavke ovog uređaja sa zajednicom",
"share_n": "Podijeli {n} program{s}",
"share_n": "Podijeli cikluse ({n})",
"export_selected": "Izvoz (odaberi podatke)",
"export_all": "Brzi izvoz svega",
"import_raw": "Napredno: zamijeni sve iz JSON datoteke",
"download_export": "Preuzmi izvoz",
"analyze_import": "Analiziraj datoteku",
"import_selected": "Uvezi odabrano",
"back": "Natrag"
"back": "Natrag",
"import_power_history": "Uvezi povijest snage",
"hist_read_recorder": "Pročitaj iz Home Assistant",
"hist_scan": "Traži cikluse",
"hist_import_n": "Uvezi cikluse: {n}",
"hist_goto_cycles": "Prikaži cikluse"
},
"conflict": {
"anti_wrinkle_exit": {
@@ -253,12 +261,12 @@
"start": "Mora biti ispod Maks. snage anti-bora ({max} W)"
},
"attn_sub": "Ispravite konflikte prije pohrane",
"attn_title": "{n} sukob{s} postavki",
"attn_title": "Sukobi postavki: {n}",
"confidence": {
"auto": "Mora biti jednak ili iznad Praga podudaranja ({match})",
"learning": "Mora biti jednak ili ispod Praga podudaranja ({match})",
"learning": "Mora biti jednak ili iznad Praga podudaranja ({match})",
"match_for_auto": "Mora biti jednak ili ispod Pouzdanosti za automatsko označavanje ({alc})",
"match_for_learning": "Mora biti jednak ili iznad Pouzdanosti učenja ({lc})"
"match_for_learning": "Mora biti jednak ili ispod Pouzdanosti učenja ({lc})"
},
"duration_ratio": {
"max": "Mora biti veći od Min. omjera trajanja ({min})",
@@ -296,14 +304,14 @@
"match": "Mora biti iznad Praga nepodudaranja ({un})",
"unmatch": "Mora biti ispod Praga podudaranja ({match}); inače potvrđeno podudaranje odmah prestaje"
},
"cascade_toast": "Automatski je prilagođeno i {n} postavki radi dosljednosti.",
"cascade_toast": "Druge postavke prilagođene radi dosljednosti: {n}",
"suggestion_resolves": "Primijenite prijedlog ({val}) u nastavku za rješavanje ovog sukoba",
"use_fix": "Koristi {val}",
"watchdog": {
"interval": "Trebao bi biti najmanje 2× Interval uzorkovanja ({si} s)",
"sampling": "Interval uzorkovanja trebao bi biti najviše pola Intervala nadzora ({wi} s)"
},
"settings_banner": "{n} sukob{s} postavki provjerite istaknute odjeljke i ispravite prije pohrane.",
"settings_banner": "Sukobi postavki: {n}. Provjerite istaknute odjeljke i ispravite ih prije spremanja.",
"settings_banner_btn": "Idi na prvi"
},
"hdr": {
@@ -356,7 +364,8 @@
"pg_outcome": "Ishod simulacije",
"pg_across_cycles": "Kroz sve vaše cikluse",
"community_store": "Zajednička trgovina",
"online_account": "Zajednička trgovina i online značajke"
"online_account": "Zajednička trgovina i online značajke",
"import_power_history": "Uvoz povijesti snage"
},
"health": {
"fair": "Prihvatljiva kvaliteta profila",
@@ -364,6 +373,7 @@
"poor": "⚠ Loša kvaliteta profila"
},
"lbl": {
"drag_to_resize": "Povucite za promjenu veličine",
"actions": "Radnje",
"activity": "Aktivnost",
"administrators": "Administratori",
@@ -435,7 +445,7 @@
"from": "Od",
"gap_s": "Razmak (s)",
"group_name": "Naziv grupe",
"head_trim": "Podrezivanje glave (s)",
"head_trim": "Obrezivanje početka (s)",
"health": "Zdravlje",
"hide_tabs": "Sakrij kartice za osobe koje nisu administratori",
"in_use": "U upotrebi",
@@ -451,7 +461,7 @@
"metric": "Metrika",
"mode_existing_profile": "Dodaj u postojeći profil",
"mode_new_profile": "Stvori novi profil",
"models_fine_tuned": "({count} modela fino podešenih)",
"models_fine_tuned": "(fino podešeni modeli: {count})",
"n_classic_suggestions": "{n} klasičan",
"n_ml_suggestions": "{n} ML",
"n_selected": "{n} odabrano",
@@ -533,7 +543,7 @@
"stage3": "Faza 3 DTW",
"stage4": "Faza 4 podudaranje",
"status": "Status",
"tail_trim": "Podrezivanje repa",
"tail_trim": "Obrezivanje kraja (s)",
"timer_auto_pause": "Automatska pauza",
"timer_min": "min",
"timer_msg_placeholder": "Poruka (nije obavezno, {device}/{program}/{minutes})",
@@ -677,7 +687,26 @@
"conflict_resolution": "Sukobi naziva",
"conflict_import_copy": "Uvezi kao kopiju",
"conflict_keep_mine": "Zadrži moje",
"conflict_overwrite": "Prepiši"
"conflict_overwrite": "Prepiši",
"hist_csv_data": "CSV podaci",
"hist_from_recorder": "Ili je pročitajte iz Home Assistant",
"days": "dana",
"hist_keep": "Zadrži ovaj ciklus",
"hist_looks_complete": "završen",
"peak_power_short": "Vrh",
"shape": "Oblik",
"hist_skip_idle": "ništa nije radilo",
"hist_skip_sparse": "prerijetka očitanja",
"hist_skip_short": "premalo očitanja",
"hist_skip_long": "nema dovoljno duge pauze za dijeljenje",
"hist_reason_short": "kraći od najkraćeg stvarnog ciklusa ovog uređaja",
"hist_reason_no_end": "nikada se nije uredno završio",
"hist_since": "Od",
"task_history_import": "Pretraživanje povijesti snage",
"task_history_import_apply": "Uvoz ciklusa",
"evidence_real_cycles": "Ciklusi koje je izvršio ovaj uređaj",
"evidence_reference_cycles": "Preuzeti iz zajedničke trgovine",
"evidence_backfill_cycles": "Nađeni u uvezenoj povijesti snage"
},
"log": {
"all_levels": "Sve razine",
@@ -756,9 +785,15 @@
"store_share": "Podijeli u zajedničku trgovinu",
"store_share_device": "Podijeli postavke uređaja",
"export_select": "Izvoz - odaberi podatke",
"import_wizard": "Uvoz - odaberi podatke"
"import_wizard": "Uvoz - odaberi podatke",
"history_import": "Uvoz povijesti snage"
},
"msg": {
"tail_trim_hint": "Uklonite ovoliko sekundi s kraja",
"store_sibling_hint": "Nema ničega podijeljenog za vaš točan model? Blisko srodan model iste marke obično je dobra početna točka.",
"store_declare_appliance": "Recite integraciji WashData koji uređaj posjedujete i ova kartica prikazat će konfiguracije koje su drugi podijelili za njega. Možete i upisati marku iznad kako biste pregledali katalog.",
"refresh_catalog_hint": "Popisi marki i uređaja zajednice privremeno se spremaju kako bi zajednička trgovina ostala u okviru svog dnevnog ograničenja. Osvježite da preuzmete unose koje su drugi dodali ili odobrili.",
"head_trim_hint": "Uklonite ovoliko sekundi s početka",
"appliance_monitor": "Monitor uređaja",
"artifact_dip_detail": "Palo ispod uobičajenog pojasa snage ~{n}s.",
"artifact_footer": "Istaknuto na gornjem grafikonu. To su prolazni artefakti (npr. vrata su se otvorila usred ciklusa), a ne nužno problemi.",
@@ -769,7 +804,7 @@
"automations_intro": "WashData pokreće događaje {start} / {end} i izlaže entitete, pa je obavijesti i radnje najbolje graditi kao normalne automatizacije Home Assistanta. Automatizacije koje koriste ovaj uređaj prikazane su ispod.",
"cleanup_intro": "Svaki označeni ciklus prekriven. Označite izvanredne vrijednosti i izbrišite da biste očistili profil.",
"clear_debug_hint": "Uklonite pohranjene podatke o otklanjanju pogrešaka da biste oslobodili prostor.",
"collecting_data": "Prikupljanje podataka: još {need} ciklusa prije početka finog podešavanja ({current}/{min}).",
"collecting_data": "Prikupljanje podataka. Još potrebnih ciklusa prije početka finog podešavanja: {need} ({current}/{min}).",
"compare_overlay_profiles": "Prekrivajući profili (slabo)",
"compare_profiles_tip": "Prekrijte druge omotnice profila na gornjoj tablici kako biste vidjeli koja najbolje odgovara ovom ciklusu.",
"compare_selected_cycles": "Odabrani ciklusi (puno) prikaži / sakrij",
@@ -779,7 +814,7 @@
"cycles_deleted": "{count} ciklus(a) izbrisano",
"enough_data": "Dovoljno podataka za učenje ({current}/{min} ciklusa).",
"export_description": "Odaberite točno koje profile, cikluse, postavke i ostalo želite izvesti u JSON datoteku ili analizirajte datoteku i uvezite samo željene dijelove.",
"feedback_cycles_pending": "{n} ciklus{s} za pregled",
"feedback_cycles_pending": "Za pregled: {n}",
"feedback_prompt": "Potvrdite da je ispravno, ispravite program ili zanemarite.",
"feedback_relabel_hint": "Ponovno označavanje ovog ciklusa također ga rješava.",
"filter_by_profile": "Filtriraj po profilu…",
@@ -793,7 +828,7 @@
"loading_curve": "Učitavanje krivulje…",
"loading_settings": "Učitavanje postavki…",
"log_buffer_hint": "Prvo najnovije · sprema zadnjih 500 ha_washdata zapisa od ponovnog pokretanja · povucite donji rub za promjenu veličine.",
"maintenance_advisory": "Povećanje trajanja/energije može ukazivati na potrebu održavanja uređaja (npr. uklanjanje kamenca, čišćenje filtera).",
"maintenance_advisory": "Povećanje trajanja/energije može ukazivati na potrebu održavanja uređaja (npr. uklanjanje kamenca, čišćenje filtera).",
"maintenance_due": "Održavanje na redu: {items}",
"maintenance_intro": "Bilježite servisiranje koje obavljate na ovom uređaju i primite podsjetnik kada svaki zadatak ponovno dođe na red.",
"maintenance_load_error": "Nije moguće učitati podatke o održavanju: {error}",
@@ -830,7 +865,7 @@
"no_split_points": "Još nema točaka razdvajanja.",
"no_suggestions": "Nema aktivnih prijedloga.",
"notify_services_hint": "Koristite ID-ove servisa {entity} (odvojene zarezima za više servisa). Varijable predloška: {vars}.",
"old_actions_warning": "Konfiguriran sa starim uređivačem akcija (sada uklonjen). I dalje se aktiviraju na događaje ciklusa, ali se više ne mogu uređivati ovdje. Pretvorite ih u normalnu automatizaciju ili ih uklonite.",
"old_actions_warning": "Konfiguriran sa starim uređivačem akcija (sada uklonjen). I dalje se aktiviraju na događaje ciklusa, ali se više ne mogu uređivati ovdje. Pretvorite ih u normalnu automatizaciju ili ih uklonite.",
"onboarding_progress": "{n} / 3 ciklusa promatrano",
"onboarding_watching": "Koristite uređaj uobičajeno WashData promatra. Nakon 3 ciklusa započet će podudaranje programa.",
"pending_feedback": "Povratne informacije o otkrivanju na čekanju",
@@ -856,7 +891,6 @@
"pg_stress_synthetic": "simulacija mirovanja počinje ovdje",
"pg_sweep_intro": "Što ako bi {param} bio drugačiji? Testirajte {steps} vrijednosti na svojih zadnjih {cycles} ciklusa kako biste pronašli postavku pri kojoj se najviše ciklusa ispravno podudara.",
"pg_sweep_step": "Korak {done} / {total}",
"pg_undetected": "{n} neotkrivenih ciklusa",
"pg_verdict_bad": "Zahtijeva pozornost: mnogi ciklusi ostaju neotkriveni.",
"pg_verdict_good": "Dobro podešeno: većina ciklusa ispravno je prepoznata i podudarana.",
"pg_verdict_ok": "Prihvatljivo: neki ciklusi su propušteni. Pokušajte sniziti prag pokretanja.",
@@ -888,6 +922,7 @@
"review_recorded_tip": "Označite ovo kao ručno odabran referentni ciklus za svoj program - ista uloga kao ručno snimljeni ciklus. Referentni ciklusi se uvijek čuvaju, postavljaju odgovarajući predložak i nikada se ne odbacuju čišćenjem. (Ovo je \"zlatna\"/snimljena zastava; obje su iste stvari.)",
"review_tags_tip": "Neobavezne oznake koje opisuju što je pošlo po zlu s ovim ciklusom, tako da obuka i čišćenje mogu objasniti to.",
"review_to_cycles": "Otvorite red čekanja za pregled ciklusa",
"samples_decimated": "Prikazano {shown} od {total} uzoraka (prorijeđeno za prikaz; vrhovi zadržani). Široki razmak ovdje znači prorjeđivanje, a ne nedostajuće podatke.",
"saving_triggers_reload": "Spremanje pokreće ponovno učitavanje integracije. HA entiteti mogu se nakratko prikazati kao nedostupni.",
"search_placeholder": "Postavke pretraživanja…",
"see_recorder": "Pogledajte widget za snimanje u nastavku",
@@ -991,12 +1026,12 @@
"share_consent": "Dijelite stvarne podatke sa svog uređaja. Ne dijelite ako su vaši obrasci korištenja privatni.",
"share_device_none": "Još nisu postavljena nikakva uređaja. Prvo dodajte uređaj.",
"share_guideline_naming": "Koristite jasna imena programa (npr. 'Cotton 40', 'Eco 60') kako bi ih drugi mogli prepoznati",
"share_guideline_quality": "Dijelite samo profile s ⭐ referentnim ciklusima ili najmanje {n} potvrđenih pokretanja",
"share_guideline_quality": "Dijelite samo cikluse koji su normalno završili -- bez prekida usred ciklusa, otvaranja vrata ili skokova napajanja.",
"share_guideline_review": "Pregledajte profile prije dijeljenja -- uklonite one koji izgledaju pogrešno",
"share_guidelines_title": "Prije dijeljenja",
"store_download_device_intro": "Preuzmite postavke uređaja iz zajednice i primijenite ih na novi ili postojeći uređaj",
"store_share_device_intro": "Podijelite programe svog uređaja (profile + referentne cikluse) sa zajednicom. Postavke su opcionalne.",
"share_profile_no_cycles": "Profil '{p}' nema referentnih ciklusa -- bit će preskočen osim ako nemate {n}+ potvrđenih pokretanja",
"store_share_device_intro": "Prenesite {brand} {model} s referentnim ciklusima koje odaberete. Drugi s istim uređajem mogu preuzeti vaše programe. Unosi se pregledavaju prije nego što postanu javno dostupni.",
"share_profile_no_cycles": "Nema referentnih ciklusa - označite ciklus sa ⭐ u kartici Ciklusi kako biste uključili ovaj profil",
"advisory_phase_inconsistent": "Čini se da '{name}' miješa različite programe ili temperature - njegovi se ciklusi griju vrlo različito dugo. Podjela na zasebne profile (npr. po temperaturi) poboljšat će podudaranje i procjene vremena.",
"advisory_phase_inconsistent_title": "⚠ Možda pomiješani programi",
"export_select_intro": "Označite točno što treba uključiti. Odabir profila bez njihovih ciklusa i dalje izvozi prepoznatljiv program (njegov naučeni oblik prenosi se s njim).",
@@ -1006,7 +1041,29 @@
"merge_hint": "Uvezene stavke se dodaju; ništa lokalno se ne gubi. Sukobi naziva rješavaju se u nastavku.",
"replace_warn": "Svaka označena kategorija briše se i zamjenjuje podacima iz datoteke. Neoznačene kategorije ostaju nepromijenjene.",
"dest_reference_hint": "Uvezeni ciklusi samo poboljšavaju prepoznavanje programa i nikada ne utječu na statistiku potrošnje/energije.",
"dest_real_history_hint": "Uvezeni ciklusi računaju se kao vlastita povijest ovog uređaja i pridonose statistici energije/potrošnje. Koristite pri premještanju jednog uređaja na novu instalaciju."
"dest_real_history_hint": "Uvezeni ciklusi računaju se kao vlastita povijest ovog uređaja i pridonose statistici energije/potrošnje. Koristite pri premještanju jednog uređaja na novu instalaciju.",
"import_history_description": "Imali ste pametni utikač i prije WashData? Učitajte izvoz povijesti njegovog senzora snage ili je pročitajte izravno iz Home Assistant, a uobičajeno otkrivanje proći će kroz te podatke, pa će se prošli ciklusi pojaviti u vašem popisu Ciklusi, spremni za imenovanje.",
"hist_input_hint": "Učitajte CSV preuzet s ploče Povijest (entitet, stanje, zadnja promjena) ili pustite WashData da izravno pročita povijest senzora. Otkrivanje se zatim izvodi jednako kao i uživo, a vi odabirete koje od nađenih ciklusa zadržati.",
"hist_recorder_hint": "Čita podatke od odabranog datuma do sada. Home Assistant standardno čuva detaljnu povijest 10 dana, a nakon toga samo satne prosjeke, koji su previše grubi za otkrivanje ciklusa - raniji datum odaberite samo ako je vaš recorder postavljen na dulje čuvanje.",
"hist_scanning": "Vašu povijest ponovno provodimo kroz detektor. Ovo se izvodi u pozadini - možete zatvoriti ovaj dijalog i vratiti se kasnije.",
"hist_imported_count": "Uvezeni ciklusi: {n}.",
"hist_duplicates": "Već prije uvezeno i preskočeno: {n}.",
"hist_capped": "Dosegnuto je ograničenje uvezenih ciklusa po uređaju; ostatak nije spremljen.",
"hist_next_step": "Nalaze se u vašem popisu Ciklusi, označeni kao uvezena povijest. Otvorite jedan i tipkom Označi mu dodijelite naziv programa kojem pripada.",
"hist_rows_read": "Pročitana očitanja: {n}",
"hist_breaks": "Praznine u kojima senzor nije bio dostupan: {n}",
"hist_other_entity": "Zanemarena očitanja drugih entiteta: {n}",
"hist_entity_substituted": "Očitano {used} (ovaj uređaj je postavljen na {wanted})",
"hist_skipped_spans": "Preskočeni odsječci",
"hist_settings_used": "Otkriveno s trenutnim postavkama ovog uređaja (minimalna snaga {w} W, odgoda isključivanja {s} s).",
"hist_none_found": "U toj povijesti nije bilo moguće otkriti nijedan ciklus.",
"hist_found": "Nađeni ciklusi: {n}. Odznačite sve što ne izgleda kao stvarni rad - ništa se ne sprema dok ne uvezete.",
"hist_scan_capped": "Prikazani su samo prvi kandidati (nađeno je {n}).",
"hist_recorder_empty": "Home Assistant nema detaljnu povijest za ovaj senzor u tom razdoblju.",
"hist_scan_failed": "Pretraživanje nije uspjelo.",
"hist_scan_expired": "To pretraživanje više nije dostupno. Pokrenite ga ponovno.",
"hist_import_failed": "Uvoz nije uspio.",
"imported_history_readonly": "Otkriveno u uvezenoj povijesti snage. Utječe na podudaranje programa, ali se ne broji u vašu statistiku i ne može se obrezati ni podijeliti. Označite ga da mu dodijelite program."
},
"phase_desc": {
"anti_crease": "Povremena kratka prevrtanja nakon završetka kako bi se smanjile bore.",
@@ -1161,7 +1218,7 @@
"label": "Tolerancija procjene"
},
"enable_ml_models": {
"doc": "While a cycle runs, let the models refine the live results: a steadier time-remaining and energy/cost estimate, and an anti-premature-stop guard on end detection (it can only ever delay a finish, never end one early, and is bounded). Koristi vaše fino podešene modele kada su dostupni, inače ugrađene. Isključeno = samo klasična logika koja se temelji na snazi (još uvijek pouzdana).",
"doc": "While a cycle runs, let the models refine the live results: a steadier time-remaining and energy/cost estimate, and an anti-premature-stop guard on end detection (it can only ever delay a finish, never end one early, and is bounded). Koristi vaše fino podešene modele kada su dostupni, inače ugrađene. Isključeno = samo klasična logika koja se temelji na snazi (još uvijek pouzdana).",
"label": "Primijeni pametne modele tijekom ciklusa"
},
"end_energy_threshold": {
@@ -1173,7 +1230,7 @@
"label": "Broj ponavljanja završetka"
},
"energy_price_entity": {
"doc": "Senzor s trenutnom cijenom električne energije po kWh (npr. dinamička tarifa). Ima prednost nad statičnom cijenom ispod. Svaki ciklus zamrzava cijenu na snazi kada završi.",
"doc": "Senzor s trenutnom cijenom električne energije po kWh (npr. dinamička tarifa). Ima prednost nad statičnom cijenom ispod. Svaki ciklus zamrzava cijenu na snazi kada završi.",
"label": "Entitet cijene energije"
},
"energy_price_static": {
@@ -1392,6 +1449,10 @@
"doc": "Pohranite puno praćenje snage i odgovarajuće podatke o otklanjanju pogrešaka za svaki ciklus. Korisno za rješavanje problema, ali povećava veličinu pohrane.",
"label": "Spremi tragove za otklanjanje pogrešaka"
},
"smart_termination_duration_ratio": {
"doc": "Koliko daleko u očekivanom trajanju podudarajućeg programa ciklus mora biti prije nego što ga Pametni završetak može ranije završiti nakon pada snage. Očekivano trajanje je prosjek programa, pa kod uređaja čije vrijeme rada jako varira - perilice s hladnom dovodnom vodom zimi u odnosu na toplu ljeti, sušilice sa senzorskim sušenjem, programi ovisni o količini rublja - otprilike polovica svih pokretanja završi kraće od tog prosjeka i nikada ne dobije brzo završavanje, već završi tek putem pričuvnog vremenskog ograničenja, nekoliko minuta kasnije. Kod takvih strojeva smanjite ovu vrijednost (npr. 0,85) kako bi se ranije završavanje ipak pokrenulo; povećajte je prema 1,0 za oprezniji pristup. Ostavite prazno za zadanu vrijednost (0,98, ili 0,99 za perilice posuđa). Ciklus može uvijek samo ranije završiti, nikada kasnije, i nikada se ne pokreće kod nejasnog podudaranja ili podudaranja niske pouzdanosti.",
"label": "Omjer pametnog završetka"
},
"smoothing_window": {
"doc": "Koliko je neobrađeni signal snage izglađen. Low (2) je osjetljiv, ali bučan; visoko (5) izglađuje skokove, ali dodaje kašnjenje.",
"label": "Prozor izglađivanja"
@@ -1522,6 +1583,10 @@
"door_end_dwell_seconds": {
"label": "Zadržavanje otvorenih vrata za završetak",
"doc": "Koliko dugo vrata moraju ostati otvorena prije nego WashData završi ciklus, kada je uključena postavka \"Vrata se automatski otvaraju na kraju\". Dovoljno dugo da se ignorira brzo dodavanje posuđa (zadano 60 s), dovoljno kratko za brz završetak kad perilica otvori vrata."
},
"profile_evidence_sources": {
"label": "Ciklusi koji oblikuju program",
"doc": "Koji se ciklusi koriste za izgradnju krivulje snage svakog programa i za podudaranje završenog ciklusa s njom. Kada odznačite neku vrstu, ona više ne utječe na vaše programe, ali se ništa ne briše - ciklusi ostaju na popisu Ciklusi i još ih je moguće označiti ili ukloniti. Korisno ako ne vjerujete uvezenim podacima. Na statistiku to ne utječe: uvijek se broje samo ciklusi koje je ovaj uređaj stvarno izvršio. Odznačavanje svega se ignorira jer se program bez ikakvih ciklusa nikada ne bi mogao podudarati."
}
},
"setting_group": {
@@ -1605,6 +1670,9 @@
},
"basic_configuration": {
"label": "Osnovna konfiguracija"
},
"profile_evidence": {
"label": "Osnova profila"
}
},
"status": {
@@ -1629,7 +1697,8 @@
"trimming": "Obrezivanje…",
"splitting": "Dijeljenje…",
"deleting": "Brisanje…",
"imported": "Uvezeno"
"imported": "Uvezeno",
"preparing": "Priprema…"
},
"suggestion": {
"both_agree": "WashData preporučuje",
@@ -1725,7 +1794,7 @@
"thr_batch": "Zadržano tik iznad najniže radne snage p05 kroz {cycles} ciklusa ({p05}W) kako bi se početak uhvatio što ranije, a prag zaustavljanja ostao ispod najniže radne snage stroja.",
"tol_per_profile": "p75 varijance trajanja po profilu kroz {profiles} profila ({cycles} ciklusa); dosljedni profili nisu kažnjeni.",
"tol_pooled": "Na temelju objedinjene varijance trajanja {cycles} novijih označenih ciklusa (p95 odstupanje={dev}).",
"watchdog": "Zadržano što nižim uz sigurnost (tik iznad razmaka ažuriranja p95 od {p95}s, najmanje 30s) kako bi se zastoji brzo uhvatili bez lažnih zaustavljanja."
"watchdog": "Zadržano što nižim uz sigurnost (tik iznad razmaka ažuriranja p95 od {p95}s i najmanje 2× intervala uzorkovanja od {median}s, najmanje 30s) kako bi se zastoji brzo uhvatili bez lažnih zaustavljanja."
},
"exclusions": {
"summary": "Isključeno {total} pogrešno otkrivenih ciklusa: {parts}.",
@@ -1772,6 +1841,7 @@
"wrong_profile": "Pogrešan profil"
},
"toast": {
"catalog_refreshed": "Katalog zajednice je osvježen",
"access_saved": "Kontrola pristupa spremljena",
"all_wiped": "Svi podaci izbrisani",
"analysis_complete_none": "Analiza dovršena: nema novih prijedloga",
@@ -1783,7 +1853,7 @@
"cycle_labelled": "Ciklus označen",
"cycle_paused": "Ciklus pauziran",
"cycle_resumed": "Ciklus je nastavljen",
"cycle_trimmed": "Ciklus podrezan",
"cycle_trimmed": "Ciklus obrezan",
"cycles_merged": "Ciklusi spojeni",
"envelope_rebuilt": "Omotnica obnovljena",
"envelopes_rebuilt": "Omotnice obnovljene",
@@ -1865,19 +1935,21 @@
"rating_saved": "Ocjena kvalitete spremljena",
"brand_added": "Marka dodana, čeka odobrenje",
"profile_added": "Profil dodan, čeka odobrenje",
"saved_except_conflicts": "Postavke spremljene -- {n} postavka{s} preskočena zbog sukoba",
"saved_except_conflicts": "Spremljeno. Ispravite istaknute sukobe da spremite ostalo.",
"share_device_none_sel": "Odaberite barem jedan program za dijeljenje",
"store_device_downloaded": "Postavke uređaja preuzete: {created} profil{c} stvoren, {dup} već postoji",
"store_device_downloaded_phases": "Postavke uređaja preuzete: {created} profil{c} stvoren, {dup} već postoji, karta faza primijenjena",
"store_device_downloaded_settings": "Postavke uređaja preuzete: {created} profil{c} stvoren, {dup} već postoji, postavke primijenjene",
"store_device_shared": "Postavke uređaja podijeljene: {n} program{s} učitan",
"store_device_shared_all_dup": "Nema ničeg novog za dijeljenje -- svi programi već postoje u trgovini",
"store_device_shared_partial": "Djelomično dijeljenje: {n} program{s} učitan, {failed} preskočeno",
"store_device_shared_some_dup": "Postavke uređaja podijeljene: {n} program{s} učitan ({dup} već postoji)",
"store_device_downloaded": "Dodano: programi {p}, snimke {c}",
"store_device_downloaded_phases": "Dodano: programi {p}, snimke {c}, karte faza {ph}",
"store_device_downloaded_settings": "Dodano: programi {p}, snimke {c}, karte faza {ph}, postavke {s}",
"store_device_shared": "Ciklusi podijeljeni u zajedničku trgovinu: {n}. Čeka se pregled.",
"store_device_shared_all_dup": "Svi ciklusi ({n}) već su bili u zajedničkoj trgovini.",
"store_device_shared_partial": "Podijeljeni ciklusi: {n}; nije preneseno: {failed}.",
"store_device_shared_some_dup": "Podijeljeni ciklusi: {created}; već u trgovini: {dup}.",
"store_download_failed": "Preuzimanje nije uspjelo: {error}",
"store_download_nothing": "Nema ništa za preuzimanje -- svi profili već postoje na ovom uređaju",
"export_selective_done": "Izvoz preuzet",
"import_selective_done": "Uvezeno {profiles} profila i {cycles} ciklusa"
"import_selective_done": "Uvezeno {profiles} profila i {cycles} ciklusa",
"hist_csv_required": "Najprije učitajte CSV datoteku ili zalijepite njezin sadržaj",
"file_read_failed": "Nije bilo moguće pročitati tu datoteku"
},
"trend": {
"down": "Trend pada",
@@ -1892,6 +1964,7 @@
},
"pg_desc": {
"dishwasher_end_spike_quiet_release": "Perilica posuđa: sekunde tišine nakon očekivanog trajanja prije nego što se otpusti čekanje na završno ispumpavanje vode",
"smart_termination_duration_ratio": "Udio očekivanog trajanja podudarajućeg programa koji ciklus mora dosegnuti prije nego što ga Pametni završetak može ranije završiti; smanjite ga za strojeve ovisne o količini rublja ili temperaturi",
"anti_wrinkle_enabled": "Upij impulse bubnja nakon glavne faze, a ne čitaj ih kao nove cikluse",
"anti_wrinkle_exit_power": "Snaga mora pasti ispod ove vrijednosti između impulsa da bi anti-bora ostala aktivna",
"anti_wrinkle_idle_timeout": "Dopušteno vrijeme mirovanja između dva impulsa bubnja prije nego što anti-bora završi",
@@ -1955,6 +2028,10 @@
"finished": "Ciklus je dosegao završno stanje i završio."
},
"store": {
"your_model_tip": "Ovo je uređaj koji ste naveli u Postavkama",
"your_model": "Vaš",
"search_brand_ph": "Pretraži po marki…",
"programs_count": "Programi: {n}",
"browse": "Pregledaj",
"device": "Uređaj",
"favorites": "Favoriti",
@@ -78,9 +78,12 @@
"awaiting": "Jóváhagyásra vár",
"imported_tip": "A közösségi boltból importálva. Csak egyeztetéshez használatos, a statisztikába nem számít bele.",
"not_importable": "itt nem elérhető",
"exists": "létezik"
"exists": "létezik",
"backfilled_tip": "Importált teljesítményelőzményekben észlelve. Csak a programegyeztetést befolyásolja, a statisztikába nem számít bele."
},
"btn": {
"set_brand_model": "Márka és modell megadása",
"refresh_catalog": "Katalógus frissítése",
"add_device": "+ Eszköz hozzáadása",
"add_device_tip": "Adjon hozzá egy másik WashData eszközt",
"add_maintenance": "Karbantartási esemény hozzáadása",
@@ -241,7 +244,12 @@
"import_selected": "Kiválasztottak importálása",
"back": "Vissza",
"mute_suggestion": "Ne javasolja többé ezt a beállítást",
"reset_muted": "Elhallgatottak visszaállítása"
"reset_muted": "Elhallgatottak visszaállítása",
"import_power_history": "Teljesítményelőzmények importálása",
"hist_read_recorder": "Beolvasás a Home Assistantból",
"hist_scan": "Ciklusok keresése",
"hist_import_n": "{n} ciklus importálása",
"hist_goto_cycles": "Ciklusok megjelenítése"
},
"conflict": {
"anti_wrinkle_exit": {
@@ -253,14 +261,14 @@
"start": "A Ránctalanítás maximális teljesítménye alatt kell lennie ({max} W)"
},
"attn_sub": "Mentés előtt javítsa az ütközéseket",
"attn_title": "{n} beállítási ütközés{s}",
"settings_banner": "{n} beállítási ütközés{s} ellenőrizze a kijelölt szakaszokat és javítsa ki mentés előtt.",
"attn_title": "Beállítási ütközések: {n}",
"settings_banner": "Beállítási ütközések: {n}. Ellenőrizze a kijelölt szakaszokat, és javítsa ki őket mentés előtt.",
"settings_banner_btn": "Ugrás az elsőhöz",
"confidence": {
"auto": "Legalább az Egyezési küszöb értékén kell lennie ({match})",
"learning": "Legfeljebb az Egyezési küszöb értékén lehet ({match})",
"learning": "Legalább az Egyezési küszöb értékén kell lennie ({match})",
"match_for_auto": "Legfeljebb az Automatikus jelölési megbízhatóság értékén lehet ({alc})",
"match_for_learning": "Legalább a Tanulási megbízhatóság értékén kell lennie ({lc})"
"match_for_learning": "Legfeljebb a Tanulási megbízhatóság értékén lehet ({lc})"
},
"duration_ratio": {
"max": "Nagyobb kell lennie a Min. időtartam aránynál ({min})",
@@ -298,7 +306,7 @@
"match": "A Nem egyező küszöb felett kell lennie ({un})",
"unmatch": "Az Egyezési küszöb alatt kell lennie ({match}); különben egy megerősített egyezés azonnal visszavonódik"
},
"cascade_toast": "Konzisztencia megőrzése érdekében {n} beállítás is automatikusan módosult.",
"cascade_toast": "A konzisztencia érdekében módosított további beállítások: {n}",
"suggestion_resolves": "A javításhoz alkalmazza az alábbi függőben lévő javaslatot ({val})",
"use_fix": "Használja a következőt: {val}",
"watchdog": {
@@ -356,7 +364,8 @@
"pg_outcome": "Szimuláció eredménye",
"pg_across_cycles": "Az összes ciklusban",
"community_store": "Közösségi bolt",
"online_account": "Közösségi bolt és online funkciók"
"online_account": "Közösségi bolt és online funkciók",
"import_power_history": "Teljesítményelőzmények importálása"
},
"health": {
"fair": "Elfogadható profilminőség",
@@ -364,6 +373,7 @@
"poor": "⚠ Gyenge profilminőség"
},
"lbl": {
"drag_to_resize": "Húzza az átméretezéshez",
"pg_anti_wrinkle": "Ránctalanítás",
"actions": "Akciók",
"activity": "Tevékenység",
@@ -435,7 +445,7 @@
"from": "Ettől",
"gap_s": "rés(ek)",
"group_name": "Csoport neve",
"head_trim": "Fejszegély(ek)",
"head_trim": "Vágás az elejéről (s)",
"health": "Egészség",
"hide_tabs": "Lapok elrejtése nem rendszergazdák számára",
"in_use": "Használatban",
@@ -451,7 +461,7 @@
"metric": "Mérőszám",
"mode_existing_profile": "Hozzáadás a meglévő profilhoz",
"mode_new_profile": "Új profil létrehozása",
"models_fine_tuned": "({count} modell finomhangolva)",
"models_fine_tuned": "(finomhangolt modellek: {count})",
"n_classic_suggestions": "{n} klasszikus",
"n_ml_suggestions": "{n} ML",
"n_selected": "{n} kijelölve",
@@ -532,7 +542,7 @@
"stage3": "3. szakasz DTW",
"stage4": "4. szakasz egyezés",
"status": "Állapot",
"tail_trim": "Farokszegély(ek)",
"tail_trim": "Vágás a végéről (s)",
"timer_auto_pause": "Automatikus szünet",
"timer_min": "min",
"timer_msg_placeholder": "Üzenet (nem kötelező, {device}/{program}/{minutes})",
@@ -677,7 +687,26 @@
"conflict_import_copy": "Importálás másolatként",
"conflict_keep_mine": "A sajátom megtartása",
"conflict_overwrite": "Felülírás",
"font_size": "Panel betűmérete"
"font_size": "Panel betűmérete",
"hist_csv_data": "CSV-adatok",
"hist_from_recorder": "Vagy olvassa be a Home Assistantból",
"hist_since": "Kezdő dátum",
"days": "nap",
"hist_keep": "Ciklus megtartása",
"hist_looks_complete": "teljes",
"peak_power_short": "Csúcs",
"shape": "Alak",
"hist_skip_idle": "nem futott semmi",
"hist_skip_sparse": "túl ritka mérések",
"hist_skip_short": "túl kevés mérés",
"hist_skip_long": "nincs elég hosszú szünet a felosztáshoz",
"hist_reason_short": "rövidebb, mint a készülék legrövidebb valódi ciklusa",
"hist_reason_no_end": "soha nem fejeződött be tisztán",
"task_history_import": "Teljesítményelőzmények vizsgálata",
"task_history_import_apply": "Ciklusok importálása",
"evidence_real_cycles": "A gép által lefuttatott ciklusok",
"evidence_reference_cycles": "Letöltve a közösségi boltból",
"evidence_backfill_cycles": "Importált teljesítményelőzményekben találva"
},
"log": {
"all_levels": "Minden szinten",
@@ -756,9 +785,15 @@
"store_share": "Megosztás a közösségi boltban",
"store_share_device": "Eszköz megosztása",
"export_select": "Exportálás - adatok kiválasztása",
"import_wizard": "Importálás - adatok kiválasztása"
"import_wizard": "Importálás - adatok kiválasztása",
"history_import": "Teljesítményelőzmények importálása"
},
"msg": {
"tail_trim_hint": "Ennyi másodperc eltávolítása a végéről",
"store_sibling_hint": "Pontosan az Ön modelljéhez nincs semmi megosztva? Ugyanannak a márkának egy közeli modellje általában jó kiindulópont.",
"store_declare_appliance": "Adja meg a WashDatának, hogy melyik készülék az Öné, és ez a lap megjeleníti a mások által hozzá megosztott programokat és felvételeket. Fent egy márkát is beírhat, ha csak körül szeretne nézni.",
"refresh_catalog_hint": "A közösségi márka- és készüléklisták gyorsítótárba kerülnek, hogy a megosztott bolt a napi lekérdezési keretén belül maradjon. Frissítsen a mások által hozzáadott vagy jóváhagyott bejegyzések betöltéséhez.",
"head_trim_hint": "Ennyi másodperc eltávolítása az elejéről",
"appliance_monitor": "Készülék monitor",
"artifact_dip_detail": "~{n}s-re a szokásos energiasáv alá esett.",
"artifact_footer": "A fenti grafikonon kiemelve. Ezek átmeneti műtermékek (pl. a ciklus közepén kinyílt ajtó), nem feltétlenül problémák.",
@@ -769,7 +804,7 @@
"automations_intro": "A WashData {start} / {end} eseményeket küld és entitásokat tesz elérhetővé, ezért az értesítések és műveletek legjobban normál Home Assistant automatizálásként építhetők fel. Az ezt az eszközt használó automatizálások alább jelennek meg.",
"cleanup_intro": "Minden címkézett ciklus átfedi. Jelölje be a kiugró értékeket, és törölje a profilt a profil megtisztításához.",
"clear_debug_hint": "Távolítsa el a tárolt hibakeresési adatokat, hogy helyet szabadítson fel.",
"collecting_data": "Adatgyűjtés folyamatban - még {need} ciklus szükséges a finomhangolás megkezdéséhez ({current}/{min}).",
"collecting_data": "Adatgyűjtés folyamatban. A finomhangolás megkezdéséhez még szükséges ciklusok: {need} ({current}/{min}).",
"compare_overlay_profiles": "Fedőprofilok (halvány)",
"compare_profiles_tip": "Fedjen rá más profilborítékokat a fenti diagramra, hogy megtudja, melyik illik legjobban ehhez a ciklushoz.",
"compare_selected_cycles": "Kiválasztott ciklusok (folytonos) megjelenítés/elrejtés",
@@ -779,7 +814,7 @@
"cycles_deleted": "{count} ciklus törölve",
"enough_data": "Elegendő adat a tanuláshoz ({current}/{min} ciklus).",
"export_description": "Válaszd ki pontosan, mely profilokat, ciklusokat, beállításokat és egyebeket exportálsz JSON-ba, vagy elemezz egy fájlt, és csak a kívánt részeket importáld.",
"feedback_cycles_pending": "{n} ciklus{s} áttekintésre vár",
"feedback_cycles_pending": "Áttekintésre vár: {n}",
"feedback_prompt": "Erősítse meg, hogy helyes volt, javítsa ki a programot, vagy hagyja figyelmen kívül.",
"feedback_relabel_hint": "Ennek a ciklusnak az újracímkézése ezt is megoldja.",
"filter_by_profile": "Szűrés profil szerint…",
@@ -856,7 +891,6 @@
"pg_stress_synthetic": "az üresjárati szimuláció itt kezdődik",
"pg_sweep_intro": "Mi lenne, ha a {param} más lenne? Teszteljen {steps} értéket az utolsó {cycles} cikluson, hogy megtalálja azt a beállítást, ahol a legtöbb ciklus helyesen egyezik.",
"pg_sweep_step": "{done} / {total}. lépés",
"pg_undetected": "{n} nem észlelt ciklus",
"pg_verdict_bad": "Figyelmet igényel: sok ciklus észrevétlen marad.",
"pg_verdict_good": "Jól hangolva: a legtöbb ciklust helyesen azonosítja és párosítja.",
"pg_verdict_ok": "Elfogadható: néhány ciklus kimaradt. Próbálja meg csökkenteni az indítási küszöböt.",
@@ -887,6 +921,7 @@
"review_recorded_tip": "Jelölje meg ezt a programhoz tartozó, kézzel kiválasztott referenciaciklusként ugyanaz a szerep, mint egy kézzel rögzített ciklus. A referenciaciklusokat mindig megőrizzük, a megfelelő sablont vetjük be, és soha nem vetik el őket a tisztítás során. (Ez az \"arany\"/rekord zászló; mindkettő ugyanaz.)",
"review_tags_tip": "Opcionális jelzők, amelyek leírják, hogy mi hibázott ebben a ciklusban, így a képzés és a tisztítás megmagyarázhatja.",
"review_to_cycles": "Nyissa meg a Ciklusok áttekintési sort",
"samples_decimated": "{shown}/{total} minta megjelenítése (megjelenítéshez ritkítva; a csúcsok megtartva). Az itt látható széles hézag ritkítás, nem hiányzó adat.",
"saving_triggers_reload": "A mentés az integráció újratöltését indítja el. A HA entitások rövid időre elérhetetlenként jelenhetnek meg.",
"search_placeholder": "Keresési beállítások…",
"see_recorder": "Lásd alább a felvevő widgetet",
@@ -1006,7 +1041,29 @@
"sug_mute_failed": "Nem sikerült elhallgattatni a javaslatot",
"sug_unmuted_all": "Az elhallgattatott javaslatok visszaállítva",
"n_suggestions_muted": "{count} elhallgattatva; az automatikus finomhangolás nem fogja javasolni ezeket.",
"font_size_hint": "Tegye nagyobbá vagy kisebbé mindent a panelen. Az ezen az eszközön lévő fiókjára vonatkozik."
"font_size_hint": "Tegye nagyobbá vagy kisebbé mindent a panelen. Az ezen az eszközön lévő fiókjára vonatkozik.",
"import_history_description": "Volt már okoskonnektora a WashData előtt? Töltse fel a teljesítményérzékelő előzmény-exportját, vagy olvassa be közvetlenül a Home Assistantból: a szokásos észlelés lefut rajta, így a régi ciklusok megjelennek a Ciklusok listában, készen az elnevezésre.",
"hist_input_hint": "Töltsön fel az Előzmények panelről letöltött CSV-t (entity, state, last changed), vagy hagyja, hogy a WashData közvetlenül beolvassa az érzékelő előzményeit. Ezután pontosan ugyanaz az észlelés fut le rajta, mint élőben, és Ön választja ki, mely megtalált ciklusokat tartja meg.",
"hist_recorder_hint": "A kiválasztott dátumtól a mostani időpontig olvas be. A Home Assistant alapértelmezés szerint 10 napig tart meg részletes előzményeket, utána már csak óránkénti átlagokat, amelyek túl durvák a ciklusok észleléséhez - csak akkor válasszon korábbi dátumot, ha a recorder többet tart meg.",
"hist_scanning": "Az előzményeket újra lejátsszuk az észlelőn keresztül. Ez a háttérben fut - bezárhatja ezt a párbeszédpanelt, és később visszatérhet hozzá.",
"hist_imported_count": "{n} ciklus importálva.",
"hist_duplicates": "{n} korábban már importálva volt, ezért kimaradt.",
"hist_capped": "Elérte az eszközre vonatkozó importált ciklus korlátot; a többi nem lett eltárolva.",
"hist_next_step": "A Ciklusok listában találhatók, importált előzményként megjelölve. Nyisson meg egyet, és a Címkézés funkcióval adja meg a hozzá tartozó programot.",
"hist_rows_read": "{n} mérés beolvasva",
"hist_entity_substituted": "{used} beolvasva (ehhez az eszközhöz {wanted} van beállítva)",
"hist_breaks": "{n} szakasz, ahol az érzékelő nem volt elérhető",
"hist_other_entity": "{n} más entitáshoz tartozó mérés kihagyva",
"hist_skipped_spans": "Kihagyott szakaszok",
"hist_settings_used": "Az eszköz jelenlegi beállításaival észlelve (minimális teljesítmény {w} W, kikapcsolási késleltetés {s} s).",
"hist_none_found": "Az adott előzményekben nem sikerült ciklust észlelni.",
"hist_found": "{n} ciklus található. Vegye ki a jelölést mindenről, ami nem tűnik valódi futásnak - importálásig semmi nem kerül eltárolásra.",
"hist_scan_capped": "Csak az első találatok láthatók (összesen {n} volt).",
"hist_recorder_empty": "A Home Assistantnak nincs részletes előzménye erről az érzékelőről abban az időszakban.",
"hist_scan_failed": "A vizsgálat nem sikerült.",
"hist_scan_expired": "Ez a vizsgálat már nem elérhető. Kérjük, futtassa újra.",
"hist_import_failed": "Az importálás nem sikerült.",
"imported_history_readonly": "Importált teljesítményelőzményekben észlelve. Befolyásolja a programegyeztetést, de nem számít bele a statisztikákba, és nem vágható vagy osztható. Címkézze fel a hozzá tartozó program megadásához."
},
"phase_desc": {
"anti_crease": "Alkalmankénti rövid bukdácsolás a befejezés után a ráncok csökkentése érdekében.",
@@ -1392,6 +1449,10 @@
"doc": "Tárolja a teljes teljesítmény nyomkövetést és a megfelelő hibakeresési adatokat minden ciklushoz. Hasznos hibaelhárításhoz, de növeli a tárhely méretét.",
"label": "Hibakeresési nyomok mentése"
},
"smart_termination_duration_ratio": {
"doc": "Mennyire kell előrehaladnia a ciklusnak az egyeztetett program várható időtartamán belül, mielőtt az intelligens leállítás a teljesítmény csökkenésekor korábban befejezheti azt. A várható időtartam a program átlaga, így azokon a készülékeken, amelyek futásideje sokat ingadozik - mosógépek hideg téli és meleg nyári befolyó vízzel, szárazságérzékelős szárítógépek, terheléstől függő programok - az összes futás nagyjából fele ennél az átlagnál rövidebben fejeződik be, és soha nem kapja meg a gyors befejezést, csak a tartalék időtúllépésen keresztül ér véget, percekkel később. Csökkentse ezt (pl. 0.85) ezeken a gépeken, hogy a korai befejezés így is elinduljon; emelje 1.0 felé az óvatosabb működéshez. Hagyja üresen az alapértelmezett értékhez (0.98, mosogatógépeknél 0.99). Csak korábban fejezhet be egy ciklust, soha nem később, és soha nem indul el bizonytalan vagy alacsony megbízhatóságú egyezésnél.",
"label": "Intelligens leállítási arány"
},
"smoothing_window": {
"doc": "Mennyire van simítva a nyers teljesítményjel. Alacsony (2) érzékeny, de zajos; magas (5) kisimítja a tüskéket, de növeli a késést.",
"label": "Simítási ablak"
@@ -1522,6 +1583,10 @@
"door_end_dwell_seconds": {
"label": "Ajtó-nyitásvégi várakozási idő",
"doc": "Mennyi ideig kell nyitva maradnia az ajtónak, mielőtt a WashData befejezi a ciklust, amikor az \"Ajtó automatikusan kinyílik a végén\" be van kapcsolva. Elég hosszú ahhoz, hogy figyelmen kívül hagyja a gyors edény betöltését (alapértelmezés: 60 s), elég rövid ahhoz, hogy gyorsan befejezzen, miután a gép kinyitja az ajtót."
},
"profile_evidence_sources": {
"label": "A programot alakító ciklusok",
"doc": "Mely ciklusok szolgálnak az egyes programok teljesítménygörbéjének felépítéséhez, és egy befejezett ciklus ahhoz való egyeztetéséhez. Ha egy fajta jelölését kikapcsolja, az többé nem alakítja a programjait, de semmi nem törlődik - a ciklusok a Ciklusok listában maradnak, és továbbra is címkézhetők vagy eltávolíthatók. Akkor hasznos, ha nem bízik az importált adatokban. A statisztikákra nincs hatással: azok mindig csak azokat a ciklusokat számolják, amelyeket ez a gép valóban lefuttatott. Ha mindent kikapcsol, azt figyelmen kívül hagyjuk, mert egy ciklusok nélküli program soha nem tudna egyezni."
}
},
"setting_group": {
@@ -1605,6 +1670,9 @@
},
"basic_configuration": {
"label": "Alapkonfiguráció"
},
"profile_evidence": {
"label": "Profil alapja"
}
},
"status": {
@@ -1629,7 +1697,8 @@
"trimming": "Vágás…",
"splitting": "Felosztás…",
"deleting": "Törlés…",
"imported": "Importált"
"imported": "Importált",
"preparing": "Előkészítés…"
},
"tab": {
"advanced": "Fejlett",
@@ -1659,6 +1728,7 @@
"wrong_profile": "Rossz profil"
},
"toast": {
"catalog_refreshed": "A közösségi katalógus frissítve",
"access_saved": "A hozzáférés-szabályozás mentve",
"all_wiped": "Minden adat törölve",
"analysis_complete_none": "Az elemzés kész: nincs új javaslat",
@@ -1764,7 +1834,9 @@
"store_download_failed": "Letöltés sikertelen: {error}",
"store_download_nothing": "Nincs új letöltendő - ez a beállítás már megvan az eszközön.",
"export_selective_done": "Export letöltve",
"import_selective_done": "{profiles} profil és {cycles} ciklus importálva"
"import_selective_done": "{profiles} profil és {cycles} ciklus importálva",
"hist_csv_required": "Először töltsön be egy CSV-fájlt, vagy illessze be a tartalmát",
"file_read_failed": "A fájl nem olvasható"
},
"suggestion": {
"both_agree": "A WashData javasolja",
@@ -1860,7 +1932,7 @@
"thr_batch": "Éppen a p05 legkisebb aktív teljesítmény fölött tartva {cycles} cikluson át ({p05}W), hogy az indítás a lehető legkorábban észlelhető legyen, a leállítási küszöb pedig a gép legkisebb üzemi teljesítménye alatt maradjon.",
"tol_per_profile": "A profilonkénti időtartam-szórás p75 értéke {profiles} profilon át ({cycles} ciklus); a stabil profilok nem kapnak büntetést.",
"tol_pooled": "{cycles} legutóbbi címkézett ciklus összevont időtartam-szórása alapján (p95 szórás={dev}).",
"watchdog": "A biztonságosan lehető legalacsonyabbra állítva (épp a p95 frissítési szünet, azaz {p95}s felett, min. 30s), hogy az elakadások gyorsan észlelhetők legyenek téves leállítások nélkül."
"watchdog": "A biztonságosan lehető legalacsonyabbra állítva (épp a p95 frissítési szünet, azaz {p95}s felett, és legalább a mintavételezési intervallum ({median}s) kétszerese, min. 30s), hogy az elakadások gyorsan észlelhetők legyenek téves leállítások nélkül."
},
"exclusions": {
"summary": "{total} tévesen észlelt ciklus kizárva: {parts}.",
@@ -1892,6 +1964,7 @@
},
"pg_desc": {
"dishwasher_end_spike_quiet_release": "Mosogatógép: csendes másodpercek a várható időtartam után, mielőtt a ciklus végi leeresztésre való várakozás feloldódik",
"smart_termination_duration_ratio": "Az egyeztetett program várható időtartamának hányada, amelyet a ciklusnak el kell érnie, mielőtt az intelligens leállítás korábban befejezheti; csökkentse a terheléstől vagy hőmérséklettől függő gépeknél",
"anti_wrinkle_enabled": "Nyelje el a fő fázis utáni szárítópulzusokat, ahelyett hogy új ciklusként olvasná őket",
"anti_wrinkle_exit_power": "A ránctalanítás aktívan tartásához a teljesítménynek az impulzusok között ez alá kell csökkennie",
"anti_wrinkle_idle_timeout": "Két szárítópulzus között engedélyezett csendes idő, mielőtt a ránctalanítás véget ér",
@@ -1955,6 +2028,10 @@
"finished": "A ciklus elérte a végállapotot és befejeződött."
},
"store": {
"your_model_tip": "Ez az a készülék, amelyet a Beállításokban megadott",
"your_model": "Az Öné",
"search_brand_ph": "Keresés márka szerint…",
"programs_count": "Programok: {n}",
"browse": "Böngészés",
"device": "Készülék",
"favorites": "Kedvencek",
@@ -78,9 +78,12 @@
"awaiting": "Bíður samþykkis",
"imported_tip": "Flutt inn úr samfélagsversluninni. Aðeins notað til samsvörunar, ekki talið með í tölfræði.",
"not_importable": "ekki hér",
"exists": "til staðar"
"exists": "til staðar",
"backfilled_tip": "Greint í innfluttri aflsögu. Hefur aðeins áhrif á kerfissamsvörun, telst ekki með í tölfræði."
},
"btn": {
"set_brand_model": "Stilla vörumerki og gerð",
"refresh_catalog": "Endurnýja skrána",
"add_device": "+ Bæta við tæki",
"add_device_tip": "Bættu við öðru WashData tæki",
"add_maintenance": "Bæta við viðhaldsatburði",
@@ -90,7 +93,7 @@
"apply_label": "Notaðu merki",
"apply_set_b": "Beita stillingum B",
"apply_split": "Notaðu Split",
"apply_trim": "Notaðu Trim",
"apply_trim": "Beita klippingu",
"auto_detect_split": "Sjálfvirk skynjun",
"auto_label_cycles": "Sjálfvirk merkingarlotur",
"auto_label_cycles_tip": "Úthlutaðu sjálfkrafa prófílnöfnum á ómerktar lotur þar sem samsvörunaröryggi nær þröskuldinum",
@@ -133,7 +136,7 @@
"new_group_tip": "Flokkaðu næstum eins snið (söm lögun/lengd, mismunandi hitastig eða snúningur) svo samsvörun velji áreiðanlega á milli þeirra",
"new_phase": "+ Nýr áfangi",
"new_profile": "+ Nýtt snið",
"new_profile_tip": "Búðu til nýjan forritaprófíl úr núverandi merktri lotu eða upptöku",
"new_profile_tip": "Búðu til nýjan prófíl fyrir kerfi úr núverandi merktri lotu eða upptöku",
"on_cycle_finished": "Á hringrás lokið",
"on_cycle_started": "Á hringrás byrjaði",
"pause_cycle": "Gera hlé",
@@ -209,8 +212,8 @@
"stop": "Stöðva",
"submit_correction": "Sendu leiðréttingu",
"train_now": "Þjálfa núna",
"trim": "Snyrta",
"trim_split": "Snyrta / Kljúfa",
"trim": "Klippa til",
"trim_split": "Klippa til / Skipta",
"undo": "Afturkalla",
"use": "Notaðu",
"wipe_all": "Þurrkaðu öll gögn",
@@ -241,7 +244,12 @@
"import_selected": "Flytja inn valið",
"back": "Til baka",
"mute_suggestion": "Hætta að stinga upp á þessari stillingu",
"reset_muted": "Endurstilla þaggaðar tillögur"
"reset_muted": "Endurstilla þaggaðar tillögur",
"import_power_history": "Flytja inn aflsögu",
"hist_read_recorder": "Lesa úr Home Assistant",
"hist_scan": "Leita að lotum",
"hist_import_n": "Flytja inn {n} lotur",
"hist_goto_cycles": "Sýndu mér loturnar"
},
"conflict": {
"anti_wrinkle_exit": {
@@ -253,12 +261,12 @@
"start": "Verður að vera undir Hám. hrukkuleys-afli ({max} W)"
},
"attn_sub": "Lagaðu árekstra áður en þú vistar",
"attn_title": "{n} stillingarárekstur{s}",
"attn_title": "Árekstrar í stillingum: {n}",
"confidence": {
"auto": "Verður að vera við eða yfir Samsvarþröskuldi ({match})",
"learning": "Verður að vera við eða undir Samsvarþröskuldi ({match})",
"learning": "Verður að vera við eða yfir Samsvarþröskuldi ({match})",
"match_for_auto": "Verður að vera við eða undir Sjálfvirkri merkingaöryggi ({alc})",
"match_for_learning": "Verður að vera við eða yfir Námsöryggi ({lc})"
"match_for_learning": "Verður að vera við eða undir Námsöryggi ({lc})"
},
"duration_ratio": {
"max": "Verður að vera meira en Lágm. lengdarhlutfall ({min})",
@@ -296,14 +304,14 @@
"match": "Verður að vera yfir Ósamsvarþröskuldi ({un})",
"unmatch": "Verður að vera undir Samsvarþröskuldi ({match}); annars er staðfest samsvörun afturkölluð samstundis"
},
"cascade_toast": "Einnig var {n} stilling{s} leiðrétt til samræmis.",
"cascade_toast": "Aðrar stillingar leiðréttar til samræmis: {n}",
"suggestion_resolves": "Notaðu tillöguna hér að neðan ({val}) til að laga þetta",
"use_fix": "Nota {val}",
"watchdog": {
"interval": "Ætti að vera að minnsta kosti 2x Sýnitakabil ({si} s)",
"sampling": "Sýnitakabil ætti að vera í mesta lagi helmingur Gæsluabils ({wi} s)"
},
"settings_banner": "{n} stillingarárekstur{s} skoðaðu auðkenndu hlutana og lagaðu þá áður en þú vistar.",
"settings_banner": "Árekstrar í stillingum: {n}. Skoðaðu auðkenndu hlutana og lagaðu þá áður en þú vistar.",
"settings_banner_btn": "Fara á fyrsta"
},
"hdr": {
@@ -331,7 +339,7 @@
"manual_recording": "Handvirk upptaka",
"manual_recording_tip": "Keyrðu lotu af ásettu ráði á meðan WashData skráir aflsporið. Smelltu á Byrjaðu upptöku rétt áður en tækið ræsist, Hættu þegar því lýkur, og síðan Ferli til að vista það sem nafngreint snið.",
"ml_learned": "Það sem WashData hefur lært",
"ml_matching_tuning": "Fínstilling í samræmi við forrit",
"ml_matching_tuning": "Fínstilling kerfissamsvörunar",
"ml_settings_card": "Stillingar",
"ml_smart_learning": "Snjallt nám",
"my_preferences": "Mínar óskir",
@@ -356,7 +364,8 @@
"pg_outcome": "Niðurstaða hermunar",
"pg_across_cycles": "Yfir lotur þínar",
"community_store": "Samfélagsverslun",
"online_account": "Samfélagsverslun og nettengdir eiginleikar"
"online_account": "Samfélagsverslun og nettengdir eiginleikar",
"import_power_history": "Flytja inn aflsögu"
},
"health": {
"fair": "Viðunanlegt prófíl",
@@ -364,6 +373,7 @@
"poor": "⚠ Léleg samsvörun"
},
"lbl": {
"drag_to_resize": "Dragðu til að breyta stærð",
"actions": "Aðgerðir",
"activity": "Virkni",
"administrators": "Stjórnendur",
@@ -434,7 +444,7 @@
"from": "Frá",
"gap_s": "Bil (s)",
"group_name": "Nafn flokks",
"head_trim": "Snyrta upphaf (s)",
"head_trim": "Klippt framan af (s)",
"health": "Heilsa",
"hide_tabs": "Fela flipa fyrir ekki stjórnendur",
"in_use": "Í notkun",
@@ -450,7 +460,7 @@
"metric": "Mæligildi",
"mode_existing_profile": "Bæta við núverandi prófíl",
"mode_new_profile": "Búðu til nýjan prófíl",
"models_fine_tuned": "({count} módel{plural} fínstillt)",
"models_fine_tuned": "(fínstillt líkön: {count})",
"n_classic_suggestions": "{n} klassískt",
"n_ml_suggestions": "{n} ML",
"n_selected": "{n} valin",
@@ -489,11 +499,11 @@
"pg_poor_match": "Léleg samsvörun",
"pg_strong_match": "Sterk samsvörun",
"pg_tile_ambiguous": "Óljóst",
"pg_tile_ambiguous_tip": "Lotur þar sem tvö forrit eru næstum jöfn",
"pg_tile_ambiguous_tip": "Lotur þar sem tvö kerfi eru næstum jöfn",
"pg_tile_detected": "Greint",
"pg_tile_detected_tip": "Lotur þar sem afl fór yfir upphafsþröskuldinn nógu lengi til að skrást sem í gangi",
"pg_tile_matched": "Samsvarað",
"pg_tile_matched_tip": "Lotur sem eru rétt tengdar við þekkt forrit",
"pg_tile_matched_tip": "Lotur sem eru rétt tengdar við þekkt kerfi",
"pg_time_left": "Tími eftir",
"pg_weak_match": "Veik samsvörun",
"phase_name": "Nafn",
@@ -502,8 +512,8 @@
"profile": "Prófíll",
"profile_index": "sniðnúmer →",
"profile_name": "Nafn prófíls",
"program": "Forrit",
"program_tip": "Hnekktu því sniði sem er samsvarað við núverandi hringrás. Sjálfvirk greining lætur samþættinguna velja bestu samsvörun sjálfkrafa. Festtu ákveðið forrit til að þvinga samsvörun þegar sjálfvirk greining er röng eða þú veist hvað er að keyra.",
"program": "Kerfi",
"program_tip": "Hnekktu því sniði sem samsvarar núverandi lotu. Sjálfvirk greining lætur samþættinguna velja bestu samsvörun sjálfkrafa. Festu ákveðið kerfi til að þvinga samsvörun þegar sjálfvirk greining er röng eða þú veist hvað er í gangi.",
"progress": "Framfarir",
"raw_socket": "Hrár tengi",
"read_only": "Eingöngu lesin",
@@ -537,7 +547,7 @@
"stage3": "Þrep 3 DTW",
"stage4": "Þrep 4 samræmi",
"status": "Staða",
"tail_trim": "Snyrta enda (s)",
"tail_trim": "Klippt aftan af (s)",
"timer_auto_pause": "Sjálfvirk hlé",
"timer_min": "mín",
"timer_msg_placeholder": "Skilaboð (valfrjálst, {device}/{program}/{minutes})",
@@ -652,7 +662,7 @@
"task_trim": "Klippi lotu til",
"task_merge": "Sameina lotur",
"task_rebuild": "Endurreikna aflhjúpa",
"cat_profiles": "Prófílar (forrit)",
"cat_profiles": "Prófílar (kerfi)",
"cat_real_cycles": "Lotur (keyrslusaga)",
"cat_reference_cycles": "Viðmiðunarlotur (innfluttar)",
"cat_custom_phases": "Sérsniðnir fasar",
@@ -677,7 +687,26 @@
"conflict_keep_mine": "Halda mínum",
"conflict_overwrite": "Skrifa yfir",
"pg_anti_wrinkle": "Hrukkuleysi",
"font_size": "Leturstærð glugga"
"font_size": "Leturstærð glugga",
"hist_csv_data": "CSV-gögn",
"hist_from_recorder": "Eða lestu hana úr Home Assistant",
"hist_since": "Síðan",
"days": "dagar",
"hist_keep": "Halda þessari lotu",
"hist_looks_complete": "fullgerð",
"peak_power_short": "Toppur",
"shape": "Lögun",
"hist_skip_idle": "ekkert í gangi",
"hist_skip_sparse": "of langt á milli mælinga",
"hist_skip_short": "of fáar mælingar",
"hist_skip_long": "ekkert hlé nógu langt til að skipta á",
"hist_reason_short": "styttri en stysta raunverulega lota þessa heimilistækis",
"hist_reason_no_end": "lauk aldrei með eðlilegum hætti",
"task_history_import": "Skanna aflsögu",
"task_history_import_apply": "Flyt inn lotur",
"evidence_real_cycles": "Lotur sem þessi vél hefur keyrt",
"evidence_reference_cycles": "Hlaðnar niður úr samfélagsversluninni",
"evidence_backfill_cycles": "Fundnar í innfluttri aflsögu"
},
"log": {
"all_levels": "Öll stig",
@@ -756,9 +785,15 @@
"store_share": "Deila í samfélagsverslun",
"store_share_device": "Deila þessu tæki",
"export_select": "Útflutningur - velja gögn",
"import_wizard": "Innflutningur - velja gögn"
"import_wizard": "Innflutningur - velja gögn",
"history_import": "Flytja inn aflsögu"
},
"msg": {
"tail_trim_hint": "Fjarlægðu þennan fjölda sekúndna frá lokum",
"store_sibling_hint": "Er engu deilt fyrir nákvæmlega þína gerð? Náskyld gerð frá sama vörumerki er oftast góður upphafspunktur.",
"store_declare_appliance": "Segðu WashData hvaða tæki þú átt, þá sýnir þessi flipi þær uppsetningar sem aðrir hafa deilt fyrir það. Þú getur líka slegið inn vörumerki hér fyrir ofan til að skoða þig um.",
"refresh_catalog_hint": "Listar samfélagsins yfir vörumerki og tæki eru vistaðir í skyndiminni til að samfélagsverslunin haldi sig innan daglegra marka. Endurnýjaðu til að fá færslur sem aðrir hafa bætt við eða samþykkt.",
"head_trim_hint": "Fjarlægðu þennan fjölda sekúndna frá byrjun",
"appliance_monitor": "Vöktunartæki",
"artifact_dip_detail": "Féll undir venjulegt aflband í ~{n}s.",
"artifact_footer": "Auðkenndur á grafinu hér að ofan. Þetta eru skammvinnir gripir (t.d. hurðin opnuð í miðjum lotu), ekki endilega vandamál.",
@@ -769,7 +804,7 @@
"automations_intro": "WashData sendir {start} / {end} atburði og birtir einingar, þannig að tilkynningar og aðgerðir eru best smíðaðar sem venjulegar Home Assistant sjálfvirkingar. Sjálfvirkingar sem nota þetta tæki birtast hér að neðan.",
"cleanup_intro": "Sérhver merkt hringrás lögð yfir. Merktu við frávik og eyddu til að hreinsa upp prófílinn.",
"clear_debug_hint": "Fjarlægðu vistuð villuleitargögn til að losa um pláss.",
"collecting_data": "Safnar gögnum: {need} lota{plural} til viðbótar áður en fínstilling getur hafist ({current}/{min}).",
"collecting_data": "Safnar gögnum. Lotur sem vantar áður en fínstilling getur hafist: {need} ({current}/{min}).",
"compare_overlay_profiles": "Yfirlagssnið (dauft)",
"compare_profiles_tip": "Leggðu önnur prófílumslög yfir á töfluna hér að ofan til að sjá hver þeirra passar best við þessa lotu.",
"compare_selected_cycles": "Valdar lotur (fastar) sýna / fela",
@@ -779,11 +814,11 @@
"cycles_deleted": "{count} lotu(m) eytt",
"enough_data": "Nóg gögn til að læra af ({current}/{min} lotur).",
"export_description": "Veldu nákvæmlega hvaða prófíla, lotur, stillingar og fleira á að flytja út í JSON, eða greindu skrá og fluttu aðeins inn þá hluta sem þú vilt.",
"feedback_cycles_pending": "{n} lota{s} til yfirferðar",
"feedback_prompt": "Staðfestu að það ri rétt, leiðréttu forritið eða hunsa.",
"feedback_cycles_pending": "Til yfirferðar: {n}",
"feedback_prompt": "Staðfestu að það hafi verið rétt, leiðréttu kerfið eða hunsaðu.",
"feedback_relabel_hint": "Að endurmerkja þessa lotu lýkur einnig yfirferðinni.",
"filter_by_profile": "Sía eftir prófíl…",
"group_modal_help": "Flokkaðu forrit með sömu lögun sem eru mismunandi hvað varðar hitastig/snúning (lengd getur verið mismunandi). Samsvörun skorar hópinn sem einn frambjóðanda og velur síðan þann sem hentar best. Veldu að minnsta kosti 2; yfirlagið sýnir hversu lík þau eru.",
"group_modal_help": "Flokkaðu kerfi með sömu lögun sem eru mismunandi hvað varðar hitastig/snúning (lengd getur verið mismunandi). Samsvörun gefur hópnum eina einkunn og velur síðan þann meðlim sem passar best. Veldu að minnsta kosti 2; yfirlagið sýnir hversu lík þau eru.",
"group_not_cohesive": "Þessir snið eru ekki nógu lík til að hópa á áreiðanlegan hátt, þannig að samsvörun meðhöndlar þá hver fyrir sig þar til þú fjarlægir frávikið eða skiptir hópnum.",
"group_preview_hint": "Merktu 2+ meðlimi til að forskoða og bera saman aflferla þeirra.",
"import_intro": "Hlaðið út útfluttri skrá eða límdu JSON-hleðslu fyrir neðan.",
@@ -799,14 +834,14 @@
"maintenance_load_error": "Ekki tókst að hlaða viðhaldsgögnum: {error}",
"maintenance_requires_access": "Viðhald og útflutningur/innflutningur krefjast fulls aðgangs.",
"manual_duration_hint": "Meðaltal/vænt hringrásarlengd sniðsins, notuð fyrir tíma sem eftir er. Breyta til að stilla það; ef það er óbreytt heldur núverandi gildi.",
"matching_tuning_intro": "Þegar þú lærir, stillir WashData einnig hversu mikið forritasamsvörun vegur lögun á móti lengd og orku.",
"matching_tuning_intro": "Þegar WashData lærir stillir það einnig hversu mikið kerfissamsvörun vegur lögun á móti lengd og orku.",
"merge_intro": "Valdar lotur eru sameinaðar í eina (tímaröð; eyður fyllt með 0 W). Veldu prófílinn sem myndast.",
"ml_intro": "WashData er sent með snjöllum gerðum sem vinna úr kassanum.",
"ml_learned_intro": "Módel fínstillt að þessari vél.",
"ml_loading": "hleður ML…",
"ml_settings_intro": "Tveir óháðir rofar: annar notar gerðir á meðan hringrás er í gangi, hinn gerir WashData kleift að fínstilla þær að vélinni þinni með tímanum.",
"name_first_program": "Þú ert með nægar lotur gefðu fyrsta prógramminu nafn til að hefja samsvörun.",
"near_duplicate_cluster": "næstum tvítekinn prófílklasi fannst. Flokkun gerir samsvörun kleift að velja áreiðanlega á milli útlita (t.d. sama forritið við mismunandi hitastig/snúning).",
"near_duplicate_cluster": "næstum tvítekinn prófílklasi fannst. Flokkun gerir samsvörun kleift að velja áreiðanlega á milli þeirra sem líkjast hver öðrum (t.d. sama kerfið við mismunandi hitastig/snúning).",
"no_cycles_match": "Engar lotur passa við núverandi síu.",
"no_cycles_profile": "Engar lotur fyrir þetta snið.",
"no_cycles_selected": "Veldu að minnsta kosti eina lotu fyrst.",
@@ -856,7 +891,6 @@
"pg_stress_synthetic": "aðgerðalaus hermun hefst hér",
"pg_sweep_intro": "Hvað ef {param} væri öðruvísi? Prófaðu {steps} gildi yfir síðustu {cycles} loturnar þínar til að finna stillinguna þar sem flestar lotur samsvarast rétt.",
"pg_sweep_step": "Skref {done} / {total}",
"pg_undetected": "{n} lota{s} ógreind",
"pg_verdict_bad": "Þarfnast athygli: margar lotur greinast ekki.",
"pg_verdict_good": "Vel stillt: flestar lotur eru rétt greindar og samsvaraðar.",
"pg_verdict_ok": "Ásættanlegt: sumar lotur misstust. Prófaðu að lækka upphafsþröskuldinn.",
@@ -870,7 +904,7 @@
"process_history_hint": "Keyra samsvörun aftur á öllum geymdum lotum, uppfæra fínstillingartillögur, þjálfa ML módel aftur (ef virkt) og endurreikna heilsu lotu. Keyrðu þetta eftir hóp yfirfarna.",
"profile_deleted": "Sniði eytt",
"profile_poor_health_detail": "Hringrásir sem eru úthlutaðar á þetta snið hafa ósamræmda lögun eða lítið öryggi. Íhugaðu að endurbyggja umslagið eða endurskoða merktar lotur.",
"profiles_intro": "Smelltu á prófíl fyrir tölfræði, áfanga og hreinsun. Flokkaðu næstum eins forrit (sama lögun/lengd, mismunandi hitastig eða snúningur) þannig að þú velur á áreiðanlegan hátt á milli þeirra.",
"profiles_intro": "Smelltu á prófíl fyrir tölfræði, áfanga og hreinsun. Flokkaðu næstum eins kerfi (sama lögun/lengd, mismunandi hitastig eða snúningur) þannig að samsvörun velji áreiðanlega á milli þeirra.",
"rbac_hint": "Þegar slökkt er á því hefur hver Home Assistant notandi fullan aðgang (sjálfgefið). Stjórnendur hafa alltaf fullan aðgang og geta stjórnað öllum.",
"recent_logs": "Nýlegar ha_washdata færslur",
"recording_in_progress": "Upptaka í gangi",
@@ -882,11 +916,12 @@
"review_in_settings": "Skoðaðu í stillingum",
"review_notes_placeholder": "Skýringar (valfrjálst)",
"review_notes_tip": "Skýringar með frjálsum texta til eigin viðmiðunar. Ekki notað við samsvörun eða þjálfun.",
"review_profile_tip": "Forritið sem þessi lota er merkt sem. Ef sjálfvirkt greind forrit var rangt skaltu leiðrétta það hér - merking kennir samsvörun fyrir framtíðarlotur.",
"review_quality_tip": "Hversu hreinn þessi hringrás er. Gott = kennslubókardæmi um þetta forrit; Slæmt = greinist en hávær eða óhefðbundin; Ónothæft = rangt greint (sameinað, stytt eða falsað). Keyrir heilsustigið og hvaða lotur eru leyfðar til að þjálfa líkanið.",
"review_recorded_tip": "Merktu þetta sem handvalna viðmiðunarlotu fyrir forritið sitt - sama hlutverk og handvirkt skráð lota. Viðmiðunarlotum er alltaf haldið, sáð samsvarandi sniðmát og er aldrei sleppt við hreinsun. (Þetta er „gyllti“/skráður fáninn; báðir eru það sama.)",
"review_profile_tip": "Kerfið sem þessi lota er merkt sem. Ef sjálfvirkt greint kerfi var rangt skaltu leiðrétta það hér - merking kennir samsvöruninni fyrir framtíðarlotur.",
"review_quality_tip": "Hversu hrein þessi lota er. Gott = kennslubókardæmi um þetta kerfi; Slæmt = greinist en hávaðasöm eða óhefðbundin; Ónothæft = rangt greint (sameinað, stytt eða falsað). Stýrir heilsustiginu og því hvaða lotur má nota til að þjálfa líkanið.",
"review_recorded_tip": "Merktu þetta sem handvalda viðmiðunarlotu fyrir kerfið sem hún tilheyrir - sama hlutverk og handvirkt skráð lota. Viðmiðunarlotum er alltaf haldið, þær móta samsvörunarsniðmát og þeim er aldrei sleppt við hreinsun. (Þetta er „gyllti“/skráði fáninn; hvort tveggja er það sama.)",
"review_tags_tip": "Valfrjálsir fánar sem lýsa því sem fór úrskeiðis við þessa lotu, svo þjálfun og hreinsun getur gert grein fyrir því.",
"review_to_cycles": "Opnaðu Cycles review biðröðina",
"samples_decimated": "Sýnir {shown} af {total} sýnum (grisjað fyrir birtingu; toppum haldið). Breið eyða hér stafar af grisjun, ekki af gögnum sem vantar.",
"saving_triggers_reload": "Vistun kallar á endurhleðslu samþættingar. HA einingar gætu sýnt stuttlega sem ófáanlegur.",
"search_placeholder": "Leitarstillingar...",
"see_recorder": "Sjá upptökugræju hér að neðan",
@@ -913,7 +948,7 @@
"toast_name_required": "Nafn er krafist",
"toast_no_automation": "Get ekki búið til sjálfvirkni hér",
"toast_profile_name_required": "Nafn sniðs er krafist",
"toast_program_set": "Forrit stillt: {program}",
"toast_program_set": "Kerfi stillt: {program}",
"toast_rebuild_failed": "Endurgerð mistókst: {error}",
"toast_resume_failed": "Haldið áfram mistókst: {error}",
"toast_revert_failed": "Endurstilling mistókst: {error}",
@@ -924,14 +959,14 @@
"trend_energy_down": "Orka á niðurleið ({pct}%/lotu)",
"trend_energy_up": "Orka hækkar ({pct}%/lotu) nýleg meðaltal {avg}",
"trim_destructive_confirm": "Aðeins {pct}% af lotunni verður eftir. Þetta er ekki hægt að afturkalla. Halda áfram?",
"trim_intro": "Dragðu rauðu handföngin eða sláðu inn gildi. Allt fyrir utan gluggann er fjarlægt.",
"trim_intro": "Dragðu rauðu handföngin eða sláðu inn gildi. Allt utan valda tímabilsins er fjarlægt.",
"tuning_suggestions_available": "{count} uppástunga að stilla í boði frá athuguðum lotum. Þau birtast við hlið viðkomandi reita.",
"unsure_detected_prefix": "WashData er ekki viss um að það hafi fundist",
"updated": "Uppfært",
"warmup_badge": "Enn að læra ({done}/{needed} lotur)",
"warmup_detail": "Þessi prófíll þarfnast {needed} merktra lota áður en sjálfvirk samsvörun hefst. Sérhver staðfest lota hjálpar honum að læra.",
"wipe_history_warning": "Eyða öllum lotum og sniðum varanlega. Ekki hægt að afturkalla.",
"compare_overlay_tip": "Leggðu lærð aflsvið prófíla yfir hvert annað til að sjá hvaða forriti hver lota líkist.",
"compare_overlay_tip": "Leggðu lærð aflsvið prófíla yfir hvert annað til að sjá hvaða kerfi hver lota líkist.",
"duration_trend_up_tip": "Lengd eykst ({pct}%/lotu)",
"duration_trend_down_tip": "Lengd minnkar ({pct}%/lotu)",
"energy_trend_up_tip": "Orka eykst ({pct}%/lotu)",
@@ -982,34 +1017,57 @@
"connect_to_confirm": "Tengstu í stillingatannhjólinu til að staðfesta eða gefa einkunn.",
"adopt_settings_hint": "Skrifar yfir greiningar- og samsvörunarmörk þessa tækis með deildum. Tilkynningar þínar, einingar og orkuverð breytast aldrei.",
"include_settings_hint": "Deilir greiningar- og samsvörunarmörkum þessa tækis (ekki tilkynningar, einingar eða orkuverð). Notendur velja sjálfir hvort þeir vilji nota þær.",
"onboard_download": "Nýtt tæki? Taktu yfir tilbúna uppsetningu (forrit, viðmiðunarlotir og fasar) frá öðrum WashData-notanda með sama tæki.",
"onboard_download": "Nýtt tæki? Taktu yfir tilbúna uppsetningu (kerfi, viðmiðunarlotur og fasa) frá öðrum WashData-notanda með sama tæki.",
"share_consent": "Ég staðfesti að þessar lotir voru kláraðar eðlilega án truflana",
"share_device_none": "Engar deilanlegar lotir enn. Merktu fyrst skráða eða handvalda lotu sem viðmiðunarlotu (⭐) í flipanum Lotir.",
"share_guideline_naming": "Gefðu hverjum prófíl nákvæmlega það nafn sem sést á hringtakkanum eða skjánum tækisins (t.d. 'Cotton 40', 'Eco 60').",
"share_guideline_quality": "Deildu aðeins lotum sem kláruðust eðlilega -- engar truflanir á miðjum lotu, opnaðar hurðir eða aflbrostir.",
"share_guideline_review": "Upphleðslan þín byrjar sem í bið og birtist opinberlega þegar nægilega margir samfélagsmeðlimir staðfesta hana.",
"share_guidelines_title": "Áður en þú deilir",
"store_download_device_intro": "Taktu yfir öll deildu forritin og viðmiðunarlotir þeirra á tækið þitt. Þínar eigin skráðar lotir og tölfræði eru ekki fyrir áhrifum.",
"store_share_device_intro": "Hlaðaðu upp {brand} {model} með viðmiðunarlotum sem þú velur. Aðrir með sama tæki geta tekið yfir forritin þín. Færslur eru yfirfarnar áður en þær birtast opinberlega.",
"store_download_device_intro": "Taktu yfir öll deildu kerfin og viðmiðunarlotur þeirra á tækið þitt. Þínar eigin skráðu lotur og tölfræði verða ekki fyrir áhrifum.",
"store_share_device_intro": "Hlaðaðu upp {brand} {model} með viðmiðunarlotunum sem þú velur. Aðrir með sama tæki geta tekið yfir kerfin þín. Færslur eru yfirfarnar áður en þær birtast opinberlega.",
"share_profile_no_cycles": "Engar viðmiðunarlotir -- merktu lotu sem ⭐ í flipanum Lotir til að hafa þennan prófíl með",
"advisory_phase_inconsistent": "'{name}' virðist blanda saman ólíkum forritum eða hitastigum - lotur þess hita mislengi. Ef þú skiptir því upp í aðskilin snið (t.d. eftir hitastigi) batnar samsvörun og tímamat.",
"advisory_phase_inconsistent_title": "⚠ Hugsanlega blönduð forrit",
"export_select_intro": "Merktu nákvæmlega við hvað á að hafa með. Að velja prófíla án lotanna þeirra flytur samt út greinanlegt forrit (lærði ferillinn fylgir með).",
"advisory_phase_inconsistent": "'{name}' virðist blanda saman ólíkum kerfum eða hitastigum - lotur þess hita mislengi. Ef þú skiptir því upp í aðskilin snið (t.d. eftir hitastigi) batnar samsvörun og tímamat.",
"advisory_phase_inconsistent_title": "⚠ Hugsanlega blönduð kerfi",
"export_select_intro": "Merktu nákvæmlega við hvað á að hafa með. Að velja prófíla án lotanna þeirra flytur samt út kerfi sem hægt er að samsvara (lærða lögunin fylgir með).",
"import_analyze_hint": "Hladdu inn útfluttri skrá (eða límdu inn JSON-ið hennar). WashData greinir hana og sýnir nákvæmlega hvað er hægt að flytja inn áður en nokkuð breytist.",
"analyzing": "Greini…",
"device_type_mismatch_warn": "Þessi útflutningur er frá annarri tegund tækis ({src} á móti {local}). Enn er hægt að flytja inn forrit og lotur sem viðmiðunargögn, en tækjabundnar stillingar og innflutningur á raunverulegri sögu eru óvirk.",
"device_type_mismatch_warn": "Þessi útflutningur er frá annarri tegund tækis ({src} á móti {local}). Enn er hægt að flytja inn kerfi og lotur sem viðmiðunargögn, en tækjabundnar stillingar og innflutningur á raunverulegri sögu eru óvirk.",
"merge_hint": "Innfluttum atriðum er bætt við; ekkert staðbundið tapast. Nafnaárekstrar eru leystir hér að neðan.",
"replace_warn": "Hver valinn flokkur er hreinsaður og settur í staðinn úr skránni. Óvaldir flokkar haldast óbreyttir.",
"dest_reference_hint": "Innfluttar lotur bæta aðeins forritasamsvörun og hafa aldrei áhrif á notkunar-/orkutölfræði.",
"dest_reference_hint": "Innfluttar lotur bæta aðeins kerfissamsvörun og hafa aldrei áhrif á notkunar-/orkutölfræði.",
"dest_real_history_hint": "Innfluttar lotur teljast sem eigin saga þessa tækis og fæða orku-/notkunartölfræði. Notaðu þetta til að flytja eitt tæki yfir í nýja uppsetningu.",
"sug_muted": "Mun ekki stinga upp á þessari stillingu aftur",
"sug_mute_failed": "Gat ekki þaggað tillögu",
"sug_unmuted_all": "Þaggaðar tillögur endurstilltar",
"n_suggestions_muted": "{count} þaggaðar; sjálfvirki stillirinn leggur ekki til þessar.",
"font_size_hint": "Gerðu allt á þessum glugga stærra eða minna. Gildir fyrir reikning þinn á þessum tæki."
"font_size_hint": "Gerðu allt á þessum glugga stærra eða minna. Gildir fyrir reikning þinn á þessum tæki.",
"import_history_description": "Varstu þegar með snjalltengil áður en þú fékkst WashData? Hlaðdu upp söguútflutningi frá aflmælinum hans, eða láttu lesa hana beint úr Home Assistant, og venjuleg greining fer yfir hana svo eldri lotur birtast í Hringrásir-listanum þínum, tilbúnar til að fá heiti.",
"hist_input_hint": "Hlaðdu upp CSV-skrá sem þú hlóðst niður úr Saga-spjaldinu (eining, staða, síðast breytt), eða láttu WashData lesa sögu mælisins beint. Greiningin fer svo yfir hana alveg eins og í beinni, og þú velur hvaða lotur á að halda af þeim sem finnast.",
"hist_recorder_hint": "Les frá þeirri dagsetningu sem þú velur og fram til nú. Home Assistant heldur nákvæmri sögu í 10 daga sjálfgefið og eftir það aðeins klukkustundarmeðaltölum, sem eru of grófgerð til að greina lotur úr - veldu dagsetningu lengra aftur í tímann aðeins ef recorder er stilltur á að geyma meira.",
"hist_scanning": "Sagan þín er spiluð í gegnum greininguna. Þetta gengur í bakgrunni - þú getur lokað þessum glugga og komið til baka síðar.",
"hist_imported_count": "{n} lotur fluttar inn.",
"hist_duplicates": "{n} voru þegar fluttar inn og var sleppt.",
"hist_capped": "Hámarki innfluttra lota fyrir hvert tæki var náð; það sem eftir stóð var ekki vistað.",
"hist_next_step": "Þær eru í Hringrásir-listanum þínum, merktar sem innflutt saga. Opnaðu eina og notaðu Merki til að gefa kerfinu sem hún tilheyrir heiti.",
"hist_rows_read": "{n} mælingar lesnar",
"hist_entity_substituted": "las {used} (þetta tæki er stillt á {wanted})",
"hist_breaks": "{n} göt þar sem mælirinn var ekki tiltækur",
"hist_other_entity": "{n} mælingum fyrir aðrar einingar var sleppt",
"hist_skipped_spans": "Bil sem var sleppt",
"hist_settings_used": "Greint með núverandi stillingum þessa tækis (lágmarksafl {w} W, slökkviðráð {s} s).",
"hist_none_found": "Engar lotur greindust í þeirri sögu.",
"hist_found": "Fann {n} lotur. Taktu hakið af öllu sem lítur ekki út eins og raunveruleg keyrsla - ekkert er vistað fyrr en þú flytur inn.",
"hist_scan_capped": "Aðeins fyrstu lotutillögurnar eru sýndar ({n} fundust).",
"hist_recorder_empty": "Home Assistant hefur enga nákvæma sögu fyrir þennan mæli á því tímabili.",
"hist_scan_failed": "Skönnun mistókst.",
"hist_scan_expired": "Sú skönnun er ekki lengur tiltæk. Skannaðu aftur.",
"hist_import_failed": "Innflutningur mistókst.",
"imported_history_readonly": "Greint í innfluttri aflsögu. Hún hefur áhrif á kerfissamsvörun en telst ekki með í tölfræðinni þinni og ekki er hægt að klippa hana til eða skipta henni. Merktu hana til að gefa kerfinu heiti."
},
"pg_desc": {
"dishwasher_end_spike_quiet_release": "Uppþvottavél: hljóðlátar sekúndur eftir áætlaða lengd áður en biðin eftir útdælingu í lok lotu er losuð",
"smart_termination_duration_ratio": "Hlutfall af væntanlegri lengd samsvaraða kerfisins sem lota þarf að ná áður en snjöll lokun má ljúka henni snemma; lækkaðu það fyrir álags- eða hitaháðar vélar",
"completion_min_seconds": "Stysta keyrsla sem telst raunveruleg lota",
"end_repeat_count": "Lágir álestrar í röð áður en lýkur",
"interrupted_min_seconds": "Stuttar lotur merktar sem truflaðar",
@@ -1154,11 +1212,11 @@
"label": "Hám. hrukkuleys-afl"
},
"auto_label_confidence": {
"doc": "Ef leikskor í lok lotu er við eða yfir þessu er forritið merkt sjálfkrafa án staðfestingar. Hækka það til að krefjast meiri vissu fyrir sjálfvirka merkingu; lækka það til að gera sjálfvirkan meira. Virkar í tengslum við Learning Confidence fyrir neðan það.",
"doc": "Ef samsvörunarskor í lok lotu er við eða yfir þessu er kerfið merkt sjálfkrafa án staðfestingar. Hækkaðu það til að krefjast meiri vissu fyrir sjálfvirka merkingu; lækkaðu það til að auka sjálfvirkni. Virkar í tengslum við „Námsöryggi“ hér fyrir neðan.",
"label": "Sjálfvirk merkingaöryggi"
},
"auto_maintenance": {
"doc": "Keyrðu næturþrif: endurbyggðu prófílumslög, endurreiknaðu heilsu hringrásarinnar, klipptu kembiforrit og geymdu nýjustu loturnar.",
"doc": "Keyrðu næturþrif: endurbyggðu aflsvið prófíla, endurreiknaðu heilsu lotanna, fjarlægðu kembiferla og geymdu nýjustu loturnar.",
"label": "Sjálfvirkt viðhald (næturþrif)"
},
"completion_min_seconds": {
@@ -1230,7 +1288,7 @@
"label": "Snúa ytri kveikin (kvikna á SLÖKKT)"
},
"learning_confidence": {
"doc": "Ef stigaskorið er á milli þessa og sjálfvirkrar merkingar sjálfstrausts, biður endurgjöfstilkynning þig um að staðfesta auðkennda forritið. Fyrir neðan þetta stig er leikurinn of óviss til að komast upp á yfirborðið. Verður að vera undir sjálfvirku merki sjálfstrausts.",
"doc": "Ef samsvörunarskorið fellur á milli þessa og „Sjálfvirk merkingaöryggi“ biður endurgjöfstilkynning þig um að staðfesta kerfið sem var auðkennt. Undir þessu skori er samsvörunin of óviss til að birta. Verður að vera lægra en „Sjálfvirk merkingaöryggi“.",
"label": "Námsöryggi"
},
"linked_device": {
@@ -1394,7 +1452,7 @@
"label": "Lágm. lengdarhlutfall"
},
"profile_match_threshold": {
"doc": "Lágmarks líkindisstig (0-1) sem krafist er í lok lotu til að samþykkja forritaauðkenni. Hækka það til að draga úr röngum auðkenningum; lækka það ef forrit vélarinnar þinnar eru ekki samræmd. Sjálfgefið 0.4 er íhaldssamt upphafspunktur.",
"doc": "Lágmarks líkindisstig (0-1) sem krafist er í lok lotu til að samþykkja auðkenningu kerfis. Hækkaðu það til að draga úr röngum auðkenningum; lækkaðu það ef kerfi vélarinnar þinnar ekki samsvörun. Sjálfgefið 0.4 er íhaldssamur upphafspunktur.",
"label": "Samsvarþröskuldur"
},
"profile_unmatch_threshold": {
@@ -1421,6 +1479,10 @@
"doc": "Geymdu fulla aflrekningu og samsvarandi villuleitargögn fyrir hverja lotu. Gagnlegt fyrir bilanaleit en eykur geymslustærð.",
"label": "Vista villuleitarspor"
},
"smart_termination_duration_ratio": {
"doc": "Hversu langt inn í væntanlega lengd samsvaraða kerfisins lota þarf að vera komin áður en snjöll lokun má ljúka henni snemma þegar aflið fellur. Væntanlega lengdin er meðaltal kerfisins, þannig að á tækjum þar sem keyrslutími er mjög breytilegur - þvottavélar með köldu inntaksvatni að vetri á móti heitu að sumri, þurrkarar með rakaskynjara, álagsháð kerfi - ljúka um það bil helmingur allra keyrslna styttri en það meðaltal og fá aldrei hina hröðu lokun, heldur ljúka fyrst mínútum síðar með vara-tímamörkunum. Lækkaðu þetta gildi (t.d. 0,85) á slíkum vélum svo að snemmbúna lokunin virkist samt; hækkaðu það í átt að 1,0 til að vera varkárari. Skildu eftir autt fyrir sjálfgefið gildi (0,98, eða 0,99 fyrir uppþvottavélar). Hún getur aðeins lokið lotu fyrr, aldrei síðar, og virkist aldrei við óljósa eða óörugga samsvörun.",
"label": "Hlutfall snjallrar lokunar"
},
"smoothing_window": {
"doc": "Hversu mikið hráorkumerkið er sléttað. Low (2) er móttækilegur en hávær; hár (5) sléttir toppa en bætir við töf.",
"label": "Jöfnunargluggi"
@@ -1434,7 +1496,7 @@
"label": "Ræsingaorka"
},
"start_threshold_w": {
"doc": "Afl verður að hækka yfir þetta stig til að staðfesta að hringrás hafi hafist. Ef það er stillt of lágt veldur rangræsingum frá biðstöðu; of há og hægt ræsandi forrit (köld fylling) missir. Tillöguvélin setur þetta rétt fyrir ofan lægsta virka afl vélarinnar.",
"doc": "Afl verður að hækka yfir þetta stig til að staðfesta að lota sé hafin. Of lág stilling veldur fölskum upphafsgreiningum frá biðstöðuafli; of há stilling lætur kerfi sem byrja hægt (köld fylling) fara fram hjá. Tillöguvélin setur þetta rétt fyrir ofan lægsta virka afl vélarinnar.",
"label": "Ræsingarþröskuldur"
},
"stop_threshold_w": {
@@ -1502,7 +1564,7 @@
},
"enable_phase_matching": {
"label": "Fasaskiptur tími sem eftir er",
"doc": "Skiptu hverri lotu í gangi upp í fasa (upphitun, þvottur, vinda) og áætlaðu tímann sem eftir er fyrir hvern fasa, blandað saman við klassíska matið - snemma í lotunni styðst það við fasaáætlunina og undir lokin við klassíska matið. Þetta sérsníður niðurtalninguna að því hversu lengi vélin þín hitar og gengur í raun, sem er mest áberandi í fyrri helmingi lotu. Slökkt = aðeins klassíska matið. Aðeins birting á tíma sem eftir er verður fyrir áhrifum; forritasamsvörun og lotugreining haldast óbreytt."
"doc": "Skiptu hverri lotu í gangi upp í fasa (upphitun, þvottur, vinda) og áætlaðu tímann sem eftir er fyrir hvern fasa, blandað saman við klassíska matið - snemma í lotunni styðst það við fasaáætlunina og undir lokin við klassíska matið. Þetta sérsníður niðurtalninguna að því hversu lengi vélin þín hitar og gengur í raun, sem er mest áberandi í fyrri helmingi lotu. Slökkt = aðeins klassíska matið. Aðeins birting á tíma sem eftir er verður fyrir áhrifum; kerfissamsvörun og lotugreining haldast óbreytt."
},
"keep_min_score": {
"label": "Lágm. samsvörunareinkunn",
@@ -1510,7 +1572,7 @@
},
"dtw_blend": {
"label": "DTW-blandning",
"doc": "Hversu mikið DTW-jöfnunarskorið kemur í stað kjarnaskorinnar frá Þrepi 2. 0 = notaðu aðeins Þreps 2 skor, 1 = notaðu aðeins DTW-skor, 0,5 (sjálfgefið) = jöfn blanda. Hækkið til að treystir meira á tímaröðun þegar forrit hafa svipaðar aflstigseiningar en ólík tímasetningarmynstur."
"doc": "Hversu mikið DTW-jöfnunarskorið kemur í stað kjarnaskorsins frá Þrepi 2. 0 = notaðu aðeins skor Þreps 2, 1 = notaðu aðeins DTW-skor, 0,5 (sjálfgefið) = jöfn blanda. Hækkaðu það til að treysta meira á tímajöfnun þegar kerfi hafa svip aflstig en ólík tímamynstur."
},
"dtw_ensemble_w": {
"label": "DTW-ensemble-blanda",
@@ -1551,6 +1613,10 @@
"door_end_dwell_seconds": {
"label": "Dvaltími hurðar við lok",
"doc": "Hversu lengi hurðin þarf að vera opin áður en WashData lýkur hringnum, þegar \"Hurð opnast sjálfkrafa í lok\" er virkt. Nógu lengi til að hunsa hraða tilbúningu fats (sjálfgefið 60 s), nógu stutt til að ljúka fljótt þegar vél spretter hurðinni upp."
},
"profile_evidence_sources": {
"label": "Lotur sem móta kerfi",
"doc": "Hvaða lotur eru notaðar til að byggja upp aflferil hvers kerfis og til að finna samsvörun við hann fyrir lokna lotu. Ef hakið er tekið af einni gerð hefur hún ekki lengur áhrif á kerfin þín, án þess að neinu sé eytt - loturnar verða áfram í Hringrásir-listanum þínum og enn má merkja þær eða fjarlægja. Gagnlegt ef þú treystir ekki innfluttum gögnum. Tölfræðin verður óbreytt: hún telur alltaf aðeins þær lotur sem þessi vél hefur í raun keyrt. Sé hakið tekið af öllu er það hunsað, því kerfi sem hefur engar lotur að baki gæti aldrei fundið samsvörun."
}
},
"setting_group": {
@@ -1634,6 +1700,9 @@
},
"basic_configuration": {
"label": "Grunnstillingar"
},
"profile_evidence": {
"label": "Grunnur sniða"
}
},
"status": {
@@ -1658,7 +1727,8 @@
"trimming": "Klippi til…",
"splitting": "Skipti…",
"deleting": "Eyði…",
"imported": "Flutt inn"
"imported": "Flutt inn",
"preparing": "Undirbý…"
},
"suggestion": {
"both_agree": "WashData mælir með",
@@ -1690,7 +1760,7 @@
"lower": "Stutt hlé nægir lotur á eftir hverri annarri kunna að skiptast"
},
"min_power": {
"higher": "Minna næmt fyrir biðstöðuafli mjög hljóð forrit kunna að gleymast",
"higher": "Minna næmt fyrir biðstöðuafli; mjög hljóðlát kerfi kunna að gleymast",
"lower": "Næmara biðstöðuafl gæti skráðst sem virkni"
},
"no_update_active_timeout": {
@@ -1711,7 +1781,7 @@
},
"start_threshold_w": {
"higher": "Forðast rangar ræsingar vegna stuttra aflhækkinga",
"lower": "Þekkir forrit með lágt afl gæti kviknaðu af hávaða"
"lower": "Þekkir kerfi með lágt afl; getur kviknað af hávaða"
},
"stop_threshold_w": {
"higher": "Lýkur lotu hraðar gæti kviknaður í hlé",
@@ -1754,7 +1824,7 @@
"thr_batch": "Haldið rétt yfir lægsta virka afli við p05 yfir {cycles} lotur ({p05}W) svo að ræsing náist eins snemma og hægt er og stöðvunarþröskuldurinn haldist undir lægsta gangafli vélarinnar.",
"tol_per_profile": "p75 af dreifni lengdar á hvert snið yfir {profiles} snið ({cycles} lotur); þröngum sniðum er ekki refsað.",
"tol_pooled": "Byggt á sameinaðri dreifni lengdar {cycles} nýjustu merktu lota (p95 frávik={dev}).",
"watchdog": "Haldið eins lágu og óhætt er (rétt yfir p95-uppfærslubilinu {p95}s, lágm. 30s) svo að stöðnun greinist fljótt án falskra stöðvana."
"watchdog": "Haldið eins lágu og óhætt er (rétt yfir p95-uppfærslubilinu {p95}s og að minnsta kosti 2x sýnatökubilinu {median}s, lágm. 30s) svo að stöðnun greinist fljótt án falskra stöðvana."
},
"exclusions": {
"summary": "Útilokaði {total} ranggreindar lotur: {parts}.",
@@ -1801,6 +1871,7 @@
"wrong_profile": "Rangt snið"
},
"toast": {
"catalog_refreshed": "Samfélagsskráin endurnýjuð",
"access_saved": "Aðgangsstýring vistuð",
"all_wiped": "Öll gögn þurrkuð út",
"analysis_complete_none": "Greiningu lokið: engar nýjar tillögur",
@@ -1812,7 +1883,7 @@
"cycle_labelled": "Hringrás merkt",
"cycle_paused": "Hlé gert á hringrásinni",
"cycle_resumed": "Hringrás hafin aftur",
"cycle_trimmed": "Hringrás klippt",
"cycle_trimmed": "Lota klippt til",
"cycles_merged": "Hringrásir sameinaðar",
"envelope_rebuilt": "Umslag endurbyggt",
"envelopes_rebuilt": "Umslög endurbyggð",
@@ -1884,7 +1955,7 @@
"store_name_required": "Sláðu inn heiti prófíls",
"store_import_failed": "Innflutningur mistókst: {error}",
"store_imported": "Flutt inn í {profile}",
"store_program_required": "Sláðu inn heiti forrits",
"store_program_required": "Sláðu inn heiti kerfis",
"store_no_appliance": "Stilltu fyrst vörumerki og gerð tækisins í Stillingum.",
"store_share_failed": "Deiling mistókst: {error}",
"store_shared": "Deilt í samfélagsversluninni, bíður yfirferðar.",
@@ -1896,9 +1967,9 @@
"profile_added": "Prófíl bætt við, bíður samþykkis",
"saved_except_conflicts": "Vistað. Leggðu úr hófi merktu árekstrana til að vista afganginn.",
"share_device_none_sel": "Veldu að minnsta kosti eina lotu til að deila",
"store_device_downloaded": "{p} forrit, {c} upptöku/upptökur bætt við",
"store_device_downloaded_phases": "{p} forrit, {c} upptöku/upptökur, {ph} fassakort bætt við",
"store_device_downloaded_settings": "{p} forrit, {c} upptöku/upptökur, {ph} fassakort, {s} stilling(ar) bætt við",
"store_device_downloaded": "{p} kerfi, {c} upptöku/upptökur bætt við",
"store_device_downloaded_phases": "{p} kerfi, {c} upptöku/upptökur, {ph} fasakort bætt við",
"store_device_downloaded_settings": "{p} kerfi, {c} upptöku/upptökur, {ph} fasakort, {s} stilling(ar) bætt við",
"store_device_shared": "{n} lota/lotir deilt í samfélagsverslunina -- bíður yfirferðar.",
"store_device_shared_all_dup": "Allar {n} lota/lotir voru þegar í samfélagsverslunina.",
"store_device_shared_partial": "{n} lota/lotir deilt; {failed} tókst ekki að hlaða upp.",
@@ -1906,7 +1977,9 @@
"store_download_failed": "Niðurhal mistókst: {error}",
"store_download_nothing": "Ekkert nýtt til að hlaða niður -- þessi uppsetning er þegar á tækinu þínu.",
"export_selective_done": "Útflutningur sóttur",
"import_selective_done": "Flutti inn {profiles} prófíl(a) og {cycles} lotu(r)"
"import_selective_done": "Flutti inn {profiles} prófíl(a) og {cycles} lotu(r)",
"hist_csv_required": "Hlaðdu fyrst inn CSV-skrá eða límdu innihald hennar",
"file_read_failed": "Gat ekki lesið þá skrá"
},
"trend": {
"down": "Stefnir niður",
@@ -1920,13 +1993,13 @@
"other": "Annað"
},
"col": {
"profile_tip": "Nafn samsvarandi forrits. Ómerkt þýðir að enginn prófíll samsvaraði við lok lotu.",
"profile_tip": "Nafn kerfisins sem samsvaraði. Ómerkt þýðir að enginn prófíll samsvaraði við lok lotu.",
"status_tip": "Niðurstaða lotu: Lokið (eðlilegur endir), Truflað (skyndilegt aflfall), Þvingað stopp (handvirkt) eða Þarf yfirferð (endurgjöf í bið).",
"date_tip": "Dagsetning og tími þegar lotan hófst.",
"duration_tip": "Heildarkeyrslutími lotu frá upphafi til enda.",
"energy_tip": "Heildarorka sem notuð er (kWh). Reiknuð með því að heilda afl yfir tíma.",
"cost_tip": "Orkukostnaður fyrir þessa lotu, fastsettur við lok út frá verðinu sem var í gildi þá (orka x verð á kWh). Stilltu verð undir Stillingar til að fylla það út.",
"confidence_tip": "Samsvörunaröryggi prófíls (0-100%). Hversu vel aflferill lotu samsvaraði auðkenndu forriti.",
"confidence_tip": "Samsvörunaröryggi prófíls (0-100%). Hversu vel aflferill lotu samsvaraði auðkenndu kerfi.",
"health_tip": "ML-heilsa lotu (hærra = betra). Smelltu á lotu til að skoða og fara yfir hana.",
"flags_tip": "Yfirferðar-, frávik- og upprunaflagg fyrir lotuna. Haltu músarbendlinum yfir tákn til að sjá upplýsingar."
},
@@ -1955,15 +2028,19 @@
"finished": "Lotan náði lokastöðu og endaði."
},
"store": {
"your_model_tip": "Þetta er tækið sem þú tilgreindir í Stillingum",
"your_model": "Þitt tæki",
"search_brand_ph": "Leita eftir vörumerki…",
"programs_count": "Kerfi: {n}",
"browse": "Skoða",
"device": "Tæki",
"favorites": "Uppáhald",
"search_ph": "Leita eftir vörumerki eða gerð…",
"no_results": "Engin samsvarandi tæki fundust. Prófaðu aðra leit.",
"n_programs": "{n} forrit",
"n_programs": "{n} kerfi",
"n_cycles": "{n} lotur",
"no_programs": "Engin deild forrit fyrir þetta tæki enn.",
"no_cycles": "Engum viðmiðunarlotum deilt fyrir þetta forrit enn.",
"no_programs": "Engum kerfum hefur verið deilt fyrir þetta tæki enn.",
"no_cycles": "Engum viðmiðunarlotum hefur verið deilt fyrir þetta kerfi enn.",
"anon": "nafnlaus",
"uploaded_by": "Deilt af {name}",
"connected_as": "Tengt sem {name}",
@@ -1993,6 +2070,7 @@
"add_profile": "Bættu við prófíl fyrir þetta tæki á samfélagssíðunni"
},
"task": {
"cancelling": "Hætti við...",
"reprocess": {
"matching": "Endurvinnsla: samsvara lotur",
"golden": "Endurvinnsla: fylli inn viðmiðunarlotur",
@@ -2025,27 +2103,27 @@
"healthy_chip": "Uppsetningu lokið"
},
"phase0": {
"washer": "WashData greinir nú þegar lotur þínar. Taktu upp fyrstu lotuna til að virkja forritsheiti og tímamat.",
"washer": "WashData greinir nú þegar lotur þínar. Taktu upp fyrstu lotuna til að virkja heiti kerfa og tímamat.",
"dishwasher": "WashData fylgist með. Uppþvottavélar hafa flóknar lotur mjög mælt er með að taka upp fyrstu lotuna. Ef greind lota keyrir of lengi skaltu nota lotu-ritilinn til að snyrta hana áður en hún er vistuð sem snið.",
"generic": "WashData fylgist með. Taktu upp eða merktu greinda lotu til að hefja uppbyggingu sniða."
},
"phase1a": {
"labelled": "Gott upphaf fyrsta forritið þitt er vistað. Fyrir hreinustu gögn skaltu íhuga að taka upp næstu lotu með upptökugræjunni."
"labelled": "Gott upphaf - fyrsta kerfið þitt er vistað. Fyrir hreinustu gögn skaltu íhuga að taka upp næstu lotu með upptökugræjunni."
},
"phase1b": {
"recorded": "Upptakan þín var vistuð sem {profile_name}. Taktu nú upp eða merktu önnur algeng forrit þín til að byggja upp þekju."
"recorded": "Upptakan þín var vistuð sem {profile_name}. Taktu nú upp eða merktu önnur algeng kerfi þín til að byggja upp þekju."
},
"phase1c": {
"verify": "Þú ert með {count} forrit úr samfélaginu. Keyrðu lotu til að staðfesta að WashData þekki hana rétt samsvörun batnar eftir því sem tækið byggir upp sína eigin sögu."
"verify": "Þú ert með {count} kerfi úr samfélaginu. Keyrðu lotu til að staðfesta að WashData þekki hana rétt - samsvörun batnar eftir því sem tækið byggir upp sína eigin sögu."
},
"phase2": {
"cluster": "WashData hefur séð {count} lotur sem samsvara ekki neinu vistuðu forriti þær líkjast hvor annarri. Viltu búa til nýtt snið fyrir þær?",
"unmatched": "Síðasta lota þín samsvaraði ekki neinu vistuðu forriti. Er þetta nýtt forrit?"
"cluster": "WashData hefur séð {count} lotur sem samsvara ekki neinu vistuðu kerfi - þær líkjast hver annarri. Viltu búa til nýtt snið fyrir þær?",
"unmatched": "Síðasta lota þín samsvaraði ekki neinu vistuðu kerfi. Er þetta nýtt kerfi?"
},
"phase3": {
"suggestions": "WashData hefur stillingatillögur byggðar á lotuferli þínum farðu yfir þær til að bæta nákvæmni greiningar.",
"groups": "Sum snið þín líkjast sama forriti við mismunandi hitastig. Skiptu þeim í hóp til að fá betri samsvörun.",
"phases": "Bættu forritsfasum við {profile_name} fyrir nákvæmara mat á tíma sem eftir er."
"groups": "Sum snið þín líkjast sama kerfi við mismunandi hitastig. Settu þau í hóp til að fá betri samsvörun.",
"phases": "Bættu fösum kerfisins við {profile_name} fyrir nákvæmara mat á tíma sem eftir er."
},
"phase4": {
"healthy": "Þetta tæki er að fullu sett upp ({profile_count} snið)."
@@ -30,9 +30,12 @@
"awaiting": "In attesa di approvazione",
"imported_tip": "Importato dallo store della community. Usato solo per la corrispondenza, non conteggiato nelle statistiche.",
"not_importable": "n/d qui",
"exists": "esiste già"
"exists": "esiste già",
"backfilled_tip": "Rilevato in uno storico di potenza importato. Influenza solo la corrispondenza dei programmi, non conteggiato nelle statistiche."
},
"btn": {
"set_brand_model": "Imposta marca e modello",
"refresh_catalog": "Aggiorna catalogo",
"add_device": "+ Aggiungi dispositivo",
"add_device_tip": "Aggiungi un altro dispositivo WashData",
"add_maintenance": "Aggiungi evento di manutenzione",
@@ -42,7 +45,7 @@
"apply_label": "Applica etichetta",
"apply_set_b": "Applica set B",
"apply_split": "Applica divisione",
"apply_trim": "Applicare Rifinitura",
"apply_trim": "Applica ritaglio",
"auto_detect_split": "Rilevamento automatico",
"auto_label_cycles": "Cicli di etichettatura automatica",
"auto_label_cycles_tip": "Assegna automaticamente nomi di profilo ai cicli senza etichetta la cui confidenza di corrispondenza supera la soglia",
@@ -161,8 +164,8 @@
"stop": "Ferma",
"submit_correction": "Invia correzione",
"train_now": "Allenati adesso",
"trim": "Ordinare",
"trim_split": "Taglia/Dividi",
"trim": "Ritaglia",
"trim_split": "Ritaglia / Dividi",
"undo": "Annulla",
"use": "Usa",
"wipe_all": "Cancella tutti i dati",
@@ -193,7 +196,12 @@
"import_selected": "Importa la selezione",
"back": "Indietro",
"mute_suggestion": "Non suggerire più questa impostazione",
"reset_muted": "Ripristina i silenziati"
"reset_muted": "Ripristina i silenziati",
"import_power_history": "Importa lo storico di potenza",
"hist_read_recorder": "Leggi da Home Assistant",
"hist_scan": "Cerca cicli",
"hist_import_n": "Importa {n} cicli",
"hist_goto_cycles": "Mostrami i cicli"
},
"conflict": {
"anti_wrinkle_exit": {
@@ -205,14 +213,14 @@
"start": "Deve essere inferiore alla Potenza massima anti-grinze ({max} W)"
},
"attn_sub": "Correggi i conflitti prima di salvare",
"attn_title": "{n} conflitto{s} nelle impostazioni",
"settings_banner": "{n} conflitto{s} nelle impostazioni controlla le sezioni evidenziate e correggile prima di salvare.",
"attn_title": "Conflitti nelle impostazioni: {n}",
"settings_banner": "Conflitti nelle impostazioni: {n}. Controlla le sezioni evidenziate e correggile prima di salvare.",
"settings_banner_btn": "Vai al primo",
"confidence": {
"auto": "Deve essere maggiore o uguale alla Soglia di corrispondenza ({match})",
"learning": "Deve essere minore o uguale alla Soglia di corrispondenza ({match})",
"learning": "Deve essere maggiore o uguale alla Soglia di corrispondenza ({match})",
"match_for_auto": "Deve essere minore o uguale alla Confidenza di etichettatura automatica ({alc})",
"match_for_learning": "Deve essere maggiore o uguale alla Confidenza di apprendimento ({lc})"
"match_for_learning": "Deve essere minore o uguale alla Confidenza di apprendimento ({lc})"
},
"duration_ratio": {
"max": "Deve essere superiore al Rapporto di durata minimo ({min})",
@@ -250,7 +258,7 @@
"match": "Deve essere superiore alla Soglia di non corrispondenza ({un})",
"unmatch": "Deve essere inferiore alla Soglia di corrispondenza ({match}); altrimenti una corrispondenza confermata viene annullata istantaneamente"
},
"cascade_toast": "Adattate anche {n} impostazione{s} per coerenza.",
"cascade_toast": "Altre impostazioni adattate per coerenza: {n}",
"suggestion_resolves": "Applica la proposta in attesa ({val}) in basso per correggere questo",
"use_fix": "Usa {val}",
"watchdog": {
@@ -308,7 +316,8 @@
"pg_outcome": "Esito della simulazione",
"pg_across_cycles": "Su tutti i tuoi cicli",
"community_store": "Store della community",
"online_account": "Store della community e funzionalità online"
"online_account": "Store della community e funzionalità online",
"import_power_history": "Importa lo storico di potenza"
},
"health": {
"fair": "Qualità profilo accettabile",
@@ -316,6 +325,7 @@
"poor": "⚠ Qualità profilo scarsa"
},
"lbl": {
"drag_to_resize": "Trascina per ridimensionare",
"actions": "Azioni",
"activity": "Attività",
"administrators": "Amministratori",
@@ -386,7 +396,7 @@
"from": "Da",
"gap_s": "Divario/i",
"group_name": "Nome del gruppo",
"head_trim": "Taglio della testa",
"head_trim": "Ritaglio iniziale (s)",
"health": "Salute",
"hide_tabs": "Nascondi le schede per i non amministratori",
"in_use": "In uso",
@@ -402,7 +412,7 @@
"metric": "Metrica",
"mode_existing_profile": "Aggiungi al profilo esistente",
"mode_new_profile": "Crea nuovo profilo",
"models_fine_tuned": "({count} modello{plural} ottimizzato)",
"models_fine_tuned": "(modelli ottimizzati: {count})",
"n_classic_suggestions": "{n} classico",
"n_ml_suggestions": "{n} ML",
"n_selected": "{n} selezionati",
@@ -484,7 +494,7 @@
"stage3": "Fase 3 DTW",
"stage4": "Fase 4 concordanza",
"status": "Stato",
"tail_trim": "Taglio(i) di coda",
"tail_trim": "Ritaglio finale (s)",
"timer_auto_pause": "Pausa automatica",
"timer_min": "min",
"timer_msg_placeholder": "Messaggio (facoltativo, {device}/{program}/{minutes})",
@@ -629,7 +639,26 @@
"conflict_import_copy": "Importa come copia",
"conflict_keep_mine": "Mantieni il mio",
"conflict_overwrite": "Sovrascrivi",
"font_size": "Dimensione testo del pannello"
"font_size": "Dimensione testo del pannello",
"hist_csv_data": "Dati CSV",
"hist_from_recorder": "Oppure leggilo da Home Assistant",
"hist_since": "Dal",
"days": "giorni",
"hist_keep": "Mantieni questo ciclo",
"hist_looks_complete": "completo",
"peak_power_short": "Picco",
"shape": "Forma",
"hist_skip_idle": "niente in funzione",
"hist_skip_sparse": "letture troppo distanti tra loro",
"hist_skip_short": "troppo poche letture",
"hist_skip_long": "nessuna pausa abbastanza lunga per dividere",
"hist_reason_short": "più corto del ciclo reale più breve di questo elettrodomestico",
"hist_reason_no_end": "non è mai terminato in modo pulito",
"task_history_import": "Scansione dello storico di potenza",
"task_history_import_apply": "Importazione dei cicli",
"evidence_real_cycles": "Cicli eseguiti da questa macchina",
"evidence_reference_cycles": "Scaricati dallo store della community",
"evidence_backfill_cycles": "Trovati in uno storico di potenza importato"
},
"log": {
"all_levels": "Tutti i livelli",
@@ -708,9 +737,15 @@
"store_share": "Condividi nello store della community",
"store_share_device": "Condividi questo dispositivo",
"export_select": "Esporta - scegli i dati",
"import_wizard": "Importa - scegli i dati"
"import_wizard": "Importa - scegli i dati",
"history_import": "Importa lo storico di potenza"
},
"msg": {
"tail_trim_hint": "Numero di secondi da rimuovere dalla fine",
"store_sibling_hint": "Non c'è nulla di condiviso per il tuo modello esatto? Un modello molto simile della stessa marca è di solito un buon punto di partenza.",
"store_declare_appliance": "Indica a WashData quale elettrodomestico possiedi e questa scheda mostrerà le configurazioni che altre persone hanno condiviso per esso. Puoi anche digitare una marca qui sopra per dare un'occhiata.",
"refresh_catalog_hint": "Gli elenchi di marche ed elettrodomestici della community sono memorizzati nella cache per mantenere lo store condiviso entro il suo limite giornaliero. Aggiorna per recuperare le voci aggiunte o approvate da altri utenti.",
"head_trim_hint": "Numero di secondi da rimuovere dall'inizio",
"appliance_monitor": "Monitor degli elettrodomestici",
"artifact_dip_detail": "È sceso sotto la banda di potenza normale per ~{n}s.",
"artifact_footer": "Evidenziato nel grafico sopra. Si tratta di artefatti temporanei (ad esempio la porta aperta a metà ciclo), non necessariamente problemi.",
@@ -721,7 +756,7 @@
"automations_intro": "WashData genera gli eventi {start} / {end} ed espone entità, quindi le notifiche e le azioni si costruiscono al meglio come normali automatizzazioni di Home Assistant. Le automatizzazioni che utilizzano questo dispositivo appaiono di seguito.",
"cleanup_intro": "Ogni ciclo etichettato è sovrapposto. Spunta i valori anomali ed elimina per ripulire il profilo.",
"clear_debug_hint": "Rimuovi i dati di debug archiviati per liberare spazio.",
"collecting_data": "Raccolta dati - ancora {need} ciclo{plural} prima che l'ottimizzazione possa iniziare ({current}/{min}).",
"collecting_data": "Raccolta dati. Cicli ancora necessari prima che l'ottimizzazione possa iniziare: {need} ({current}/{min}).",
"compare_overlay_profiles": "Profili sovrapposti (debole)",
"compare_profiles_tip": "Sovrapponi altri involucri del profilo sulla tabella sopra per vedere quale si adatta meglio a questo ciclo.",
"compare_selected_cycles": "Cicli selezionati (fissi) mostra/nascondi",
@@ -731,7 +766,7 @@
"cycles_deleted": "{count} ciclo/i eliminato/i",
"enough_data": "Dati sufficienti per apprendere ({current}/{min} cicli).",
"export_description": "Scegli esattamente quali profili, cicli, impostazioni e altro esportare in JSON, oppure analizza un file e importa solo le parti che vuoi.",
"feedback_cycles_pending": "{n} ciclo{s} da revisionare",
"feedback_cycles_pending": "Da revisionare: {n}",
"feedback_prompt": "Conferma che fosse corretto, correggi il programma o ignoralo.",
"feedback_relabel_hint": "Anche rietichettare questo ciclo lo risolve.",
"filter_by_profile": "Filtra per profilo…",
@@ -808,7 +843,6 @@
"pg_stress_synthetic": "la simulazione in standby inizia qui",
"pg_sweep_intro": "E se {param} fosse diverso? Testa {steps} valori sui tuoi ultimi {cycles} cicli per trovare l'impostazione in cui il maggior numero di cicli viene riconosciuto correttamente.",
"pg_sweep_step": "Passaggio {done} / {total}",
"pg_undetected": "{n} ciclo{s} non rilevato",
"pg_verdict_bad": "Richiede attenzione: molti cicli non vengono rilevati.",
"pg_verdict_good": "Ben regolato: la maggior parte dei cicli viene identificata e riconosciuta correttamente.",
"pg_verdict_ok": "Accettabile: alcuni cicli mancati. Prova ad abbassare la soglia di avvio.",
@@ -839,6 +873,7 @@
"review_recorded_tip": "Contrassegnalo come ciclo di riferimento selezionato manualmente per il suo programma: lo stesso ruolo di un ciclo registrato manualmente. I cicli di riferimento vengono sempre mantenuti, seminano il modello corrispondente e non vengono mai eliminati dalla pulizia. (Questa è la bandiera \"d'oro\"/registrata; entrambe sono la stessa cosa.)",
"review_tags_tip": "Flag facoltativi che descrivono cosa è andato storto in questo ciclo, in modo che l'addestramento e la pulizia possano tenerne conto.",
"review_to_cycles": "Apri la coda di revisione dei cicli",
"samples_decimated": "Visualizzazione di {shown} di {total} campioni (ridotti per la visualizzazione; picchi mantenuti). Un ampio spazio vuoto qui è dovuto alla riduzione, non a dati mancanti.",
"saving_triggers_reload": "Il salvataggio attiva un ricaricamento dell'integrazione. Le entità HA potrebbero essere visualizzate brevemente come non disponibili.",
"search_placeholder": "Cerca impostazioni...",
"see_recorder": "Vedi il widget del registratore di seguito",
@@ -958,10 +993,33 @@
"sug_mute_failed": "Impossibile silenziare il suggerimento",
"sug_unmuted_all": "Suggerimenti silenziati ripristinati",
"n_suggestions_muted": "{count} silenziati; il sistema di ottimizzazione automatica non proporrà questi.",
"font_size_hint": "Rendi tutto in questo pannello più grande o più piccolo. Si applica al tuo account su questo dispositivo."
"font_size_hint": "Rendi tutto in questo pannello più grande o più piccolo. Si applica al tuo account su questo dispositivo.",
"import_history_description": "Avevi già una presa intelligente prima di WashData? Carica un'esportazione dello storico del suo sensore di potenza, oppure leggilo direttamente da Home Assistant: il normale rilevamento viene eseguito su quei dati, così i cicli passati compaiono nel tuo elenco Cicli, pronti da nominare.",
"hist_input_hint": "Carica un CSV scaricato dal pannello Cronologia (entità, stato, ultima modifica), oppure lascia che WashData legga direttamente lo storico del sensore. Il rilevamento viene poi eseguito esattamente come in tempo reale e sei tu a scegliere quali dei cicli trovati mantenere.",
"hist_recorder_hint": "Legge dalla data che scegli fino a ora. Home Assistant conserva lo storico dettagliato per 10 giorni per impostazione predefinita e successivamente solo medie orarie, troppo grossolane per rilevare i cicli - scegli una data più indietro nel tempo solo se il recorder di Home Assistant è configurato per conservarne di più.",
"hist_scanning": "Il tuo storico viene rieseguito attraverso il rilevatore. L'operazione avviene in background: puoi chiudere questa finestra e tornarci più tardi.",
"hist_imported_count": "{n} cicli importati.",
"hist_duplicates": "{n} erano già stati importati e sono stati saltati.",
"hist_capped": "È stato raggiunto il limite di cicli importati per dispositivo; il resto non è stato salvato.",
"hist_next_step": "Sono nel tuo elenco Cicli, contrassegnati come storico importato. Aprine uno e usa Assegna etichetta per indicare il programma a cui appartiene.",
"hist_rows_read": "{n} letture lette",
"hist_breaks": "{n} interruzioni in cui il sensore non era disponibile",
"hist_other_entity": "{n} letture di altre entità ignorate",
"hist_entity_substituted": "{used} letto (questo dispositivo è configurato per {wanted})",
"hist_skipped_spans": "Tratti saltati",
"hist_settings_used": "Rilevato con le impostazioni attuali di questo dispositivo (potenza minima {w} W, ritardo spegnimento {s} s).",
"hist_none_found": "Non è stato possibile rilevare alcun ciclo in quello storico.",
"hist_found": "Trovati {n} cicli. Deseleziona tutto ciò che non sembra un ciclo reale: nulla viene salvato finché non importi.",
"hist_scan_capped": "Vengono mostrati solo i primi candidati ({n} trovati in totale).",
"hist_recorder_empty": "Home Assistant non ha uno storico dettagliato per questo sensore in quel periodo.",
"hist_scan_failed": "Scansione non riuscita.",
"hist_scan_expired": "Quella scansione non è più disponibile. Esegui di nuovo la scansione.",
"hist_import_failed": "Importazione non riuscita.",
"imported_history_readonly": "Rilevato in uno storico di potenza importato. Influenza la corrispondenza dei programmi ma non viene conteggiato nelle tue statistiche e non può essere ritagliato né diviso. Assegna un'etichetta per indicare il programma."
},
"pg_desc": {
"dishwasher_end_spike_quiet_release": "Lavastoviglie: secondi di silenzio dopo la durata prevista prima che venga rilasciata l'attesa dello scarico di fine ciclo",
"smart_termination_duration_ratio": "Frazione della durata prevista del programma corrispondente che un ciclo deve raggiungere prima che la Terminazione intelligente possa concluderlo in anticipo; abbassala per le macchine che dipendono dal carico o dalla temperatura",
"anti_wrinkle_enabled": "Assorbire gli impulsi di rotazione dopo la fase principale invece di leggerli come nuovi cicli",
"anti_wrinkle_exit_power": "La potenza deve scendere sotto questo valore tra gli impulsi affinché la modalità antirughe resti attiva",
"anti_wrinkle_idle_timeout": "Tempo di silenzio consentito tra due impulsi di rotazione prima che la modalità antirughe termini",
@@ -1373,6 +1431,10 @@
"doc": "Memorizzare la traccia di potenza completa e i dati di debug corrispondenti per ciascun ciclo. Utile per la risoluzione dei problemi ma aumenta le dimensioni dello spazio di archiviazione.",
"label": "Salva tracce di debug"
},
"smart_termination_duration_ratio": {
"doc": "Quanto un ciclo deve essere avanzato nella durata prevista del programma corrispondente prima che la Terminazione intelligente possa concluderlo in anticipo una volta che la potenza cala. La durata prevista è la media del programma, quindi sugli apparecchi il cui tempo di funzionamento varia molto - lavatrici a seconda dell'acqua di ingresso fredda d'inverno o tiepida d'estate, asciugatrici con sensore di umidità, programmi che dipendono dal carico - circa la metà dei cicli termina prima di quella media e non ottiene mai la conclusione rapida, terminando solo tramite il timeout di riserva con minuti di ritardo. Abbassa questo valore (ad es. 0,85) su quelle macchine affinché la conclusione anticipata si attivi comunque; alzalo verso 1,0 per essere più prudente. Lascia vuoto per il valore predefinito (0,98, o 0,99 per le lavastoviglie). Può solo concludere un ciclo prima, mai dopo, e non si attiva mai su una corrispondenza ambigua o a bassa affidabilità.",
"label": "Rapporto di terminazione intelligente"
},
"smoothing_window": {
"doc": "Quanto viene attenuato il segnale di potenza grezza. Basso (2) è reattivo ma rumoroso; alto (5) attenua i picchi ma aggiunge ritardo.",
"label": "Finestra di smussamento"
@@ -1503,6 +1565,10 @@
"door_end_dwell_seconds": {
"label": "Attesa apertura porta al termine",
"doc": "Per quanto tempo lo sportello deve restare aperto prima che WashData termini il ciclo, quando \"Porta si apre automaticamente al termine\" è attiva. Abbastanza lungo da ignorare l'aggiunta rapida di un piatto (predefinito 60 s), abbastanza breve da terminare prontamente quando la macchina apre lo sportello."
},
"profile_evidence_sources": {
"label": "Cicli che formano un programma",
"doc": "Quali cicli vengono usati per costruire la curva di potenza di ogni programma e per confrontare con essa un ciclo terminato. Deselezionare un tipo fa sì che non modelli più i tuoi programmi senza eliminare nulla - i cicli restano nel tuo elenco Cicli e possono ancora essere etichettati o rimossi. Utile se non ti fidi dei dati importati. Le statistiche non sono influenzate: conteggiano sempre solo i cicli che questa macchina ha effettivamente eseguito. Deselezionare tutto viene ignorato, perché un programma senza cicli alle spalle non potrebbe mai corrispondere."
}
},
"setting_group": {
@@ -1586,6 +1652,9 @@
},
"basic_configuration": {
"label": "Configurazione di base"
},
"profile_evidence": {
"label": "Base dei profili"
}
},
"status": {
@@ -1607,10 +1676,11 @@
"analyzing": "Analisi…",
"resetting": "Reimpostazione…",
"reverting": "Ripristino…",
"trimming": "Rifinitura…",
"trimming": "Ritaglio…",
"splitting": "Divisione…",
"deleting": "Eliminazione…",
"imported": "Importato"
"imported": "Importato",
"preparing": "Preparazione…"
},
"tab": {
"advanced": "Avanzato",
@@ -1640,6 +1710,7 @@
"wrong_profile": "Profilo sbagliato"
},
"toast": {
"catalog_refreshed": "Catalogo della community aggiornato",
"access_saved": "Controllo accessi salvato",
"all_wiped": "Tutti i dati cancellati",
"analysis_complete_none": "Analisi completata: nessun nuovo suggerimento",
@@ -1651,7 +1722,7 @@
"cycle_labelled": "Ciclo etichettato",
"cycle_paused": "Ciclo in pausa",
"cycle_resumed": "Ciclo ripreso",
"cycle_trimmed": "Ciclo tagliato",
"cycle_trimmed": "Ciclo ritagliato",
"cycles_merged": "Cicli uniti",
"envelope_rebuilt": "Busta ricostruita",
"envelopes_rebuilt": "Buste ricostruite",
@@ -1745,7 +1816,9 @@
"store_download_failed": "Download non riuscito: {error}",
"store_download_nothing": "Nulla di nuovo da scaricare - questa configurazione è già sul tuo dispositivo.",
"export_selective_done": "Esportazione scaricata",
"import_selective_done": "Importati {profiles} profilo/i e {cycles} ciclo/i"
"import_selective_done": "Importati {profiles} profilo/i e {cycles} ciclo/i",
"hist_csv_required": "Carica prima un file CSV o incolla il suo contenuto",
"file_read_failed": "Impossibile leggere quel file"
},
"suggestion": {
"both_agree": "WashData consiglia",
@@ -1841,7 +1914,7 @@
"thr_batch": "Mantenuto appena sopra la potenza attiva più bassa al p05 su {cycles} cicli ({p05}W) affinché un avvio venga rilevato il prima possibile e la soglia di arresto resti sotto la potenza di funzionamento più bassa della macchina.",
"tol_per_profile": "p75 della varianza di durata per profilo su {profiles} profili ({cycles} cicli); i profili stretti non vengono penalizzati.",
"tol_pooled": "In base alla varianza di durata aggregata di {cycles} cicli etichettati di recente (deviazione p95={dev}).",
"watchdog": "Mantenuto il più basso possibile in sicurezza (poco sopra l'intervallo di aggiornamento p95 di {p95}s, min 30s) per rilevare rapidamente i blocchi senza arresti falsi."
"watchdog": "Mantenuto il più basso possibile in sicurezza (poco sopra l'intervallo di aggiornamento p95 di {p95}s e almeno 2x l'intervallo di campionamento di {median}s, min 30s) per rilevare rapidamente i blocchi senza arresti falsi."
},
"exclusions": {
"summary": "Esclusi {total} cicli rilevati male: {parts}.",
@@ -1907,6 +1980,10 @@
"finished": "Il ciclo ha raggiunto lo stato finale e si è concluso."
},
"store": {
"your_model_tip": "Questo è l'elettrodomestico che hai dichiarato nelle Impostazioni",
"your_model": "Il tuo",
"search_brand_ph": "Cerca per marca…",
"programs_count": "Programmi: {n}",
"browse": "Sfoglia",
"device": "Dispositivo",
"favorites": "Preferiti",
@@ -78,9 +78,12 @@
"awaiting": "承認待ち",
"imported_tip": "コミュニティストアからインポートしました。マッチングにのみ使用され、統計には含まれません。",
"not_importable": "対象外",
"exists": "既存"
"exists": "既存",
"backfilled_tip": "インポートした電力履歴から検出されました。プログラムのマッチングにのみ影響し、統計には含まれません。"
},
"btn": {
"set_brand_model": "ブランドとモデルを設定",
"refresh_catalog": "カタログを更新",
"add_device": "+ デバイスを追加",
"add_device_tip": "別の WashData デバイスを追加する",
"add_maintenance": "メンテナンスイベントを追加",
@@ -241,7 +244,12 @@
"import_selected": "選択項目をインポート",
"back": "戻る",
"mute_suggestion": "この設定の提案を停止",
"reset_muted": "ミュートをリセット"
"reset_muted": "ミュートをリセット",
"import_power_history": "電力履歴をインポート",
"hist_read_recorder": "Home Assistant から読み込む",
"hist_scan": "サイクルを検索",
"hist_import_n": "{n} サイクルをインポート",
"hist_goto_cycles": "サイクルを表示"
},
"conflict": {
"anti_wrinkle_exit": {
@@ -253,12 +261,12 @@
"start": "しわ防止最大電力 ({max} W) を下回る必要があります"
},
"attn_sub": "保存する前に競合を解消してください",
"attn_title": "{n}件の設定競合{s}",
"attn_title": "設定競合: {n}",
"confidence": {
"auto": "マッチしきい値 ({match}) 以上である必要があります",
"learning": "マッチしきい値 ({match}) 以である必要があります",
"learning": "マッチしきい値 ({match}) 以である必要があります",
"match_for_auto": "自動ラベル信頼度 ({alc}) 以下である必要があります",
"match_for_learning": "学習信頼度 ({lc}) 以である必要があります"
"match_for_learning": "学習信頼度 ({lc}) 以である必要があります"
},
"duration_ratio": {
"max": "最小時間比率 ({min}) より大きい必要があります",
@@ -296,14 +304,14 @@
"match": "アンマッチしきい値 ({un}) を上回る必要があります",
"unmatch": "マッチしきい値 ({match}) を下回る必要があります。そうでないと確定した一致が即座に解除されます"
},
"cascade_toast": "整合性のため、さらに{n}件の設定{s}も自動調整しました。",
"cascade_toast": "整合性のため調整した他の設定: {n}",
"suggestion_resolves": "下の保留中の提案({val})を適用してこれを修正してください",
"use_fix": "{val} を使用",
"watchdog": {
"interval": "サンプリング間隔 ({si} 秒) の少なくとも 2 倍である必要があります",
"sampling": "サンプリング間隔はウォッチドッグ間隔 ({wi} 秒) の半分以下である必要があります"
},
"settings_banner": "{n} 件の設定競合{s} 強調表示されたセクションを確認し、保存前に修正してください。",
"settings_banner": "設定競合: {n}。強調表示されたセクションを確認し、保存前に修正してください。",
"settings_banner_btn": "最初へ"
},
"hdr": {
@@ -356,7 +364,8 @@
"pg_outcome": "シミュレーション結果",
"pg_across_cycles": "全サイクルにわたって",
"community_store": "コミュニティストア",
"online_account": "コミュニティストアとオンライン機能"
"online_account": "コミュニティストアとオンライン機能",
"import_power_history": "電力履歴のインポート"
},
"health": {
"fair": "プロファイル品質: 普通",
@@ -364,6 +373,7 @@
"poor": "⚠ プロファイル品質: 低"
},
"lbl": {
"drag_to_resize": "ドラッグしてサイズ変更",
"actions": "アクション",
"activity": "活動",
"administrators": "管理者",
@@ -434,7 +444,7 @@
"from": "開始",
"gap_s": "ギャップ (秒)",
"group_name": "グループ名",
"head_trim": "ヘッドトリム (秒)",
"head_trim": "先頭のトリム (秒)",
"health": "健康",
"hide_tabs": "管理者以外のタブを非表示にする",
"in_use": "使用中",
@@ -450,7 +460,7 @@
"metric": "指標",
"mode_existing_profile": "既存のプロファイルに追加",
"mode_new_profile": "新しいプロファイルの作成",
"models_fine_tuned": "{count}モデル{plural}微調整済み)",
"models_fine_tuned": "(微調整済みモデル: {count}",
"n_classic_suggestions": "{n} クラシック",
"n_ml_suggestions": "{n} ML",
"n_selected": "{n} 件選択中",
@@ -532,7 +542,7 @@
"stage3": "ステージ 3 DTW",
"stage4": "ステージ 4 一致度",
"status": "状態",
"tail_trim": "テールトリム (秒)",
"tail_trim": "末尾のトリム (秒)",
"timer_auto_pause": "自動一時停止",
"timer_min": "分",
"timer_msg_placeholder": "メッセージ (オプション、{device}/{program}/{minutes})",
@@ -677,7 +687,26 @@
"conflict_import_copy": "コピーとしてインポート",
"conflict_keep_mine": "自分のを保持",
"conflict_overwrite": "上書き",
"font_size": "パネルのフォントサイズ"
"font_size": "パネルのフォントサイズ",
"hist_csv_data": "CSV データ",
"hist_from_recorder": "または Home Assistant から読み込む",
"hist_since": "開始日",
"days": "日",
"hist_keep": "このサイクルを保持",
"hist_looks_complete": "完全",
"peak_power_short": "ピーク",
"shape": "形状",
"hist_skip_idle": "稼働なし",
"hist_skip_sparse": "計測値の間隔が広すぎる",
"hist_skip_short": "計測値が少なすぎる",
"hist_skip_long": "分割できる十分な中断がない",
"hist_reason_short": "この家電の実際の最短サイクルより短い",
"hist_reason_no_end": "正常に終了していない",
"task_history_import": "電力履歴のスキャン",
"task_history_import_apply": "サイクルのインポート",
"evidence_real_cycles": "この機器が実行したサイクル",
"evidence_reference_cycles": "コミュニティストアからダウンロード",
"evidence_backfill_cycles": "インポートした電力履歴から検出"
},
"log": {
"all_levels": "すべてのレベル",
@@ -756,9 +785,15 @@
"store_share": "コミュニティストアに共有",
"store_share_device": "このデバイスを共有",
"export_select": "エクスポート - データを選択",
"import_wizard": "インポート - データを選択"
"import_wizard": "インポート - データを選択",
"history_import": "電力履歴のインポート"
},
"msg": {
"tail_trim_hint": "末尾から削除する秒数",
"store_sibling_hint": "お使いの機種そのものが共有されていない場合は、同じブランドの近い機種から始めるとうまくいくことが多いです。",
"store_declare_appliance": "お使いの家電を WashData に指定すると、このタブに他のユーザーが共有したプログラムや録音が表示されます。上でブランド名を入力して見て回ることもできます。",
"refresh_catalog_hint": "コミュニティのブランドと家電の一覧はキャッシュされ、共有ストアが 1 日あたりの読み取り上限内に収まるようにしています。更新すると、他のユーザーが追加または承認した項目を取得できます。",
"head_trim_hint": "先頭から削除する秒数",
"appliance_monitor": "アプライアンスモニター",
"artifact_dip_detail": "通常の電力帯の下側に約{n}秒間落ちました。",
"artifact_footer": "上のグラフで強調表示されています。これらは一時的なアーチファクト (サイクルの途中でドアが開いたなど) であり、必ずしも問題があるわけではありません。",
@@ -769,7 +804,7 @@
"automations_intro": "WashData は {start} / {end} イベントを発火しエンティティを公開するため、通知やアクションは通常の Home Assistant オートメーションとして構築するのが最適です。このデバイスを使用するオートメーションは以下に表示されます。",
"cleanup_intro": "すべてのラベル付きサイクルがオーバーレイされます。外れ値にチェックを入れて削除し、プロファイルをクリーンアップします。",
"clear_debug_hint": "保存されているデバッグ データを削除して領域を解放します。",
"collecting_data": "データを収集中です。微調整を開始するにはあと {need} サイクル{plural}必要です{current}/{min})。",
"collecting_data": "データを収集中です。微調整を開始するために必要な残りサイクル数: {need}{current}/{min})。",
"compare_overlay_profiles": "オーバーレイプロファイル (淡い)",
"compare_profiles_tip": "他のプロファイル エンベロープを上のチャートに重ねて、どれがこのサイクルに最も適合するかを確認します。",
"compare_selected_cycles": "選択されたサイクル (実線) – 表示/非表示",
@@ -779,7 +814,7 @@
"cycles_deleted": "{count} 件のサイクルを削除しました",
"enough_data": "学習に十分なデータがあります({current}/{min} サイクル)。",
"export_description": "JSONにエクスポートするプロファイル、サイクル、設定などを正確に選択するか、ファイルを解析して必要な部分だけをインポートできます。",
"feedback_cycles_pending": "レビューが必要なサイクル: {n}件{s}",
"feedback_cycles_pending": "レビュー: {n}",
"feedback_prompt": "それが正しかったことを確認し、プログラムを修正するか、無視してください。",
"feedback_relabel_hint": "このサイクルを再ラベル付けすると、これも解決します。",
"filter_by_profile": "プロファイルでフィルター…",
@@ -827,7 +862,7 @@
"no_profiles_yet": "まだプロフィールはありません。ラベル付きサイクルからサイクルを作成します。",
"no_profiles_yet_short": "まだプロフィールはありません。",
"no_settings_match": "「{q}」に一致する設定はありません",
"no_split_points": "まだ分割ポイントはありません。",
"no_split_points": "まだ分 割ポイントはありません。",
"no_suggestions": "積極的な提案はありません。",
"notify_services_hint": "{entity} サービス ID を使用してください(複数はカンマ区切り)。テンプレート変数:{vars}。",
"old_actions_warning": "古いアクション エディター (現在は削除されています) で構成されています。これらは引き続きサイクル イベントで起動されますが、ここでは編集できなくなりました。それらを通常のオートメーションに変換するか、削除します。",
@@ -856,12 +891,11 @@
"pg_stress_synthetic": "待機シミュレーションはここから開始",
"pg_sweep_intro": "もし {param} が違っていたら? 最も多くのサイクルが正しくマッチする設定を見つけるため、直近 {cycles} サイクルにわたって {steps} 個の値をテストします。",
"pg_sweep_step": "ステップ {done} / {total}",
"pg_undetected": "{n} 件のサイクル{s}が未検出",
"pg_verdict_bad": "要注意: 多くのサイクルが検出されずに終わっています。",
"pg_verdict_good": "よく調整されています: ほとんどのサイクルが正しく識別・マッチされています。",
"pg_verdict_ok": "許容範囲: 一部のサイクルを見逃しています。開始しきい値を下げてみてください。",
"phase_catalog_intro": "サイクルの名前付きセグメント (前洗浄、加熱、脱水など)。コントロール パネルからプロファイルにそれらを割り当てます。",
"phase_ranges_intro": "位相範囲 (サイクル開始からの分) が平均曲線に重ねられます。値を編集してライブでプレビューします。",
"phase_ranges_intro": "位相範囲 (サイクル開始からの分) が平均曲線に重ねられます。値を編 集してライブでプレビューします。",
"playground_intro": "過去のサイクルを異なる設定で再生し、2 つの構成を並べて比較し、サイクルがプロフィールにどう整合するかを確認できる安全なサンドボックスです。明示的に適用するまで、ここでの操作が実データを変更することはありません。",
"playground_needs_restart": "プレイグラウンドツールを有効にするには Home Assistant を再起動してください。",
"preferences_admin": "設定、パネル、アクセス制御",
@@ -887,6 +921,7 @@
"review_recorded_tip": "これをプログラム用に厳選された参照サイクルとしてマークします。これは、手動で記録されたサイクルと同じ役割です。参照サイクルは常に保持され、一致するテンプレートにシードされ、クリーンアップによって削除されることはありません。 (これは「ゴールデン」/記録済みフラグです。両方とも同じものです。)",
"review_tags_tip": "このサイクルで何が問題だったかを説明するオプションのフラグ。トレーニングとクリーンアップで問題を解決できます。",
"review_to_cycles": "Cycles レビューキューを開く",
"samples_decimated": "{total} サンプル中 {shown} 件を表示中 (表示用に間引き。ピークは保持)。ここでの大きな間隔は間引きであり、データの欠落ではありません。",
"saving_triggers_reload": "保存すると統合のリロードがトリガーされます。 HA エンティティが一時的に利用不可として表示される場合があります。",
"search_placeholder": "検索設定…",
"see_recorder": "以下のレコーダー ウィジェットを参照してください",
@@ -1006,7 +1041,29 @@
"sug_mute_failed": "提案のミュートに失敗しました",
"sug_unmuted_all": "ミュートした提案をリセットしました",
"n_suggestions_muted": "{count} 件がミュート済み。自動チューナーはこれらを提案しません。",
"font_size_hint": "このパネル全体の文字を大きくまたは小さくします。このデバイスのあなたのアカウントに適用されます。"
"font_size_hint": "このパネル全体の文字を大きくまたは小さくします。このデバイスのあなたのアカウントに適用されます。",
"import_history_description": "WashData を使う前からスマートプラグをお使いでしたか?その電力センサーの履歴エクスポートをアップロードするか、Home Assistant から直接読み込むと、通常の検出がそのデータに対して実行され、過去のサイクルが「サイクル」一覧に表示されて名前を付けられる状態になります。",
"hist_input_hint": "履歴パネルからダウンロードした CSV (entity, state, last changed) をアップロードするか、WashData にセンサーの履歴を直接読み込ませてください。その後、ライブ動作とまったく同じ検出が実行され、見つかったサイクルのうちどれを保持するかを選択できます。",
"hist_recorder_hint": "選択した日付から現在までを読み込みます。Home Assistant は既定で詳細な履歴を 10 日間保持し、それ以降は 1 時間ごとの平均値のみを保持します。平均値は粗すぎてサイクルを検出できないため、さらに過去の日付を選ぶのは recorder がより長く保持する設定になっている場合だけにしてください。",
"hist_scanning": "履歴を検出器で再生しています。この処理はバックグラウンドで実行されます。このダイアログを閉じて後で戻ってきても問題ありません。",
"hist_imported_count": "{n} サイクルをインポートしました。",
"hist_duplicates": "{n} 件はすでにインポート済みのためスキップしました。",
"hist_capped": "デバイスごとのインポート済みサイクル数の上限に達したため、残りは保存されませんでした。",
"hist_next_step": "「サイクル」一覧にインポートした履歴として表示されています。1 つ開いて「ラベル付け」から該当するプログラム名を設定してください。",
"hist_rows_read": "{n} 件の計測値を読み込みました",
"hist_entity_substituted": "{used} を読み込みました(このデバイスには {wanted} が設定されています)",
"hist_breaks": "センサーが利用できなかった空白が {n} 箇所",
"hist_other_entity": "他のエンティティの計測値 {n} 件は無視されました",
"hist_skipped_spans": "スキップした区間",
"hist_settings_used": "このデバイスの現在の設定 (最小電力 {w} W、オフ遅延 {s} 秒) で検出しました。",
"hist_none_found": "その履歴からはサイクルを検出できませんでした。",
"hist_found": "{n} サイクルが見つかりました。実際の稼働に見えないものはチェックを外してください。インポートするまで何も保存されません。",
"hist_scan_capped": "最初の候補のみを表示しています (合計 {n} 件見つかりました)。",
"hist_recorder_empty": "Home Assistant には、その期間のこのセンサーの詳細な履歴がありません。",
"hist_scan_failed": "スキャンに失敗しました。",
"hist_scan_expired": "そのスキャン結果はすでに利用できません。もう一度スキャンしてください。",
"hist_import_failed": "インポートに失敗しました。",
"imported_history_readonly": "インポートした電力履歴から検出されました。プログラムのマッチングには反映されますが、統計には含まれず、トリミングや分割はできません。ラベル付けしてプログラム名を設定してください。"
},
"pg_desc": {
"completion_min_seconds": "実サイクルとみなす最短の稼働時間",
@@ -1035,7 +1092,8 @@
"dtw_refine_top_n": "ステージ 3: DTW が再スコアリングする候補数; 正しいプロファイルが 4-5 位になる場合は 7-9 に増やす(デフォルト 5)",
"duration_scale": "ステージ 4: 運転時間の一致スコアが半分になる対数比率; 小さいほど厳格なペナルティ(デフォルト 0.175)",
"energy_scale": "ステージ 4: エネルギーの一致スコアが半分になる対数比率; 小さいほど厳格なペナルティ(デフォルト 0.25)",
"dishwasher_end_spike_quiet_release": "食器洗い機: 予想所要時間を過ぎた後、サイクル終了時の排水待機を解除するまでの静音秒数"
"dishwasher_end_spike_quiet_release": "食器洗い機: 予想所要時間を過ぎた後、サイクル終了時の排水待機を解除するまでの静音秒数",
"smart_termination_duration_ratio": "一致したプログラムの想定所要時間のうち、スマート終了が早期に終了できるようになるまでにサイクルが到達すべき割合。負荷や温度に左右されるマシンでは下げる"
},
"phase_desc": {
"anti_crease": "メインサイクル後にドラムが断続的に回転し、衣類のシワを防止します。",
@@ -1214,7 +1272,7 @@
"label": "デバッグエンティティを公開"
},
"external_end_trigger": {
"doc": "状態の変化がサイクルの終了を示すバイナリ センサー (例: アプライアンスの「完了」接触またはコンパニオン統合)。",
"doc": "状態の変化がサイクルの終了を示すバイナリ センサー (例: アプライアンスの「完了」接触またはコンパニオン統合)。",
"label": "外部トリガーエンティティ"
},
"external_end_trigger_enabled": {
@@ -1338,7 +1396,7 @@
"label": "開始サービス"
},
"notify_timeout_seconds": {
"doc": "この秒数が経過すると、通知が自動的に閉じられます (通知をサポートしているプラットフォームの場合)。 0 は手動で終了するまで保持します。",
"doc": "この秒数が経過すると、通知が自動的に閉じられます (通知をサポートしているプラ ットフォームの場合)。 0 は手動で終了するまで保持します。",
"label": "自動消去まで"
},
"notify_title": {
@@ -1386,7 +1444,7 @@
"label": "最大時間比率"
},
"profile_match_min_duration_ratio": {
"doc": "プロファイルに対する最小サイクル長。 0.9 は、サイクルがプロファイル期間の少なくとも 90% でなければ一致しないことを意味します。",
"doc": "プロファイルに対する最小サイクル長。 0.9 は、サイクルがプロファイル期間の少なくとも 90% でな ければ一致しないことを意味します。",
"label": "最小時間比率"
},
"profile_match_threshold": {
@@ -1417,6 +1475,10 @@
"doc": "各サイクルの全電力トレースと一致するデバッグ データを保存します。トラブルシューティングには役立ちますが、ストレージ サイズが増加します。",
"label": "デバッグトレースを保存"
},
"smart_termination_duration_ratio": {
"doc": "一致したプログラムの想定所要時間のうち、どこまでサイクルが進んでから、電力低下時にスマート終了がサイクルを早期に終了できるかを指定します。想定所要時間はそのプログラムの平均値のため、実行時間が大きく変動する家電 (冬の冷たい給水と夏の温かい給水で変わる洗濯機、センサー乾燥式の乾燥機、負荷に依存するプログラムなど) では、全実行の約半数が平均より短く終わり、早期終了が働かず、フォールバックのタイムアウトによって数分遅れて終了するだけになります。こうしたマシンではこの値を下げて (例: 0.85)、早期終了が確実に作動するようにし、より慎重にしたい場合は 1.0 に近づけます。デフォルト (0.98、食器洗い機は 0.99) にするには空欄のままにします。サイクルを早めに終了することしかできず、遅らせることは決してなく、あいまいな一致や信頼度の低い一致では作動しません。",
"label": "スマート終了比率"
},
"smoothing_window": {
"doc": "生の電力信号がどの程度平滑化されるか。低 (2) は応答性は高くなりますが、ノイズが多くなります。高 (5) はスパイクを滑らかにしますが、ラグが追加されます。",
"label": "スムージングウィンドウ"
@@ -1551,6 +1613,10 @@
"dishwasher_end_spike_quiet_release": {
"label": "パッシブ乾燥の静音解除",
"doc": "サイクルが予想所要時間を過ぎた後、WashData が最終排水を待つのをやめてサイクルを終了するまでに、食器洗い機が静音状態(停止しきい値を下回る状態)を維持しなければならない時間です。遅れて発生する最終排水の前に長い無音の乾燥フェーズがあり、その排水が見逃されている場合は、この値を上げてください。ウィンドウを広げると、学習された所要時間が古い平均値に固定されず、季節変動(給水温度が低い=サイクルが長くなる)に追従できます。この設定は、内部の 30 分間の終了スパイク待機上限に対して待機時間を短縮することしかできず、延長することはありません。"
},
"profile_evidence_sources": {
"label": "プログラムを形づくるサイクル",
"doc": "各プログラムの電力カーブを作成し、完了したサイクルをそれと照合するために使用するサイクルの種類です。種類のチェックを外すと、その種類はプログラムに反映されなくなりますが、何も削除されません。サイクルはサイクル一覧に残り、ラベル付けや削除も引き続きできます。インポートしたデータを信頼できない場合に便利です。統計には影響しません。統計は常に、この機器が実際に実行したサイクルのみを数えます。すべてのチェックを外した場合は無視されます。裏付けとなるサイクルがないプログラムは、決してマッチングできないためです。"
}
},
"setting_group": {
@@ -1634,6 +1700,9 @@
},
"basic_configuration": {
"label": "基本設定"
},
"profile_evidence": {
"label": "プロファイルの根拠"
}
},
"status": {
@@ -1658,7 +1727,8 @@
"trimming": "トリム中…",
"splitting": "分割中…",
"deleting": "削除中…",
"imported": "インポート済み"
"imported": "インポート済み",
"preparing": "準備中…"
},
"tab": {
"advanced": "高度な",
@@ -1688,6 +1758,7 @@
"wrong_profile": "間違ったプロフィール"
},
"toast": {
"catalog_refreshed": "コミュニティカタログを更新しました",
"access_saved": "アクセス制御が保存されました",
"all_wiped": "すべてのデータが消去されました",
"analysis_complete_none": "分析が完了しました: 新しい提案はありません",
@@ -1699,7 +1770,7 @@
"cycle_labelled": "サイクルラベル付き",
"cycle_paused": "サイクルが一時停止されました",
"cycle_resumed": "サイクルが再開されました",
"cycle_trimmed": "サイクルトリ",
"cycle_trimmed": "サイクルトリミングしました",
"cycles_merged": "統合されたサイクル",
"envelope_rebuilt": "再構築されたエンベロープ",
"envelopes_rebuilt": "再構築された封筒",
@@ -1708,7 +1779,7 @@
"feedback_confirmed": "フィードバックが確認されました",
"feedback_dismissed": "フィードバックは却下されました",
"group_deleted": "グループが削除されました",
"group_name_required": "グループ名は必須です",
"group_name_required": "グループ名は必 須です",
"group_saved": "グループが保存されました",
"import_successful": "インポートは成功しました。統合のリロード",
"json_required": "JSONデータは必須です",
@@ -1793,7 +1864,9 @@
"store_download_failed": "ダウンロードに失敗しました: {error}",
"store_download_nothing": "ダウンロードする新しいものはありません - このセットアップは既にデバイスにあります。",
"export_selective_done": "エクスポートをダウンロードしました",
"import_selective_done": "{profiles} 件のプロファイルと {cycles} 件のサイクルをインポートしました"
"import_selective_done": "{profiles} 件のプロファイルと {cycles} 件のサイクルをインポートしました",
"hist_csv_required": "先に CSV ファイルを読み込むか、内容を貼り付けてください",
"file_read_failed": "そのファイルを読み込めませんでした"
},
"suggestion": {
"both_agree": "WashDataの推奨",
@@ -1889,7 +1962,7 @@
"thr_batch": "{cycles} サイクルにわたる p05 の最低稼働電力({p05}W)のすぐ上に設定。これにより開始をできるだけ早く捉え、停止しきい値は機器の最低稼働電力を下回ったままになります。",
"tol_per_profile": "{profiles} 件のプロファイル({cycles} サイクル)にわたるプロファイルごとの時間分散の p75。ばらつきの小さいプロファイルは不利になりません。",
"tol_pooled": "{cycles} 件の直近のラベル付きサイクルの統合時間分散に基づく(p95 偏差={dev})。",
"watchdog": "安全な範囲でできるだけ低く設定(p95 の更新間隔 {p95}s をわずかに上回る値、最小 30s)。誤った停止なしに停滞を素早く検出します。"
"watchdog": "安全な範囲でできるだけ低く設定(p95 の更新間隔 {p95}s をわずかに上回り、かつサンプリング間隔 {median}s の 2 倍以上、最小 30s)。誤った停止なしに停滞を素早く検出します。"
},
"exclusions": {
"summary": "{total} 件の誤検出サイクルを除外しました: {parts}。",
@@ -1955,6 +2028,10 @@
"finished": "サイクルが終了状態に達して終了しました。"
},
"store": {
"your_model_tip": "設定で指定した家電です",
"your_model": "自分の機種",
"search_brand_ph": "ブランドで検索…",
"programs_count": "プログラム: {n}",
"browse": "閲覧",
"device": "デバイス",
"favorites": "お気に入り",
@@ -1993,6 +2070,7 @@
"add_profile": "コミュニティサイトでこの家電のプロファイルを追加してください"
},
"task": {
"cancelling": "キャンセル中...",
"reprocess": {
"matching": "再処理: サイクルのマッチング",
"golden": "再処理: 基準サイクルの補完",
@@ -78,9 +78,12 @@
"awaiting": "승인 대기 중",
"imported_tip": "커뮤니티 스토어에서 가져왔습니다. 매칭에만 사용되며 통계에는 포함되지 않습니다.",
"not_importable": "해당 없음",
"exists": "존재함"
"exists": "존재함",
"backfilled_tip": "가져온 전력 이력에서 감지되었습니다. 프로그램 매칭에만 영향을 주며 통계에는 포함되지 않습니다."
},
"btn": {
"set_brand_model": "브랜드 및 모델 설정",
"refresh_catalog": "카탈로그 새로 고침",
"add_device": "+ 장치 추가",
"add_device_tip": "다른 WashData 장치 추가",
"add_maintenance": "유지보수 이벤트 추가",
@@ -90,7 +93,7 @@
"apply_label": "라벨 적용",
"apply_set_b": "세트 B 적용",
"apply_split": "분할 적용",
"apply_trim": "트림 적용",
"apply_trim": "자르기 적용",
"auto_detect_split": "자동 감지",
"auto_label_cycles": "사이클 자동 라벨 지정",
"auto_label_cycles_tip": "일치 신뢰도가 임계값을 초과하는 미라벨 주기에 프로필 이름을 자동으로 할당합니다",
@@ -209,8 +212,8 @@
"stop": "정지",
"submit_correction": "정정사항 제출",
"train_now": "지금 훈련",
"trim": "다듬기",
"trim_split": "다듬기/분할",
"trim": "자르기",
"trim_split": "자르기/분할",
"undo": "실행 취소",
"use": "사용",
"wipe_all": "모든 데이터 지우기",
@@ -241,7 +244,12 @@
"import_selected": "선택 항목 가져오기",
"back": "뒤로",
"mute_suggestion": "이 설정 제안 중지",
"reset_muted": "뮤트 초기화"
"reset_muted": "뮤트 초기화",
"import_power_history": "전력 이력 가져오기",
"hist_read_recorder": "Home Assistant에서 읽기",
"hist_scan": "사이클 검색",
"hist_import_n": "{n}개 사이클 가져오기",
"hist_goto_cycles": "사이클 보기"
},
"conflict": {
"anti_wrinkle_exit": {
@@ -253,12 +261,12 @@
"start": "구김 방지 최대 전력 ({max} W) 미만이어야 합니다"
},
"attn_sub": "저장하기 전에 충돌을 해결하세요",
"attn_title": "설정 충돌 {n}건{s}",
"attn_title": "설정 충돌: {n}",
"confidence": {
"auto": "매칭 임계값 ({match}) 이상이어야 합니다",
"learning": "매칭 임계값 ({match}) 이이어야 합니다",
"learning": "매칭 임계값 ({match}) 이이어야 합니다",
"match_for_auto": "자동 라벨 신뢰도 ({alc}) 이하이어야 합니다",
"match_for_learning": "학습 신뢰도 ({lc}) 이이어야 합니다"
"match_for_learning": "학습 신뢰도 ({lc}) 이이어야 합니다"
},
"duration_ratio": {
"max": "최소 기간 비율 ({min}) 보다 커야 합니다",
@@ -296,14 +304,14 @@
"match": "언매칭 임계값 ({un}) 이상이어야 합니다",
"unmatch": "매칭 임계값 ({match}) 미만이어야 합니다. 그렇지 않으면 확정된 일치가 즉시 해제됩니다"
},
"cascade_toast": "일관성을 위해 {n}개 설정{s}을 추가로 자동 조정했습니다.",
"cascade_toast": "일관성을 위해 조정된 다른 설정: {n}",
"suggestion_resolves": "이 문제를 해결하려면 아래의 보류 중인 제안({val})을 적용하세요",
"use_fix": "{val} 사용",
"watchdog": {
"interval": "샘플링 간격 ({si} 초)의 최소 2배이어야 합니다",
"sampling": "샘플링 간격은 워치독 간격 ({wi} 초)의 절반 이하이어야 합니다"
},
"settings_banner": "{n}건의 설정 충돌{s} 강조 표시된 섹션을 확인하고 저장 전에 수정하세요.",
"settings_banner": "설정 충돌: {n}. 강조 표시된 섹션을 확인하고 저장 전에 수정하세요.",
"settings_banner_btn": "첫 번째로"
},
"hdr": {
@@ -356,7 +364,8 @@
"pg_outcome": "시뮬레이션 결과",
"pg_across_cycles": "전체 사이클에 걸쳐",
"community_store": "커뮤니티 스토어",
"online_account": "커뮤니티 스토어 및 온라인 기능"
"online_account": "커뮤니티 스토어 및 온라인 기능",
"import_power_history": "전력 이력 가져오기"
},
"health": {
"fair": "프로파일 품질: 보통",
@@ -364,6 +373,7 @@
"poor": "⚠ 프로파일 품질: 불량"
},
"lbl": {
"drag_to_resize": "드래그하여 크기 조정",
"actions": "작업",
"activity": "활동",
"administrators": "관리자",
@@ -434,7 +444,7 @@
"from": "시작",
"gap_s": "간격(초)",
"group_name": "그룹 이름",
"head_trim": "헤드 트림(초)",
"head_trim": "시작 부분 자르기(초)",
"health": "건강",
"hide_tabs": "관리자가 아닌 사용자를 위한 탭 숨기기",
"in_use": "사용 중",
@@ -450,7 +460,7 @@
"metric": "지표",
"mode_existing_profile": "기존 프로필에 추가",
"mode_new_profile": "새 프로필 만들기",
"models_fine_tuned": "({count}개 모델{plural} 미세 조정됨)",
"models_fine_tuned": "(미세 조정된 모델: {count})",
"n_classic_suggestions": "{n} 클래식",
"n_ml_suggestions": "{n} ML",
"n_selected": "{n}개 선택됨",
@@ -532,7 +542,7 @@
"stage3": "3단계 DTW",
"stage4": "4단계 일치도",
"status": "상태",
"tail_trim": "테일 트림(초)",
"tail_trim": "끝부분 자르기(초)",
"timer_auto_pause": "자동 일시중지",
"timer_min": "분",
"timer_msg_placeholder": "메시지(선택사항, {device}/{program}/{minutes})",
@@ -650,7 +660,7 @@
"show_contributor": "기여자 이름 표시",
"task_pg_detail": "사이클 시뮬레이션",
"task_split": "사이클 분할 중",
"task_trim": "사이클 트리밍 중",
"task_trim": "사이클 자르는 중",
"task_merge": "사이클 병합 중",
"task_rebuild": "엔벨로프 재구성 중",
"cat_profiles": "프로필(프로그램)",
@@ -677,7 +687,26 @@
"conflict_import_copy": "사본으로 가져오기",
"conflict_keep_mine": "내 것 유지",
"conflict_overwrite": "덮어쓰기",
"font_size": "패널 글꼴 크기"
"font_size": "패널 글꼴 크기",
"hist_csv_data": "CSV 데이터",
"hist_from_recorder": "또는 Home Assistant에서 읽기",
"hist_since": "시작 날짜",
"days": "일",
"hist_keep": "이 사이클 유지",
"hist_looks_complete": "완전",
"peak_power_short": "피크",
"shape": "형태",
"hist_skip_idle": "작동 없음",
"hist_skip_sparse": "측정값 간격이 너무 넓음",
"hist_skip_short": "측정값이 너무 적음",
"hist_skip_long": "나눌 만큼 긴 공백이 없음",
"hist_reason_short": "이 가전의 실제 최단 사이클보다 짧음",
"hist_reason_no_end": "정상적으로 종료되지 않음",
"task_history_import": "전력 이력 검색",
"task_history_import_apply": "사이클 가져오기",
"evidence_real_cycles": "이 기기가 실행한 사이클",
"evidence_reference_cycles": "커뮤니티 스토어에서 다운로드",
"evidence_backfill_cycles": "가져온 전력 이력에서 발견"
},
"log": {
"all_levels": "모든 레벨",
@@ -756,9 +785,15 @@
"store_share": "커뮤니티 스토어에 공유",
"store_share_device": "이 기기 공유",
"export_select": "내보내기 - 데이터 선택",
"import_wizard": "가져오기 - 데이터 선택"
"import_wizard": "가져오기 - 데이터 선택",
"history_import": "전력 이력 가져오기"
},
"msg": {
"tail_trim_hint": "끝부분에서 제거할 초 수",
"store_sibling_hint": "정확히 같은 모델로 공유된 항목이 없나요? 같은 브랜드의 비슷한 모델이 보통 좋은 출발점이 됩니다.",
"store_declare_appliance": "보유한 가전제품을 WashData에 지정하면 이 탭에 다른 사용자가 공유한 프로그램과 녹음이 표시됩니다. 위에 브랜드를 입력해 둘러볼 수도 있습니다.",
"refresh_catalog_hint": "커뮤니티 브랜드 및 가전제품 목록은 공유 스토어가 일일 조회 한도를 넘지 않도록 캐시됩니다. 새로 고치면 다른 사용자가 추가하거나 승인한 항목을 가져옵니다.",
"head_trim_hint": "시작 부분에서 제거할 초 수",
"appliance_monitor": "가전제품 모니터",
"artifact_dip_detail": "일반 전력 범위 아래로 약 {n}초 동안 내려갔습니다.",
"artifact_footer": "위 그래프에 강조표시되어 있습니다. 이는 일시적인 아티팩트(예: 사이클 중간에 문이 열림)이며 반드시 문제가 되는 것은 아닙니다.",
@@ -769,7 +804,7 @@
"automations_intro": "WashData는 {start} / {end} 이벤트를 발생시키고 엔티티를 노출하므로, 알림과 동작은 일반 Home Assistant 자동화로 구축하는 것이 가장 좋습니다. 이 기기를 사용하는 자동화가 아래에 표시됩니다.",
"cleanup_intro": "라벨이 붙은 모든 사이클이 중첩됩니다. 이상값을 선택하고 삭제하여 프로필을 정리하세요.",
"clear_debug_hint": "저장된 디버그 데이터를 제거하여 여유 공간을 확보하세요.",
"collecting_data": "데이터 수집 중입니다. 미세 조정을 시작하려면 {need}번의 사이클{plural}이 더 필요합니다({current}/{min})。",
"collecting_data": "데이터 수집 중입니다. 미세 조정을 시작하기까지 더 필요한 사이클: {need} ({current}/{min}).",
"compare_overlay_profiles": "오버레이 프로필(희미함)",
"compare_profiles_tip": "위 차트에 다른 프로필 봉투를 겹쳐서 어느 것이 이 주기에 가장 적합한지 확인하세요.",
"compare_selected_cycles": "선택한 주기(단색) – 표시/숨기기",
@@ -779,7 +814,7 @@
"cycles_deleted": "{count}개 사이클이 삭제되었습니다",
"enough_data": "학습할 충분한 데이터가 있습니다({current}/{min}사이클)。",
"export_description": "JSON으로 내보낼 프로필, 사이클, 설정 등을 정확히 선택하거나, 파일을 분석하여 원하는 부분만 가져올 수 있습니다.",
"feedback_cycles_pending": "검토가 필요한 사이클 {n}개{s}",
"feedback_cycles_pending": "검토 대기: {n}",
"feedback_prompt": "그것이 옳았는지 확인하고, 프로그램을 수정하거나, 무시하십시오.",
"feedback_relabel_hint": "이 사이클을 다시 라벨 지정하면 이것도 해결됩니다.",
"filter_by_profile": "프로필로 필터링…",
@@ -856,7 +891,6 @@
"pg_stress_synthetic": "대기 시뮬레이션이 여기서 시작됩니다",
"pg_sweep_intro": "{param}이(가) 달랐다면 어땠을까요? 가장 많은 사이클이 올바르게 매칭되는 설정을 찾기 위해 최근 {cycles}개 사이클에서 {steps}개 값을 테스트합니다.",
"pg_sweep_step": "단계 {done} / {total}",
"pg_undetected": "{n}개 사이클{s} 미감지",
"pg_verdict_bad": "주의 필요: 많은 사이클이 감지되지 않고 있습니다.",
"pg_verdict_good": "잘 조정됨: 대부분의 사이클이 올바르게 식별되고 매칭됩니다.",
"pg_verdict_ok": "양호: 일부 사이클을 놓쳤습니다. 시작 임계값을 낮춰 보세요.",
@@ -887,6 +921,7 @@
"review_recorded_tip": "이를 프로그램에 대해 직접 선택한 참조 주기로 표시합니다. 이는 수동으로 기록된 주기와 동일한 역할입니다. 참조 순환은 항상 유지되고 일치하는 템플릿을 시드하며 정리로 인해 삭제되지 않습니다. (이것은 \"황금\"/기록된 플래그입니다. 둘 다 동일합니다.)",
"review_tags_tip": "이 주기에 무엇이 잘못되었는지 설명하는 선택적 플래그이므로 훈련과 정리가 이를 설명할 수 있습니다.",
"review_to_cycles": "사이클 검토 대기열 열기",
"samples_decimated": "{total}개 샘플 중 {shown}개 표시 중 (표시용으로 솎아냄; 피크는 유지). 여기서 넓은 간격은 솎아낸 것이며 누락된 데이터가 아닙니다.",
"saving_triggers_reload": "저장하면 통합 다시 로드가 트리거됩니다. HA 엔터티는 일시적으로 사용할 수 없는 것으로 표시될 수 있습니다.",
"search_placeholder": "검색 설정…",
"see_recorder": "아래의 녹음기 위젯을 참조하세요",
@@ -1006,7 +1041,29 @@
"sug_mute_failed": "제안을 음소거할 수 없습니다",
"sug_unmuted_all": "뮤트된 제안을 초기화했습니다",
"n_suggestions_muted": "{count}개 뮤트됨. 자동 튜너가 이 설정들을 제안하지 않습니다.",
"font_size_hint": "이 패널의 모든 내용을 크거나 작게 표시합니다. 이 기기의 내 계정에 적용됩니다."
"font_size_hint": "이 패널의 모든 내용을 크거나 작게 표시합니다. 이 기기의 내 계정에 적용됩니다.",
"import_history_description": "WashData를 사용하기 전에도 스마트 플러그를 쓰고 있었나요? 해당 전력 센서의 이력 내보내기 파일을 업로드하거나 Home Assistant에서 바로 읽어오면 평소와 같은 감지가 그 데이터에 실행되어, 과거 사이클이 사이클 목록에 나타나 이름을 지정할 수 있습니다.",
"hist_input_hint": "이력 패널에서 다운로드한 CSV(entity, state, last changed)를 업로드하거나, WashData가 센서 이력을 직접 읽도록 하세요. 그러면 실시간과 똑같은 감지가 실행되고, 찾은 사이클 중 어떤 것을 보관할지 직접 선택합니다.",
"hist_recorder_hint": "선택한 날짜부터 현재까지 읽습니다. Home Assistant는 기본적으로 상세 이력을 10일간 보관하고 그 이후에는 시간별 평균만 남기는데, 이는 사이클을 감지하기에 너무 거칩니다. recorder가 더 오래 보관하도록 설정되어 있을 때만 더 이전 날짜를 선택하세요.",
"hist_scanning": "이력을 감지기로 다시 재생하고 있습니다. 이 작업은 백그라운드에서 실행되므로 이 창을 닫고 나중에 다시 열어도 됩니다.",
"hist_imported_count": "{n}개 사이클을 가져왔습니다.",
"hist_duplicates": "{n}개는 이미 가져온 항목이라 건너뛰었습니다.",
"hist_capped": "기기당 가져온 사이클 한도에 도달하여 나머지는 저장되지 않았습니다.",
"hist_next_step": "가져온 이력으로 표시되어 사이클 목록에 있습니다. 하나를 열고 라벨 지정으로 해당 프로그램 이름을 지정하세요.",
"hist_rows_read": "측정값 {n}개 읽음",
"hist_entity_substituted": "{used}을(를) 읽었습니다 (이 기기에는 {wanted}이(가) 설정되어 있습니다)",
"hist_breaks": "센서를 사용할 수 없었던 공백 {n}곳",
"hist_other_entity": "다른 엔티티의 측정값 {n}개 무시됨",
"hist_skipped_spans": "건너뛴 구간",
"hist_settings_used": "이 기기의 현재 설정(최소 전력 {w} W, 오프 지연 {s}초)으로 감지했습니다.",
"hist_none_found": "해당 이력에서 사이클을 감지할 수 없었습니다.",
"hist_found": "{n}개 사이클을 찾았습니다. 실제 작동으로 보이지 않는 항목은 선택을 해제하세요. 가져오기 전에는 아무것도 저장되지 않습니다.",
"hist_scan_capped": "처음 후보만 표시합니다(총 {n}개 발견).",
"hist_recorder_empty": "Home Assistant에 해당 기간의 이 센서 상세 이력이 없습니다.",
"hist_scan_failed": "검색에 실패했습니다.",
"hist_scan_expired": "해당 검색 결과는 더 이상 사용할 수 없습니다. 다시 검색해 주세요.",
"hist_import_failed": "가져오기에 실패했습니다.",
"imported_history_readonly": "가져온 전력 이력에서 감지되었습니다. 프로그램 매칭에 반영되지만 통계에는 포함되지 않으며, 자르거나 분할할 수 없습니다. 라벨을 지정해 프로그램 이름을 정하세요."
},
"pg_desc": {
"completion_min_seconds": "실제 사이클로 인정되는 최단 실행",
@@ -1035,7 +1092,8 @@
"dtw_refine_top_n": "Stage 3: DTW가 재점수화하는 후보 수; 올바른 프로파일이 4-5위면 7-9로 높임(기본값 5)",
"duration_scale": "Stage 4: 지속 시간 일치 점수가 반으로 줄어드는 로그 비율; 작을수록 엄격한 패널티(기본값 0.175)",
"energy_scale": "Stage 4: 에너지 일치 점수가 반으로 줄어드는 로그 비율; 작을수록 엄격한 패널티(기본값 0.25)",
"dishwasher_end_spike_quiet_release": "식기세척기: 예상 소요 시간 이후 사이클 종료 배수 대기가 해제되기 전 조용히 유지되는 초"
"dishwasher_end_spike_quiet_release": "식기세척기: 예상 소요 시간 이후 사이클 종료 배수 대기가 해제되기 전 조용히 유지되는 초",
"smart_termination_duration_ratio": "일치된 프로그램의 예상 소요 시간 중 스마트 종료가 조기에 끝낼 수 있으려면 주기가 도달해야 하는 비율; 부하나 온도에 따라 달라지는 기기에서는 낮추십시오"
},
"phase_desc": {
"anti_crease": "메인 사이클 후 드럼이 간헐적으로 회전하여 의류 구김을 방지합니다.",
@@ -1417,6 +1475,10 @@
"doc": "각 사이클에 대해 전체 전력 추적 및 일치하는 디버그 데이터를 저장합니다. 문제 해결에 유용하지만 저장소 크기가 늘어납니다.",
"label": "디버그 추적 저장"
},
"smart_termination_duration_ratio": {
"doc": "전력이 떨어졌을 때 스마트 종료가 주기를 조기에 끝낼 수 있으려면, 일치된 프로그램의 예상 소요 시간 중 어느 정도까지 주기가 진행되어야 하는지를 지정합니다. 예상 소요 시간은 해당 프로그램의 평균값이므로, 실행 시간이 크게 달라지는 가전제품(겨울철 차가운 급수 대 여름철 따뜻한 급수의 세탁기, 센서 건조식 건조기, 부하에 따라 달라지는 프로그램)에서는 전체 실행의 약 절반이 그 평균보다 짧게 끝나 빠른 종료가 적용되지 않고, 폴백 시간 초과를 통해서만 몇 분 늦게 종료됩니다. 이러한 기기에서는 이 값을 낮춰(예: 0.85) 조기 종료가 계속 작동하도록 하고, 더 보수적으로 하려면 1.0에 가깝게 높이십시오. 기본값(0.98, 식기세척기는 0.99)을 사용하려면 비워 두십시오. 주기를 더 일찍 끝낼 수만 있고 더 늦출 수는 없으며, 모호하거나 신뢰도가 낮은 일치에서는 작동하지 않습니다.",
"label": "스마트 종료 비율"
},
"smoothing_window": {
"doc": "원시 전력 신호가 얼마나 평탄화되는지입니다. 낮음(2)은 반응이 좋지만 소음이 있습니다. 높음(5)은 스파이크를 부드럽게 하지만 지연을 추가합니다.",
"label": "스무딩 윈도우"
@@ -1551,6 +1613,10 @@
"dishwasher_end_spike_quiet_release": {
"label": "자연 건조 조용 시 해제",
"doc": "사이클이 예상 소요 시간을 지난 후, WashData가 최종 배수를 더 이상 기다리지 않고 사이클을 종료하기까지 식기세척기가 조용한 상태(중지 임계값 미만)를 유지해야 하는 시간입니다. 늦게 발생하는 최종 배수 전에 긴 무음 건조 단계가 있고 그 배수가 감지되지 않고 있다면 값을 높이세요. 창을 넓히면 학습된 소요 시간이 예전 평균값에 고정되지 않고 계절적 변동(급수 온도가 낮을수록 사이클이 길어짐)을 따라갈 수 있습니다. 이 설정은 내부의 30분 종료 스파이크 상한에 비해 대기 시간을 단축할 수만 있고 연장하지는 않습니다."
},
"profile_evidence_sources": {
"label": "프로그램을 형성하는 사이클",
"doc": "각 프로그램의 전력 곡선을 만들고 완료된 사이클을 그것과 매칭할 때 사용할 사이클 종류입니다. 종류의 선택을 해제하면 해당 종류는 더 이상 프로그램에 반영되지 않지만 아무것도 삭제되지 않습니다. 사이클은 사이클 목록에 그대로 남아 있으며 계속 라벨을 지정하거나 삭제할 수 있습니다. 가져온 데이터를 신뢰할 수 없을 때 유용합니다. 통계에는 영향이 없습니다. 통계는 항상 이 기기가 실제로 실행한 사이클만 계산합니다. 모두 선택 해제하면 무시됩니다. 근거가 되는 사이클이 없는 프로그램은 결코 매칭될 수 없기 때문입니다."
}
},
"setting_group": {
@@ -1634,6 +1700,9 @@
},
"basic_configuration": {
"label": "기본 구성"
},
"profile_evidence": {
"label": "프로필 근거"
}
},
"status": {
@@ -1655,10 +1724,11 @@
"analyzing": "분석 중…",
"resetting": "재설정 중…",
"reverting": "되돌리는 중…",
"trimming": "다듬는 중…",
"trimming": "자르는 중…",
"splitting": "분할 중…",
"deleting": "삭제 중…",
"imported": "가져옴"
"imported": "가져옴",
"preparing": "준비 중…"
},
"tab": {
"advanced": "고급",
@@ -1688,6 +1758,7 @@
"wrong_profile": "잘못된 프로필"
},
"toast": {
"catalog_refreshed": "커뮤니티 카탈로그를 새로 고쳤습니다",
"access_saved": "액세스 제어가 저장되었습니다.",
"all_wiped": "모든 데이터가 지워졌습니다.",
"analysis_complete_none": "분석 완료: 새로운 제안 없음",
@@ -1699,7 +1770,7 @@
"cycle_labelled": "라벨이 붙은 사이클",
"cycle_paused": "주기가 일시중지됨",
"cycle_resumed": "사이클 재개",
"cycle_trimmed": "주기가 잘림",
"cycle_trimmed": "사이클을 잘랐습니다",
"cycles_merged": "사이클이 병합되었습니다.",
"envelope_rebuilt": "봉투 재구축",
"envelopes_rebuilt": "봉투 재구축",
@@ -1793,7 +1864,9 @@
"store_download_failed": "다운로드 실패: {error}",
"store_download_nothing": "다운로드할 새 항목 없음 - 이 설정은 이미 기기에 있습니다.",
"export_selective_done": "내보내기 다운로드 완료",
"import_selective_done": "{profiles}개 프로필과 {cycles}개 사이클을 가져왔습니다"
"import_selective_done": "{profiles}개 프로필과 {cycles}개 사이클을 가져왔습니다",
"hist_csv_required": "먼저 CSV 파일을 불러오거나 내용을 붙여넣으세요",
"file_read_failed": "해당 파일을 읽을 수 없습니다"
},
"suggestion": {
"both_agree": "WashData 권장",
@@ -1889,7 +1962,7 @@
"thr_batch": "{cycles} 사이클의 p05 최저 활성 전력({p05}W) 바로 위로 유지합니다. 그래서 시작을 최대한 빨리 포착하고, 정지 임계값은 기기의 최저 작동 전력보다 낮게 유지됩니다.",
"tol_per_profile": "{profiles}개 프로필({cycles} 사이클)의 프로필별 시간 분산 p75. 편차가 작은 프로필은 불이익을 받지 않습니다.",
"tol_pooled": "{cycles}개 최근 라벨 사이클의 통합 시간 분산 기반(p95 편차={dev}).",
"watchdog": "안전한 범위에서 최대한 낮게 유지(p95 업데이트 간격 {p95}s보다 약간 큰 값, 최소 30s). 잘못된 정지 없이 멈춤을 빠르게 감지합니다."
"watchdog": "안전한 범위에서 최대한 낮게 유지(p95 업데이트 간격 {p95}s보다 약간 크고, 샘플링 간격 {median}s의 2배 이상, 최소 30s). 잘못된 정지 없이 멈춤을 빠르게 감지합니다."
},
"exclusions": {
"summary": "잘못 감지된 사이클 {total}개를 제외했습니다: {parts}.",
@@ -1955,6 +2028,10 @@
"finished": "사이클이 종료 상태에 도달하여 끝났습니다."
},
"store": {
"your_model_tip": "설정에서 지정한 가전제품입니다",
"your_model": "내 기기",
"search_brand_ph": "브랜드로 검색…",
"programs_count": "프로그램: {n}",
"browse": "탐색",
"device": "기기",
"favorites": "즐겨찾기",
@@ -2010,7 +2087,7 @@
"apply": "사이클 분할 중"
},
"trim": {
"apply": "사이클 트리밍 중"
"apply": "사이클 자르는 중"
},
"merge": {
"apply": "사이클 병합 중"
@@ -78,9 +78,12 @@
"awaiting": "Laukiama patvirtinimo",
"imported_tip": "Importuota iš bendruomenės parduotuvės. Naudojama tik atitikčiai, neįskaičiuojama į statistiką.",
"not_importable": "čia nepasiekiama",
"exists": "jau yra"
"exists": "jau yra",
"backfilled_tip": "Aptikta importuotoje galios istorijoje. Turi įtakos tik programų atpažinimui, neįskaičiuojama į statistiką."
},
"btn": {
"set_brand_model": "Nustatyti prekės ženklą ir modelį",
"refresh_catalog": "Atnaujinti katalogą",
"add_device": "+ Pridėti įrenginį",
"add_device_tip": "Pridėkite kitą WashData įrenginį",
"add_maintenance": "Pridėti priežiūros įvykį",
@@ -241,7 +244,12 @@
"import_selected": "Importuoti pasirinktus",
"back": "Atgal",
"mute_suggestion": "Nebesiūlyti šio nustatymo",
"reset_muted": "Atstatyti nutildytus"
"reset_muted": "Atstatyti nutildytus",
"import_power_history": "Importuoti galios istoriją",
"hist_read_recorder": "Nuskaityti iš Home Assistant",
"hist_scan": "Ieškoti ciklų",
"hist_import_n": "Importuoti ciklus ({n})",
"hist_goto_cycles": "Parodyti ciklus"
},
"conflict": {
"anti_wrinkle_exit": {
@@ -253,14 +261,14 @@
"start": "Turi būti žemiau maksimalios apsaugos nuo raukšlių galios ({max} W)"
},
"attn_sub": "Prieš išsaugant ištaisykite konfliktus",
"attn_title": "{n} nustatymų konfliktas{s}",
"settings_banner": "{n} nustatymų konfliktas{s} patikrinkite pažymėtas sekcijas ir ištaisykite prieš išsaugant.",
"attn_title": "Nustatymų konfliktai: {n}",
"settings_banner": "Nustatymų konfliktai: {n}. Patikrinkite pažymėtas sekcijas ir ištaisykite jas prieš išsaugant.",
"settings_banner_btn": "Eiti į pirmą",
"confidence": {
"auto": "Turi būti lygus arba aukščiau atitikimo slenksčio ({match})",
"learning": "Turi būti lygus arba žemiau atitikimo slenksčio ({match})",
"learning": "Turi būti lygus arba aukščiau atitikimo slenksčio ({match})",
"match_for_auto": "Turi būti lygus arba žemiau automatinio žymėjimo pasitikėjimo ({alc})",
"match_for_learning": "Turi būti lygus arba aukščiau mokymosi pasitikėjimo ({lc})"
"match_for_learning": "Turi būti lygus arba žemiau mokymosi pasitikėjimo ({lc})"
},
"duration_ratio": {
"max": "Turi būti daugiau nei minimalaus trukmės santykio ({min})",
@@ -298,7 +306,7 @@
"match": "Turi būti aukščiau neatitikimo slenksčio ({un})",
"unmatch": "Turi būti žemiau atitikimo slenksčio ({match}); priešingu atveju patvirtintas atitikimas iškart panaikinamas"
},
"cascade_toast": "Taip pat automatiškai pakoreguoti {n} nustatymai dėl nuoseklumo.",
"cascade_toast": "Dėl nuoseklumo pakoreguoti ir kiti nustatymai: {n}",
"suggestion_resolves": "Pritaikykite žemiau esantį laukiantį pasiūlymą ({val}), kad tai ištaisytumėte",
"use_fix": "Naudoti {val}",
"watchdog": {
@@ -356,7 +364,8 @@
"pg_outcome": "Simuliacijos rezultatas",
"pg_across_cycles": "Per visus jūsų ciklus",
"community_store": "Bendruomenės parduotuvė",
"online_account": "Bendruomenės parduotuvė ir interneto funkcijos"
"online_account": "Bendruomenės parduotuvė ir interneto funkcijos",
"import_power_history": "Galios istorijos importavimas"
},
"health": {
"fair": "Priimtina profilio kokybė",
@@ -364,6 +373,7 @@
"poor": "⚠ Prasta profilio kokybė"
},
"lbl": {
"drag_to_resize": "Vilkite, kad pakeistumėte dydį",
"pg_anti_wrinkle": "Apsauga nuo raukšlių",
"actions": "Veiksmai",
"activity": "Veikla",
@@ -435,7 +445,7 @@
"from": "Nuo",
"gap_s": "Tarpas (-iai)",
"group_name": "Grupės pavadinimas",
"head_trim": "Galvos apdaila (-ai)",
"head_trim": "Apkarpymas nuo pradžios (s)",
"health": "Sveikata",
"hide_tabs": "Slėpti skirtukus ne administratoriams",
"in_use": "Naudojamas",
@@ -451,7 +461,7 @@
"metric": "Metrika",
"mode_existing_profile": "Pridėti prie esamo profilio",
"mode_new_profile": "Sukurti naują profilį",
"models_fine_tuned": "({count} modeliai tiksliai sureguliuoti)",
"models_fine_tuned": "(tiksliai suderinti modeliai: {count})",
"n_classic_suggestions": "{n} klasikinis",
"n_ml_suggestions": "{n} ML",
"n_selected": "Pasirinkta: {n}",
@@ -532,7 +542,7 @@
"stage3": "3 etapas DTW",
"stage4": "4 etapas atitikimas",
"status": "Būsena",
"tail_trim": "Uodegos apdaila (-ai)",
"tail_trim": "Apkarpymas nuo galo (s)",
"timer_auto_pause": "Automatinis pristabdymas",
"timer_min": "min",
"timer_msg_placeholder": "Pranešimas (pasirenkama, {device}/{program}/{minutes})",
@@ -677,7 +687,26 @@
"conflict_import_copy": "Importuoti kaip kopiją",
"conflict_keep_mine": "Išlaikyti manuosius",
"conflict_overwrite": "Perrašyti",
"font_size": "Skydelio šrifto dydis"
"font_size": "Skydelio šrifto dydis",
"hist_csv_data": "CSV duomenys",
"hist_from_recorder": "Arba nuskaitykite iš Home Assistant",
"hist_since": "Nuo",
"days": "d.",
"hist_keep": "Palikti šį ciklą",
"hist_looks_complete": "užbaigtas",
"peak_power_short": "Pikas",
"shape": "Forma",
"hist_skip_idle": "niekas neveikė",
"hist_skip_sparse": "per reti rodmenys",
"hist_skip_short": "per mažai rodmenų",
"hist_skip_long": "nėra pakankamai ilgos pauzės padalijimui",
"hist_reason_short": "trumpesnis nei trumpiausias tikras šio prietaiso ciklas",
"hist_reason_no_end": "niekada tvarkingai nepasibaigė",
"task_history_import": "Skenuojama galios istorija",
"task_history_import_apply": "Importuojami ciklai",
"evidence_real_cycles": "Šio prietaiso atlikti ciklai",
"evidence_reference_cycles": "Atsisiųsti iš bendruomenės parduotuvės",
"evidence_backfill_cycles": "Rasti importuotoje galios istorijoje"
},
"log": {
"all_levels": "Visi lygiai",
@@ -756,9 +785,15 @@
"store_share": "Bendrinti bendruomenės parduotuvėje",
"store_share_device": "Bendrinti šį įrenginį",
"export_select": "Eksportas - pasirinkti duomenis",
"import_wizard": "Importas - pasirinkti duomenis"
"import_wizard": "Importas - pasirinkti duomenis",
"history_import": "Galios istorijos importavimas"
},
"msg": {
"tail_trim_hint": "Kiek sekundžių pašalinti nuo galo",
"store_sibling_hint": "Jūsų tiksliam modeliui nieko nebendrinta? Artimas to paties prekės ženklo modelis paprastai yra gera pradžia.",
"store_declare_appliance": "Nurodykite WashData, kurį prietaisą turite, ir šiame skirtuke bus rodomos kitų jam bendrintos programos bei įrašai. Taip pat galite viršuje įrašyti prekės ženklą ir tiesiog pasižiūrėti.",
"refresh_catalog_hint": "Bendruomenės prekės ženklų ir prietaisų sąrašai laikomi podėlyje, kad bendrinama parduotuvė neviršytų savo dienos užklausų limito. Atnaujinkite, kad pamatytumėte kitų pridėtus ar patvirtintus įrašus.",
"head_trim_hint": "Kiek sekundžių pašalinti nuo pradžios",
"appliance_monitor": "Prietaisų monitorius",
"artifact_dip_detail": "Nukrito žemiau įprastos galios juostos maždaug {n}s.",
"artifact_footer": "Paryškinta aukščiau esančiame grafike. Tai yra trumpalaikiai artefaktai (pvz., durys atidarytos ciklo viduryje), nebūtinai problemos.",
@@ -769,7 +804,7 @@
"automations_intro": "WashData paleidžia {start} / {end} įvykius ir atskleidžia esybes, todėl pranešimai ir veiksmai geriausiai kuriami kaip įprasti Home Assistant automatizavimai. Žemiau rodomi automatizavimai, naudojantys šį prietaisą.",
"cleanup_intro": "Kiekvienas pažymėtas ciklas padengtas. Pažymėkite nuokrypius ir ištrinkite, kad išvalytumėte profilį.",
"clear_debug_hint": "Pašalinkite saugomus derinimo duomenis, kad atlaisvintumėte vietos.",
"collecting_data": "Renkami duomenys - reikia dar {need} ciklų, kad galėtų prasidėti tikslus derinimas ({current}/{min}).",
"collecting_data": "Renkami duomenys. Dar reikia ciklų, kad galėtų prasidėti tikslus derinimas: {need} ({current}/{min}).",
"compare_overlay_profiles": "Perdangos profiliai (blankūs)",
"compare_profiles_tip": "Aukščiau pateiktoje diagramoje uždėkite kitus profilio vokus, kad sužinotumėte, kuris iš jų geriausiai tinka šiam ciklui.",
"compare_selected_cycles": "Pasirinkti ciklai (vientisas) rodyti / slėpti",
@@ -779,7 +814,7 @@
"cycles_deleted": "Ištrinta ciklų: {count}",
"enough_data": "Pakankamai duomenų mokymui ({current}/{min} ciklų).",
"export_description": "Pasirinkite tiksliai, kuriuos profilius, ciklus, nustatymus ir kita eksportuoti į JSON, arba išanalizuokite failą ir importuokite tik norimas dalis.",
"feedback_cycles_pending": "{n} cikl{s} peržiūrai",
"feedback_cycles_pending": "Peržiūrai: {n}",
"feedback_prompt": "Patvirtinkite, kad tai buvo teisinga, pataisykite programą arba ignoruokite.",
"feedback_relabel_hint": "Šio ciklo pažymėjimas iš naujo taip pat išsprendžia peržiūrą.",
"filter_by_profile": "Filtruoti pagal profilį…",
@@ -856,7 +891,6 @@
"pg_stress_synthetic": "budėjimo imitacija prasideda čia",
"pg_sweep_intro": "O kas, jei {param} būtų kitokia? Išbandykite {steps} reikšmes paskutiniuose {cycles} cikluose ir raskite nustatymą, su kuriuo teisingai atitinka daugiausiai ciklų.",
"pg_sweep_step": "Žingsnis {done} / {total}",
"pg_undetected": "Neaptikta ciklų: {n}",
"pg_verdict_bad": "Reikia dėmesio: daugelis ciklų lieka neaptikti.",
"pg_verdict_good": "Gerai suderinta: dauguma ciklų teisingai atpažįstami ir atitinkami.",
"pg_verdict_ok": "Priimtina: kai kurie ciklai praleisti. Pabandykite sumažinti paleidimo slenkstį.",
@@ -887,6 +921,7 @@
"review_recorded_tip": "Pažymėkite tai kaip savo programos etaloninį ciklą tą patį vaidmenį kaip ir rankiniu būdu įrašytą ciklą. Etaloniniai ciklai visada išsaugomi, imamasi atitinkamo šablono ir niekada nenuleidžiami valant. (Tai yra „auksinė“ / įrašyta vėliava; abi yra tas pats.)",
"review_tags_tip": "Pasirenkamos vėliavėlės, nurodančios, kas nutiko šiame cikle, todėl mokymai ir valymas gali tai paaiškinti.",
"review_to_cycles": "Atidarykite ciklų peržiūros eilę",
"samples_decimated": "Rodoma {shown} iš {total} pavyzdžių (praretinta rodymui; smailės išsaugotos). Platus tarpas čia yra praretinimas, o ne trūkstami duomenys.",
"saving_triggers_reload": "Išsaugojus suaktyvinamas integracijos įkėlimas iš naujo. HA objektai trumpam gali būti rodomi kaip nepasiekiami.",
"search_placeholder": "Paieškos nustatymai…",
"see_recorder": "Žiūrėkite įrašymo valdiklį žemiau",
@@ -1006,7 +1041,29 @@
"sug_mute_failed": "Nepavyko nutildyti pasiūlymo",
"sug_unmuted_all": "Nutildyti pasiūlymai atstatyti",
"n_suggestions_muted": "{count} nutildyti; automatinis derintuvas jų nebesiūlys.",
"font_size_hint": "Padidinkite arba sumažinkite visą tekstą šiame skydelyje. Galioja jūsų paskyrai šiame įrenginyje."
"font_size_hint": "Padidinkite arba sumažinkite visą tekstą šiame skydelyje. Galioja jūsų paskyrai šiame įrenginyje.",
"import_history_description": "Išmanųjį kištuką turėjote dar prieš WashData? Įkelkite jo galios sensoriaus istorijos eksportą arba nuskaitykite ją tiesiai iš Home Assistant, ir įprastas aptikimas peržiūrės tuos duomenis, todėl ankstesni ciklai atsiras jūsų „Ciklai“ sąraše ir juos bus galima pavadinti.",
"hist_input_hint": "Įkelkite CSV, atsisiųstą iš „Istorijos“ skydelio (objektas, būsena, paskutinis pakeitimas), arba leiskite WashData nuskaityti sensoriaus istoriją tiesiogiai. Tada aptikimas vykdomas lygiai taip pat kaip realiu laiku, o jūs pasirenkate, kuriuos rastus ciklus palikti.",
"hist_recorder_hint": "Nuskaito nuo jūsų pasirinktos datos iki dabar. Home Assistant pagal numatytuosius nustatymus išsamią istoriją saugo 10 dienų, o vėliau tik valandinius vidurkius, kurie yra per stambūs, kad iš jų būtų galima aptikti ciklus - senesnę datą rinkitės tik tuo atveju, jei jūsų recorder nustatytas saugoti ilgiau.",
"hist_scanning": "Jūsų istorija leidžiama per detektorių. Tai vykdoma fone - galite užverti šį dialogą ir sugrįžti vėliau.",
"hist_imported_count": "Importuota ciklų: {n}.",
"hist_duplicates": "Jau anksčiau importuota ir praleista: {n}.",
"hist_capped": "Pasiektas šio įrenginio importuotų ciklų limitas; likusieji neišsaugoti.",
"hist_next_step": "Jie yra jūsų „Ciklai“ sąraše, pažymėti kaip importuota istorija. Atverkite vieną ir paspauskite „Pažymėti“, kad nurodytumėte jo programą.",
"hist_rows_read": "Nuskaityta rodmenų: {n}",
"hist_entity_substituted": "nuskaityta {used} (šiam įrenginiui sukonfigūruotas {wanted})",
"hist_breaks": "Tarpai, kai sensorius buvo nepasiekiamas: {n}",
"hist_other_entity": "Praleisti kitų objektų rodmenys: {n}",
"hist_skipped_spans": "Praleistos atkarpos",
"hist_settings_used": "Aptikta naudojant esamus šio įrenginio nustatymus (minimali galia {w} W, išjungimo delsimas {s} s).",
"hist_none_found": "Toje istorijoje nepavyko aptikti nė vieno ciklo.",
"hist_found": "Rasta ciklų: {n}. Atžymėkite tai, kas neatrodo kaip tikras paleidimas - kol neimportuojate, nieko neišsaugoma.",
"hist_scan_capped": "Rodomi tik pirmieji kandidatai (rasta: {n}).",
"hist_recorder_empty": "Home Assistant neturi išsamios šio sensoriaus istorijos tuo laikotarpiu.",
"hist_scan_failed": "Skenavimas nepavyko.",
"hist_scan_expired": "To skenavimo rezultatų jau nėra. Nuskenuokite dar kartą.",
"hist_import_failed": "Importavimas nepavyko.",
"imported_history_readonly": "Aptikta importuotoje galios istorijoje. Tai daro įtaką programų atpažinimui, bet neįskaičiuojama į jūsų statistiką, o ciklo negalima apkarpyti ar padalyti. Paspauskite „Pažymėti“, kad nurodytumėte programą."
},
"phase_desc": {
"anti_crease": "Po pagrindinio ciklo būgnas intermitiškai sukasi, kad išvengtų audinių raukšlių.",
@@ -1392,6 +1449,10 @@
"doc": "Išsaugokite visą galios pėdsaką ir atitinkamus kiekvieno ciklo derinimo duomenis. Naudinga trikčių šalinimui, bet padidina saugyklos dydį.",
"label": "Įrašyti derinimo pėdsakus"
},
"smart_termination_duration_ratio": {
"doc": "Kaip toli į atitiktos programos numatytą trukmę ciklas turi būti pažengęs, kad išmanusis užbaigimas galėtų jį užbaigti anksčiau, kai sumažėja galia. Numatyta trukmė yra programos vidurkis, todėl prietaisuose, kurių veikimo laikas labai svyruoja - skalbyklės su šaltu žiemos ir šiltu vasaros tiekiamu vandeniu, jutiklinio džiovinimo džiovyklės, nuo apkrovos priklausančios programos - maždaug pusė visų paleidimų baigiasi trumpiau nei šis vidurkis ir niekada nesulaukia greito užbaigimo, o baigiasi tik per atsarginį skirtąjį laiką, kelias minutes vėliau. Sumažinkite tai (pvz., 0,85) tose mašinose, kad ankstyvas užbaigimas vis tiek suveiktų; padidinkite jį link 1,0, kad veiktų atsargiau. Palikite tuščią numatytajai vertei (0,98 arba 0,99 indaplovėms). Jis gali užbaigti ciklą tik anksčiau, niekada ne vėliau, ir niekada nesuveikia esant neaiškiai ar mažo patikimumo atitikčiai.",
"label": "Išmaniojo užbaigimo santykis"
},
"smoothing_window": {
"doc": "Kiek išlyginamas neapdorotos galios signalas. Žemas (2) yra jautrus, bet triukšmingas; aukštas (5) išlygina smailes, bet padidina atsilikimą.",
"label": "Išlyginimo langas"
@@ -1522,6 +1583,10 @@
"door_end_dwell_seconds": {
"label": "Durų atidarymo pabaigos laukimas",
"doc": "Kiek laiko durys turi likti atviros, kad WashData užbaigtų ciklą, kai įjungta parinktis \"Durys automatiškai atsidaromos pabaigoje\". Pakankamai ilgai, kad ignoruotų greitai dedamą indą (numatytasis 60 s), pakankamai trumpai, kad greitai užbaigtų, kai prietaisas atidaro duris."
},
"profile_evidence_sources": {
"label": "Ciklai, formuojantys programą",
"doc": "Kurie ciklai naudojami kiekvienos programos galios kreivei sudaryti ir baigtam ciklui su ja palyginti. Atžymėjus tam tikrą rūšį, ji nebeturi įtakos jūsų programoms, tačiau nieko neištrinama - ciklai lieka sąraše Ciklai ir juos vis tiek galima pažymėti arba ištrinti. Naudinga, jei nepasitikite importuotais duomenimis. Statistikai tai neturi įtakos: joje visada įskaičiuojami tik tie ciklai, kuriuos šis prietaisas tikrai atliko. Visų žymių pašalinimas ignoruojamas, nes programa be jokių ciklų niekada negalėtų būti atpažinta."
}
},
"setting_group": {
@@ -1605,6 +1670,9 @@
},
"basic_configuration": {
"label": "Pagrindinė konfigūracija"
},
"profile_evidence": {
"label": "Profilio duomenys"
}
},
"status": {
@@ -1629,7 +1697,8 @@
"trimming": "Apkarpoma…",
"splitting": "Padalijama…",
"deleting": "Trinama…",
"imported": "Importuota"
"imported": "Importuota",
"preparing": "Ruošiama…"
},
"tab": {
"advanced": "Išplėstinė",
@@ -1659,6 +1728,7 @@
"wrong_profile": "Neteisingas profilis"
},
"toast": {
"catalog_refreshed": "Bendruomenės katalogas atnaujintas",
"access_saved": "Prieigos valdymas išsaugotas",
"all_wiped": "Visi duomenys ištrinti",
"analysis_complete_none": "Analizė baigta: jokių naujų pasiūlymų",
@@ -1764,7 +1834,9 @@
"store_download_failed": "Atsisiuntimas nepavyko: {error}",
"store_download_nothing": "Nieko naujo atsisiųsti -- ši konfigūracija jau yra jūsų įrenginyje.",
"export_selective_done": "Eksportas atsisiųstas",
"import_selective_done": "Importuota {profiles} profilių ir {cycles} ciklų"
"import_selective_done": "Importuota {profiles} profilių ir {cycles} ciklų",
"hist_csv_required": "Pirmiausia įkelkite CSV failą arba įklijuokite jo turinį",
"file_read_failed": "Nepavyko nuskaityti to failo"
},
"suggestion": {
"both_agree": "WashData rekomenduoja",
@@ -1860,7 +1932,7 @@
"thr_batch": "Paliktas šiek tiek virš p05 mažiausios aktyvios galios per {cycles} ciklus ({p05}W), kad pradžia būtų aptikta kuo anksčiau, o sustabdymo slenkstis liktų žemiau mažiausios veikiančios mašinos galios.",
"tol_per_profile": "p75 kiekvieno profilio trukmės dispersijos per {profiles} profilius ({cycles} ciklai); stabilūs profiliai nebaudžiami.",
"tol_pooled": "Pagrįsta sujungta {cycles} naujausių pažymėtų ciklų trukmės dispersija (p95 nuokrypis={dev}).",
"watchdog": "Paliktas kuo mažesnis, kiek saugu (vos didesnis nei p95 atnaujinimo tarpas {p95}s, min. 30s), kad strigtys būtų aptiktos greitai be klaidingų sustabdymų."
"watchdog": "Paliktas kuo mažesnis, kiek saugu (vos didesnis nei p95 atnaujinimo tarpas {p95}s ir bent 2x mėginių ėmimo intervalas {median}s, min. 30s), kad strigtys būtų aptiktos greitai be klaidingų sustabdymų."
},
"exclusions": {
"summary": "Neįtraukta {total} klaidingai aptiktų ciklų: {parts}.",
@@ -1892,6 +1964,7 @@
},
"pg_desc": {
"dishwasher_end_spike_quiet_release": "Indaplovė: tylos sekundės po numatytos trukmės, kol atleidžiamas ciklo pabaigos vandens išleidimo laukimas",
"smart_termination_duration_ratio": "Atitiktos programos numatytos trukmės dalis, kurią ciklas turi pasiekti, kad išmanusis užbaigimas galėtų jį užbaigti anksčiau; sumažinkite ją nuo apkrovos ar temperatūros priklausančioms mašinoms",
"anti_wrinkle_enabled": "Sugerkite būgninius impulsus po pagrindinės fazės, o ne skaitykite juos kaip naujus ciklus",
"anti_wrinkle_exit_power": "Kad apsauga nuo raukšlių išliktų aktyvi, galia tarp impulsų turi nukristi žemiau šios ribos",
"anti_wrinkle_idle_timeout": "Tylos laikas, leidžiamas tarp dviejų būgninių impulsų prieš pasibaigiant apsaugai nuo raukšlių",
@@ -1955,6 +2028,10 @@
"finished": "Ciklas pasiekė galutinę būseną ir baigėsi."
},
"store": {
"your_model_tip": "Tai prietaisas, kurį nurodėte nustatymuose",
"your_model": "Jūsų modelis",
"search_brand_ph": "Ieškoti pagal prekės ženklą…",
"programs_count": "Programos: {n}",
"browse": "Naršyti",
"device": "Prietaisas",
"favorites": "Mėgstamiausi",
@@ -78,9 +78,12 @@
"awaiting": "Gaida apstiprinājumu",
"imported_tip": "Importēts no kopienas veikala. Izmanto tikai saskaņošanai, netiek ieskaitīts statistikā.",
"not_importable": "šeit nav pieejams",
"exists": "jau eksistē"
"exists": "jau eksistē",
"backfilled_tip": "Noteikts importētā jaudas vēsturē. Ietekmē tikai programmu saskaņošanu, netiek ieskaitīts statistikā."
},
"btn": {
"set_brand_model": "Iestatīt zīmolu un modeli",
"refresh_catalog": "Atsvaidzināt katalogu",
"add_device": "+ Pievienot ierīci",
"add_device_tip": "Pievienojiet citu WashData ierīci",
"add_maintenance": "Pievienot apkopes notikumu",
@@ -241,7 +244,12 @@
"import_selected": "Importēt atlasītos",
"back": "Atpakaļ",
"mute_suggestion": "Pārtraukt ieteikt šo iestatījumu",
"reset_muted": "Atiestatīt klusinātos"
"reset_muted": "Atiestatīt klusinātos",
"import_power_history": "Importēt jaudas vēsturi",
"hist_read_recorder": "Nolasīt no Home Assistant",
"hist_scan": "Meklēt ciklus",
"hist_import_n": "Importēt ciklus ({n})",
"hist_goto_cycles": "Parādīt ciklus"
},
"conflict": {
"anti_wrinkle_exit": {
@@ -253,14 +261,14 @@
"start": "Jābūt zem maksimālās pretgrumbu jaudas ({max} W)"
},
"attn_sub": "Pirms saglabāšanas novērsiet konfliktus",
"attn_title": "{n} iestatījumu konflikts{s}",
"settings_banner": "{n} iestatījumu konflikts{s} pārbaudiet iezīmētās sadaļas un labojiet pirms saglabāšanas.",
"attn_title": "Iestatījumu konflikti: {n}",
"settings_banner": "Iestatījumu konflikti: {n}. Pārbaudiet iezīmētās sadaļas un labojiet tās pirms saglabāšanas.",
"settings_banner_btn": "Doties uz pirmo",
"confidence": {
"auto": "Jābūt vienādam vai virs atbilstības sliekšņa ({match})",
"learning": "Jābūt vienādam vai zem atbilstības sliekšņa ({match})",
"learning": "Jābūt vienādam vai virs atbilstības sliekšņa ({match})",
"match_for_auto": "Jābūt vienādam vai zem automātiskās marķēšanas pārliecības ({alc})",
"match_for_learning": "Jābūt vienādam vai virs mācīšanās pārliecības ({lc})"
"match_for_learning": "Jābūt vienādam vai zem mācīšanās pārliecības ({lc})"
},
"duration_ratio": {
"max": "Jābūt lielākam par minimālo ilguma attiecību ({min})",
@@ -298,7 +306,7 @@
"match": "Jābūt virs neatbilstības sliekšņa ({un})",
"unmatch": "Jābūt zem atbilstības sliekšņa ({match}); pretējā gadījumā apstiprināta atbilstība uzreiz tiek atcelta"
},
"cascade_toast": "Automātiski tika koriģēti arī {n} iestatījumi konsekvences labad.",
"cascade_toast": "Konsekvences labad pielāgoti arī citi iestatījumi: {n}",
"suggestion_resolves": "Lai to labotu, lietojiet zemāk esošo gaidošo ieteikumu ({val})",
"use_fix": "Izmantot {val}",
"watchdog": {
@@ -356,7 +364,8 @@
"pg_outcome": "Simulācijas rezultāts",
"pg_across_cycles": "Pa visiem jūsu cikliem",
"community_store": "Kopienas veikals",
"online_account": "Kopienas veikals un tiešsaistes funkcijas"
"online_account": "Kopienas veikals un tiešsaistes funkcijas",
"import_power_history": "Jaudas vēstures importēšana"
},
"health": {
"fair": "Pieņemama profila kvalitāte",
@@ -364,6 +373,7 @@
"poor": "⚠ Slikta profila kvalitāte"
},
"lbl": {
"drag_to_resize": "Velciet, lai mainītu izmēru",
"pg_anti_wrinkle": "Pretgrumbu režīms",
"actions": "Darbības",
"activity": "Aktivitāte",
@@ -435,7 +445,7 @@
"from": "No",
"gap_s": "Atstarpe (s)",
"group_name": "Grupas nosaukums",
"head_trim": "Galvas apdare (-es)",
"head_trim": "Apgriešana no sākuma (s)",
"health": "Veselība",
"hide_tabs": "Slēpt cilnes, kas nav administratori",
"in_use": "Lietošanā",
@@ -451,7 +461,7 @@
"metric": "Metrika",
"mode_existing_profile": "Pievienot esošajam profilam",
"mode_new_profile": "Izveidot jaunu profilu",
"models_fine_tuned": "({count} modeļi precizēti)",
"models_fine_tuned": "(precizētie modeļi: {count})",
"n_classic_suggestions": "{n} klasiskais",
"n_ml_suggestions": "{n} ML",
"n_selected": "Atlasīti: {n}",
@@ -532,7 +542,7 @@
"stage3": "3. posms DTW",
"stage4": "4. posms atbilstība",
"status": "Statuss",
"tail_trim": "Astes apdare (-es)",
"tail_trim": "Apgriešana no beigām (s)",
"timer_auto_pause": "Automātiska pauze",
"timer_min": "min",
"timer_msg_placeholder": "Ziņojums (neobligāti, {device}/{program}/{minutes})",
@@ -677,7 +687,26 @@
"conflict_import_copy": "Importēt kā kopiju",
"conflict_keep_mine": "Paturēt manējos",
"conflict_overwrite": "Pārrakstīt",
"font_size": "Paneļa fonta lielums"
"font_size": "Paneļa fonta lielums",
"hist_csv_data": "CSV dati",
"hist_from_recorder": "Vai nolasiet to no Home Assistant",
"hist_since": "No",
"days": "dienas",
"hist_keep": "Saglabāt šo ciklu",
"hist_looks_complete": "pabeigts",
"peak_power_short": "Maksimums",
"shape": "Forma",
"hist_skip_idle": "nekas nedarbojās",
"hist_skip_sparse": "rādījumi pārāk reti",
"hist_skip_short": "pārāk maz rādījumu",
"hist_skip_long": "nav pietiekami garas pauzes, kur sadalīt",
"hist_reason_short": "īsāks par šīs iekārtas īsāko īsto ciklu",
"hist_reason_no_end": "nekad netika korekti pabeigts",
"task_history_import": "Jaudas vēstures skenēšana",
"task_history_import_apply": "Ciklu importēšana",
"evidence_real_cycles": "Šīs ierīces izpildītie cikli",
"evidence_reference_cycles": "Lejupielādēti no kopienas veikala",
"evidence_backfill_cycles": "Atrasti importētā jaudas vēsturē"
},
"log": {
"all_levels": "Visi līmeņi",
@@ -756,9 +785,15 @@
"store_share": "Kopīgot kopienas veikalā",
"store_share_device": "Kopīgot šo ierīci",
"export_select": "Eksports - izvēlēties datus",
"import_wizard": "Imports - izvēlēties datus"
"import_wizard": "Imports - izvēlēties datus",
"history_import": "Jaudas vēstures importēšana"
},
"msg": {
"tail_trim_hint": "Cik sekundes noņemt no beigām",
"store_sibling_hint": "Jūsu precīzajam modelim nekas nav kopīgots? Tuvs tā paša zīmola modelis parasti ir labs sākumpunkts.",
"store_declare_appliance": "Norādiet WashData, kura ierīce jums pieder, un šajā cilnē tiks parādītas citu tai kopīgotās programmas un ieraksti. Varat arī augšā ievadīt zīmolu un vienkārši paskatīties apkārt.",
"refresh_catalog_hint": "Kopienas zīmolu un ierīču saraksti tiek saglabāti kešatmiņā, lai kopīgotais veikals nepārsniegtu savu dienas pieprasījumu limitu. Atsvaidziniet, lai iegūtu citu pievienotos vai apstiprinātos ierakstus.",
"head_trim_hint": "Cik sekundes noņemt no sākuma",
"appliance_monitor": "Ierīces monitors",
"artifact_dip_detail": "Krita zem parastā jaudas joslas ~{n}s.",
"artifact_footer": "Izcelts augstāk esošajā grafikā. Tie ir pārejoši artefakti (piemēram, durvis atvērtas cikla vidū), ne vienmēr problēmas.",
@@ -769,7 +804,7 @@
"automations_intro": "WashData aktivizē {start} / {end} notikumus un atklāj entītijas, tāpēc paziņojumus un darbības vislabāk veidot kā parastas Home Assistant automatizācijas. Zemāk redzamas automatizācijas, kas izmanto šo ierīci.",
"cleanup_intro": "Katrs iezīmētais cikls ir pārklāts. Atzīmējiet izņēmumus un izdzēsiet, lai notīrītu profilu.",
"clear_debug_hint": "Noņemiet saglabātos atkļūdošanas datus, lai atbrīvotu vietu.",
"collecting_data": "Datu vākšana - nepieciešami vēl {need} cikli, lai varētu sākt precizēšanu ({current}/{min}).",
"collecting_data": "Notiek datu vākšana. Vēl nepieciešamie cikli, lai varētu sākt precizēšanu: {need} ({current}/{min}).",
"compare_overlay_profiles": "Pārklājuma profili (blāvi)",
"compare_profiles_tip": "Iepriekš redzamajā diagrammā pārklājiet citas profila aploksnes, lai redzētu, kura no tām vislabāk atbilst šim ciklam.",
"compare_selected_cycles": "Atlasītie cikli (pastāvīgi) parādīt/slēpt",
@@ -779,7 +814,7 @@
"cycles_deleted": "Dzēsti cikli: {count}",
"enough_data": "Pietiek datu mācīšanai ({current}/{min} cikli).",
"export_description": "Izvēlieties precīzi, kurus profilus, ciklus, iestatījumus un citus datus eksportēt uz JSON, vai analizējiet failu un importējiet tikai vēlamās daļas.",
"feedback_cycles_pending": "{n} cikl{s} pārskatīšanai",
"feedback_cycles_pending": "Pārskatīšanai: {n}",
"feedback_prompt": "Apstipriniet, ka tas bija pareizi, labojiet programmu vai ignorējiet.",
"feedback_relabel_hint": "Šī cikla atkārtota marķēšana arī to atrisina.",
"filter_by_profile": "Filtrēt pēc profila…",
@@ -856,7 +891,6 @@
"pg_stress_synthetic": "dīkstāves simulācija sākas šeit",
"pg_sweep_intro": "Kā būtu, ja {param} atšķirtos? Pārbaudiet {steps} vērtības pēdējos {cycles} ciklos, lai atrastu iestatījumu, kurā pareizi tiek saskaņoti visvairāk ciklu.",
"pg_sweep_step": "Solis {done} / {total}",
"pg_undetected": "Neatklāti cikli: {n}",
"pg_verdict_bad": "Nepieciešama uzmanība: daudzi cikli netiek noteikti.",
"pg_verdict_good": "Labi noregulēts: lielākā daļa ciklu tiek pareizi identificēti un saskaņoti.",
"pg_verdict_ok": "Pieņemami: daži cikli palaisti garām. Mēģiniet pazemināt sākuma slieksni.",
@@ -887,6 +921,7 @@
"review_recorded_tip": "Atzīmējiet to kā manuāli izvēlētu atsauces ciklu savai programmai tāda pati loma kā manuāli ierakstītam ciklam. Atsauces cikli vienmēr tiek saglabāti, ievietojiet atbilstošo veidni, un tīrīšanas laikā tie nekad netiek atmesti. (Šis ir \"zelta\"/ierakstītais karogs; abi ir viens un tas pats.)",
"review_tags_tip": "Izvēles karodziņi, kas apraksta, kas šajā ciklā nogāja greizi, tāpēc apmācība un tīrīšana var to izskaidrot.",
"review_to_cycles": "Atveriet ciklu pārskatīšanas rindu",
"samples_decimated": "Rāda {shown} no {total} paraugiem (attēlošanai retināts; virsotnes saglabātas). Plaša atstarpe šeit ir retināšana, nevis trūkstoši dati.",
"saving_triggers_reload": "Saglabāšana aktivizē integrācijas atkārtotu ielādi. HA entītijas var īslaicīgi parādīties kā nepieejamas.",
"search_placeholder": "Meklēšanas iestatījumi…",
"see_recorder": "Skatiet ierakstītāja logrīku zemāk",
@@ -1006,7 +1041,29 @@
"sug_mute_failed": "Neizdevās klusināt ieteikumu",
"sug_unmuted_all": "Klusināto ieteikumu atiestatīšana pabeigta",
"n_suggestions_muted": "{count} klusināti; automātiskais regulētājs tos vairs nepiedāvās.",
"font_size_hint": "Palieliniet vai samaziniet visu šajā panelī. Attiecas uz jūsu kontu šajā ierīcē."
"font_size_hint": "Palieliniet vai samaziniet visu šajā panelī. Attiecas uz jūsu kontu šajā ierīcē.",
"import_history_description": "Viedā kontaktdakša jums bija jau pirms WashData? Augšupielādējiet tās jaudas sensora vēstures eksportu vai nolasiet to tieši no Home Assistant, un parastā noteikšana izies tam cauri, tāpēc iepriekšējie cikli parādīsies jūsu Ciklu sarakstā gatavi nosaukšanai.",
"hist_input_hint": "Augšupielādējiet CSV, kas lejupielādēts no Vēstures paneļa (entītija, stāvoklis, pēdējās izmaiņas), vai ļaujiet WashData nolasīt sensora vēsturi tieši. Pēc tam noteikšana izies tam cauri tieši tāpat kā reāllaikā, un jūs izvēlaties, kurus no atrastajiem cikliem paturēt.",
"hist_recorder_hint": "Nolasa no jūsu izvēlētā datuma līdz pašreizējam brīdim. Home Assistant pēc noklusējuma glabā detalizētu vēsturi 10 dienas, bet pēc tam tikai vidējās vērtības pa stundām, kas ir pārāk rupjas, lai no tām noteiktu ciklus - senāku datumu izvēlieties tikai tad, ja jūsu recorder ir iestatīts glabāt vairāk.",
"hist_scanning": "Jūsu vēsture tiek izlaista caur detektoru. Tas notiek fonā - varat aizvērt šo dialogu un atgriezties vēlāk.",
"hist_imported_count": "Importēti cikli: {n}.",
"hist_duplicates": "Jau iepriekš importēti un izlaisti: {n}.",
"hist_capped": "Sasniegts ierīces importēto ciklu ierobežojums; pārējie netika saglabāti.",
"hist_next_step": "Tie ir jūsu Ciklu sarakstā, atzīmēti kā importēta vēsture. Atveriet vienu un izmantojiet pogu Iezīmēt, lai norādītu tā programmu.",
"hist_rows_read": "Nolasīti rādījumi: {n}",
"hist_entity_substituted": "nolasīts {used} (šai ierīcei ir konfigurēts {wanted})",
"hist_breaks": "Pārtraukumi, kad sensors nebija pieejams: {n}",
"hist_other_entity": "Izlaisti citu entītiju rādījumi: {n}",
"hist_skipped_spans": "Izlaistie posmi",
"hist_settings_used": "Noteikts, izmantojot šīs ierīces pašreizējos iestatījumus (minimālā jauda {w} W, izslēgšanas aizkave {s} s).",
"hist_none_found": "Šajā vēsturē nevienu ciklu nebija iespējams noteikt.",
"hist_found": "Atrasti cikli: {n}. Noņemiet atzīmi visam, kas neizskatās pēc īstas darbības - līdz importēšanai nekas netiek saglabāts.",
"hist_scan_capped": "Tiek parādīti tikai pirmie kandidāti (atrasti: {n}).",
"hist_recorder_empty": "Home Assistant nav detalizētas vēstures par šo sensoru šajā periodā.",
"hist_scan_failed": "Skenēšana neizdevās.",
"hist_scan_expired": "Šī skenēšana vairs nav pieejama. Lūdzu, skenējiet vēlreiz.",
"hist_import_failed": "Importēšana neizdevās.",
"imported_history_readonly": "Noteikts importētā jaudas vēsturē. Tas ietekmē programmu saskaņošanu, bet netiek ieskaitīts jūsu statistikā, un to nevar apgriezt vai sadalīt. Izmantojiet pogu Iezīmēt, lai norādītu programmu."
},
"phase_desc": {
"anti_crease": "Laiku pa laikam pēc pabeigšanas veiciet īsus gājienus, lai samazinātu grumbiņas.",
@@ -1392,6 +1449,10 @@
"doc": "Saglabājiet pilnas jaudas izsekošanu un atbilstošos atkļūdošanas datus katram ciklam. Noderīgs problēmu novēršanai, bet palielina krātuves apjomu.",
"label": "Saglabāt atkļūdošanas pēdas"
},
"smart_termination_duration_ratio": {
"doc": "Cik tālu atbilstošās programmas paredzētajā ilgumā ciklam jābūt nonākušam, pirms vieda pabeigšana drīkst to pabeigt agrāk, kad jauda samazinās. Paredzētais ilgums ir programmas vidējais rādītājs, tāpēc ierīcēs, kuru darbības laiks stipri mainās - veļas mašīnas ar aukstu ziemas un siltu vasaras ieplūstošo ūdeni, žāvētāji ar sensora žāvēšanu, no slodzes atkarīgas programmas - apmēram puse no visiem cikliem beidzas īsāk par šo vidējo un nekad nesaņem ātro pabeigšanu, beidzoties tikai caur rezerves noildzi, dažas minūtes vēlāk. Samaziniet to (piem., 0,85) šajās mašīnās, lai agrā pabeigšana tomēr nostrādātu; palieliniet to virzienā uz 1,0, lai būtu piesardzīgāks. Atstājiet tukšu noklusējuma vērtībai (0,98 vai 0,99 trauku mazgājamām mašīnām). Tā var pabeigt ciklu tikai agrāk, nekad ne vēlāk, un nekad nenostrādā pie neskaidras vai zemas pārliecības atbilstības.",
"label": "Viedas pabeigšanas attiecība"
},
"smoothing_window": {
"doc": "Cik daudz neapstrādāts jaudas signāls ir izlīdzināts. Zems (2) ir atsaucīgs, bet trokšņains; augsts (5) izlīdzina tapas, bet palielina nobīdi.",
"label": "Izlīdzināšanas logs"
@@ -1417,7 +1478,7 @@
"label": "Slēdža entītija"
},
"watchdog_interval": {
"doc": "Cik bieži fona sargsuns pārbauda, vai sensori nav apstājušies un vai nav pagājis noildzes laiks. Noklusējums 30 s.",
"doc": "Cik bieži fona sargsuns pārbauda, vai sensori nav apstājušies un vai nav pagājis noildzes laiks. Noklusējums 30 s.",
"label": "Sargsuna intervāls"
},
"notify_milestone_message": {
@@ -1522,6 +1583,10 @@
"door_end_dwell_seconds": {
"label": "Durvju atvēršanas beigu uzturēšanās laiks",
"doc": "Cik ilgi durvis jāpaliek atvērtām, lai WashData beigtu ciklu, kad ir ieslēgts iestatījums \"Durvis automātiski atveras beigās\". Pietiekami ilgi, lai ignorētu ātru trauka pievienošanu (noklusējums 60 s), pietiekami īsi, lai ātri beigtu, kad mašīna atver durvis."
},
"profile_evidence_sources": {
"label": "Cikli, kas veido programmu",
"doc": "Kuri cikli tiek izmantoti katras programmas jaudas līknes izveidei un pabeigta cikla saskaņošanai ar to. Ja kādam veidam noņemat atzīmi, tas vairs neietekmē jūsu programmas, taču nekas netiek dzēsts - cikli paliek sarakstā Cikli, un tos joprojām var iezīmēt vai izņemt. Noderīgi, ja neuzticaties importētajiem datiem. Statistiku tas neietekmē: tajā vienmēr tiek ieskaitīti tikai tie cikli, ko šī ierīce patiešām ir izpildījusi. Visu atzīmju noņemšana tiek ignorēta, jo programma bez neviena cikla nekad nevarētu tikt saskaņota."
}
},
"setting_group": {
@@ -1605,6 +1670,9 @@
},
"basic_configuration": {
"label": "Pamatkonfigurācija"
},
"profile_evidence": {
"label": "Profila pamatdati"
}
},
"status": {
@@ -1629,7 +1697,8 @@
"trimming": "Apgriež…",
"splitting": "Sadala…",
"deleting": "Dzēš…",
"imported": "Importēts"
"imported": "Importēts",
"preparing": "Sagatavo…"
},
"tab": {
"advanced": "Papildu",
@@ -1659,6 +1728,7 @@
"wrong_profile": "Nepareizs profils"
},
"toast": {
"catalog_refreshed": "Kopienas katalogs atsvaidzināts",
"access_saved": "Piekļuves kontrole saglabāta",
"all_wiped": "Visi dati ir izdzēsti",
"analysis_complete_none": "Analīze pabeigta: nav jaunu ieteikumu",
@@ -1764,7 +1834,9 @@
"store_download_failed": "Lejupielāde neizdevās: {error}",
"store_download_nothing": "Nav nekā jauna lejupielādei - šis iestatījums jau ir jūsų ierīcē.",
"export_selective_done": "Eksports lejupielādēts",
"import_selective_done": "Importēti {profiles} profili un {cycles} cikli"
"import_selective_done": "Importēti {profiles} profili un {cycles} cikli",
"hist_csv_required": "Vispirms ielādējiet CSV failu vai ielīmējiet tā saturu",
"file_read_failed": "Šo failu nevarēja nolasīt"
},
"suggestion": {
"both_agree": "WashData iesaka",
@@ -1860,7 +1932,7 @@
"thr_batch": "Saglabāts nedaudz virs p05 zemākās aktīvās jaudas {cycles} ciklos ({p05}W), lai sākums tiktu uztverts pēc iespējas agrāk un apturēšanas slieksnis paliktu zem mašīnas zemākās darbības jaudas.",
"tol_per_profile": "p75 no katra profila ilguma dispersijas {profiles} profilos ({cycles} cikli); stabili profili netiek sodīti.",
"tol_pooled": "Pamatots ar apvienoto ilguma dispersiju {cycles} nesen marķētiem cikliem (p95 novirze={dev}).",
"watchdog": "Saglabāts pēc iespējas zemāks, cik droši (tikai nedaudz virs p95 atjaunināšanas intervāla {p95}s, min. 30s), lai apstāšanās tiktu atklāta ātri bez viltus apturēšanas."
"watchdog": "Saglabāts pēc iespējas zemāks, cik droši (tikai nedaudz virs p95 atjaunināšanas intervāla {p95}s un vismaz 2x paraugu ņemšanas intervāls {median}s, min. 30s), lai apstāšanās tiktu atklāta ātri bez viltus apturēšanas."
},
"exclusions": {
"summary": "Izslēgti {total} kļūdaini atpazīti cikli: {parts}.",
@@ -1892,6 +1964,7 @@
},
"pg_desc": {
"dishwasher_end_spike_quiet_release": "Trauku mazgājamā mašīna: klusās sekundes pēc paredzētā ilguma, pirms tiek atbrīvota cikla beigu ūdens izvadīšanas gaidīšana",
"smart_termination_duration_ratio": "Atbilstošās programmas paredzētā ilguma daļa, kas ciklam jāsasniedz, pirms vieda pabeigšana drīkst to pabeigt agrāk; samaziniet to no slodzes vai temperatūras atkarīgām mašīnām",
"anti_wrinkle_enabled": "Absorbējiet griešanās impulsus pēc galvenās fāzes, nevis nolasiet tos kā jaunus ciklus",
"anti_wrinkle_exit_power": "Lai pretgrumbu režīms paliktu aktīvs, jaudai starp impulsiem jānokrītas zem šīs vērtības",
"anti_wrinkle_idle_timeout": "Atļautais klusuma laiks starp diviem griešanās impulsiem, pirms pretgrumbu režīms beidzas",
@@ -1955,6 +2028,10 @@
"finished": "Cikls sasniedza gala stāvokli un beidzās."
},
"store": {
"your_model_tip": "Šī ir ierīce, ko norādījāt iestatījumos",
"your_model": "Jūsu modelis",
"search_brand_ph": "Meklēt pēc zīmola…",
"programs_count": "Programmas: {n}",
"browse": "Pārlūkot",
"device": "Ierīce",
"favorites": "Izlase",
@@ -78,9 +78,12 @@
"awaiting": "Чека одобрување",
"imported_tip": "Увезено од продавницата на заедницата. Се користи само за совпаѓање, не се брои во статистиката.",
"not_importable": "неприменливо",
"exists": "постои"
"exists": "постои",
"backfilled_tip": "Откриено во увезена историја на моќност. Влијае само на совпаѓањето на програмите, не се брои во статистиката."
},
"btn": {
"set_brand_model": "Постави бренд и модел",
"refresh_catalog": "Освежи го каталогот",
"add_device": "+ Додај уред",
"add_device_tip": "Додадете друг уред WashData",
"add_maintenance": "Додади настан за одржување",
@@ -90,7 +93,7 @@
"apply_label": "Примени етикета",
"apply_set_b": "Примени сет B",
"apply_split": "Примени Сплит",
"apply_trim": "Нанесете го Trim",
"apply_trim": "Примени скратување",
"auto_detect_split": "Автоматско откривање",
"auto_label_cycles": "Циклуси за автоматско обележување",
"auto_label_cycles_tip": "Автоматски доделува имиња на профили на неозначени циклуси чијашто доверба за совпаѓање го надминува прагот",
@@ -211,8 +214,8 @@
"stop": "Стопирај",
"submit_correction": "Поднесете корекција",
"train_now": "Тренирај сега",
"trim": "Намали",
"trim_split": "Намали / Сплит",
"trim": "Скрати",
"trim_split": "Скрати / Раздели",
"undo": "Врати",
"use": "Користете",
"wipe_all": "Избришете ги сите податоци",
@@ -234,14 +237,19 @@
"download_device": "Преземи поставки на уредот",
"share_device": "Сподели поставки на уредот",
"share_device_tip": "Споделете ги програмите и поставките на овој уред со заедницата",
"share_n": "Сподели {n} програм{s}",
"share_n": "Сподели циклуси ({n})",
"export_selected": "Извоз (избор на податоци)",
"export_all": "Брз извоз на сè",
"import_raw": "Напредно: замени сè од JSON",
"download_export": "Преземи извоз",
"analyze_import": "Анализирај датотека",
"import_selected": "Увези избрано",
"back": "Назад"
"back": "Назад",
"import_power_history": "Увези историја на моќност",
"hist_read_recorder": "Прочитај од Home Assistant",
"hist_scan": "Побарај циклуси",
"hist_import_n": "Увези циклуси ({n})",
"hist_goto_cycles": "Прикажи ги циклусите"
},
"conflict": {
"anti_wrinkle_exit": {
@@ -253,14 +261,14 @@
"start": "Мора да е под Макс. Моќноста Против Брчки ({max} Вт)"
},
"attn_sub": "Поправете ги конфликтите пред зачувување",
"attn_title": "{n} конфликт{s} во поставките",
"settings_banner": "{n} конфликт{s} во поставките проверете ги означените раздели и поправете пред зачувување.",
"attn_title": "Конфликти во поставките: {n}",
"settings_banner": "Конфликти во поставките: {n}. Проверете ги означените раздели и поправете ги пред зачувување.",
"settings_banner_btn": "Оди на прв",
"confidence": {
"auto": "Мора да е на или над Прагот за Совпаѓање ({match})",
"learning": "Мора да е на или под Прагот за Совпаѓање ({match})",
"learning": "Мора да е на или над Прагот за Совпаѓање ({match})",
"match_for_auto": "Мора да е на или под Довербата за Автоматско Означување ({alc})",
"match_for_learning": "Мора да е на или над Довербата при Учење ({lc})"
"match_for_learning": "Мора да е на или под Довербата при Учење ({lc})"
},
"duration_ratio": {
"max": "Мора да е поголем од Мин. Соодносот на Траење ({min})",
@@ -298,7 +306,7 @@
"match": "Мора да е над Прагот за Несовпаѓање ({un})",
"unmatch": "Мора да е под Прагот за Совпаѓање ({match}); инаку потврденото совпаѓање веднаш се откажува"
},
"cascade_toast": "За конзистентност, исто така се прилагодени уште {n} параметар{s}.",
"cascade_toast": "Други поставки прилагодени за конзистентност: {n}",
"suggestion_resolves": "Активирајте го чекечкиот предлог ({val}) подолу за да го поправите ова",
"use_fix": "Користи {val}",
"watchdog": {
@@ -356,7 +364,8 @@
"pg_outcome": "Резултат од симулацијата",
"pg_across_cycles": "Низ сите ваши циклуси",
"community_store": "Продавница на заедницата",
"online_account": "Продавница на заедницата и онлајн функции"
"online_account": "Продавница на заедницата и онлајн функции",
"import_power_history": "Увоз на историја на моќност"
},
"health": {
"fair": "Прифатлив квалитет на профилот",
@@ -364,6 +373,7 @@
"poor": "⚠ Лош квалитет на профилот"
},
"lbl": {
"drag_to_resize": "Повлечете за промена на големината",
"actions": "Акции",
"activity": "Активност",
"administrators": "Администраторите",
@@ -435,7 +445,7 @@
"from": "Од",
"gap_s": "Јаз (и)",
"group_name": "Назив на групата",
"head_trim": "Намалување на главата (и)",
"head_trim": "Скратување на почетокот (с)",
"health": "Здравје",
"hide_tabs": "Скриј јазичиња за не-администратори",
"in_use": "Во употреба",
@@ -451,7 +461,7 @@
"metric": "Метрика",
"mode_existing_profile": "Додај во постоечкиот профил",
"mode_new_profile": "Креирај нов профил",
"models_fine_tuned": "({count} модел{plural} дотерани)",
"models_fine_tuned": "(фино подесени модели: {count})",
"n_classic_suggestions": "{n} класично",
"n_ml_suggestions": "{n} ML",
"n_selected": "{n} избрани",
@@ -533,7 +543,7 @@
"stage3": "Етапа 3 DTW",
"stage4": "Етапа 4 – согласување",
"status": "Статус",
"tail_trim": "Намалување на опашката (и)",
"tail_trim": "Скратување на крајот (с)",
"timer_auto_pause": "Автоматска пауза",
"timer_min": "мин",
"timer_msg_placeholder": "Порака (изборно, {device}/{program}/{minutes})",
@@ -651,7 +661,7 @@
"show_contributor": "Прикажи соработник",
"task_pg_detail": "Симулирај циклус",
"task_split": "Разделување на циклус",
"task_trim": "Отсекување на циклус",
"task_trim": "Скратување на циклус",
"task_merge": "Спојување на циклуси",
"task_rebuild": "Повторно градење на обвивки",
"cat_profiles": "Профили (програми)",
@@ -677,7 +687,26 @@
"conflict_resolution": "Конфликти на имиња",
"conflict_import_copy": "Увези како копија",
"conflict_keep_mine": "Задржи ги моите",
"conflict_overwrite": "Презапиши"
"conflict_overwrite": "Презапиши",
"hist_csv_data": "CSV податоци",
"hist_from_recorder": "Или прочитај ја од Home Assistant",
"days": "дена",
"hist_keep": "Зачувај го овој циклус",
"hist_looks_complete": "завршен",
"peak_power_short": "Врв",
"shape": "Форма",
"hist_skip_idle": "ништо не работело",
"hist_skip_sparse": "читањата се премногу разретчени",
"hist_skip_short": "премалку читања",
"hist_skip_long": "нема доволно долга пауза за разделување",
"hist_reason_short": "пократок од најкраткиот вистински циклус на овој уред",
"hist_reason_no_end": "никогаш не заврши правилно",
"hist_since": "Од",
"task_history_import": "Скенирање на историјата на моќност",
"task_history_import_apply": "Увоз на циклуси",
"evidence_real_cycles": "Циклуси што ги извршил овој уред",
"evidence_reference_cycles": "Преземени од продавницата на заедницата",
"evidence_backfill_cycles": "Најдени во увезена историја на моќност"
},
"log": {
"all_levels": "Сите нивоа",
@@ -756,9 +785,15 @@
"store_share": "Сподели во продавницата на заедницата",
"store_share_device": "Сподели поставки на уредот",
"export_select": "Извоз - избор на податоци",
"import_wizard": "Увоз - избор на податоци"
"import_wizard": "Увоз - избор на податоци",
"history_import": "Увоз на историја на моќност"
},
"msg": {
"tail_trim_hint": "Отстранете толку секунди од крајот",
"store_sibling_hint": "Нема ништо споделено за вашиот точен модел? Близок модел од истиот бренд обично е добра почетна точка.",
"store_declare_appliance": "Кажете му на WashData кој уред го поседувате и оваа картичка ќе ги прикаже конфигурациите што другите ги споделиле за него. Можете и да напишете бренд погоре за да го разгледате каталогот.",
"refresh_catalog_hint": "Списоците со брендови и уреди на заедницата се чуваат во кеш за да остане продавницата на заедницата во рамките на своето дневно ограничување. Освежете за да ги преземете записите што други ги додале или одобриле.",
"head_trim_hint": "Отстранете толку секунди од почетокот",
"appliance_monitor": "Монитор на апаратот",
"artifact_dip_detail": "Падна под вообичаениот опсег на моќност за ~{n}с.",
"artifact_footer": "Нагласено на графиконот погоре. Ова се минливи артефакти (на пр. вратата отворена во средината на циклусот), а не нужно проблеми.",
@@ -769,7 +804,7 @@
"automations_intro": "WashData активира настани {start} / {end} и изложува ентитети, па известувањата и акциите е најдобро да се градат како нормални автоматизации на Home Assistant. Автоматизациите кои го користат овој уред се прикажани подолу.",
"cleanup_intro": "Секој означен циклус е преклопен. Штиклирајте ги оддалечените и избришете за да го исчистите профилот.",
"clear_debug_hint": "Отстранете ги зачуваните податоци за отстранување грешки за да ослободите простор.",
"collecting_data": "Собирање на податоци – уште {need} циклус{plural} пред почетокот на финото подесување ({current}/{min}).",
"collecting_data": "Собирање на податоци. Циклуси што уште се потребни пред да почне финото подесување: {need} ({current}/{min}).",
"compare_overlay_profiles": "Преклопени профили (бледо)",
"compare_profiles_tip": "Преклопете ги другите пликови на профили на табелата погоре за да видите кој најдобро одговара на овој циклус.",
"compare_selected_cycles": "Избрани циклуси (цврсти) - прикажи / скриј",
@@ -779,7 +814,7 @@
"cycles_deleted": "Избришани се {count} циклуси",
"enough_data": "Доволно податоци за учење ({current}/{min} циклуси).",
"export_description": "Изберете точно кои профили, циклуси, поставки и друго да се извезат во JSON, или анализирајте датотека и увезете само деловите што ги сакате.",
"feedback_cycles_pending": "{n} циклус{s} за преглед",
"feedback_cycles_pending": "За преглед: {n}",
"feedback_prompt": "Потврдете дека е точно, поправете ја програмата или игнорирајте.",
"feedback_relabel_hint": "Повторното етикетирање на овој циклус исто така го решава.",
"filter_by_profile": "Филтрирај по профил…",
@@ -856,7 +891,6 @@
"pg_stress_synthetic": "симулацијата на мирување почнува тука",
"pg_sweep_intro": "Што ако {param} беше поинаков? Тестирајте {steps} вредности врз вашите последни {cycles} циклуси за да ја пронајдете поставката каде што најмногу циклуси се совпаѓаат правилно.",
"pg_sweep_step": "Чекор {done} / {total}",
"pg_undetected": "{n} неоткриен циклус{s}",
"pg_verdict_bad": "Бара внимание: многу циклуси остануваат неоткриени.",
"pg_verdict_good": "Добро наместено: повеќето циклуси правилно се откриваат и совпаѓаат.",
"pg_verdict_ok": "Прифатливо: некои циклуси се пропуштени. Обидете се да го намалите прагот за старт.",
@@ -888,6 +922,7 @@
"review_recorded_tip": "Означете го ова како рачно избран референтен циклус за неговата програма - иста улога како рачно снимен циклус. Референтните циклуси секогаш се чуваат, се засноваат соодветниот шаблон и никогаш не се испуштаат со чистење. (Ова е „златното“/снимено знаме; и двете се иста работа.)",
"review_tags_tip": "Изборни знаменца што опишуваат што тргнало наопаку со овој циклус, така што обуката и чистењето можат да одговорат за тоа.",
"review_to_cycles": "Отворете го редот за преглед на циклуси",
"samples_decimated": "Прикажани {shown} од {total} примероци (проретчени за приказ; врвовите се задржани). Широк процеп тука е проретчување, а не податоци што недостасуваат.",
"saving_triggers_reload": "Зачувувањето активира повторно вчитување на интеграцијата. Ентитетите на HA може накратко да се покажат како недостапни.",
"search_placeholder": "Поставки за пребарување…",
"see_recorder": "Погледнете го додатокот за рекордер подолу",
@@ -991,12 +1026,12 @@
"share_consent": "Споделувате вистински податоци од вашиот уред. Не споделувајте ако вашите обрасци за користење се приватни.",
"share_device_none": "Сè уште нема поставени уреди. Прво додајте уред.",
"share_guideline_naming": "Користете јасни имиња на програмите (напр. 'Cotton 40', 'Eco 60') за да можат другите да ги препознаат",
"share_guideline_quality": "Споделувајте само профили со ⭐ референтни циклуси или барем {n} потврдени стартувања",
"share_guideline_quality": "Споделувајте само циклуси што завршиле нормално -- без прекини среде циклусот, отворања на вратата или трепкања во напојувањето.",
"share_guideline_review": "Прегледајте ги профилите пред споделување -- отстранете ги оние кои изгледаат погрешно",
"share_guidelines_title": "Пред споделување",
"store_download_device_intro": "Преземете поставки на уредот од заедницата и применете ги на нов или постоечки уред",
"store_share_device_intro": "Споделете ги програмите на вашиот уред (профили + референтни циклуси) со заедницата. Поставките се опционални.",
"share_profile_no_cycles": "Профилот '{p}' нема референтни циклуси -- ќе биде прескокнат освен ако немате {n}+ потврдени стартувања",
"store_share_device_intro": "Прикачете {brand} {model} со референтните циклуси што ќе ги изберете. Други со истиот уред можат да ги преземат вашите програми. Записите се прегледуваат пред да станат јавни.",
"share_profile_no_cycles": "Нема референтни циклуси - означете циклус со ⭐ во картичката Циклуси за да го вклучите овој профил",
"advisory_phase_inconsistent": "Изгледа дека '{name}' меша различни програми или температури - неговите циклуси се загреваат многу различно долго. Поделбата на посебни профили (на пр. по температура) ќе ги подобри совпаѓањето и проценките на времето.",
"advisory_phase_inconsistent_title": "⚠ Можеби измешани програми",
"export_select_intro": "Означете што точно да се вклучи. Изборот на профили без нивните циклуси сепак извезува препознатлива програма (нејзината научена форма се пренесува заедно со неа).",
@@ -1006,7 +1041,29 @@
"merge_hint": "Увезените ставки се додаваат; ништо локално не се губи. Конфликтите на имиња се решаваат подолу.",
"replace_warn": "Секоја означена категорија се брише и се заменува со податоците од датотеката. Неозначените категории остануваат непроменети.",
"dest_reference_hint": "Увезените циклуси само го подобруваат препознавањето на програми и никогаш не влијаат на статистиката за користење/енергија.",
"dest_real_history_hint": "Увезените циклуси се сметаат за сопствена историја на овој уред и ја хранат статистиката за енергија/користење. Користете за преместување на еден уред на нова инсталација."
"dest_real_history_hint": "Увезените циклуси се сметаат за сопствена историја на овој уред и ја хранат статистиката за енергија/користење. Користете за преместување на еден уред на нова инсталација.",
"import_history_description": "Имавте паметен приклучок и пред WashData? Поставете извоз од историјата на неговиот сензор за моќност или прочитајте ја директно од Home Assistant, и вообичаената детекција ќе помине низ неа, така што минатите циклуси ќе се појават во списокот „Циклуси“ подготвени за именување.",
"hist_input_hint": "Поставете CSV преземен од панелот „Историја“ (ентитет, состојба, последна промена) или дозволете WashData да ја прочита историјата на сензорот директно. Потоа детекцијата поминува низ неа исто како и во живо, а вие избирате кои од најдените циклуси да ги зачувате.",
"hist_recorder_hint": "Ги чита податоците од избраниот датум до сега. Home Assistant стандардно чува детална историја 10 дена, а потоа само часовни просеци, кои се премногу груби за детекција на циклуси - изберете поран датум само ако вашиот recorder е поставен да чува повеќе.",
"hist_scanning": "Вашата историја се пушта низ детекторот. Ова се извршува во заднина - можете да го затворите овој дијалог и да се вратите подоцна.",
"hist_imported_count": "Увезени циклуси: {n}.",
"hist_duplicates": "Веќе увезени и прескокнати: {n}.",
"hist_capped": "Достигнато е ограничувањето на увезени циклуси по уред; останатите не се зачувани.",
"hist_next_step": "Тие се во списокот „Циклуси“, означени како увезена историја. Отворете еден и користете „Етикета“ за да ја наведете неговата програма.",
"hist_rows_read": "Прочитани читања: {n}",
"hist_breaks": "Празнини каде сензорот бил недостапен: {n}",
"hist_other_entity": "Прескокнати читања за други ентитети: {n}",
"hist_entity_substituted": "Прочитано {used} (овој уред е поставен на {wanted})",
"hist_skipped_spans": "Прескокнати делови",
"hist_settings_used": "Откриено со тековните поставки на овој уред (Минимална моќност {w} Вт, Одложување на исклучување {s} с).",
"hist_none_found": "Во таа историја не можеше да се открие ниту еден циклус.",
"hist_found": "Најдени циклуси: {n}. Отштиклирајте сè што не изгледа како вистинско пуштање - ништо не се зачувува додека не увезете.",
"hist_scan_capped": "Прикажани се само првите кандидати (најдени: {n}).",
"hist_recorder_empty": "Home Assistant нема детална историја за овој сензор во тој период.",
"hist_scan_failed": "Скенирањето не успеа.",
"hist_scan_expired": "Тоа скенирање повеќе не е достапно. Скенирајте повторно.",
"hist_import_failed": "Увозот не успеа.",
"imported_history_readonly": "Откриено во увезена историја на моќност. Влијае на совпаѓањето на програмите, но не се брои во вашата статистика и не може да се скратува или разделува. Користете „Етикета“ за да ја наведете програмата."
},
"phase_desc": {
"anti_crease": "Повремени кратки превртувања по завршувањето за да се намалат брчките.",
@@ -1409,7 +1466,7 @@
"label": "Праг за почеток"
},
"stop_threshold_w": {
"doc": "Напојувањето мора да падне под ова ниво пред да започне одбројувањето за исклучување. Поставете го под прагот за почеток - јазот меѓу нив е лентата за хистереза што го спречува треперењето. Ако е поставено премногу високо, фазите со мала моќност (држење на плакнење, против туткање) лажно ја активираат крајната низа.",
"doc": "Напојувањето мора да падне под ова ниво пред да започне одбројувањето за исклучување. Поставете го под прагот за почеток - јазот меѓу нив е лентата за хистереза што го спречува треперењето. Ако е поставено премногу високо, фазите со мала моќност (држење на плакнење, против туткање) лажно ја активираат крајната низа.",
"label": "Праг за стоп"
},
"switch_entity": {
@@ -1471,6 +1528,10 @@
"show_contributor": {
"doc": "Прикажи го името на соработникот на профилите преземени од продавницата на заедницата"
},
"smart_termination_duration_ratio": {
"doc": "Колку длабоко во очекуваното траење на совпаднатата програма мора да навлезе циклусот пред Паметното завршување да може да го заврши предвреме штом падне моќноста. Очекуваното траење е просекот на програмата, па кај уреди со многу променливо време на работа - машини за перење при студена зимска и топла летна влезна вода, машини за сушење со сензор за влажност, програми што зависат од полнењето - околу половина од сите циклуси завршуваат пократко од тој просек и никогаш не го добиваат брзото завршување, туку завршуваат дури преку резервниот тајмаут со неколку минути задоцнување. Намалете ја оваа вредност (пр. 0.85) кај такви машини за да се активира сепак предвременото завршување; зголемете ја кон 1.0 за поконзервативно однесување. Оставете празно за стандардната вредност (0.98 или 0.99 за мијалници). Може само да заврши циклус порано, никогаш подоцна, и никогаш не се активира при двосмислено или недоволно сигурно совпаѓање.",
"label": "Сооднос на паметно завршување"
},
"enable_phase_matching": {
"label": "Преостанато време според фазите",
"doc": "Го дели секој активен циклус на фази (загревање, перење, центрифугирање) и го распределува преостанатото време по фази, во комбинација со класичната проценка - потпирајќи се на распределбата по фази на почетокот на циклусот, а на класичната проценка кон крајот. Ова го прилагодува одбројувањето на тоа колку навистина се загрева и работи вашата машина, што е најзабележливо во првата половина од циклусот. Исклучено = само класичната проценка. Влијае само на приказот на преостанатото време; совпаѓањето на програми и откривањето на циклуси остануваат непроменети."
@@ -1522,6 +1583,10 @@
"door_end_dwell_seconds": {
"label": "Задржување при отворена врата",
"doc": "Колку долго вратата мора да остане отворена пред WashData да го заврши циклусот, кога е вклучено \"Вратата се отвора автоматски на крај\". Доволно долго за да се игнора брзото додавање сад (стандардно 60 с), доволно кратко за брзо завршување откако машината ја отвора вратата."
},
"profile_evidence_sources": {
"label": "Циклуси што обликуваат програма",
"doc": "Кои циклуси се користат за изградба на кривата на моќност на секоја програма и за совпаѓање на завршен циклус со неа. Ако одзначите некој вид, тој престанува да ги обликува вашите програми, но ништо не се брише - циклусите остануваат во списокот Циклуси и сѐ уште можат да се означат или отстранат. Корисно ако не им верувате на увезените податоци. Статистиката не се менува: во неа секогаш се бројат само циклусите што овој уред навистина ги извршил. Одзначувањето на сè се игнорира, бидејќи програма без ниту еден циклус никогаш не би можела да се совпадне."
}
},
"setting_group": {
@@ -1605,6 +1670,9 @@
},
"basic_configuration": {
"label": "Основна конфигурација"
},
"profile_evidence": {
"label": "Основа на профилот"
}
},
"status": {
@@ -1629,7 +1697,8 @@
"trimming": "Скратување…",
"splitting": "Разделување…",
"deleting": "Бришење…",
"imported": "Увезено"
"imported": "Увезено",
"preparing": "Подготовка…"
},
"tab": {
"advanced": "Напредно",
@@ -1659,6 +1728,7 @@
"wrong_profile": "Погрешен профил"
},
"toast": {
"catalog_refreshed": "Каталогот на заедницата е освежен",
"access_saved": "Контролата за пристап е зачувана",
"all_wiped": "Сите податоци се избришани",
"analysis_complete_none": "Анализата е завршена: нема нови предлози",
@@ -1670,7 +1740,7 @@
"cycle_labelled": "Циклус означен",
"cycle_paused": "Циклусот е паузиран",
"cycle_resumed": "Циклусот продолжи",
"cycle_trimmed": "Циклус скратен",
"cycle_trimmed": "Циклусот е скратен",
"cycles_merged": "Циклусите се споија",
"envelope_rebuilt": "Пликот повторно изграден",
"envelopes_rebuilt": "Пликовите повторно изградени",
@@ -1752,19 +1822,21 @@
"rating_saved": "Оцената за квалитет е зачувана",
"brand_added": "Брендот е додаден, чека одобрување",
"profile_added": "Профилот е додаден, чека одобрување",
"saved_except_conflicts": "Поставките се зачувани -- {n} поставка{s} прескокната поради конфликти",
"saved_except_conflicts": "Зачувано. Поправете ги означените конфликти за да го зачувате останатото.",
"share_device_none_sel": "Изберете барем една програма за споделување",
"store_device_downloaded": "Поставките на уредот се преземени: {created} профил{c} создаден, {dup} веќе постоеше",
"store_device_downloaded_phases": "Поставките на уредот се преземени: {created} профил{c} создаден, {dup} веќе постоеше, картата на фазите е применета",
"store_device_downloaded_settings": "Поставките на уредот се преземени: {created} профил{c} создаден, {dup} веќе постоеше, поставките се применети",
"store_device_shared": "Поставките на уредот се споделени: {n} програм{s} прикачена",
"store_device_shared_all_dup": "Нема ништо ново за споделување -- сите програми веќе постојат во продавницата",
"store_device_shared_partial": "Делумно споделување: {n} програм{s} прикачена, {failed} прескокнато",
"store_device_shared_some_dup": "Поставките на уредот се споделени: {n} програм{s} прикачена ({dup} веќе постоеше)",
"store_device_downloaded": "Додадено: програми {p}, снимки {c}",
"store_device_downloaded_phases": "Додадено: програми {p}, снимки {c}, карти на фазите {ph}",
"store_device_downloaded_settings": "Додадено: програми {p}, снимки {c}, карти на фазите {ph}, поставки {s}",
"store_device_shared": "Циклуси споделени во продавницата на заедницата: {n}. Се чека преглед.",
"store_device_shared_all_dup": "Сите циклуси ({n}) веќе беа во продавницата на заедницата.",
"store_device_shared_partial": "Споделени циклуси: {n}; неприкачени: {failed}.",
"store_device_shared_some_dup": "Споделени циклуси: {created}; веќе во продавницата: {dup}.",
"store_download_failed": "Неуспешно преземање: {error}",
"store_download_nothing": "Нема ништо за преземање -- сите профили веќе постојат на овој уред",
"export_selective_done": "Извозот е преземен",
"import_selective_done": "Увезени се {profiles} профил(и) и {cycles} циклус(и)"
"import_selective_done": "Увезени се {profiles} профил(и) и {cycles} циклус(и)",
"hist_csv_required": "Најпрво вчитајте CSV датотека или вметнете ја нејзината содржина",
"file_read_failed": "Таа датотека не можеше да се прочита"
},
"suggestion": {
"both_agree": "WashData препорачува",
@@ -1860,7 +1932,7 @@
"thr_batch": "Задржано веднаш над најниската работна моќност p05 низ {cycles} циклуси ({p05}W) за стартот да се фати што е можно порано, а прагот на запирање да остане под најниската работна моќност на машината.",
"tol_per_profile": "p75 на варијансата на траењето по профил низ {profiles} профили ({cycles} циклуси); доследните профили не се казнуваат.",
"tol_pooled": "Врз основа на здружената варијанса на траењето на {cycles} неодамнешни означени циклуси (p95 отстапување={dev}).",
"watchdog": "Задржано што е можно пониско додека е безбедно (малку над интервалот на ажурирање p95 од {p95}s, мин. 30s) за застоите брзо да се фатат без лажни запирања."
"watchdog": "Задржано што е можно пониско додека е безбедно (малку над интервалот на ажурирање p95 од {p95}s и барем 2x интервалот на земање примероци од {median}s, мин. 30s) за застоите брзо да се фатат без лажни запирања."
},
"exclusions": {
"summary": "Исклучени се {total} погрешно откриени циклуси: {parts}.",
@@ -1892,6 +1964,7 @@
},
"pg_desc": {
"dishwasher_end_spike_quiet_release": "Машина за миење садови: секунди неактивност по очекуваното траење пред да се ослободи чекањето за испумпување на крајот од циклусот",
"smart_termination_duration_ratio": "Дел од очекуваното траење на совпаднатата програма што циклусот мора да го достигне пред Паметното завршување да може да го заврши предвреме; намалете го за машини што зависат од полнењето или температурата",
"completion_min_seconds": "Најкратко извршување што се смета за вистински циклус",
"end_repeat_count": "Ниски отчитувања по ред пред завршување",
"interrupted_min_seconds": "Кратки циклуси означени како прекинати",
@@ -1955,6 +2028,10 @@
"finished": "Циклусот достигна крајна состојба и заврши."
},
"store": {
"your_model_tip": "Ова е уредот што го наведовте во поставките",
"your_model": "Ваш",
"search_brand_ph": "Пребарување по бренд…",
"programs_count": "Програми: {n}",
"browse": "Прелистување",
"device": "Уред",
"favorites": "Омилени",
@@ -1993,6 +2070,7 @@
"add_profile": "Додајте профил за овој уред на сајтот на заедницата"
},
"task": {
"cancelling": "Откажување...",
"reprocess": {
"matching": "Повторна обработка: совпаѓање на циклуси",
"golden": "Повторна обработка: пополнување референтни",
@@ -2010,7 +2088,7 @@
"apply": "Разделување на циклус"
},
"trim": {
"apply": "Отсекување на циклус"
"apply": "Скратување на циклус"
},
"merge": {
"apply": "Спојување на циклуси"
@@ -78,9 +78,12 @@
"awaiting": "Venter på godkjenning",
"imported_tip": "Importert fra fellesskapsbutikken. Brukes kun til matching, telles ikke med i statistikken.",
"not_importable": "ikke her",
"exists": "finnes"
"exists": "finnes",
"backfilled_tip": "Oppdaget i importert effekthistorikk. Påvirker bare programmatching, telles ikke med i statistikken."
},
"btn": {
"set_brand_model": "Angi merke og modell",
"refresh_catalog": "Oppdater katalog",
"add_device": "+ Legg til enhet",
"add_device_tip": "Legg til en annen WashData-enhet",
"add_maintenance": "Legg til vedlikeholdshendelse",
@@ -90,7 +93,7 @@
"apply_label": "Påfør etikett",
"apply_set_b": "Bruk sett B",
"apply_split": "Påfør Split",
"apply_trim": "Påfør Trim",
"apply_trim": "Bruk beskjæring",
"auto_detect_split": "Automatisk gjenkjenning",
"auto_label_cycles": "Automatiske etikettsykluser",
"auto_label_cycles_tip": "Tilordne automatisk profilnavn til umerkede sykluser der matchkonfidensen overstiger terskelen",
@@ -209,8 +212,8 @@
"stop": "Stopp",
"submit_correction": "Send inn rettelse",
"train_now": "Tren nå",
"trim": "Trim",
"trim_split": "Trim / Splitt",
"trim": "Beskjær",
"trim_split": "Beskjær / Splitt",
"undo": "Angre",
"use": "Bruk",
"wipe_all": "Tørk alle data",
@@ -241,7 +244,12 @@
"import_selected": "Importer valgte",
"back": "Tilbake",
"mute_suggestion": "Slutt å foreslå denne innstillingen",
"reset_muted": "Tilbakestill dempede forslag"
"reset_muted": "Tilbakestill dempede forslag",
"import_power_history": "Importer effekthistorikk",
"hist_read_recorder": "Les fra Home Assistant",
"hist_scan": "Søk etter sykluser",
"hist_import_n": "Importer {n} sykluser",
"hist_goto_cycles": "Vis meg syklusene"
},
"conflict": {
"anti_wrinkle_exit": {
@@ -253,12 +261,12 @@
"start": "Må være under maksimal anti-krøll-effekt ({max} W)"
},
"attn_sub": "Rett konflikter før du lagrer",
"attn_title": "{n} innstillingskonflikt{s}",
"attn_title": "Innstillingskonflikter: {n}",
"confidence": {
"auto": "Må være ved eller over matchingsterskelen ({match})",
"learning": "Må være ved eller under matchingsterskelen ({match})",
"learning": "Må være ved eller over matchingsterskelen ({match})",
"match_for_auto": "Må være ved eller under auto-merke-konfidensen ({alc})",
"match_for_learning": "Må være ved eller over læringskonfidensen ({lc})"
"match_for_learning": "Må være ved eller under læringskonfidensen ({lc})"
},
"duration_ratio": {
"max": "Må være større enn min varighetsforhold ({min})",
@@ -296,14 +304,14 @@
"match": "Må være over avmatch-terskelen ({un})",
"unmatch": "Må være under matchingsterskelen ({match}); ellers avmatchs en bekreftet match øyeblikkelig"
},
"cascade_toast": "Også {n} innstilling{s} justert for konsistens.",
"cascade_toast": "Andre innstillinger justert for konsistens: {n}",
"suggestion_resolves": "Bruk forslaget nedenfor ({val}) for å løse dette",
"use_fix": "Bruk {val}",
"watchdog": {
"interval": "Bør være minst 2x samplingsintervallet ({si} s)",
"sampling": "Samplingsintervall bør være høyst halvparten av vaktbikkjeintervallet ({wi} s)"
},
"settings_banner": "{n} innstillingskonflikt{s} sjekk de fremhevede seksjonene og rett dem opp før du lagrer.",
"settings_banner": "Innstillingskonflikter: {n}. Sjekk de fremhevede seksjonene og rett dem opp før du lagrer.",
"settings_banner_btn": "Gå til første"
},
"hdr": {
@@ -356,7 +364,8 @@
"pg_outcome": "Simuleringsresultat",
"pg_across_cycles": "På tvers av syklusene dine",
"community_store": "Fellesskapsbutikk",
"online_account": "Fellesskapsbutikk og nettfunksjoner"
"online_account": "Fellesskapsbutikk og nettfunksjoner",
"import_power_history": "Importer effekthistorikk"
},
"health": {
"fair": "Akseptabel profilkvalitet",
@@ -364,6 +373,7 @@
"poor": "⚠ Dårlig profilkvalitet"
},
"lbl": {
"drag_to_resize": "Dra for å endre størrelse",
"actions": "Handlinger",
"activity": "Aktivitet",
"administrators": "Administratorer",
@@ -450,7 +460,7 @@
"metric": "Metrikk",
"mode_existing_profile": "Legg til i eksisterende profil",
"mode_new_profile": "Opprett ny profil",
"models_fine_tuned": "({count} modell{plural} finjustert)",
"models_fine_tuned": "(finjusterte modeller: {count})",
"n_classic_suggestions": "{n} klassisk",
"n_ml_suggestions": "{n} ML",
"n_selected": "{n} valgt",
@@ -677,7 +687,26 @@
"conflict_keep_mine": "Behold mine",
"conflict_overwrite": "Overskriv",
"pg_anti_wrinkle": "Anti-rynke",
"font_size": "Panelets skriftstørrelse"
"font_size": "Panelets skriftstørrelse",
"hist_csv_data": "CSV-data",
"hist_from_recorder": "Eller les den fra Home Assistant",
"hist_since": "Siden",
"days": "dager",
"hist_keep": "Behold denne syklusen",
"hist_looks_complete": "komplett",
"peak_power_short": "Topp",
"shape": "Form",
"hist_skip_idle": "ingenting kjørte",
"hist_skip_sparse": "avlesninger for langt fra hverandre",
"hist_skip_short": "for få avlesninger",
"hist_skip_long": "ingen pause lang nok å dele på",
"hist_reason_short": "kortere enn dette apparatets korteste virkelige syklus",
"hist_reason_no_end": "avsluttet aldri rent",
"task_history_import": "Søker gjennom effekthistorikk",
"task_history_import_apply": "Importerer sykluser",
"evidence_real_cycles": "Sykluser denne maskinen har kjørt",
"evidence_reference_cycles": "Lastet ned fra fellesskapsbutikken",
"evidence_backfill_cycles": "Funnet i importert effekthistorikk"
},
"log": {
"all_levels": "Alle nivåer",
@@ -756,9 +785,15 @@
"store_share": "Del i fellesskapsbutikken",
"store_share_device": "Del dette apparatet",
"export_select": "Eksport - velg data",
"import_wizard": "Import - velg data"
"import_wizard": "Import - velg data",
"history_import": "Importer effekthistorikk"
},
"msg": {
"tail_trim_hint": "Fjern så mange sekunder fra slutten",
"store_sibling_hint": "Er ingenting delt for nøyaktig din modell? En nært beslektet modell fra samme merke er vanligvis et godt utgangspunkt.",
"store_declare_appliance": "Fortell WashData hvilket apparat du har, så viser denne fanen oppsettene andre har delt for det. Du kan også skrive et merke ovenfor for å se deg rundt.",
"refresh_catalog_hint": "Fellesskapets lister over merker og apparater mellomlagres for at fellesskapsbutikken skal holde seg innenfor sin daglige grense. Oppdater for å hente bidrag som andre har lagt til eller godkjent.",
"head_trim_hint": "Fjern så mange sekunder fra starten",
"appliance_monitor": "Apparatmonitor",
"artifact_dip_detail": "Falt under det vanlige effektbåndet i ~{n}s.",
"artifact_footer": "Fremhevet på grafen over. Dette er forbigående artefakter (f.eks. døren åpnet midt i syklusen), ikke nødvendigvis problemer.",
@@ -769,7 +804,7 @@
"automations_intro": "WashData utløser {start} / {end}-hendelser og gjør entiteter tilgjengelige, slik at varsler og handlinger best bygges som vanlige Home Assistant-automatiseringer. Automatiseringer som bruker denne enheten, vises nedenfor.",
"cleanup_intro": "Hver merket syklus er lagt over. Kryss av for uteliggere og slett for å rydde opp i profilen.",
"clear_debug_hint": "Fjern lagrede feilsøkingsdata for å frigjøre plass.",
"collecting_data": "Samler inn data: {need} syklus{plural} til før finjustering kan starte ({current}/{min}).",
"collecting_data": "Samler inn data. Sykluser som mangler før finjustering kan starte: {need} ({current}/{min}).",
"compare_overlay_profiles": "Overleggsprofiler (svak)",
"compare_profiles_tip": "Legg over andre profilkonvolutter på diagrammet ovenfor for å se hvilken som passer best til denne syklusen.",
"compare_selected_cycles": "Valgte sykluser (fast) vis / skjul",
@@ -779,7 +814,7 @@
"cycles_deleted": "{count} syklus(er) slettet",
"enough_data": "Nok data til å lære av ({current}/{min} sykluser).",
"export_description": "Velg nøyaktig hvilke profiler, sykluser, innstillinger og mer som skal eksporteres til JSON, eller analyser en fil og importer bare delene du vil ha.",
"feedback_cycles_pending": "{n} syklus{s} til gjennomgang",
"feedback_cycles_pending": "Til gjennomgang: {n}",
"feedback_prompt": "Bekreft at det var riktig, korriger programmet eller ignorer.",
"feedback_relabel_hint": "Å merke denne syklusen på nytt løser også gjennomgangen.",
"filter_by_profile": "Filtrer etter profil…",
@@ -856,7 +891,6 @@
"pg_stress_synthetic": "inaktiv simulering starter her",
"pg_sweep_intro": "Hva om {param} var annerledes? Test {steps} verdier på tvers av dine siste {cycles} sykluser for å finne innstillingen der flest sykluser blir riktig matchet.",
"pg_sweep_step": "Trinn {done} / {total}",
"pg_undetected": "{n} syklus{s} ikke oppdaget",
"pg_verdict_bad": "Trenger oppmerksomhet: mange sykluser blir ikke oppdaget.",
"pg_verdict_good": "Godt innstilt: de fleste sykluser blir riktig identifisert og matchet.",
"pg_verdict_ok": "Akseptabelt: noen sykluser ble oversett. Prøv å senke startterskelen.",
@@ -887,6 +921,7 @@
"review_recorded_tip": "Merk dette som en håndplukket referansesyklus for programmet - samme rolle som en manuelt registrert syklus. Referansesykluser beholdes alltid, setter den matchende malen, og blir aldri droppet ved opprydding. (Dette er det \"gyldne\"/innspilte flagget; begge er det samme.)",
"review_tags_tip": "Valgfrie flagg som beskriver hva som gikk galt med denne syklusen, slik at trening og opprydding kan forklare det.",
"review_to_cycles": "Åpne Cycles review-køen",
"samples_decimated": "Viser {shown} av {total} prøver (tynnet ut for visning; topper beholdes). Et bredt hull her er uttynning, ikke manglende data.",
"saving_triggers_reload": "Lagring utløser en ny integrasjon. HA-enheter kan kort vises som utilgjengelige.",
"search_placeholder": "Søkeinnstillinger...",
"see_recorder": "Se opptaker-widget nedenfor",
@@ -1006,10 +1041,33 @@
"sug_mute_failed": "Kunne ikke dempe forslaget",
"sug_unmuted_all": "Dempede forslag tilbakestilt",
"n_suggestions_muted": "{count} dempet; autotuner vil ikke foreslå disse.",
"font_size_hint": "Gjør alt i dette panelet større eller mindre. Gjelder for kontoen din på denne enheten."
"font_size_hint": "Gjør alt i dette panelet større eller mindre. Gjelder for kontoen din på denne enheten.",
"import_history_description": "Hadde du allerede en smartplugg før du tok i bruk WashData? Last opp en historikkeksport fra effektsensoren, eller la den leses rett fra Home Assistant, og den vanlige deteksjonen kjører over den slik at tidligere sykluser dukker opp i Sykluser-listen din, klare til å navngis.",
"hist_input_hint": "Last opp en CSV-fil lastet ned fra Historikk-panelet (entitet, tilstand, sist endret), eller la WashData lese sensorens historikk direkte. Deteksjonen kjører deretter over den akkurat som live, og du velger hvilke av syklusene den finner du vil beholde.",
"hist_recorder_hint": "Leser fra datoen du velger og fram til nå. Home Assistant beholder detaljert historikk i 10 dager som standard og deretter bare timesgjennomsnitt, som er for grove å oppdage sykluser fra - velg en dato lenger tilbake bare hvis recorderen din er satt til å beholde mer.",
"hist_scanning": "Historikken din spilles gjennom deteksjonen. Dette kjører i bakgrunnen - du kan lukke denne dialogen og komme tilbake til den senere.",
"hist_imported_count": "{n} sykluser importert.",
"hist_duplicates": "{n} var allerede importert og ble hoppet over.",
"hist_capped": "Grensen per enhet for importerte sykluser ble nådd; resten ble ikke lagret.",
"hist_next_step": "De ligger i Sykluser-listen din, merket som importert historikk. Åpne en og bruk Merk for å navngi programmet den hører til.",
"hist_rows_read": "{n} avlesninger lest",
"hist_entity_substituted": "leste {used} (denne enheten er konfigurert for {wanted})",
"hist_breaks": "{n} hull der sensoren var utilgjengelig",
"hist_other_entity": "{n} avlesninger for andre entiteter ignorert",
"hist_skipped_spans": "Utelatte strekninger",
"hist_settings_used": "Oppdaget med denne enhetens gjeldende innstillinger (minimum effekt {w} W, av-forsinkelse {s} s).",
"hist_none_found": "Ingen sykluser kunne oppdages i den historikken.",
"hist_found": "Fant {n} sykluser. Fjern avkryssingen for alt som ikke ser ut som en virkelig kjøring - ingenting lagres før du importerer.",
"hist_scan_capped": "Bare de første kandidatene vises ({n} ble funnet).",
"hist_recorder_empty": "Home Assistant har ingen detaljert historikk for denne sensoren i det vinduet.",
"hist_scan_failed": "Søket mislyktes.",
"hist_scan_expired": "Det søket er ikke lenger tilgjengelig. Søk på nytt.",
"hist_import_failed": "Importen mislyktes.",
"imported_history_readonly": "Oppdaget i importert effekthistorikk. Den påvirker programmatching, men telles ikke med i statistikken din og kan ikke beskjæres eller deles. Merk den for å navngi programmet."
},
"pg_desc": {
"dishwasher_end_spike_quiet_release": "Oppvaskmaskin: stille sekunder etter forventet varighet før ventingen på tømming ved slutten av syklusen frigjøres",
"smart_termination_duration_ratio": "Andel av det gjenkjente programmets forventede varighet som en syklus må nå før smart avslutning kan avslutte den tidlig; senk den for last- eller temperaturavhengige maskiner",
"completion_min_seconds": "Korteste kjøring som teller som en ekte syklus",
"end_repeat_count": "Lave avlesninger på rad før avslutning",
"interrupted_min_seconds": "Korte sykluser merkes som avbrutt",
@@ -1421,6 +1479,10 @@
"doc": "Lagre full effektsporing og samsvarende feilsøkingsdata for hver syklus. Nyttig for feilsøking, men øker lagringsstørrelsen.",
"label": "Lagre feilsøkingsspor"
},
"smart_termination_duration_ratio": {
"doc": "Hvor langt inn i det gjenkjente programmets forventede varighet en syklus må være før smart avslutning kan avslutte den tidlig når effekten faller. Den forventede varigheten er programmets gjennomsnitt, så på apparater med sterkt varierende kjøretid - vaskemaskiner med kaldt vinter- kontra varmt sommerinnløpsvann, tørketromler med fuktsensor, lastavhengige programmer - avslutter omtrent halvparten av alle kjøringer kortere enn dette gjennomsnittet og får aldri den raske avslutningen, men avsluttes først minutter senere via reserve-tidsavbruddet. Senk denne verdien (f.eks. 0,85) på slike maskiner slik at den tidlige avslutningen fortsatt utløses; øk den mot 1,0 for å være mer forsiktig. La feltet stå tomt for standarden (0,98, eller 0,99 for oppvaskmaskiner). Den kan bare avslutte en syklus tidligere, aldri senere, og utløses aldri ved en tvetydig eller usikker gjenkjenning.",
"label": "Forhold for smart avslutning"
},
"smoothing_window": {
"doc": "Hvor mye råeffektsignalet jevnes ut. Lav (2) er responsiv, men støyende; høy (5) jevner ut pigger, men legger til etterslep.",
"label": "Utjevningsvindu"
@@ -1551,6 +1613,10 @@
"door_end_dwell_seconds": {
"label": "Dørens åpningstid ved avslutning",
"doc": "Hvor lenge døren må forbli åpen før WashData avslutter syklusen, når \"Dør åpnes automatisk ved avslutning\" er aktivert. Lang nok til å ignorere rask tillegging av et fat (standard 60 s), kort nok til å avslutte raskt når maskinen spretter opp døren."
},
"profile_evidence_sources": {
"label": "Sykluser som former et program",
"doc": "Hvilke sykluser som brukes til å bygge opp effektkurven for hvert program, og til å matche en ferdig syklus mot den. Fjerner du haken for en type, former den ikke lenger programmene dine, uten at noe slettes - syklusene blir liggende i Sykluser-listen din og kan fortsatt merkes eller fjernes. Nyttig hvis du ikke stoler på importerte data. Statistikken påvirkes ikke: den teller alltid bare syklusene denne maskinen faktisk har kjørt. Å fjerne alle hakene blir ignorert, siden et program uten sykluser bak seg aldri kunne matche."
}
},
"setting_group": {
@@ -1634,6 +1700,9 @@
},
"basic_configuration": {
"label": "Grunnleggende konfigurasjon"
},
"profile_evidence": {
"label": "Profilgrunnlag"
}
},
"status": {
@@ -1658,7 +1727,8 @@
"trimming": "Beskjærer…",
"splitting": "Deler opp…",
"deleting": "Sletter…",
"imported": "Importert"
"imported": "Importert",
"preparing": "Forbereder…"
},
"suggestion": {
"both_agree": "WashData anbefaler",
@@ -1754,7 +1824,7 @@
"thr_batch": "Holdt like over den laveste aktive effekten ved p05 på tvers av {cycles} sykluser ({p05}W) slik at en start fanges så tidlig som mulig og stoppterskelen holder seg under maskinens laveste driftseffekt.",
"tol_per_profile": "p75 for varighetsvariansen per profil på tvers av {profiles} profiler ({cycles} sykluser); stramme profiler straffes ikke.",
"tol_pooled": "Basert på samlet varighetsvarians for {cycles} nyeste merkede sykluser (p95 avvik={dev}).",
"watchdog": "Holdt så lavt som forsvarlig (like over p95-oppdateringsmellomrommet på {p95}s, min 30s) slik at stans fanges raskt uten falske stopp."
"watchdog": "Holdt så lavt som forsvarlig (like over p95-oppdateringsmellomrommet på {p95}s og minst 2x samplingsintervallet på {median}s, min. 30s) slik at stans fanges raskt uten falske stopp."
},
"exclusions": {
"summary": "Ekskluderte {total} feildetekterte syklus(er): {parts}.",
@@ -1801,6 +1871,7 @@
"wrong_profile": "Feil profil"
},
"toast": {
"catalog_refreshed": "Fellesskapskatalogen er oppdatert",
"access_saved": "Tilgangskontroll lagret",
"all_wiped": "Alle data slettet",
"analysis_complete_none": "Analysen er fullført: ingen nye forslag",
@@ -1812,7 +1883,7 @@
"cycle_labelled": "Syklus merket",
"cycle_paused": "Syklus stoppet",
"cycle_resumed": "Syklusen ble gjenopptatt",
"cycle_trimmed": "Syklus trimmet",
"cycle_trimmed": "Syklus beskjært",
"cycles_merged": "Sykluser slått sammen",
"envelope_rebuilt": "Konvolutt gjenoppbygd",
"envelopes_rebuilt": "Konvolutter gjenoppbygd",
@@ -1906,7 +1977,9 @@
"store_download_failed": "Nedlasting mislyktes: {error}",
"store_download_nothing": "Ingenting nytt å laste ned -- dette oppsettet er allerede på apparatet ditt.",
"export_selective_done": "Eksport lastet ned",
"import_selective_done": "Importerte {profiles} profil(er) og {cycles} syklus(er)"
"import_selective_done": "Importerte {profiles} profil(er) og {cycles} syklus(er)",
"hist_csv_required": "Last inn en CSV-fil eller lim inn innholdet først",
"file_read_failed": "Kunne ikke lese den filen"
},
"trend": {
"down": "Trender nedover",
@@ -1955,6 +2028,10 @@
"finished": "Syklusen nådde en sluttilstand og stoppet."
},
"store": {
"your_model_tip": "Dette er apparatet du har angitt i Innstillinger",
"your_model": "Ditt apparat",
"search_brand_ph": "Søk etter merke…",
"programs_count": "Programmer: {n}",
"browse": "Bla gjennom",
"device": "Enhet",
"favorites": "Favoritter",
@@ -78,9 +78,12 @@
"awaiting": "Wacht op goedkeuring",
"imported_tip": "Geïmporteerd uit de communitystore. Alleen gebruikt voor matchen, telt niet mee in statistieken.",
"not_importable": "hier n.v.t.",
"exists": "bestaat"
"exists": "bestaat",
"backfilled_tip": "Gedetecteerd in geïmporteerde vermogensgeschiedenis. Beïnvloedt alleen het matchen van programma's, telt niet mee in statistieken."
},
"btn": {
"set_brand_model": "Merk en model instellen",
"refresh_catalog": "Catalogus vernieuwen",
"add_device": "+ Apparaat toevoegen",
"add_device_tip": "Voeg nog een WashData-apparaat toe",
"add_maintenance": "Onderhoudsgebeurtenis toevoegen",
@@ -90,7 +93,7 @@
"apply_label": "Etiket toepassen",
"apply_set_b": "Set B toepassen",
"apply_split": "Splitsing toepassen",
"apply_trim": "Pas trimmen toe",
"apply_trim": "Bijsnijden toepassen",
"auto_detect_split": "Automatische detectie",
"auto_label_cycles": "Cycli automatisch labelen",
"auto_label_cycles_tip": "Wijs automatisch profielnamen toe aan ongelabelde cycli waarvan de matchbetrouwbaarheid de drempel haalt",
@@ -209,8 +212,8 @@
"stop": "Stoppen",
"submit_correction": "Correctie indienen",
"train_now": "Train nu",
"trim": "Trimmen",
"trim_split": "Trimmen/splitsen",
"trim": "Bijsnijden",
"trim_split": "Bijsnijden / splitsen",
"undo": "Ongedaan maken",
"use": "Gebruik",
"wipe_all": "Wis alle gegevens",
@@ -241,7 +244,12 @@
"import_selected": "Selectie importeren",
"back": "Terug",
"mute_suggestion": "Deze instelling niet meer voorstellen",
"reset_muted": "Gedempte suggesties herstellen"
"reset_muted": "Gedempte suggesties herstellen",
"import_power_history": "Vermogensgeschiedenis importeren",
"hist_read_recorder": "Uit Home Assistant lezen",
"hist_scan": "Zoeken naar cycli",
"hist_import_n": "{n} cycli importeren",
"hist_goto_cycles": "Toon me de cycli"
},
"conflict": {
"anti_wrinkle_exit": {
@@ -253,12 +261,12 @@
"start": "Moet onder het maximale anti-kreuk-vermogen ({max} W) liggen"
},
"attn_sub": "Los conflicten op voor het opslaan",
"attn_title": "{n} instellingsconflict{s}",
"attn_title": "Instellingsconflicten: {n}",
"confidence": {
"auto": "Moet op of boven de overeenkomstdrempel ({match}) liggen",
"learning": "Moet op of onder de overeenkomstdrempel ({match}) liggen",
"learning": "Moet op of boven de overeenkomstdrempel ({match}) liggen",
"match_for_auto": "Moet op of onder het automatisch-label-betrouwbaarheidsniveau ({alc}) liggen",
"match_for_learning": "Moet op of boven het leerbetrouwbaarheidsniveau ({lc}) liggen"
"match_for_learning": "Moet op of onder het leerbetrouwbaarheidsniveau ({lc}) liggen"
},
"duration_ratio": {
"max": "Moet groter zijn dan de minimale duurverhouding ({min})",
@@ -296,14 +304,14 @@
"match": "Moet boven de niet-overeenkomstdrempel ({un}) liggen",
"unmatch": "Moet onder de overeenkomstdrempel ({match}) liggen; anders wordt een bevestigde overeenkomst direct ongedaan gemaakt"
},
"cascade_toast": "Ook {n} instelling{s} aangepast voor consistentie.",
"cascade_toast": "Andere instellingen aangepast voor consistentie: {n}",
"suggestion_resolves": "Pas hieronder de openstaande suggestie ({val}) toe om dit op te lossen",
"use_fix": "Gebruik {val}",
"watchdog": {
"interval": "Moet minimaal 2x het bemonsteringsinterval ({si} s) zijn",
"sampling": "Bemonsteringsinterval moet maximaal de helft van het watchdog-interval ({wi} s) zijn"
},
"settings_banner": "{n} instellingsconflict{s} controleer de gemarkeerde secties en los ze op voor het opslaan.",
"settings_banner": "Instellingsconflicten: {n}. Controleer de gemarkeerde secties en los ze op voordat u opslaat.",
"settings_banner_btn": "Ga naar eerste"
},
"hdr": {
@@ -356,7 +364,8 @@
"pg_outcome": "Simulatieresultaat",
"pg_across_cycles": "Over al je cycli",
"community_store": "Communitystore",
"online_account": "Communitystore en onlinefuncties"
"online_account": "Communitystore en onlinefuncties",
"import_power_history": "Vermogensgeschiedenis importeren"
},
"health": {
"fair": "Acceptabele profielkwaliteit",
@@ -364,6 +373,7 @@
"poor": "⚠ Slechte profielkwaliteit"
},
"lbl": {
"drag_to_resize": "Sleep om het formaat te wijzigen",
"actions": "Acties",
"activity": "Activiteit",
"administrators": "Beheerders",
@@ -450,7 +460,7 @@
"metric": "Metriek",
"mode_existing_profile": "Toevoegen aan bestaand profiel",
"mode_new_profile": "Nieuw profiel maken",
"models_fine_tuned": "({count} model{plural} verfijnd)",
"models_fine_tuned": "(verfijnde modellen: {count})",
"n_classic_suggestions": "{n} klassiek",
"n_ml_suggestions": "{n} ML",
"n_selected": "{n} geselecteerd",
@@ -677,7 +687,26 @@
"conflict_keep_mine": "Die van mij behouden",
"conflict_overwrite": "Overschrijven",
"pg_anti_wrinkle": "Anti-kreuk",
"font_size": "Paneel lettergrootte"
"font_size": "Paneel lettergrootte",
"hist_csv_data": "CSV-gegevens",
"hist_from_recorder": "Of lees het uit Home Assistant",
"hist_since": "Sinds",
"days": "dagen",
"hist_keep": "Deze cyclus bewaren",
"hist_looks_complete": "volledig",
"peak_power_short": "Piek",
"shape": "Vorm",
"hist_skip_idle": "niets actief",
"hist_skip_sparse": "metingen te ver uit elkaar",
"hist_skip_short": "te weinig metingen",
"hist_skip_long": "geen pauze lang genoeg om op te splitsen",
"hist_reason_short": "korter dan de kortste echte cyclus van dit apparaat",
"hist_reason_no_end": "nooit netjes beëindigd",
"task_history_import": "Vermogensgeschiedenis doorzoeken",
"task_history_import_apply": "Cycli importeren",
"evidence_real_cycles": "Cycli die deze machine heeft uitgevoerd",
"evidence_reference_cycles": "Gedownload uit de communitystore",
"evidence_backfill_cycles": "Gevonden in geïmporteerde vermogensgeschiedenis"
},
"log": {
"all_levels": "Alle niveaus",
@@ -756,9 +785,15 @@
"store_share": "Delen in communitystore",
"store_share_device": "Dit apparaat delen",
"export_select": "Export - gegevens kiezen",
"import_wizard": "Import - gegevens kiezen"
"import_wizard": "Import - gegevens kiezen",
"history_import": "Vermogensgeschiedenis importeren"
},
"msg": {
"tail_trim_hint": "Dit aantal seconden aan het einde verwijderen",
"store_sibling_hint": "Niets gedeeld voor precies uw model? Een nauw verwant model van hetzelfde merk is meestal een goed startpunt.",
"store_declare_appliance": "Laat WashData weten welk apparaat u bezit, dan toont dit tabblad de setups die anderen ervoor hebben gedeeld. U kunt hierboven ook een merk invoeren om rond te kijken.",
"refresh_catalog_hint": "De merken- en apparatenlijsten van de community worden in de cache opgeslagen zodat de communitystore binnen zijn daglimiet blijft. Vernieuw om vermeldingen op te halen die anderen hebben toegevoegd of goedgekeurd.",
"head_trim_hint": "Dit aantal seconden aan het begin verwijderen",
"appliance_monitor": "Apparaatmonitor",
"artifact_dip_detail": "Daalde onder de gebruikelijke vermogensband voor ~{n}s.",
"artifact_footer": "Gemarkeerd in de bovenstaande grafiek. Dit zijn tijdelijke artefacten (bijvoorbeeld de deur die halverwege de cyclus wordt geopend), en niet noodzakelijkerwijs problemen.",
@@ -769,7 +804,7 @@
"automations_intro": "WashData activeert {start} / {end}-gebeurtenissen en stelt entiteiten beschikbaar, waardoor meldingen en acties het best als gewone Home Assistant-automatiseringen worden gebouwd. Automatiseringen die dit apparaat gebruiken, worden hieronder weergegeven.",
"cleanup_intro": "Elke gelabelde cyclus wordt overlay. Vink uitschieters aan en verwijder deze om het profiel op te schonen.",
"clear_debug_hint": "Verwijder opgeslagen foutopsporingsgegevens om ruimte vrij te maken.",
"collecting_data": "Gegevens worden verzameld: nog {need} cyclus{plural} voordat verfijning kan beginnen ({current}/{min}).",
"collecting_data": "Gegevens worden verzameld. Nog benodigde cycli voordat verfijning kan beginnen: {need} ({current}/{min}).",
"compare_overlay_profiles": "Overlay-profielen (vaag)",
"compare_profiles_tip": "Leg andere profielenveloppen op het schema hierboven om te zien welke het beste bij deze cyclus past.",
"compare_selected_cycles": "Geselecteerde cycli (vast) tonen/verbergen",
@@ -779,7 +814,7 @@
"cycles_deleted": "{count} cyclus(sen) verwijderd",
"enough_data": "Voldoende gegevens om van te leren ({current}/{min} cycli).",
"export_description": "Kies precies welke profielen, cycli, instellingen en meer u naar JSON wilt exporteren, of analyseer een bestand en importeer alleen de onderdelen die u wilt.",
"feedback_cycles_pending": "{n} cyclus{s} te beoordelen",
"feedback_cycles_pending": "Te beoordelen: {n}",
"feedback_prompt": "Bevestig dat het goed was, corrigeer het programma of negeer het.",
"feedback_relabel_hint": "Deze cyclus opnieuw labelen lost de beoordeling ook op.",
"filter_by_profile": "Filteren op profiel…",
@@ -856,7 +891,6 @@
"pg_stress_synthetic": "inactieve simulatie begint hier",
"pg_sweep_intro": "Wat als {param} anders was? Test {steps} waarden over je laatste {cycles} cycli om de instelling te vinden waarbij de meeste cycli correct worden herkend.",
"pg_sweep_step": "Stap {done} / {total}",
"pg_undetected": "{n} cyclus{s} niet gedetecteerd",
"pg_verdict_bad": "Vereist aandacht: veel cycli worden niet gedetecteerd.",
"pg_verdict_good": "Goed afgestemd: de meeste cycli worden correct herkend en gematcht.",
"pg_verdict_ok": "Acceptabel: sommige cycli gemist. Probeer de startdrempel te verlagen.",
@@ -887,6 +921,7 @@
"review_recorded_tip": "Markeer dit als een zorgvuldig uitgekozen referentiecyclus voor het programma - dezelfde rol als een handmatig geregistreerde cyclus. Referentiecycli worden altijd bewaard, voorzien van de overeenkomende sjabloon en worden nooit verwijderd door opschoning. (Dit is de \"gouden\"/opgenomen vlag; beide zijn hetzelfde.)",
"review_tags_tip": "Optionele vlaggen die beschrijven wat er mis is gegaan in deze cyclus, zodat training en opruiming hiervan een verklaring kunnen zijn.",
"review_to_cycles": "Open de wachtrij voor het beoordelen van cycli",
"samples_decimated": "{shown} van {total} metingen weergegeven (uitgedund voor weergave; pieken behouden). Een brede leemte hier is uitdunning, geen ontbrekende gegevens.",
"saving_triggers_reload": "Opslaan activeert een herladen van de integratie. HA-entiteiten kunnen kort worden weergegeven als niet beschikbaar.",
"search_placeholder": "Zoekinstellingen…",
"see_recorder": "Zie recorderwidget hieronder",
@@ -896,7 +931,7 @@
"shape_drift_detail": "Het vermogenspatroon voor dit profiel is in de loop van de tijd verschoven mogelijk slijtage van het apparaat of onderhoud nodig (bijv. ontkalken, filterreiniging).",
"show_all_settings": "Toon alle instellingen",
"showing_suggestions": "Instelling {count} met suggesties weergegeven.",
"split_intro": "Klik op de grafiek om een splitspunt toe te voegen of te verwijderen, of om automatisch gaten in de grafiek te detecteren. Elk resulterend segment kan zijn eigen profiel krijgen.",
"split_intro": "Klik op de grafiek om een splitspunt toe te voegen of te verwijderen, of om automatisch gaten in de grafiek te detecteren. Elk resulterend segment kan zijn eigen profiel krijgen.",
"storage_diagnostics": "Opslagstatistieken, onderhoud, export/import",
"sug_staged": "{key} = {val} ingesteld. Sla op om toe te passen.",
"toast_auto_detect_enabled": "Automatische detectie ingeschakeld",
@@ -924,7 +959,7 @@
"trend_energy_down": "Energietrend omlaag ({pct}%/cyclus)",
"trend_energy_up": "Energie stijgt ({pct}%/cyclus) recent gemiddelde {avg}",
"trim_destructive_confirm": "Hiermee wordt slechts {pct}% van de cyclus behouden. Dit kan niet ongedaan worden gemaakt. Doorgaan?",
"trim_intro": "Versleep de rode grepen of voer waarden in. Alles buiten het raam wordt verwijderd.",
"trim_intro": "Versleep de rode handgrepen of voer waarden in. Alles buiten het venster wordt verwijderd.",
"tuning_suggestions_available": "{count} afstemmingssuggestie beschikbaar op basis van waargenomen cycli. Ze verschijnen naast de relevante velden.",
"unsure_detected_prefix": "WashData weet niet zeker of het is gedetecteerd",
"updated": "Bijgewerkt",
@@ -1006,10 +1041,33 @@
"sug_mute_failed": "Instelling kon niet worden gedempt",
"sug_unmuted_all": "Gedempte suggesties hersteld",
"n_suggestions_muted": "{count} gedempt; de autotuner stelt deze niet meer voor.",
"font_size_hint": "Maak alles in dit paneel groter of kleiner. Geldt voor uw account op dit apparaat."
"font_size_hint": "Maak alles in dit paneel groter of kleiner. Geldt voor uw account op dit apparaat.",
"import_history_description": "Had je al een slimme stekker voordat je WashData ging gebruiken? Upload een geschiedenisexport van de vermogenssensor, of laat die rechtstreeks uit Home Assistant lezen, en de normale detectie loopt eroverheen zodat oude cycli in je Cycli-lijst verschijnen, klaar om benoemd te worden.",
"hist_input_hint": "Upload een CSV die je uit het Geschiedenis-paneel hebt gedownload (entiteit, status, laatst gewijzigd), of laat WashData de geschiedenis van de sensor direct lezen. De detectie loopt er dan precies zo over als live, en jij kiest welke van de gevonden cycli je bewaart.",
"hist_recorder_hint": "Leest vanaf de datum die je kiest tot nu. Home Assistant bewaart standaard 10 dagen gedetailleerde geschiedenis en daarna alleen uurgemiddelden, die te grof zijn om cycli in te detecteren - kies alleen een datum verder terug als je recorder is ingesteld om meer te bewaren.",
"hist_scanning": "Je geschiedenis wordt door de detectie gehaald. Dit gebeurt op de achtergrond - je kunt dit venster sluiten en later terugkomen.",
"hist_imported_count": "{n} cycli geïmporteerd.",
"hist_duplicates": "{n} waren al geïmporteerd en zijn overgeslagen.",
"hist_capped": "De limiet per apparaat voor geïmporteerde cycli is bereikt; de rest is niet opgeslagen.",
"hist_next_step": "Ze staan in je Cycli-lijst, gemarkeerd als geïmporteerde geschiedenis. Open er een en gebruik Labelen om het bijbehorende programma te benoemen.",
"hist_rows_read": "{n} metingen gelezen",
"hist_entity_substituted": "{used} gelezen (dit apparaat is geconfigureerd voor {wanted})",
"hist_breaks": "{n} gaten waarin de sensor niet beschikbaar was",
"hist_other_entity": "{n} metingen voor andere entiteiten genegeerd",
"hist_skipped_spans": "Overgeslagen stukken",
"hist_settings_used": "Gedetecteerd met de huidige instellingen van dit apparaat (minimaal vermogen {w} W, uitschakelvertraging {s} s).",
"hist_none_found": "Er konden geen cycli in die geschiedenis worden gedetecteerd.",
"hist_found": "{n} cycli gevonden. Vink alles uit wat niet op een echte draaibeurt lijkt - er wordt niets opgeslagen totdat je importeert.",
"hist_scan_capped": "Alleen de eerste kandidaten worden weergegeven ({n} gevonden).",
"hist_recorder_empty": "Home Assistant heeft in dat tijdvak geen gedetailleerde geschiedenis voor deze sensor.",
"hist_scan_failed": "Zoeken mislukt.",
"hist_scan_expired": "Die zoekopdracht is niet meer beschikbaar. Zoek opnieuw.",
"hist_import_failed": "Importeren mislukt.",
"imported_history_readonly": "Gedetecteerd in geïmporteerde vermogensgeschiedenis. Het beïnvloedt het matchen van programma's, maar telt niet mee in je statistieken en kan niet worden bijgesneden of gesplitst. Label het om het programma te benoemen."
},
"pg_desc": {
"dishwasher_end_spike_quiet_release": "Vaatwasser: stille seconden na de verwachte duur voordat de wachttijd op het wegpompen aan het einde van de cyclus wordt vrijgegeven",
"smart_termination_duration_ratio": "Deel van de verwachte duur van het herkende programma dat een cyclus moet bereiken voordat de slimme beëindiging hem vroegtijdig mag afsluiten; verlaag deze voor belasting- of temperatuurafhankelijke machines",
"completion_min_seconds": "Kortste run die als een echte cyclus telt",
"end_repeat_count": "Opeenvolgende lage metingen voor het einde",
"interrupted_min_seconds": "Korte cycli gemarkeerd als onderbroken",
@@ -1162,7 +1220,7 @@
"label": "Automatisch onderhoud (nachtelijke opruiming)"
},
"completion_min_seconds": {
"doc": "Cycli korter dan dit worden weggegooid als spookcycli (testruns, de deur openen om een sok toe te voegen).",
"doc": "Cycli korter dan dit worden weggegooid als spookcycli (testruns, de deur openen om een sok toe te voegen).",
"label": "Min. cyclusduur"
},
"delay_confirm_seconds": {
@@ -1246,7 +1304,7 @@
"label": "Minimaal vermogen"
},
"ml_training_enabled": {
"doc": "Bestudeer uw beoordeelde cycli regelmatig van de ene op de andere dag en stem de modellen af op deze specifieke machine. Een verandering wordt alleen behouden als deze daadwerkelijk beter scoort op aanhoudende cycli, dus dit kan alleen maar helpen of hetzelfde blijven - nooit achteruitgaan.",
"doc": "Bestudeer uw beoordeelde cycli regelmatig van de ene op de andere dag en stem de modellen af op deze specifieke machine. Een verandering wordt alleen behouden als deze daadwerkelijk beter scoort op aanhoudende cycli, dus dit kan alleen maar helpen of hetzelfde blijven - nooit achteruitgaan.",
"label": "Leren van deze machine"
},
"ml_training_hour": {
@@ -1266,7 +1324,7 @@
"label": "Apparaatnaam"
},
"no_update_active_timeout": {
"doc": "Als er gedurende deze tijd geen stroomupdates arriveren tijdens het gebruik, ga er dan van uit dat de stekker offline is gevallen en forceer een stop om een zombiecyclus te voorkomen. Standaard 600 s maakt cloud- of mesh-vertraging mogelijk.",
"doc": "Als er gedurende deze tijd geen stroomupdates arriveren tijdens het gebruik, ga er dan van uit dat de stekker offline is gevallen en forceer een stop om een zombiecyclus te voorkomen. Standaard 600 s maakt cloud- of mesh-vertraging mogelijk.",
"label": "Time-out zonder update"
},
"notify_before_end_minutes": {
@@ -1394,7 +1452,7 @@
"label": "Min. duurverhouding"
},
"profile_match_threshold": {
"doc": "Minimale gelijkheidsscore (0-1) vereist aan het einde van de cyclus om een programma-identificatie te accepteren. Verhoog het om verkeerde identificaties te verminderen; verlaag het als de programma's van uw machine niet overeenkomen. Standaard 0,4 is een conservatief uitgangspunt.",
"doc": "Minimale gelijkheidsscore (0-1) vereist aan het einde van de cyclus om een programma-identificatie te accepteren. Verhoog het om verkeerde identificaties te verminderen; verlaag het als de programma's van uw machine niet overeenkomen. Standaard 0,4 is een conservatief uitgangspunt.",
"label": "Afstemmingsdrempel"
},
"profile_unmatch_threshold": {
@@ -1421,12 +1479,16 @@
"doc": "Bewaar de volledige vermogenstrace en overeenkomende foutopsporingsgegevens voor elke cyclus. Handig voor het oplossen van problemen, maar vergroot de opslaggrootte.",
"label": "Foutopsporingssporen opslaan"
},
"smart_termination_duration_ratio": {
"doc": "Hoe ver een cyclus in de verwachte duur van het herkende programma moet zijn voordat de slimme beëindiging hem vroegtijdig mag afsluiten zodra het vermogen daalt. De verwachte duur is het gemiddelde van het programma, dus bij apparaten waarvan de looptijd sterk varieert - wasmachines met koud toevoerwater in de winter versus warm in de zomer, drogers met vochtsensor, belastingafhankelijke programma's - eindigt ongeveer de helft van alle draaien korter dan dat gemiddelde en krijgt nooit de snelle beëindiging, maar eindigt pas minuten later via de fallback-time-out. Verlaag deze waarde (bijv. 0,85) op zulke machines zodat de vroegtijdige beëindiging toch wordt geactiveerd; verhoog hem richting 1,0 om voorzichtiger te zijn. Laat leeg voor de standaard (0,98, of 0,99 voor vaatwassers). Hij kan een cyclus alleen eerder beëindigen, nooit later, en wordt nooit geactiveerd bij een dubbelzinnige of onzekere herkenning.",
"label": "Verhouding slimme beëindiging"
},
"smoothing_window": {
"doc": "Hoeveel het ruwe stroomsignaal wordt afgevlakt. Laag (2) is responsief maar luidruchtig; hoog (5) verzacht pieken maar voegt vertraging toe.",
"label": "Afvlakkingsvenster"
},
"start_duration_threshold": {
"doc": "Het vermogen moet zo lang boven de startdrempel blijven om een echte start te bevestigen, waardoor wordt voorkomen dat aan/uit-schakelaars van een fractie van een seconde een cyclus starten.",
"doc": "Het vermogen moet zo lang boven de startdrempel blijven om een echte start te bevestigen, waardoor wordt voorkomen dat aan/uit-schakelaars van een fractie van een seconde een cyclus starten.",
"label": "Startduur"
},
"start_energy_threshold": {
@@ -1551,6 +1613,10 @@
"door_end_dwell_seconds": {
"label": "Deuropen-eindverwijltijd",
"doc": "Hoe lang de deur open moet blijven voordat WashData de cyclus beëindigt, wanneer \"Deur opent automatisch aan het einde\" is ingeschakeld. Lang genoeg om het snel toevoegen van een bord te negeren (standaard 60 s), kort genoeg om de cyclus snel te beëindigen zodra de machine de deur opent."
},
"profile_evidence_sources": {
"label": "Cycli die een programma vormen",
"doc": "Welke cycli worden gebruikt om de vermogenscurve van elk programma op te bouwen en om een voltooide cyclus daarmee te matchen. Een soort uitvinken laat die uw programma's niet langer vormen zonder dat er iets wordt verwijderd - de cycli blijven in uw Cycli-lijst staan en kunnen nog steeds gelabeld of verwijderd worden. Handig als u geïmporteerde gegevens niet vertrouwt. Statistieken blijven ongewijzigd: die tellen altijd alleen de cycli die deze machine echt heeft uitgevoerd. Alles uitvinken wordt genegeerd, want een programma zonder cycli erachter zou nooit kunnen matchen."
}
},
"setting_group": {
@@ -1634,6 +1700,9 @@
},
"basic_configuration": {
"label": "Basisconfiguratie"
},
"profile_evidence": {
"label": "Profielonderbouwing"
}
},
"status": {
@@ -1658,7 +1727,8 @@
"trimming": "Bijsnijden…",
"splitting": "Splitsen…",
"deleting": "Verwijderen…",
"imported": "Geïmporteerd"
"imported": "Geïmporteerd",
"preparing": "Voorbereiden…"
},
"suggestion": {
"both_agree": "WashData raadt aan",
@@ -1754,7 +1824,7 @@
"thr_batch": "Net boven het laagste actieve vermogen op p05 over {cycles} cycli ({p05}W) gehouden zodat een start zo vroeg mogelijk wordt opgemerkt en de stopdrempel onder het laagste draaivermogen van de machine blijft.",
"tol_per_profile": "p75 van de duurvariantie per profiel over {profiles} profielen ({cycles} cycli); strakke profielen worden niet benadeeld.",
"tol_pooled": "Op basis van de gebundelde duurvariantie van {cycles} recent gelabelde cycli (p95-afwijking={dev}).",
"watchdog": "Zo laag als veilig gehouden (net boven de p95-updatekloof van {p95}s, min. 30s) zodat vastlopers snel worden opgemerkt zonder valse stops."
"watchdog": "Zo laag als veilig gehouden (net boven de p95-updatekloof van {p95}s en minstens 2x het meetinterval van {median}s, min. 30s) zodat vastlopers snel worden opgemerkt zonder valse stops."
},
"exclusions": {
"summary": "{total} verkeerd gedetecteerde cyclus(sen) uitgesloten: {parts}.",
@@ -1801,6 +1871,7 @@
"wrong_profile": "Verkeerd profiel"
},
"toast": {
"catalog_refreshed": "Communitycatalogus vernieuwd",
"access_saved": "Toegangscontrole opgeslagen",
"all_wiped": "Alle gegevens gewist",
"analysis_complete_none": "Analyse voltooid: geen nieuwe suggesties",
@@ -1812,7 +1883,7 @@
"cycle_labelled": "Cyclus gelabeld",
"cycle_paused": "Cyclus onderbroken",
"cycle_resumed": "Cyclus hervat",
"cycle_trimmed": "Cyclus ingekort",
"cycle_trimmed": "Cyclus bijgesneden",
"cycles_merged": "Cycli samengevoegd",
"envelope_rebuilt": "Envelop opnieuw opgebouwd",
"envelopes_rebuilt": "Enveloppen opnieuw opgebouwd",
@@ -1906,7 +1977,9 @@
"store_download_failed": "Downloaden mislukt: {error}",
"store_download_nothing": "Niets nieuws te downloaden -- deze instelling staat al op uw apparaat.",
"export_selective_done": "Export gedownload",
"import_selective_done": "{profiles} profiel(en) en {cycles} cyclus(sen) geïmporteerd"
"import_selective_done": "{profiles} profiel(en) en {cycles} cyclus(sen) geïmporteerd",
"hist_csv_required": "Laad eerst een CSV-bestand of plak de inhoud ervan",
"file_read_failed": "Kon dat bestand niet lezen"
},
"trend": {
"down": "Trend naar beneden",
@@ -1955,6 +2028,10 @@
"finished": "De cyclus bereikte een eindtoestand en stopte."
},
"store": {
"your_model_tip": "Dit is het apparaat dat u bij Instellingen hebt opgegeven",
"your_model": "Uw apparaat",
"search_brand_ph": "Zoeken op merk…",
"programs_count": "Programma's: {n}",
"browse": "Bladeren",
"device": "Apparaat",
"favorites": "Favorieten",
@@ -78,9 +78,12 @@
"awaiting": "Oczekuje na zatwierdzenie",
"imported_tip": "Zaimportowano ze sklepu społecznościowego. Używane tylko do dopasowywania, nie liczy się do statystyk.",
"not_importable": "niedostępne",
"exists": "istnieje"
"exists": "istnieje",
"backfilled_tip": "Wykryty w zaimportowanej historii mocy. Wpływa tylko na dopasowywanie programów, nie liczy się do statystyk."
},
"btn": {
"set_brand_model": "Ustaw markę i model",
"refresh_catalog": "Odśwież katalog",
"add_device": "+ Dodaj urządzenie",
"add_device_tip": "Dodaj kolejne urządzenie WashData",
"add_maintenance": "Dodaj zdarzenie konserwacji",
@@ -234,14 +237,19 @@
"download_device": "Pobierz konfigurację urządzenia",
"share_device": "Udostępnij konfigurację urządzenia",
"share_device_tip": "Udostępnij programy i ustawienia tego urządzenia społeczności",
"share_n": "Udostępnij {n} program{s}",
"share_n": "Udostępnij cykle: {n}",
"export_selected": "Eksport (wybierz dane)",
"export_all": "Szybki eksport wszystkiego",
"import_raw": "Zaawansowane: zastąp wszystko z pliku JSON",
"download_export": "Pobierz eksport",
"analyze_import": "Analizuj plik",
"import_selected": "Importuj wybrane",
"back": "Wstecz"
"back": "Wstecz",
"import_power_history": "Importuj historię mocy",
"hist_read_recorder": "Wczytaj z Home Assistant",
"hist_scan": "Szukaj cykli",
"hist_import_n": "Importuj cykle: {n}",
"hist_goto_cycles": "Pokaż cykle"
},
"conflict": {
"anti_wrinkle_exit": {
@@ -253,12 +261,12 @@
"start": "Musi być poniżej Maks. Mocy Antygniotowej ({max} W)"
},
"attn_sub": "Przed zapisaniem napraw konflikty",
"attn_title": "{n} konflikt{s} ustawień",
"attn_title": "Konflikty ustawień: {n}",
"confidence": {
"auto": "Musi być równy lub wyższy niż Próg Dopasowania ({match})",
"learning": "Musi być równy lub niższy niż Próg Dopasowania ({match})",
"learning": "Musi być równy lub wyższy niż Próg Dopasowania ({match})",
"match_for_auto": "Musi być równy lub niższy niż Pewność Automatycznego Etykietowania ({alc})",
"match_for_learning": "Musi być równy lub wyższy niż Pewność Uczenia ({lc})"
"match_for_learning": "Musi być równy lub niższy niż Pewność Uczenia ({lc})"
},
"duration_ratio": {
"max": "Musi być większy niż Minimalna Proporcja Czasu Trwania ({min})",
@@ -296,14 +304,14 @@
"match": "Musi być powyżej Progu Niedopasowania ({un})",
"unmatch": "Musi być poniżej Progu Dopasowania ({match}); w przeciwnym razie potwierdzone dopasowanie natychmiast się cofa"
},
"cascade_toast": "Dodatkowo dostosowano {n} ustawień w celu zachowania spójności.",
"cascade_toast": "Inne ustawienia dostosowane w celu zachowania spójności: {n}",
"suggestion_resolves": "Zastosuj oczekującą sugestię ({val}) poniżej, aby rozwiązać ten konflikt",
"use_fix": "Użyj {val}",
"watchdog": {
"interval": "Powinien wynosić co najmniej 2× Interwał Próbkowania ({si} s)",
"sampling": "Interwał Próbkowania powinien wynosić co najwyżej połowę Interwału Watchdog ({wi} s)"
},
"settings_banner": "{n} konflikt{s} ustawień sprawdź podświetlone sekcje i popraw przed zapisaniem.",
"settings_banner": "Konflikty ustawień: {n}. Sprawdź podświetlone sekcje i popraw je przed zapisaniem.",
"settings_banner_btn": "Przejdź do pierwszego"
},
"hdr": {
@@ -356,7 +364,8 @@
"pg_outcome": "Wynik symulacji",
"pg_across_cycles": "We wszystkich Twoich cyklach",
"community_store": "Sklep społecznościowy",
"online_account": "Sklep społecznościowy i funkcje online"
"online_account": "Sklep społecznościowy i funkcje online",
"import_power_history": "Import historii mocy"
},
"health": {
"fair": "Akceptowalna jakość profilu",
@@ -364,6 +373,7 @@
"poor": "⚠ Słaba jakość profilu"
},
"lbl": {
"drag_to_resize": "Przeciągnij, aby zmienić rozmiar",
"actions": "Działania",
"activity": "Działalność",
"administrators": "Administratorzy",
@@ -435,7 +445,7 @@
"from": "Od",
"gap_s": "Luka (y)",
"group_name": "Nazwa grupy",
"head_trim": "Głowica (e)",
"head_trim": "Przycięcie początku (s)",
"health": "Zdrowie",
"hide_tabs": "Ukryj karty dla osób niebędących administratorami",
"in_use": "W użyciu",
@@ -451,7 +461,7 @@
"metric": "Metryka",
"mode_existing_profile": "Dodaj do istniejącego profilu",
"mode_new_profile": "Utwórz nowy profil",
"models_fine_tuned": "({count} modeli dostrojonych)",
"models_fine_tuned": "(dostrojone modele: {count})",
"n_classic_suggestions": "{n} klasyczne",
"n_ml_suggestions": "{n} ML",
"n_selected": "Wybrano {n}",
@@ -533,7 +543,7 @@
"stage3": "Etap 3 DTW",
"stage4": "Etap 4 zgodność",
"status": "Status",
"tail_trim": "Trymowanie ogona",
"tail_trim": "Przycięcie końca (s)",
"timer_auto_pause": "Automatyczna pauza",
"timer_min": "min",
"timer_msg_placeholder": "Wiadomość (opcjonalnie, {device}/{program}/{minutes})",
@@ -677,7 +687,26 @@
"conflict_resolution": "Konflikty nazw",
"conflict_import_copy": "Importuj jako kopię",
"conflict_keep_mine": "Zachowaj moje",
"conflict_overwrite": "Nadpisz"
"conflict_overwrite": "Nadpisz",
"hist_csv_data": "Dane CSV",
"hist_from_recorder": "Albo wczytaj ją z Home Assistant",
"days": "dni",
"hist_keep": "Zachowaj ten cykl",
"hist_looks_complete": "zakończony",
"peak_power_short": "Szczyt",
"shape": "Kształt",
"hist_skip_idle": "nic nie działało",
"hist_skip_sparse": "odczyty zbyt oddalone od siebie",
"hist_skip_short": "za mało odczytów",
"hist_skip_long": "brak przerwy dość długiej, by podzielić",
"hist_reason_short": "krótszy niż najkrótszy rzeczywisty cykl tego urządzenia",
"hist_reason_no_end": "nigdy nie zakończył się poprawnie",
"hist_since": "Od",
"task_history_import": "Skanowanie historii mocy",
"task_history_import_apply": "Importowanie cykli",
"evidence_real_cycles": "Cykle wykonane przez to urządzenie",
"evidence_reference_cycles": "Pobrane ze sklepu społecznościowego",
"evidence_backfill_cycles": "Znalezione w zaimportowanej historii mocy"
},
"log": {
"all_levels": "Wszystkie poziomy",
@@ -756,9 +785,15 @@
"store_share": "Udostępnij w sklepie społecznościowym",
"store_share_device": "Udostępnij konfigurację urządzenia",
"export_select": "Eksport - wybierz dane",
"import_wizard": "Import - wybierz dane"
"import_wizard": "Import - wybierz dane",
"history_import": "Import historii mocy"
},
"msg": {
"tail_trim_hint": "Ile sekund usunąć z końca",
"store_sibling_hint": "Nic nie udostępniono dla Twojego dokładnego modelu? Bardzo podobny model tej samej marki to zwykle dobry punkt wyjścia.",
"store_declare_appliance": "Wskaż WashData, jakie urządzenie posiadasz, a ta karta pokaże konfiguracje udostępnione dla niego przez innych użytkowników. Możesz też wpisać markę powyżej, aby się rozejrzeć.",
"refresh_catalog_hint": "Listy marek i urządzeń społeczności są przechowywane w pamięci podręcznej, aby wspólny sklep nie przekroczył swojego dziennego limitu zapytań. Odśwież, aby pobrać pozycje dodane lub zatwierdzone przez innych.",
"head_trim_hint": "Ile sekund usunąć z początku",
"appliance_monitor": "Monitor urządzenia",
"artifact_dip_detail": "Moc spadła poniżej normalnego zakresu przez ~{n}s.",
"artifact_footer": "Zaznaczono na powyższym wykresie. Są to artefakty przejściowe (np. otwarcie drzwi w połowie cyklu), niekoniecznie problemy.",
@@ -769,7 +804,7 @@
"automations_intro": "WashData uruchamia zdarzenia {start} / {end} i udostępnia encje, więc powiadomienia i akcje najlepiej budować jako normalne automatyzacje Home Assistant. Automatyzacje korzystające z tego urządzenia są widoczne poniżej.",
"cleanup_intro": "Każdy oznaczony cykl został nałożony. Zaznacz wartości odstające i usuń, aby oczyścić profil.",
"clear_debug_hint": "Usuń zapisane dane debugowania, aby zwolnić miejsce.",
"collecting_data": "Zbieranie danych: jeszcze {need} cykli do rozpoczęcia dostrajania ({current}/{min}).",
"collecting_data": "Zbieranie danych. Brakujące cykle do rozpoczęcia dostrajania: {need} ({current}/{min}).",
"compare_overlay_profiles": "Profile nakładkowe (słabe)",
"compare_profiles_tip": "Nałóż inne koperty profili na powyższy wykres, aby zobaczyć, która z nich najlepiej pasuje do tego cyklu.",
"compare_selected_cycles": "Wybrane cykle (pełne) pokaż / ukryj",
@@ -779,7 +814,7 @@
"cycles_deleted": "Usunięto cykle: {count}",
"enough_data": "Wystarczająco danych do nauki ({current}/{min} cykli).",
"export_description": "Wybierz dokładnie, które profile, cykle, ustawienia i inne dane wyeksportować do pliku JSON, albo przeanalizuj plik i zaimportuj tylko wybrane części.",
"feedback_cycles_pending": "{n} cykl{s} do sprawdzenia",
"feedback_cycles_pending": "Do sprawdzenia: {n}",
"feedback_prompt": "Potwierdź, że wszystko było w porządku, popraw program lub zignoruj.",
"feedback_relabel_hint": "Ponowne oznaczenie tego cyklu również go rozwiązuje.",
"filter_by_profile": "Filtruj według profilu…",
@@ -856,7 +891,6 @@
"pg_stress_synthetic": "symulacja bezczynności zaczyna się tutaj",
"pg_sweep_intro": "Co by było, gdyby {param} był inny? Przetestuj {steps} wartości na swoich ostatnich {cycles} cyklach, aby znaleźć ustawienie, przy którym najwięcej cykli jest poprawnie dopasowanych.",
"pg_sweep_step": "Krok {done} / {total}",
"pg_undetected": "{n} niewykrytych cykli",
"pg_verdict_bad": "Wymaga uwagi: wiele cykli pozostaje niewykrytych.",
"pg_verdict_good": "Dobrze dostrojone: większość cykli jest poprawnie rozpoznawana i dopasowywana.",
"pg_verdict_ok": "Akceptowalnie: część cykli pominięto. Spróbuj obniżyć próg startu.",
@@ -888,6 +922,7 @@
"review_recorded_tip": "Oznacz to jako ręcznie wybrany cykl referencyjny dla swojego programu pełni tę samą rolę, co cykl nagrany ręcznie. Cykle referencyjne są zawsze zachowywane, zaszczepiają pasujący szablon i nigdy nie są usuwane podczas czyszczenia. (To jest „złota”/nagrana flaga; obie są tym samym.)",
"review_tags_tip": "Opcjonalne flagi opisujące, co poszło nie tak w tym cyklu, więc szkolenie i czyszczenie mogą to wyjaśnić.",
"review_to_cycles": "Otwórz kolejkę przeglądu Cykli",
"samples_decimated": "Wyświetlanie {shown} z {total} próbek (przerzedzone do wyświetlania; szczyty zachowane). Szeroka przerwa oznacza tu przerzedzenie, a nie brakujące dane.",
"saving_triggers_reload": "Zapisanie powoduje przeładowanie integracji. Jednostki HA mogą przez chwilę być wyświetlane jako niedostępne.",
"search_placeholder": "Ustawienia wyszukiwania…",
"see_recorder": "Zobacz widżet rejestratora poniżej",
@@ -929,7 +964,7 @@
"trend_energy_down": "Energia wykazuje tendencję spadkową ({pct}%/cykl)",
"trend_energy_up": "Trend wzrostowy w zakresie energii ({pct}%/cykl) ostatnia średnia {avg}",
"trim_destructive_confirm": "To zachowa tylko {pct}% cyklu i tej operacji nie można cofnąć. Kontynuować?",
"trim_intro": "Przeciągnij czerwone uchwyty lub wprowadź wartości. Wszystko za oknem jest usuwane.",
"trim_intro": "Przeciągnij czerwone uchwyty lub wprowadź wartości. Wszystko poza oknem jest usuwane.",
"tuning_suggestions_available": "Sugestia dostrojenia {count} dostępna z obserwowanych cykli. Pojawiają się obok odpowiednich pól.",
"unsure_detected_prefix": "WashData nie jest pewien, czy został wykryty",
"updated": "Zaktualizowano",
@@ -991,12 +1026,12 @@
"share_consent": "Udostępniasz rzeczywiste dane ze swojego urządzenia. Nie udostępniaj, jeśli Twoje wzorce użytkowania są prywatne.",
"share_device_none": "Nie skonfigurowano jeszcze żadnych urządzeń. Najpierw dodaj urządzenie.",
"share_guideline_naming": "Używaj czytelnych nazw programów (np. 'Cotton 40', 'Eco 60'), żeby inni mogli je zidentyfikować",
"share_guideline_quality": "Udostępniaj tylko profile z ⭐ cyklami referencyjnymi lub co najmniej {n} potwierdzonymi uruchomieniami",
"share_guideline_quality": "Udostępniaj tylko cykle, które zakończyły się normalnie: bez przerw w połowie cyklu, otwierania drzwi ani chwilowych zaników zasilania.",
"share_guideline_review": "Przejrzyj swoje profile przed udostępnieniem -- usuń te, które wyglądają błędnie",
"share_guidelines_title": "Przed udostępnieniem",
"store_download_device_intro": "Pobierz konfigurację urządzenia ze społeczności i zastosuj ją do nowego lub istniejącego urządzenia",
"store_share_device_intro": "Udostępnij programy swojego urządzenia (profile + cykle referencyjne) społeczności. Ustawienia są opcjonalne.",
"share_profile_no_cycles": "Profil '{p}' nie ma ⭐ cykli referencyjnych -- zostanie pominięty, chyba że masz {n}+ potwierdzonych uruchomień",
"store_share_device_intro": "Prześlij {brand} {model} wraz z wybranymi cyklami referencyjnymi. Inne osoby z tym samym urządzeniem mogą przyjąć Twoje programy. Wpisy są sprawdzane przed publikacją.",
"share_profile_no_cycles": "Brak cykli referencyjnych. Aby dołączyć ten profil, oznacz cykl jako ⭐ na karcie Cykle",
"advisory_phase_inconsistent": "Wygląda na to, że '{name}' miesza różne programy lub temperatury - jego cykle nagrzewają się przez bardzo różne czasy. Podzielenie go na osobne profile (np. dla każdej temperatury) poprawi dopasowanie i szacowanie czasu.",
"advisory_phase_inconsistent_title": "⚠ Prawdopodobnie pomieszane programy",
"export_select_intro": "Zaznacz dokładnie to, co ma zostać uwzględnione. Wybranie profili bez ich cykli i tak eksportuje rozpoznawalny program (jego wyuczony kształt jest przenoszony razem z nim).",
@@ -1006,7 +1041,29 @@
"merge_hint": "Zaimportowane elementy są dodawane; nic lokalnego nie zostaje utracone. Konflikty nazw rozwiązuje się poniżej.",
"replace_warn": "Każda zaznaczona kategoria zostaje wyczyszczona i zastąpiona danymi z pliku. Niezaznaczone kategorie pozostają nietknięte.",
"dest_reference_hint": "Zaimportowane cykle jedynie poprawiają rozpoznawanie programów i nigdy nie wpływają na statystyki zużycia/energii.",
"dest_real_history_hint": "Zaimportowane cykle liczą się jako własna historia tego urządzenia i zasilają statystyki energii/zużycia. Użyj przy przenoszeniu jednego urządzenia do nowej instalacji."
"dest_real_history_hint": "Zaimportowane cykle liczą się jako własna historia tego urządzenia i zasilają statystyki energii/zużycia. Użyj przy przenoszeniu jednego urządzenia do nowej instalacji.",
"import_history_description": "Twoja inteligentna wtyczka działała już przed WashData? Wgraj eksport historii jej czujnika mocy albo wczytaj ją wprost z Home Assistant - normalne wykrywanie przebiegnie po tych danych, więc dawne cykle pojawią się na liście Cykle, gotowe do nazwania.",
"hist_input_hint": "Wgraj plik CSV pobrany z panelu Historia (encja, stan, ostatnia zmiana) albo pozwól WashData wczytać historię czujnika bezpośrednio. Wykrywanie przebiegnie dokładnie tak samo jak na żywo, a Ty wybierasz, które z odnalezionych cykli zachować.",
"hist_recorder_hint": "Odczytuje dane od wybranej daty do teraz. Home Assistant domyślnie przechowuje szczegółową historię przez 10 dni, a potem już tylko średnie godzinowe, zbyt zgrubne do wykrywania cykli - wcześniejszą datę wybieraj tylko wtedy, gdy Twój recorder jest ustawiony na dłuższe przechowywanie.",
"hist_scanning": "Odtwarzamy Twoją historię przez detektor. Działa to w tle - możesz zamknąć to okno i wrócić później.",
"hist_imported_count": "Zaimportowane cykle: {n}.",
"hist_duplicates": "Już wcześniej zaimportowane i pominięte: {n}.",
"hist_capped": "Osiągnięto limit zaimportowanych cykli na urządzenie; reszta nie została zapisana.",
"hist_next_step": "Są na liście Cykle, oznaczone jako zaimportowana historia. Otwórz jeden z nich i przyciskiem Oznacz nadaj mu nazwę programu, do którego należy.",
"hist_rows_read": "Wczytane odczyty: {n}",
"hist_breaks": "Przerwy, w których czujnik był niedostępny: {n}",
"hist_other_entity": "Pominięte odczyty innych encji: {n}",
"hist_entity_substituted": "Odczytano {used} (to urządzenie jest skonfigurowane dla {wanted})",
"hist_skipped_spans": "Pominięte odcinki",
"hist_settings_used": "Wykryto przy aktualnych ustawieniach tego urządzenia (minimalna moc {w} W, opóźnienie wyłączenia {s} s).",
"hist_none_found": "W tej historii nie udało się wykryć żadnych cykli.",
"hist_found": "Znalezione cykle: {n}. Odznacz wszystko, co nie wygląda na prawdziwy przebieg - nic nie zostanie zapisane, dopóki nie zaimportujesz.",
"hist_scan_capped": "Pokazywane są tylko pierwsze kandydatury (znaleziono: {n}).",
"hist_recorder_empty": "Home Assistant nie ma szczegółowej historii tego czujnika w tym okresie.",
"hist_scan_failed": "Skanowanie nie powiodło się.",
"hist_scan_expired": "To skanowanie nie jest już dostępne. Uruchom je ponownie.",
"hist_import_failed": "Import nie powiódł się.",
"imported_history_readonly": "Wykryty w zaimportowanej historii mocy. Wpływa na dopasowywanie programów, ale nie liczy się do Twoich statystyk i nie można go przyciąć ani podzielić. Oznacz go, aby nadać mu nazwę programu."
},
"phase_desc": {
"anti_crease": "Sporadyczne krótkie obroty bębna po zakończeniu w celu zapobiegania gnieceniu tkanin.",
@@ -1349,7 +1406,7 @@
"label": "Czujnik Mocy"
},
"profile_duration_tolerance": {
"doc": "Pasmo +/- wokół średniego czasu trwania profilu używanego podczas dopasowywania. Wartość 0,25 oznacza, że profil 60-minutowy odpowiada cyklom 45-75-minutowym.",
"doc": "Pasmo +/- wokół średniego czasu trwania profilu używanego podczas dopasowywania. Wartość 0,25 oznacza, że profil 60-minutowy odpowiada cyklom 45-75-minutowym.",
"label": "Tolerancja Czasu Profilu"
},
"profile_match_interval": {
@@ -1357,11 +1414,11 @@
"label": "Interwał Dopasowania"
},
"profile_match_max_duration_ratio": {
"doc": "Maksymalna długość cyklu w stosunku do profilu. 1.3 oznacza, że cykl musi trwać krócej niż 130% czasu trwania profilu, aby uzyskać zgodność.",
"doc": "Maksymalna długość cyklu w stosunku do profilu. 1.3 oznacza, że cykl musi trwać krócej niż 130% czasu trwania profilu, aby uzyskać zgodność.",
"label": "Maksymalna Proporcja Czasu Trwania"
},
"profile_match_min_duration_ratio": {
"doc": "Minimalna długość cyklu w stosunku do profilu. Wartość 0,9 oznacza, że aby cykl był zgodny, musi wynosić co najmniej 90% czasu trwania profilu.",
"doc": "Minimalna długość cyklu w stosunku do profilu. Wartość 0,9 oznacza, że aby cykl był zgodny, musi wynosić co najmniej 90% czasu trwania profilu.",
"label": "Minimalna Proporcja Czasu Trwania"
},
"profile_match_threshold": {
@@ -1392,6 +1449,10 @@
"doc": "Przechowuj ślad pełnej mocy i pasujące dane debugowania dla każdego cyklu. Przydatne do rozwiązywania problemów, ale zwiększa rozmiar pamięci.",
"label": "Zapisuj Ślady Debugowania"
},
"smart_termination_duration_ratio": {
"doc": "Jak daleko w oczekiwanym czasie trwania dopasowanego programu musi znajdować się cykl, zanim Inteligentne zakończenie może go zakończyć wcześniej po spadku mocy. Oczekiwany czas trwania to średnia programu, więc w urządzeniach, których czas pracy bardzo się waha - pralki z zimną wodą dopływową zimą wobec ciepłej latem, suszarki z suszeniem czujnikowym, programy zależne od wsadu - około połowa wszystkich uruchomień kończy się krócej niż ta średnia i nigdy nie doczeka się szybkiego zakończenia, kończąc dopiero przez awaryjny limit czasu, kilka minut później. W takich maszynach obniż tę wartość (np. 0,85), aby wcześniejsze zakończenie nadal się uruchamiało; zwiększ ją w stronę 1,0, aby zachować większą ostrożność. Pozostaw puste dla wartości domyślnej (0,98, a dla zmywarek 0,99). Może jedynie zakończyć cykl wcześniej, nigdy później, i nigdy nie uruchamia się przy niejednoznacznym dopasowaniu lub dopasowaniu o niskiej pewności.",
"label": "Współczynnik inteligentnego zakończenia"
},
"smoothing_window": {
"doc": "W jakim stopniu surowy sygnał mocy jest wygładzany. Niski (2) reaguje, ale jest głośny; wysoki (5) wygładza skoki, ale dodaje opóźnienia.",
"label": "Okno Wygładzania"
@@ -1522,6 +1583,10 @@
"door_end_dwell_seconds": {
"label": "Czas otwarcia drzwi do zakończenia cyklu",
"doc": "Jak długo drzwi muszą pozostać otwarte, zanim WashData zakończy cykl, gdy włączone jest \"Drzwi otwierają się automatycznie na końcu\". Wystarczająco długo, aby zignorować szybkie dodawanie naczyń (domyślnie 60 s), wystarczająco krótko, aby szybko zakończyć, gdy maszyna otworzy drzwi."
},
"profile_evidence_sources": {
"label": "Cykle kształtujące program",
"doc": "Które cykle są używane do zbudowania krzywej mocy każdego programu i do dopasowania do niej zakończonego cyklu. Odznaczenie danego rodzaju sprawia, że przestaje on wpływać na Twoje programy, ale nic nie zostaje usunięte - cykle pozostają na liście Cykle i nadal można je oznaczyć lub usunąć. Przydatne, jeśli nie masz zaufania do zaimportowanych danych. Nie ma to wpływu na statystyki: zawsze liczą tylko cykle, które to urządzenie faktycznie wykonało. Odznaczenie wszystkiego jest ignorowane, ponieważ program bez żadnych cykli nigdy nie mógłby zostać dopasowany."
}
},
"setting_group": {
@@ -1605,6 +1670,9 @@
},
"basic_configuration": {
"label": "Podstawowa konfiguracja"
},
"profile_evidence": {
"label": "Podstawa profilu"
}
},
"status": {
@@ -1629,7 +1697,8 @@
"trimming": "Przycinanie…",
"splitting": "Dzielenie…",
"deleting": "Usuwanie…",
"imported": "Zaimportowano"
"imported": "Zaimportowano",
"preparing": "Przygotowywanie…"
},
"suggestion": {
"both_agree": "WashData zaleca",
@@ -1725,7 +1794,7 @@
"thr_batch": "Utrzymane tuż powyżej najniższej mocy czynnej p05 w {cycles} cyklach ({p05}W), aby start był wykrywany jak najwcześniej, a próg zatrzymania pozostawał poniżej najniższej mocy pracy urządzenia.",
"tol_per_profile": "p75 wariancji czasu trwania na profil w {profiles} profilach ({cycles} cykli); spójne profile nie są karane.",
"tol_pooled": "Na podstawie łącznej wariancji czasu trwania {cycles} ostatnich oznaczonych cykli (odchylenie p95={dev}).",
"watchdog": "Utrzymane tak nisko, jak to bezpieczne (tuż powyżej przerwy aktualizacji p95 wynoszącej {p95}s, min. 30s), aby zawieszenia były szybko wykrywane bez fałszywych zatrzymań."
"watchdog": "Utrzymane tak nisko, jak to bezpieczne (tuż powyżej przerwy aktualizacji p95 wynoszącej {p95}s i co najmniej 2x powyżej interwału próbkowania {median}s, min. 30s), aby zawieszenia były szybko wykrywane bez fałszywych zatrzymań."
},
"exclusions": {
"summary": "Wykluczono {total} błędnie wykrytych cykli: {parts}.",
@@ -1772,6 +1841,7 @@
"wrong_profile": "Zły profil"
},
"toast": {
"catalog_refreshed": "Katalog społeczności odświeżony",
"access_saved": "Kontrola dostępu zapisana",
"all_wiped": "Wszystkie dane zostały usunięte",
"analysis_complete_none": "Analiza ukończona: brak nowych sugestii",
@@ -1811,7 +1881,7 @@
"pg_sugg_ml_loaded": "Załadowano {n} wartości skalibrowanych przez ML - uruchom piaskownicę, aby porównać",
"phase_name_required": "Nazwa fazy jest wymagana",
"phase_updated": "Faza zaktualizowana",
"phases_saved": "Fazy zapisane",
"phases_saved": "Fazy zapisane",
"preferences_saved": "Preferencje zostały zapisane",
"profile_name_required": "Nazwa profilu jest wymagana",
"profile_renamed": "Zmieniono nazwę profilu",
@@ -1865,19 +1935,21 @@
"rating_saved": "Ocena jakości zapisana",
"brand_added": "Marka dodana, oczekuje na zatwierdzenie",
"profile_added": "Profil dodany, oczekuje na zatwierdzenie",
"saved_except_conflicts": "Ustawienia zapisane -- {n} ustawienie{s} pominięte z powodu konfliktów",
"saved_except_conflicts": "Zapisano. Popraw podświetlone konflikty, aby zapisać pozostałe.",
"share_device_none_sel": "Wybierz co najmniej jeden program do udostępnienia",
"store_device_downloaded": "Konfiguracja urządzenia pobrana: {created} profil{c} utworzony, {dup} już istniało",
"store_device_downloaded_phases": "Konfiguracja urządzenia pobrana: {created} profil{c} utworzony, {dup} już istniało, mapa faz zastosowana",
"store_device_downloaded_settings": "Konfiguracja urządzenia pobrana: {created} profil{c} utworzony, {dup} już istniało, ustawienia zastosowane",
"store_device_shared": "Konfiguracja urządzenia udostępniona: {n} program{s} przesłany",
"store_device_shared_all_dup": "Nic nowego do udostępnienia -- wszystkie programy już istnieją w sklepie",
"store_device_shared_partial": "Częściowe udostępnienie: {n} program{s} przesłany, {failed} pominięte",
"store_device_shared_some_dup": "Konfiguracja urządzenia udostępniona: {n} program{s} przesłany ({dup} już istniało)",
"store_device_downloaded": "Dodano programów: {p}, nagrań: {c}",
"store_device_downloaded_phases": "Dodano programów: {p}, nagrań: {c}, map faz: {ph}",
"store_device_downloaded_settings": "Dodano programów: {p}, nagrań: {c}, map faz: {ph}, ustawień: {s}",
"store_device_shared": "Udostępniono w sklepie społecznościowym (cykli: {n}), oczekuje na weryfikację.",
"store_device_shared_all_dup": "Wszystkie wybrane cykle ({n}) były już w sklepie społecznościowym.",
"store_device_shared_partial": "Udostępniono cykli: {n}; nie udało się przesłać: {failed}.",
"store_device_shared_some_dup": "Udostępniono cykli: {created}; już w sklepie: {dup}.",
"store_download_failed": "Pobieranie nie powiodło się: {error}",
"store_download_nothing": "Nic do pobrania -- wszystkie profile już istnieją na tym urządzeniu",
"export_selective_done": "Eksport pobrany",
"import_selective_done": "Zaimportowano {profiles} profil(e) i {cycles} cykl(e)"
"import_selective_done": "Zaimportowano {profiles} profil(e) i {cycles} cykl(e)",
"hist_csv_required": "Najpierw wczytaj plik CSV lub wklej jego zawartość",
"file_read_failed": "Nie udało się odczytać tego pliku"
},
"trend": {
"down": "Trend w dół",
@@ -1892,6 +1964,7 @@
},
"pg_desc": {
"dishwasher_end_spike_quiet_release": "Zmywarka: sekundy ciszy po oczekiwanym czasie trwania, zanim zwolnione zostanie oczekiwanie na końcowe odpompowanie wody",
"smart_termination_duration_ratio": "Ułamek oczekiwanego czasu trwania dopasowanego programu, który cykl musi osiągnąć, zanim Inteligentne zakończenie może go zakończyć wcześniej; obniż go w przypadku maszyn zależnych od wsadu lub temperatury",
"anti_wrinkle_enabled": "Pochłaniaj impulsy bębna po głównej fazie, zamiast odczytywać je jako nowe cykle",
"anti_wrinkle_exit_power": "Moc musi spaść poniżej tej wartości pomiędzy impulsami, aby tryb antygniotowy pozostał aktywny",
"anti_wrinkle_idle_timeout": "Dozwolony czas ciszy między dwoma impulsami bębna, zanim tryb antygniotowy się zakończy",
@@ -1955,6 +2028,10 @@
"finished": "Cykl osiągnął stan końcowy i zakończył się."
},
"store": {
"your_model_tip": "To urządzenie wskazane przez Ciebie w Ustawieniach",
"your_model": "Twoje",
"search_brand_ph": "Szukaj według marki…",
"programs_count": "Programy: {n}",
"browse": "Przeglądaj",
"device": "Urządzenie",
"favorites": "Ulubione",
@@ -30,9 +30,12 @@
"awaiting": "Aguardando aprovação",
"imported_tip": "Importado da loja da comunidade. Usado apenas para correspondência, não contabilizado nas estatísticas.",
"not_importable": "n/d aqui",
"exists": "já existe"
"exists": "já existe",
"backfilled_tip": "Detectado em um histórico de potência importado. Influencia apenas a correspondência de programas, não é contabilizado nas estatísticas."
},
"btn": {
"set_brand_model": "Definir marca e modelo",
"refresh_catalog": "Atualizar catálogo",
"add_device": "+ Adicionar dispositivo",
"add_device_tip": "Adicionar outro dispositivo WashData",
"add_maintenance": "Adicionar evento de manutenção",
@@ -193,7 +196,12 @@
"import_selected": "Importar seleção",
"back": "Voltar",
"mute_suggestion": "Parar de sugerir esta configuração",
"reset_muted": "Redefinir silenciados"
"reset_muted": "Redefinir silenciados",
"import_power_history": "Importar histórico de potência",
"hist_read_recorder": "Ler do Home Assistant",
"hist_scan": "Procurar ciclos",
"hist_import_n": "Importar {n} ciclos",
"hist_goto_cycles": "Ver os ciclos"
},
"conflict": {
"anti_wrinkle_exit": {
@@ -205,14 +213,14 @@
"start": "Deve ser abaixo da Potência máxima antiamassado ({max} W)"
},
"attn_sub": "Corrija os conflitos antes de salvar",
"attn_title": "{n} conflito{s} de configurações",
"settings_banner": "{n} conflito{s} de configurações verifique as seções destacadas e corrija antes de salvar.",
"attn_title": "Conflitos de configurações: {n}",
"settings_banner": "Conflitos de configurações: {n}. Verifique as seções destacadas e corrija-os antes de salvar.",
"settings_banner_btn": "Ir para o primeiro",
"confidence": {
"auto": "Deve ser maior ou igual ao Limiar de correspondência ({match})",
"learning": "Deve ser menor ou igual ao Limiar de correspondência ({match})",
"learning": "Deve ser maior ou igual ao Limiar de correspondência ({match})",
"match_for_auto": "Deve ser menor ou igual à Confiança de rotulagem automática ({alc})",
"match_for_learning": "Deve ser maior ou igual à Confiança de aprendizado ({lc})"
"match_for_learning": "Deve ser menor ou igual à Confiança de aprendizado ({lc})"
},
"duration_ratio": {
"max": "Deve ser maior que a Proporção de duração mínima ({min})",
@@ -250,7 +258,7 @@
"match": "Deve ser acima do Limiar de não correspondência ({un})",
"unmatch": "Deve ser abaixo do Limiar de correspondência ({match}); caso contrário, uma correspondência confirmada é imediatamente desfeita"
},
"cascade_toast": "Também foram aplicados {n} ajuste{s} por consistência.",
"cascade_toast": "Outras configurações ajustadas por consistência: {n}",
"suggestion_resolves": "Aplique a sugestão pendente ({val}) abaixo para corrigir este conflito",
"use_fix": "Usar {val}",
"watchdog": {
@@ -308,7 +316,8 @@
"pg_outcome": "Resultado da simulação",
"pg_across_cycles": "Em todos os seus ciclos",
"community_store": "Loja da comunidade",
"online_account": "Loja da comunidade e recursos online"
"online_account": "Loja da comunidade e recursos online",
"import_power_history": "Importar histórico de potência"
},
"health": {
"fair": "Qualidade de perfil aceitável",
@@ -316,6 +325,7 @@
"poor": "⚠ Qualidade de perfil fraca"
},
"lbl": {
"drag_to_resize": "Arraste para redimensionar",
"actions": "Ações",
"activity": "Atividade",
"administrators": "Administradores",
@@ -402,7 +412,7 @@
"metric": "Métrica",
"mode_existing_profile": "Adicionar a perfil existente",
"mode_new_profile": "Criar novo perfil",
"models_fine_tuned": "({count} modelo{plural} ajustado{plural})",
"models_fine_tuned": "(modelos ajustados: {count})",
"n_classic_suggestions": "{n} clássico",
"n_ml_suggestions": "{n} ML",
"n_selected": "{n} selecionados",
@@ -629,7 +639,26 @@
"conflict_import_copy": "Importar como cópia",
"conflict_keep_mine": "Manter o meu",
"conflict_overwrite": "Sobrescrever",
"font_size": "Tamanho da fonte do painel"
"font_size": "Tamanho da fonte do painel",
"hist_csv_data": "Dados CSV",
"hist_from_recorder": "Ou ler direto do Home Assistant",
"hist_since": "Desde",
"days": "dias",
"hist_keep": "Manter este ciclo",
"hist_looks_complete": "completo",
"peak_power_short": "Pico",
"shape": "Forma",
"hist_skip_idle": "nada em funcionamento",
"hist_skip_sparse": "leituras muito espaçadas",
"hist_skip_short": "leituras insuficientes",
"hist_skip_long": "nenhuma pausa longa o suficiente para dividir",
"hist_reason_short": "mais curto que o ciclo real mais curto deste aparelho",
"hist_reason_no_end": "nunca terminou de forma limpa",
"task_history_import": "Analisando o histórico de potência",
"task_history_import_apply": "Importando ciclos",
"evidence_real_cycles": "Ciclos que esta máquina executou",
"evidence_reference_cycles": "Baixados da loja da comunidade",
"evidence_backfill_cycles": "Encontrados em um histórico de potência importado"
},
"log": {
"all_levels": "Todos os níveis",
@@ -708,9 +737,15 @@
"store_share": "Compartilhar na loja da comunidade",
"store_share_device": "Compartilhar este dispositivo",
"export_select": "Exportar - escolher dados",
"import_wizard": "Importar - escolher dados"
"import_wizard": "Importar - escolher dados",
"history_import": "Importar histórico de potência"
},
"msg": {
"tail_trim_hint": "Número de segundos a remover do final",
"store_sibling_hint": "Nada compartilhado para o seu modelo exato? Um modelo muito parecido da mesma marca costuma ser um bom ponto de partida.",
"store_declare_appliance": "Informe ao WashData qual eletrodoméstico você tem e esta aba mostrará as configurações que outras pessoas compartilharam para ele. Você também pode digitar uma marca acima para dar uma olhada.",
"refresh_catalog_hint": "As listas de marcas e eletrodomésticos da comunidade ficam em cache para manter a loja compartilhada dentro do seu limite diário. Atualize para obter as entradas adicionadas ou aprovadas por outras pessoas.",
"head_trim_hint": "Número de segundos a remover do início",
"appliance_monitor": "Monitor de eletrodoméstico",
"artifact_dip_detail": "Caiu abaixo da banda de potência habitual por ~{n}s.",
"artifact_footer": "Destacadas no gráfico acima. São artefatos transitórios (por exemplo, a porta foi aberta no meio do ciclo), não necessariamente problemas.",
@@ -721,7 +756,7 @@
"automations_intro": "O WashData dispara eventos {start} / {end} e expõe entidades, portanto as notificações e ações são melhor criadas como automatizações normais do Home Assistant. As automatizações que usam este dispositivo aparecem abaixo.",
"cleanup_intro": "Todos os ciclos rotulados sobrepostos. Marque os valores discrepantes e exclua para limpar o perfil.",
"clear_debug_hint": "Remova os dados de depuração armazenados para liberar espaço.",
"collecting_data": "Coletando dados - {need} ciclo{plural} a mais antes que o ajuste fino possa começar ({current}/{min}).",
"collecting_data": "Coletando dados. Ciclos ainda necessários para que o ajuste fino possa começar: {need} ({current}/{min}).",
"compare_overlay_profiles": "Sobrepor perfis (fraco)",
"compare_profiles_tip": "Sobreponha outros envelopes de perfil no gráfico acima para ver qual deles melhor se adapta a este ciclo.",
"compare_selected_cycles": "Ciclos selecionados (sólido) mostrar / ocultar",
@@ -731,7 +766,7 @@
"cycles_deleted": "{count} ciclo(s) excluído(s)",
"enough_data": "Dados suficientes para aprender ({current}/{min} ciclos).",
"export_description": "Escolha exatamente quais perfis, ciclos, configurações e mais exportar para JSON, ou analise um arquivo e importe apenas as partes que quiser.",
"feedback_cycles_pending": "{n} ciclo{s} para revisar",
"feedback_cycles_pending": "Para revisar: {n}",
"feedback_prompt": "Confirme que estava correto, corrija o programa ou ignore.",
"feedback_relabel_hint": "Rotular novamente este ciclo também o resolve.",
"filter_by_profile": "Filtrar por perfil…",
@@ -808,7 +843,6 @@
"pg_stress_synthetic": "a simulação de espera começa aqui",
"pg_sweep_intro": "E se {param} fosse diferente? Teste {steps} valores nos seus últimos {cycles} ciclos para encontrar a configuração em que o maior número de ciclos é correspondido corretamente.",
"pg_sweep_step": "Etapa {done} / {total}",
"pg_undetected": "{n} ciclo{s} sem detecção",
"pg_verdict_bad": "Requer atenção: muitos ciclos estão passando sem detecção.",
"pg_verdict_good": "Bem ajustado: a maioria dos ciclos é identificada e correspondida corretamente.",
"pg_verdict_ok": "Aceitável: alguns ciclos não foram detectados. Tente reduzir o limite de início.",
@@ -839,6 +873,7 @@
"review_recorded_tip": "Marque este ciclo como referência escolhida a dedo para seu programa o mesmo papel de um ciclo gravado manualmente. Os ciclos de referência são sempre mantidos, alimentam o modelo de correspondência e nunca são removidos pela limpeza. (Esta é a bandeira \"dourada\"/gravada; ambas são a mesma coisa.)",
"review_tags_tip": "Etiquetas opcionais que descrevem o que deu errado com este ciclo, para que o treinamento e a limpeza possam levar isso em conta.",
"review_to_cycles": "Abrir a fila de revisão de Ciclos",
"samples_decimated": "Mostrando {shown} de {total} amostras (reduzidas para exibição; picos mantidos). Um intervalo grande aqui se deve à redução, não a dados faltantes.",
"saving_triggers_reload": "Salvar aciona um recarregamento da integração. As entidades do HA podem ficar brevemente indisponíveis.",
"search_placeholder": "Pesquisar configurações…",
"see_recorder": "Veja o widget de gravação abaixo",
@@ -958,7 +993,29 @@
"sug_mute_failed": "Não foi possível silenciar a sugestão",
"sug_unmuted_all": "Sugestões silenciadas redefinidas",
"n_suggestions_muted": "{count} silenciadas; o ajuste automático não irá propô-las.",
"font_size_hint": "Amplie ou reduza o texto neste painel. Aplica-se à sua conta neste dispositivo."
"font_size_hint": "Amplie ou reduza o texto neste painel. Aplica-se à sua conta neste dispositivo.",
"import_history_description": "Você já tinha uma tomada inteligente antes do WashData? Carregue uma exportação do histórico do sensor de potência dela, ou leia direto do Home Assistant: a detecção normal é executada sobre esses dados, então os ciclos antigos aparecem na sua lista de Ciclos, prontos para nomear.",
"hist_input_hint": "Carregue um CSV baixado do painel Histórico (entidade, estado, última alteração), ou deixe o WashData ler o histórico do sensor diretamente. A detecção é executada em seguida exatamente como em tempo real, e você escolhe quais dos ciclos encontrados quer manter.",
"hist_recorder_hint": "Lê desde a data que você escolher até agora. O Home Assistant mantém o histórico detalhado por 10 dias por padrão e, depois disso, apenas médias por hora, grosseiras demais para detectar ciclos - escolha uma data mais antiga somente se o recorder do Home Assistant estiver configurado para guardar mais.",
"hist_scanning": "Seu histórico está sendo reproduzido no detector. Isso é executado em segundo plano: você pode fechar esta janela e voltar depois.",
"hist_imported_count": "{n} ciclos importados.",
"hist_duplicates": "{n} já tinham sido importados e foram ignorados.",
"hist_capped": "O limite de ciclos importados por dispositivo foi atingido; os restantes não foram salvos.",
"hist_next_step": "Eles estão na sua lista de Ciclos, marcados como histórico importado. Abra um e use Rotular para indicar o programa a que ele pertence.",
"hist_rows_read": "{n} leituras lidas",
"hist_breaks": "{n} intervalos em que o sensor estava indisponível",
"hist_other_entity": "{n} leituras de outras entidades ignoradas",
"hist_entity_substituted": "{used} lido (este dispositivo está configurado para {wanted})",
"hist_skipped_spans": "Trechos ignorados",
"hist_settings_used": "Detectado com as configurações atuais deste dispositivo (potência mínima {w} W, atraso de desligamento {s} s).",
"hist_none_found": "Não foi possível detectar nenhum ciclo nesse histórico.",
"hist_found": "Encontrados {n} ciclos. Desmarque tudo o que não pareça um ciclo real: nada é salvo até você importar.",
"hist_scan_capped": "Somente os primeiros candidatos são exibidos ({n} foram encontrados).",
"hist_recorder_empty": "O Home Assistant não tem histórico detalhado para este sensor nesse período.",
"hist_scan_failed": "A análise falhou.",
"hist_scan_expired": "Essa análise não está mais disponível. Analise novamente.",
"hist_import_failed": "A importação falhou.",
"imported_history_readonly": "Detectado em um histórico de potência importado. Influencia a correspondência de programas, mas não é contabilizado nas suas estatísticas e não pode ser recortado nem dividido. Rotule-o para indicar o programa."
},
"phase_desc": {
"anti_crease": "Giros curtos ocasionais após a conclusão para reduzir amassados.",
@@ -1169,7 +1226,7 @@
"label": "Potência Mínima"
},
"ml_training_enabled": {
"doc": "Estude periodicamente seus ciclos revisados durante a noite e ajuste os modelos para esta máquina específica. Uma mudança só é mantida quando realmente obtém resultados melhores em ciclos prolongados, portanto, isso só pode ajudar ou permanecer igual - nunca regredir.",
"doc": "Estude periodicamente seus ciclos revisados durante a noite e ajuste os modelos para esta máquina específica. Uma mudança só é mantida quando realmente obtém resultados melhores em ciclos prolongados, portanto, isso só pode ajudar ou permanecer igual - nunca regredir.",
"label": "Aprender com esta máquina"
},
"ml_training_hour": {
@@ -1269,7 +1326,7 @@
"label": "Dispensar Automaticamente Após"
},
"notify_title": {
"doc": "Título da notificação. Variáveis de modelo: {device}, {program}, {duration}, {energy}, {cost}, {date}, {time}, {minutes}.",
"doc": "Título da notificação. Variáveis de modelo: {device}, {program}, {duration}, {energy}, {cost}, {date}, {time}, {minutes}.",
"label": "Título da Notificação"
},
"notify_unload_delay_minutes": {
@@ -1344,6 +1401,10 @@
"doc": "Armazene o rastreamento de energia completo e os dados de depuração correspondentes para cada ciclo. Útil para solução de problemas, mas aumenta o tamanho do armazenamento.",
"label": "Salvar Rastros de Depuração"
},
"smart_termination_duration_ratio": {
"doc": "Até que ponto um ciclo deve ter avançado na duração esperada do programa correspondente antes de o Encerramento inteligente poder encerrá-lo mais cedo assim que a potência cai. A duração esperada é a média do programa, então em aparelhos cujo tempo de funcionamento varia muito - lavadoras conforme a água de entrada fria no inverno ou morna no verão, secadoras com sensor de umidade, programas que dependem da carga - cerca de metade das execuções termina mais cedo do que essa média e nunca recebe o fim rápido, terminando apenas pelo tempo limite de reserva com minutos de atraso. Reduza este valor (p. ex. 0,85) nessas máquinas para que o fim antecipado continue disparando; aumente-o para perto de 1,0 para ser mais conservador. Deixe vazio para o valor padrão (0,98, ou 0,99 para lava-louças). Ele só pode encerrar um ciclo mais cedo, nunca mais tarde, e nunca dispara em uma correspondência ambígua ou de baixa confiança.",
"label": "Proporção de encerramento inteligente"
},
"smoothing_window": {
"doc": "Quanto o sinal de potência bruta é suavizado. Baixo (2) é responsivo, mas barulhento; alto (5) suaviza os picos, mas adiciona atraso.",
"label": "Janela de Suavização"
@@ -1369,7 +1430,7 @@
"label": "Entidade do Switch"
},
"watchdog_interval": {
"doc": "Com que frequência o watchdog em segundo plano verifica sensores paralisados e tempos limite decorridos. Padrão 30 seg.",
"doc": "Com que frequência o watchdog em segundo plano verifica sensores paralisados e tempos limite decorridos. Padrão 30 seg.",
"label": "Intervalo do Watchdog"
},
"notify_milestone_message": {
@@ -1474,6 +1535,10 @@
"door_end_dwell_seconds": {
"label": "Tempo de Espera da Porta Aberta",
"doc": "Por quanto tempo a porta deve permanecer aberta antes de o WashData encerrar o ciclo, quando a opção \"Porta Abre Automaticamente ao Final\" está ativa. Longo o suficiente para ignorar a adição rápida de um prato (padrão 60 s), curto o suficiente para encerrar prontamente assim que a máquina abre a porta."
},
"profile_evidence_sources": {
"label": "Ciclos que moldam um programa",
"doc": "Quais ciclos são usados para construir a curva de potência de cada programa e para comparar um ciclo finalizado com ela. Ao desmarcar um tipo, ele para de moldar seus programas sem que nada seja excluído - os ciclos continuam na sua lista de Ciclos e ainda podem ser rotulados ou removidos. Útil se você não confia nos dados importados. As estatísticas não são afetadas: elas sempre contabilizam apenas os ciclos que esta máquina realmente executou. Desmarcar tudo é ignorado, pois um programa sem ciclos por trás nunca conseguiria corresponder."
}
},
"setting_group": {
@@ -1557,6 +1622,9 @@
},
"basic_configuration": {
"label": "Configuração básica"
},
"profile_evidence": {
"label": "Base dos Perfis"
}
},
"status": {
@@ -1581,7 +1649,8 @@
"trimming": "Recortando…",
"splitting": "Dividindo…",
"deleting": "Excluindo…",
"imported": "Importado"
"imported": "Importado",
"preparing": "Preparando…"
},
"tab": {
"advanced": "Avançado",
@@ -1611,6 +1680,7 @@
"wrong_profile": "Perfil errado"
},
"toast": {
"catalog_refreshed": "Catálogo da comunidade atualizado",
"access_saved": "Controle de acesso salvo",
"all_wiped": "Todos os dados apagados",
"analysis_complete_none": "Análise concluída: sem novas sugestões",
@@ -1716,7 +1786,9 @@
"store_download_failed": "Falha no download: {error}",
"store_download_nothing": "Nada novo para baixar - esta configuração já está neste dispositivo.",
"export_selective_done": "Exportação baixada",
"import_selective_done": "Importados {profiles} perfil(is) e {cycles} ciclo(s)"
"import_selective_done": "Importados {profiles} perfil(is) e {cycles} ciclo(s)",
"hist_csv_required": "Carregue primeiro um arquivo CSV ou cole o conteúdo dele",
"file_read_failed": "Não foi possível ler esse arquivo"
},
"suggestion": {
"both_agree": "WashData recomenda",
@@ -1812,7 +1884,7 @@
"thr_batch": "Mantido logo acima da menor potência ativa p05 em {cycles} ciclos ({p05}W) para que um início seja captado o mais cedo possível e o limiar de parada permaneça abaixo da menor potência de funcionamento da máquina.",
"tol_per_profile": "p75 da variância de duração por perfil em {profiles} perfis ({cycles} ciclos); perfis consistentes não são penalizados.",
"tol_pooled": "Com base na variância de duração agregada de {cycles} ciclos rotulados recentes (desvio p95={dev}).",
"watchdog": "Mantido tão baixo quanto é seguro (logo acima do intervalo de atualização p95 de {p95}s, mín. 30s) para que travamentos sejam detectados rapidamente sem paradas falsas."
"watchdog": "Mantido tão baixo quanto é seguro (logo acima do intervalo de atualização p95 de {p95}s e pelo menos 2x o intervalo de amostragem de {median}s, mín. 30s) para que travamentos sejam detectados rapidamente sem paradas falsas."
},
"exclusions": {
"summary": "Excluído(s) {total} ciclo(s) mal detectado(s): {parts}.",
@@ -1844,6 +1916,7 @@
},
"pg_desc": {
"dishwasher_end_spike_quiet_release": "Lava-louças: segundos de silêncio após a duração esperada antes de liberar a espera da descarga de fim de ciclo",
"smart_termination_duration_ratio": "Fração da duração esperada do programa correspondente que um ciclo deve atingir antes de o Encerramento inteligente poder encerrá-lo mais cedo; reduza-a para máquinas que dependem da carga ou da temperatura",
"anti_wrinkle_enabled": "Absorver os pulsos de giro após a fase principal em vez de lê-los como novos ciclos",
"anti_wrinkle_exit_power": "A potência deve cair abaixo deste valor entre os pulsos para que o modo antiamasso permaneça ativo",
"anti_wrinkle_idle_timeout": "Tempo de silêncio permitido entre dois pulsos de giro antes de o modo antiamasso terminar",
@@ -1907,6 +1980,10 @@
"finished": "O ciclo atingiu um estado final e foi encerrado."
},
"store": {
"your_model_tip": "Este é o eletrodoméstico que você declarou em Configurações",
"your_model": "Seu",
"search_brand_ph": "Pesquisar por marca…",
"programs_count": "Programas: {n}",
"browse": "Navegar",
"device": "Dispositivo",
"favorites": "Favoritos",
@@ -30,9 +30,12 @@
"awaiting": "A aguardar aprovação",
"imported_tip": "Importado da loja da comunidade. Usado apenas para correspondência, não contabilizado nas estatísticas.",
"not_importable": "n/d aqui",
"exists": "já existe"
"exists": "já existe",
"backfilled_tip": "Detetado num histórico de potência importado. Influencia apenas a correspondência de programas, não é contabilizado nas estatísticas."
},
"btn": {
"set_brand_model": "Definir marca e modelo",
"refresh_catalog": "Actualizar catálogo",
"add_device": "+ Adicionar dispositivo",
"add_device_tip": "Adicionar outro dispositivo WashData",
"add_maintenance": "Adicionar evento de manutenção",
@@ -193,7 +196,12 @@
"import_selected": "Importar seleção",
"back": "Voltar",
"mute_suggestion": "Não sugerir mais esta definição",
"reset_muted": "Repor silenciados"
"reset_muted": "Repor silenciados",
"import_power_history": "Importar histórico de potência",
"hist_read_recorder": "Ler do Home Assistant",
"hist_scan": "Procurar ciclos",
"hist_import_n": "Importar {n} ciclos",
"hist_goto_cycles": "Ver os ciclos"
},
"conflict": {
"anti_wrinkle_exit": {
@@ -205,14 +213,14 @@
"start": "Deve ser inferior à Potência máxima anti-vincos ({max} W)"
},
"attn_sub": "Corrija os conflitos antes de guardar",
"attn_title": "{n} conflito{s} de definições",
"settings_banner": "{n} conflito{s} de definições verifique as secções realçadas e corrija antes de guardar.",
"attn_title": "Conflitos de definições: {n}",
"settings_banner": "Conflitos de definições: {n}. Verifique as secções realçadas e corrija-os antes de guardar.",
"settings_banner_btn": "Ir para o primeiro",
"confidence": {
"auto": "Deve ser superior ou igual ao Limiar de correspondência ({match})",
"learning": "Deve ser inferior ou igual ao Limiar de correspondência ({match})",
"learning": "Deve ser superior ou igual ao Limiar de correspondência ({match})",
"match_for_auto": "Deve ser inferior ou igual à Confiança de etiquetagem automática ({alc})",
"match_for_learning": "Deve ser superior ou igual à Confiança de aprendizagem ({lc})"
"match_for_learning": "Deve ser inferior ou igual à Confiança de aprendizagem ({lc})"
},
"duration_ratio": {
"max": "Deve ser superior ao Rácio de duração mínimo ({min})",
@@ -250,7 +258,7 @@
"match": "Deve ser superior ao Limiar de não correspondência ({un})",
"unmatch": "Deve ser inferior ao Limiar de correspondência ({match}); caso contrário, uma correspondência confirmada é imediatamente anulada"
},
"cascade_toast": "Também foram aplicados {n} ajuste{s} por consistência.",
"cascade_toast": "Outras definições ajustadas por consistência: {n}",
"suggestion_resolves": "Aplique a sugestão pendente ({val}) abaixo para corrigir este conflito",
"use_fix": "Usar {val}",
"watchdog": {
@@ -308,7 +316,8 @@
"pg_outcome": "Resultado da simulação",
"pg_across_cycles": "Em todos os seus ciclos",
"community_store": "Loja da comunidade",
"online_account": "Loja da comunidade e funcionalidades online"
"online_account": "Loja da comunidade e funcionalidades online",
"import_power_history": "Importar histórico de potência"
},
"health": {
"fair": "Qualidade de perfil aceitável",
@@ -316,6 +325,7 @@
"poor": "⚠ Qualidade de perfil fraca"
},
"lbl": {
"drag_to_resize": "Arraste para redimensionar",
"actions": "Acções",
"activity": "Actividade",
"administrators": "Administradores",
@@ -402,7 +412,7 @@
"metric": "Métrica",
"mode_existing_profile": "Adicionar a perfil existente",
"mode_new_profile": "Criar novo perfil",
"models_fine_tuned": "({count} modelo{plural} ajustado{plural})",
"models_fine_tuned": "(modelos ajustados: {count})",
"n_classic_suggestions": "{n} clássico",
"n_ml_suggestions": "{n} ML",
"n_selected": "{n} selecionados",
@@ -602,7 +612,7 @@
"show_contributor": "Mostrar nomes dos colaboradores",
"task_pg_detail": "Simular ciclo",
"task_split": "A dividir o ciclo",
"task_trim": "A recortar o ciclo",
"task_trim": "A cortar o ciclo",
"task_merge": "A combinar ciclos",
"task_rebuild": "A reconstruir envelopes",
"cat_profiles": "Perfis (programas)",
@@ -629,7 +639,26 @@
"conflict_import_copy": "Importar como cópia",
"conflict_keep_mine": "Manter o meu",
"conflict_overwrite": "Substituir",
"font_size": "Tamanho da letra do painel"
"font_size": "Tamanho da letra do painel",
"hist_csv_data": "Dados CSV",
"hist_from_recorder": "Ou ler diretamente do Home Assistant",
"hist_since": "Desde",
"days": "dias",
"hist_keep": "Manter este ciclo",
"hist_looks_complete": "completo",
"peak_power_short": "Pico",
"shape": "Forma",
"hist_skip_idle": "nada em funcionamento",
"hist_skip_sparse": "leituras demasiado espaçadas",
"hist_skip_short": "muito poucas leituras",
"hist_skip_long": "nenhuma pausa suficientemente longa para dividir",
"hist_reason_short": "mais curto do que o ciclo real mais curto deste aparelho",
"hist_reason_no_end": "nunca terminou de forma limpa",
"task_history_import": "A analisar o histórico de potência",
"task_history_import_apply": "A importar ciclos",
"evidence_real_cycles": "Ciclos que esta máquina executou",
"evidence_reference_cycles": "Transferidos da loja da comunidade",
"evidence_backfill_cycles": "Encontrados num histórico de potência importado"
},
"log": {
"all_levels": "Todos os níveis",
@@ -708,9 +737,15 @@
"store_share": "Partilhar na loja da comunidade",
"store_share_device": "Partilhar este dispositivo",
"export_select": "Exportar - escolher dados",
"import_wizard": "Importar - escolher dados"
"import_wizard": "Importar - escolher dados",
"history_import": "Importar histórico de potência"
},
"msg": {
"tail_trim_hint": "Número de segundos a remover do fim",
"store_sibling_hint": "Não há nada partilhado para o seu modelo exato? Um modelo muito semelhante da mesma marca é normalmente um bom ponto de partida.",
"store_declare_appliance": "Indique ao WashData qual o electrodoméstico que possui e este separador mostrará as configurações que outras pessoas partilharam para ele. Também pode escrever uma marca acima para explorar.",
"refresh_catalog_hint": "As listas de marcas e electrodomésticos da comunidade são guardadas em cache para manter a loja partilhada dentro do seu limite diário. Actualize para obter as entradas adicionadas ou aprovadas por outros utilizadores.",
"head_trim_hint": "Número de segundos a remover do início",
"appliance_monitor": "Monitor de electrodoméstico",
"artifact_dip_detail": "Caiu abaixo da banda de potência habitual durante ~{n}s.",
"artifact_footer": "Realçadas no gráfico acima. São artefactos transitórios (por exemplo, a porta foi aberta a meio do ciclo), não necessariamente problemas.",
@@ -721,7 +756,7 @@
"automations_intro": "O WashData dispara os eventos {start} / {end} e expõe entidades, por isso as notificações e ações são melhor criadas como automatizações normais do Home Assistant. As automatizações que utilizam este dispositivo aparecem abaixo.",
"cleanup_intro": "Todos os ciclos rotulados sobrepostos. Assinale os valores aberrantes e elimine para limpar o perfil.",
"clear_debug_hint": "Remova os dados de depuração armazenados para libertar espaço.",
"collecting_data": "A recolher dados - mais {need} ciclo{plural} antes de o ajuste fino poder começar ({current}/{min}).",
"collecting_data": "A recolher dados. Ciclos ainda necessários para o ajuste fino poder começar: {need} ({current}/{min}).",
"compare_overlay_profiles": "Sobrepor perfis (ténue)",
"compare_profiles_tip": "Sobreponha outros envelopes de perfil no gráfico acima para ver qual deles melhor se adequa a este ciclo.",
"compare_selected_cycles": "Ciclos seleccionados (sólido) mostrar / ocultar",
@@ -731,7 +766,7 @@
"cycles_deleted": "{count} ciclo(s) eliminado(s)",
"enough_data": "Dados suficientes para aprender ({current}/{min} ciclos).",
"export_description": "Escolha exatamente que perfis, ciclos, definições e mais exportar para JSON, ou analise um ficheiro e importe apenas as partes que quiser.",
"feedback_cycles_pending": "{n} ciclo{s} para rever",
"feedback_cycles_pending": "Para rever: {n}",
"feedback_prompt": "Confirme que estava correcto, corrija o programa ou ignore.",
"feedback_relabel_hint": "Voltar a rotular este ciclo também o resolve.",
"filter_by_profile": "Filtrar por perfil…",
@@ -808,7 +843,6 @@
"pg_stress_synthetic": "a simulação de repouso começa aqui",
"pg_sweep_intro": "E se {param} fosse diferente? Teste {steps} valores nos seus últimos {cycles} ciclos para encontrar a definição em que mais ciclos são reconhecidos corretamente.",
"pg_sweep_step": "Passo {done} / {total}",
"pg_undetected": "{n} ciclo{s} não detetado{s}",
"pg_verdict_bad": "Requer atenção: muitos ciclos não são detetados.",
"pg_verdict_good": "Bem afinado: a maioria dos ciclos é identificada e reconhecida corretamente.",
"pg_verdict_ok": "Aceitável: alguns ciclos não foram detetados. Tente baixar o limiar de início.",
@@ -839,6 +873,7 @@
"review_recorded_tip": "Marque este ciclo como referência escolhida a dedo para o seu programa o mesmo papel de um ciclo gravado manualmente. Os ciclos de referência são sempre mantidos, semeiam o modelo de correspondência e nunca são removidos pela limpeza. (Esta é a bandeira \"dourada\"/gravada; ambas são a mesma coisa.)",
"review_tags_tip": "Etiquetas opcionais que descrevem o que correu mal com este ciclo, para que o treino e a limpeza possam ter isso em conta.",
"review_to_cycles": "Abrir a fila de revisão de Ciclos",
"samples_decimated": "A mostrar {shown} de {total} amostras (reduzidas para exibição; picos mantidos). Um intervalo grande aqui deve-se à redução, não a dados em falta.",
"saving_triggers_reload": "Guardar desencadeia um recarregamento da integração. As entidades HA podem ficar brevemente indisponíveis.",
"search_placeholder": "Pesquisar definições…",
"see_recorder": "Veja o widget de gravação abaixo",
@@ -958,10 +993,33 @@
"sug_mute_failed": "Não foi possível silenciar a sugestão",
"sug_unmuted_all": "Sugestões silenciadas repostas",
"n_suggestions_muted": "{count} silenciadas; o ajustador automático não proporá estas definições.",
"font_size_hint": "Torna tudo neste painel maior ou menor. Aplica-se à sua conta neste dispositivo."
"font_size_hint": "Torna tudo neste painel maior ou menor. Aplica-se à sua conta neste dispositivo.",
"import_history_description": "Já tinha uma tomada inteligente antes do WashData? Carregue uma exportação do histórico do respetivo sensor de potência, ou leia-o diretamente do Home Assistant: a deteção normal é executada sobre esses dados, pelo que os ciclos passados aparecem na sua lista de Ciclos, prontos a nomear.",
"hist_input_hint": "Carregue um CSV descarregado do painel Histórico (entidade, estado, última alteração), ou deixe o WashData ler diretamente o histórico do sensor. A deteção é depois executada exatamente como em tempo real e escolhe quais dos ciclos encontrados quer manter.",
"hist_recorder_hint": "Lê desde a data que escolher até agora. O Home Assistant guarda o histórico detalhado durante 10 dias por predefinição e, depois disso, apenas médias horárias, demasiado grosseiras para detetar ciclos - escolha uma data mais antiga apenas se o recorder do Home Assistant estiver configurado para guardar mais.",
"hist_scanning": "O seu histórico está a ser reproduzido através do detetor. Isto é executado em segundo plano: pode fechar esta janela e voltar mais tarde.",
"hist_imported_count": "{n} ciclos importados.",
"hist_duplicates": "{n} já tinham sido importados e foram ignorados.",
"hist_capped": "Foi atingido o limite de ciclos importados por dispositivo; os restantes não foram guardados.",
"hist_next_step": "Estão na sua lista de Ciclos, marcados como histórico importado. Abra um e use Rotular para indicar o programa a que pertence.",
"hist_rows_read": "{n} leituras lidas",
"hist_breaks": "{n} intervalos em que o sensor estava indisponível",
"hist_other_entity": "{n} leituras de outras entidades ignoradas",
"hist_entity_substituted": "{used} lido (este dispositivo está configurado para {wanted})",
"hist_skipped_spans": "Trechos ignorados",
"hist_settings_used": "Detetado com as definições atuais deste dispositivo (potência mínima {w} W, atraso de desligamento {s} s).",
"hist_none_found": "Não foi possível detetar nenhum ciclo nesse histórico.",
"hist_found": "Encontrados {n} ciclos. Desmarque tudo o que não pareça um ciclo real: nada é guardado até importar.",
"hist_scan_capped": "São mostrados apenas os primeiros candidatos (foram encontrados {n}).",
"hist_recorder_empty": "O Home Assistant não tem histórico detalhado para este sensor nesse período.",
"hist_scan_failed": "A análise falhou.",
"hist_scan_expired": "Essa análise já não está disponível. Analise novamente.",
"hist_import_failed": "A importação falhou.",
"imported_history_readonly": "Detetado num histórico de potência importado. Influencia a correspondência de programas, mas não é contabilizado nas suas estatísticas e não pode ser cortado nem dividido. Rotule-o para indicar o programa."
},
"pg_desc": {
"dishwasher_end_spike_quiet_release": "Máquina de lavar louça: segundos de silêncio após a duração esperada antes de libertar a espera da descarga de fim de ciclo",
"smart_termination_duration_ratio": "Fração da duração esperada do programa correspondente que um ciclo deve atingir antes de a Terminação inteligente o poder terminar mais cedo; reduza-a para máquinas que dependem da carga ou da temperatura",
"anti_wrinkle_enabled": "Absorver os pulsos de rotação após a fase principal em vez de os ler como novos ciclos",
"anti_wrinkle_exit_power": "A potência deve descer abaixo deste valor entre pulsos para que o modo anti-vincos permaneça ativo",
"anti_wrinkle_idle_timeout": "Tempo de silêncio permitido entre dois pulsos de rotação antes de o modo anti-vincos terminar",
@@ -1198,7 +1256,7 @@
"label": "Potência Mínima"
},
"ml_training_enabled": {
"doc": "Estude periodicamente seus ciclos revisados durante a noite e ajuste os modelos para esta máquina específica. Uma mudança só é mantida quando realmente obtém resultados melhores em ciclos prolongados, portanto, isso só pode ajudar ou permanecer igual - nunca regredir.",
"doc": "Estude periodicamente seus ciclos revisados durante a noite e ajuste os modelos para esta máquina específica. Uma mudança só é mantida quando realmente obtém resultados melhores em ciclos prolongados, portanto, isso só pode ajudar ou permanecer igual - nunca regredir.",
"label": "Aprender com esta máquina"
},
"ml_training_hour": {
@@ -1298,7 +1356,7 @@
"label": "Dispensar Automaticamente Após"
},
"notify_title": {
"doc": "Título da notificação. Variáveis de modelo: {device}, {program}, {duration}, {energy}, {cost}, {date}, {time}, {minutes}.",
"doc": "Título da notificação. Variáveis de modelo: {device}, {program}, {duration}, {energy}, {cost}, {date}, {time}, {minutes}.",
"label": "Título da Notificação"
},
"notify_unload_delay_minutes": {
@@ -1373,6 +1431,10 @@
"doc": "Armazene o rastreamento de energia completo e os dados de depuração correspondentes para cada ciclo. Útil para solução de problemas, mas aumenta o tamanho do armazenamento.",
"label": "Guardar Traços de Depuração"
},
"smart_termination_duration_ratio": {
"doc": "Até que ponto um ciclo deve ter avançado na duração esperada do programa correspondente antes de a Terminação inteligente o poder terminar mais cedo assim que a potência cai. A duração esperada é a média do programa, por isso em aparelhos cujo tempo de funcionamento varia muito - máquinas de lavar consoante a água de entrada fria no inverno ou morna no verão, secadores com sensor de humidade, programas que dependem da carga - cerca de metade das execuções termina mais cedo do que essa média e nunca beneficia do fim rápido, terminando apenas através do tempo limite de reserva com minutos de atraso. Reduza este valor (p. ex. 0,85) nessas máquinas para que o fim antecipado continue a disparar; aumente-o para perto de 1,0 para ser mais conservador. Deixe vazio para o valor predefinido (0,98, ou 0,99 para máquinas de lavar louça). Só pode terminar um ciclo mais cedo, nunca mais tarde, e nunca dispara numa correspondência ambígua ou de baixa confiança.",
"label": "Rácio de terminação inteligente"
},
"smoothing_window": {
"doc": "Quanto o sinal de potência bruta é suavizado. Baixo (2) é responsivo, mas barulhento; alto (5) suaviza os picos, mas adiciona atraso.",
"label": "Janela de Suavização"
@@ -1398,7 +1460,7 @@
"label": "Entidade do Switch"
},
"watchdog_interval": {
"doc": "Com que frequência o watchdog em segundo plano verifica sensores paralisados e tempos limite decorridos. Padrão 30 seg.",
"doc": "Com que frequência o watchdog em segundo plano verifica sensores paralisados e tempos limite decorridos. Padrão 30 seg.",
"label": "Intervalo do Watchdog"
},
"notify_milestone_message": {
@@ -1503,6 +1565,10 @@
"door_end_dwell_seconds": {
"label": "Tempo de Espera com Porta Aberta para Fim",
"doc": "Quanto tempo a porta tem de permanecer aberta antes de o WashData terminar o ciclo, quando a opção \"Porta Abre Automaticamente no Fim\" está ativa. Suficientemente longo para ignorar a adição rápida de um prato (predefinição: 60 s), suficientemente curto para terminar prontamente quando a máquina abre a porta."
},
"profile_evidence_sources": {
"label": "Ciclos que moldam um programa",
"doc": "Que ciclos são usados para construir a curva de potência de cada programa e para comparar um ciclo terminado com ela. Ao desmarcar um tipo, este deixa de moldar os seus programas sem que nada seja apagado - os ciclos permanecem na sua lista de Ciclos e podem continuar a ser rotulados ou removidos. Útil se não confiar nos dados importados. As estatísticas não são afetadas: contabilizam sempre apenas os ciclos que esta máquina realmente executou. Desmarcar tudo é ignorado, pois um programa sem ciclos por trás nunca poderia corresponder."
}
},
"setting_group": {
@@ -1586,6 +1652,9 @@
},
"basic_configuration": {
"label": "Configuração básica"
},
"profile_evidence": {
"label": "Base dos Perfis"
}
},
"status": {
@@ -1610,7 +1679,8 @@
"trimming": "A cortar…",
"splitting": "A dividir…",
"deleting": "A eliminar…",
"imported": "Importado"
"imported": "Importado",
"preparing": "A preparar…"
},
"tab": {
"advanced": "Avançado",
@@ -1640,6 +1710,7 @@
"wrong_profile": "Perfil errado"
},
"toast": {
"catalog_refreshed": "Catálogo da comunidade actualizado",
"access_saved": "Controlo de acesso guardado",
"all_wiped": "Todos os dados apagados",
"analysis_complete_none": "Análise concluída: sem novas sugestões",
@@ -1745,7 +1816,9 @@
"store_download_failed": "Falha na transferência: {error}",
"store_download_nothing": "Nada de novo para transferir -- esta configuração já está no seu dispositivo.",
"export_selective_done": "Exportação transferida",
"import_selective_done": "Importados {profiles} perfil(is) e {cycles} ciclo(s)"
"import_selective_done": "Importados {profiles} perfil(is) e {cycles} ciclo(s)",
"hist_csv_required": "Carregue primeiro um ficheiro CSV ou cole o respetivo conteúdo",
"file_read_failed": "Não foi possível ler esse ficheiro"
},
"suggestion": {
"both_agree": "WashData recomenda",
@@ -1841,7 +1914,7 @@
"thr_batch": "Mantido logo acima da potência ativa mais baixa no p05 ao longo de {cycles} ciclos ({p05}W) para que um arranque seja captado o mais cedo possível e o limiar de paragem se mantenha abaixo da potência de funcionamento mais baixa da máquina.",
"tol_per_profile": "p75 da variância de duração por perfil em {profiles} perfis ({cycles} ciclos); os perfis restritos não são penalizados.",
"tol_pooled": "Com base na variância de duração agrupada de {cycles} ciclos rotulados recentes (desvio p95={dev}).",
"watchdog": "Mantido o mais baixo que é seguro (ligeiramente acima do intervalo de atualização p95 de {p95}s, mín. 30s) para detetar rapidamente os bloqueios sem paragens falsas."
"watchdog": "Mantido o mais baixo que é seguro (ligeiramente acima do intervalo de atualização p95 de {p95}s e pelo menos 2x o intervalo de amostragem de {median}s, mín. 30s) para detetar rapidamente os bloqueios sem paragens falsas."
},
"exclusions": {
"summary": "Excluído(s) {total} ciclo(s) mal detetado(s): {parts}.",
@@ -1907,6 +1980,10 @@
"finished": "O ciclo atingiu um estado final e terminou."
},
"store": {
"your_model_tip": "Este é o electrodoméstico que declarou nas Definições",
"your_model": "O seu",
"search_brand_ph": "Pesquisar por marca…",
"programs_count": "Programas: {n}",
"browse": "Explorar",
"device": "Dispositivo",
"favorites": "Favoritos",
@@ -1962,7 +2039,7 @@
"apply": "A dividir o ciclo"
},
"trim": {
"apply": "A recortar o ciclo"
"apply": "A cortar o ciclo"
},
"merge": {
"apply": "A combinar ciclos"
@@ -30,9 +30,12 @@
"awaiting": "În așteptarea aprobării",
"imported_tip": "Importat din magazinul comunității. Folosit doar pentru potrivire, necontabilizat în statistici.",
"not_importable": "n/a aici",
"exists": "există deja"
"exists": "există deja",
"backfilled_tip": "Detectat într-un istoric de putere importat. Influențează doar potrivirea programelor, nu este contabilizat în statistici."
},
"btn": {
"set_brand_model": "Stabiliți marca și modelul",
"refresh_catalog": "Actualizați catalogul",
"add_device": "+ Adăugați dispozitiv",
"add_device_tip": "Adăugați un alt dispozitiv WashData",
"add_maintenance": "Adăugați eveniment de întreținere",
@@ -193,7 +196,12 @@
"import_selected": "Importă selecția",
"back": "Înapoi",
"mute_suggestion": "Nu mai sugerați această setare",
"reset_muted": "Resetați cele ignorate"
"reset_muted": "Resetați cele ignorate",
"import_power_history": "Importați istoricul de putere",
"hist_read_recorder": "Citiți din Home Assistant",
"hist_scan": "Căutați cicluri",
"hist_import_n": "Importați {n} cicluri",
"hist_goto_cycles": "Vedeți ciclurile"
},
"conflict": {
"anti_wrinkle_exit": {
@@ -205,14 +213,14 @@
"start": "Trebuie să fie sub Puterea maximă anti-șifonare ({max} W)"
},
"attn_sub": "Rezolvați conflictele înainte de salvare",
"attn_title": "{n} conflict{s} de setări",
"settings_banner": "{n} conflict{s} de setări verificați secțiunile evidențiate și remediați înainte de salvare.",
"attn_title": "Conflicte de setări: {n}",
"settings_banner": "Conflicte de setări: {n}. Verificați secțiunile evidențiate și remediați-le înainte de salvare.",
"settings_banner_btn": "Salt la primul",
"confidence": {
"auto": "Trebuie să fie cel puțin egal cu Pragul de potrivire ({match})",
"learning": "Trebuie să fie cel mult egal cu Pragul de potrivire ({match})",
"learning": "Trebuie să fie cel puțin egal cu Pragul de potrivire ({match})",
"match_for_auto": "Trebuie să fie cel mult egal cu Încrederea de etichetare automată ({alc})",
"match_for_learning": "Trebuie să fie cel puțin egal cu Încrederea de învățare ({lc})"
"match_for_learning": "Trebuie să fie cel mult egal cu Încrederea de învățare ({lc})"
},
"duration_ratio": {
"max": "Trebuie să fie mai mare decât Raportul de durată minim ({min})",
@@ -250,7 +258,7 @@
"match": "Trebuie să fie peste Pragul de non-potrivire ({un})",
"unmatch": "Trebuie să fie sub Pragul de potrivire ({match}); altfel o potrivire confirmată este anulată instantaneu"
},
"cascade_toast": "De asemenea, s-au ajustat {n} setare{s} pentru consecvență.",
"cascade_toast": "Alte setări ajustate pentru consecvență: {n}",
"suggestion_resolves": "Aplicați sugestia în așteptare ({val}) de mai jos pentru a remedia aceasta",
"use_fix": "Folosiți {val}",
"watchdog": {
@@ -308,7 +316,8 @@
"pg_outcome": "Rezultatul simulării",
"pg_across_cycles": "În toate ciclurile tale",
"community_store": "Magazinul comunității",
"online_account": "Magazinul comunității și funcții online"
"online_account": "Magazinul comunității și funcții online",
"import_power_history": "Importați istoricul de putere"
},
"health": {
"fair": "Calitate acceptabilă a profilului",
@@ -316,6 +325,7 @@
"poor": "⚠ Calitate slabă a profilului"
},
"lbl": {
"drag_to_resize": "Trageți pentru redimensionare",
"actions": "Acțiuni",
"activity": "Activitate",
"administrators": "Administratori",
@@ -402,7 +412,7 @@
"metric": "Metrică",
"mode_existing_profile": "Adăugați la profilul existent",
"mode_new_profile": "Creați un profil nou",
"models_fine_tuned": "({count} model{plural} reglat fin)",
"models_fine_tuned": "(modele ajustate: {count})",
"n_classic_suggestions": "{n} clasice",
"n_ml_suggestions": "{n} ML",
"n_selected": "{n} selectate",
@@ -602,7 +612,7 @@
"show_contributor": "Afișați numele contribuitorilor",
"task_pg_detail": "Simulare ciclu",
"task_split": "Se divide ciclul",
"task_trim": "Se decupează ciclul",
"task_trim": "Se taie ciclul",
"task_merge": "Se îmbină ciclurile",
"task_rebuild": "Se reconstruiesc anvelopele",
"cat_profiles": "Profiluri (programe)",
@@ -629,7 +639,26 @@
"conflict_import_copy": "Importă drept copie",
"conflict_keep_mine": "Păstrează-l pe al meu",
"conflict_overwrite": "Suprascrie",
"font_size": "Dimensiunea fontului panoului"
"font_size": "Dimensiunea fontului panoului",
"hist_csv_data": "Date CSV",
"hist_from_recorder": "Sau citiți-l din Home Assistant",
"hist_since": "De la data",
"days": "zile",
"hist_keep": "Păstrați acest ciclu",
"hist_looks_complete": "complet",
"peak_power_short": "Vârf",
"shape": "Formă",
"hist_skip_idle": "nimic în funcțiune",
"hist_skip_sparse": "citiri prea îndepărtate între ele",
"hist_skip_short": "prea puține citiri",
"hist_skip_long": "nicio pauză suficient de lungă pentru divizare",
"hist_reason_short": "mai scurt decât cel mai scurt ciclu real al acestui aparat",
"hist_reason_no_end": "nu s-a încheiat niciodată curat",
"task_history_import": "Se analizează istoricul de putere",
"task_history_import_apply": "Se importă ciclurile",
"evidence_real_cycles": "Cicluri rulate de această mașină",
"evidence_reference_cycles": "Descărcate din magazinul comunității",
"evidence_backfill_cycles": "Găsite într-un istoric de putere importat"
},
"log": {
"all_levels": "Toate nivelurile",
@@ -708,9 +737,15 @@
"store_share": "Partajați în magazinul comunității",
"store_share_device": "Partajați acest dispozitiv",
"export_select": "Exportă - alege datele",
"import_wizard": "Importă - alege datele"
"import_wizard": "Importă - alege datele",
"history_import": "Importați istoricul de putere"
},
"msg": {
"tail_trim_hint": "Numărul de secunde de eliminat de la sfârșit",
"store_sibling_hint": "Nu există nimic partajat pentru modelul dvs. exact? Un model foarte apropiat de la aceeași marcă este de obicei un bun punct de plecare.",
"store_declare_appliance": "Indicați în WashData ce aparat dețineți, iar această filă va afișa configurațiile pe care alte persoane le-au partajat pentru el. Puteți și să scrieți o marcă mai sus pentru a explora.",
"refresh_catalog_hint": "Listele de mărci și aparate ale comunității sunt păstrate în cache pentru a menține magazinul partajat în limita zilnică. Actualizați pentru a prelua intrările adăugate sau aprobate de alții.",
"head_trim_hint": "Numărul de secunde de eliminat de la început",
"appliance_monitor": "Monitor de aparate",
"artifact_dip_detail": "A scăzut sub banda de putere obișnuită timp de ~{n}s.",
"artifact_footer": "Evidențiate în graficul de mai sus. Acestea sunt artefacte tranzitorii (de exemplu, ușa deschisă la jumătatea ciclului), nu neapărat probleme.",
@@ -721,7 +756,7 @@
"automations_intro": "WashData declanșează evenimente {start} / {end} și expune entități, astfel că notificările și acțiunile sunt cel mai bine construite ca automatizări normale Home Assistant. Automatizările care utilizează acest dispozitiv apar mai jos.",
"cleanup_intro": "Toate ciclurile etichetate suprapuse. Bifați valorile aberante și ștergeți pentru a curăța profilul.",
"clear_debug_hint": "Eliminați datele de depanare stocate pentru a elibera spațiu.",
"collecting_data": "Se colectează date - mai sunt necesare {need} ciclu{plural} înainte ca reglajul fin să poată începe ({current}/{min}).",
"collecting_data": "Se colectează date. Cicluri încă necesare înainte ca reglajul fin să poată începe: {need} ({current}/{min}).",
"compare_overlay_profiles": "Suprapuneți profiluri (estompat)",
"compare_profiles_tip": "Suprapuneți alte plicuri de profil pe graficul de mai sus pentru a vedea care dintre ele se potrivește cel mai bine acestui ciclu.",
"compare_selected_cycles": "Cicluri selectate (solid) afișați / ascundeți",
@@ -731,7 +766,7 @@
"cycles_deleted": "{count} ciclu(ri) șterse",
"enough_data": "Date suficiente pentru a învăța ({current}/{min} cicluri).",
"export_description": "Alege exact ce profiluri, cicluri, setări și altele să exporți în JSON, sau analizează un fișier și importă doar părțile dorite.",
"feedback_cycles_pending": "{n} ciclu{s} de revizuit",
"feedback_cycles_pending": "De revizuit: {n}",
"feedback_prompt": "Confirmați că a fost corect, corectați programul sau ignorați.",
"feedback_relabel_hint": "Și reetichetarea acestui ciclu îl rezolvă.",
"filter_by_profile": "Filtrează după profil…",
@@ -808,7 +843,6 @@
"pg_stress_synthetic": "simularea în repaus începe aici",
"pg_sweep_intro": "Ce-ar fi dacă {param} ar fi diferit? Testați {steps} valori pe ultimele {cycles} cicluri pentru a găsi setarea la care se potrivesc corect cele mai multe cicluri.",
"pg_sweep_step": "Pasul {done} / {total}",
"pg_undetected": "{n} ciclu{s} nedetectat",
"pg_verdict_bad": "Necesită atenție: multe cicluri rămân nedetectate.",
"pg_verdict_good": "Bine reglat: majoritatea ciclurilor sunt identificate și potrivite corect.",
"pg_verdict_ok": "Acceptabil: unele cicluri au fost ratate. Încercați să reduceți pragul de pornire.",
@@ -839,6 +873,7 @@
"review_recorded_tip": "Marcați acest lucru ca un ciclu de referință ales manual pentru programul său același rol ca un ciclu înregistrat manual. Ciclurile de referință sunt întotdeauna păstrate, generează șablonul de potrivire și nu sunt niciodată eliminate de curățare. (Acesta este steagul \"de aur\"/înregistrat; ambele sunt același lucru.)",
"review_tags_tip": "Semnale opționale care descriu ce a mers prost cu acest ciclu, astfel încât antrenamentul și curățarea pot ține cont de acest lucru.",
"review_to_cycles": "Deschideți coada de revizuire a Ciclurilor",
"samples_decimated": "Se afișează {shown} din {total} eșantioane (reduse pentru afișare; vârfurile păstrate). Un spațiu mare aici se datorează reducerii, nu unor date lipsă.",
"saving_triggers_reload": "Salvarea declanșează o reîncărcare a integrării. Entitățile HA pot apărea pe scurt ca indisponibile.",
"search_placeholder": "Căutați setări…",
"see_recorder": "Consultați widgetul de înregistrare de mai jos",
@@ -958,7 +993,29 @@
"sug_mute_failed": "Nu s-a putut dezactiva sugestia",
"sug_unmuted_all": "Sugestiile dezactivate au fost resetate",
"n_suggestions_muted": "{count} dezactivate; reglajul automat nu le va propune.",
"font_size_hint": "Faceți tot din acest panou mai mare sau mai mic. Se aplică contului dvs. pe acest dispozitiv."
"font_size_hint": "Faceți tot din acest panou mai mare sau mai mic. Se aplică contului dvs. pe acest dispozitiv.",
"import_history_description": "Aveați deja o priză inteligentă înainte de WashData? Încărcați un export al istoricului senzorului său de putere sau citiți-l direct din Home Assistant: detectarea obișnuită rulează pe aceste date, astfel încât ciclurile anterioare apar în lista dvs. Cicluri, pregătite pentru a fi denumite.",
"hist_input_hint": "Încărcați un CSV descărcat din panoul Istoric (entitate, stare, ultima modificare) sau lăsați WashData să citească direct istoricul senzorului. Detectarea rulează apoi exact ca în timp real, iar dvs. alegeți care dintre ciclurile găsite să fie păstrate.",
"hist_recorder_hint": "Citește de la data pe care o alegeți până în prezent. Home Assistant păstrează implicit istoricul detaliat timp de 10 zile, iar după aceea doar medii orare, prea grosiere pentru a detecta cicluri - alegeți o dată mai veche doar dacă recorder-ul din Home Assistant este configurat să păstreze mai mult.",
"hist_scanning": "Istoricul dvs. este reluat prin detector. Această operațiune rulează în fundal: puteți închide această fereastră și reveni mai târziu.",
"hist_imported_count": "{n} cicluri importate.",
"hist_duplicates": "{n} fuseseră deja importate și au fost omise.",
"hist_capped": "Limita de cicluri importate pentru acest dispozitiv a fost atinsă; restul nu au fost salvate.",
"hist_next_step": "Se află în lista dvs. Cicluri, marcate ca istoric importat. Deschideți unul și folosiți Etichetează pentru a indica programul căruia îi aparține.",
"hist_rows_read": "{n} citiri preluate",
"hist_breaks": "{n} întreruperi în care senzorul nu a fost disponibil",
"hist_other_entity": "{n} citiri pentru alte entități ignorate",
"hist_entity_substituted": "{used} citit (acest dispozitiv este configurat pentru {wanted})",
"hist_skipped_spans": "Porțiuni omise",
"hist_settings_used": "Detectat cu setările actuale ale acestui dispozitiv (putere minimă {w} W, întârziere la oprire {s} s).",
"hist_none_found": "Nu a putut fi detectat niciun ciclu în acel istoric.",
"hist_found": "S-au găsit {n} cicluri. Debifați tot ce nu pare un ciclu real: nimic nu este salvat până la import.",
"hist_scan_capped": "Sunt afișați doar primii candidați (au fost găsiți {n}).",
"hist_recorder_empty": "Home Assistant nu are istoric detaliat pentru acest senzor în acea perioadă.",
"hist_scan_failed": "Analiza a eșuat.",
"hist_scan_expired": "Acea analiză nu mai este disponibilă. Reluați analiza.",
"hist_import_failed": "Importul a eșuat.",
"imported_history_readonly": "Detectat într-un istoric de putere importat. Influențează potrivirea programelor, dar nu este contabilizat în statisticile dvs. și nu poate fi tăiat sau divizat. Etichetați-l pentru a indica programul."
},
"phase_desc": {
"anti_crease": "Tumblări scurte ocazionale după finalizare pentru a reduce șifonarea.",
@@ -1344,6 +1401,10 @@
"doc": "Stocați urmărirea completă a puterii și datele de depanare corespunzătoare pentru fiecare ciclu. Util pentru depanare, dar mărește dimensiunea de stocare.",
"label": "Salvați Urmele de Depanare"
},
"smart_termination_duration_ratio": {
"doc": "Cât de mult trebuie să fi avansat un ciclu în durata așteptată a programului corespunzător înainte ca Terminarea inteligentă să îl poată încheia mai devreme odată ce puterea scade. Durata așteptată este media programului, așa că pe aparatele al căror timp de funcționare variază mult - mașini de spălat în funcție de apa de alimentare rece iarna sau caldă vara, uscătoare cu senzor de umiditate, programe care depind de încărcătură - aproximativ jumătate dintre rulări se termină mai devreme decât acea medie și nu beneficiază niciodată de încheierea rapidă, terminându-se doar prin expirarea de rezervă cu minute întârziere. Reduceți această valoare (de ex. 0,85) pe acele mașini pentru ca încheierea anticipată să se declanșeze totuși; măriți-o spre 1,0 pentru a fi mai conservator. Lăsați gol pentru valoarea implicită (0,98 sau 0,99 pentru mașinile de spălat vase). Poate doar să încheie un ciclu mai devreme, niciodată mai târziu, și nu se declanșează niciodată la o potrivire ambiguă sau cu încredere scăzută.",
"label": "Raport de terminare inteligentă"
},
"smoothing_window": {
"doc": "Cât de mult este netezit semnalul de putere brută. Scăzut (2) este receptiv, dar zgomotos; ridicat (5) netezește vârfurile, dar adaugă lag.",
"label": "Fereastră de Netezire"
@@ -1474,6 +1535,10 @@
"door_end_dwell_seconds": {
"label": "Durată de așteptare la deschiderea ușii",
"doc": "Cât timp trebuie să rămână ușa deschisă înainte ca WashData să termine ciclul, când opțiunea \"Ușa se deschide automat la final\" este activată. Destul de lungă pentru a ignora adăugarea rapidă a unui vas (implicit 60 s), destul de scurtă pentru a termina prompt odată ce mașina deschide ușa."
},
"profile_evidence_sources": {
"label": "Ciclurile care formează un program",
"doc": "Ce cicluri sunt folosite pentru a construi curba de putere a fiecărui program și pentru a compara un ciclu încheiat cu ea. Debifarea unui tip face ca acesta să nu mai modeleze programele dvs., fără a șterge nimic - ciclurile rămân în lista dvs. Cicluri și pot fi în continuare etichetate sau eliminate. Util dacă nu aveți încredere în datele importate. Statisticile nu sunt afectate: ele numără întotdeauna doar ciclurile pe care această mașină le-a rulat efectiv. Debifarea tuturor este ignorată, deoarece un program fără cicluri în spate nu s-ar putea potrivi niciodată."
}
},
"setting_group": {
@@ -1557,6 +1622,9 @@
},
"basic_configuration": {
"label": "Configurație de bază"
},
"profile_evidence": {
"label": "Baza Profilurilor"
}
},
"status": {
@@ -1581,7 +1649,8 @@
"trimming": "Se taie…",
"splitting": "Se divide…",
"deleting": "Se șterge…",
"imported": "Importat"
"imported": "Importat",
"preparing": "Se pregătește…"
},
"tab": {
"advanced": "Avansat",
@@ -1611,6 +1680,7 @@
"wrong_profile": "Profil greșit"
},
"toast": {
"catalog_refreshed": "Catalogul comunității a fost actualizat",
"access_saved": "Controlul accesului a fost salvat",
"all_wiped": "Toate datele au fost șterse",
"analysis_complete_none": "Analiză finalizată: nicio sugestie nouă",
@@ -1716,7 +1786,9 @@
"store_download_failed": "Descărcare eșuată: {error}",
"store_download_nothing": "Nimic nou de descărcat - această configurație este deja pe dispozitivul dvs.",
"export_selective_done": "Export descărcat",
"import_selective_done": "Importate {profiles} profil(uri) și {cycles} ciclu(ri)"
"import_selective_done": "Importate {profiles} profil(uri) și {cycles} ciclu(ri)",
"hist_csv_required": "Încărcați mai întâi un fișier CSV sau lipiți conținutul acestuia",
"file_read_failed": "Fișierul nu a putut fi citit"
},
"suggestion": {
"both_agree": "WashData recomandă",
@@ -1812,7 +1884,7 @@
"thr_batch": "Păstrat chiar deasupra celei mai mici puteri active p05 pe {cycles} cicluri ({p05}W), astfel încât o pornire să fie surprinsă cât mai devreme posibil, iar pragul de oprire să rămână sub cea mai mică putere de funcționare a mașinii.",
"tol_per_profile": "p75 al varianței duratei per profil pe {profiles} profiluri ({cycles} cicluri); profilurile stabile nu sunt penalizate.",
"tol_pooled": "Pe baza varianței combinate a duratei a {cycles} cicluri recente etichetate (deviație p95={dev}).",
"watchdog": "Păstrat cât mai mic în siguranță (puțin peste intervalul de actualizare p95 de {p95}s, min. 30s), astfel încât blocajele să fie surprinse rapid fără opriri false."
"watchdog": "Păstrat cât mai mic în siguranță (puțin peste intervalul de actualizare p95 de {p95}s și cel puțin 2x intervalul de eșantionare de {median}s, min. 30s), astfel încât blocajele să fie surprinse rapid fără opriri false."
},
"exclusions": {
"summary": "Excluse {total} cicluri detectate greșit: {parts}.",
@@ -1844,6 +1916,7 @@
},
"pg_desc": {
"dishwasher_end_spike_quiet_release": "Mașină de spălat vase: secunde de liniște după durata așteptată înainte de a elibera așteptarea evacuării de la sfârșitul ciclului",
"smart_termination_duration_ratio": "Fracțiunea din durata așteptată a programului corespunzător pe care un ciclu trebuie să o atingă înainte ca Terminarea inteligentă să îl poată încheia mai devreme; reduceți-o pentru mașinile care depind de încărcătură sau de temperatură",
"anti_wrinkle_enabled": "Absoarbe impulsurile de rotire de după faza principală în loc să le trateze drept cicluri noi",
"anti_wrinkle_exit_power": "Puterea trebuie să scadă sub această valoare între impulsuri pentru ca modul anti-șifonare să rămână activ",
"anti_wrinkle_idle_timeout": "Timp de liniște permis între două impulsuri de rotire înainte ca modul anti-șifonare să se încheie",
@@ -1907,6 +1980,10 @@
"finished": "Ciclul a ajuns într-o stare finală și s-a încheiat."
},
"store": {
"your_model_tip": "Acesta este aparatul pe care l-ați declarat în Setări",
"your_model": "Al dvs.",
"search_brand_ph": "Căutați după marcă…",
"programs_count": "Programe: {n}",
"browse": "Răsfoiți",
"device": "Dispozitiv",
"favorites": "Favorite",
@@ -1962,7 +2039,7 @@
"apply": "Se divide ciclul"
},
"trim": {
"apply": "Se decupează ciclul"
"apply": "Se taie ciclul"
},
"merge": {
"apply": "Se îmbină ciclurile"
@@ -78,9 +78,12 @@
"awaiting": "Ожидает одобрения",
"imported_tip": "Импортировано из магазина сообщества. Используется только для сопоставления, не учитывается в статистике.",
"not_importable": "недоступно",
"exists": "существует"
"exists": "существует",
"backfilled_tip": "Обнаружено в импортированной истории мощности. Влияет только на сопоставление программ, не учитывается в статистике."
},
"btn": {
"set_brand_model": "Указать бренд и модель",
"refresh_catalog": "Обновить каталог",
"add_device": "+ Добавить устройство",
"add_device_tip": "Добавить ещё одно устройство WashData",
"add_maintenance": "Добавить событие обслуживания",
@@ -234,14 +237,19 @@
"download_device": "Скачать конфигурацию устройства",
"share_device": "Поделиться конфигурацией устройства",
"share_device_tip": "Поделиться программами и настройками этого устройства с сообществом",
"share_n": "Поделиться: {n} программ{s}",
"share_n": "Поделиться циклами: {n}",
"export_selected": "Экспорт (выбрать данные)",
"export_all": "Быстрый экспорт всего",
"import_raw": "Расширенно: заменить всё из JSON",
"download_export": "Скачать экспорт",
"analyze_import": "Анализировать файл",
"import_selected": "Импортировать выбранное",
"back": "Назад"
"back": "Назад",
"import_power_history": "Импорт истории мощности",
"hist_read_recorder": "Считать из Home Assistant",
"hist_scan": "Найти циклы",
"hist_import_n": "Импортировать циклы ({n})",
"hist_goto_cycles": "Показать циклы"
},
"conflict": {
"anti_wrinkle_exit": {
@@ -253,14 +261,14 @@
"start": "Должен быть ниже Макс. Мощности Защиты от Морщин ({max} Вт)"
},
"attn_sub": "Исправьте конфликты перед сохранением",
"attn_title": "{n} конфликт{s} настроек",
"settings_banner": "{n} конфликт{s} настроек проверьте выделенные разделы и исправьте перед сохранением.",
"attn_title": "Конфликты настроек: {n}",
"settings_banner": "Конфликты настроек: {n}. Проверьте выделенные разделы и исправьте их перед сохранением.",
"settings_banner_btn": "К первому",
"confidence": {
"auto": "Должен быть не ниже Порога Совпадения ({match})",
"learning": "Должен быть не выше Порога Совпадения ({match})",
"learning": "Должен быть не ниже Порога Совпадения ({match})",
"match_for_auto": "Должен быть не выше Уверенности Авто-Маркировки ({alc})",
"match_for_learning": "Должен быть не ниже Уверенности Обучения ({lc})"
"match_for_learning": "Должен быть не выше Уверенности Обучения ({lc})"
},
"duration_ratio": {
"max": "Должен быть больше Мин. Соотношения Длительности ({min})",
@@ -298,7 +306,7 @@
"match": "Должен быть выше Порога Несовпадения ({un})",
"unmatch": "Должен быть ниже Порога Совпадения ({match}); иначе принятое совпадение немедленно теряется"
},
"cascade_toast": ля согласованности также автоматически изменено ещё {n} параметр{s}.",
"cascade_toast": ругие настройки изменены для согласованности: {n}",
"suggestion_resolves": "Активируйте ожидающее предложение ({val}) ниже, чтобы исправить это",
"use_fix": "Использовать {val}",
"watchdog": {
@@ -356,7 +364,8 @@
"pg_outcome": "Результат симуляции",
"pg_across_cycles": "По всем вашим циклам",
"community_store": "Магазин сообщества",
"online_account": "Магазин сообщества и онлайн-функции"
"online_account": "Магазин сообщества и онлайн-функции",
"import_power_history": "Импорт истории мощности"
},
"health": {
"fair": "Приемлемое качество профиля",
@@ -364,6 +373,7 @@
"poor": "⚠ Низкое качество профиля"
},
"lbl": {
"drag_to_resize": "Перетащите, чтобы изменить размер",
"actions": "Действия",
"activity": "Активность",
"administrators": "Администраторы",
@@ -451,7 +461,7 @@
"metric": "Метрика",
"mode_existing_profile": "Добавить к существующему профилю",
"mode_new_profile": "Создать новый профиль",
"models_fine_tuned": "({count} модель{plural} точно настроено)",
"models_fine_tuned": "(точно настроенные модели: {count})",
"n_classic_suggestions": "{n} классических",
"n_ml_suggestions": "{n} ML",
"n_selected": "{n} выбрано",
@@ -677,7 +687,26 @@
"conflict_resolution": "Конфликты имён",
"conflict_import_copy": "Импортировать как копию",
"conflict_keep_mine": "Сохранить мои",
"conflict_overwrite": "Перезаписать"
"conflict_overwrite": "Перезаписать",
"hist_csv_data": "Данные CSV",
"hist_from_recorder": "Или считать из Home Assistant",
"days": "дн.",
"hist_keep": "Сохранить этот цикл",
"hist_looks_complete": "завершён",
"peak_power_short": "Пик",
"shape": "Форма",
"hist_skip_idle": "ничего не работало",
"hist_skip_sparse": "показания слишком редкие",
"hist_skip_short": "слишком мало показаний",
"hist_skip_long": "нет достаточно длинной паузы для разделения",
"hist_reason_short": "короче самого короткого реального цикла этого прибора",
"hist_reason_no_end": "так и не завершился корректно",
"hist_since": "Начиная с",
"task_history_import": "Сканирование истории мощности",
"task_history_import_apply": "Импорт циклов",
"evidence_real_cycles": "Циклы, выполненные этой машиной",
"evidence_reference_cycles": "Загружены из магазина сообщества",
"evidence_backfill_cycles": "Найдены в импортированной истории мощности"
},
"log": {
"all_levels": "Все уровни",
@@ -756,9 +785,15 @@
"store_share": "Поделиться в магазине сообщества",
"store_share_device": "Поделиться конфигурацией устройства",
"export_select": "Экспорт - выбор данных",
"import_wizard": "Импорт - выбор данных"
"import_wizard": "Импорт - выбор данных",
"history_import": "Импорт истории мощности"
},
"msg": {
"tail_trim_hint": "Сколько секунд обрезать с конца",
"store_sibling_hint": "Для вашей точной модели ничего не опубликовано? Очень похожая модель того же бренда обычно является хорошей отправной точкой.",
"store_declare_appliance": "Укажите WashData, какое у вас устройство, и на этой вкладке появятся конфигурации, опубликованные для него другими пользователями. Можно также ввести бренд выше и просто посмотреть, что есть.",
"refresh_catalog_hint": "Списки брендов и устройств сообщества кэшируются, чтобы общий магазин не превышал свой дневной лимит запросов. Обновите, чтобы получить записи, добавленные или одобренные другими.",
"head_trim_hint": "Сколько секунд обрезать с начала",
"appliance_monitor": "Монитор прибора",
"artifact_dip_detail": "Мощность упала ниже обычного диапазона на ~{n}с.",
"artifact_footer": "Выделено на графике выше. Это временные артефакты (например, дверь открылась в середине цикла), а не обязательно проблемы.",
@@ -769,7 +804,7 @@
"automations_intro": "WashData запускает события {start} / {end} и предоставляет объекты, поэтому уведомления и действия лучше всего строить как обычные автоматизации Home Assistant. Автоматизации, использующие это устройство, отображаются ниже.",
"cleanup_intro": "Все помеченные циклы наложены. Отметьте выбросы и удалите для очистки профиля.",
"clear_debug_hint": "Удалите сохраненные данные отладки, чтобы освободить место.",
"collecting_data": "Сбор данных ещё {need} цикл{plural} до начала точной настройки ({current}/{min}).",
"collecting_data": "Сбор данных. Осталось циклов до начала точной настройки: {need} ({current}/{min}).",
"compare_overlay_profiles": "Наложить профили (бледные)",
"compare_profiles_tip": "Наложите конверты других профилей на диаграмму выше, чтобы увидеть, какой из них лучше всего подходит для этого цикла.",
"compare_selected_cycles": "Выбранные циклы (чёткие) – показать / скрыть",
@@ -779,7 +814,7 @@
"cycles_deleted": "Удалено циклов: {count}",
"enough_data": "Достаточно данных для обучения ({current}/{min} циклов).",
"export_description": "Выберите, какие именно профили, циклы, настройки и прочее экспортировать в JSON, или проанализируйте файл и импортируйте только нужные части.",
"feedback_cycles_pending": "{n} цикл{s} для проверки",
"feedback_cycles_pending": "На проверку: {n}",
"feedback_prompt": "Подтвердите правильность, исправьте программу или проигнорируйте.",
"feedback_relabel_hint": "Повторная маркировка этого цикла также решает его.",
"filter_by_profile": "Фильтр по профилю…",
@@ -856,7 +891,6 @@
"pg_stress_synthetic": "здесь начинается симуляция режима ожидания",
"pg_sweep_intro": "Что если бы {param} было другим? Проверьте {steps} значений на ваших последних {cycles} циклах, чтобы найти настройку, при которой правильно сопоставляется больше всего циклов.",
"pg_sweep_step": "Шаг {done} / {total}",
"pg_undetected": "{n} цикл{s} не обнаружено",
"pg_verdict_bad": "Требует внимания: многие циклы остаются необнаруженными.",
"pg_verdict_good": "Хорошо настроено: большинство циклов правильно определяются и сопоставляются.",
"pg_verdict_ok": "Приемлемо: некоторые циклы пропущены. Попробуйте снизить порог запуска.",
@@ -888,6 +922,7 @@
"review_recorded_tip": "Отметьте это как выбранный вручную эталонный цикл для своей программы – та же роль, что и цикл, записанный вручную. Ссылочные циклы всегда сохраняются, заполняют соответствующий шаблон и никогда не удаляются при очистке. (Это «золотой»/записанный флаг; оба – одно и то же.)",
"review_tags_tip": "Необязательные флаги, описывающие, что пошло не так в этом цикле, чтобы это можно было учесть при обучении и очистке.",
"review_to_cycles": "Открыть очередь проверки циклов",
"samples_decimated": "Показано {shown} из {total} отсчётов (прорежено для отображения; пики сохранены). Широкий разрыв здесь - это прореживание, а не пропуск данных.",
"saving_triggers_reload": "Сохранение вызывает перезагрузку интеграции. Объекты HA могут кратко отображаться как недоступные.",
"search_placeholder": "Поиск настроек…",
"see_recorder": "Смотрите виджет записи ниже",
@@ -991,12 +1026,12 @@
"share_consent": "Вы делитесь реальными данными вашего прибора. Не делитесь, если ваши сценарии использования являются личными.",
"share_device_none": "Устройства ещё не настроены. Сначала добавьте устройство.",
"share_guideline_naming": "Используйте понятные названия программ (например, 'Cotton 40', 'Eco 60'), чтобы другие могли их идентифицировать",
"share_guideline_quality": "Делитесь только профилями с ⭐ эталонными циклами или не менее {n} подтверждёнными запусками",
"share_guideline_quality": "Делитесь только циклами, которые завершились нормально: без прерываний в середине цикла, открытия дверцы или кратковременных сбоев питания.",
"share_guideline_review": "Просмотрите профили перед публикацией -- удалите те, которые выглядят неправильно",
"share_guidelines_title": "Перед публикацией",
"store_download_device_intro": "Скачать конфигурацию устройства из сообщества и применить её к новому или существующему устройству",
"store_share_device_intro": "Поделиться программами вашего устройства (профили + эталонные циклы) с сообществом. Настройки являются необязательными.",
"share_profile_no_cycles": "Профиль '{p}' не имеет ⭐ эталонных циклов -- он будет пропущен, если у вас нет {n}+ подтверждённых запусков",
"store_share_device_intro": "Загрузите {brand} {model} с выбранными вами эталонными циклами. Другие пользователи с таким же устройством смогут принять ваши программы. Записи проверяются перед публикацией.",
"share_profile_no_cycles": "Нет эталонных циклов. Чтобы включить этот профиль, отметьте цикл как ⭐ на вкладке Циклы",
"advisory_phase_inconsistent": "Похоже, что '{name}' смешивает разные программы или температуры - его циклы нагреваются в течение очень разного времени. Разделение на отдельные профили (напр. по температуре) улучшит сопоставление и оценки времени.",
"advisory_phase_inconsistent_title": "⚠ Возможно, смешанные программы",
"export_select_intro": "Отметьте, что именно включить. Выбор профилей без их циклов всё равно экспортирует распознаваемую программу (её изученная форма передаётся вместе с ней).",
@@ -1006,7 +1041,29 @@
"merge_hint": "Импортируемые элементы добавляются; ничего локального не теряется. Конфликты имён разрешаются ниже.",
"replace_warn": "Каждая отмеченная категория очищается и заменяется данными из файла. Неотмеченные категории остаются без изменений.",
"dest_reference_hint": "Импортированные циклы только улучшают распознавание программ и никогда не влияют на статистику использования/энергии.",
"dest_real_history_hint": "Импортированные циклы считаются собственной историей этого устройства и учитываются в статистике энергии/использования. Используйте для переноса одного прибора в новую установку."
"dest_real_history_hint": "Импортированные циклы считаются собственной историей этого устройства и учитываются в статистике энергии/использования. Используйте для переноса одного прибора в новую установку.",
"import_history_description": "Умная розетка была у вас ещё до WashData? Загрузите экспорт истории её датчика мощности или считайте её прямо из Home Assistant, и обычное обнаружение пройдёт по этим данным, так что прошлые циклы появятся в списке «Циклы» и их можно будет назвать.",
"hist_input_hint": "Загрузите CSV, скачанный из панели «История» (объект, состояние, время изменения), или позвольте WashData считать историю датчика напрямую. Затем обнаружение пройдёт по этим данным точно так же, как в реальном времени, а вы выберете, какие из найденных циклов сохранить.",
"hist_recorder_hint": "Читает данные с выбранной даты по текущий момент. По умолчанию Home Assistant хранит подробную историю 10 дней, а после этого только часовые средние значения, которые слишком грубые для обнаружения циклов - выбирайте более раннюю дату, только если в настройках recorder задан больший срок хранения.",
"hist_scanning": "История воспроизводится через детектор. Это выполняется в фоне - можно закрыть это окно и вернуться позже.",
"hist_imported_count": "Импортировано циклов: {n}.",
"hist_duplicates": "Уже импортировано ранее и пропущено: {n}.",
"hist_capped": "Достигнут лимит импортированных циклов для устройства; остальные не сохранены.",
"hist_next_step": "Они в списке «Циклы» с отметкой об импортированной истории. Откройте цикл и нажмите «Пометить», чтобы указать его программу.",
"hist_rows_read": "Прочитано показаний: {n}",
"hist_breaks": "Пропусков, где датчик был недоступен: {n}",
"hist_other_entity": "Показаний других объектов пропущено: {n}",
"hist_entity_substituted": "Прочитано {used} (для этого устройства настроен {wanted})",
"hist_skipped_spans": "Пропущенные участки",
"hist_settings_used": "Обнаружено с текущими настройками этого устройства (Минимальная Мощность {w} Вт, Задержка Выключения {s} с).",
"hist_none_found": "В этой истории не удалось обнаружить ни одного цикла.",
"hist_found": "Найдено циклов: {n}. Снимите отметки с того, что не похоже на реальный запуск - до импорта ничего не сохраняется.",
"hist_scan_capped": "Показаны только первые кандидаты (найдено: {n}).",
"hist_recorder_empty": "В Home Assistant нет подробной истории для этого датчика за указанный период.",
"hist_scan_failed": "Сканирование не удалось.",
"hist_scan_expired": "Это сканирование больше недоступно. Выполните сканирование заново.",
"hist_import_failed": "Импорт не удался.",
"imported_history_readonly": "Обнаружено в импортированной истории мощности. Влияет на сопоставление программ, но не учитывается в вашей статистике; такой цикл нельзя обрезать или разделить. Нажмите «Пометить», чтобы указать программу."
},
"phase_desc": {
"anti_crease": "Периодические короткие вращения барабана после завершения для уменьшения складок.",
@@ -1471,6 +1528,10 @@
"show_contributor": {
"doc": "Показать имя автора на профилях, загруженных из магазина сообщества"
},
"smart_termination_duration_ratio": {
"doc": "Насколько глубоко в ожидаемую длительность сопоставленной программы должен зайти цикл, прежде чем Умное завершение сможет завершить его досрочно при падении мощности. Ожидаемая длительность - это среднее значение программы, поэтому на приборах с сильно изменчивым временем работы - стиральные машины при холодной зимней и тёплой летней воде на входе, сушильные машины с датчиком влажности, программы, зависящие от загрузки - около половины всех запусков завершаются короче этого среднего и никогда не получают быстрого завершения, заканчиваясь только по резервному тайм-ауту с опозданием на несколько минут. Уменьшите это значение (напр., 0.85) на таких машинах, чтобы досрочное завершение всё же срабатывало; повышайте ближе к 1.0 для большей осторожности. Оставьте пустым для значения по умолчанию (0.98 или 0.99 для посудомоечных машин). Оно может только завершить цикл раньше, но никогда позже, и никогда не срабатывает при неоднозначном или недостаточно уверенном совпадении.",
"label": "Коэффициент умного завершения"
},
"enable_phase_matching": {
"label": "Оставшееся время с учётом фаз",
"doc": "Разбивает каждый активный цикл на фазы (нагрев, стирка, отжим) и распределяет оставшееся время по фазам, сочетая это с классической оценкой - опираясь на распределение по фазам в начале цикла и на классическую оценку ближе к концу. Это персонализирует отсчёт под то, сколько на самом деле нагревается и работает ваша машина, что наиболее заметно в первой половине цикла. Выключено = только классическая оценка. Влияет только на отображение оставшегося времени; сопоставление программ и обнаружение цикла остаются без изменений."
@@ -1522,6 +1583,10 @@
"door_end_dwell_seconds": {
"label": "Выдержка при открытой дверце",
"doc": "Как долго дверца должна оставаться открытой до завершения цикла, когда включено \"Дверца открывается автоматически в конце\". Достаточно долго, чтобы игнорировать быструю загрузку посуды (по умолчанию 60 с), достаточно коротко для быстрого завершения после открытия дверцы машиной."
},
"profile_evidence_sources": {
"label": "Циклы, формирующие программу",
"doc": "Какие циклы используются для построения кривой мощности каждой программы и для сопоставления с ней завершённого цикла. Если снять галочку с какого-то вида, он перестанет влиять на ваши программы, но ничего не удалится: циклы останутся в списке Циклы, их по-прежнему можно пометить или удалить. Полезно, если вы не доверяете импортированным данным. На статистику это не влияет: в ней всегда учитываются только циклы, которые эта машина действительно выполнила. Если снять все галочки, это будет проигнорировано, ведь программа без циклов никогда не смогла бы совпасть."
}
},
"setting_group": {
@@ -1605,6 +1670,9 @@
},
"basic_configuration": {
"label": "Основные настройки"
},
"profile_evidence": {
"label": "Основа профиля"
}
},
"status": {
@@ -1629,7 +1697,8 @@
"trimming": "Обрезка…",
"splitting": "Разбивка…",
"deleting": "Удаление…",
"imported": "Импортировано"
"imported": "Импортировано",
"preparing": "Подготовка…"
},
"tab": {
"advanced": "Дополнительно",
@@ -1659,6 +1728,7 @@
"wrong_profile": "Неверный профиль"
},
"toast": {
"catalog_refreshed": "Каталог сообщества обновлён",
"access_saved": "Управление доступом сохранено",
"all_wiped": "Все данные удалены",
"analysis_complete_none": "Анализ завершён: нет новых предложений",
@@ -1752,19 +1822,21 @@
"rating_saved": "Оценка качества сохранена",
"brand_added": "Бренд добавлен, ожидает одобрения",
"profile_added": "Профиль добавлен, ожидает одобрения",
"saved_except_conflicts": "Настройки сохранены -- {n} настройка{s} пропущена из-за конфликтов",
"saved_except_conflicts": "Сохранено. Исправьте выделенные конфликты, чтобы сохранить остальное.",
"share_device_none_sel": "Выберите хотя бы одну программу для публикации",
"store_device_downloaded": "Конфигурация устройства загружена: {created} профиль{c} создан, {dup} уже существовало",
"store_device_downloaded_phases": "Конфигурация устройства загружена: {created} профиль{c} создан, {dup} уже существовало, карта фаз применена",
"store_device_downloaded_settings": "Конфигурация устройства загружена: {created} профиль{c} создан, {dup} уже существовало, настройки применены",
"store_device_shared": "Конфигурация устройства опубликована: {n} программ{s} загружено",
"store_device_shared_all_dup": "Нет ничего нового для публикации -- все программы уже есть в магазине",
"store_device_shared_partial": "Частичная публикация: {n} программ{s} загружено, {failed} пропущено",
"store_device_shared_some_dup": "Конфигурация устройства опубликована: {n} программ{s} загружено ({dup} уже существовало)",
"store_device_downloaded": "Добавлено программ: {p}, записей: {c}",
"store_device_downloaded_phases": "Добавлено программ: {p}, записей: {c}, карт фаз: {ph}",
"store_device_downloaded_settings": "Добавлено программ: {p}, записей: {c}, карт фаз: {ph}, настроек: {s}",
"store_device_shared": "Опубликовано в магазине сообщества (циклов: {n}), ожидает проверки.",
"store_device_shared_all_dup": "Все выбранные циклы ({n}) уже были в магазине сообщества.",
"store_device_shared_partial": "Опубликовано циклов: {n}; не удалось загрузить: {failed}.",
"store_device_shared_some_dup": "Опубликовано циклов: {created}; уже в магазине: {dup}.",
"store_download_failed": "Ошибка загрузки: {error}",
"store_download_nothing": "Нечего загружать -- все профили уже существуют на этом устройстве",
"export_selective_done": "Экспорт скачан",
"import_selective_done": "Импортировано профилей: {profiles}, циклов: {cycles}"
"import_selective_done": "Импортировано профилей: {profiles}, циклов: {cycles}",
"hist_csv_required": "Сначала загрузите файл CSV или вставьте его содержимое",
"file_read_failed": "Не удалось прочитать этот файл"
},
"suggestion": {
"both_agree": "WashData рекомендует",
@@ -1860,7 +1932,7 @@
"thr_batch": "Оставлено чуть выше наименьшей активной мощности p05 по {cycles} циклам ({p05}W), чтобы запуск фиксировался как можно раньше, а порог остановки оставался ниже минимальной рабочей мощности машины.",
"tol_per_profile": "p75 разброса длительности по профилям среди {profiles} профилей ({cycles} циклов); стабильные профили не штрафуются.",
"tol_pooled": "На основе объединённого разброса длительности {cycles} недавних размеченных циклов (отклонение p95={dev}).",
"watchdog": "Оставлено настолько низким, насколько это безопасно (чуть выше интервала обновления p95, равного {p95}s, мин. 30s), чтобы зависания выявлялись быстро без ложных остановок."
"watchdog": "Оставлено настолько низким, насколько это безопасно (чуть выше интервала обновления p95, равного {p95}s, и не менее 2x интервала выборки {median}s, мин. 30s), чтобы зависания выявлялись быстро без ложных остановок."
},
"exclusions": {
"summary": "Исключено {total} ошибочно определённых циклов: {parts}.",
@@ -1892,6 +1964,7 @@
},
"pg_desc": {
"dishwasher_end_spike_quiet_release": "Посудомоечная машина: секунды неактивности после ожидаемой длительности перед снятием ожидания финального слива в конце цикла",
"smart_termination_duration_ratio": "Доля ожидаемой длительности сопоставленной программы, которую должен достичь цикл, прежде чем Умное завершение сможет завершить его досрочно; уменьшите её для машин, зависящих от загрузки или температуры",
"completion_min_seconds": "Кратчайший запуск, считающийся настоящим циклом",
"end_repeat_count": "Сколько низких показаний подряд до завершения",
"interrupted_min_seconds": "Короткие циклы помечаются как прерванные",
@@ -1955,6 +2028,10 @@
"finished": "Цикл достиг конечного состояния и завершился."
},
"store": {
"your_model_tip": "Это устройство, которое вы указали в настройках",
"your_model": "Ваше",
"search_brand_ph": "Поиск по бренду…",
"programs_count": "Программы: {n}",
"browse": "Обзор",
"device": "Устройство",
"favorites": "Избранное",
@@ -78,9 +78,12 @@
"awaiting": "Čaká na schválenie",
"imported_tip": "Importované z komunitného obchodu. Používa sa iba na porovnávanie, nezapočítava sa do štatistík.",
"not_importable": "nedostupné",
"exists": "existuje"
"exists": "existuje",
"backfilled_tip": "Detekované v importovanej histórii výkonu. Ovplyvňuje iba priraďovanie programov, nezapočítava sa do štatistík."
},
"btn": {
"set_brand_model": "Nastaviť značku a model",
"refresh_catalog": "Obnoviť katalóg",
"add_device": "+ Pridať zariadenie",
"add_device_tip": "Pridajte ďalšie zariadenie WashData",
"add_maintenance": "Pridať udalosť údržby",
@@ -234,14 +237,19 @@
"download_device": "Stiahnuť nastavenie zariadenia",
"share_device": "Zdieľať nastavenie zariadenia",
"share_device_tip": "Zdieľať programy a nastavenia tohto zariadenia s komunitou",
"share_n": "Zdieľať {n} program{s}",
"share_n": "Zdieľať cykly: {n}",
"export_selected": "Export (vybrať údaje)",
"export_all": "Rýchly export všetkého",
"import_raw": "Pokročilé: nahradiť všetko zo súboru JSON",
"download_export": "Stiahnuť export",
"analyze_import": "Analyzovať súbor",
"import_selected": "Importovať vybrané",
"back": "Späť"
"back": "Späť",
"import_power_history": "Importovať históriu výkonu",
"hist_read_recorder": "Načítať z Home Assistant",
"hist_scan": "Vyhľadať cykly",
"hist_import_n": "Importovať cykly: {n}",
"hist_goto_cycles": "Zobraziť cykly"
},
"conflict": {
"anti_wrinkle_exit": {
@@ -253,12 +261,12 @@
"start": "Musí byť pod Max. výkonom ochrany pred krčením ({max} W)"
},
"attn_sub": "Pred uložením opravte konflikty",
"attn_title": "{n} konflikt{s} nastavení",
"attn_title": "Konflikty nastavení: {n}",
"confidence": {
"auto": "Musí byť na úrovni alebo nad Prahom zhody ({match})",
"learning": "Musí byť na úrovni alebo pod Prahom zhody ({match})",
"learning": "Musí byť na úrovni alebo nad Prahom zhody ({match})",
"match_for_auto": "Musí byť na úrovni alebo pod Spoľahlivosťou autooznačovania ({alc})",
"match_for_learning": "Musí byť na úrovni alebo nad Spoľahlivosťou učenia ({lc})"
"match_for_learning": "Musí byť na úrovni alebo pod Spoľahlivosťou učenia ({lc})"
},
"duration_ratio": {
"max": "Musí byť väčší ako Min. pomer trvania ({min})",
@@ -296,14 +304,14 @@
"match": "Musí byť nad Prahom nezhody ({un})",
"unmatch": "Musí byť pod Prahom zhody ({match}); inak sa potvrdená zhoda ihneď zruší"
},
"cascade_toast": "Bolo tiež automaticky upravených {n} nastavení pre zachovanie konzistencie.",
"cascade_toast": "Ďalšie nastavenia upravené pre zachovanie konzistencie: {n}",
"suggestion_resolves": "Uplatnite nižšie čakajúci návrh ({val}) na vyriešenie tohto konfliktu",
"use_fix": "Použiť {val}",
"watchdog": {
"interval": "Mal by byť aspoň 2× Interval vzorkovania ({si} s)",
"sampling": "Interval vzorkovania by mal byť najviac polovica Intervalu watchdog ({wi} s)"
},
"settings_banner": "{n} konflikt{s} nastavení skontrolujte zvýraznené sekcie a opravte pred uložením.",
"settings_banner": "Konflikty nastavení: {n}. Skontrolujte zvýraznené sekcie a opravte ich pred uložením.",
"settings_banner_btn": "Prejsť na prvý"
},
"hdr": {
@@ -356,7 +364,8 @@
"pg_outcome": "Výsledok simulácie",
"pg_across_cycles": "Naprieč vašimi cyklami",
"community_store": "Komunitný obchod",
"online_account": "Komunitný obchod a online funkcie"
"online_account": "Komunitný obchod a online funkcie",
"import_power_history": "Import histórie výkonu"
},
"health": {
"fair": "Prijateľná kvalita profilu",
@@ -364,6 +373,7 @@
"poor": "⚠ Zlá kvalita profilu"
},
"lbl": {
"drag_to_resize": "Potiahnutím zmeníte veľkosť",
"actions": "Akcie",
"activity": "Aktivita",
"administrators": "Administrátori",
@@ -451,7 +461,7 @@
"metric": "Metrika",
"mode_existing_profile": "Pridať k existujúcemu profilu",
"mode_new_profile": "Vytvoriť nový profil",
"models_fine_tuned": "({count} modelov doladených)",
"models_fine_tuned": "(doladené modely: {count})",
"n_classic_suggestions": "{n} klasické",
"n_ml_suggestions": "{n} ML",
"n_selected": "{n} vybraných",
@@ -677,7 +687,26 @@
"conflict_resolution": "Konflikty názvov",
"conflict_import_copy": "Importovať ako kópiu",
"conflict_keep_mine": "Ponechať moje",
"conflict_overwrite": "Prepísať"
"conflict_overwrite": "Prepísať",
"hist_csv_data": "Údaje CSV",
"hist_from_recorder": "Alebo ju načítajte z Home Assistant",
"days": "dní",
"hist_keep": "Zachovať tento cyklus",
"hist_looks_complete": "dokončený",
"peak_power_short": "Špička",
"shape": "Tvar",
"hist_skip_idle": "nič nebežalo",
"hist_skip_sparse": "merania príliš vzdialené od seba",
"hist_skip_short": "príliš málo meraní",
"hist_skip_long": "žiadna dostatočne dlhá prestávka na rozdelenie",
"hist_reason_short": "kratší než najkratší skutočný cyklus tohto spotrebiča",
"hist_reason_no_end": "nikdy sa riadne neskončil",
"hist_since": "Od",
"task_history_import": "Prehľadávanie histórie výkonu",
"task_history_import_apply": "Import cyklov",
"evidence_real_cycles": "Cykly, ktoré tento spotrebič vykonal",
"evidence_reference_cycles": "Stiahnuté z komunitného obchodu",
"evidence_backfill_cycles": "Nájdené v importovanej histórii výkonu"
},
"log": {
"all_levels": "Všetky úrovne",
@@ -756,9 +785,15 @@
"store_share": "Zdieľať do komunitného obchodu",
"store_share_device": "Zdieľať nastavenie zariadenia",
"export_select": "Export - vybrať údaje",
"import_wizard": "Import - vybrať údaje"
"import_wizard": "Import - vybrať údaje",
"history_import": "Import histórie výkonu"
},
"msg": {
"tail_trim_hint": "Koľko sekúnd odstrániť z konca",
"store_sibling_hint": "Pre váš konkrétny model nie je nič zdieľané? Veľmi podobný model od tej istej značky je zvyčajne dobrý východiskový bod.",
"store_declare_appliance": "Povedzte WashData, aký spotrebič máte, a táto karta zobrazí nastavenia, ktoré pre neho zdieľali ostatní používatelia. Môžete tiež zadať značku vyššie a poobzerať sa.",
"refresh_catalog_hint": "Zoznamy značiek a spotrebičov z komunity sa ukladajú do medzipamäte, aby zdieľaný obchod neprekročil svoj denný limit dotazov. Obnovením načítate položky, ktoré ostatní pridali alebo schválili.",
"head_trim_hint": "Koľko sekúnd odstrániť zo začiatku",
"appliance_monitor": "Monitor spotrebiča",
"artifact_dip_detail": "Poklesol pod bežné pásmo výkonu počas ~{n} s.",
"artifact_footer": "Zvýraznené na grafe vyššie. Sú to prechodné artefakty (napr. dvere otvorené uprostred cyklu), nie nevyhnutne problémy.",
@@ -769,7 +804,7 @@
"automations_intro": "WashData spúšťa udalosti {start} / {end} a sprístupňuje entity, takže notifikácie a akcie sa najlepšie vytvárajú ako bežné automatizácie Home Assistant. Automatizácie používajúce toto zariadenie sú zobrazené nižšie.",
"cleanup_intro": "Všetky označené cykly naložené. Označte odchýlky a odstráňte pre vyčistenie profilu.",
"clear_debug_hint": "Odstráňte uložené údaje ladenia, aby ste uvoľnili miesto.",
"collecting_data": "Zbieranie dát: ešte {need} cyklov do spustenia doladenia ({current}/{min}).",
"collecting_data": "Zbieranie dát. Zostávajúce cykly do spustenia doladenia: {need} ({current}/{min}).",
"compare_overlay_profiles": "Prekryté profily (bledé)",
"compare_profiles_tip": "Prekryte ostatné profilové obálky v tabuľke vyššie, aby ste videli, ktorá z nich najlepšie vyhovuje tomuto cyklu.",
"compare_selected_cycles": "Vybraté cykly (tučné) zobraziť / skryť",
@@ -779,7 +814,7 @@
"cycles_deleted": "Odstránených cyklov: {count}",
"enough_data": "Dostatok dát na učenie ({current}/{min} cyklov).",
"export_description": "Vyberte presne, ktoré profily, cykly, nastavenia a ďalšie údaje exportovať do súboru JSON, alebo analyzujte súbor a importujte len tie časti, ktoré chcete.",
"feedback_cycles_pending": "{n} cyklov na kontrolu",
"feedback_cycles_pending": "Na kontrolu: {n}",
"feedback_prompt": "Potvrďte správnosť, opravte program alebo ignorujte.",
"feedback_relabel_hint": "Opätovné označenie tohto cyklu ho tiež vyrieši.",
"filter_by_profile": "Filtrovať podľa profilu…",
@@ -856,7 +891,6 @@
"pg_stress_synthetic": "simulácia nečinnosti začína tu",
"pg_sweep_intro": "Čo keby bol {param} iný? Otestujte {steps} hodnôt na vašich posledných {cycles} cykloch a nájdite nastavenie, pri ktorom je správne priradených najviac cyklov.",
"pg_sweep_step": "Krok {done} / {total}",
"pg_undetected": "{n} nezistených cyklov",
"pg_verdict_bad": "Vyžaduje pozornosť: mnoho cyklov zostáva nezistených.",
"pg_verdict_good": "Dobre vyladené: väčšina cyklov je správne rozpoznaná a priradená.",
"pg_verdict_ok": "Prijateľné: niektoré cykly neboli zachytené. Skúste znížiť prah spustenia.",
@@ -888,6 +922,7 @@
"review_recorded_tip": "Označte to ako ručne vybraný referenčný cyklus pre svoj program rovnakú úlohu ako manuálne zaznamenaný cyklus. Referenčné cykly sa vždy uchovávajú, nasadzujú zodpovedajúcu šablónu a pri čistení sa nikdy nezrušia. (Toto je zlatá/zaznamenaná vlajka; obe sú to isté.)",
"review_tags_tip": "Voliteľné príznaky popisujúce, čo sa v tomto cykle pokazilo, aby to tréning a čistenie mohli zohľadniť.",
"review_to_cycles": "Otvoriť front kontroly cyklov",
"samples_decimated": "Zobrazených {shown} z {total} vzoriek (preriedené pre zobrazenie; špičky zachované). Široká medzera tu znamená preriedenie, nie chýbajúce dáta.",
"saving_triggers_reload": "Uloženie spustí opätovné načítanie integrácie. Entity HA sa môžu nakrátko zobraziť ako nedostupné.",
"search_placeholder": "Hľadať nastavenia…",
"see_recorder": "Pozrite si widget nahrávania nižšie",
@@ -991,12 +1026,12 @@
"share_consent": "Zdieľate skutočné dáta zo svojho spotrebiča. Nezdieľajte, ak sú vaše vzorce používania súkromné.",
"share_device_none": "Zatiaľ nie sú nastavené žiadne zariadenia. Najprv pridajte zariadenie.",
"share_guideline_naming": "Používajte zrozumiteľné názvy programov (napr. 'Cotton 40', 'Eco 60'), aby ich ostatní mohli identifikovať",
"share_guideline_quality": "Zdieľajte iba profily s ⭐ referenčnými cyklami alebo aspoň {n} potvrdenými spusteniami",
"share_guideline_quality": "Zdieľajte iba cykly, ktoré prebehli normálne: bez prerušení uprostred cyklu, otvorenia dvierok alebo krátkych výpadkov napájania.",
"share_guideline_review": "Pred zdieľaním skontrolujte svoje profily -- odstráňte tie, ktoré vyzerajú zle",
"share_guidelines_title": "Pred zdieľaním",
"store_download_device_intro": "Stiahnuť nastavenie zariadenia komunity a použiť ho na nové alebo existujúce zariadenie",
"store_share_device_intro": "Zdieľať programy vášho zariadenia (profily + referenčné cykly) s komunitou. Nastavenia sú voliteľné.",
"share_profile_no_cycles": "Profil '{p}' nemá žiadne referenčné cykly -- bude preskočený, ak nemáte {n}+ potvrdených spustení",
"store_share_device_intro": "Nahrajte {brand} {model} s referenčnými cyklami, ktoré vyberiete. Ostatní s rovnakým spotrebičom môžu vaše programy prevziať. Záznamy sú pred zverejnením skontrolované.",
"share_profile_no_cycles": "Žiadne referenčné cykly. Ak chcete zahrnúť tento profil, označte cyklus ako ⭐ na karte Cykly",
"advisory_phase_inconsistent": "Zdá sa, že '{name}' mieša rôzne programy alebo teploty - jeho cykly sa ohrievajú veľmi rôzne dlho. Rozdelenie na samostatné profily (napr. podľa teploty) zlepší zhodu aj odhady času.",
"advisory_phase_inconsistent_title": "⚠ Možno zmiešané programy",
"export_select_intro": "Zaškrtnite presne to, čo sa má zahrnúť. Výber profilov bez ich cyklov aj tak exportuje rozpoznateľný program (jeho naučená krivka sa prenesie spolu s ním).",
@@ -1006,7 +1041,29 @@
"merge_hint": "Importované položky sa pridajú; nič miestne sa nestratí. Konflikty názvov sa riešia nižšie.",
"replace_warn": "Každá zaškrtnutá kategória sa vymaže a nahradí údajmi zo súboru. Nezaškrtnuté kategórie zostanú bez zmeny.",
"dest_reference_hint": "Importované cykly len zlepšujú rozpoznávanie programov a nikdy neovplyvňujú štatistiky spotreby/energie.",
"dest_real_history_hint": "Importované cykly sa počítajú ako vlastná história tohto zariadenia a prispievajú do štatistík energie/spotreby. Použite pri presune jedného spotrebiča do novej inštalácie."
"dest_real_history_hint": "Importované cykly sa počítajú ako vlastná história tohto zariadenia a prispievajú do štatistík energie/spotreby. Použite pri presune jedného spotrebiča do novej inštalácie.",
"import_history_description": "Mali ste inteligentnú zásuvku už pred WashData? Nahrajte export histórie jej senzora výkonu alebo ju načítajte priamo z Home Assistant a prebehne nad ňou bežná detekcia, takže sa staršie cykly objavia v zozname Cykly pripravené na pomenovanie.",
"hist_input_hint": "Nahrajte CSV stiahnuté z panela História (entita, stav, posledná zmena), alebo nechajte WashData načítať históriu senzora priamo. Detekcia potom prebehne presne tak ako naživo a vy vyberiete, ktoré z nájdených cyklov si ponecháte.",
"hist_recorder_hint": "Načíta údaje od zvoleného dátumu až doteraz. Home Assistant štandardne uchováva podrobnú históriu 10 dní a potom už len hodinové priemery, ktoré sú na detekciu cyklov príliš hrubé - skorší dátum voľte len vtedy, ak máte recorder nastavený na dlhšie uchovávanie.",
"hist_scanning": "Prehrávame vašu históriu cez detektor. Beží to na pozadí - tento dialóg môžete zavrieť a vrátiť sa k nemu neskôr.",
"hist_imported_count": "Importované cykly: {n}.",
"hist_duplicates": "Už predtým importované a preskočené: {n}.",
"hist_capped": "Bol dosiahnutý limit importovaných cyklov na zariadenie; zvyšok sa neuložil.",
"hist_next_step": "Nájdete ich v zozname Cykly, označené ako importovaná história. Otvorte niektorý z nich a tlačidlom Označiť pomenujte program, ku ktorému patrí.",
"hist_rows_read": "Prečítané merania: {n}",
"hist_breaks": "Medzery, keď bol senzor nedostupný: {n}",
"hist_other_entity": "Ignorované merania iných entít: {n}",
"hist_entity_substituted": "Načítané {used} (toto zariadenie má nastavené {wanted})",
"hist_skipped_spans": "Preskočené úseky",
"hist_settings_used": "Detekované s aktuálnymi nastaveniami tohto zariadenia (minimálny výkon {w} W, oneskorenie vypnutia {s} s).",
"hist_none_found": "V tejto histórii sa nepodarilo detekovať žiadne cykly.",
"hist_found": "Nájdené cykly: {n}. Odškrtnite všetko, čo nevyzerá ako skutočný beh - kým neurobíte import, nič sa neuloží.",
"hist_scan_capped": "Zobrazujú sa len prví kandidáti (nájdených bolo {n}).",
"hist_recorder_empty": "Home Assistant nemá pre tento senzor v danom období žiadnu podrobnú históriu.",
"hist_scan_failed": "Vyhľadávanie sa nepodarilo.",
"hist_scan_expired": "Toto vyhľadávanie už nie je dostupné. Spustite ho prosím znova.",
"hist_import_failed": "Import sa nepodaril.",
"imported_history_readonly": "Detekované v importovanej histórii výkonu. Ovplyvňuje priraďovanie programov, ale nezapočítava sa do vašich štatistík a nedá sa orezať ani rozdeliť. Označením mu priraďte program."
},
"phase_desc": {
"anti_crease": "Príležitostné krátke vírenia po dokončení na predchádzanie krčeniu oblečenia.",
@@ -1392,6 +1449,10 @@
"doc": "Uložte úplnú stopu výkonu a zodpovedajúce údaje ladenia pre každý cyklus. Užitočné pri riešení problémov, ale zvyšuje veľkosť úložiska.",
"label": "Uložiť ladiace záznamy"
},
"smart_termination_duration_ratio": {
"doc": "Ako ďaleko v očakávanej dobe trvania priradeného programu musí byť cyklus, než ho Inteligentné ukončenie môže po poklese príkonu ukončiť skôr. Očakávaná doba trvania je priemer programu, takže pri spotrebičoch, ktorých doba behu veľmi kolíše - práčky so studenou prívodnou vodou v zime oproti teplej v lete, sušičky so senzorovým sušením, programy závislé od náplne - skončí približne polovica všetkých behov skôr než tento priemer a nikdy sa rýchleho ukončenia nedočká, takže skončí až o niekoľko minút neskôr cez záložný časový limit. Pri takýchto strojoch túto hodnotu znížte (napr. 0,85), aby sa skoršie ukončenie napriek tomu spustilo; pre opatrnejšie správanie ju zvýšte smerom k 1,0. Ponechajte prázdne pre predvolenú hodnotu (0,98, pri umývačkách riadu 0,99). Cyklus môže vždy len ukončiť skôr, nikdy neskôr, a nikdy sa nespustí pri nejednoznačnej zhode alebo zhode s nízkou spoľahlivosťou.",
"label": "Pomer inteligentného ukončenia"
},
"smoothing_window": {
"doc": "Ako veľmi je vyhladený signál surového výkonu. Nízka (2) reaguje, ale je hlučná; vysoká (5) vyhladzuje hroty, ale pridáva oneskorenie.",
"label": "Okno vyhladzovania"
@@ -1522,6 +1583,10 @@
"door_end_dwell_seconds": {
"label": "Čakanie na otvorenie dverí pre ukončenie",
"doc": "Ako dlho musia dvere zostať otvorené, kým WashData ukončí cyklus, keď je zapnutá funkcia \"Dvere sa na konci automaticky otvoria\". Dostatočne dlho na ignorovanie rýchleho pridania riadu (predvolene 60 s), dostatočne krátko pre rýchle ukončenie po otvorení dverí spotrebičom."
},
"profile_evidence_sources": {
"label": "Cykly tvoriace program",
"doc": "Ktoré cykly sa používajú na zostavenie krivky výkonu každého programu a na priradenie dokončeného cyklu k nej. Keď niektorý druh odškrtnete, prestane ovplyvňovať vaše programy, ale nič sa nezmaže - cykly zostanú v zozname Cykly a stále ich možno označiť alebo odstrániť. Užitočné, ak nedôverujete importovaným údajom. Štatistiky to neovplyvní: vždy počítajú len cykly, ktoré tento spotrebič skutočne vykonal. Odškrtnutie všetkých možností sa ignoruje, pretože program bez cyklov by nikdy nemohol byť priradený."
}
},
"setting_group": {
@@ -1605,6 +1670,9 @@
},
"basic_configuration": {
"label": "Základná konfigurácia"
},
"profile_evidence": {
"label": "Podklady profilu"
}
},
"status": {
@@ -1629,7 +1697,8 @@
"trimming": "Orezávanie…",
"splitting": "Rozdeľovanie…",
"deleting": "Odstraňovanie…",
"imported": "Importované"
"imported": "Importované",
"preparing": "Príprava…"
},
"suggestion": {
"both_agree": "WashData odporúča",
@@ -1725,7 +1794,7 @@
"thr_batch": "Ponechané tesne nad najnižším činným výkonom p05 naprieč {cycles} cyklami ({p05}W), aby sa štart zachytil čo najskôr a prah zastavenia zostal pod najnižším prevádzkovým výkonom stroja.",
"tol_per_profile": "p75 rozptylu dĺžky podľa profilu naprieč {profiles} profilmi ({cycles} cyklov); konzistentné profily nie sú penalizované.",
"tol_pooled": "Na základe zlúčeného rozptylu dĺžky {cycles} nedávnych označených cyklov (odchýlka p95={dev}).",
"watchdog": "Ponechané čo najnižšie pri zachovaní bezpečnosti (tesne nad intervalom aktualizácie p95 vo výške {p95}s, min. 30s), aby sa zaseknutia rýchlo odhalili bez falošných zastavení."
"watchdog": "Ponechané čo najnižšie pri zachovaní bezpečnosti (tesne nad intervalom aktualizácie p95 vo výške {p95}s a aspoň 2x nad intervalom vzorkovania {median}s, min. 30s), aby sa zaseknutia rýchlo odhalili bez falešných zastavení."
},
"exclusions": {
"summary": "Vylúčených {total} chybne zistených cyklov: {parts}.",
@@ -1772,6 +1841,7 @@
"wrong_profile": "Nesprávny profil"
},
"toast": {
"catalog_refreshed": "Katalóg komunity obnovený",
"access_saved": "Kontrola prístupu uložená",
"all_wiped": "Všetky dáta vymazané",
"analysis_complete_none": "Analýza dokončená: žiadne nové návrhy",
@@ -1865,19 +1935,21 @@
"rating_saved": "Hodnotenie kvality uložené",
"brand_added": "Značka pridaná, čaká na schválenie",
"profile_added": "Profil pridaný, čaká na schválenie",
"saved_except_conflicts": "Nastavenia uložené -- {n} nastavenie{s} preskočené kvôli konfliktom",
"saved_except_conflicts": "Uložené. Opravte zvýraznené konflikty, aby sa uložil zvyšok.",
"share_device_none_sel": "Vyberte aspoň jeden program na zdieľanie",
"store_device_downloaded": "Nastavenie zariadenia stiahnuté: {created} profil{c} vytvorený, {dup} už existovalo",
"store_device_downloaded_phases": "Nastavenie zariadenia stiahnuté: {created} profil{c} vytvorený, {dup} už existovalo, mapa fáz použitá",
"store_device_downloaded_settings": "Nastavenie zariadenia stiahnuté: {created} profil{c} vytvorený, {dup} už existovalo, nastavenia použité",
"store_device_shared": "Nastavenie zariadenia zdieľané: {n} program{s} nahraný",
"store_device_shared_all_dup": "Nič nové na zdieľanie -- všetky programy v obchode už existujú",
"store_device_shared_partial": "Čiastočné zdieľanie: {n} program{s} nahraný, {failed} preskočené",
"store_device_shared_some_dup": "Nastavenie zariadenia zdieľané: {n} program{s} nahraný ({dup} už existovalo)",
"store_device_downloaded": "Pridaných programov: {p}, nahrávok: {c}",
"store_device_downloaded_phases": "Pridaných programov: {p}, nahrávok: {c}, máp fáz: {ph}",
"store_device_downloaded_settings": "Pridaných programov: {p}, nahrávok: {c}, máp fáz: {ph}, nastavení: {s}",
"store_device_shared": "Zdieľané do komunitného obchodu (cyklov: {n}), čaká na kontrolu.",
"store_device_shared_all_dup": "Všetky vybrané cykly ({n}) už v komunitnom obchode sú.",
"store_device_shared_partial": "Zdieľaných cyklov: {n}; {failed} sa nepodarilo nahrať.",
"store_device_shared_some_dup": "Zdieľaných cyklov: {created}; už v obchode: {dup}.",
"store_download_failed": "Sťahovanie zlyhalo: {error}",
"store_download_nothing": "Nič na stiahnutie -- všetky profily na tomto zariadení už existujú",
"export_selective_done": "Export stiahnutý",
"import_selective_done": "Importovaných {profiles} profilov a {cycles} cyklov"
"import_selective_done": "Importovaných {profiles} profilov a {cycles} cyklov",
"hist_csv_required": "Najprv načítajte súbor CSV alebo prilepte jeho obsah",
"file_read_failed": "Tento súbor sa nepodarilo prečítať"
},
"trend": {
"down": "Klesajúci trend",
@@ -1892,6 +1964,7 @@
},
"pg_desc": {
"dishwasher_end_spike_quiet_release": "Umývačka: tiché sekundy po očakávanom trvaní, než sa uvoľní čakanie na záverečné odčerpanie vody",
"smart_termination_duration_ratio": "Zlomok očakávanej doby trvania priradeného programu, ktorý musí cyklus dosiahnuť, než ho Inteligentné ukončenie môže ukončiť skôr; znížte ho pri strojoch závislých od náplne alebo teploty",
"anti_wrinkle_enabled": "Pohltiť impulzy bubna po hlavnej fáze namiesto ich čítania ako nové cykly",
"anti_wrinkle_exit_power": "Výkon musí medzi impulzmi klesnúť pod túto hodnotu, aby ochrana pred krčením zostala aktívna",
"anti_wrinkle_idle_timeout": "Povolený pokoj medzi dvoma impulzmi bubna, než sa ochrana pred krčením skončí",
@@ -1955,6 +2028,10 @@
"finished": "Cyklus dosiahol koncový stav a skončil."
},
"store": {
"your_model_tip": "Toto je spotrebič, ktorý ste zadali v Nastaveniach",
"your_model": "Vaše",
"search_brand_ph": "Hľadať podľa značky…",
"programs_count": "Programy: {n}",
"browse": "Prehliadať",
"device": "Zariadenie",
"favorites": "Obľúbené",
@@ -78,9 +78,12 @@
"awaiting": "Čaka na odobritev",
"imported_tip": "Uvoženo iz skupnostne trgovine. Uporablja se samo za ujemanje, ne šteje se v statistiko.",
"not_importable": "ni na voljo",
"exists": "obstaja"
"exists": "obstaja",
"backfilled_tip": "Zaznano v uvoženi zgodovini moči. Vpliva samo na ujemanje programov, ne šteje se v statistiko."
},
"btn": {
"set_brand_model": "Nastavi znamko in model",
"refresh_catalog": "Osveži katalog",
"add_device": "+ Dodaj napravo",
"add_device_tip": "Dodajte drugo napravo WashData",
"add_maintenance": "Dodaj dogodek vzdrževanja",
@@ -234,14 +237,19 @@
"download_device": "Prenesi nastavitve naprave",
"share_device": "Deli nastavitve naprave",
"share_device_tip": "Deli programe in nastavitve te naprave s skupnostjo",
"share_n": "Deli {n} program{s}",
"share_n": "Deli cikle ({n})",
"export_selected": "Izvoz (izberi podatke)",
"export_all": "Hitri izvoz vsega",
"import_raw": "Napredno: zamenjaj vse iz datoteke JSON",
"download_export": "Prenesi izvoz",
"analyze_import": "Analiziraj datoteko",
"import_selected": "Uvozi izbrano",
"back": "Nazaj"
"back": "Nazaj",
"import_power_history": "Uvozi zgodovino moči",
"hist_read_recorder": "Preberi iz Home Assistant",
"hist_scan": "Poišči cikle",
"hist_import_n": "Uvozi cikle: {n}",
"hist_goto_cycles": "Pokaži cikle"
},
"conflict": {
"anti_wrinkle_exit": {
@@ -253,12 +261,12 @@
"start": "Mora biti pod Maks. močjo zaščite pred gubami ({max} W)"
},
"attn_sub": "Pred shranjevanjem odpravite konflikte",
"attn_title": "{n} konflikt{s} nastavitev",
"attn_title": "Konflikti nastavitev: {n}",
"confidence": {
"auto": "Mora biti enak ali nad Pragom ujemanja ({match})",
"learning": "Mora biti enak ali pod Pragom ujemanja ({match})",
"learning": "Mora biti enak ali nad Pragom ujemanja ({match})",
"match_for_auto": "Mora biti enak ali pod Zaupanjem samodejnega označevanja ({alc})",
"match_for_learning": "Mora biti enak ali nad Zaupanjem učenja ({lc})"
"match_for_learning": "Mora biti enak ali pod Zaupanjem učenja ({lc})"
},
"duration_ratio": {
"max": "Mora biti večje od Min. razmerja trajanja ({min})",
@@ -296,14 +304,14 @@
"match": "Mora biti nad Pragom neujemanja ({un})",
"unmatch": "Mora biti pod Pragom ujemanja ({match}); sicer se potrjeno ujemanje takoj razveljavi"
},
"cascade_toast": "Samodejno je bilo prilagojenih {n} nastavitev za doslednost.",
"cascade_toast": "Druge nastavitve, prilagojene za doslednost: {n}",
"suggestion_resolves": "Uveljavite čakajoči predlog ({val}) spodaj za odpravo tega konflikta",
"use_fix": "Uporabi {val}",
"watchdog": {
"interval": "Mora biti vsaj 2× Interval vzorčenja ({si} s)",
"sampling": "Interval vzorčenja mora biti največ polovica Intervala nadzornika ({wi} s)"
},
"settings_banner": "{n} konflikt{s} nastavitev preverite označene razdelke in popravite pred shranjevanjem.",
"settings_banner": "Konflikti nastavitev: {n}. Preverite označene razdelke in jih popravite pred shranjevanjem.",
"settings_banner_btn": "Pojdi na prvega"
},
"hdr": {
@@ -356,7 +364,8 @@
"pg_outcome": "Izid simulacije",
"pg_across_cycles": "Po vseh vaših ciklih",
"community_store": "Skupnostna trgovina",
"online_account": "Skupnostna trgovina in spletne funkcije"
"online_account": "Skupnostna trgovina in spletne funkcije",
"import_power_history": "Uvoz zgodovine moči"
},
"health": {
"fair": "Sprejemljiva kakovost profila",
@@ -364,6 +373,7 @@
"poor": "⚠ Slaba kakovost profila"
},
"lbl": {
"drag_to_resize": "Povlecite za spremembo velikosti",
"actions": "Dejanja",
"activity": "Aktivnost",
"administrators": "Skrbniki",
@@ -451,7 +461,7 @@
"metric": "Meritev",
"mode_existing_profile": "Dodaj k obstoječemu profilu",
"mode_new_profile": "Ustvari nov profil",
"models_fine_tuned": "({count} modelov prilagojenih)",
"models_fine_tuned": "(natančno prilagojeni modeli: {count})",
"n_classic_suggestions": "{n} klasično",
"n_ml_suggestions": "{n} ML",
"n_selected": "{n} izbranih",
@@ -677,7 +687,26 @@
"conflict_resolution": "Spori imen",
"conflict_import_copy": "Uvozi kot kopijo",
"conflict_keep_mine": "Obdrži moje",
"conflict_overwrite": "Prepiši"
"conflict_overwrite": "Prepiši",
"hist_csv_data": "Podatki CSV",
"hist_from_recorder": "Ali jo preberite iz Home Assistant",
"days": "dni",
"hist_keep": "Ohrani ta cikel",
"hist_looks_complete": "zaključen",
"peak_power_short": "Vrh",
"shape": "Oblika",
"hist_skip_idle": "nič ni delovalo",
"hist_skip_sparse": "odčitki preveč oddaljeni med seboj",
"hist_skip_short": "premalo odčitkov",
"hist_skip_long": "ni dovolj dolgega premora za razdelitev",
"hist_reason_short": "krajši od najkrajšega resničnega cikla te naprave",
"hist_reason_no_end": "se ni nikoli pravilno končal",
"hist_since": "Od",
"task_history_import": "Pregledovanje zgodovine moči",
"task_history_import_apply": "Uvažanje ciklov",
"evidence_real_cycles": "Cikli, ki jih je izvedla ta naprava",
"evidence_reference_cycles": "Preneseni iz skupnostne trgovine",
"evidence_backfill_cycles": "Najdeni v uvoženi zgodovini moči"
},
"log": {
"all_levels": "Vse ravni",
@@ -756,9 +785,15 @@
"store_share": "Deli v skupnostno trgovino",
"store_share_device": "Deli nastavitve naprave",
"export_select": "Izvoz - izberi podatke",
"import_wizard": "Uvoz - izberi podatke"
"import_wizard": "Uvoz - izberi podatke",
"history_import": "Uvoz zgodovine moči"
},
"msg": {
"tail_trim_hint": "Odstranite toliko sekund s konca",
"store_sibling_hint": "Za vaš točni model ni nič deljenega? Tesno soroden model iste znamke je običajno dobro izhodišče.",
"store_declare_appliance": "Povejte integraciji WashData, katero napravo imate, in ta zavihek bo prikazal konfiguracije, ki so jih zanjo delili drugi. Zgoraj lahko tudi vpišete znamko in pregledate katalog.",
"refresh_catalog_hint": "Seznama znamk in naprav skupnosti sta shranjena v predpomnilniku, da skupnostna trgovina ostane v okviru svoje dnevne omejitve. Osvežite, da prevzamete vnose, ki so jih dodali ali odobrili drugi.",
"head_trim_hint": "Odstranite toliko sekund z začetka",
"appliance_monitor": "Monitor naprave",
"artifact_dip_detail": "Padel pod normalni pas moči za ~{n} s.",
"artifact_footer": "Označeno na zgornjem grafu. To so prehodni artefakti (npr. vrata so se odprla sredi cikla), ne pa nujno težave.",
@@ -769,7 +804,7 @@
"automations_intro": "WashData sproži dogodke {start} / {end} in razkrije entitete, zato je obvestila in dejanja najbolje graditi kot navadne avtomatizacije Home Assistant. Spodaj so prikazane avtomatizacije, ki uporabljajo to napravo.",
"cleanup_intro": "Vsi označeni cikli naloženi. Označi odmike in briši za čiščenje profila.",
"clear_debug_hint": "Odstranite shranjene podatke za odpravljanje napak, da sprostite prostor.",
"collecting_data": "Zbiranje podatkov: še {need} ciklov pred začetkom finega nastavljanja ({current}/{min}).",
"collecting_data": "Zbiranje podatkov. Še potrebnih ciklov pred začetkom natančnega prilagajanja: {need} ({current}/{min}).",
"compare_overlay_profiles": "Prekriti profili (bledi)",
"compare_profiles_tip": "Prekrijte druge ovojnice profila na zgornji tabeli, da vidite, katera najbolj ustreza temu ciklu.",
"compare_selected_cycles": "Izbrani cikli (polni) prikaži / skrij",
@@ -779,7 +814,7 @@
"cycles_deleted": "Izbrisanih ciklov: {count}",
"enough_data": "Dovolj podatkov za učenje ({current}/{min} ciklov).",
"export_description": "Izberite natančno, katere profile, cikle, nastavitve in drugo želite izvoziti v datoteko JSON, ali analizirajte datoteko in uvozite samo želene dele.",
"feedback_cycles_pending": "{n} ciklov za pregled",
"feedback_cycles_pending": "Za pregled: {n}",
"feedback_prompt": "Potrdite pravilnost, popravite program ali prezrite.",
"feedback_relabel_hint": "Ponovno označevanje tega cikla ga prav tako razreši.",
"filter_by_profile": "Filtriraj po profilu…",
@@ -856,7 +891,6 @@
"pg_stress_synthetic": "simulacija mirovanja se začne tukaj",
"pg_sweep_intro": "Kaj če bi bil {param} drugačen? Preizkusite {steps} vrednosti na svojih zadnjih {cycles} ciklih in poiščite nastavitev, pri kateri se pravilno ujema največ ciklov.",
"pg_sweep_step": "Korak {done} / {total}",
"pg_undetected": "{n} nezaznanih ciklov",
"pg_verdict_bad": "Zahteva pozornost: veliko ciklov ostaja nezaznanih.",
"pg_verdict_good": "Dobro nastavljeno: večina ciklov je pravilno prepoznanih in ujemanih.",
"pg_verdict_ok": "Sprejemljivo: nekateri cikli so bili spregledani. Poskusite znižati prag zagona.",
@@ -888,6 +922,7 @@
"review_recorded_tip": "Označite to kot ročno izbran referenčni cikel za svoj program enaka vloga kot ročno posnet cikel. Referenčni cikli so vedno shranjeni, zasejejo ujemajočo se predlogo in se nikoli ne izbrišejo s čiščenjem. (To je zlata/posneta zastava; obe sta enaki.)",
"review_tags_tip": "Neobvezne zastavice, ki opisujejo, kaj je šlo narobe s tem ciklom, tako da lahko to pojasnita usposabljanje in čiščenje.",
"review_to_cycles": "Odpri čakalno vrsto pregleda ciklov",
"samples_decimated": "Prikazanih {shown} od {total} vzorcev (razredčeno za prikaz; konice ohranjene). Široka vrzel tukaj pomeni razredčitev, ne manjkajočih podatkov.",
"saving_triggers_reload": "Shranjevanje sproži ponovni zagon integracije. Entitete HA se lahko za kratek čas prikažejo kot nedostopne.",
"search_placeholder": "Iskanje nastavitev…",
"see_recorder": "Glejte pripomoček za snemanje spodaj",
@@ -991,12 +1026,12 @@
"share_consent": "Delite dejanske podatke svojega aparata. Ne delite, če so vaši vzorci uporabe zasebni.",
"share_device_none": "Še ni nastavljenih naprav. Najprej dodajte napravo.",
"share_guideline_naming": "Uporabite jasna imena programov (npr. 'Cotton 40', 'Eco 60'), da jih drugi lažje prepoznajo",
"share_guideline_quality": "Delite samo profile z ⭐ referenčnimi cikli ali vsaj {n} potrjenimi zagoni",
"share_guideline_quality": "Delite samo cikle, ki so se normalno zaključili -- brez prekinitev sredi cikla, odpiranja vrat ali nihanj napajanja.",
"share_guideline_review": "Preglejte profile pred deljenjem -- odstranite tiste, ki izgledajo napačni",
"share_guidelines_title": "Pred deljenjem",
"store_download_device_intro": "Prenesi nastavitve skupnostne naprave in jih uporabi za novo ali obstoječo napravo",
"store_share_device_intro": "Deli programe svoje naprave (profile + referenčne cikle) s skupnostjo. Nastavitve so neobvezne.",
"share_profile_no_cycles": "Profil '{p}' nima ⭐ referenčnih ciklov -- preskočen bo, razen če imate {n}+ potrjenih zagonov",
"store_share_device_intro": "Naložite {brand} {model} z referenčnimi cikli, ki jih izberete. Drugi z enako napravo lahko prevzamejo vaše programe. Vnosi so pregledani pred javno objavo.",
"share_profile_no_cycles": "Ni referenčnih ciklov - označite cikel z ⭐ v zavihku Cikli, da vključite ta profil",
"advisory_phase_inconsistent": "Videti je, da '{name}' meša različne programe ali temperature - njegovi cikli se segrevajo zelo različno dolgo. Če ga razdelite na ločene profile (npr. po temperaturi), boste izboljšali ujemanje in ocene časa.",
"advisory_phase_inconsistent_title": "⚠ Morda pomešani programi",
"export_select_intro": "Označite natančno, kaj naj bo vključeno. Izbira profilov brez njihovih ciklov še vedno izvozi prepoznaven program (njegova naučena oblika se prenese z njim).",
@@ -1006,7 +1041,29 @@
"merge_hint": "Uvoženi elementi se dodajo; nič lokalnega se ne izgubi. Spori imen se rešujejo spodaj.",
"replace_warn": "Vsaka označena kategorija se izbriše in zamenja s podatki iz datoteke. Neoznačene kategorije ostanejo nespremenjene.",
"dest_reference_hint": "Uvoženi cikli le izboljšajo prepoznavanje programov in nikoli ne vplivajo na statistiko porabe/energije.",
"dest_real_history_hint": "Uvoženi cikli se štejejo kot lastna zgodovina te naprave in napajajo statistiko energije/porabe. Uporabite pri prenosu ene naprave na novo namestitev."
"dest_real_history_hint": "Uvoženi cikli se štejejo kot lastna zgodovina te naprave in napajajo statistiko energije/porabe. Uporabite pri prenosu ene naprave na novo namestitev.",
"import_history_description": "Ste pametni vtič uporabljali že pred WashData? Naložite izvoz zgodovine njegovega senzorja moči ali jo preberite neposredno iz Home Assistant in nad njo se izvede običajno zaznavanje, tako da se pretekli cikli pojavijo v vašem seznamu Cikli, pripravljeni za poimenovanje.",
"hist_input_hint": "Naložite CSV, prenesen iz plošče Zgodovina (entiteta, stanje, zadnja sprememba), ali pustite, da WashData prebere zgodovino senzorja neposredno. Zaznavanje nato poteka povsem enako kot v živo, vi pa izberete, katere najdene cikle boste ohranili.",
"hist_recorder_hint": "Bere podatke od izbranega datuma do zdaj. Home Assistant privzeto hrani podrobno zgodovino 10 dni, po tem pa le urna povprečja, ki so za zaznavanje ciklov preveč groba - zgodnejši datum izberite samo, če je vaš recorder nastavljen na daljše hranjenje.",
"hist_scanning": "Vašo zgodovino predvajamo skozi zaznavalnik. To poteka v ozadju - to pogovorno okno lahko zaprete in se vrnete pozneje.",
"hist_imported_count": "Uvoženi cikli: {n}.",
"hist_duplicates": "Že prej uvoženo in preskočeno: {n}.",
"hist_capped": "Dosežena je bila omejitev uvoženih ciklov na napravo; ostali niso bili shranjeni.",
"hist_next_step": "So v vašem seznamu Cikli, označeni kot uvožena zgodovina. Odprite enega in z gumbom Označi poimenujte program, ki mu pripada.",
"hist_rows_read": "Prebrani odčitki: {n}",
"hist_breaks": "Vrzeli, ko senzor ni bil dosegljiv: {n}",
"hist_other_entity": "Prezrti odčitki drugih entitet: {n}",
"hist_entity_substituted": "Prebrano {used} (ta naprava je nastavljena na {wanted})",
"hist_skipped_spans": "Preskočeni odseki",
"hist_settings_used": "Zaznano s trenutnimi nastavitvami te naprave (minimalna moč {w} W, zamuda izklopa {s} s).",
"hist_none_found": "V tej zgodovini ni bilo mogoče zaznati nobenega cikla.",
"hist_found": "Najdeni cikli: {n}. Odstranite kljukico pri vsem, kar ni videti kot resničen zagon - nič ni shranjeno, dokler ne uvozite.",
"hist_scan_capped": "Prikazani so samo prvi kandidati (najdenih je bilo {n}).",
"hist_recorder_empty": "Home Assistant za ta senzor v tem obdobju nima podrobne zgodovine.",
"hist_scan_failed": "Pregledovanje ni uspelo.",
"hist_scan_expired": "Ta pregled ni več na voljo. Zaženite ga znova.",
"hist_import_failed": "Uvoz ni uspel.",
"imported_history_readonly": "Zaznano v uvoženi zgodovini moči. Vpliva na ujemanje programov, ne šteje pa se v vašo statistiko in ga ni mogoče obrezati ali razdeliti. Označite ga, da mu določite program."
},
"phase_desc": {
"anti_crease": "Občasni kratki premiki po zaključku za preprečevanje gub na oblačilih.",
@@ -1377,7 +1434,7 @@
"label": "Zamuda ponastavitve napredka"
},
"pump_stuck_duration": {
"doc": "Nekaj sekund lahko črpalka deluje neprekinjeno, preden je označena kot morebitna zastoj (sproži dogodek zastoja črpalke).",
"doc": "Nekaj sekund lahko črpalka deluje neprekinjeno, preden je označena kot morebitna zastoj (sproži dogodek zastoja črpalke).",
"label": "Trajanje zataknjenosti črpalke"
},
"running_dead_zone": {
@@ -1392,6 +1449,10 @@
"doc": "Shranite celotno sled moči in ustrezne podatke o odpravljanju napak za vsak cikel. Uporabno za odpravljanje težav, vendar poveča velikost pomnilnika.",
"label": "Shrani sledove za odpravljanje napak"
},
"smart_termination_duration_ratio": {
"doc": "Kako daleč v pričakovanem trajanju ujemajočega programa mora biti cikel, preden ga Pametni zaključek lahko po padcu moči predčasno konča. Pričakovano trajanje je povprečje programa, zato se pri napravah, katerih čas delovanja močno niha - pralni stroji s hladno dovodno vodo pozimi v primerjavi s toplo poleti, sušilni stroji s senzorskim sušenjem, programi, odvisni od količine perila - približno polovica vseh zagonov konča prej kot to povprečje in nikoli ne dobi hitrega zaključka, temveč se konča šele prek nadomestnega časovnega zamika, nekaj minut prepozno. Pri takih strojih to vrednost znižajte (npr. 0,85), da se predčasni zaključek vseeno sproži; za bolj konservativno delovanje jo zvišajte proti 1,0. Pustite prazno za privzeto vrednost (0,98 ali 0,99 za pomivalne stroje). Cikel lahko vedno le predčasno konča, nikoli pozneje, in se nikoli ne sproži pri nejasnem ujemanju ali ujemanju z nizko zanesljivostjo.",
"label": "Razmerje pametnega zaključka"
},
"smoothing_window": {
"doc": "Koliko je zglajen signal neobdelane moči. Nizka (2) je odzivna, a hrupna; visoko (5) zgladi konice, vendar doda zamik.",
"label": "Okno glajenja"
@@ -1522,6 +1583,10 @@
"door_end_dwell_seconds": {
"label": "Čas odprtosti vrat za zaključek",
"doc": "Kako dolgo morajo vrata ostati odprta, preden WashData zaključi cikel, ko je vklopljeno \"Vrata se ob koncu samodejno odprejo\". Dovolj dolgo, da se prezre hitro dodajanje posode (privzeto 60 s), dovolj kratko za hiter zaključek, ko stroj odpre vrata."
},
"profile_evidence_sources": {
"label": "Cikli, ki oblikujejo program",
"doc": "Kateri cikli se uporabijo za izgradnjo krivulje moči vsakega programa in za ujemanje zaključenega cikla z njo. Če neko vrsto odkljukate, ta ne vpliva več na vaše programe, vendar se nič ne izbriše - cikli ostanejo na seznamu Cikli in jih je še vedno mogoče označiti ali odstraniti. Uporabno, če uvoženim podatkom ne zaupate. Na statistiko to ne vpliva: vedno šteje samo cikle, ki jih je ta naprava res izvedla. Če odkljukate vse, se to prezre, saj se program brez ciklov nikoli ne bi mogel ujemati."
}
},
"setting_group": {
@@ -1605,6 +1670,9 @@
},
"basic_configuration": {
"label": "Osnovna konfiguracija"
},
"profile_evidence": {
"label": "Podlaga profila"
}
},
"status": {
@@ -1629,7 +1697,8 @@
"trimming": "Obrezovanje…",
"splitting": "Deljenje…",
"deleting": "Brisanje…",
"imported": "Uvoženo"
"imported": "Uvoženo",
"preparing": "Pripravljanje…"
},
"suggestion": {
"both_agree": "WashData priporoča",
@@ -1725,7 +1794,7 @@
"thr_batch": "Ohranjeno tik nad najnižjo delovno močjo p05 čez {cycles} ciklov ({p05}W), da se začetek zazna čim prej in da prag ustavitve ostane pod najnižjo delovno močjo naprave.",
"tol_per_profile": "p75 variance trajanja po posameznih profilih čez {profiles} profilov ({cycles} ciklov); dosledni profili niso kaznovani.",
"tol_pooled": "Na podlagi združene variance trajanja {cycles} nedavnih označenih ciklov (p95 odklon={dev}).",
"watchdog": "Ohranjeno tako nizko, kot je varno (tik nad vrzeljo posodobitve p95 {p95}s, najmanj 30s), da se zastoji hitro zaznajo brez lažnih ustavitev."
"watchdog": "Ohranjeno tako nizko, kot je varno (tik nad vrzeljo posodobitve p95 {p95}s in vsaj 2× interval vzorčenja {median}s, najmanj 30s), da se zastoji hitro zaznajo brez lažnih ustavitev."
},
"exclusions": {
"summary": "Izključeno {total} napačno zaznanih ciklov: {parts}.",
@@ -1772,6 +1841,7 @@
"wrong_profile": "Napačen profil"
},
"toast": {
"catalog_refreshed": "Katalog skupnosti je osvežen",
"access_saved": "Nadzor dostopa shranjen",
"all_wiped": "Vsi podatki izbrisani",
"analysis_complete_none": "Analiza zaključena: ni novih predlogov",
@@ -1865,19 +1935,21 @@
"rating_saved": "Ocena kakovosti shranjena",
"brand_added": "Znamka dodana, čaka na odobritev",
"profile_added": "Profil dodan, čaka na odobritev",
"saved_except_conflicts": "Nastavitve shranjene -- {n} nastavitev{s} preskočena zaradi konfliktov",
"saved_except_conflicts": "Shranjeno. Popravite označene konflikte, da shranite še ostalo.",
"share_device_none_sel": "Izberite vsaj en program za deljenje",
"store_device_downloaded": "Nastavitve naprave prenesene: {created} profil{c} ustvarjen, {dup} že obstaja",
"store_device_downloaded_phases": "Nastavitve naprave prenesene: {created} profil{c} ustvarjen, {dup} že obstaja, fazna karta uporabljena",
"store_device_downloaded_settings": "Nastavitve naprave prenesene: {created} profil{c} ustvarjen, {dup} že obstaja, nastavitve uporabljene",
"store_device_shared": "Nastavitve naprave deljene: {n} program{s} naložen",
"store_device_shared_all_dup": "Nič novega za deljenje -- vsi programi že obstajajo v trgovini",
"store_device_shared_partial": "Delno deljenje: {n} program{s} naložen, {failed} preskočenih",
"store_device_shared_some_dup": "Nastavitve naprave deljene: {n} program{s} naložen ({dup} že obstaja)",
"store_device_downloaded": "Dodano: programi {p}, posnetki {c}",
"store_device_downloaded_phases": "Dodano: programi {p}, posnetki {c}, fazne karte {ph}",
"store_device_downloaded_settings": "Dodano: programi {p}, posnetki {c}, fazne karte {ph}, nastavitve {s}",
"store_device_shared": "Cikli, deljeni v skupnostno trgovino: {n}. Čaka na pregled.",
"store_device_shared_all_dup": "Vsi cikli ({n}) so bili že v skupnostni trgovini.",
"store_device_shared_partial": "Deljeni cikli: {n}; ni bilo mogoče naložiti: {failed}.",
"store_device_shared_some_dup": "Deljeni cikli: {created}; že v trgovini: {dup}.",
"store_download_failed": "Prenos ni uspel: {error}",
"store_download_nothing": "Ni ničesar za prenos -- vsi profili že obstajajo na tej napravi",
"export_selective_done": "Izvoz prenesen",
"import_selective_done": "Uvoženih {profiles} profilov in {cycles} ciklov"
"import_selective_done": "Uvoženih {profiles} profilov in {cycles} ciklov",
"hist_csv_required": "Najprej naložite datoteko CSV ali prilepite njeno vsebino",
"file_read_failed": "Te datoteke ni bilo mogoče prebrati"
},
"trend": {
"down": "Padajoči trend",
@@ -1892,6 +1964,7 @@
},
"pg_desc": {
"dishwasher_end_spike_quiet_release": "Pomivalni stroj: sekunde tišine po pričakovanem trajanju, preden se sprosti čakanje na končno izčrpavanje vode",
"smart_termination_duration_ratio": "Delež pričakovanega trajanja ujemajočega programa, ki ga mora cikel doseči, preden ga Pametni zaključek lahko predčasno konča; znižajte ga pri strojih, odvisnih od količine perila ali temperature",
"anti_wrinkle_enabled": "Vsrkaj vrtilne impulze po glavni fazi, namesto da jih obravnavaš kot nove cikle",
"anti_wrinkle_exit_power": "Moč mora med impulzi pasti pod to vrednost, da zaščita pred gubami ostane aktivna",
"anti_wrinkle_idle_timeout": "Dovoljeni mir med dvema vrtilnima impulzoma, preden se zaščita pred gubami konča",
@@ -1955,6 +2028,10 @@
"finished": "Cikel je dosegel končno stanje in se je končal."
},
"store": {
"your_model_tip": "To je naprava, ki ste jo navedli v Nastavitvah",
"your_model": "Vaša",
"search_brand_ph": "Iskanje po znamki…",
"programs_count": "Programi: {n}",
"browse": "Brskaj",
"device": "Naprava",
"favorites": "Priljubljeni",
@@ -78,9 +78,12 @@
"awaiting": "Në pritje të miratimit",
"imported_tip": "Importuar nga dyqani i komunitetit. Përdoret vetëm për përputhje, nuk llogaritet në statistika.",
"not_importable": "s'aplikohet këtu",
"exists": "ekziston"
"exists": "ekziston",
"backfilled_tip": "Zbuluar në historikun e importuar të fuqisë. Ndikon vetëm në përputhjen e programeve, nuk llogaritet në statistika."
},
"btn": {
"set_brand_model": "Cakto markën dhe modelin",
"refresh_catalog": "Rifresko katalogun",
"add_device": "+ Shto pajisje",
"add_device_tip": "Shto një pajisje tjetër WashData",
"add_maintenance": "Shto ngjarje mirëmbajtjeje",
@@ -209,8 +212,8 @@
"stop": "Ndalo",
"submit_correction": "Dërgo korrigjimin",
"train_now": "Trajno tani",
"trim": "Priti",
"trim_split": "Priti / Ndaj",
"trim": "Prerje",
"trim_split": "Prerje / Ndarje",
"undo": "Zhbëj",
"use": "Përdor",
"wipe_all": "Fshi të gjitha të dhënat",
@@ -241,7 +244,12 @@
"import_selected": "Importo të zgjedhurat",
"back": "Prapa",
"mute_suggestion": "Mos e sugjeroni këtë cilësim",
"reset_muted": "Rivendos të heshturat"
"reset_muted": "Rivendos të heshturat",
"import_power_history": "Importo historikun e fuqisë",
"hist_read_recorder": "Lexo nga Home Assistant",
"hist_scan": "Kërko cikle",
"hist_import_n": "Importo {n} cikle",
"hist_goto_cycles": "Shfaq ciklet"
},
"conflict": {
"anti_wrinkle_exit": {
@@ -253,12 +261,12 @@
"start": "Duhet të jetë nën Fuqinë Maks. Kundër Rrudhave ({max} W)"
},
"attn_sub": "Rregulloni konfliktet para se të ruani",
"attn_title": "{n} konflikt{s} cilësimi",
"attn_title": "Konflikte cilësimesh: {n}",
"confidence": {
"auto": "Duhet të jetë në ose mbi Pragun e Përputhjes ({match})",
"learning": "Duhet të jetë në ose nën Pragun e Përputhjes ({match})",
"learning": "Duhet të jetë në ose mbi Pragun e Përputhjes ({match})",
"match_for_auto": "Duhet të jetë në ose nën Besueshmërinë e Etiketimit Automatik ({alc})",
"match_for_learning": "Duhet të jetë në ose mbi Besueshmërinë e të Mësuarit ({lc})"
"match_for_learning": "Duhet të jetë në ose nën Besueshmërinë e të Mësuarit ({lc})"
},
"duration_ratio": {
"max": "Duhet të jetë më i madh se Raporti Min. i Kohëzgjatjes ({min})",
@@ -296,14 +304,14 @@
"match": "Duhet të jetë mbi Pragun e Mosperputhjeve ({un})",
"unmatch": "Duhet të jetë nën Pragun e Përputhjes ({match}); përndryshe një përputhje e konfirmuar zhbëhet menjëherë"
},
"cascade_toast": "U rregulluan edhe {n} cilësim{s} për konsistencë.",
"cascade_toast": "Cilësime të tjera të rregulluara për konsistencë: {n}",
"suggestion_resolves": "Zbato sugjerimin e pritshëm ({val}) më poshtë për ta rregulluar këtë",
"use_fix": "Përdor {val}",
"watchdog": {
"interval": "Duhet të jetë të paktën 2× Intervali i Kampionimit ({si} s)",
"sampling": "Intervali i Kampionimit duhet të jetë të paktën gjysma e Intervalit të Rojtarit ({wi} s)"
},
"settings_banner": "{n} konflikt{s} cilësimi kontrolloni seksionet e theksuara dhe korrigjojini para ruajtjes.",
"settings_banner": "Konflikte cilësimesh: {n}. Kontrolloni seksionet e theksuara dhe korrigjojini para ruajtjes.",
"settings_banner_btn": "Shko te i pari"
},
"hdr": {
@@ -356,7 +364,8 @@
"pg_outcome": "Rezultati i simulimit",
"pg_across_cycles": "Në të gjithë ciklet tuaja",
"community_store": "Dyqani i Komunitetit",
"online_account": "Dyqani i Komunitetit dhe veçoritë online"
"online_account": "Dyqani i Komunitetit dhe veçoritë online",
"import_power_history": "Importo historikun e fuqisë"
},
"health": {
"fair": "Cilësi e pranueshme e profilit",
@@ -364,6 +373,7 @@
"poor": "⚠ Cilësi e keqe e profilit"
},
"lbl": {
"drag_to_resize": "Tërhiqni për të ndryshuar madhësinë",
"actions": "Veprime",
"activity": "Aktivitet",
"administrators": "Administratorë",
@@ -434,7 +444,7 @@
"from": "Nga",
"gap_s": "Ndërrimi (s)",
"group_name": "Emri i grupit",
"head_trim": "Prerja e kreut (s)",
"head_trim": "Prerje në fillim (s)",
"health": "Shëndeti",
"hide_tabs": "Fshih skedat për jo-administratorët",
"in_use": "Në përdorim",
@@ -450,7 +460,7 @@
"metric": "Metrika",
"mode_existing_profile": "Shto te profili ekzistues",
"mode_new_profile": "Krijo profil të ri",
"models_fine_tuned": "({count} model{plural} të sintonizuar)",
"models_fine_tuned": "(modele të rregulluara mirë: {count})",
"n_classic_suggestions": "{n} klasike",
"n_ml_suggestions": "{n} ML",
"n_selected": "{n} të zgjedhura",
@@ -532,7 +542,7 @@
"stage3": "Etapa 3 DTW",
"stage4": "Etapa 4 përputhja",
"status": "Statusi",
"tail_trim": "Prerja e fundit (s)",
"tail_trim": "Prerje në fund (s)",
"timer_auto_pause": "Auto-pauzë",
"timer_min": "min",
"timer_msg_placeholder": "Mesazh (opsionale, {device}/{program}/{minutes})",
@@ -677,7 +687,26 @@
"conflict_import_copy": "Importo si kopje",
"conflict_keep_mine": "Mba të miat",
"conflict_overwrite": "Mbishkruaj",
"font_size": "Madhësia e shkronjave të panelit"
"font_size": "Madhësia e shkronjave të panelit",
"hist_csv_data": "Të dhëna CSV",
"hist_from_recorder": "Ose lexoje nga Home Assistant",
"hist_since": "Që nga",
"days": "ditë",
"hist_keep": "Mbaje këtë cikël",
"hist_looks_complete": "i plotë",
"peak_power_short": "Kulmi",
"shape": "Forma",
"hist_skip_idle": "asgjë në punë",
"hist_skip_sparse": "lexime shumë të shpërndara",
"hist_skip_short": "shumë pak lexime",
"hist_skip_long": "nuk ka pushim aq të gjatë sa të ndahet",
"hist_reason_short": "më i shkurtër se cikli real më i shkurtër i kësaj pajisjeje",
"hist_reason_no_end": "nuk përfundoi kurrë si duhet",
"task_history_import": "Skanim i historikut të fuqisë",
"task_history_import_apply": "Importim i cikleve",
"evidence_real_cycles": "Ciklet që kreu kjo makinë",
"evidence_reference_cycles": "Shkarkuar nga dyqani i komunitetit",
"evidence_backfill_cycles": "Gjetur në historikun e importuar të fuqisë"
},
"log": {
"all_levels": "Të gjitha nivelet",
@@ -756,9 +785,15 @@
"store_share": "Ndaj në dyqanin e komunitetit",
"store_share_device": "Ndaj këtë pajisje",
"export_select": "Eksporto - zgjidh të dhënat",
"import_wizard": "Importo - zgjidh të dhënat"
"import_wizard": "Importo - zgjidh të dhënat",
"history_import": "Importo historikun e fuqisë"
},
"msg": {
"tail_trim_hint": "Hiqni kaq sekonda nga fundi",
"store_sibling_hint": "Nuk ka asgjë të ndarë për modelin tuaj të saktë? Një model i afërt i të njëjtës markë është zakonisht një pikënisje e mirë.",
"store_declare_appliance": "Përcaktoni në WashData pajisjen që zotëroni dhe kjo skedë shfaq konfigurimet që të tjerët kanë ndarë për të. Mund edhe të shkruani një markë më lart për t'i hedhur një sy katalogut.",
"refresh_catalog_hint": "Listat e markave dhe pajisjeve të komunitetit mbahen në kujtesën e përkohshme, që dyqani i komunitetit të mbetet brenda kufirit të tij ditor. Rifreskoni për të marrë hyrjet e shtuara ose të miratuara nga të tjerët.",
"head_trim_hint": "Hiqni kaq sekonda nga fillimi",
"appliance_monitor": "Monitor i pajisjes",
"artifact_dip_detail": "Ra nën brezin e zakonshëm të fuqisë për ~{n} s.",
"artifact_footer": "E theksuar në grafikun e mësipërm. Këto janë objekte kalimtare (p.sh. dera e hapur në mes të ciklit), jo domosdoshmërisht probleme.",
@@ -769,7 +804,7 @@
"automations_intro": "WashData ndez ngjarje {start} / {end} dhe ekspozon entitete, kështu njoftimet dhe veprimet ndërtohen më mirë si automatizime normale të Home Assistant. Automatizimi që përdorin këtë pajisje shfaqen më poshtë.",
"cleanup_intro": "Çdo cikël i etiketuar mbivendosur. Shëno outlier-ët dhe fshi për të pastruar profilin.",
"clear_debug_hint": "Hiqni të dhënat e ruajtura të korrigjimit për të liruar hapësirën.",
"collecting_data": "Duke mbledhur të dhëna: nevojiten edhe {need} cikël{plural} para se të fillojë sintonizimi i imët ({current}/{min}).",
"collecting_data": "Duke mbledhur të dhëna. Cikle që nevojiten para se të fillojë rregullimi i hollë: {need} ({current}/{min}).",
"compare_overlay_profiles": "Mbivendos profilet (të zbetura)",
"compare_profiles_tip": "Mbivendosni zarfat e tjerë të profileve në grafikun e mësipërm për të parë se cili i përshtatet më mirë këtij cikli.",
"compare_selected_cycles": "Ciklet e zgjedhura (solide) shfaq / fshih",
@@ -779,7 +814,7 @@
"cycles_deleted": "{count} cikël(e) u fshinë",
"enough_data": "Të dhëna të mjaftueshme për të mësuar ({current}/{min} cikle).",
"export_description": "Zgjidhni saktësisht cilat profile, cikle, cilësime dhe të tjera do të eksportohen në JSON, ose analizoni një skedar dhe importoni vetëm pjesët që dëshironi.",
"feedback_cycles_pending": "{n} cikël{s} për rishikim",
"feedback_cycles_pending": "Për rishikim: {n}",
"feedback_prompt": "Konfirmo nëse ishte i saktë, korrigjo programin ose injorojë.",
"feedback_relabel_hint": "Rietiketimi i këtij cikli e zgjidh atë gjithashtu.",
"filter_by_profile": "Filtro sipas profilit…",
@@ -856,7 +891,6 @@
"pg_stress_synthetic": "simulimi i gjendjes statike fillon këtu",
"pg_sweep_intro": "Po sikur {param} të ishte ndryshe? Testoni {steps} vlera në {cycles} ciklet tuaja të fundit për të gjetur cilësimin ku përputhen saktë sa më shumë cikle.",
"pg_sweep_step": "Hapi {done} / {total}",
"pg_undetected": "{n} cikël{s} të pazbuluar",
"pg_verdict_bad": "Kërkon vëmendje: shumë cikle mbeten të pazbuluara.",
"pg_verdict_good": "Rregulluar mirë: shumica e cikleve identifikohen dhe përputhen saktë.",
"pg_verdict_ok": "I pranueshëm: disa cikle munguan. Provoni të ulni pragun e fillimit.",
@@ -887,6 +921,7 @@
"review_recorded_tip": "Shënojeni këtë si një cikël referimi të zgjedhur vetë për programin e tij - i njëjti rol si një cikël i regjistruar manualisht. Ciklet e referencës mbahen gjithmonë, vendosin shabllonin që përputhet dhe nuk hiqen kurrë nga pastrimi. (Ky është flamuri \"i artë\"/regjistruar; të dy janë e njëjta gjë.)",
"review_tags_tip": "Flamujt opsionalë që përshkruajnë atë që shkoi keq me këtë cikël, kështu që trajnimi dhe pastrimi mund të jenë përgjegjës për këtë.",
"review_to_cycles": "Hap radhën e rishikimit të Cikleve",
"samples_decimated": "Duke shfaqur {shown} nga {total} kampione (të holluara për shfaqje; kulmet janë ruajtur). Një hapësirë e gjerë këtu është hollim, jo të dhëna që mungojnë.",
"saving_triggers_reload": "Ruajtja aktivizon ringarkimin e integrimit. Njësitë HA mund të shfaqen shkurtimisht si të padisponueshme.",
"search_placeholder": "Kërko cilësime…",
"see_recorder": "Shiko veglën e regjistruesit më poshtë",
@@ -1006,7 +1041,29 @@
"sug_mute_failed": "Nuk mund të heshtte sugjerimi",
"sug_unmuted_all": "Sugjerime të heshtura u rivendosën",
"n_suggestions_muted": "{count} të heshtura; motori i sugjerimeve nuk do t'i propozojë këto.",
"font_size_hint": "Bëni gjithçka në këtë panel më të madhe ose më të vogël. Aplikohet për llogarinë tuaj në këtë pajisje."
"font_size_hint": "Bëni gjithçka në këtë panel më të madhe ose më të vogël. Aplikohet për llogarinë tuaj në këtë pajisje.",
"import_history_description": "Kishit priz inteligjent edhe përpara WashData? Ngarkoni një eksport të historikut të sensorit të fuqisë, ose lexojeni drejtpërdrejt nga Home Assistant, dhe zbulimi i zakonshëm kalon mbi të, kështu ciklet e kaluara shfaqen në listën e Cikleve, gati për t'u emërtuar.",
"hist_input_hint": "Ngarkoni një CSV të shkarkuar nga paneli i Historikut (entity, state, last changed), ose lini WashData t'i lexojë drejtpërdrejt historikun e sensorit. Më pas zbulimi kalon mbi të saktësisht si në kohë reale, dhe ju zgjidhni cilat nga ciklet e gjetura do të mbani.",
"hist_recorder_hint": "Lexon nga data që zgjidhni deri tani. Home Assistant mban historik të detajuar për 10 ditë si parazgjedhje dhe vetëm mesatare orare më pas, të cilat janë tepër të përafërta për të zbuluar cikle - zgjidhni një datë më të hershme vetëm nëse recorder është konfiguruar të mbajë më shumë.",
"hist_scanning": "Historiku po riluhet përmes zbuluesit. Kjo ekzekutohet në sfond - mund ta mbyllni këtë dritare dhe të ktheheni më vonë.",
"hist_imported_count": "{n} cikle u importuan.",
"hist_duplicates": "{n} ishin importuar më parë dhe u anashkaluan.",
"hist_capped": "U arrit kufiri i cikleve të importuara për pajisje; pjesa tjetër nuk u ruajt.",
"hist_next_step": "Ndodhen në listën e Cikleve, të shënuara si historik i importuar. Hapni një dhe përdorni Etiketoje për të emërtuar programin të cilit i përket.",
"hist_rows_read": "U lexuan {n} lexime",
"hist_entity_substituted": "u lexua {used} (kjo pajisje është konfiguruar për {wanted})",
"hist_breaks": "{n} boshllëqe ku sensori nuk ishte i disponueshëm",
"hist_other_entity": "{n} lexime për entitete të tjera u shpërfillën",
"hist_skipped_spans": "Intervale të anashkaluara",
"hist_settings_used": "Zbuluar me cilësimet aktuale të kësaj pajisjeje (fuqia minimale {w} W, vonesë fikjeje {s} s).",
"hist_none_found": "Në atë historik nuk u zbulua asnjë cikël.",
"hist_found": "U gjetën {n} cikle. Hiqni shenjën nga çdo gjë që nuk ngjan me një punë reale - asgjë nuk ruhet derisa të importoni.",
"hist_scan_capped": "Shfaqen vetëm kandidatët e parë (u gjetën {n}).",
"hist_recorder_empty": "Home Assistant nuk ka historik të detajuar për këtë sensor në atë periudhë.",
"hist_scan_failed": "Skanimi dështoi.",
"hist_scan_expired": "Ai skanim nuk është më i disponueshëm. Skanoni përsëri.",
"hist_import_failed": "Importimi dështoi.",
"imported_history_readonly": "Zbuluar në historikun e importuar të fuqisë. Ndikon në përputhjen e programeve, por nuk llogaritet në statistikat tuaja dhe nuk mund të shkurtohet ose të ndahet. Etiketojeni për të emërtuar programin."
},
"phase_desc": {
"anti_crease": "Rrotullime të shkurtra të herëpashershme pas përfundimit për të reduktuar rrudhat.",
@@ -1467,6 +1524,10 @@
"show_contributor": {
"doc": "Shfaq atribuimin \"nga <kontribuesi>\" në pajisjet dhe ciklet referuese të komunitetit."
},
"smart_termination_duration_ratio": {
"doc": "Sa larg brenda kohëzgjatjes së pritur të programit të përputhur duhet të ketë ecur një cikël përpara se Përfundimi i Zgjuar të mund ta mbyllë atë herët sapo bie fuqia. Kohëzgjatja e pritur është mesatarja e programit, prandaj te pajisjet kohëzgjatja e të cilave ndryshon shumë - makinat larëse me ujë hyrës të ftohtë në dimër dhe të ngrohtë në verë, tharëset me sensor lagështie, programet që varen nga ngarkesa - rreth gjysma e të gjitha nisjeve përfundojnë më shkurt se ajo mesatare dhe nuk e marrin kurrë përfundimin e shpejtë, duke mbaruar vetëm përmes afatit rezervë me disa minuta vonesë. Uleni këtë vlerë (p.sh. 0.85) te këto makina që përfundimi i hershëm të aktivizohet gjithsesi; ngrijeni drejt 1.0 për një sjellje më konservatore. Lëreni bosh për vlerën e parazgjedhur (0.98, ose 0.99 për pjatalarëset). Ai mund vetëm ta mbyllë një cikël më herët, kurrë më vonë, dhe nuk aktivizohet kurrë në një përputhje të paqartë ose me besim të ulët.",
"label": "Raporti i Përfundimit të Zgjuar"
},
"enable_phase_matching": {
"label": "Kohë e mbetur e ndërgjegjshme për fazat",
"doc": "Ndan çdo cikël që po funksionon në faza (ngrohje, larje, centrifugim) dhe shpërndan kohën e mbetur për çdo fazë, e përzier me vlerësimin klasik - duke u mbështetur te shpërndarja sipas fazave në fillim të ciklit dhe te vlerësimi klasik afër fundit. Kjo e personalizon numërimin mbrapsht sipas kohës që makina juaj në të vërtetë ngroh dhe punon, gjë që vihet re më së shumti në gjysmën e parë të një cikli. Off = vetëm vlerësimi klasik. Preket vetëm shfaqja e kohës së mbetur; përputhja e programeve dhe zbulimi i ciklit mbeten të pandryshuara."
@@ -1522,6 +1583,10 @@
"dishwasher_end_spike_quiet_release": {
"label": "Lirim në qetësi gjatë tharjes pasive",
"doc": "Sapo cikli të kalojë kohëzgjatjen e tij të pritur, sa kohë duhet të qëndrojë e qetë pjatalarësja (nën Pragun e ndalimit) përpara se WashData të ndalojë pritjen për një shkarkim përfundimtar dhe ta mbyllë ciklin. Rriteni nëse makina juaj ka një fazë të gjatë tharjeje të heshtur përpara një shkarkimi përfundimtar të vonuar që po humbet - një dritare më e gjerë e lejon kohëzgjatjen e mësuar të ndjekë zhvendosjen sezonale (ujë hyrës më i ftohtë = cikle më të gjata) në vend që të bllokohet në mesataren e vjetër. Ai vetëm sa e shkurton pritjen në raport me kufirin e brendshëm 30-minutësh të kulmit të fundit, kurrë nuk e zgjat."
},
"profile_evidence_sources": {
"label": "Ciklet që formojnë një program",
"doc": "Cilat cikle përdoren për të ndërtuar kurbën e fuqisë së secilit program dhe për të përputhur me të një cikël të përfunduar. Heqja e shenjës nga një lloj e ndalon atë të formojë programet tuaja pa fshirë asgjë - ciklet mbeten në listën Cikle dhe mund të etiketohen ose të hiqen si më parë. E dobishme nëse nuk i besoni të dhënave të importuara. Statistikat nuk preken: ato numërojnë gjithmonë vetëm ciklet që kjo makinë kreu vërtet. Heqja e shenjës nga të gjitha llojet shpërfillet, sepse një program pa cikle pas tij nuk mund të përputhej kurrë."
}
},
"setting_group": {
@@ -1605,6 +1670,9 @@
},
"basic_configuration": {
"label": "Konfigurimi bazë"
},
"profile_evidence": {
"label": "Burimet e profilit"
}
},
"status": {
@@ -1626,10 +1694,11 @@
"analyzing": "Po analizohet…",
"resetting": "Po rivendoset…",
"reverting": "Po kthehet…",
"trimming": "Po pritet…",
"trimming": "Duke prerë…",
"splitting": "Po ndahet…",
"deleting": "Po fshihet…",
"imported": "Importuar"
"imported": "Importuar",
"preparing": "Po përgatitet…"
},
"tab": {
"advanced": "I avancuar",
@@ -1659,6 +1728,7 @@
"wrong_profile": "Profil i gabuar"
},
"toast": {
"catalog_refreshed": "Katalogu i komunitetit u rifreskua",
"access_saved": "Kontrolli i aksesit u ruajt",
"all_wiped": "Të gjitha të dhënat u fshien",
"analysis_complete_none": "Analiza e plotë: asnjë sugjerim i ri",
@@ -1670,7 +1740,7 @@
"cycle_labelled": "Cikli u etiketua",
"cycle_paused": "Cikli u ndal",
"cycle_resumed": "Cikli u vazhdua",
"cycle_trimmed": "Cikli u prit",
"cycle_trimmed": "Cikli u pre",
"cycles_merged": "Ciklet u bashkuan",
"envelope_rebuilt": "Zarfi u rindërtua",
"envelopes_rebuilt": "Zarfet u rindërtuan",
@@ -1764,7 +1834,9 @@
"store_download_failed": "Shkarkimi dështoi: {error}",
"store_download_nothing": "Asgjë e re për të shkarkuar - ky konfigurim është tashmë në pajisjen tuaj.",
"export_selective_done": "Eksporti u shkarkua",
"import_selective_done": "U importuan {profiles} profil(e) dhe {cycles} cikël(cikle)"
"import_selective_done": "U importuan {profiles} profil(e) dhe {cycles} cikël(cikle)",
"hist_csv_required": "Ngarkoni së pari një skedar CSV ose ngjitni përmbajtjen e tij",
"file_read_failed": "Skedari nuk mund të lexohej"
},
"suggestion": {
"both_agree": "WashData rekomandon",
@@ -1860,7 +1932,7 @@
"thr_batch": "Mbahet pak mbi fuqinë aktive më të ulët p05 në {cycles} cikle ({p05}W) që një nisje të kapet sa më herët të jetë e mundur dhe pragu i ndalimit të mbetet nën fuqinë më të ulët të punës së makinës.",
"tol_per_profile": "p75 e variancës së kohëzgjatjes për profil në {profiles} profile ({cycles} cikle); profilet e qëndrueshme nuk penalizohen.",
"tol_pooled": "Bazuar në variancën e bashkuar të kohëzgjatjes së {cycles} cikleve të fundit të etiketuara (devijimi p95={dev}).",
"watchdog": "Mbahet sa më i ulët në mënyrë të sigurt (pak mbi boshllëkun e përditësimit p95 prej {p95}s, min. 30s) që bllokimet të kapen shpejt pa ndalime të rreme."
"watchdog": "Mbahet sa më i ulët në mënyrë të sigurt (pak mbi boshllëkun e përditësimit p95 prej {p95}s dhe të paktën 2× intervalin e kampionimit prej {median}s, min. 30s) që bllokimet të kapen shpejt pa ndalime të rreme."
},
"exclusions": {
"summary": "U përjashtuan {total} cikle të zbuluar gabimisht: {parts}.",
@@ -1917,7 +1989,8 @@
"dtw_refine_top_n": "Etapa 3: kandidatë të rishënuara nga DTW; rriteni në 7-9 nëse profili i saktë renditet i 4-5 (parazgjedhja 5)",
"duration_scale": "Etapa 4: raporti logaritmik ku marrëveshja e kohëzgjatjes gjysmohet; më i vogël = ndëshkim më i rreptë (parazgjedhja 0.175)",
"energy_scale": "Etapa 4: raporti logaritmik ku marrëveshja e energjisë gjysmohet; më i vogël = ndëshkim më i rreptë (parazgjedhja 0.25)",
"dishwasher_end_spike_quiet_release": "Pjatalarëse: sekonda qetësie pas kohëzgjatjes së pritur para se të lirohet pritja e shkarkimit në fund të ciklit"
"dishwasher_end_spike_quiet_release": "Pjatalarëse: sekonda qetësie pas kohëzgjatjes së pritur para se të lirohet pritja e shkarkimit në fund të ciklit",
"smart_termination_duration_ratio": "Pjesa e kohëzgjatjes së pritur të programit të përputhur që një cikël duhet të arrijë përpara se Përfundimi i Zgjuar të mund ta mbyllë atë herët; uleni për makina që varen nga ngarkesa ose temperatura"
},
"col": {
"profile_tip": "Emri i programit të përputhur. I paetiketuar do të thotë se asnjë profil nuk u përputh në fund të ciklit.",
@@ -1955,6 +2028,10 @@
"finished": "Cikli arriti gjendjen përfundimtare dhe përfundoi."
},
"store": {
"your_model_tip": "Kjo është pajisja që deklaruat te Cilësimet",
"your_model": "E juaja",
"search_brand_ph": "Kërko sipas markës…",
"programs_count": "Programe: {n}",
"browse": "Shfleto",
"device": "Pajisja",
"favorites": "Të preferuarat",
@@ -1993,6 +2070,7 @@
"add_profile": "Shtoni një profil për këtë pajisje në sitin e komunitetit"
},
"task": {
"cancelling": "Po anulohet...",
"reprocess": {
"matching": "Ripërpunim: përputhja e cikleve",
"golden": "Ripërpunim: shënimi i cikleve referues",
@@ -78,9 +78,12 @@
"awaiting": "Čeka odobrenje",
"imported_tip": "Uvezeno iz prodavnice zajednice. Koristi se samo za podudaranje, ne računa se u statistiku.",
"not_importable": "nije primenljivo",
"exists": "postoji"
"exists": "postoji",
"backfilled_tip": "Detektovano u uvezenoj istoriji snage. Utiče samo na podudaranje programa, ne računa se u statistiku."
},
"btn": {
"set_brand_model": "Postavi marku i model",
"refresh_catalog": "Osveži katalog",
"add_device": "+ Dodaj uređaj",
"add_device_tip": "Dodaj još jedan WashData uređaj",
"add_maintenance": "Dodaj događaj održavanja",
@@ -234,14 +237,19 @@
"download_device": "Preuzmi podešavanja uređaja",
"share_device": "Podeli podešavanja uređaja",
"share_device_tip": "Podelite programe i podešavanja ovog uređaja sa zajednicom",
"share_n": "Podeli {n} program{s}",
"share_n": "Podeli cikluse ({n})",
"export_selected": "Izvoz (izbor podataka)",
"export_all": "Brzi izvoz svega",
"import_raw": "Napredno: zameni sve iz JSON-a",
"download_export": "Preuzmi izvoz",
"analyze_import": "Analiziraj datoteku",
"import_selected": "Uvezi izabrano",
"back": "Nazad"
"back": "Nazad",
"import_power_history": "Uvezi istoriju snage",
"hist_read_recorder": "Pročitaj iz Home Assistant",
"hist_scan": "Potraži cikluse",
"hist_import_n": "Uvezi cikluse: {n}",
"hist_goto_cycles": "Prikaži cikluse"
},
"conflict": {
"anti_wrinkle_exit": {
@@ -253,12 +261,12 @@
"start": "Mora biti ispod Maks. snage zaštite od gužvanja ({max} W)"
},
"attn_sub": "Ispravite konflikte pre čuvanja",
"attn_title": "{n} konflikt{s} podešavanja",
"attn_title": "Konflikti podešavanja: {n}",
"confidence": {
"auto": "Mora biti jednak ili iznad Praga podudaranja ({match})",
"learning": "Mora biti jednak ili ispod Praga podudaranja ({match})",
"learning": "Mora biti jednak ili iznad Praga podudaranja ({match})",
"match_for_auto": "Mora biti jednak ili ispod Pouzdanosti automatskog označavanja ({alc})",
"match_for_learning": "Mora biti jednak ili iznad Pouzdanosti učenja ({lc})"
"match_for_learning": "Mora biti jednak ili ispod Pouzdanosti učenja ({lc})"
},
"duration_ratio": {
"max": "Mora biti veći od Min. odnosa trajanja ({min})",
@@ -296,14 +304,14 @@
"match": "Mora biti iznad Praga nepodudaranja ({un})",
"unmatch": "Mora biti ispod Praga podudaranja ({match}); inače potvrđeno podudaranje odmah prestaje"
},
"cascade_toast": "Automatski je prilagođeno i {n} postavki radi doslednosti.",
"cascade_toast": "Druga podešavanja prilagođena radi doslednosti: {n}",
"suggestion_resolves": "Primenite predlog na čekanju ({val}) ispod za rešavanje ovog konflikta",
"use_fix": "Koristi {val}",
"watchdog": {
"interval": "Treba biti najmanje 2× Interval uzorkovanja ({si} s)",
"sampling": "Interval uzorkovanja treba biti najviše pola Intervala nadzornika ({wi} s)"
},
"settings_banner": "{n} konflikt{s} podešavanja proverite istaknute odeljke i ispravite pre čuvanja.",
"settings_banner": "Konflikti podešavanja: {n}. Proverite istaknute odeljke i ispravite ih pre čuvanja.",
"settings_banner_btn": "Idi na prvi"
},
"hdr": {
@@ -356,7 +364,8 @@
"pg_outcome": "Ishod simulacije",
"pg_across_cycles": "Kroz sve vaše cikluse",
"community_store": "Prodavnica zajednice",
"online_account": "Prodavnica zajednice i online funkcije"
"online_account": "Prodavnica zajednice i online funkcije",
"import_power_history": "Uvoz istorije snage"
},
"health": {
"fair": "Prihvatljiva kvaliteta profila",
@@ -364,6 +373,7 @@
"poor": "⚠ Loša kvaliteta profila"
},
"lbl": {
"drag_to_resize": "Prevucite za promenu veličine",
"actions": "Akcije",
"activity": "Aktivnost",
"administrators": "Administratori",
@@ -451,7 +461,7 @@
"metric": "Metrika",
"mode_existing_profile": "Dodaj u postojeći profil",
"mode_new_profile": "Napravi novi profil",
"models_fine_tuned": "({count} modela fino podešenih)",
"models_fine_tuned": "(fino podešeni modeli: {count})",
"n_classic_suggestions": "{n} klasično",
"n_ml_suggestions": "{n} ML",
"n_selected": "{n} izabrano",
@@ -651,7 +661,7 @@
"show_contributor": "Prikaži saradnika",
"task_pg_detail": "Simuliraj ciklus",
"task_split": "Deljenje ciklusa",
"task_trim": "Obrezivanje ciklusa",
"task_trim": "Isecanje ciklusa",
"task_merge": "Spajanje ciklusa",
"task_rebuild": "Ponovna izgradnja omotača",
"cat_profiles": "Profili (programi)",
@@ -677,7 +687,26 @@
"conflict_resolution": "Sukobi imena",
"conflict_import_copy": "Uvezi kao kopiju",
"conflict_keep_mine": "Zadrži moje",
"conflict_overwrite": "Prepiši"
"conflict_overwrite": "Prepiši",
"hist_csv_data": "CSV podaci",
"hist_from_recorder": "Ili je pročitajte iz Home Assistant",
"days": "dana",
"hist_keep": "Zadrži ovaj ciklus",
"hist_looks_complete": "završen",
"peak_power_short": "Vrh",
"shape": "Oblik",
"hist_skip_idle": "nije bilo aktivnosti",
"hist_skip_sparse": "očitavanja previše razmaknuta",
"hist_skip_short": "nedovoljno očitavanja",
"hist_skip_long": "nema dovoljno duge pauze za deljenje",
"hist_reason_short": "kraći od najkraćeg stvarnog ciklusa ovog uređaja",
"hist_reason_no_end": "nikada se nije ispravno završio",
"hist_since": "Od",
"task_history_import": "Pretraživanje istorije snage",
"task_history_import_apply": "Uvoz ciklusa",
"evidence_real_cycles": "Ciklusi koje je ovaj uređaj obavio",
"evidence_reference_cycles": "Preuzeti iz prodavnice zajednice",
"evidence_backfill_cycles": "Pronađeni u uvezenoj istoriji snage"
},
"log": {
"all_levels": "Svi nivoi",
@@ -756,9 +785,15 @@
"store_share": "Podeli u prodavnicu zajednice",
"store_share_device": "Podeli podešavanja uređaja",
"export_select": "Izvoz - izbor podataka",
"import_wizard": "Uvoz - izbor podataka"
"import_wizard": "Uvoz - izbor podataka",
"history_import": "Uvoz istorije snage"
},
"msg": {
"tail_trim_hint": "Uklonite ovoliko sekundi sa kraja",
"store_sibling_hint": "Nema ničega podeljenog za vaš tačan model? Blisko srodan model iste marke obično je dobra početna tačka.",
"store_declare_appliance": "Recite integraciji WashData koji uređaj posedujete i ova kartica će prikazati konfiguracije koje su drugi podelili za njega. Možete i da upišete marku iznad da biste pregledali katalog.",
"refresh_catalog_hint": "Liste marki i uređaja zajednice privremeno se čuvaju kako bi prodavnica zajednice ostala u okviru svog dnevnog ograničenja. Osvežite da preuzmete unose koje su drugi dodali ili odobrili.",
"head_trim_hint": "Uklonite ovoliko sekundi sa početka",
"appliance_monitor": "Monitor uređaja",
"artifact_dip_detail": "Pao ispod uobičajenog opsega snage za ~{n} s.",
"artifact_footer": "Istaknuto na grafikonu iznad. Ovo su prolazni artefakti (npr. vrata se otvaraju usred ciklusa), ne nužno problemi.",
@@ -769,7 +804,7 @@
"automations_intro": "WashData okida događaje {start} / {end} i izlaže entitete, pa je obaveštenja i akcije najbolje graditi kao normalne automatizacije Home Assistanta. Automatizacije koje koriste ovaj uređaj prikazane su ispod.",
"cleanup_intro": "Svaki označeni ciklus je prekriven. Označi outlier-e i izbriši za čišćenje profila.",
"clear_debug_hint": "Uklonite sačuvane podatke za otklanjanje grešaka da biste oslobodili prostor.",
"collecting_data": "Prikupljanje podataka: još {need} ciklusa do početka finog podešavanja ({current}/{min}).",
"collecting_data": "Prikupljanje podataka. Još potrebnih ciklusa pre početka finog podešavanja: {need} ({current}/{min}).",
"compare_overlay_profiles": "Preklapanje profila (bledi)",
"compare_profiles_tip": "Prekrijte druge omotače profila na gornjem grafikonu da vidite koji najbolje odgovara ovom ciklusu.",
"compare_selected_cycles": "Izabrani ciklusi (neprozirni) prikaži / sakrij",
@@ -779,7 +814,7 @@
"cycles_deleted": "Obrisano ciklusa: {count}",
"enough_data": "Dovoljno podataka za učenje ({current}/{min} ciklusa).",
"export_description": "Izaberite tačno koje profile, cikluse, podešavanja i drugo želite da izvezete u JSON, ili analizirajte datoteku i uvezite samo delove koje želite.",
"feedback_cycles_pending": "{n} ciklusa za pregled",
"feedback_cycles_pending": "Za pregled: {n}",
"feedback_prompt": "Potvrdi da je bio tačan, ispravi program ili ignoriši.",
"feedback_relabel_hint": "Ponovno označavanje ovog ciklusa takođe ga rešava.",
"filter_by_profile": "Filtriraj po profilu…",
@@ -856,7 +891,6 @@
"pg_stress_synthetic": "simulacija mirovanja počinje ovde",
"pg_sweep_intro": "Šta ako bi {param} bio drugačiji? Testirajte {steps} vrednosti na vaših poslednjih {cycles} ciklusa da pronađete podešavanje pri kojem se najviše ciklusa ispravno poklapa.",
"pg_sweep_step": "Korak {done} / {total}",
"pg_undetected": "{n} neotkrivenih ciklusa",
"pg_verdict_bad": "Zahteva pažnju: mnogi ciklusi ostaju neotkriveni.",
"pg_verdict_good": "Dobro podešeno: većina ciklusa se ispravno prepoznaje i poklapa.",
"pg_verdict_ok": "Prihvatljivo: neki ciklusi su propušteni. Pokušajte da smanjite prag pokretanja.",
@@ -888,6 +922,7 @@
"review_recorded_tip": "Označite ovo kao ručno odabran referentni ciklus za njegov program - istu ulogu kao i ručno snimljeni ciklus. Referentni ciklusi se uvek čuvaju, postavljaju odgovarajući šablon i nikada se ne ispuštaju čišćenjem. (Ovo je \"zlatna\"/snimljena zastavica; obe su ista stvar.)",
"review_tags_tip": "Opcionalne zastavice koje opisuju šta je pošlo po zlu sa ovim ciklusom, tako da obuka i čišćenje mogu da budu odgovorni za to.",
"review_to_cycles": "Otvori red za pregled Ciklusa",
"samples_decimated": "Prikazano {shown} od {total} uzoraka (proređeno za prikaz; pikovi zadržani). Široki razmak ovde je proređivanje, a ne nedostajući podaci.",
"saving_triggers_reload": "Čuvanje pokreće ponovni pun integracije. HA entiteti mogu se kratko prikazati kao nedostupni.",
"search_placeholder": "Pretraži podešavanja…",
"see_recorder": "Pogledaj widget za snimanje ispod",
@@ -991,12 +1026,12 @@
"share_consent": "Delite stvarne podatke sa svog uređaja. Nemojte deliti ako su vaši obrasci korišćenja privatni.",
"share_device_none": "Još nema postavljenih uređaja. Prvo dodajte uređaj.",
"share_guideline_naming": "Koristite jasna imena programa (npr. 'Cotton 40', 'Eco 60') kako bi ih drugi mogli prepoznati",
"share_guideline_quality": "Delite samo profile sa ⭐ referentnim ciklusima ili najmanje {n} potvrđenih pokretanja",
"share_guideline_quality": "Delite samo cikluse koji su se normalno završili -- bez prekida usred ciklusa, otvaranja vrata ili skokova napajanja.",
"share_guideline_review": "Pregledajte profile pre deljenja -- uklonite one koji izgledaju pogrešno",
"share_guidelines_title": "Pre deljenja",
"store_download_device_intro": "Preuzmite podešavanja uređaja iz zajednice i primenite ih na novi ili postojeći uređaj",
"store_share_device_intro": "Podelite programe svog uređaja (profile + referentne cikluse) sa zajednicom. Podešavanja su opcionalna.",
"share_profile_no_cycles": "Profil '{p}' nema referentnih ciklusa -- biće preskočen osim ako nemate {n}+ potvrđenih pokretanja",
"store_share_device_intro": "Otpremite {brand} {model} sa referentnim ciklusima koje izaberete. Drugi sa istim uređajem mogu da preuzmu vaše programe. Unosi se pregledaju pre nego što postanu javni.",
"share_profile_no_cycles": "Nema referentnih ciklusa - označite ciklus sa ⭐ u kartici Ciklusi da uključite ovaj profil",
"advisory_phase_inconsistent": "Izgleda da '{name}' meša različite programe ili temperature - njegovi ciklusi se greju veoma različito dugo. Podela na zasebne profile (npr. po temperaturi) poboljšaće podudaranje i procene vremena.",
"advisory_phase_inconsistent_title": "⚠ Možda pomešani programi",
"export_select_intro": "Označite tačno šta želite da uključite. Izbor profila bez njihovih ciklusa i dalje izvozi prepoznatljiv program (njegov naučeni oblik ide zajedno sa njim).",
@@ -1006,7 +1041,29 @@
"merge_hint": "Uvezene stavke se dodaju; ništa lokalno se ne gubi. Sukobi imena rešavaju se ispod.",
"replace_warn": "Svaka označena kategorija se briše i zamenjuje podacima iz datoteke. Neoznačene kategorije ostaju netaknute.",
"dest_reference_hint": "Uvezeni ciklusi samo poboljšavaju prepoznavanje programa i nikada ne utiču na statistiku potrošnje/energije.",
"dest_real_history_hint": "Uvezeni ciklusi se računaju kao sopstvena istorija ovog uređaja i pune statistiku energije/potrošnje. Koristite za premeštanje jednog uređaja na novu instalaciju."
"dest_real_history_hint": "Uvezeni ciklusi se računaju kao sopstvena istorija ovog uređaja i pune statistiku energije/potrošnje. Koristite za premeštanje jednog uređaja na novu instalaciju.",
"import_history_description": "Imali ste pametni priključak i pre WashData? Učitajte izvoz istorije njegovog senzora snage ili je pročitajte direktno iz Home Assistant, a uobičajena detekcija proći će kroz te podatke, pa će se prošli ciklusi pojaviti na vašoj listi Ciklusi, spremni za imenovanje.",
"hist_input_hint": "Učitajte CSV preuzet sa panela Istorija (entitet, stanje, poslednja promena) ili pustite WashData da direktno pročita istoriju senzora. Detekcija se zatim izvodi isto kao i uživo, a vi birate koje od pronađenih ciklusa ćete zadržati.",
"hist_recorder_hint": "Čita podatke od izabranog datuma do sada. Home Assistant podrazumevano čuva detaljnu istoriju 10 dana, a posle toga samo satne proseke, koji su previše grubi za detekciju ciklusa - raniji datum birajte samo ako je vaš recorder podešen na duže čuvanje.",
"hist_scanning": "Vašu istoriju ponovo provodimo kroz detektor. Ovo se izvodi u pozadini - možete zatvoriti ovaj dijalog i vratiti se kasnije.",
"hist_imported_count": "Uvezeni ciklusi: {n}.",
"hist_duplicates": "Već ranije uvezeno i preskočeno: {n}.",
"hist_capped": "Dostignuto je ograničenje uvezenih ciklusa po uređaju; ostatak nije sačuvan.",
"hist_next_step": "Nalaze se na vašoj listi Ciklusi, obeleženi kao uvezena istorija. Otvorite jedan i tasterom Označi mu dodelite naziv programa kojem pripada.",
"hist_rows_read": "Pročitana očitavanja: {n}",
"hist_breaks": "Praznine u kojima senzor nije bio dostupan: {n}",
"hist_other_entity": "Zanemarena očitavanja drugih entiteta: {n}",
"hist_entity_substituted": "Očitano {used} (ovaj uređaj je podešen na {wanted})",
"hist_skipped_spans": "Preskočeni delovi",
"hist_settings_used": "Detektovano sa trenutnim podešavanjima ovog uređaja (minimalna snaga {w} W, kašnjenje isklopa {s} s).",
"hist_none_found": "U toj istoriji nije bilo moguće detektovati nijedan ciklus.",
"hist_found": "Pronađeni ciklusi: {n}. Odznačite sve što ne izgleda kao stvarni rad - ništa se ne čuva dok ne uvezete.",
"hist_scan_capped": "Prikazani su samo prvi kandidati (pronađeno je {n}).",
"hist_recorder_empty": "Home Assistant nema detaljnu istoriju za ovaj senzor u tom periodu.",
"hist_scan_failed": "Pretraživanje nije uspelo.",
"hist_scan_expired": "To pretraživanje više nije dostupno. Pokrenite ga ponovo.",
"hist_import_failed": "Uvoz nije uspeo.",
"imported_history_readonly": "Detektovano u uvezenoj istoriji snage. Utiče na podudaranje programa, ali se ne računa u vašu statistiku i ne može se isecati ni deliti. Označite ga da mu dodelite program."
},
"phase_desc": {
"anti_crease": "Povremena kratka okretanja nakon završetka radi smanjenja gužvanja.",
@@ -1471,6 +1528,10 @@
"show_contributor": {
"doc": "Prikaži ime saradnika na profilima preuzetim iz prodavnice zajednice"
},
"smart_termination_duration_ratio": {
"doc": "Koliko duboko u očekivano trajanje podudarenog programa ciklus mora da odmakne pre nego što Pametno završavanje sme da ga okonča ranije kad snaga opadne. Očekivano trajanje je prosek programa, pa kod uređaja čije vreme rada dosta varira - mašine za pranje veša pri hladnoj zimskoj i toploj letnjoj dovodnoj vodi, mašine za sušenje sa senzorom vlage, programi zavisni od količine veša - oko polovine svih ciklusa završi kraće od tog proseka i nikada ne dobije brzi završetak, već se okonča tek preko rezervnog tajmauta sa nekoliko minuta zakašnjenja. Smanjite ovu vrednost (npr. 0.85) na takvim mašinama da bi se rano završavanje ipak aktiviralo; povećajte je ka 1.0 za oprezniji rad. Ostavite prazno za podrazumevanu vrednost (0.98, ili 0.99 za mašine za pranje sudova). Može samo da okonča ciklus ranije, nikada kasnije, i nikada se ne aktivira pri dvosmislenom ili nepouzdanom podudaranju.",
"label": "Koeficijent pametnog završavanja"
},
"enable_phase_matching": {
"label": "Preostalo vreme prilagođeno fazama",
"doc": "Deli svaki aktivni ciklus na faze (zagrevanje, pranje, centrifuga) i raspoređuje preostalo vreme po fazama, u kombinaciji sa klasičnom procenom - oslanjajući se na raspored po fazama na početku ciklusa, a na klasičnu procenu pri kraju. Ovo prilagođava odbrojavanje tome koliko se vaša mašina zaista greje i radi, što je najuočljivije u prvoj polovini ciklusa. Isključeno = samo klasična procena. Utiče samo na prikaz preostalog vremena; podudaranje programa i detekcija ciklusa ostaju nepromenjeni."
@@ -1522,6 +1583,10 @@
"door_end_dwell_seconds": {
"label": "Zadržavanje pri otvorenim vratima",
"doc": "Koliko dugo vrata moraju ostati otvorena pre nego WashData završi ciklus, kada je uključeno \"Vrata se automatski otvaraju na kraju\". Dovoljno dugo da se ignoriše brzo dodavanje posuđa (podrazumevano 60 s), dovoljno kratko za brzo završavanje kada mašina otvori vrata."
},
"profile_evidence_sources": {
"label": "Ciklusi koji grade program",
"doc": "Koji se ciklusi koriste za izgradnju krive snage svakog programa i za podudaranje završenog ciklusa s njom. Kada odznačite neku vrstu, ona više ne utiče na vaše programe, ali se ništa ne briše - ciklusi ostaju na spisku Ciklusi i mogu se i dalje označiti ili ukloniti. Korisno ako ne verujete uvezenim podacima. Na statistiku to ne utiče: uvek se računaju samo ciklusi koje je ovaj uređaj zaista izvršio. Odznačavanje svega se ignoriše jer program bez ikakvih ciklusa nikada ne bi mogao da se podudari."
}
},
"setting_group": {
@@ -1605,6 +1670,9 @@
},
"basic_configuration": {
"label": "Osnovna konfiguracija"
},
"profile_evidence": {
"label": "Osnov profila"
}
},
"status": {
@@ -1626,10 +1694,11 @@
"analyzing": "Analiziranje…",
"resetting": "Resetovanje…",
"reverting": "Vraćanje…",
"trimming": "Obrezivanje…",
"trimming": "Isecanje…",
"splitting": "Deljenje…",
"deleting": "Brisanje…",
"imported": "Uvezeno"
"imported": "Uvezeno",
"preparing": "Priprema…"
},
"suggestion": {
"both_agree": "WashData preporučuje",
@@ -1725,7 +1794,7 @@
"thr_batch": "Zadržano tik iznad najniže radne snage p05 kroz {cycles} ciklusa ({p05}W) kako bi se početak uhvatio što ranije, a prag zaustavljanja ostao ispod najniže radne snage mašine.",
"tol_per_profile": "p75 varijanse trajanja po profilu kroz {profiles} profila ({cycles} ciklusa); dosledni profili nisu kažnjeni.",
"tol_pooled": "Na osnovu objedinjene varijanse trajanja {cycles} novijih označenih ciklusa (p95 odstupanje={dev}).",
"watchdog": "Zadržano što nižim uz bezbednost (tik iznad razmaka ažuriranja p95 od {p95}s, najmanje 30s) kako bi se zastoji brzo uhvatili bez lažnih zaustavljanja."
"watchdog": "Zadržano što nižim uz bezbednost (tik iznad razmaka ažuriranja p95 od {p95}s i najmanje 2× intervala uzorkovanja od {median}s, najmanje 30s) kako bi se zastoji brzo uhvatili bez lažnih zaustavljanja."
},
"exclusions": {
"summary": "Isključeno {total} pogrešno detektovanih ciklusa: {parts}.",
@@ -1772,6 +1841,7 @@
"wrong_profile": "Pogrešan profil"
},
"toast": {
"catalog_refreshed": "Katalog zajednice je osvežen",
"access_saved": "Kontrola pristupa sačuvana",
"all_wiped": "Svi podaci obrisani",
"analysis_complete_none": "Analiza završena: nema novih prijedloga",
@@ -1865,19 +1935,21 @@
"rating_saved": "Ocena kvaliteta sačuvana",
"brand_added": "Marka dodata, čeka odobrenje",
"profile_added": "Profil dodat, čeka odobrenje",
"saved_except_conflicts": "Podešavanja sačuvana -- {n} podešavanje{s} preskočeno zbog konflikata",
"saved_except_conflicts": "Sačuvano. Ispravite istaknute konflikte da sačuvate ostalo.",
"share_device_none_sel": "Odaberite barem jedan program za deljenje",
"store_device_downloaded": "Podešavanja uređaja preuzeta: {created} profil{c} kreiran, {dup} već postoji",
"store_device_downloaded_phases": "Podešavanja uređaja preuzeta: {created} profil{c} kreiran, {dup} već postoji, mapa faza primenjena",
"store_device_downloaded_settings": "Podešavanja uređaja preuzeta: {created} profil{c} kreiran, {dup} već postoji, podešavanja primenjena",
"store_device_shared": "Podešavanja uređaja podeljena: {n} program{s} učitan",
"store_device_shared_all_dup": "Nema ničeg novog za deljenje -- svi programi već postoje u prodavnici",
"store_device_shared_partial": "Delimično deljenje: {n} program{s} učitan, {failed} preskočeno",
"store_device_shared_some_dup": "Podešavanja uređaja podeljena: {n} program{s} učitan ({dup} već postoji)",
"store_device_downloaded": "Dodato: programi {p}, snimci {c}",
"store_device_downloaded_phases": "Dodato: programi {p}, snimci {c}, mape faza {ph}",
"store_device_downloaded_settings": "Dodato: programi {p}, snimci {c}, mape faza {ph}, podešavanja {s}",
"store_device_shared": "Ciklusi podeljeni u prodavnicu zajednice: {n}. Čeka se pregled.",
"store_device_shared_all_dup": "Svi ciklusi ({n}) su već bili u prodavnici zajednice.",
"store_device_shared_partial": "Podeljeni ciklusi: {n}; nije otpremljeno: {failed}.",
"store_device_shared_some_dup": "Podeljeni ciklusi: {created}; već u prodavnici: {dup}.",
"store_download_failed": "Preuzimanje nije uspelo: {error}",
"store_download_nothing": "Nema ničeg za preuzimanje -- svi profili već postoje na ovom uređaju",
"export_selective_done": "Izvoz preuzet",
"import_selective_done": "Uvezeno {profiles} profil(a) i {cycles} ciklus(a)"
"import_selective_done": "Uvezeno {profiles} profil(a) i {cycles} ciklus(a)",
"hist_csv_required": "Prvo učitajte CSV datoteku ili nalepite njen sadržaj",
"file_read_failed": "Nije bilo moguće pročitati tu datoteku"
},
"trend": {
"down": "Opadajući trend",
@@ -1892,6 +1964,7 @@
},
"pg_desc": {
"dishwasher_end_spike_quiet_release": "Mašina za pranje sudova: sekunde tišine nakon očekivanog trajanja pre nego što se otpusti čekanje na završno ispumpavanje vode",
"smart_termination_duration_ratio": "Deo očekivanog trajanja podudarenog programa koji ciklus mora da dostigne pre nego što Pametno završavanje sme da ga okonča ranije; smanjite ga za mašine zavisne od količine veša ili temperature",
"completion_min_seconds": "Najkraće pokretanje koje se računa kao pravi ciklus",
"end_repeat_count": "Niska očitavanja zaredom pre završetka",
"interrupted_min_seconds": "Kratki ciklusi označeni kao prekinuti",
@@ -1955,6 +2028,10 @@
"finished": "Ciklus je dostigao završno stanje i završio."
},
"store": {
"your_model_tip": "Ovo je uređaj koji ste naveli u Podešavanjima",
"your_model": "Vaš",
"search_brand_ph": "Pretraži po marki…",
"programs_count": "Programi: {n}",
"browse": "Pregledaj",
"device": "Uređaj",
"favorites": "Omiljeni",
@@ -1993,6 +2070,7 @@
"add_profile": "Dodajte profil za ovaj uređaj na sajtu zajednice"
},
"task": {
"cancelling": "Otkazivanje...",
"reprocess": {
"matching": "Ponovna obrada: podudaranje ciklusa",
"golden": "Ponovna obrada: popunjavanje referentnih",
@@ -2010,7 +2088,7 @@
"apply": "Deljenje ciklusa"
},
"trim": {
"apply": "Obrezivanje ciklusa"
"apply": "Isecanje ciklusa"
},
"merge": {
"apply": "Spajanje ciklusa"
@@ -78,9 +78,12 @@
"awaiting": "Väntar på godkännande",
"imported_tip": "Importerad från gemenskapsbutiken. Används endast för matchning, räknas inte in i statistiken.",
"not_importable": "ej här",
"exists": "finns"
"exists": "finns",
"backfilled_tip": "Detekterad i importerad effekthistorik. Påverkar bara programmatchningen, räknas inte in i statistiken."
},
"btn": {
"set_brand_model": "Ange märke och modell",
"refresh_catalog": "Uppdatera katalog",
"add_device": "+ Lägg till enhet",
"add_device_tip": "Lägg till ytterligare en WashData-enhet",
"add_maintenance": "Lägg till underhållshändelse",
@@ -90,7 +93,7 @@
"apply_label": "Tillämpa etikett",
"apply_set_b": "Använd uppsättning B",
"apply_split": "Tillämpa delning",
"apply_trim": "Tillämpa trimning",
"apply_trim": "Tillämpa beskärning",
"auto_detect_split": "Autoidentifiera",
"auto_label_cycles": "Automatisk märkning av cykler",
"auto_label_cycles_tip": "Tilldela automatiskt profilnamn till omärkta cykler vars matchningskonfidens klarar tröskeln",
@@ -209,8 +212,8 @@
"stop": "Stoppa",
"submit_correction": "Skicka korrigering",
"train_now": "Träna nu",
"trim": "Trimma",
"trim_split": "Trimma / Dela",
"trim": "Beskär",
"trim_split": "Beskär / Dela",
"undo": "Ångra",
"use": "Använd",
"wipe_all": "Rensa all data",
@@ -241,7 +244,12 @@
"import_selected": "Importera valda",
"back": "Tillbaka",
"mute_suggestion": "Sluta föreslå den här inställningen",
"reset_muted": "Återställ tysta förslag"
"reset_muted": "Återställ tysta förslag",
"import_power_history": "Importera effekthistorik",
"hist_read_recorder": "Läs från Home Assistant",
"hist_scan": "Sök efter cykler",
"hist_import_n": "Importera {n} cykler",
"hist_goto_cycles": "Visa mig cyklerna"
},
"conflict": {
"anti_wrinkle_exit": {
@@ -253,12 +261,12 @@
"start": "Måste vara under skrynkelskyddets maxeffekt ({max} W)"
},
"attn_sub": "Åtgärda konflikter innan du sparar",
"attn_title": "{n} inställningskonflikt{s}",
"attn_title": "Inställningskonflikter: {n}",
"confidence": {
"auto": "Måste vara vid eller över matchningströskel ({match})",
"learning": "Måste vara vid eller under matchningströskel ({match})",
"learning": "Måste vara vid eller över matchningströskel ({match})",
"match_for_auto": "Måste vara vid eller under automatisk-märknings-konfidensen ({alc})",
"match_for_learning": "Måste vara vid eller över inlärningskonfidensen ({lc})"
"match_for_learning": "Måste vara vid eller under inlärningskonfidensen ({lc})"
},
"duration_ratio": {
"max": "Måste vara större än minimal varaktighetskvot ({min})",
@@ -296,14 +304,14 @@
"match": "Måste vara över avmatchningströskel ({un})",
"unmatch": "Måste vara under matchningströskel ({match}); annars avmatchas en bekräftad matchning omedelbart"
},
"cascade_toast": "Även {n} inställning{s} justerades för konsekvens.",
"cascade_toast": "Andra inställningar justerades för konsekvens: {n}",
"suggestion_resolves": "Tillämpa förslaget nedan ({val}) för att lösa detta",
"use_fix": "Använd {val}",
"watchdog": {
"interval": "Bör vara minst 2x samplingsintervallet ({si} s)",
"sampling": "Samplingsintervall bör vara högst hälften av vakthundsintervallet ({wi} s)"
},
"settings_banner": "{n} inställningskonflikt{s} kontrollera de markerade avsnitten och åtgärda dem innan du sparar.",
"settings_banner": "Inställningskonflikter: {n}. Kontrollera de markerade avsnitten och åtgärda dem innan du sparar.",
"settings_banner_btn": "Gå till första"
},
"hdr": {
@@ -356,7 +364,8 @@
"pg_outcome": "Simuleringsresultat",
"pg_across_cycles": "Över dina cykler",
"community_store": "Gemenskapsbutik",
"online_account": "Gemenskapsbutik och onlinefunktioner"
"online_account": "Gemenskapsbutik och onlinefunktioner",
"import_power_history": "Importera effekthistorik"
},
"health": {
"fair": "Acceptabel profilkvalitet",
@@ -364,6 +373,7 @@
"poor": "⚠ Dålig profilkvalitet"
},
"lbl": {
"drag_to_resize": "Dra för att ändra storlek",
"actions": "Åtgärder",
"activity": "Aktivitet",
"administrators": "Administratörer",
@@ -434,7 +444,7 @@
"from": "Från",
"gap_s": "Lucka (s)",
"group_name": "Gruppnamn",
"head_trim": "Starttrimning (s)",
"head_trim": "Beskär start (s)",
"health": "Hälsa",
"hide_tabs": "Dölj flikar för icke-administratörer",
"in_use": "Används",
@@ -450,7 +460,7 @@
"metric": "Mått",
"mode_existing_profile": "Lägg till i befintlig profil",
"mode_new_profile": "Skapa ny profil",
"models_fine_tuned": "({count} modell{plural} finjusterad)",
"models_fine_tuned": "(finjusterade modeller: {count})",
"n_classic_suggestions": "{n} klassisk",
"n_ml_suggestions": "{n} ML",
"n_selected": "{n} valda",
@@ -537,7 +547,7 @@
"stage3": "Steg 3 DTW",
"stage4": "Steg 4 överensstämmelse",
"status": "Status",
"tail_trim": "Sluttrimning (s)",
"tail_trim": "Beskär slut (s)",
"timer_auto_pause": "Automatisk paus",
"timer_min": "min",
"timer_msg_placeholder": "Meddelande (valfritt, {device}/{program}/{minutes})",
@@ -677,7 +687,26 @@
"conflict_keep_mine": "Behåll mina",
"conflict_overwrite": "Skriv över",
"pg_anti_wrinkle": "Skrynkelskydd",
"font_size": "Panelens teckenstorlek"
"font_size": "Panelens teckenstorlek",
"hist_csv_data": "CSV-data",
"hist_from_recorder": "Eller läs den från Home Assistant",
"hist_since": "Sedan",
"days": "dagar",
"hist_keep": "Behåll den här cykeln",
"hist_looks_complete": "komplett",
"peak_power_short": "Topp",
"shape": "Form",
"hist_skip_idle": "inget kördes",
"hist_skip_sparse": "avläsningar för långt ifrån varandra",
"hist_skip_short": "för få avläsningar",
"hist_skip_long": "ingen paus lång nog att dela på",
"hist_reason_short": "kortare än den här apparatens kortaste verkliga cykel",
"hist_reason_no_end": "avslutades aldrig rent",
"task_history_import": "Söker igenom effekthistorik",
"task_history_import_apply": "Importerar cykler",
"evidence_real_cycles": "Cykler den här maskinen har kört",
"evidence_reference_cycles": "Nedladdade från gemenskapsbutiken",
"evidence_backfill_cycles": "Hittade i importerad effekthistorik"
},
"log": {
"all_levels": "Alla nivåer",
@@ -756,9 +785,15 @@
"store_share": "Dela till gemenskapsbutiken",
"store_share_device": "Dela den här apparaten",
"export_select": "Export - välj data",
"import_wizard": "Import - välj data"
"import_wizard": "Import - välj data",
"history_import": "Importera effekthistorik"
},
"msg": {
"tail_trim_hint": "Ta bort så här många sekunder från slutet",
"store_sibling_hint": "Finns inget delat för exakt din modell? En närbesläktad modell från samma märke är oftast en bra utgångspunkt.",
"store_declare_appliance": "Berätta för WashData vilken apparat du har, så visar den här fliken de färdiga inställningar andra har delat för den. Du kan också skriva ett märke ovanför för att se dig omkring.",
"refresh_catalog_hint": "Gemenskapens listor över märken och apparater cachelagras för att gemenskapsbutiken ska hålla sig inom sin dagliga gräns. Uppdatera för att hämta poster som andra har lagt till eller godkänt.",
"head_trim_hint": "Ta bort så här många sekunder från början",
"appliance_monitor": "Apparatövervakning",
"artifact_dip_detail": "Föll under det normala effektbandet i ~{n} s.",
"artifact_footer": "Markerad i grafen ovan. Dessa är övergående artefakter (t.ex. dörren öppnas mitt i cykeln), inte nödvändigtvis problem.",
@@ -769,7 +804,7 @@
"automations_intro": "WashData utlöser {start} / {end}-händelser och tillhandahåller entiteter aviseringar och åtgärder byggs bäst som vanliga Home Assistant-automatiseringar. Automatiseringar som använder den här enheten visas nedan.",
"cleanup_intro": "Alla märkta cykler är överlagda. Kryssa i avvikare och ta bort dem för att rensa profilen.",
"clear_debug_hint": "Ta bort lagrad felsökningsdata för att frigöra utrymme.",
"collecting_data": "Samlar in data: {need} cykel{plural} kvar innan finjustering kan starta ({current}/{min}).",
"collecting_data": "Samlar in data. Cykler som återstår innan finjustering kan starta: {need} ({current}/{min}).",
"compare_overlay_profiles": "Lägg över profiler (svag)",
"compare_profiles_tip": "Lägg över andra profilkuvert på diagrammet ovan för att se vilket som passar bäst för denna cykel.",
"compare_selected_cycles": "Valda cykler (solid) visa / dölj",
@@ -779,7 +814,7 @@
"cycles_deleted": "{count} cykler borttagna",
"enough_data": "Tillräckligt med data för att lära sig av ({current}/{min} cykler).",
"export_description": "Välj exakt vilka profiler, cykler, inställningar och mer som ska exporteras till JSON, eller analysera en fil och importera bara de delar du vill ha.",
"feedback_cycles_pending": "{n} cykel{s} att granska",
"feedback_cycles_pending": "Att granska: {n}",
"feedback_prompt": "Bekräfta att det var rätt, korrigera programmet eller ignorera.",
"feedback_relabel_hint": "Att märka om den här cykeln löser också granskningen.",
"filter_by_profile": "Filtrera efter profil…",
@@ -856,7 +891,6 @@
"pg_stress_synthetic": "inaktiv simulering börjar här",
"pg_sweep_intro": "Tänk om {param} vore annorlunda? Testa {steps} värden över dina senaste {cycles} cykler för att hitta inställningen där flest cykler matchas korrekt.",
"pg_sweep_step": "Steg {done} / {total}",
"pg_undetected": "{n} cykel{s} oupptäckt",
"pg_verdict_bad": "Behöver åtgärdas: många cykler förblir oupptäckta.",
"pg_verdict_good": "Väl inställt: de flesta cykler identifieras och matchas korrekt.",
"pg_verdict_ok": "Godtagbart: några cykler missades. Prova att sänka startröskeln.",
@@ -887,6 +921,7 @@
"review_recorded_tip": "Markera detta som en handplockad referenscykel för sitt program - samma roll som en manuellt inspelad cykel. Referenscykler hålls alltid, såddar den matchande mallen och släpps aldrig vid rengöring. (Detta är den \"gyllene\"/inspelade flaggan; båda är samma sak.)",
"review_tags_tip": "Valfria flaggor som beskriver vad som gick fel med den här cykeln, så träning och städning kan förklara det.",
"review_to_cycles": "Öppna granskningskön för Cykler",
"samples_decimated": "Visar {shown} av {total} sampel (gallrat för visning; toppar behålls). En bred lucka här är gallring, inte saknade data.",
"saving_triggers_reload": "Sparande utlöser en integration-omladdning. HA-enheter kan kortvarigt visas som otillgängliga.",
"search_placeholder": "Sök inställningar…",
"see_recorder": "Se inspelningswidgeten nedan",
@@ -1006,10 +1041,33 @@
"sug_mute_failed": "Kunde inte tysta förslaget",
"sug_unmuted_all": "Tysta förslag återställda",
"n_suggestions_muted": "{count} tystade; auto-tunern föreslår inte dessa.",
"font_size_hint": "Gör allt i den här panelen större eller mindre. Gäller för ditt konto på den här enheten."
"font_size_hint": "Gör allt i den här panelen större eller mindre. Gäller för ditt konto på den här enheten.",
"import_history_description": "Hade du redan en smart kontakt innan du började med WashData? Ladda upp en historikexport från dess effektsensor, eller låt den läsas direkt från Home Assistant, och den vanliga detekteringen körs över den så att tidigare cykler dyker upp i din Cykler-lista, klara att namnges.",
"hist_input_hint": "Ladda upp en CSV-fil som hämtats från Historik-panelen (entitet, tillstånd, senast ändrad), eller låt WashData läsa sensorns historik direkt. Detekteringen körs sedan över den precis som live, och du väljer vilka av cyklerna den hittar du vill behålla.",
"hist_recorder_hint": "Läser från det datum du väljer fram till nu. Home Assistant sparar detaljerad historik i 10 dagar som standard och därefter bara timmedelvärden, som är för grova för att detektera cykler ur - välj ett datum längre tillbaka bara om din recorder är inställd på att spara mer.",
"hist_scanning": "Din historik spelas upp genom detekteringen. Detta körs i bakgrunden - du kan stänga den här dialogen och komma tillbaka till den senare.",
"hist_imported_count": "{n} cykler importerade.",
"hist_duplicates": "{n} var redan importerade och hoppades över.",
"hist_capped": "Gränsen per enhet för importerade cykler nåddes; resten sparades inte.",
"hist_next_step": "De finns i din Cykler-lista, märkta som importerad historik. Öppna en och använd Märk för att namnge programmet den hör till.",
"hist_rows_read": "{n} avläsningar lästa",
"hist_entity_substituted": "läste {used} (den här enheten är konfigurerad för {wanted})",
"hist_breaks": "{n} luckor där sensorn var otillgänglig",
"hist_other_entity": "{n} avläsningar för andra entiteter ignorerade",
"hist_skipped_spans": "Överhoppade sträckor",
"hist_settings_used": "Detekterad med den här enhetens nuvarande inställningar (minimieffekt {w} W, avfördröjning {s} s).",
"hist_none_found": "Inga cykler kunde detekteras i den historiken.",
"hist_found": "Hittade {n} cykler. Avmarkera allt som inte ser ut som en verklig körning - inget sparas förrän du importerar.",
"hist_scan_capped": "Endast de första kandidaterna visas ({n} hittades).",
"hist_recorder_empty": "Home Assistant har ingen detaljerad historik för den här sensorn i det tidsfönstret.",
"hist_scan_failed": "Sökningen misslyckades.",
"hist_scan_expired": "Den sökningen är inte längre tillgänglig. Sök igen.",
"hist_import_failed": "Importen misslyckades.",
"imported_history_readonly": "Detekterad i importerad effekthistorik. Den påverkar programmatchningen men räknas inte in i din statistik och kan inte beskäras eller delas. Märk den för att namnge programmet."
},
"pg_desc": {
"dishwasher_end_spike_quiet_release": "Diskmaskin: tysta sekunder efter förväntad varaktighet innan väntan på tömning vid cykelslut frisläpps",
"smart_termination_duration_ratio": "Andel av det matchade programmets förväntade varaktighet som en cykel måste nå innan smart avslutning får avsluta den i förtid; sänk den för last- eller temperaturberoende maskiner",
"completion_min_seconds": "Kortaste körning som räknas som en riktig cykel",
"end_repeat_count": "Antal låga avläsningar i rad innan avslut",
"interrupted_min_seconds": "Korta cykler markeras som avbrutna",
@@ -1421,6 +1479,10 @@
"doc": "Lagra spårningen av full effekt och matchande felsökningsdata för varje cykel. Användbar för felsökning men ökar lagringsstorleken.",
"label": "Spara felsökningsspår"
},
"smart_termination_duration_ratio": {
"doc": "Hur långt in i det matchade programmets förväntade varaktighet en cykel måste vara innan smart avslutning får avsluta den i förtid när effekten sjunker. Den förväntade varaktigheten är programmets genomsnitt, så på apparater vars körtid varierar mycket - tvättmaskiner med kallt vinter- kontra varmt sommarinloppsvatten, torktumlare med fuktsensor, lastberoende program - avslutas ungefär hälften av alla körningar kortare än det genomsnittet och får aldrig den snabba avslutningen, utan avslutas först minuter senare via reserv-timeouten. Sänk detta värde (t.ex. 0,85) på sådana maskiner så att den tidiga avslutningen ändå utlöses; höj det mot 1,0 för att vara mer försiktig. Lämna tomt för standardvärdet (0,98, eller 0,99 för diskmaskiner). Den kan bara avsluta en cykel tidigare, aldrig senare, och utlöses aldrig vid en tvetydig eller osäker matchning.",
"label": "Kvot för smart avslutning"
},
"smoothing_window": {
"doc": "Hur mycket råeffektsignalen utjämnas. Låg (2) är lyhörd men bullrig; hög (5) jämnar ut spikar men lägger till eftersläpning.",
"label": "Utjämningsfönster"
@@ -1551,6 +1613,10 @@
"door_end_dwell_seconds": {
"label": "Dörröppningens uppehållstid vid avslut",
"doc": "Hur länge dörren måste förbli öppen innan WashData avslutar cykeln, när \"Dörren öppnas automatiskt vid avslut\" är aktiverat. Tillräckligt länge för att ignorera snabb tilläggning av ett fat (standard 60 s), tillräckligt kort för att avsluta snabbt när maskinen poppar upp dörren."
},
"profile_evidence_sources": {
"label": "Cykler som formar ett program",
"doc": "Vilka cykler som används för att bygga upp effektkurvan för varje program och för att matcha en avslutad cykel mot den. Avmarkerar du en typ formar den inte längre dina program, utan att något tas bort - cyklerna ligger kvar i din Cykler-lista och kan fortfarande märkas eller tas bort. Praktiskt om du inte litar på importerade data. Statistiken påverkas inte: den räknar alltid bara de cykler som den här maskinen verkligen har kört. Att avmarkera allt ignoreras, eftersom ett program utan cykler bakom sig aldrig skulle kunna matcha."
}
},
"setting_group": {
@@ -1634,6 +1700,9 @@
},
"basic_configuration": {
"label": "Grundkonfiguration"
},
"profile_evidence": {
"label": "Profilunderlag"
}
},
"status": {
@@ -1658,7 +1727,8 @@
"trimming": "Beskär…",
"splitting": "Delar upp…",
"deleting": "Raderar…",
"imported": "Importerad"
"imported": "Importerad",
"preparing": "Förbereder…"
},
"suggestion": {
"both_agree": "WashData rekommenderar",
@@ -1754,7 +1824,7 @@
"thr_batch": "Hålls precis över den lägsta aktiva effekten vid p05 över {cycles} cykler ({p05}W) så att en start fångas så tidigt som möjligt och stopptröskeln stannar under maskinens lägsta driftseffekt.",
"tol_per_profile": "p75 för varaktighetsvariansen per profil över {profiles} profiler ({cycles} cykler); snäva profiler bestraffas inte.",
"tol_pooled": "Baserat på sammanslagen varaktighetsvarians för {cycles} senaste märkta cykler (p95 avvikelse={dev}).",
"watchdog": "Hålls så lågt som är säkert (strax över p95-uppdateringsmellanrummet på {p95}s, min 30s) så att stillestånd upptäcks snabbt utan falska stopp."
"watchdog": "Hålls så lågt som är säkert (strax över p95-uppdateringsmellanrummet på {p95}s och minst 2x samplingsintervallet på {median}s, min. 30s) så att stillestånd upptäcks snabbt utan falska stopp."
},
"exclusions": {
"summary": "Uteslöt {total} feldetekterade cykler: {parts}.",
@@ -1801,6 +1871,7 @@
"wrong_profile": "Fel profil"
},
"toast": {
"catalog_refreshed": "Gemenskapskatalogen har uppdaterats",
"access_saved": "Åtkomstkontroll sparad",
"all_wiped": "All data rensad",
"analysis_complete_none": "Analys klar: inga nya förslag",
@@ -1812,7 +1883,7 @@
"cycle_labelled": "Cykel märkt",
"cycle_paused": "Cykel pausad",
"cycle_resumed": "Cykel återupptagen",
"cycle_trimmed": "Cykel trimmad",
"cycle_trimmed": "Cykel beskuren",
"cycles_merged": "Cykler sammanslagna",
"envelope_rebuilt": "Kuvert ombyggt",
"envelopes_rebuilt": "Kuvert ombyggda",
@@ -1906,7 +1977,9 @@
"store_download_failed": "Nedladdning misslyckades: {error}",
"store_download_nothing": "Inget nytt att ladda ner -- den här inställningen finns redan på din apparat.",
"export_selective_done": "Export nedladdad",
"import_selective_done": "Importerade {profiles} profil(er) och {cycles} cykel/cykler"
"import_selective_done": "Importerade {profiles} profil(er) och {cycles} cykel/cykler",
"hist_csv_required": "Ladda in en CSV-fil eller klistra in dess innehåll först",
"file_read_failed": "Kunde inte läsa den filen"
},
"trend": {
"down": "Nedåtgående trend",
@@ -1955,6 +2028,10 @@
"finished": "Cykeln nådde ett sluttillstånd och avslutades."
},
"store": {
"your_model_tip": "Det här är apparaten du har angett i Inställningar",
"your_model": "Din apparat",
"search_brand_ph": "Sök efter märke…",
"programs_count": "Program: {n}",
"browse": "Bläddra",
"device": "Enhet",
"favorites": "Favoriter",
@@ -78,9 +78,12 @@
"awaiting": "Onay bekleniyor",
"imported_tip": "Topluluk mağazasından içe aktarıldı. Yalnızca eşleştirme için kullanılır, istatistiklere sayılmaz.",
"not_importable": "burada geçersiz",
"exists": "mevcut"
"exists": "mevcut",
"backfilled_tip": "İçe aktarılan güç geçmişinde algılandı. Yalnızca program eşleştirmesini etkiler, istatistiklere sayılmaz."
},
"btn": {
"set_brand_model": "Marka ve modeli ayarla",
"refresh_catalog": "Kataloğu yenile",
"add_device": "+ Cihaz ekle",
"add_device_tip": "Başka bir WashData cihazı ekleyin",
"add_maintenance": "Bakım kaydı ekle",
@@ -241,7 +244,12 @@
"import_selected": "Seçileni içe aktar",
"back": "Geri",
"mute_suggestion": "Bu ayarı önerme",
"reset_muted": "Susturulanları sıfırla"
"reset_muted": "Susturulanları sıfırla",
"import_power_history": "Güç geçmişini içe aktar",
"hist_read_recorder": "Home Assistant'tan oku",
"hist_scan": "Döngüleri tara",
"hist_import_n": "{n} döngüyü içe aktar",
"hist_goto_cycles": "Döngüleri göster"
},
"conflict": {
"anti_wrinkle_exit": {
@@ -253,14 +261,14 @@
"start": "Kırışıklık Önleme Maks. Gücü'nün altında olmalıdır ({max} W)"
},
"attn_sub": "Kaydetmeden önce çakışmaları düzeltin",
"attn_title": "{n} ayar çakışması{s}",
"settings_banner": "{n} ayar çakışması{s} vurgulanan bölümleri kontrol edin ve kaydetmeden önce düzeltin.",
"attn_title": "Ayar çakışmaları: {n}",
"settings_banner": "Ayar çakışmaları: {n}. Vurgulanan bölümleri kontrol edin ve kaydetmeden önce düzeltin.",
"settings_banner_btn": "İlkine git",
"confidence": {
"auto": "Eşleşme Eşiğinde veya üzerinde olmalıdır ({match})",
"learning": "Eşleşme Eşiğinde veya altında olmalıdır ({match})",
"learning": "Eşleşme Eşiğinde veya üzerinde olmalıdır ({match})",
"match_for_auto": "Otomatik Etiket Güveni'nde veya altında olmalıdır ({alc})",
"match_for_learning": "Öğrenme Güveni'nde veya üzerinde olmalıdır ({lc})"
"match_for_learning": "Öğrenme Güveni'nde veya altında olmalıdır ({lc})"
},
"duration_ratio": {
"max": "Min. Süre Oranından büyük olmalıdır ({min})",
@@ -298,7 +306,7 @@
"match": "Eşleşmeme Eşiğinin üzerinde olmalıdır ({un})",
"unmatch": "Eşleşme Eşiğinin altında olmalıdır ({match}); aksi takdirde onaylanan bir eşleşme anında iptal olur"
},
"cascade_toast": "Tutarlılık için {n} ayar{s} daha otomatik olarak düzenlendi.",
"cascade_toast": "Tutarlılık için düzenlenen diğer ayarlar: {n}",
"suggestion_resolves": "Bunu düzeltmek için aşağıdaki bekleyen öneriyi ({val}) etkinleştirin",
"use_fix": "{val} kullan",
"watchdog": {
@@ -356,7 +364,8 @@
"pg_outcome": "Simülasyon sonucu",
"pg_across_cycles": "Tüm döngülerinizde",
"community_store": "Topluluk Mağazası",
"online_account": "Topluluk Mağazası ve çevrimiçi özellikler"
"online_account": "Topluluk Mağazası ve çevrimiçi özellikler",
"import_power_history": "Güç geçmişini içe aktar"
},
"health": {
"fair": "Kabul edilebilir profil kalitesi",
@@ -364,6 +373,7 @@
"poor": "⚠ Düşük profil kalitesi"
},
"lbl": {
"drag_to_resize": "Yeniden boyutlandırmak için sürükleyin",
"actions": "Eylemler",
"activity": "Aktivite",
"administrators": "Yöneticiler",
@@ -434,7 +444,7 @@
"from": "Başlangıç",
"gap_s": "Boşluk (s)",
"group_name": "Grup adı",
"head_trim": "Baş Kırpma (s)",
"head_trim": "Baştan Kırpma (s)",
"health": "Sağlık",
"hide_tabs": "Yönetici olmayanlar için sekmeleri gizle",
"in_use": "Kullanımda",
@@ -450,7 +460,7 @@
"metric": "Metrik",
"mode_existing_profile": "Mevcut Profile Ekle",
"mode_new_profile": "Yeni Profil Oluştur",
"models_fine_tuned": "({count} model{plural} ince ayarlı)",
"models_fine_tuned": "(ince ayarlı modeller: {count})",
"n_classic_suggestions": "{n} klasik",
"n_ml_suggestions": "{n} ML",
"n_selected": "{n} seçili",
@@ -532,7 +542,7 @@
"stage3": "Aşama 3 DTW",
"stage4": "Aşama 4 uyum",
"status": "Durum",
"tail_trim": "Kuyruk Kırpma (s)",
"tail_trim": "Sondan Kırpma (s)",
"timer_auto_pause": "Otomatik duraklatma",
"timer_min": "dk.",
"timer_msg_placeholder": "Mesaj (isteğe bağlı, {device}/{program}/{minutes})",
@@ -677,7 +687,26 @@
"conflict_import_copy": "Kopya olarak içe aktar",
"conflict_keep_mine": "Benimkini koru",
"conflict_overwrite": "Üzerine yaz",
"font_size": "Panel yazı tipi boyutu"
"font_size": "Panel yazı tipi boyutu",
"hist_csv_data": "CSV verisi",
"hist_from_recorder": "Veya Home Assistant'tan okuyun",
"hist_since": "Başlangıç tarihi",
"days": "gün",
"hist_keep": "Bu döngüyü sakla",
"hist_looks_complete": "tamamlanmış",
"peak_power_short": "Tepe",
"shape": "Şekil",
"hist_skip_idle": "hiçbir şey çalışmıyor",
"hist_skip_sparse": "okumalar birbirinden çok uzak",
"hist_skip_short": "çok az okuma",
"hist_skip_long": "bölmeye yetecek kadar uzun bir ara yok",
"hist_reason_short": "bu cihazın en kısa gerçek döngüsünden daha kısa",
"hist_reason_no_end": "hiç düzgün şekilde bitmedi",
"task_history_import": "Güç geçmişi taraması",
"task_history_import_apply": "Döngüleri içe aktarma",
"evidence_real_cycles": "Bu makinenin çalıştırdığı döngüler",
"evidence_reference_cycles": "Topluluk mağazasından indirilenler",
"evidence_backfill_cycles": "İçe aktarılan güç geçmişinde bulunanlar"
},
"log": {
"all_levels": "Tüm seviyeler",
@@ -756,9 +785,15 @@
"store_share": "Topluluk mağazasında paylaş",
"store_share_device": "Bu cihazı paylaş",
"export_select": "Dışa aktarma - veri seçin",
"import_wizard": "İçe aktarma - veri seçin"
"import_wizard": "İçe aktarma - veri seçin",
"history_import": "Güç geçmişini içe aktar"
},
"msg": {
"tail_trim_hint": "Sondan kaldırılacak saniye sayısı",
"store_sibling_hint": "Tam olarak sizin modeliniz için paylaşılmış bir şey yok mu? Aynı markanın yakın bir modeli genellikle iyi bir başlangıç noktasıdır.",
"store_declare_appliance": "WashData'ya hangi cihaza sahip olduğunuzu bildirin; bu sekme, başkalarının o cihaz için paylaştığı programları ve kayıtları gösterir. Ayrıca yukarıya bir marka yazıp göz atabilirsiniz.",
"refresh_catalog_hint": "Topluluk marka ve cihaz listeleri, paylaşılan mağazanın günlük okuma kotası içinde kalması için önbelleğe alınır. Başkalarının eklediği veya onayladığı kayıtları almak için yenileyin.",
"head_trim_hint": "Baştan kaldırılacak saniye sayısı",
"appliance_monitor": "Cihaz monitörü",
"artifact_dip_detail": "Normal güç bandının altında yaklaşık ~{n} saniye sürdü.",
"artifact_footer": "Yukarıdaki grafikte vurgulanmıştır. Bunlar geçici eserlerdir (örn. döngünün ortasında kapının açılması), mutlaka sorun teşkil etmez.",
@@ -769,7 +804,7 @@
"automations_intro": "WashData, {start} / {end} olaylarını tetikler ve varlıkları gösterir; bu nedenle bildirimler ve eylemler en iyi şekilde normal Home Assistant otomasyonları olarak oluşturulur. Bu cihazı kullanan otomasyonlar aşağıda görünür.",
"cleanup_intro": "Tüm etiketli döngüler üst üste bindirilmiş. Aykırı değerleri işaretleyip silerek profili temizleyin.",
"clear_debug_hint": "Saklanan hata ayıklama verilerini kaldırarak boş alan açın.",
"collecting_data": "Veri toplanıyor: ince ayar başlamadan önce {need} döngü{plural} daha gerekiyor ({current}/{min}).",
"collecting_data": "Veri toplanıyor. İnce ayarın başlaması için gereken döngü sayısı: {need} ({current}/{min}).",
"compare_overlay_profiles": "Profilleri üst üste bindirin (soluk)",
"compare_profiles_tip": "Hangisinin bu döngüye en uygun olduğunu görmek için diğer profil zarflarını yukarıdaki tabloya yerleştirin.",
"compare_selected_cycles": "Seçili döngüler (katı) göster / gizle",
@@ -779,7 +814,7 @@
"cycles_deleted": "{count} döngü silindi",
"enough_data": "Öğrenmek için yeterli veri ({current}/{min} döngü).",
"export_description": "JSON'a dışa aktarılacak profilleri, döngüleri, ayarları ve daha fazlasını tam olarak seçin ya da bir dosyayı analiz edip yalnızca istediğiniz kısımları içe aktarın.",
"feedback_cycles_pending": "İncelenecek {n} döngü{s}",
"feedback_cycles_pending": "İncelenecek: {n}",
"feedback_prompt": "Doğru olduğunu onaylayın, programı düzeltin veya yoksayın.",
"feedback_relabel_hint": "Bu döngüyü yeniden etiketlemek de bunu çözer.",
"filter_by_profile": "Profile göre filtrele…",
@@ -856,7 +891,6 @@
"pg_stress_synthetic": "bekleme simülasyonu burada başlar",
"pg_sweep_intro": "{param} farklı olsaydı ne olurdu? En çok döngünün doğru şekilde eşleştirildiği ayarı bulmak için son {cycles} döngünüzde {steps} değeri test edin.",
"pg_sweep_step": "Adım {done} / {total}",
"pg_undetected": "{n} döngü{s} algılanmadı",
"pg_verdict_bad": "Dikkat gerekiyor: birçok döngü algılanmadan geçiyor.",
"pg_verdict_good": "İyi ayarlanmış: çoğu döngü doğru şekilde tanımlanıp eşleştiriliyor.",
"pg_verdict_ok": "Kabul edilebilir: bazı döngüler kaçırıldı. Başlangıç eşiğini düşürmeyi deneyin.",
@@ -887,6 +921,7 @@
"review_recorded_tip": "Bunu, programı için özenle seçilmiş bir referans döngüsü olarak işaretleyin; manuel olarak kaydedilen bir döngüyle aynı rol. Referans döngüleri her zaman tutulur, eşleşen şablonun çekirdeği oluşturulur ve hiçbir zaman temizleme işlemi nedeniyle bırakılmaz. (Bu \"altın\"/kaydedilmiş bayraktır; ikisi de aynı şeydir.)",
"review_tags_tip": "Bu döngüde neyin yanlış gittiğini açıklayan isteğe bağlı bayraklar, böylece eğitim ve temizlik bunu açıklayabilir.",
"review_to_cycles": "Döngü inceleme kuyruğunu aç",
"samples_decimated": "{total} örnekten {shown} tanesi gösteriliyor (görüntü için seyreltildi; tepe noktaları korundu). Buradaki geniş bir boşluk seyreltmedir, eksik veri değildir.",
"saving_triggers_reload": "Kaydetme bir entegrasyon yeniden yüklemesini tetikler. HA varlıkları kısa süreliğine kullanılamaz olarak görünebilir.",
"search_placeholder": "Ayar ara…",
"see_recorder": "Aşağıdaki kaydedici widget'ına bakın",
@@ -1006,7 +1041,29 @@
"sug_mute_failed": "Öneri susturulamadı",
"sug_unmuted_all": "Susturulan öneriler sıfırlandı",
"n_suggestions_muted": "{count} susturuldu; öneri motoru bunları önermeyecek.",
"font_size_hint": "Bu paneldeki her şeyi büyütün veya küçültün. Bu cihazdaki hesabınıza uygulanır."
"font_size_hint": "Bu paneldeki her şeyi büyütün veya küçültün. Bu cihazdaki hesabınıza uygulanır.",
"import_history_description": "WashData'dan önce de akıllı bir priziniz var mıydı? Güç sensörünün geçmiş dışa aktarımını yükleyin veya doğrudan Home Assistant'tan okutun; normal algılama bunun üzerinde çalışır ve geçmiş döngüler adlandırılmaya hazır şekilde Döngüler listenizde görünür.",
"hist_input_hint": "Geçmiş panelinden indirdiğiniz bir CSV dosyasını yükleyin (entity, state, last changed) veya WashData'nın sensörün geçmişini doğrudan okumasına izin verin. Ardından algılama, tıpkı canlı çalışırken olduğu gibi bunun üzerinde çalışır ve bulunan döngülerden hangilerini saklayacağınızı siz seçersiniz.",
"hist_recorder_hint": "Seçtiğiniz tarihten şimdiye kadar okur. Home Assistant varsayılan olarak ayrıntılı geçmişi 10 gün tutar, sonrasında yalnızca saatlik ortalamaları saklar; bunlar döngü algılamak için fazla kabadır - yalnızca recorder daha uzun süre saklayacak şekilde ayarlıysa daha eski bir tarih seçin.",
"hist_scanning": "Geçmişiniz algılayıcı üzerinden yeniden oynatılıyor. Bu işlem arka planda çalışır - bu pencereyi kapatıp daha sonra geri dönebilirsiniz.",
"hist_imported_count": "{n} döngü içe aktarıldı.",
"hist_duplicates": "{n} tanesi daha önce içe aktarılmıştı ve atlandı.",
"hist_capped": "İçe aktarılan döngüler için cihaz başına sınıra ulaşıldı; kalanlar kaydedilmedi.",
"hist_next_step": "Döngüler listenizde, içe aktarılmış geçmiş olarak işaretli halde duruyorlar. Birini açın ve ait olduğu programı adlandırmak için Etiketle'yi kullanın.",
"hist_rows_read": "{n} okuma alındı",
"hist_entity_substituted": "{used} okundu (bu cihaz {wanted} için yapılandırılmış)",
"hist_breaks": "sensörün kullanılamadığı {n} boşluk",
"hist_other_entity": "diğer varlıklara ait {n} okuma yoksayıldı",
"hist_skipped_spans": "Atlanan aralıklar",
"hist_settings_used": "Bu cihazın mevcut ayarlarıyla algılandı (minimum güç {w} W, kapatma gecikmesi {s} s).",
"hist_none_found": "Bu geçmişte hiçbir döngü algılanamadı.",
"hist_found": "{n} döngü bulundu. Gerçek bir çalışma gibi görünmeyenlerin işaretini kaldırın - içe aktarana kadar hiçbir şey kaydedilmez.",
"hist_scan_capped": "Yalnızca ilk adaylar gösteriliyor (toplam {n} bulundu).",
"hist_recorder_empty": "Home Assistant'ta bu sensör için o aralıkta ayrıntılı geçmiş yok.",
"hist_scan_failed": "Tarama başarısız oldu.",
"hist_scan_expired": "Bu tarama artık kullanılamıyor. Lütfen yeniden tarayın.",
"hist_import_failed": "İçe aktarma başarısız oldu.",
"imported_history_readonly": "İçe aktarılan güç geçmişinde algılandı. Program eşleştirmesini etkiler ancak istatistiklerinize sayılmaz, kırpılamaz veya bölünemez. Programını adlandırmak için etiketleyin."
},
"pg_desc": {
"completion_min_seconds": "Gerçek döngü sayılan en kısa çalışma",
@@ -1035,7 +1092,8 @@
"dtw_refine_top_n": "Aşama 3: DTW'nin yeniden puanladığı aday sayısı; doğru profil 4-5. sıraya düşüyorsa 7-9'a yükseltin (varsayılan 5)",
"duration_scale": "Aşama 4: süre uyumunun yarılandığı logaritmik oran; küçük = daha sert ceza (varsayılan 0.175)",
"energy_scale": "Aşama 4: enerji uyumunun yarılandığı logaritmik oran; küçük = daha sert ceza (varsayılan 0.25)",
"dishwasher_end_spike_quiet_release": "Bulaşık makinesi: beklenen süreden sonra döngü sonu tahliye beklemesi bırakılmadan önceki sessiz saniyeler"
"dishwasher_end_spike_quiet_release": "Bulaşık makinesi: beklenen süreden sonra döngü sonu tahliye beklemesi bırakılmadan önceki sessiz saniyeler",
"smart_termination_duration_ratio": "Eşleşen programın beklenen süresinin, Akıllı Sonlandırma'nın döngüyü erken bitirebilmesi için döngünün ulaşması gereken kesri; yüke veya sıcaklığa bağlı makinelerde düşürün"
},
"phase_desc": {
"anti_crease": "Kırışıklıkları azaltmak için tamamlandıktan sonra ara sıra kısa yuvarlanmalar.",
@@ -1390,7 +1448,7 @@
"label": "Min. Süre Oranı"
},
"profile_match_threshold": {
"doc": "Bir program tanımlamasını kabul etmek için döngü sonunda gereken minimum benzerlik puanı (0-1). Yanlış tanımlamaları azaltmak için kaldırın; makinenizin programları eşleşmiyorsa düşürün. Varsayılan 0,4 ihtiyatlı bir başlangıç noktasıdır.",
"doc": "Bir program tanımlamasını kabul etmek için döngü sonunda gereken minimum benzerlik puanı (0-1). Yanlış tanımlamaları azaltmak için kaldırın; makinenizin programları eşleşmiyorsa düşürün. Varsayılan 0,4 ihtiyatlı bir başlangıç noktasıdır.",
"label": "Eşleşme Eşiği"
},
"profile_unmatch_threshold": {
@@ -1417,6 +1475,10 @@
"doc": "Her döngü için tam güç takibini ve eşleşen hata ayıklama verilerini saklayın. Sorun giderme için kullanışlıdır ancak depolama boyutunu artırır.",
"label": "Hata Ayıklama İzlerini Kaydet"
},
"smart_termination_duration_ratio": {
"doc": "Güç düştüğünde Akıllı Sonlandırma'nın bir döngüyü erken bitirebilmesi için, döngünün eşleşen programın beklenen süresinin ne kadarına ilerlemiş olması gerektiğini belirler. Beklenen süre, programın ortalamasıdır; bu nedenle çalışma süresi çok değişen cihazlarda (kışın soğuk, yazın sıcak şebeke suyuyla çalışan çamaşır makineleri, sensörle kurutan kurutucular, yüke bağlı programlar) tüm çalışmaların yaklaşık yarısı bu ortalamadan daha kısa biter ve hızlı bitişi hiç alamaz, yalnızca yedek zaman aşımıyla dakikalar sonra sona erer. Bu makinelerde erken bitişin yine de devreye girmesi için bu değeri düşürün (örn. 0,85); daha ihtiyatlı olmak için 1,0'a doğru yükseltin. Varsayılan (0,98, bulaşık makineleri için 0,99) için boş bırakın. Bir döngüyü yalnızca daha erken bitirebilir, asla daha geç bitiremez ve belirsiz veya düşük güvenilirlikli bir eşleşmede asla devreye girmez.",
"label": "Akıllı Sonlandırma Oranı"
},
"smoothing_window": {
"doc": "Ham güç sinyalinin ne kadar yumuşatıldığı. Düşük (2) duyarlıdır ancak gürültülüdür; yüksek (5) ani artışları yumuşatır ancak gecikme ekler.",
"label": "Yumuşatma Penceresi"
@@ -1434,7 +1496,7 @@
"label": "Başlangıç Eşiği"
},
"stop_threshold_w": {
"doc": "Düşmede gecikme geri sayımı başlamadan önce güç bu seviyenin altına düşmelidir. Bunu Başlangıç Eşiğinin altına ayarlayın; aralarındaki boşluk, titremeyi önleyen histerezis bandıdır. Çok yükseğe ayarlanırsa, düşük güçlü fazlar (durulamada bekletme, kırışık önleme) hatalı şekilde bitiş sırasını tetikler.",
"doc": "Düşmede gecikme geri sayımı başlamadan önce güç bu seviyenin altına düşmelidir. Bunu Başlangıç Eşiğinin altına ayarlayın; aralarındaki boşluk, titremeyi önleyen histerezis bandıdır. Çok yükseğe ayarlanırsa, düşük güçlü fazlar (durulamada bekletme, kırışık önleme) hatalı şekilde bitiş sırasını tetikler.",
"label": "Durdurma Eşiği"
},
"switch_entity": {
@@ -1551,6 +1613,10 @@
"dishwasher_end_spike_quiet_release": {
"label": "Pasif Kurutma Sessiz Serbest Bırakma",
"doc": "Döngü beklenen süresini aştıktan sonra, WashData bir son tahliye beklemeyi bırakıp döngüyü sonlandırmadan önce bulaşık makinesinin ne kadar süre sessiz (Durdurma Eşiği'nin altında) kalması gerektiğidir. Makineniz, gecikmeli bir son tahliyeden önce uzun ve sessiz bir kurutma aşamasına sahipse ve bu tahliye kaçırılıyorsa değeri artırın - daha geniş bir pencere, öğrenilen sürenin eski ortalamaya kilitlenmek yerine mevsimsel kaymayı (daha soğuk şebeke suyu = daha uzun döngüler) izlemesini sağlar. Bu ayar, dahili 30 dakikalık son tahliye tepesi sınırına göre beklemeyi yalnızca kısaltabilir, asla uzatamaz."
},
"profile_evidence_sources": {
"label": "Bir programı şekillendiren döngüler",
"doc": "Her programın güç eğrisini oluşturmak ve tamamlanmış bir döngüyü onunla eşleştirmek için hangi döngülerin kullanılacağı. Bir türün işaretini kaldırmak, hiçbir şey silmeden onun programlarınızı şekillendirmesini durdurur - döngüler Döngüler listenizde kalır ve yine etiketlenebilir veya kaldırılabilir. İçe aktarılan verilere güvenmiyorsanız kullanışlıdır. İstatistikler etkilenmez: her zaman yalnızca bu makinenin gerçekten çalıştırdığı döngüleri sayarlar. Her şeyin işaretini kaldırmak yok sayılır, çünkü arkasında hiç döngü olmayan bir program asla eşleşemez."
}
},
"setting_group": {
@@ -1634,6 +1700,9 @@
},
"basic_configuration": {
"label": "Temel yapılandırma"
},
"profile_evidence": {
"label": "Profil Kaynakları"
}
},
"status": {
@@ -1658,7 +1727,8 @@
"trimming": "Kırpılıyor…",
"splitting": "Bölünüyor…",
"deleting": "Siliniyor…",
"imported": "İçe aktarıldı"
"imported": "İçe aktarıldı",
"preparing": "Hazırlanıyor…"
},
"tab": {
"advanced": "Gelişmiş",
@@ -1688,6 +1758,7 @@
"wrong_profile": "Yanlış profil"
},
"toast": {
"catalog_refreshed": "Topluluk kataloğu yenilendi",
"access_saved": "Erişim denetimi kaydedildi",
"all_wiped": "Tüm veriler silindi",
"analysis_complete_none": "Analiz tamamlandı: yeni öneri yok",
@@ -1793,7 +1864,9 @@
"store_download_failed": "İndirme başarısız: {error}",
"store_download_nothing": "İndirilecek yeni bir şey yok - bu kurulum zaten cihazınızda.",
"export_selective_done": "Dışa aktarma indirildi",
"import_selective_done": "{profiles} profil ve {cycles} döngü içe aktarıldı"
"import_selective_done": "{profiles} profil ve {cycles} döngü içe aktarıldı",
"hist_csv_required": "Önce bir CSV dosyası yükleyin veya içeriğini yapıştırın",
"file_read_failed": "Bu dosya okunamadı"
},
"suggestion": {
"both_agree": "WashData öneriyor",
@@ -1889,7 +1962,7 @@
"thr_batch": "{cycles} çevrim boyunca p05 en düşük aktif gücün ({p05}W) hemen üzerinde tutuldu; böylece başlangıç olabildiğince erken yakalanır ve durdurma eşiği makinenin en düşük çalışma gücünün altında kalır.",
"tol_per_profile": "{profiles} profil boyunca ({cycles} çevrim) profil başına süre varyansının p75'i; tutarlı profiller cezalandırılmaz.",
"tol_pooled": "{cycles} son etiketli çevrimin birleştirilmiş süre varyansına dayalı (p95 sapma={dev}).",
"watchdog": "Güvenli olduğu kadar düşük tutuldu ({p95}s'lik p95 güncelleme boşluğunun hemen üzerinde, en az 30s); böylece takılmalar yanlış durdurmalar olmadan hızlıca yakalanır."
"watchdog": "Güvenli olduğu kadar düşük tutuldu (p95 güncelleme boşluğu {p95}s değerinin hemen üzerinde ve örnekleme aralığı {median}s değerinin en az 2 katı, en az 30s); böylece takılmalar yanlış durdurmalar olmadan hızlıca yakalanır."
},
"exclusions": {
"summary": "{total} yanlış algılanan döngü hariç tutuldu: {parts}.",
@@ -1955,6 +2028,10 @@
"finished": "Döngü, son duruma ulaştı ve sona erdi."
},
"store": {
"your_model_tip": "Bu, Ayarlar'da belirttiğiniz cihazdır",
"your_model": "Sizinki",
"search_brand_ph": "Markaya göre ara…",
"programs_count": "Programlar: {n}",
"browse": "Göz at",
"device": "Cihaz",
"favorites": "Favoriler",
@@ -78,9 +78,12 @@
"awaiting": "Очікує схвалення",
"imported_tip": "Імпортовано з магазину спільноти. Використовується лише для зіставлення, не враховується у статистиці.",
"not_importable": "недоступно",
"exists": "існує"
"exists": "існує",
"backfilled_tip": "Виявлено в імпортованій історії потужності. Впливає лише на зіставлення програм, не враховується у статистиці."
},
"btn": {
"set_brand_model": "Вказати бренд і модель",
"refresh_catalog": "Оновити каталог",
"add_device": "+ Додати пристрій",
"add_device_tip": "Додати інший пристрій WashData",
"add_maintenance": "Додати запис обслуговування",
@@ -234,14 +237,19 @@
"download_device": "Завантажити конфігурацію пристрою",
"share_device": "Поділитися конфігурацією пристрою",
"share_device_tip": "Поділитися програмами та налаштуваннями цього пристрою зі спільнотою",
"share_n": "Поділитися: {n} програм{s}",
"share_n": "Поділитися циклами: {n}",
"export_selected": "Експорт (вибрати дані)",
"export_all": "Швидкий експорт усього",
"import_raw": "Розширено: замінити все з JSON",
"download_export": "Завантажити експорт",
"analyze_import": "Проаналізувати файл",
"import_selected": "Імпортувати вибране",
"back": "Назад"
"back": "Назад",
"import_power_history": "Імпорт історії потужності",
"hist_read_recorder": "Зчитати з Home Assistant",
"hist_scan": "Знайти цикли",
"hist_import_n": "Імпортувати цикли ({n})",
"hist_goto_cycles": "Показати цикли"
},
"conflict": {
"anti_wrinkle_exit": {
@@ -253,14 +261,14 @@
"start": "Має бути нижчим за Макс. Потужність Захисту від Зминання ({max} Вт)"
},
"attn_sub": "Виправте конфлікти перед збереженням",
"attn_title": "{n} конфлікт{s} налаштувань",
"settings_banner": "{n} конфлікт{s} налаштувань перевірте виділені розділи й виправте перед збереженням.",
"attn_title": "Конфлікти налаштувань: {n}",
"settings_banner": "Конфлікти налаштувань: {n}. Перевірте виділені розділи та виправте їх перед збереженням.",
"settings_banner_btn": "До першого",
"confidence": {
"auto": "Має бути не нижчим за Поріг Зіставлення ({match})",
"learning": "Має бути не вищим за Поріг Зіставлення ({match})",
"learning": "Має бути не нижчим за Поріг Зіставлення ({match})",
"match_for_auto": "Має бути не вищим за Впевненість Автоматичного Маркування ({alc})",
"match_for_learning": "Має бути не нижчим за Впевненість Навчання ({lc})"
"match_for_learning": "Має бути не вищим за Впевненість Навчання ({lc})"
},
"duration_ratio": {
"max": "Має бути більшим за Мін. Коефіцієнт Тривалості ({min})",
@@ -298,7 +306,7 @@
"match": "Має бути вищим за Поріг Незіставлення ({un})",
"unmatch": "Має бути нижчим за Поріг Зіставлення ({match}); інакше підтверджений збіг одразу скасовується"
},
"cascade_toast": "Для узгодженості також автоматично скориговано ще {n} параметр{s}.",
"cascade_toast": "Інші налаштування змінено для узгодженості: {n}",
"suggestion_resolves": "Активуйте очікувану пропозицію ({val}) нижче, щоб виправити це",
"use_fix": "Використати {val}",
"watchdog": {
@@ -356,7 +364,8 @@
"pg_outcome": "Результат симуляції",
"pg_across_cycles": "За всіма вашими циклами",
"community_store": "Магазин спільноти",
"online_account": "Магазин спільноти та онлайн-функції"
"online_account": "Магазин спільноти та онлайн-функції",
"import_power_history": "Імпорт історії потужності"
},
"health": {
"fair": "Прийнятна якість профілю",
@@ -364,6 +373,7 @@
"poor": "⚠ Погана якість профілю"
},
"lbl": {
"drag_to_resize": "Перетягніть, щоб змінити розмір",
"actions": "Дії",
"activity": "Активність",
"administrators": "Адміністратори",
@@ -451,7 +461,7 @@
"metric": "Метрика",
"mode_existing_profile": "Додати до наявного профілю",
"mode_new_profile": "Створити новий профіль",
"models_fine_tuned": "({count} модель{plural} дотреновано)",
"models_fine_tuned": "(дотреновані моделі: {count})",
"n_classic_suggestions": "{n} класичне",
"n_ml_suggestions": "{n} ML",
"n_selected": "Вибрано {n}",
@@ -677,7 +687,26 @@
"conflict_resolution": "Конфлікти імен",
"conflict_import_copy": "Імпортувати як копію",
"conflict_keep_mine": "Зберегти мої",
"conflict_overwrite": "Перезаписати"
"conflict_overwrite": "Перезаписати",
"hist_csv_data": "Дані CSV",
"hist_from_recorder": "Або зчитати з Home Assistant",
"days": "дн.",
"hist_keep": "Зберегти цей цикл",
"hist_looks_complete": "завершений",
"peak_power_short": "Пік",
"shape": "Форма",
"hist_skip_idle": "нічого не працювало",
"hist_skip_sparse": "показання надто рідкі",
"hist_skip_short": "надто мало показань",
"hist_skip_long": "немає достатньо довгої паузи для розділення",
"hist_reason_short": "коротший за найкоротший справжній цикл цього приладу",
"hist_reason_no_end": "так і не завершився коректно",
"hist_since": "Починаючи з",
"task_history_import": "Сканування історії потужності",
"task_history_import_apply": "Імпорт циклів",
"evidence_real_cycles": "Цикли, виконані цим приладом",
"evidence_reference_cycles": "Завантажені з магазину спільноти",
"evidence_backfill_cycles": "Знайдені в імпортованій історії потужності"
},
"log": {
"all_levels": "Усі рівні",
@@ -756,9 +785,15 @@
"store_share": "Поділитися в магазині спільноти",
"store_share_device": "Поділитися конфігурацією пристрою",
"export_select": "Експорт - вибір даних",
"import_wizard": "Імпорт - вибір даних"
"import_wizard": "Імпорт - вибір даних",
"history_import": "Імпорт історії потужності"
},
"msg": {
"tail_trim_hint": "Скільки секунд обрізати з кінця",
"store_sibling_hint": "Для вашої точної моделі нічого не опубліковано? Дуже схожа модель того самого бренду зазвичай є доброю відправною точкою.",
"store_declare_appliance": "Вкажіть WashData, який у вас пристрій, і на цій вкладці з'являться конфігурації, опубліковані для нього іншими користувачами. Можна також ввести бренд вище і просто подивитися, що є.",
"refresh_catalog_hint": "Списки брендів і пристроїв спільноти кешуються, щоб спільний магазин не перевищував свій денний ліміт запитів. Оновіть, щоб отримати записи, додані або схвалені іншими.",
"head_trim_hint": "Скільки секунд обрізати з початку",
"appliance_monitor": "Монітор приладу",
"artifact_dip_detail": "Опустився нижче звичайної смуги потужності приблизно на ~{n} с.",
"artifact_footer": "Виділено на графіку вище. Це тимчасові артефакти (наприклад, двері відчинені посередині циклу), не обов'язково проблеми.",
@@ -769,7 +804,7 @@
"automations_intro": "WashData запускає події {start} / {end} та надає об'єкти, тому сповіщення й дії найкраще будувати як звичайні автоматизації Home Assistant. Автоматизації, що використовують цей пристрій, відображаються нижче.",
"cleanup_intro": "Усі позначені цикли накладено. Позначте аномалії і видаліть їх для очищення профілю.",
"clear_debug_hint": "Видаліть збережені дані налагодження, щоб звільнити місце.",
"collecting_data": "Збір даних – потрібно ще {need} цикл{plural} до початку точного налаштування ({current}/{min}).",
"collecting_data": "Збір даних. Залишилося циклів до початку точного налаштування: {need} ({current}/{min}).",
"compare_overlay_profiles": "Накласти профілі (блідо)",
"compare_profiles_tip": "Накладіть інші конверти профілів на таблицю вище, щоб побачити, який з них найкраще підходить для цього циклу.",
"compare_selected_cycles": "Вибрані цикли (суцільно) – показати / приховати",
@@ -779,7 +814,7 @@
"cycles_deleted": "Видалено циклів: {count}",
"enough_data": "Достатньо даних для навчання ({current}/{min} циклів).",
"export_description": "Виберіть, які саме профілі, цикли, налаштування та інше експортувати в JSON, або проаналізуйте файл та імпортуйте лише потрібні частини.",
"feedback_cycles_pending": "{n} цикл{s} для перегляду",
"feedback_cycles_pending": "На перегляд: {n}",
"feedback_prompt": "Підтвердьте правильність, виправте програму або проігноруйте.",
"feedback_relabel_hint": "Повторне маркування цього циклу також вирішує його.",
"filter_by_profile": "Фільтр за профілем…",
@@ -856,7 +891,6 @@
"pg_stress_synthetic": "тут починається симуляція режиму очікування",
"pg_sweep_intro": "Що якби {param} було іншим? Перевірте {steps} значень на ваших останніх {cycles} циклах, щоб знайти налаштування, за якого правильно зіставляється найбільше циклів.",
"pg_sweep_step": "Крок {done} / {total}",
"pg_undetected": "{n} цикл{s} не виявлено",
"pg_verdict_bad": "Потребує уваги: багато циклів залишаються невиявленими.",
"pg_verdict_good": "Добре налаштовано: більшість циклів правильно визначаються та зіставляються.",
"pg_verdict_ok": "Прийнятно: деякі цикли пропущено. Спробуйте знизити поріг запуску.",
@@ -888,6 +922,7 @@
"review_recorded_tip": "Позначте це як підібраний вручну еталонний цикл для своєї програми – така ж роль, як цикл, записаний вручну. Довідкові цикли завжди зберігаються, заповнюють відповідний шаблон і ніколи не відкидаються під час очищення. (Це «золотий»/записаний прапор; обидва – одне й те саме.)",
"review_tags_tip": "Необов'язкові прапорці, що описують, що пішло не так у цьому циклі, щоб навчання та очищення могли це врахувати.",
"review_to_cycles": "Відкрити чергу огляду циклів",
"samples_decimated": "Показано {shown} із {total} відліків (проріджено для відображення; піки збережено). Широкий розрив тут - це проріджування, а не пропуск даних.",
"saving_triggers_reload": "Збереження запускає перезавантаження інтеграції. Об'єкти HA можуть короткочасно відображатися як недоступні.",
"search_placeholder": "Пошук налаштувань…",
"see_recorder": "Дивіться віджет записувача нижче",
@@ -991,12 +1026,12 @@
"share_consent": "Ви ділитеся реальними даними вашого приладу. Не діліться, якщо ваші шаблони використання є приватними.",
"share_device_none": "Пристрої ще не налаштовані. Спочатку додайте пристрій.",
"share_guideline_naming": "Використовуйте зрозумілі назви програм (наприклад, 'Cotton 40', 'Eco 60'), щоб інші могли їх ідентифікувати",
"share_guideline_quality": "Діліться тільки профілями з ⭐ еталонними циклами або щонайменше {n} підтвердженими запусками",
"share_guideline_quality": "Діліться лише циклами, які завершилися нормально: без перерв посеред циклу, відкривання дверцят або короткочасних збоїв живлення.",
"share_guideline_review": "Перегляньте профілі перед публікацією -- видаліть ті, що виглядають неправильно",
"share_guidelines_title": "Перед публікацією",
"store_download_device_intro": "Завантажити конфігурацію пристрою зі спільноти та застосувати її до нового або наявного пристрою",
"store_share_device_intro": "Поділитися програмами вашого пристрою (профілі + еталонні цикли) зі спільнотою. Налаштування необов'язкові.",
"share_profile_no_cycles": "Профіль '{p}' не має еталонних циклів -- його буде пропущено, якщо у вас немає {n}+ підтверджених запусків",
"store_share_device_intro": "Завантажте {brand} {model} з вибраними вами еталонними циклами. Інші користувачі з таким самим пристроєм зможуть прийняти ваші програми. Записи перевіряються перед публікацією.",
"share_profile_no_cycles": "Немає еталонних циклів. Щоб включити цей профіль, позначте цикл як ⭐ на вкладці Цикли",
"advisory_phase_inconsistent": "Схоже, що '{name}' поєднує різні програми або температури - його цикли нагріваються протягом дуже різного часу. Розділення на окремі профілі (напр. за температурою) покращить зіставлення та оцінки часу.",
"advisory_phase_inconsistent_title": "⚠ Можливо, змішані програми",
"export_select_intro": "Позначте, що саме включити. Вибір профілів без їхніх циклів усе одно експортує розпізнавану програму (її вивчена форма передається разом із нею).",
@@ -1006,7 +1041,29 @@
"merge_hint": "Імпортовані елементи додаються; нічого локального не втрачається. Конфлікти імен вирішуються нижче.",
"replace_warn": "Кожна позначена категорія очищується та замінюється даними з файлу. Непозначені категорії залишаються без змін.",
"dest_reference_hint": "Імпортовані цикли лише покращують розпізнавання програм і ніколи не впливають на статистику використання/енергії.",
"dest_real_history_hint": "Імпортовані цикли зараховуються як власна історія цього пристрою та враховуються в статистиці енергії/використання. Використовуйте для перенесення одного приладу на нове встановлення."
"dest_real_history_hint": "Імпортовані цикли зараховуються як власна історія цього пристрою та враховуються в статистиці енергії/використання. Використовуйте для перенесення одного приладу на нове встановлення.",
"import_history_description": "Розумна розетка була у вас ще до WashData? Завантажте експорт історії її датчика потужності або зчитайте її прямо з Home Assistant, і звичайне виявлення пройде цими даними, тож минулі цикли з'являться у списку «Цикли», готові до позначення.",
"hist_input_hint": "Завантажте CSV, отриманий на панелі «Історія» (сутність, стан, час зміни), або дозвольте WashData зчитати історію датчика напряму. Далі виявлення пройде цими даними так само, як у реальному часі, а ви виберете, які зі знайдених циклів зберегти.",
"hist_recorder_hint": "Читає дані від вибраної дати до цього моменту. Типово Home Assistant зберігає докладну історію 10 днів, а після цього лише погодинні середні значення, які надто грубі для виявлення циклів - вибирайте давнішу дату лише тоді, коли в налаштуваннях recorder задано довший термін зберігання.",
"hist_scanning": "Ваша історія відтворюється через детектор. Це виконується у фоні - можна закрити це вікно та повернутися пізніше.",
"hist_imported_count": "Імпортовано циклів: {n}.",
"hist_duplicates": "Уже імпортовано раніше та пропущено: {n}.",
"hist_capped": "Досягнуто ліміту імпортованих циклів для пристрою; решту не збережено.",
"hist_next_step": "Вони у списку «Цикли» з позначкою імпортованої історії. Відкрийте цикл і натисніть «Позначити», щоб вказати його програму.",
"hist_rows_read": "Прочитано показань: {n}",
"hist_breaks": "Пропусків, де датчик був недоступний: {n}",
"hist_other_entity": "Показань інших сутностей пропущено: {n}",
"hist_entity_substituted": "Прочитано {used} (для цього пристрою налаштовано {wanted})",
"hist_skipped_spans": "Пропущені ділянки",
"hist_settings_used": "Виявлено з поточними налаштуваннями цього пристрою (Мінімальна потужність {w} Вт, Затримка вимкнення {s} с).",
"hist_none_found": "У цій історії не вдалося виявити жодного циклу.",
"hist_found": "Знайдено циклів: {n}. Зніміть позначки з того, що не схоже на справжній запуск - до імпорту нічого не зберігається.",
"hist_scan_capped": "Показано лише перших кандидатів (знайдено: {n}).",
"hist_recorder_empty": "У Home Assistant немає докладної історії для цього датчика за цей період.",
"hist_scan_failed": "Сканування не вдалося.",
"hist_scan_expired": "Це сканування вже недоступне. Виконайте сканування ще раз.",
"hist_import_failed": "Імпорт не вдався.",
"imported_history_readonly": "Виявлено в імпортованій історії потужності. Впливає на зіставлення програм, але не враховується у вашій статистиці; такий цикл не можна обрізати чи розділити. Натисніть «Позначити», щоб вказати програму."
},
"phase_desc": {
"anti_crease": "Час від часу короткі оберти після завершення для зменшення зморшок.",
@@ -1471,6 +1528,10 @@
"show_contributor": {
"doc": "Показати ім'я автора на профілях, завантажених з магазину спільноти"
},
"smart_termination_duration_ratio": {
"doc": "Наскільки глибоко в очікувану тривалість зіставленої програми має зайти цикл, перш ніж Розумне завершення зможе завершити його достроково після падіння потужності. Очікувана тривалість - це середнє значення програми, тому на приладах із дуже мінливим часом роботи - пральні машини за холодної зимової та теплої літньої води на вході, сушильні машини з датчиком вологості, програми, що залежать від завантаження - близько половини всіх запусків завершуються коротше за це середнє й ніколи не отримують швидкого завершення, закінчуючись лише за резервним тайм-аутом із запізненням на кілька хвилин. Зменшіть це значення (напр., 0.85) на таких машинах, щоб дострокове завершення все ж спрацьовувало; підвищуйте ближче до 1.0 для більшої обережності. Залиште порожнім для значення за замовчуванням (0.98 або 0.99 для посудомийних машин). Воно може лише завершити цикл раніше, але ніколи пізніше, і ніколи не спрацьовує за неоднозначного або недостатньо впевненого зіставлення.",
"label": "Коефіцієнт розумного завершення"
},
"enable_phase_matching": {
"label": "Залишок часу з урахуванням фаз",
"doc": "Розбиває кожен активний цикл на фази (нагрівання, прання, віджим) і розподіляє залишок часу за фазами, поєднуючи це з класичною оцінкою - спираючись на розподіл за фазами на початку циклу та на класичну оцінку ближче до кінця. Це персоналізує відлік під те, скільки насправді нагрівається та працює ваша машина, що найпомітніше в першій половині циклу. Вимкнено = лише класична оцінка. Впливає лише на відображення залишку часу; зіставлення програм і виявлення циклу залишаються незмінними."
@@ -1522,6 +1583,10 @@
"door_end_dwell_seconds": {
"label": "Витримка при відкритих дверцятах",
"doc": "Як довго дверцята повинні залишатися відкритими до завершення циклу, коли увімкнено \"Дверцята відкриваються автоматично наприкінці\". Достатньо довго, щоб ігнорувати швидке додавання посуду (за замовчуванням 60 с), достатньо коротко для швидкого завершення після відкриття дверцят машиною."
},
"profile_evidence_sources": {
"label": "Цикли, що формують програму",
"doc": "Які цикли беруть участь у побудові кривої потужності кожної програми та в зіставленні з нею завершеного циклу. Якщо зняти позначку з певного виду, він більше не формує ваші програми, але нічого не видаляється: цикли залишаються у списку Цикли, їх так само можна позначити або вилучити. Корисно, якщо ви не довіряєте імпортованим даним. На статистику це не впливає: у ній завжди враховуються лише цикли, які цей прилад справді виконав. Якщо зняти всі позначки, це буде проігноровано, адже програма без жодного циклу ніколи не могла б зіставитися."
}
},
"setting_group": {
@@ -1605,6 +1670,9 @@
},
"basic_configuration": {
"label": "Основні налаштування"
},
"profile_evidence": {
"label": "Дані для профілю"
}
},
"status": {
@@ -1629,7 +1697,8 @@
"trimming": "Обрізання…",
"splitting": "Розділення…",
"deleting": "Видалення…",
"imported": "Імпортовано"
"imported": "Імпортовано",
"preparing": "Підготовка…"
},
"tab": {
"advanced": "Розширені",
@@ -1659,6 +1728,7 @@
"wrong_profile": "Неправильний профіль"
},
"toast": {
"catalog_refreshed": "Каталог спільноти оновлено",
"access_saved": "Контроль доступу збережено",
"all_wiped": "Усі дані видалено",
"analysis_complete_none": "Аналіз завершено: нових пропозицій немає",
@@ -1752,19 +1822,21 @@
"rating_saved": "Оцінку якості збережено",
"brand_added": "Бренд додано, очікує схвалення",
"profile_added": "Профіль додано, очікує схвалення",
"saved_except_conflicts": "Налаштування збережені -- {n} налаштування{s} пропущено через конфлікти",
"saved_except_conflicts": "Збережено. Виправте виділені конфлікти, щоб зберегти решту.",
"share_device_none_sel": "Виберіть принаймні одну програму для публікації",
"store_device_downloaded": "Конфігурацію пристрою завантажено: {created} профіль{c} створено, {dup} вже існувало",
"store_device_downloaded_phases": "Конфігурацію пристрою завантажено: {created} профіль{c} створено, {dup} вже існувало, карту фаз застосовано",
"store_device_downloaded_settings": "Конфігурацію пристрою завантажено: {created} профіль{c} створено, {dup} вже існувало, налаштування застосовано",
"store_device_shared": "Конфігурацію пристрою опубліковано: {n} програм{s} завантажено",
"store_device_shared_all_dup": "Нема нічого нового для публікації -- всі програми вже є в магазині",
"store_device_shared_partial": "Часткова публікація: {n} програм{s} завантажено, {failed} пропущено",
"store_device_shared_some_dup": "Конфігурацію пристрою опубліковано: {n} програм{s} завантажено ({dup} вже існувало)",
"store_device_downloaded": "Додано програм: {p}, записів: {c}",
"store_device_downloaded_phases": "Додано програм: {p}, записів: {c}, карт фаз: {ph}",
"store_device_downloaded_settings": "Додано програм: {p}, записів: {c}, карт фаз: {ph}, налаштувань: {s}",
"store_device_shared": "Опубліковано в магазині спільноти (циклів: {n}), очікує перевірки.",
"store_device_shared_all_dup": "Усі вибрані цикли ({n}) уже були в магазині спільноти.",
"store_device_shared_partial": "Опубліковано циклів: {n}; не вдалося завантажити: {failed}.",
"store_device_shared_some_dup": "Опубліковано циклів: {created}; уже в магазині: {dup}.",
"store_download_failed": "Помилка завантаження: {error}",
"store_download_nothing": "Нема що завантажувати -- всі профілі вже існують на цьому пристрої",
"export_selective_done": "Експорт завантажено",
"import_selective_done": "Імпортовано профілів: {profiles}, циклів: {cycles}"
"import_selective_done": "Імпортовано профілів: {profiles}, циклів: {cycles}",
"hist_csv_required": "Спочатку завантажте файл CSV або вставте його вміст",
"file_read_failed": "Не вдалося прочитати цей файл"
},
"suggestion": {
"both_agree": "WashData рекомендує",
@@ -1860,7 +1932,7 @@
"thr_batch": "Залишено трохи вище найменшої активної потужності p05 за {cycles} циклами ({p05}W), щоб запуск фіксувався якомога раніше, а поріг зупинки залишався нижчим за мінімальну робочу потужність машини.",
"tol_per_profile": "p75 розкиду тривалості за профілями серед {profiles} профілів ({cycles} циклів); стабільні профілі не штрафуються.",
"tol_pooled": "На основі об'єднаного розкиду тривалості {cycles} нещодавніх розмічених циклів (відхилення p95={dev}).",
"watchdog": "Залишено настільки низьким, наскільки це безпечно (трохи вище інтервалу оновлення p95, що дорівнює {p95}s, мін. 30s), щоб зависання виявлялися швидко без хибних зупинок."
"watchdog": "Залишено настільки низьким, наскільки це безпечно (трохи вище інтервалу оновлення p95, що дорівнює {p95}s, і щонайменше 2x інтервалу вибірки {median}s, мін. 30s), щоб зависання виявлялися швидко без хибних зупинок."
},
"exclusions": {
"summary": "Виключено {total} помилково виявлених циклів: {parts}.",
@@ -1892,6 +1964,7 @@
},
"pg_desc": {
"dishwasher_end_spike_quiet_release": "Посудомийна машина: секунди неактивності після очікуваної тривалості перед зняттям очікування фінального зливу в кінці циклу",
"smart_termination_duration_ratio": "Частка очікуваної тривалості зіставленої програми, якої має досягти цикл, перш ніж Розумне завершення зможе завершити його достроково; зменшіть її для машин, що залежать від завантаження або температури",
"completion_min_seconds": "Найкоротший запуск, що вважається справжнім циклом",
"end_repeat_count": "Скільки низьких показань поспіль до завершення",
"interrupted_min_seconds": "Короткі цикли позначаються як перервані",
@@ -1955,6 +2028,10 @@
"finished": "Цикл досяг кінцевого стану й завершився."
},
"store": {
"your_model_tip": "Це пристрій, який ви вказали в налаштуваннях",
"your_model": "Ваш",
"search_brand_ph": "Пошук за брендом…",
"programs_count": "Програми: {n}",
"browse": "Огляд",
"device": "Пристрій",
"favorites": "Обране",
@@ -78,9 +78,12 @@
"awaiting": "等待批准",
"imported_tip": "从社区商店导入。仅用于匹配,不计入统计。",
"not_importable": "此处不适用",
"exists": "已存在"
"exists": "已存在",
"backfilled_tip": "在导入的功率历史中检测到。仅影响程序匹配,不计入统计。"
},
"btn": {
"set_brand_model": "设置品牌和型号",
"refresh_catalog": "刷新目录",
"add_device": "+ 添加设备",
"add_device_tip": "添加另一个 WashData 设备",
"add_maintenance": "添加维护事件",
@@ -241,7 +244,12 @@
"import_selected": "导入所选",
"back": "返回",
"mute_suggestion": "停止建议此设置",
"reset_muted": "重置已屏蔽"
"reset_muted": "重置已屏蔽",
"import_power_history": "导入功率历史",
"hist_read_recorder": "从 Home Assistant 读取",
"hist_scan": "扫描周期",
"hist_import_n": "导入 {n} 个周期",
"hist_goto_cycles": "查看这些周期"
},
"conflict": {
"anti_wrinkle_exit": {
@@ -253,12 +261,12 @@
"start": "必须低于防皱最大功率 ({max} W)"
},
"attn_sub": "保存前请解决冲突",
"attn_title": "{n} 个设置冲突{s}",
"attn_title": "设置冲突{n}",
"confidence": {
"auto": "必须不低于匹配阈值 ({match})",
"learning": "必须不超过匹配阈值 ({match})",
"learning": "必须不低于匹配阈值 ({match})",
"match_for_auto": "必须不超过自动标记置信度 ({alc})",
"match_for_learning": "必须不低于学习置信度 ({lc})"
"match_for_learning": "必须不超过学习置信度 ({lc})"
},
"duration_ratio": {
"max": "必须大于最小时长比例 ({min})",
@@ -296,14 +304,14 @@
"match": "必须高于不匹配阈值 ({un})",
"unmatch": "必须低于匹配阈值 ({match});否则已确认的匹配会立即取消"
},
"cascade_toast": "为保持一致性,还自动调整了 {n} 项设置{s}。",
"cascade_toast": "为保持一致性而调整的其他设置:{n}",
"suggestion_resolves": "应用下方的待处理建议({val})以修复此问题",
"use_fix": "使用 {val}",
"watchdog": {
"interval": "应至少为采样间隔 ({si} 秒) 的 2 倍",
"sampling": "采样间隔应最多为看门狗间隔 ({wi} 秒) 的一半"
},
"settings_banner": "{n} 个设置冲突{s} 请检查高亮显示的部分,并在保存前修复。",
"settings_banner": "设置冲突:{n}。请检查高亮显示的部分,并在保存前修复。",
"settings_banner_btn": "前往第一处"
},
"hdr": {
@@ -356,7 +364,8 @@
"pg_outcome": "模拟结果",
"pg_across_cycles": "所有周期综合",
"community_store": "社区商店",
"online_account": "社区商店与在线功能"
"online_account": "社区商店与在线功能",
"import_power_history": "导入功率历史"
},
"health": {
"fair": "配置文件质量尚可",
@@ -364,6 +373,7 @@
"poor": "⚠ 配置文件质量差"
},
"lbl": {
"drag_to_resize": "拖动以调整大小",
"actions": "操作",
"activity": "活动",
"administrators": "管理员",
@@ -434,7 +444,7 @@
"from": "起始",
"gap_s": "间隔(秒)",
"group_name": "组名称",
"head_trim": "头裁剪(秒)",
"head_trim": "头裁剪(秒)",
"health": "健康",
"hide_tabs": "对非管理员隐藏标签",
"in_use": "使用中",
@@ -450,7 +460,7 @@
"metric": "指标",
"mode_existing_profile": "添加到现有配置文件",
"mode_new_profile": "创建新配置文件",
"models_fine_tuned": "{count}个模型{plural}已微调)",
"models_fine_tuned": "(已微调的模型:{count}",
"n_classic_suggestions": "{n} 经典",
"n_ml_suggestions": "{n} ML",
"n_selected": "已选 {n} 个",
@@ -532,7 +542,7 @@
"stage3": "阶段 3 DTW",
"stage4": "阶段 4 一致度",
"status": "状态",
"tail_trim": "尾裁剪(秒)",
"tail_trim": "尾裁剪(秒)",
"timer_auto_pause": "自动暂停",
"timer_min": "分钟",
"timer_msg_placeholder": "消息(可选,{device}/{program}/{minutes}",
@@ -677,7 +687,26 @@
"conflict_import_copy": "作为副本导入",
"conflict_keep_mine": "保留我的",
"conflict_overwrite": "覆盖",
"font_size": "面板字体大小"
"font_size": "面板字体大小",
"hist_csv_data": "CSV 数据",
"hist_from_recorder": "或从 Home Assistant 读取",
"hist_since": "起始日期",
"days": "天",
"hist_keep": "保留此周期",
"hist_looks_complete": "完整",
"peak_power_short": "峰值",
"shape": "形状",
"hist_skip_idle": "没有运行",
"hist_skip_sparse": "读数间隔过大",
"hist_skip_short": "读数太少",
"hist_skip_long": "没有足够长的间断可用于切分",
"hist_reason_short": "比该设备最短的真实周期还短",
"hist_reason_no_end": "从未正常结束",
"task_history_import": "扫描功率历史",
"task_history_import_apply": "导入周期",
"evidence_real_cycles": "本机实际运行的周期",
"evidence_reference_cycles": "从社区商店下载",
"evidence_backfill_cycles": "在导入的功率历史中发现"
},
"log": {
"all_levels": "所有级别",
@@ -756,9 +785,15 @@
"store_share": "分享到社区商店",
"store_share_device": "分享此设备",
"export_select": "导出 - 选择数据",
"import_wizard": "导入 - 选择数据"
"import_wizard": "导入 - 选择数据",
"history_import": "导入功率历史"
},
"msg": {
"tail_trim_hint": "从末尾移除的秒数",
"store_sibling_hint": "没有与您型号完全一致的分享内容?同品牌中相近的型号通常是不错的起点。",
"store_declare_appliance": "告知 WashData 您拥有哪台家电,此标签页便会显示其他用户为它分享的程序和录制。您也可以在上方输入品牌名称随意浏览。",
"refresh_catalog_hint": "社区品牌和家电列表已缓存,以便共享商店保持在每日读取额度内。刷新可获取他人新增或已批准的条目。",
"head_trim_hint": "从开头移除的秒数",
"appliance_monitor": "设备监控",
"artifact_dip_detail": "跌破通常功率范围约 {n} 秒。",
"artifact_footer": "在上图中高亮显示。这些是瞬态异常(例如门在周期中打开),不一定是问题。",
@@ -769,7 +804,7 @@
"automations_intro": "WashData 触发 {start} / {end} 事件并公开实体,因此通知和操作最好构建为常规 Home Assistant 自动化。使用此设备的自动化显示在下方。",
"cleanup_intro": "显示所有已标记周期的叠加。勾选离群值并删除以清理配置文件。",
"clear_debug_hint": "删除存储的调试数据以释放空间。",
"collecting_data": "正在收集数据,还需要 {need} 个周期{plural}才能开始微调{current}/{min})。",
"collecting_data": "正在收集数据。开始微调前还需要的周期数:{need}{current}/{min})。",
"compare_overlay_profiles": "叠加配置文件(浅色)",
"compare_profiles_tip": "将其他配置文件包络叠加在上方图表上,看哪个最适合此周期。",
"compare_selected_cycles": "选中的周期(实线)– 显示/隐藏",
@@ -779,7 +814,7 @@
"cycles_deleted": "已删除 {count} 个周期",
"enough_data": "有足够数据可供学习({current}/{min} 个循环)。",
"export_description": "精确选择要导出到 JSON 的配置文件、周期、设置等,或分析文件并仅导入所需的部分。",
"feedback_cycles_pending": "{n} 个周期{s}待审查",
"feedback_cycles_pending": "待审查{n}",
"feedback_prompt": "确认正确、修正程序或忽略。",
"feedback_relabel_hint": "重新标记此周期也会解决它。",
"filter_by_profile": "按配置文件筛选…",
@@ -856,7 +891,6 @@
"pg_stress_synthetic": "待机模拟从此处开始",
"pg_sweep_intro": "如果 {param} 不同会怎样?在最近 {cycles} 个周期上测试 {steps} 个值,找到能正确匹配最多周期的设置。",
"pg_sweep_step": "步骤 {done} / {total}",
"pg_undetected": "{n} 个周期{s}未检测到",
"pg_verdict_bad": "需要注意: 许多周期未被检测到。",
"pg_verdict_good": "调校良好: 大多数周期都被正确识别和匹配。",
"pg_verdict_ok": "尚可: 漏掉了一些周期。可尝试降低启动阈值。",
@@ -887,6 +921,7 @@
"review_recorded_tip": "将此标记为其程序的精选参考周期 – 与手动录制周期的作用相同。参考周期始终保留,为匹配模板提供种子,且不会被清理删除。(这是“黄金”/录制标志;两者是同一件事。)",
"review_tags_tip": "描述此周期出现问题的可选标志,以便训练和清理可以考虑这些问题。",
"review_to_cycles": "打开周期审查队列",
"samples_decimated": "正在显示 {total} 个样本中的 {shown} 个(为显示而抽稀;保留峰值)。此处的较大间隔是抽稀,而非缺失数据。",
"saving_triggers_reload": "保存会触发集成重载。HA 实体可能短暂显示为不可用。",
"search_placeholder": "搜索设置…",
"see_recorder": "查看下方的录制小部件",
@@ -1006,7 +1041,29 @@
"sug_mute_failed": "无法屏蔽建议",
"sug_unmuted_all": "已重置屏蔽的建议",
"n_suggestions_muted": "已屏蔽 {count} 项,自动调整器将不再提议这些设置。",
"font_size_hint": "调整此面板所有内容的字体大小,仅对您在此设备上的账户生效。"
"font_size_hint": "调整此面板所有内容的字体大小,仅对您在此设备上的账户生效。",
"import_history_description": "在使用 WashData 之前就已经有智能插座了?上传其功率传感器的历史导出文件,或直接从 Home Assistant 读取,常规检测会在这些数据上运行,过去的周期便会出现在您的周期列表中,等待命名。",
"hist_input_hint": "上传从历史面板下载的 CSVentity、state、last changed),或让 WashData 直接读取该传感器的历史。随后检测会像实时运行时一样在这些数据上运行,并由您选择保留其中哪些周期。",
"hist_recorder_hint": "从您选择的日期读取到现在。Home Assistant 默认保留 10 天的详细历史,之后仅保留每小时平均值,过于粗略,无法用于检测周期;只有当 recorder 配置为保留更长时间时,才选择更早的日期。",
"hist_scanning": "正在通过检测器重放您的历史数据。该任务在后台运行 - 您可以关闭此对话框,稍后再回来查看。",
"hist_imported_count": "已导入 {n} 个周期。",
"hist_duplicates": "其中 {n} 个此前已导入,已跳过。",
"hist_capped": "已达到每台设备可导入周期的上限,其余未保存。",
"hist_next_step": "它们已在您的周期列表中,标记为导入的历史。打开其中一个,用“标记”指定它所属的程序。",
"hist_rows_read": "已读取 {n} 条读数",
"hist_entity_substituted": "已读取 {used}(此设备配置的是 {wanted}",
"hist_breaks": "{n} 处传感器不可用的空缺",
"hist_other_entity": "已忽略其他实体的 {n} 条读数",
"hist_skipped_spans": "跳过的时段",
"hist_settings_used": "使用该设备的当前设置检测(最小功率 {w} W,关闭延迟 {s} 秒)。",
"hist_none_found": "在该历史数据中未能检测到任何周期。",
"hist_found": "找到 {n} 个周期。取消勾选看起来不像真实运行的项 - 在导入之前不会保存任何内容。",
"hist_scan_capped": "仅显示前若干个候选项(共找到 {n} 个)。",
"hist_recorder_empty": "Home Assistant 中没有该传感器在该时间段的详细历史。",
"hist_scan_failed": "扫描失败。",
"hist_scan_expired": "该次扫描结果已不可用,请重新扫描。",
"hist_import_failed": "导入失败。",
"imported_history_readonly": "在导入的功率历史中检测到。它会影响程序匹配,但不计入您的统计,且无法裁剪或拆分。请标记以指定其程序。"
},
"pg_desc": {
"completion_min_seconds": "计为真实周期的最短运行时间",
@@ -1035,7 +1092,8 @@
"dtw_refine_top_n": "Stage 3: DTW 重新评分的候选数量; 若正确档案排在第 4-5 位则调高至 7-9(默认 5",
"duration_scale": "Stage 4: 时长一致性得分减半时的对数比率; 越小惩罚越严格(默认 0.175)",
"energy_scale": "Stage 4: 能耗一致性得分减半时的对数比率; 越小惩罚越严格(默认 0.25)",
"dishwasher_end_spike_quiet_release": "洗碗机:预期时长过后、解除周期结束排水等待之前保持静止的秒数"
"dishwasher_end_spike_quiet_release": "洗碗机:预期时长过后、解除周期结束排水等待之前保持静止的秒数",
"smart_termination_duration_ratio": "匹配程序预期时长中,周期在智能终止可以提前结束之前必须达到的比例;对于取决于负载或温度的机器请调低"
},
"phase_desc": {
"anti_crease": "完成后偶尔进行短暂的翻滚以减少皱纹。",
@@ -1290,7 +1348,7 @@
"label": "结束服务"
},
"notify_fire_events": {
"doc": "还在循环开始/结束时触发 ha_washdata_* 事件,以便您可以构建自己的自动化。",
"doc": "还在循环开始/结束时触发 ha_washdata_* 事件,以便您可以构建自己的自动化。",
"label": "为通知触发 HA 事件"
},
"notify_icon": {
@@ -1417,6 +1475,10 @@
"doc": "存储每个周期的完整功率跟踪和匹配调试数据。对于故障排除很有用,但会增加存储大小。",
"label": "保存调试追踪"
},
"smart_termination_duration_ratio": {
"doc": "指定在功率下降后、智能终止可以提前结束一个周期之前,该周期必须进行到匹配程序预期时长的多大比例。预期时长是该程序的平均值,因此对于运行时间波动很大的家电(冬季冷进水与夏季暖进水的洗衣机、传感器烘干的烘干机、取决于负载的程序),大约一半的运行会比该平均值更早结束,从而无法获得快速结束,只能通过后备超时晚几分钟才结束。对于这些机器,请调低此值(例如 0.85),使提前结束仍然生效;若要更保守,则将其调高至接近 1.0。留空则使用默认值(0.98,洗碗机为 0.99)。它只能让周期更早结束,绝不会更晚,并且在匹配结果不明确或置信度较低时绝不会触发。",
"label": "智能终止比率"
},
"smoothing_window": {
"doc": "原始功率信号被平滑了多少。低 (2) 响应灵敏,但噪音较大;高 (5) 可平滑尖峰,但会增加滞后。",
"label": "平滑窗口"
@@ -1551,6 +1613,10 @@
"dishwasher_end_spike_quiet_release": {
"label": "自然干燥静止释放",
"doc": "当周期超过其预期时长后,洗碗机必须保持静止(低于停止阈值)多长时间,WashData 才会停止等待最终排水并结束该周期。如果您的机器在较晚的最终排水之前有一个较长的近乎无声的干燥阶段,导致该次排水被漏检,请调高此值 - 更宽的窗口可让学习到的时长跟随季节性漂移(进水更冷 = 周期更长),而不是锁定在旧的平均值上。它只能相对于内部 30 分钟的结束尖峰上限缩短等待时间,绝不会延长。"
},
"profile_evidence_sources": {
"label": "用于构建程序的周期",
"doc": "用于构建每个程序的功率曲线,并将已完成的周期与其匹配的周期种类。取消勾选某一种类会使其不再影响您的程序,但不会删除任何内容 - 这些周期仍留在周期列表中,仍可标记或删除。如果您不信任导入的数据,此选项很有用。统计不受影响:统计始终只计入本机实际运行过的周期。取消勾选全部会被忽略,因为没有任何周期作为依据的程序永远无法匹配。"
}
},
"setting_group": {
@@ -1634,6 +1700,9 @@
},
"basic_configuration": {
"label": "基本配置"
},
"profile_evidence": {
"label": "配置文件依据"
}
},
"status": {
@@ -1658,7 +1727,8 @@
"trimming": "裁剪中…",
"splitting": "拆分中…",
"deleting": "删除中…",
"imported": "已导入"
"imported": "已导入",
"preparing": "正在准备…"
},
"tab": {
"advanced": "高级",
@@ -1688,6 +1758,7 @@
"wrong_profile": "错误配置文件"
},
"toast": {
"catalog_refreshed": "社区目录已刷新",
"access_saved": "已保存访问控制",
"all_wiped": "所有数据已清除",
"analysis_complete_none": "分析完成:没有新建议",
@@ -1793,7 +1864,9 @@
"store_download_failed": "下载失败:{error}",
"store_download_nothing": "没有新内容可下载 - 此配置已在您的设备上。",
"export_selective_done": "导出已下载",
"import_selective_done": "已导入 {profiles} 个配置文件和 {cycles} 个周期"
"import_selective_done": "已导入 {profiles} 个配置文件和 {cycles} 个周期",
"hist_csv_required": "请先加载 CSV 文件或粘贴其内容",
"file_read_failed": "无法读取该文件"
},
"suggestion": {
"both_agree": "WashData建议",
@@ -1889,7 +1962,7 @@
"thr_batch": "保持在 {cycles} 个周期中 p05 最低工作功率({p05}W)略上方,以便尽早捕捉到启动,同时使停止阈值保持在设备最低运行功率之下。",
"tol_per_profile": "{profiles} 个配置文件({cycles} 个周期)中每个配置文件时长方差的 p75;波动小的配置文件不受惩罚。",
"tol_pooled": "基于 {cycles} 个近期已标注周期的合并时长方差(p95 偏差={dev})。",
"watchdog": "在安全范围内保持尽可能低(略高于 p95 更新间隔 {p95}s,最小 30s),以便快速捕捉到停滞而不产生误停止。"
"watchdog": "在安全范围内保持尽可能低(略高于 p95 更新间隔 {p95}s,且至少为采样间隔 {median}s 的 2 倍,最小 30s),以便快速捕捉到停滞而不产生误停止。"
},
"exclusions": {
"summary": "已排除 {total} 个误检测周期:{parts}。",
@@ -1955,6 +2028,10 @@
"finished": "循环到达终止状态并已结束。"
},
"store": {
"your_model_tip": "这是您在设置中指定的家电",
"your_model": "您的型号",
"search_brand_ph": "按品牌搜索…",
"programs_count": "程序:{n}",
"browse": "浏览",
"device": "设备",
"favorites": "收藏",
@@ -193,15 +193,15 @@
},
"user_confirmed": {
"name": "Підтвердити виявлену програму",
"description": "Установіть true, якщо виявлена програма правильна."
"description": "Установіть true, якщо виявлена програма правильна."
},
"corrected_profile": {
"name": "Виправлений профіль",
"description": "Якщо не підтверджено, укажіть правильну назву профілю/програми."
},
"corrected_duration": {
"name": "Виправлена тривалість (секунди)",
"description": "Додаткова виправлена тривалість у секундах."
"name": "Виправлена тривалість (секунди)",
"description": "Додаткова виправлена тривалість у секундах."
},
"notes": {
"name": "Примітки",
File diff suppressed because it is too large Load Diff
+102 -3
View File
@@ -80,11 +80,16 @@ class DeviceInfo(TypedDict):
current_power_w: float | None
cycle_progress_pct: float | None
suggestions_count: int
suggestion_keys: list[str]
feedback_count: int
recording: bool
is_user_paused: bool
manual_program: bool
options: dict[str, Any]
# Device-resolved defaults for the cadence/ratio fields whose default varies by
# device type (#396/#393), so the device-list conflict/suggestion badges can score
# an unset field against the value the integration would use (matches the Settings tab).
option_defaults: dict[str, Any]
class GetDevicesResponse(TypedDict):
@@ -95,6 +100,7 @@ class GetDeviceCyclesResponse(TypedDict):
entry_id: str
cycles: list[dict[str, Any]]
reference_cycles: list[dict[str, Any]]
backfill_cycles: list[dict[str, Any]]
total: int
has_more: bool
@@ -103,6 +109,10 @@ class GetDeviceCyclesResponse(TypedDict):
class GetOptionsResponse(TypedDict):
options: dict[str, Any]
# Device-resolved defaults for the cadence settings whose default varies by
# device type (sampling_interval / watchdog_interval / start_duration_threshold),
# used by the panel as the render + conflict-check fallback for an unset field (#396).
defaults: dict[str, Any]
class GetSettingsChangelogResponse(TypedDict):
@@ -258,11 +268,15 @@ class RunSuggestionAnalysisResponse(TypedDict, total=False):
# ─── Cycle curve / interactive editing ─────────────────────────────────────────
class GetCyclePowerDataResponse(TypedDict, total=False):
"""``cycle_id`` / ``samples`` / ``full_duration_s`` are always present; the
metadata keys are present only when the cycle is found."""
"""``cycle_id`` / ``samples`` / ``sample_count`` / ``decimated`` /
``full_duration_s`` are always present; the metadata keys are present only
when the cycle is found. ``sample_count`` is the stored point count and
``decimated`` is True when ``samples`` was thinned below it (#395)."""
cycle_id: str
samples: list[list[float]]
sample_count: int
decimated: bool
full_duration_s: float
start_time: str | None
end_time: str | None
@@ -272,13 +286,22 @@ class GetCyclePowerDataResponse(TypedDict, total=False):
energy_kwh: float | None
artifacts: list[dict[str, Any]]
restart_gaps: list[Any]
# Capability keys spread from _cycle_capabilities(cycle, origin). ``is_reference``
# is present for every cycle; the other three ride along for a non-``past`` cycle
# (reference/backfill), so declare them or the WS contract check flags them and the
# generated ws-types.d.ts omits the fields the panel needs to type.
is_reference: bool
labelable: bool
editable: bool
cycle_origin: str
class AnalyzeSplitResponse(TypedDict):
segments: list[list[float]]
split_offsets: list[float]
samples: list[list[float]]
sample_count: int
decimated: bool
full_duration_s: float
@@ -513,6 +536,31 @@ class StartTaskResponse(TypedDict):
task_id: str
class HistoryImportBeginResponse(TypedDict):
"""Staging slot opened for a CSV upload (issue #344)."""
token: str
max_bytes: int
chunk_bytes: int
class HistoryImportChunkResponse(TypedDict):
received_bytes: int
next_seq: int
class HistoryImportRecorderResponse(TypedDict):
"""Staging slot filled from the recorder instead of an upload."""
token: str
rows: int
entity_id: str
days: int
# Oldest day actually queried (ISO date), for "read since <date>".
start_date: str
truncated: bool
class SubscribeTasksResponse(TypedDict, total=False):
"""Empty ack for the ``subscribe_tasks`` subscription; the live data arrives
as ``{"type": "task", "task": TaskSnapshot}`` event messages, not in this
@@ -606,6 +654,25 @@ class StoreDeviceProfilesResponse(TypedDict, total=False):
disabled: bool
class StoreCatalogEntryResponse(TypedDict, total=False):
"""One appliance's catalog identity: its brand + device documents, resolved by id.
``brand`` / ``device`` are None when that entry is not in the catalog yet (not an
error -- it just means nobody has contributed it). Backs the settings form's status
badges without downloading the brand/device lists.
"""
device_id: str
brand: dict | None
device: dict | None
disabled: bool
class StoreRefreshCatalogResponse(TypedDict, total=False):
"""Acknowledgement that the cached catalog was dropped."""
ok: bool
disabled: bool
class StoreUploadDeviceResponse(TypedDict, total=False):
"""Result of sharing a whole-device bundle (multi-profile, multi-cycle)."""
ok: bool
@@ -737,6 +804,11 @@ WS_RESPONSE_TYPES: dict[str, type] = {
"start_playground_history": StartTaskResponse,
"start_playground_sweep": StartTaskResponse,
"start_playground_cycle_detail": StartTaskResponse,
"history_import_begin": HistoryImportBeginResponse,
"history_import_chunk": HistoryImportChunkResponse,
"history_import_recorder": HistoryImportRecorderResponse,
"start_history_import_scan": StartTaskResponse,
"apply_history_import": StartTaskResponse,
"store_status": StoreStatusResponse,
"store_connect": StoreSimpleResponse,
"store_disconnect": StoreSimpleResponse,
@@ -752,6 +824,8 @@ WS_RESPONSE_TYPES: dict[str, type] = {
"store_set_online": StoreOnlineResponse,
"store_set_prefs": StorePrefsResponse,
"store_get_device_profiles": StoreDeviceProfilesResponse,
"store_get_catalog_entry": StoreCatalogEntryResponse,
"store_refresh_catalog": StoreRefreshCatalogResponse,
"store_upload_device": StoreUploadDeviceResponse,
"store_download_device": StoreDownloadDeviceResponse,
"get_shareable_cycles": GetShareableCyclesResponse,
@@ -1006,7 +1080,10 @@ WS_COMMANDS: dict[str, dict] = {
_p("cycle_id", "str"),
_p("profile_name", "str|null", False),
]},
"get_playground_settings": {"params": [_entry()]},
"get_playground_settings": {"params": [
_entry(),
_p("include_suggestions", "bool", False),
]},
"save_playground_preset": {"params": [
_entry(),
_p("name", "str"),
@@ -1037,6 +1114,26 @@ WS_COMMANDS: dict[str, dict] = {
_p("stress_tail", "bool", False),
_p("stress_idle_w", "float|null", False),
]},
"history_import_begin": {"params": [_entry()]},
"history_import_chunk": {"params": [
_entry(),
_p("token", "str"),
_p("seq", "int"),
_p("text", "str"),
]},
"history_import_recorder": {"params": [
_entry(),
# Either bound: `start_date` (an ISO local calendar day, what the panel's date
# picker sends) wins over the legacy `days` count when both are present.
_p("start_date", "str|null", False),
_p("days", "int", False),
]},
"start_history_import_scan": {"params": [_entry(), _p("token", "str")]},
"apply_history_import": {"params": [
_entry(),
_p("scan_task_id", "str"),
_p("accept", "list"),
]},
# Community store (online features)
"store_status": {"params": [_entry()]},
"store_connect": {"params": [
@@ -1054,6 +1151,8 @@ WS_COMMANDS: dict[str, dict] = {
"store_get_cycles": {"params": [_entry(), _p("profile_id", "str")]},
"store_get_device_quality": {"params": [_entry(), _p("device_id", "str")]},
"store_get_device_profiles": {"params": [_entry(), _p("brand", "str"), _p("model", "str"), _p("appliance_type", "str")]},
"store_get_catalog_entry": {"params": [_entry(), _p("brand", "str"), _p("model", "str"), _p("appliance_type", "str")]},
"store_refresh_catalog": {"params": [_entry()]},
"store_confirm_device": {"params": [_entry(), _p("device_id", "str")]},
"store_rate_device": {"params": [_entry(), _p("device_id", "str"), _p("rating", "int")]},
"store_set_online": {"params": [_entry(), _p("enabled", "bool")]},
@@ -0,0 +1,19 @@
{
"generator": "esbuild 0.25.12",
"assets": {
"ha-washdata-panel.js": {
"artifact": "ha-washdata-panel.min.js",
"source_sha256": "b7065b51086421552eecaa395f8dfd743b2f0b646f9ad80a5e3e955dc54b5926",
"artifact_sha256": "92d975bc6c11acff7060c2bd11d1ad09b1c43b0575e1655d7bec67a9438cd327",
"source_bytes": 843545,
"artifact_bytes": 564506
},
"ha-washdata-card.js": {
"artifact": "ha-washdata-card.min.js",
"source_sha256": "71a6d762af2ab78525a3bc169d6bfa682ce5f79ab3bd23a808059102a1d223e3",
"artifact_sha256": "f7e8ab6492010f5ad6875e0c2969a5fe43ff3040ac96ada665cd61016963ea16",
"source_bytes": 50627,
"artifact_bytes": 29435
}
}
}
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
+97
View File
@@ -20,6 +20,8 @@ export interface AnalyzeSplitResponse {
segments: number[][];
split_offsets: number[];
samples: number[][];
sample_count: number;
decimated: boolean;
full_duration_s: number;
}
@@ -54,11 +56,13 @@ export interface DeviceInfo {
current_power_w: number | null;
cycle_progress_pct: number | null;
suggestions_count: number;
suggestion_keys: string[];
feedback_count: number;
recording: boolean;
is_user_paused: boolean;
manual_program: boolean;
options: Record<string, unknown>;
option_defaults: Record<string, unknown>;
}
export interface DismissAllFeedbacksResponse {
@@ -109,6 +113,8 @@ export interface GetConstantsResponse {
export interface GetCyclePowerDataResponse {
cycle_id?: string;
samples?: number[][];
sample_count?: number;
decimated?: boolean;
full_duration_s?: number;
start_time?: string | null;
end_time?: string | null;
@@ -119,12 +125,16 @@ export interface GetCyclePowerDataResponse {
artifacts?: Record<string, unknown>[];
restart_gaps?: unknown[];
is_reference?: boolean;
labelable?: boolean;
editable?: boolean;
cycle_origin?: string;
}
export interface GetDeviceCyclesResponse {
entry_id: string;
cycles: Record<string, unknown>[];
reference_cycles: Record<string, unknown>[];
backfill_cycles: Record<string, unknown>[];
total: number;
has_more: boolean;
}
@@ -203,6 +213,7 @@ export interface GetMlTrainingStatusResponse {
export interface GetOptionsResponse {
options: Record<string, unknown>;
defaults: Record<string, unknown>;
}
export interface GetPanelConfigResponse {
@@ -300,6 +311,26 @@ export interface GetSuggestionsResponse {
locked_suggestions: string[];
}
export interface HistoryImportBeginResponse {
token: string;
max_bytes: number;
chunk_bytes: number;
}
export interface HistoryImportChunkResponse {
received_bytes: number;
next_seq: number;
}
export interface HistoryImportRecorderResponse {
token: string;
rows: number;
entity_id: string;
days: number;
start_date: string;
truncated: boolean;
}
export interface ImportConfigSelectiveResponse {
success: boolean;
summary: Record<string, unknown>;
@@ -393,6 +424,13 @@ export interface StartTaskResponse {
task_id: string;
}
export interface StoreCatalogEntryResponse {
device_id?: string;
brand?: Record<string, unknown> | null;
device?: Record<string, unknown> | null;
disabled?: boolean;
}
export interface StoreConfirmResponse {
confirmed?: boolean;
confirmCount?: number;
@@ -447,6 +485,11 @@ export interface StoreQualityResponse {
disabled?: boolean;
}
export interface StoreRefreshCatalogResponse {
ok?: boolean;
disabled?: boolean;
}
export interface StoreSimpleResponse {
connected?: boolean;
uid?: string | null;
@@ -915,6 +958,7 @@ export interface GetDtwDebugRequest {
export interface GetPlaygroundSettingsRequest {
entry_id: string;
include_suggestions?: boolean;
}
export interface SavePlaygroundPresetRequest {
@@ -967,6 +1011,34 @@ export interface StartPlaygroundCycleDetailRequest {
stress_idle_w?: number | null;
}
export interface HistoryImportBeginRequest {
entry_id: string;
}
export interface HistoryImportChunkRequest {
entry_id: string;
token: string;
seq: number;
text: string;
}
export interface HistoryImportRecorderRequest {
entry_id: string;
start_date?: string | null;
days?: number;
}
export interface StartHistoryImportScanRequest {
entry_id: string;
token: string;
}
export interface ApplyHistoryImportRequest {
entry_id: string;
scan_task_id: string;
accept: unknown[];
}
export interface StoreStatusRequest {
entry_id: string;
}
@@ -1018,6 +1090,17 @@ export interface StoreGetDeviceProfilesRequest {
appliance_type: string;
}
export interface StoreGetCatalogEntryRequest {
entry_id: string;
brand: string;
model: string;
appliance_type: string;
}
export interface StoreRefreshCatalogRequest {
entry_id: string;
}
export interface StoreConfirmDeviceRequest {
entry_id: string;
device_id: string;
@@ -1161,6 +1244,11 @@ export interface WashDataWsRequests {
"ha_washdata/start_playground_history": StartPlaygroundHistoryRequest;
"ha_washdata/start_playground_sweep": StartPlaygroundSweepRequest;
"ha_washdata/start_playground_cycle_detail": StartPlaygroundCycleDetailRequest;
"ha_washdata/history_import_begin": HistoryImportBeginRequest;
"ha_washdata/history_import_chunk": HistoryImportChunkRequest;
"ha_washdata/history_import_recorder": HistoryImportRecorderRequest;
"ha_washdata/start_history_import_scan": StartHistoryImportScanRequest;
"ha_washdata/apply_history_import": ApplyHistoryImportRequest;
"ha_washdata/store_status": StoreStatusRequest;
"ha_washdata/store_connect": StoreConnectRequest;
"ha_washdata/store_disconnect": StoreDisconnectRequest;
@@ -1170,6 +1258,8 @@ export interface WashDataWsRequests {
"ha_washdata/store_get_cycles": StoreGetCyclesRequest;
"ha_washdata/store_get_device_quality": StoreGetDeviceQualityRequest;
"ha_washdata/store_get_device_profiles": StoreGetDeviceProfilesRequest;
"ha_washdata/store_get_catalog_entry": StoreGetCatalogEntryRequest;
"ha_washdata/store_refresh_catalog": StoreRefreshCatalogRequest;
"ha_washdata/store_confirm_device": StoreConfirmDeviceRequest;
"ha_washdata/store_rate_device": StoreRateDeviceRequest;
"ha_washdata/store_set_online": StoreSetOnlineRequest;
@@ -1270,6 +1360,11 @@ export interface WashDataWsResponses {
"ha_washdata/start_playground_history": StartTaskResponse;
"ha_washdata/start_playground_sweep": StartTaskResponse;
"ha_washdata/start_playground_cycle_detail": StartTaskResponse;
"ha_washdata/history_import_begin": HistoryImportBeginResponse;
"ha_washdata/history_import_chunk": HistoryImportChunkResponse;
"ha_washdata/history_import_recorder": HistoryImportRecorderResponse;
"ha_washdata/start_history_import_scan": StartTaskResponse;
"ha_washdata/apply_history_import": StartTaskResponse;
"ha_washdata/store_status": StoreStatusResponse;
"ha_washdata/store_connect": StoreSimpleResponse;
"ha_washdata/store_disconnect": StoreSimpleResponse;
@@ -1285,6 +1380,8 @@ export interface WashDataWsResponses {
"ha_washdata/store_set_online": StoreOnlineResponse;
"ha_washdata/store_set_prefs": StorePrefsResponse;
"ha_washdata/store_get_device_profiles": StoreDeviceProfilesResponse;
"ha_washdata/store_get_catalog_entry": StoreCatalogEntryResponse;
"ha_washdata/store_refresh_catalog": StoreRefreshCatalogResponse;
"ha_washdata/store_upload_device": StoreUploadDeviceResponse;
"ha_washdata/store_download_device": StoreDownloadDeviceResponse;
"ha_washdata/get_shareable_cycles": GetShareableCyclesResponse;
+32 -32
View File
@@ -4,10 +4,10 @@
"state": "ON",
"led_brightness": 100,
"countdown_to_turn_off": 0,
"voltage": 122.4,
"voltage": 122.1,
"countdown_to_turn_on": 0,
"ac_frequency": 60,
"power_factor": 0.11,
"power_factor": 0.13,
"update": {
"state": "idle",
"installed_version": 268513381,
@@ -22,15 +22,15 @@
},
"0xffffb40e0607af27": {
"state": "ON",
"voltage": 121.9,
"voltage": 122,
"ac_frequency": 60,
"led_brightness": 100,
"countdown_to_turn_off": 0,
"countdown_to_turn_on": 0,
"power": 1.9,
"current": 0.1,
"energy": 32.14,
"power_factor": 0.17,
"power": 3.8,
"current": 0.11,
"energy": 32.19,
"power_factor": 0.28,
"update": {
"state": "idle",
"installed_version": 268513381,
@@ -45,9 +45,9 @@
"state": "ON",
"led_brightness": 100,
"countdown_to_turn_off": 0,
"voltage": 121.9,
"voltage": 122.5,
"countdown_to_turn_on": 0,
"energy": 63.6,
"energy": 63.64,
"power_factor": 0.2,
"ac_frequency": 60,
"update": {
@@ -58,8 +58,8 @@
"latest_release_notes": null
},
"linkquality": 138,
"power": 84.2,
"current": 0.78,
"power": 0.2,
"current": 0.01,
"power_on_behavior": "on"
},
"0xb40e060fffe031e3": {
@@ -74,13 +74,13 @@
"led_brightness": 100,
"countdown_to_turn_off": 0,
"countdown_to_turn_on": 0,
"voltage": 121.3,
"voltage": 121.5,
"state": "ON",
"ac_frequency": 60,
"energy": 128.77,
"power": 3.7,
"current": 0.05,
"power_factor": 0.41,
"energy": 128.83,
"power": 94.6,
"current": 0.84,
"power_factor": 0.4,
"update": {
"state": "idle",
"installed_version": 268513381,
@@ -95,13 +95,13 @@
"led_brightness": 100,
"countdown_to_turn_off": 0,
"countdown_to_turn_on": 0,
"voltage": 122.2,
"energy": 60.55,
"voltage": 122.5,
"energy": 60.59,
"state": "ON",
"power": 27.6,
"current": 0.45,
"power": 28.2,
"current": 0.44,
"ac_frequency": 60,
"power_factor": 0.55,
"power_factor": 0.54,
"update": {
"state": "idle",
"installed_version": 268513381,
@@ -114,12 +114,12 @@
},
"0xffffb40e060895b3": {
"state": "ON",
"voltage": 120.7,
"voltage": 122.5,
"ac_frequency": 60,
"energy": 8.78,
"current": 0.01,
"power": 0.2,
"power_factor": 0.11,
"power": 0.1,
"power_factor": 0.2,
"linkquality": 109,
"update": {
"state": "idle",
@@ -136,7 +136,7 @@
"0xffffb40e0608864e": {
"led_brightness": 100,
"countdown_to_turn_off": 0,
"voltage": 122.7,
"voltage": 123,
"energy": 20.07,
"countdown_to_turn_on": 0,
"state": "ON",
@@ -170,15 +170,15 @@
}
},
"0xffffb40e060893d8": {
"state": "OFF",
"state": "ON",
"led_brightness": 100,
"voltage": 122.3,
"voltage": 123,
"countdown_to_turn_off": 0,
"countdown_to_turn_on": 0,
"energy": 3.27,
"power_on_behavior": "on",
"linkquality": 142,
"current": 0,
"current": 0.06,
"ac_frequency": 60,
"update": {
"state": "idle",
@@ -187,12 +187,12 @@
"latest_source": "https://raw.githubusercontent.com/Koenkk/zigbee-OTA/master/images/ThirdReality/SmartPlug_Zigbee_PROD_OTA_V101_1.01.01.ota",
"latest_release_notes": null
},
"power_factor": 0,
"power": 0
"power_factor": 0.86,
"power": 9.7
},
"0xa4c1380d0679ffff": {
"battery": 100,
"temperature": 26.4,
"temperature": 26.7,
"temperature_units": "celsius",
"temperature_calibration": 0,
"update": {
@@ -245,7 +245,7 @@
},
"0xb40e060fffe717c5": {
"battery": 100,
"occupancy": false,
"occupancy": true,
"tamper": false,
"battery_low": false,
"linkquality": 138,