Updated apps
This commit is contained in:
@@ -75,15 +75,9 @@ from .const import (
|
||||
CONF_SMOOTHING_WINDOW,
|
||||
CONF_PROFILE_DURATION_TOLERANCE,
|
||||
CONF_INTERRUPTED_MIN_SECONDS,
|
||||
CONF_ABRUPT_DROP_WATTS,
|
||||
CONF_ABRUPT_DROP_RATIO,
|
||||
CONF_ABRUPT_HIGH_LOAD_FACTOR,
|
||||
DEFAULT_SMOOTHING_WINDOW,
|
||||
DEFAULT_PROFILE_DURATION_TOLERANCE,
|
||||
DEFAULT_INTERRUPTED_MIN_SECONDS,
|
||||
DEFAULT_ABRUPT_DROP_WATTS,
|
||||
DEFAULT_ABRUPT_DROP_RATIO,
|
||||
DEFAULT_ABRUPT_HIGH_LOAD_FACTOR,
|
||||
CONF_PROFILE_MATCH_INTERVAL,
|
||||
CONF_PROFILE_MATCH_MIN_DURATION_RATIO,
|
||||
CONF_PROFILE_MATCH_MAX_DURATION_RATIO,
|
||||
@@ -142,7 +136,19 @@ async def async_migrate_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||
)
|
||||
return False
|
||||
|
||||
if version == 3 and minor_version >= 6:
|
||||
if version == 3 and minor_version >= 7:
|
||||
return True
|
||||
|
||||
# 3.6 → 3.7: remove initial_profile stub key from entry.data.
|
||||
if version == 3 and minor_version == 6:
|
||||
new_data = {k: v for k, v in entry.data.items() if k != "initial_profile"}
|
||||
hass.config_entries.async_update_entry(
|
||||
entry, data=new_data, minor_version=7
|
||||
)
|
||||
minor_version = 7
|
||||
_log.debug("Migrated WashData entry from 3.6 to 3.7")
|
||||
|
||||
if version == 3 and minor_version >= 7:
|
||||
return True
|
||||
|
||||
data: dict[str, Any] = dict(entry.data)
|
||||
@@ -185,9 +191,6 @@ async def async_migrate_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||
CONF_PROFILE_DURATION_TOLERANCE, DEFAULT_PROFILE_DURATION_TOLERANCE
|
||||
)
|
||||
options.setdefault(CONF_INTERRUPTED_MIN_SECONDS, DEFAULT_INTERRUPTED_MIN_SECONDS)
|
||||
options.setdefault(CONF_ABRUPT_DROP_WATTS, DEFAULT_ABRUPT_DROP_WATTS)
|
||||
options.setdefault(CONF_ABRUPT_DROP_RATIO, DEFAULT_ABRUPT_DROP_RATIO)
|
||||
options.setdefault(CONF_ABRUPT_HIGH_LOAD_FACTOR, DEFAULT_ABRUPT_HIGH_LOAD_FACTOR)
|
||||
|
||||
options.setdefault(
|
||||
CONF_DEVICE_TYPE, data.get(CONF_DEVICE_TYPE, DEFAULT_DEVICE_TYPE)
|
||||
@@ -280,10 +283,10 @@ async def async_migrate_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||
data=data,
|
||||
options=options,
|
||||
version=3,
|
||||
minor_version=6,
|
||||
minor_version=7,
|
||||
)
|
||||
_log.info(
|
||||
"Migrated WashData entry from version %s.%s to 3.6", version, minor_version
|
||||
"Migrated WashData entry from version %s.%s to 3.7", version, minor_version
|
||||
)
|
||||
return True
|
||||
|
||||
@@ -370,28 +373,6 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||
await manager.async_setup()
|
||||
await _migrate_online_to_global(hass, entry, manager)
|
||||
|
||||
# Check for initial profile from onboarding
|
||||
if "initial_profile" in entry.data:
|
||||
init_prof = entry.data["initial_profile"]
|
||||
name = init_prof.get("name")
|
||||
duration = init_prof.get("avg_duration")
|
||||
if name:
|
||||
try:
|
||||
# Create the profile immediately
|
||||
await manager.profile_store.create_profile_standalone(
|
||||
name, avg_duration=duration
|
||||
)
|
||||
manager._logger.info("Created initial profile '%s' from onboarding", name)
|
||||
|
||||
# Clean up config entry (remove initial_profile to avoid re-creation or cruft)
|
||||
new_data = {
|
||||
k: v for k, v in entry.data.items() if k != "initial_profile"
|
||||
}
|
||||
hass.config_entries.async_update_entry(entry, data=new_data)
|
||||
|
||||
except Exception as e: # pylint: disable=broad-exception-caught
|
||||
manager._logger.error("Failed to create initial profile: %s", e)
|
||||
|
||||
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
|
||||
|
||||
_apply_device_link(hass, entry)
|
||||
|
||||
@@ -24,6 +24,8 @@ import numpy as np
|
||||
|
||||
from .const import (
|
||||
DEFAULT_DTW_MODE,
|
||||
DEFAULT_PROFILE_MATCH_MAX_DURATION_RATIO,
|
||||
DEFAULT_PROFILE_MATCH_MIN_DURATION_RATIO,
|
||||
MATCH_CORR_WEIGHT,
|
||||
MATCH_DDTW_DIST_SCALE,
|
||||
MATCH_DTW_BLEND,
|
||||
@@ -270,8 +272,8 @@ def compute_matches_worker(
|
||||
"""Worker function to compute matches against snapshots."""
|
||||
candidates: list[dict[str, Any]] = []
|
||||
|
||||
min_duration_ratio = config.get("min_duration_ratio", 0.07)
|
||||
max_duration_ratio = config.get("max_duration_ratio", 1.3)
|
||||
min_duration_ratio = config.get("min_duration_ratio", DEFAULT_PROFILE_MATCH_MIN_DURATION_RATIO)
|
||||
max_duration_ratio = config.get("max_duration_ratio", DEFAULT_PROFILE_MATCH_MAX_DURATION_RATIO)
|
||||
dtw_bandwidth = config.get("dtw_bandwidth", 0.1)
|
||||
dtw_mode = config.get("dtw_mode", DEFAULT_DTW_MODE)
|
||||
keep_min = float(config.get("keep_min_score", MATCH_KEEP_MIN_SCORE))
|
||||
|
||||
@@ -147,7 +147,7 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): # pylint: disable=a
|
||||
"""Handle a config flow for WashData."""
|
||||
|
||||
VERSION = 3
|
||||
MINOR_VERSION = 6
|
||||
MINOR_VERSION = 7
|
||||
|
||||
def __init__(self) -> None:
|
||||
"""Initialize the config flow."""
|
||||
@@ -182,42 +182,7 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): # pylint: disable=a
|
||||
)
|
||||
|
||||
self._user_input = user_input
|
||||
return await self.async_step_first_profile()
|
||||
|
||||
async def async_step_first_profile(
|
||||
self, user_input: dict[str, Any] | None = None # pylint: disable=unused-argument
|
||||
) -> FlowResult:
|
||||
"""Step to optionally create the first profile."""
|
||||
|
||||
if user_input is not None:
|
||||
profile_name = user_input.get("profile_name", "").strip()
|
||||
data = dict(self._user_input)
|
||||
|
||||
if profile_name:
|
||||
duration_mins = user_input.get("manual_duration")
|
||||
duration_sec = (duration_mins * 60.0) if duration_mins else None
|
||||
data["initial_profile"] = {
|
||||
"name": profile_name,
|
||||
"avg_duration": duration_sec,
|
||||
}
|
||||
|
||||
return self.async_create_entry(title=data[CONF_NAME], data=data)
|
||||
|
||||
schema = vol.Schema(
|
||||
{
|
||||
vol.Optional("profile_name"): str,
|
||||
vol.Optional("manual_duration", default=120): selector.NumberSelector(
|
||||
selector.NumberSelectorConfig(
|
||||
min=0,
|
||||
max=480,
|
||||
unit_of_measurement="min",
|
||||
mode=selector.NumberSelectorMode.BOX,
|
||||
)
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
return self.async_show_form(step_id="first_profile", data_schema=schema)
|
||||
return self.async_create_entry(title=self._user_input[CONF_NAME], data=self._user_input)
|
||||
|
||||
async def async_step_reconfigure(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
|
||||
@@ -96,13 +96,33 @@ CONF_POWER_OFF_DELAY = (
|
||||
"power_off_delay" # Seconds below the power-off threshold before Finished/Clean -> Off
|
||||
)
|
||||
CONF_EXPOSE_DEBUG_ENTITIES = "expose_debug_entities" # Expose detailed debug sensors
|
||||
# Per-device opt-in: blend the phase-resolved (per-role budget) ETA into the
|
||||
# time-remaining estimate for phase-matching-supported device types (washing
|
||||
# machine, washer-dryer). Default off. Validated by the Phase-0 ETA gate; see
|
||||
# docs/superpowers/specs/2026-07-17-phase-segmented-matching-design.md.
|
||||
CONF_ENABLE_PHASE_MATCHING = "enable_phase_matching"
|
||||
# Phase-structure consistency advisory (Profiles tab, never a notification).
|
||||
# A single-program/temperature profile should have a fairly consistent heating
|
||||
# block; wildly varying heating time or heating present in only some cycles
|
||||
# usually means different programs/temperatures were labelled under one profile
|
||||
# (the "mixed labels" data-hygiene problem). Pure statistics from the cached
|
||||
# phase profile - no relabeling (phase matching does not label better than the
|
||||
# whole-cycle matcher; see the Phase-0 gate).
|
||||
# Minimum member cycles before a profile's cached phase profile is trusted to
|
||||
# drive the live phase-resolved ETA (mirrors the envelope's cycle_count>=2 gate);
|
||||
# below this the priors are too noisy (single-cycle -> zero variance) and the
|
||||
# estimate falls back to the classic one. Design §6 cold-start floor.
|
||||
PHASE_PROFILE_MIN_CYCLES = 2
|
||||
PHASE_CONSISTENCY_MIN_CYCLES = 4
|
||||
# Heating-time std/mean above this -> likely mixed temperatures under one label.
|
||||
# A clean single-temperature profile sits ~0.2 (load variation only); a profile
|
||||
# mixing 30/40/90C sits ~0.45-0.6, so 0.45 catches genuine mixing with margin.
|
||||
PHASE_HEAT_CV_WARN = 0.45
|
||||
PHASE_HEAT_OCC_MIXED_LO = 0.25 # heating present in only 25%-75% of cycles ->
|
||||
PHASE_HEAT_OCC_MIXED_HI = 0.75 # mixed with a non-heating program
|
||||
CONF_SAVE_DEBUG_TRACES = (
|
||||
"save_debug_traces" # Improve historical cycle data with rich debug info
|
||||
)
|
||||
# Cycle interruption detection settings (not exposed in UI, but used internally)
|
||||
CONF_ABRUPT_DROP_WATTS = "abrupt_drop_watts" # Power cliff threshold for interrupted status
|
||||
CONF_ABRUPT_DROP_RATIO = "abrupt_drop_ratio" # Relative drop ratio for interrupted status
|
||||
CONF_ABRUPT_HIGH_LOAD_FACTOR = "abrupt_high_load_factor" # High load factor threshold
|
||||
CONF_AUTO_TUNE_NOISE_EVENTS_THRESHOLD = "auto_tune_noise_events_threshold" # Noise events before auto-tune
|
||||
CONF_EXTERNAL_END_TRIGGER_ENABLED = "external_end_trigger_enabled" # Enable external cycle end trigger
|
||||
CONF_EXTERNAL_END_TRIGGER = "external_end_trigger" # Binary sensor entity for external cycle end
|
||||
@@ -138,6 +158,14 @@ CONF_NOTIFY_CHANNEL = "notify_channel" # Android channel for status/live/remind
|
||||
CONF_NOTIFY_FINISH_CHANNEL = "notify_finish_channel" # Distinct Android channel for finished/clean
|
||||
CONF_ENERGY_PRICE_STATIC = "energy_price_static"
|
||||
CONF_ENERGY_PRICE_ENTITY = "energy_price_entity"
|
||||
# Optional external cumulative energy meter (issue #316). When set, each cycle's
|
||||
# reported energy is taken from this counter's start->end delta instead of the
|
||||
# integrated power trace, which systematically under-counts on report-on-change
|
||||
# plugs. Strictly opt-in: with no entity configured, behaviour is unchanged. The
|
||||
# integrated value is always still computed and stored (energy_wh) so matching,
|
||||
# ML and anomaly stats stay internally consistent; the meter only supplies the
|
||||
# user-facing reported figure (cost, lifetime total, notifications, panel).
|
||||
CONF_ENERGY_SENSOR = "energy_sensor"
|
||||
# Peak-rate awareness: when the current price meets/exceeds this threshold, the
|
||||
# start notification gets an informational tip appended (purely advisory).
|
||||
CONF_PEAK_RATE_THRESHOLD = "peak_rate_threshold"
|
||||
@@ -323,10 +351,6 @@ TERMINAL_DROP_MIN_PEAK_RATIO = 5.0 # cycle must have been clearly ON (peak
|
||||
# rather than assumed to be a stop.
|
||||
TERMINAL_DROP_PEAK_FAMILIAR_TOL = 0.4
|
||||
|
||||
# Cycle interruption detection defaults (internal)
|
||||
DEFAULT_ABRUPT_DROP_WATTS = 500.0 # Power cliff detection threshold (W)
|
||||
DEFAULT_ABRUPT_DROP_RATIO = 0.6 # 60% drop considered abrupt
|
||||
DEFAULT_ABRUPT_HIGH_LOAD_FACTOR = 5.0 # High load factor threshold
|
||||
DEFAULT_AUTO_TUNE_NOISE_EVENTS_THRESHOLD = 3 # Ghost cycles before threshold adjustment
|
||||
|
||||
# Anti-wrinkle defaults (advanced; disabled by default)
|
||||
@@ -435,6 +459,8 @@ REFERENCE_PROFILE_CURVE_POINTS = 50
|
||||
# actually DROPPING (62.7%->59.9%). Raising weight alone at the old loose scale
|
||||
# inflated both recall and FP (net-negative), so both knobs move together.
|
||||
MATCH_DURATION_WEIGHT = 0.22
|
||||
# Despite the name, "energy" here means mean power (W), not Wh — the Stage-4
|
||||
# agreement term compares cur_energy=mean(curr_arr) vs profile_mean_power.
|
||||
MATCH_ENERGY_WEIGHT = 0.22
|
||||
MATCH_DURATION_SCALE = 0.175 # ~ln ratio at which duration agreement halves
|
||||
MATCH_ENERGY_SCALE = 0.25 # ~ln ratio at which energy agreement halves
|
||||
@@ -688,7 +714,10 @@ GROUP_MIN_COHESION = 0.80
|
||||
# v9: pre-initialize additive top-level keys (lifetime_energy_wh,
|
||||
# settings_changelog, maintenance_log) so they are present from first load
|
||||
# rather than only appearing lazily on first use.
|
||||
STORAGE_VERSION = 10
|
||||
# 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
|
||||
STORAGE_KEY = "ha_washdata"
|
||||
|
||||
# Notification events
|
||||
|
||||
@@ -107,9 +107,6 @@ class CycleDetectorConfig:
|
||||
device_type: str = DEVICE_TYPE_WASHING_MACHINE
|
||||
smoothing_window: int = 5
|
||||
interrupted_min_seconds: int = 150
|
||||
abrupt_drop_watts: float = 500.0
|
||||
abrupt_drop_ratio: float = 0.6
|
||||
abrupt_high_load_factor: float = 5.0
|
||||
completion_min_seconds: int = 600
|
||||
start_duration_threshold: float = 5.0
|
||||
start_energy_threshold: float = 0.005
|
||||
@@ -273,7 +270,6 @@ class CycleDetector:
|
||||
self._matched_profile: str | None = None
|
||||
self._verified_pause: bool = False
|
||||
|
||||
self._abrupt_drop: bool = False
|
||||
self._last_power: float | None = None
|
||||
self._time_in_state: float = 0.0
|
||||
|
||||
@@ -780,7 +776,6 @@ class CycleDetector:
|
||||
self._energy_since_idle_wh = power * (dt / 3600.0) if dt > 0 else 0.0
|
||||
|
||||
self._cycle_max_power = max(candidate_peak, power)
|
||||
self._abrupt_drop = False
|
||||
elif self._state != STATE_ANTI_WRINKLE:
|
||||
self._anti_wrinkle_candidate_start = None
|
||||
self._anti_wrinkle_candidate_peak = 0.0
|
||||
@@ -891,7 +886,6 @@ class CycleDetector:
|
||||
self._power_readings = [(timestamp, power)]
|
||||
self._energy_since_idle_wh = power * (dt / 3600.0) if dt > 0 else 0.0
|
||||
self._cycle_max_power = power
|
||||
self._abrupt_drop = False
|
||||
# NOTE: terminal-state expiry (Finished/Interrupted/Force-Stopped -> Off)
|
||||
# is owned solely by the manager (WashDataManager._handle_state_expiry),
|
||||
# which has a wall-clock timer that also fires when a change-only power
|
||||
@@ -941,7 +935,6 @@ class CycleDetector:
|
||||
if timestamp != start_timestamp:
|
||||
self._power_readings.append((timestamp, power))
|
||||
self._cycle_max_power = max(start_power, power)
|
||||
self._abrupt_drop = False
|
||||
else:
|
||||
# Power dropped back below start threshold - clear the
|
||||
# high-power streak anchor so the next high reading
|
||||
@@ -1729,10 +1722,6 @@ class CycleDetector:
|
||||
status = "interrupted"
|
||||
elif duration < self._config.completion_min_seconds:
|
||||
status = "interrupted"
|
||||
elif self._abrupt_drop and duration < (
|
||||
self._config.interrupted_min_seconds + 90
|
||||
):
|
||||
status = "interrupted"
|
||||
|
||||
# Trim leading/trailing zero readings for cleaner data
|
||||
# If we keep tail, we explicitly do NOT trim end zeros
|
||||
|
||||
@@ -54,6 +54,7 @@ _SENSITIVE_KEYS = {
|
||||
"door_sensor_entity",
|
||||
"switch_entity",
|
||||
"energy_price_entity",
|
||||
"energy_sensor",
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -35,7 +35,6 @@ class CycleSignature:
|
||||
duration: float
|
||||
total_energy: float
|
||||
max_power: float
|
||||
event_density: float # Deprecated/reserved: always 0.0 (event detector removed); kept for signature back-compat
|
||||
time_to_first_high: float # Seconds to first HEATER/HIGH phase
|
||||
high_phase_ratio: float # Duration of high phases / total duration
|
||||
# Distributions (quantiles of power)
|
||||
@@ -59,7 +58,7 @@ def compute_signature(
|
||||
"""
|
||||
if len(power) == 0:
|
||||
# Return empty/zero signature
|
||||
return CycleSignature(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
|
||||
return CycleSignature(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
|
||||
|
||||
duration = timestamps[-1] - timestamps[0]
|
||||
|
||||
@@ -97,15 +96,10 @@ def compute_signature(
|
||||
else:
|
||||
high_phase_ratio = 0.0
|
||||
|
||||
# Event density: always 0 now that the event detector is gone; retained as a
|
||||
# signature field for backward compatibility with stored signatures.
|
||||
event_density = 0.0
|
||||
|
||||
return CycleSignature(
|
||||
duration=float(duration),
|
||||
total_energy=float(total_energy),
|
||||
max_power=float(max_p),
|
||||
event_density=float(event_density),
|
||||
time_to_first_high=float(time_to_first_high),
|
||||
high_phase_ratio=float(high_phase_ratio),
|
||||
p05=float(qs[0]),
|
||||
|
||||
@@ -68,9 +68,6 @@ from .const import (
|
||||
CONF_SMOOTHING_WINDOW,
|
||||
CONF_PROFILE_DURATION_TOLERANCE,
|
||||
CONF_INTERRUPTED_MIN_SECONDS,
|
||||
CONF_ABRUPT_DROP_WATTS,
|
||||
CONF_ABRUPT_DROP_RATIO,
|
||||
CONF_ABRUPT_HIGH_LOAD_FACTOR,
|
||||
CONF_PROGRESS_RESET_DELAY,
|
||||
CONF_LEARNING_CONFIDENCE,
|
||||
CONF_DURATION_TOLERANCE,
|
||||
@@ -133,9 +130,6 @@ from .const import (
|
||||
DEFAULT_SMOOTHING_WINDOW,
|
||||
DEFAULT_PROFILE_DURATION_TOLERANCE,
|
||||
DEFAULT_INTERRUPTED_MIN_SECONDS,
|
||||
DEFAULT_ABRUPT_DROP_WATTS,
|
||||
DEFAULT_ABRUPT_DROP_RATIO,
|
||||
DEFAULT_ABRUPT_HIGH_LOAD_FACTOR,
|
||||
DEFAULT_COMPLETION_MIN_SECONDS,
|
||||
DEFAULT_NOTIFY_BEFORE_END_MINUTES,
|
||||
DEFAULT_PROFILE_MATCH_THRESHOLD,
|
||||
@@ -175,6 +169,7 @@ from .const import (
|
||||
CONF_NOTIFY_FINISH_CHANNEL,
|
||||
CONF_ENERGY_PRICE_STATIC,
|
||||
CONF_ENERGY_PRICE_ENTITY,
|
||||
CONF_ENERGY_SENSOR,
|
||||
CONF_PEAK_RATE_THRESHOLD,
|
||||
CONF_PEAK_RATE_MESSAGE,
|
||||
DEFAULT_PEAK_RATE_MESSAGE,
|
||||
@@ -249,9 +244,8 @@ from .learning import LearningManager
|
||||
from .profile_store import (
|
||||
ProfileStore,
|
||||
decompress_power_data,
|
||||
device_active_peak_range,
|
||||
earliest_sustained_quiet_offset,
|
||||
is_terminal_drop,
|
||||
terminal_drop_baseline,
|
||||
)
|
||||
from .signal_processing import integrate_wh, energy_gap_threshold_s
|
||||
from .recorder import CycleRecorder
|
||||
@@ -260,6 +254,7 @@ from .log_utils import DeviceLoggerAdapter
|
||||
from .time_utils import power_data_to_offsets
|
||||
from . import progress as progress_mod
|
||||
from . import notification_rules as notif_rules
|
||||
from .phase_segmenter import phase_matching_enabled
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
@@ -418,6 +413,12 @@ class WashDataManager:
|
||||
# Matching always uses real readings only; this list is for display/anomaly.
|
||||
self._restart_gaps: list[dict[str, Any]] = []
|
||||
|
||||
# External energy-meter snapshot for the current cycle (issue #316).
|
||||
# Captured at cycle start, read back at cycle end for the start->end delta.
|
||||
# Both survive a restart via the active-cycle snapshot.
|
||||
self._energy_meter_start: float | None = None
|
||||
self._energy_meter_source: str | None = None
|
||||
|
||||
# Pause tracking (user-triggered)
|
||||
self._user_pause_start: datetime | None = None
|
||||
self._total_user_paused_seconds: float = 0.0
|
||||
@@ -607,12 +608,6 @@ class WashDataManager:
|
||||
interrupted_min_seconds = int(
|
||||
config_entry.options.get("interrupted_min_seconds", 150)
|
||||
)
|
||||
abrupt_drop_watts = float(config_entry.options.get("abrupt_drop_watts", 500.0))
|
||||
abrupt_drop_ratio = float(config_entry.options.get("abrupt_drop_ratio", 0.6))
|
||||
abrupt_high_load_factor = float(
|
||||
config_entry.options.get("abrupt_high_load_factor", 5.0)
|
||||
)
|
||||
|
||||
# Get device specific default for completion threshold
|
||||
device_default_completion = DEVICE_COMPLETION_THRESHOLDS.get(
|
||||
self.device_type, DEFAULT_COMPLETION_MIN_SECONDS
|
||||
@@ -647,9 +642,6 @@ class WashDataManager:
|
||||
off_delay=int(off_delay),
|
||||
smoothing_window=smoothing_window,
|
||||
interrupted_min_seconds=interrupted_min_seconds,
|
||||
abrupt_drop_watts=abrupt_drop_watts,
|
||||
abrupt_drop_ratio=abrupt_drop_ratio,
|
||||
abrupt_high_load_factor=abrupt_high_load_factor,
|
||||
completion_min_seconds=completion_min_seconds,
|
||||
start_duration_threshold=start_duration_threshold,
|
||||
running_dead_zone=running_dead_zone,
|
||||
@@ -796,6 +788,9 @@ class WashDataManager:
|
||||
self._terminal_drop_cache: (
|
||||
tuple[int, float | None, tuple[float, float] | None] | None
|
||||
) = None
|
||||
# Cycle count an executor refresh of the baseline is in-flight/done for, so
|
||||
# the loop never recomputes it (issue #311) and never double-schedules.
|
||||
self._terminal_drop_refresh_n: int | None = None
|
||||
|
||||
self._remove_listener = None
|
||||
self._remove_external_trigger_listener = None # External cycle end trigger
|
||||
@@ -895,6 +890,11 @@ class WashDataManager:
|
||||
self._logger.debug("Matching skipped: no readings")
|
||||
return
|
||||
|
||||
# Skip match entirely when no real profiles exist — nothing to match against.
|
||||
if not self.profile_store.has_real_profiles:
|
||||
self._logger.debug("Matching skipped: no real profiles configured yet")
|
||||
return
|
||||
|
||||
self._matching_task = self.hass.async_create_task(self._async_do_perform_matching(readings))
|
||||
except Exception as e:
|
||||
self._logger.error("Perform combined matching trigger failed: %s", e)
|
||||
@@ -1577,6 +1577,15 @@ class WashDataManager:
|
||||
"manual_program", False
|
||||
)
|
||||
|
||||
# Restore the external energy-meter snapshot (issue #316) so a
|
||||
# restart mid-cycle keeps an accurate start->end delta.
|
||||
self._energy_meter_start = active_snapshot_to_restore.get(
|
||||
"energy_meter_start"
|
||||
)
|
||||
self._energy_meter_source = active_snapshot_to_restore.get(
|
||||
"energy_meter_source"
|
||||
)
|
||||
|
||||
# If we restored into a low-power state, ensure we don't
|
||||
# immediately quit. For now we just log this; the cycle
|
||||
# detector's off_delay will handle actual shutdown.
|
||||
@@ -1887,9 +1896,6 @@ class WashDataManager:
|
||||
old_off_delay = self.detector.config.off_delay
|
||||
old_smoothing = self.detector.config.smoothing_window
|
||||
old_interrupted_min = self.detector.config.interrupted_min_seconds
|
||||
old_abrupt_drop_watts = self.detector.config.abrupt_drop_watts
|
||||
old_abrupt_drop_ratio = self.detector.config.abrupt_drop_ratio
|
||||
old_abrupt_high_load = self.detector.config.abrupt_high_load_factor
|
||||
|
||||
# Get new values from config
|
||||
new_min_power = float(
|
||||
@@ -1904,12 +1910,6 @@ class WashDataManager:
|
||||
CONF_INTERRUPTED_MIN_SECONDS, DEFAULT_INTERRUPTED_MIN_SECONDS
|
||||
)
|
||||
)
|
||||
new_abrupt_drop_watts = float(
|
||||
config_entry.options.get(CONF_ABRUPT_DROP_WATTS, DEFAULT_ABRUPT_DROP_WATTS)
|
||||
)
|
||||
new_abrupt_drop_ratio = float(
|
||||
config_entry.options.get(CONF_ABRUPT_DROP_RATIO, DEFAULT_ABRUPT_DROP_RATIO)
|
||||
)
|
||||
self.detector.config.match_interval = int(
|
||||
config_entry.options.get(
|
||||
CONF_PROFILE_MATCH_INTERVAL, DEFAULT_PROFILE_MATCH_INTERVAL
|
||||
@@ -1918,11 +1918,6 @@ class WashDataManager:
|
||||
self.profile_store.dtw_bandwidth = float(
|
||||
config_entry.options.get(CONF_DTW_BANDWIDTH, DEFAULT_DTW_BANDWIDTH)
|
||||
)
|
||||
new_abrupt_high_load = float(
|
||||
config_entry.options.get(
|
||||
CONF_ABRUPT_HIGH_LOAD_FACTOR, DEFAULT_ABRUPT_HIGH_LOAD_FACTOR
|
||||
)
|
||||
)
|
||||
|
||||
# Device default
|
||||
dev_def = DEVICE_COMPLETION_THRESHOLDS.get(
|
||||
@@ -2017,9 +2012,6 @@ class WashDataManager:
|
||||
self.detector.config.off_delay = new_off_delay
|
||||
self.detector.config.smoothing_window = new_smoothing
|
||||
self.detector.config.interrupted_min_seconds = new_interrupted_min
|
||||
self.detector.config.abrupt_drop_watts = new_abrupt_drop_watts
|
||||
self.detector.config.abrupt_drop_ratio = new_abrupt_drop_ratio
|
||||
self.detector.config.abrupt_high_load_factor = new_abrupt_high_load
|
||||
self.detector.config.completion_min_seconds = new_completion_min
|
||||
self.detector.config.start_duration_threshold = new_start_threshold
|
||||
self.detector.config.running_dead_zone = new_running_dead_zone
|
||||
@@ -2048,14 +2040,10 @@ class WashDataManager:
|
||||
or old_off_delay != new_off_delay
|
||||
or old_smoothing != new_smoothing
|
||||
or old_interrupted_min != new_interrupted_min
|
||||
or old_abrupt_drop_watts != new_abrupt_drop_watts
|
||||
or old_abrupt_drop_ratio != new_abrupt_drop_ratio
|
||||
or old_abrupt_high_load != new_abrupt_high_load
|
||||
):
|
||||
self._logger.info(
|
||||
"Updated detector config: min_power %.1fW→%.1fW, off_delay %ds→%ds, "
|
||||
"smoothing %d→%d, interrupted_min %ds→%ds, abrupt_drop %.0fW→%.0fW, "
|
||||
"abrupt_ratio %.2f→%.2f, high_load %.1f→%.1f",
|
||||
"Updated detector config: min_power %.1fW->%.1fW, off_delay %ds->%ds, "
|
||||
"smoothing %d->%d, interrupted_min %ds->%ds",
|
||||
old_min_power,
|
||||
new_min_power,
|
||||
old_off_delay,
|
||||
@@ -2064,12 +2052,6 @@ class WashDataManager:
|
||||
new_smoothing,
|
||||
old_interrupted_min,
|
||||
new_interrupted_min,
|
||||
old_abrupt_drop_watts,
|
||||
new_abrupt_drop_watts,
|
||||
old_abrupt_drop_ratio,
|
||||
new_abrupt_drop_ratio,
|
||||
old_abrupt_high_load,
|
||||
new_abrupt_high_load,
|
||||
)
|
||||
|
||||
# Update profile matching parameters
|
||||
@@ -2190,8 +2172,6 @@ class WashDataManager:
|
||||
self._reset_live_notification_state()
|
||||
self._check_live_progress_notification()
|
||||
|
||||
self._logger.info("Configuration reloaded successfully")
|
||||
|
||||
# Trigger entity updates to reflect any changes
|
||||
async_dispatcher_send(self.hass, f"ha_washdata_update_{self.entry_id}")
|
||||
|
||||
@@ -2270,15 +2250,7 @@ class WashDataManager:
|
||||
|
||||
# Save active state before shutdown
|
||||
if self.detector.state in {STATE_RUNNING, STATE_PAUSED, STATE_STARTING, STATE_ENDING}:
|
||||
snapshot = self.detector.get_state_snapshot()
|
||||
snapshot["manual_program"] = self._manual_program_active
|
||||
snapshot["notified_start"] = self._notified_start
|
||||
snapshot["start_event_fired"] = self._start_event_fired
|
||||
snapshot["is_user_paused"] = self._is_user_paused
|
||||
snapshot["user_pause_start"] = (
|
||||
self._user_pause_start.isoformat() if self._user_pause_start else None
|
||||
)
|
||||
snapshot["total_user_paused_seconds"] = self._total_user_paused_seconds
|
||||
snapshot = self._augment_active_snapshot(self.detector.get_state_snapshot())
|
||||
await self.profile_store.async_save_active_cycle(snapshot)
|
||||
|
||||
self._last_reading_time = None
|
||||
@@ -2829,15 +2801,7 @@ class WashDataManager:
|
||||
if not last_save or (now - last_save).total_seconds() > 60:
|
||||
# Fire and forget save task
|
||||
# Inject manual program flag into snapshot before saving
|
||||
snapshot = self.detector.get_state_snapshot()
|
||||
snapshot["manual_program"] = self._manual_program_active
|
||||
snapshot["notified_start"] = self._notified_start
|
||||
snapshot["start_event_fired"] = self._start_event_fired
|
||||
snapshot["is_user_paused"] = self._is_user_paused
|
||||
snapshot["user_pause_start"] = (
|
||||
self._user_pause_start.isoformat() if self._user_pause_start else None
|
||||
)
|
||||
snapshot["total_user_paused_seconds"] = self._total_user_paused_seconds
|
||||
snapshot = self._augment_active_snapshot(self.detector.get_state_snapshot())
|
||||
|
||||
self.hass.async_create_task(
|
||||
self.profile_store.async_save_active_cycle(snapshot)
|
||||
@@ -3463,6 +3427,9 @@ class WashDataManager:
|
||||
self._cycle_start_time = self.detector.current_cycle_start or dt_util.now()
|
||||
self._ranking_snapshot_cycle_id = str(uuid.uuid4())
|
||||
self._reset_live_notification_state()
|
||||
# Snapshot the external energy meter (issue #316) so cycle end can
|
||||
# take an accurate start->end delta. No-op when none is configured.
|
||||
self._snapshot_energy_meter_start()
|
||||
|
||||
# Reset pause tracking and clean state for new cycle
|
||||
self._is_user_paused = False
|
||||
@@ -3623,6 +3590,16 @@ class WashDataManager:
|
||||
# Store energy for notification and persistence (calculated above for ghost detection)
|
||||
cycle_data["energy_wh"] = round(cycle_energy_wh, 3)
|
||||
|
||||
# External energy meter (issue #316): when an accurate start->end delta is
|
||||
# available, record it alongside the integrated value and mark the source.
|
||||
# The integrated energy_wh above is left untouched so matching / ML / anomaly
|
||||
# stats stay internally consistent; only user-facing figures prefer the meter.
|
||||
cycle_data["energy_source"] = "integration"
|
||||
meter_wh = self._compute_meter_energy_wh()
|
||||
if meter_wh is not None:
|
||||
cycle_data["energy_meter_wh"] = round(meter_wh, 3)
|
||||
cycle_data["energy_source"] = "meter"
|
||||
|
||||
# Schedule heavy post-processing asynchronously. Capture this cycle's identity
|
||||
# token so the async tail can tell if a NEW cycle started while it was awaiting
|
||||
# (power changes are handled synchronously, so a back-to-back load can drive the
|
||||
@@ -3736,23 +3713,53 @@ class WashDataManager:
|
||||
|
||||
Both are learned from the device's completed cycles and used by the
|
||||
terminal-drop detector (anomaly + familiarity gates). Keyed by cycle
|
||||
count so it refreshes as history grows without re-decompressing every
|
||||
trace on each low-power reading."""
|
||||
count so it refreshes as history grows.
|
||||
|
||||
The recompute decompresses every completed trace, which is too heavy to run
|
||||
on the event loop inside the detector's reading path (issue #311). So this
|
||||
NEVER recomputes synchronously: on a miss/stale cache it schedules an
|
||||
executor refresh and serves the last known baseline in the meantime (one
|
||||
cycle stale is harmless for an anomaly heuristic). Until the first refresh
|
||||
lands there is no baseline, so it returns ``(None, None)`` and
|
||||
``is_terminal_drop`` defers to the proven slow end-detection."""
|
||||
cycles = self.profile_store.get_past_cycles()
|
||||
n = len(cycles)
|
||||
cache = self._terminal_drop_cache
|
||||
if cache is not None and cache[0] == n:
|
||||
return cache[1], cache[2]
|
||||
stop_threshold = float(self.detector.config.stop_threshold_w)
|
||||
earliest = earliest_sustained_quiet_offset(
|
||||
cycles,
|
||||
stop_threshold,
|
||||
TERMINAL_DROP_MIN_QUIET_SPAN_S,
|
||||
TERMINAL_DROP_MIN_CLEAN_CYCLES,
|
||||
)
|
||||
peak_range = device_active_peak_range(cycles, TERMINAL_DROP_MIN_CLEAN_CYCLES)
|
||||
self._terminal_drop_cache = (n, earliest, peak_range)
|
||||
return earliest, peak_range
|
||||
self._schedule_terminal_drop_refresh(n)
|
||||
if cache is not None:
|
||||
return cache[1], cache[2]
|
||||
return None, None
|
||||
|
||||
def _schedule_terminal_drop_refresh(self, n: int) -> None:
|
||||
"""Kick a one-shot executor refresh of the terminal-drop baseline for the
|
||||
current cycle count, unless one is already in-flight/done for it."""
|
||||
if self._terminal_drop_refresh_n == n:
|
||||
return
|
||||
self._terminal_drop_refresh_n = n
|
||||
self.hass.async_create_task(self._async_refresh_terminal_drop_baseline(n))
|
||||
|
||||
async def _async_refresh_terminal_drop_baseline(self, n: int) -> None:
|
||||
"""Recompute the baseline off the event loop and cache it. Never raises -
|
||||
the anomaly signal must never break detection."""
|
||||
try:
|
||||
# Snapshot the list on the loop before handing it to the executor.
|
||||
cycles = list(self.profile_store.get_past_cycles())
|
||||
stop_threshold = float(self.detector.config.stop_threshold_w)
|
||||
earliest, peak_range = await self.hass.async_add_executor_job(
|
||||
terminal_drop_baseline,
|
||||
cycles,
|
||||
stop_threshold,
|
||||
TERMINAL_DROP_MIN_QUIET_SPAN_S,
|
||||
TERMINAL_DROP_MIN_CLEAN_CYCLES,
|
||||
)
|
||||
self._terminal_drop_cache = (len(cycles), earliest, peak_range)
|
||||
except Exception as err: # noqa: BLE001 - anomaly signal must never break detection
|
||||
self._logger.debug("Terminal-drop baseline refresh failed: %s", err)
|
||||
# Allow a later reading to retry the refresh for this count.
|
||||
if self._terminal_drop_refresh_n == n:
|
||||
self._terminal_drop_refresh_n = None
|
||||
|
||||
def _ml_progress_percent(
|
||||
self,
|
||||
@@ -3899,6 +3906,102 @@ class WashDataManager:
|
||||
pass
|
||||
return None
|
||||
|
||||
def _read_energy_meter(self) -> tuple[float, str] | None:
|
||||
"""Read the configured external energy meter, normalized to Wh.
|
||||
|
||||
Returns ``(value_wh, entity_id)`` or ``None`` when no meter is configured
|
||||
or its reading is not usable (unknown/unavailable/non-numeric state, or an
|
||||
unrecognised unit). Never raises -- every failure path returns ``None`` so
|
||||
the caller falls back to the integrated energy (issue #316).
|
||||
"""
|
||||
entity_id = self.config_entry.options.get(CONF_ENERGY_SENSOR)
|
||||
if not entity_id:
|
||||
return None
|
||||
state = self.hass.states.get(entity_id)
|
||||
if state is None or state.state in (None, "unknown", "unavailable", ""):
|
||||
return None
|
||||
try:
|
||||
value = float(state.state)
|
||||
except (ValueError, TypeError):
|
||||
return None
|
||||
unit = str(state.attributes.get("unit_of_measurement") or "").strip().lower()
|
||||
# Normalize to Wh. An unrecognised unit is treated as unusable so a
|
||||
# mis-configured entity falls back rather than reporting a wrong figure.
|
||||
scale = {"wh": 1.0, "kwh": 1000.0, "mwh": 1_000_000.0}.get(unit)
|
||||
if scale is None:
|
||||
return None
|
||||
return value * scale, entity_id
|
||||
|
||||
def _snapshot_energy_meter_start(self) -> None:
|
||||
"""Capture the meter reading at cycle start (issue #316)."""
|
||||
snap = self._read_energy_meter()
|
||||
if snap is None:
|
||||
self._energy_meter_start = None
|
||||
self._energy_meter_source = None
|
||||
else:
|
||||
self._energy_meter_start, self._energy_meter_source = snap
|
||||
|
||||
def _compute_meter_energy_wh(self) -> float | None:
|
||||
"""Cycle energy from the external meter's start->end delta, or None.
|
||||
|
||||
Falls back (returns ``None``) when: no start was captured; no meter is
|
||||
configured now; the configured entity differs from the one snapshotted at
|
||||
start (source changed mid-cycle -- no cross-meter delta); the current
|
||||
reading is unusable; or the delta is <= 0 (counter reset or stuck plug).
|
||||
"""
|
||||
start = self._energy_meter_start
|
||||
source = self._energy_meter_source
|
||||
if start is None or source is None:
|
||||
return None
|
||||
cur = self._read_energy_meter()
|
||||
if cur is None:
|
||||
return None
|
||||
cur_wh, cur_source = cur
|
||||
if cur_source != source:
|
||||
return None
|
||||
delta = cur_wh - start
|
||||
if delta <= 0:
|
||||
return None
|
||||
return delta
|
||||
|
||||
@staticmethod
|
||||
def _cycle_report_energy_wh(cycle_data: dict[str, Any]) -> float:
|
||||
"""User-facing reported energy (Wh): meter value if present, else integrated.
|
||||
|
||||
The integrated ``energy_wh`` is always stored and used internally (matching,
|
||||
ML, anomaly, envelopes); only cost/lifetime/notifications/panel display
|
||||
prefer the more accurate meter figure when one was captured (issue #316).
|
||||
"""
|
||||
meter = cycle_data.get("energy_meter_wh")
|
||||
if meter is not None:
|
||||
try:
|
||||
return float(meter)
|
||||
except (ValueError, TypeError):
|
||||
pass
|
||||
try:
|
||||
return float(cycle_data.get("energy_wh", 0.0))
|
||||
except (ValueError, TypeError):
|
||||
return 0.0
|
||||
|
||||
def _augment_active_snapshot(self, snapshot: dict[str, Any]) -> dict[str, Any]:
|
||||
"""Add manager-owned fields to a detector snapshot before persisting.
|
||||
|
||||
The detector snapshot only carries detector state; these fields are owned
|
||||
by the manager and must survive a restart alongside it. Kept in one place
|
||||
so every save site (shutdown, periodic, pause, resume) stays consistent.
|
||||
"""
|
||||
snapshot["manual_program"] = self._manual_program_active
|
||||
snapshot["notified_start"] = self._notified_start
|
||||
snapshot["start_event_fired"] = self._start_event_fired
|
||||
snapshot["is_user_paused"] = self._is_user_paused
|
||||
snapshot["user_pause_start"] = (
|
||||
self._user_pause_start.isoformat() if self._user_pause_start else None
|
||||
)
|
||||
snapshot["total_user_paused_seconds"] = self._total_user_paused_seconds
|
||||
snapshot["energy_meter_start"] = self._energy_meter_start
|
||||
snapshot["energy_meter_source"] = self._energy_meter_source
|
||||
return snapshot
|
||||
|
||||
@staticmethod
|
||||
def _format_vs_typical(
|
||||
duration: float,
|
||||
@@ -4145,7 +4248,9 @@ class WashDataManager:
|
||||
price = self._resolve_energy_price()
|
||||
if price is not None:
|
||||
cycle_data["energy_price"] = price
|
||||
cycle_data["cost"] = round(cycle_data.get("energy_wh", 0.0) / 1000.0 * price, 4)
|
||||
cycle_data["cost"] = round(
|
||||
self._cycle_report_energy_wh(cycle_data) / 1000.0 * price, 4
|
||||
)
|
||||
|
||||
# Score cycle quality with the ML model before persisting so the score is
|
||||
# stored on the cycle record and available to the learning manager immediately.
|
||||
@@ -4209,7 +4314,7 @@ class WashDataManager:
|
||||
if cycle_persisted:
|
||||
try:
|
||||
await self.profile_store.async_add_lifetime_energy_wh(
|
||||
cycle_data.get("energy_wh", 0.0)
|
||||
self._cycle_report_energy_wh(cycle_data)
|
||||
)
|
||||
except Exception as e: # pylint: disable=broad-exception-caught
|
||||
self._logger.debug("Failed to accumulate lifetime energy: %s", e)
|
||||
@@ -4269,7 +4374,7 @@ class WashDataManager:
|
||||
duration_min = int(cycle_data['duration'] / 60)
|
||||
program_name = event_cycle_data.get("profile_name", "unknown")
|
||||
|
||||
energy_kwh = round(cycle_data.get("energy_wh", 0.0) / 1000, 3)
|
||||
energy_kwh = round(self._cycle_report_energy_wh(cycle_data) / 1000, 3)
|
||||
|
||||
# Reuse the cost frozen onto the cycle above (same price resolution).
|
||||
cost_val = cycle_data.get("cost")
|
||||
@@ -5252,6 +5357,10 @@ class WashDataManager:
|
||||
# the waiting message again.
|
||||
self._live_waiting_notification_sent = False
|
||||
if not has_profile_match:
|
||||
# Suppress the waiting notification when no profiles exist at all —
|
||||
# the setup card explains the state instead.
|
||||
if not self.profile_store.has_real_profiles:
|
||||
return
|
||||
if self._live_waiting_notification_sent:
|
||||
return
|
||||
|
||||
@@ -5650,6 +5759,24 @@ class WashDataManager:
|
||||
trace, duration_so_far, self._current_program
|
||||
)
|
||||
ml_pct = self._ml_progress_percent(trace, self._current_program)
|
||||
|
||||
# Opt-in phase-resolved ETA (washing machine / washer-dryer only). Segment
|
||||
# the observed-so-far trace, match against cached per-profile phase profiles,
|
||||
# and blend the per-role budget remaining into the estimate (progress.py
|
||||
# owns the blend). Gated + guarded: any failure leaves the proven estimate
|
||||
# untouched (phase_remaining_s stays None -> byte-identical behaviour).
|
||||
phase_remaining_s: float | None = None
|
||||
if (
|
||||
len(trace) >= 10
|
||||
and self._current_program not in ("detecting...", "off", None)
|
||||
and phase_matching_enabled(self.config_entry.options, self.device_type)
|
||||
):
|
||||
pr = self.profile_store.phase_remaining(
|
||||
trace, self.device_type, self._current_program
|
||||
)
|
||||
if pr is not None:
|
||||
phase_remaining_s = pr.get("remaining_s")
|
||||
|
||||
result = progress_mod.compute_progress(
|
||||
self.device_type,
|
||||
float(self._matched_profile_duration),
|
||||
@@ -5658,6 +5785,7 @@ class WashDataManager:
|
||||
phase_result,
|
||||
ml_pct,
|
||||
self._logger,
|
||||
phase_remaining_s=phase_remaining_s,
|
||||
)
|
||||
|
||||
self._cycle_progress = result.progress
|
||||
@@ -6135,15 +6263,7 @@ class WashDataManager:
|
||||
self.detector.set_verified_pause(prev_verified)
|
||||
return False
|
||||
|
||||
snapshot = self.detector.get_state_snapshot()
|
||||
snapshot["manual_program"] = self._manual_program_active
|
||||
snapshot["notified_start"] = self._notified_start
|
||||
snapshot["start_event_fired"] = self._start_event_fired
|
||||
snapshot["is_user_paused"] = self._is_user_paused
|
||||
snapshot["user_pause_start"] = (
|
||||
self._user_pause_start.isoformat() if self._user_pause_start else None
|
||||
)
|
||||
snapshot["total_user_paused_seconds"] = self._total_user_paused_seconds
|
||||
snapshot = self._augment_active_snapshot(self.detector.get_state_snapshot())
|
||||
self.hass.async_create_task(self.profile_store.async_save_active_cycle(snapshot))
|
||||
self._notify_update()
|
||||
return True
|
||||
@@ -6203,15 +6323,7 @@ class WashDataManager:
|
||||
# early with the card still up, matching the real (still-paused) state.
|
||||
self._clear_timer_pause_notification()
|
||||
|
||||
snapshot = self.detector.get_state_snapshot()
|
||||
snapshot["manual_program"] = self._manual_program_active
|
||||
snapshot["notified_start"] = self._notified_start
|
||||
snapshot["start_event_fired"] = self._start_event_fired
|
||||
snapshot["is_user_paused"] = self._is_user_paused
|
||||
snapshot["user_pause_start"] = (
|
||||
self._user_pause_start.isoformat() if self._user_pause_start else None
|
||||
)
|
||||
snapshot["total_user_paused_seconds"] = self._total_user_paused_seconds
|
||||
snapshot = self._augment_active_snapshot(self.detector.get_state_snapshot())
|
||||
self.hass.async_create_task(self.profile_store.async_save_active_cycle(snapshot))
|
||||
self._notify_update()
|
||||
return True
|
||||
|
||||
@@ -21,5 +21,5 @@
|
||||
"requirements": [
|
||||
"numpy"
|
||||
],
|
||||
"version": "0.5.0"
|
||||
"version": "0.5.1"
|
||||
}
|
||||
@@ -43,6 +43,8 @@ MODEL_NAME = 'cycle_end_detector'
|
||||
MODEL_TARGET = 'cycle_truly_ended'
|
||||
MODEL_KIND = 'standardized_logistic'
|
||||
TARGET_UNITS = ''
|
||||
# Training artifact for select_threshold only — NOT used at live inference.
|
||||
# The live defer-finish gate reads DEFAULT_DEFER_FINISH_CONFIDENCE from const.py.
|
||||
THRESHOLD = 0.6
|
||||
|
||||
FEATURE_COLUMNS = [
|
||||
|
||||
@@ -43,6 +43,8 @@ MODEL_NAME = 'hybrid_curve_quality'
|
||||
MODEL_TARGET = 'problem_cycle'
|
||||
MODEL_KIND = 'standardized_logistic'
|
||||
TARGET_UNITS = ''
|
||||
# Training artifact for select_threshold only — NOT used at live inference.
|
||||
# The live quality-suspicious gate reads ML_QUALITY_SUSPICIOUS_THRESHOLD from const.py.
|
||||
THRESHOLD = 0.19
|
||||
|
||||
FEATURE_COLUMNS = [
|
||||
|
||||
@@ -43,6 +43,8 @@ MODEL_NAME = 'live_match_commit'
|
||||
MODEL_TARGET = 'match_top1_correct'
|
||||
MODEL_KIND = 'standardized_logistic'
|
||||
TARGET_UNITS = ''
|
||||
# Training artifact for select_threshold only — NOT used at live inference.
|
||||
# The live early-commit gate reads ML_MATCH_COMMIT_THRESHOLD from const.py.
|
||||
THRESHOLD = 0.371786
|
||||
|
||||
FEATURE_COLUMNS = [
|
||||
|
||||
@@ -0,0 +1,320 @@
|
||||
# WashData - Home Assistant integration for appliance cycle monitoring via smart plugs.
|
||||
# Copyright (C) 2026 Lukas Bandura
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""Phase-aware profile matching and phase-resolved ETA (Phase 0 prototype).
|
||||
|
||||
Given a cycle segmented into phases (:mod:`phase_segmenter`), this module:
|
||||
|
||||
* builds a per-profile :class:`PhaseProfile` (per-role duration/energy priors)
|
||||
from the profile's member cycles;
|
||||
* scores candidate profiles by **per-role** duration + energy agreement, so two
|
||||
profiles that differ mainly in heating length (i.e. temperature) are separated
|
||||
by a large per-phase signal instead of a small whole-cycle-correlation delta;
|
||||
* projects **time-remaining** as a per-role budget (Σ expected_role_total −
|
||||
consumed_role), which personalises the ETA to the matched variant.
|
||||
|
||||
The matcher handles **partial** (observed-so-far) cycles for progressive
|
||||
narrowing: completed roles are compared fully; the open current role is scored
|
||||
one-sided (a candidate is only penalised if the observed duration already
|
||||
*exceeds* its expected total), so the correct larger-heating variant is not
|
||||
prematurely ruled out while heating is still in progress.
|
||||
|
||||
Constraint: NumPy only, no Home Assistant imports. Pure and executor-safe;
|
||||
consumed live (behind the default-off ``enable_phase_matching`` per-device gate)
|
||||
by ``ProfileStore.phase_remaining`` and the progress blend. See
|
||||
`docs/superpowers/specs/2026-07-17-phase-segmented-matching-design.md`.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import math
|
||||
from dataclasses import asdict, dataclass
|
||||
|
||||
from .phase_segmenter import (
|
||||
ROLE_HEATING,
|
||||
ROLE_IDLE,
|
||||
ROLE_SPIN,
|
||||
ROLE_WASH,
|
||||
PhaseSegment,
|
||||
)
|
||||
|
||||
# Per-role weight in the match score. Heating dominates because it is the
|
||||
# temperature discriminator; the wash middle is load-variable; spin/idle are
|
||||
# weak/noisy signals. Overridable via the match config.
|
||||
_ROLE_WEIGHTS: dict[str, float] = {
|
||||
ROLE_HEATING: 0.50,
|
||||
ROLE_WASH: 0.25,
|
||||
ROLE_SPIN: 0.15,
|
||||
ROLE_IDLE: 0.10,
|
||||
}
|
||||
_DUR_SCALE = 0.35 # log-ratio agreement scale for per-role duration
|
||||
_EN_SCALE = 0.40 # ... and per-role energy
|
||||
# Agreement score credited when a role is present on one side but absent on the
|
||||
# other (structural mismatch, e.g. a heating vs no-heating cycle). 0.0 = full
|
||||
# penalty (structural difference is a strong, wanted discriminator); raise toward
|
||||
# 1.0 to soften. Config-overridable via ``occ_penalty``.
|
||||
_OCC_PENALTY = 0.0
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class RoleStat:
|
||||
"""Aggregated per-role prior across a profile's member cycles."""
|
||||
|
||||
dur_mean: float
|
||||
dur_std: float
|
||||
dur_p50: float
|
||||
en_mean: float
|
||||
occurrence: float # fraction of member cycles that contain this role
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class PhaseProfile:
|
||||
"""Per-profile phase model: per-role priors + total-duration prior."""
|
||||
|
||||
name: str
|
||||
roles: dict[str, RoleStat]
|
||||
total_dur_mean: float
|
||||
total_dur_std: float
|
||||
n_cycles: int
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class PhaseMatchResult:
|
||||
name: str
|
||||
score: float
|
||||
|
||||
|
||||
def phase_profile_to_dict(profile: PhaseProfile) -> dict:
|
||||
"""Serialize a :class:`PhaseProfile` for storage (JSON-safe)."""
|
||||
return {
|
||||
"name": profile.name,
|
||||
"n_cycles": profile.n_cycles,
|
||||
"total_dur_mean": profile.total_dur_mean,
|
||||
"total_dur_std": profile.total_dur_std,
|
||||
"roles": {role: asdict(stat) for role, stat in profile.roles.items()},
|
||||
}
|
||||
|
||||
|
||||
def phase_profile_from_dict(data: dict | None) -> PhaseProfile | None:
|
||||
"""Rebuild a :class:`PhaseProfile` from stored form. Never raises."""
|
||||
if not isinstance(data, dict):
|
||||
return None
|
||||
try:
|
||||
roles = {
|
||||
str(role): RoleStat(
|
||||
dur_mean=float(s.get("dur_mean", 0.0)),
|
||||
dur_std=float(s.get("dur_std", 0.0)),
|
||||
dur_p50=float(s.get("dur_p50", 0.0)),
|
||||
en_mean=float(s.get("en_mean", 0.0)),
|
||||
occurrence=float(s.get("occurrence", 0.0)),
|
||||
)
|
||||
for role, s in (data.get("roles") or {}).items()
|
||||
if isinstance(s, dict)
|
||||
}
|
||||
if not roles:
|
||||
return None
|
||||
return PhaseProfile(
|
||||
name=str(data.get("name", "")),
|
||||
roles=roles,
|
||||
total_dur_mean=float(data.get("total_dur_mean", 0.0)),
|
||||
total_dur_std=float(data.get("total_dur_std", 0.0)),
|
||||
n_cycles=int(data.get("n_cycles", 0)),
|
||||
)
|
||||
except (TypeError, ValueError, AttributeError):
|
||||
return None
|
||||
|
||||
|
||||
def _agree(observed: float, expected: float, scale: float) -> float:
|
||||
"""Log-ratio agreement in (0, 1]; 1.0 when equal, sharper for small scale."""
|
||||
if observed <= 0.0 or expected <= 0.0:
|
||||
# Both ~zero → perfect agreement; one zero → no agreement.
|
||||
return 1.0 if observed <= 0.0 and expected <= 0.0 else 0.0
|
||||
scale = scale if scale > 1e-9 else 1e-9 # avoid div-by-zero on a 0 config scale
|
||||
return 1.0 / (1.0 + abs(math.log(observed / expected)) / scale)
|
||||
|
||||
|
||||
def _role_totals(segments: list[PhaseSegment]) -> dict[str, dict[str, float]]:
|
||||
"""Sum duration + energy per role across a cycle's segments."""
|
||||
totals: dict[str, dict[str, float]] = {}
|
||||
for seg in segments:
|
||||
acc = totals.setdefault(seg.role, {"dur": 0.0, "en": 0.0})
|
||||
acc["dur"] += max(0.0, seg.duration_s)
|
||||
acc["en"] += max(0.0, seg.energy_wh)
|
||||
return totals
|
||||
|
||||
|
||||
def build_phase_profile(name: str, segmented_cycles: list[list[PhaseSegment]]) -> PhaseProfile | None:
|
||||
"""Aggregate a profile's member cycles into per-role priors. Never raises.
|
||||
|
||||
Returns ``None`` when no usable cycles are supplied.
|
||||
"""
|
||||
cycles = [c for c in segmented_cycles if c]
|
||||
if not cycles:
|
||||
return None
|
||||
n = len(cycles)
|
||||
per_role_durs: dict[str, list[float]] = {}
|
||||
per_role_ens: dict[str, list[float]] = {}
|
||||
role_count: dict[str, int] = {}
|
||||
totals_dur: list[float] = []
|
||||
for segs in cycles:
|
||||
totals = _role_totals(segs)
|
||||
totals_dur.append(sum(v["dur"] for v in totals.values()))
|
||||
for role, v in totals.items():
|
||||
per_role_durs.setdefault(role, []).append(v["dur"])
|
||||
per_role_ens.setdefault(role, []).append(v["en"])
|
||||
role_count[role] = role_count.get(role, 0) + 1
|
||||
|
||||
def _mean(xs: list[float]) -> float:
|
||||
return float(sum(xs) / len(xs)) if xs else 0.0
|
||||
|
||||
def _std(xs: list[float], m: float) -> float:
|
||||
return float((sum((x - m) ** 2 for x in xs) / len(xs)) ** 0.5) if xs else 0.0
|
||||
|
||||
def _p50(xs: list[float]) -> float:
|
||||
if not xs:
|
||||
return 0.0
|
||||
s = sorted(xs)
|
||||
mid = len(s) // 2
|
||||
return float(s[mid] if len(s) % 2 else (s[mid - 1] + s[mid]) / 2.0)
|
||||
|
||||
roles: dict[str, RoleStat] = {}
|
||||
for role, durs in per_role_durs.items():
|
||||
m = _mean(durs)
|
||||
roles[role] = RoleStat(
|
||||
dur_mean=m, dur_std=_std(durs, m), dur_p50=_p50(durs),
|
||||
en_mean=_mean(per_role_ens[role]),
|
||||
occurrence=role_count[role] / n,
|
||||
)
|
||||
tm = _mean(totals_dur)
|
||||
return PhaseProfile(
|
||||
name=name, roles=roles,
|
||||
total_dur_mean=tm, total_dur_std=_std(totals_dur, tm), n_cycles=n,
|
||||
)
|
||||
|
||||
|
||||
def match_phase_profiles(
|
||||
observed: list[PhaseSegment],
|
||||
candidates: list[PhaseProfile],
|
||||
config: dict | None = None,
|
||||
) -> list[PhaseMatchResult]:
|
||||
"""Rank ``candidates`` for the ``observed`` (full or partial) cycle. Never raises.
|
||||
|
||||
Score = weighted mean over roles of ``sqrt(dur_agree * energy_agree)``, with a
|
||||
structural (occurrence-mismatch) penalty. The observed cycle's *open* role
|
||||
(partial cycle) is scored one-sided so a larger-heating candidate is not
|
||||
ruled out mid-heating.
|
||||
"""
|
||||
if not observed or not candidates:
|
||||
return []
|
||||
cfg = config or {}
|
||||
weights = {**_ROLE_WEIGHTS, **(cfg.get("role_weights") or {})}
|
||||
dur_scale = float(cfg.get("dur_scale", _DUR_SCALE))
|
||||
en_scale = float(cfg.get("en_scale", _EN_SCALE))
|
||||
occ_pen = float(cfg.get("occ_penalty", _OCC_PENALTY))
|
||||
|
||||
totals = _role_totals(observed)
|
||||
open_role = next((s.role for s in observed if s.open), None)
|
||||
is_partial = open_role is not None
|
||||
|
||||
results: list[PhaseMatchResult] = []
|
||||
for cand in candidates:
|
||||
all_roles = set(totals) | set(cand.roles)
|
||||
num = 0.0
|
||||
den = 0.0
|
||||
for role in all_roles:
|
||||
w = weights.get(role, 0.1)
|
||||
if w <= 0:
|
||||
continue
|
||||
obs = totals.get(role, {"dur": 0.0, "en": 0.0})
|
||||
stat = cand.roles.get(role)
|
||||
if stat is None:
|
||||
# Observed a role the candidate never exhibits: structural miss.
|
||||
if obs["dur"] > 0:
|
||||
num += w * occ_pen
|
||||
den += w
|
||||
continue
|
||||
if role not in totals:
|
||||
# Candidate expects a role not yet observed. Future phase on a
|
||||
# partial cycle → neutral (skip). On a completed cycle →
|
||||
# structural miss (candidate does a phase this cycle never had).
|
||||
if not is_partial:
|
||||
num += w * occ_pen
|
||||
den += w
|
||||
continue
|
||||
if role == open_role:
|
||||
# One-sided: only penalise if the in-progress duration/energy
|
||||
# already EXCEEDS what this candidate expects for the whole role
|
||||
# (a larger-budget candidate must not be ruled out mid-phase).
|
||||
# Energy is the cleanest temperature discriminator, so score it
|
||||
# one-sided too rather than dropping it (weaker narrowing).
|
||||
da = 1.0 if obs["dur"] <= stat.dur_mean else _agree(obs["dur"], stat.dur_mean, dur_scale)
|
||||
ea = 1.0 if obs["en"] <= stat.en_mean else _agree(obs["en"], stat.en_mean, en_scale)
|
||||
agree = math.sqrt(da * ea)
|
||||
else:
|
||||
da = _agree(obs["dur"], stat.dur_mean, dur_scale)
|
||||
ea = _agree(obs["en"], stat.en_mean, en_scale)
|
||||
agree = math.sqrt(da * ea)
|
||||
num += w * agree
|
||||
den += w
|
||||
score = (num / den) if den > 0 else 0.0
|
||||
results.append(PhaseMatchResult(name=cand.name, score=float(score)))
|
||||
|
||||
results.sort(key=lambda r: r.score, reverse=True)
|
||||
return results
|
||||
|
||||
|
||||
def phase_eta(
|
||||
observed: list[PhaseSegment],
|
||||
profile: PhaseProfile,
|
||||
) -> float | None:
|
||||
"""Project remaining seconds as a per-role budget. Never raises.
|
||||
|
||||
Classifies each profile role against the observed-so-far segments (design §8):
|
||||
|
||||
* **current** (the open, in-progress role): contribute
|
||||
``max(0, dur_mean − consumed)`` using the CONDITIONAL mean (the role is
|
||||
known present, so no occurrence discount);
|
||||
* **completed** (a role already observed but not the open one): contribute
|
||||
**0** — it is done, even if it ran shorter than the profile mean (fixing
|
||||
the "phantom remaining" over-count);
|
||||
* **future** (a profile role not yet observed): contribute the
|
||||
occurrence-weighted prior ``dur_mean × occurrence`` (we do not yet know
|
||||
whether it will occur).
|
||||
|
||||
Returns ``None`` when no phase priors are available (caller falls back to the
|
||||
current estimator).
|
||||
"""
|
||||
if profile is None or not profile.roles:
|
||||
return None
|
||||
consumed = _role_totals(observed) if observed else {}
|
||||
# The open (in-progress) role. If the caller did not mark one (e.g. a
|
||||
# completed trace), treat the last observed role as current so completed
|
||||
# roles still contribute 0 rather than a spurious prior.
|
||||
open_role = next((s.role for s in (observed or []) if s.open), None)
|
||||
if open_role is None and observed:
|
||||
open_role = observed[-1].role
|
||||
remaining = 0.0
|
||||
for role, stat in profile.roles.items():
|
||||
done = consumed.get(role, {}).get("dur", 0.0)
|
||||
if role == open_role:
|
||||
# current: conditional mean (occurrence -> 1, role is present)
|
||||
remaining += max(0.0, stat.dur_mean - done)
|
||||
elif role in consumed:
|
||||
# completed: nothing more to spend on it
|
||||
continue
|
||||
else:
|
||||
# future: unconditional prior (may or may not occur)
|
||||
remaining += stat.dur_mean * max(0.0, min(1.0, stat.occurrence))
|
||||
return float(max(0.0, remaining))
|
||||
@@ -0,0 +1,312 @@
|
||||
# WashData - Home Assistant integration for appliance cycle monitoring via smart plugs.
|
||||
# Copyright (C) 2026 Lukas Bandura
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""Unsupervised power-trace phase segmentation (Phase 0 prototype).
|
||||
|
||||
Turns a cycle's power trace into an ordered list of :class:`PhaseSegment`
|
||||
(role, start/end offset, duration, energy, mean/peak power) via a hysteresis
|
||||
regime classifier (idle / active / high) + minimum-run merge + role assignment
|
||||
driven by a per-device-type :class:`PhaseModel`.
|
||||
|
||||
Constraint: NumPy only, no Home Assistant imports. Pure and executor-safe;
|
||||
``segment_cycle`` never raises - it returns ``[]`` on malformed input.
|
||||
|
||||
Consumed live (behind the default-off ``enable_phase_matching`` per-device gate)
|
||||
by `profile_store.ProfileStore` (phase-profile cache + `phase_remaining`) and,
|
||||
offline, by the side-by-side harness (`devtools/eta_phase_eval.py`). See
|
||||
`docs/superpowers/specs/2026-07-17-phase-segmented-matching-design.md`.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass, field
|
||||
from typing import Mapping, Optional
|
||||
|
||||
import numpy as np
|
||||
|
||||
from .const import CONF_ENABLE_PHASE_MATCHING
|
||||
from .signal_processing import energy_gap_threshold_s, integrate_wh
|
||||
|
||||
# Regime tokens (internal, not user-facing).
|
||||
_IDLE = 0
|
||||
_ACTIVE = 1
|
||||
_HIGH = 2
|
||||
|
||||
# Role tokens. Physically detectable roles; mapping to display phase names
|
||||
# (phase_catalog.DEFAULT_PHASES_BY_DEVICE) is a later (Phase 6) concern.
|
||||
ROLE_HEATING = "heating"
|
||||
ROLE_WASH = "wash"
|
||||
ROLE_SPIN = "spin"
|
||||
ROLE_IDLE = "idle"
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class PhaseSegment:
|
||||
"""One contiguous phase of a cycle."""
|
||||
|
||||
role: str
|
||||
t_start: float # seconds from cycle start
|
||||
t_end: float
|
||||
duration_s: float
|
||||
energy_wh: float
|
||||
mean_w: float
|
||||
peak_w: float
|
||||
open: bool = False # True when this is the final segment of a partial cycle
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class PhaseModel:
|
||||
"""Per-device-type segmentation parameters and role vocabulary.
|
||||
|
||||
``high`` threshold = ``max(high_w_floor, high_frac * robust_peak)`` where the
|
||||
robust peak is the 95th percentile of the trace, so a heating element is
|
||||
detected relative to the device's own scale without a single spike inflating
|
||||
it. ``active_w`` separates motor/fill activity from idle. A terminal
|
||||
``active`` block whose mean power >= ``spin_min_w`` and which begins in the
|
||||
last ``spin_tail_frac`` of the (completed) cycle is labelled ``spin``.
|
||||
"""
|
||||
|
||||
device_type: str
|
||||
high_w_floor: float
|
||||
high_frac: float
|
||||
active_w: float
|
||||
spin_min_w: float
|
||||
spin_tail_frac: float
|
||||
min_run_s: float
|
||||
roles: tuple[str, ...] = field(default=(ROLE_HEATING, ROLE_WASH, ROLE_SPIN, ROLE_IDLE))
|
||||
|
||||
|
||||
# Only washing_machine is intended for live rollout first; dishwasher and
|
||||
# washer-dryer models exist for OFFLINE evaluation in the Phase-0 harness.
|
||||
_MODELS: dict[str, PhaseModel] = {
|
||||
"washing_machine": PhaseModel(
|
||||
device_type="washing_machine",
|
||||
high_w_floor=800.0, high_frac=0.5,
|
||||
active_w=30.0, spin_min_w=200.0, spin_tail_frac=0.30,
|
||||
min_run_s=90.0,
|
||||
),
|
||||
"washer_dryer": PhaseModel(
|
||||
device_type="washer_dryer",
|
||||
high_w_floor=800.0, high_frac=0.5,
|
||||
active_w=30.0, spin_min_w=200.0, spin_tail_frac=0.30,
|
||||
min_run_s=90.0,
|
||||
),
|
||||
# Dishwasher: heating element is the dominant HIGH regime; the long passive
|
||||
# dry tail lands in IDLE. Deferred for LIVE rollout (delicate end-of-cycle
|
||||
# logic) - present here only for offline measurement.
|
||||
"dishwasher": PhaseModel(
|
||||
device_type="dishwasher",
|
||||
high_w_floor=800.0, high_frac=0.5,
|
||||
active_w=25.0, spin_min_w=250.0, spin_tail_frac=0.25,
|
||||
min_run_s=120.0,
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
# Device types phase matching is rolled out for LIVE (validated by the Phase-0
|
||||
# ETA gate). Dishwasher has a model for OFFLINE evaluation only (its ETA gate was
|
||||
# a no-go and its end-of-cycle logic is delicate), so it is deliberately excluded
|
||||
# here even though ``phase_model_for("dishwasher")`` returns a model.
|
||||
LIVE_PHASE_DEVICE_TYPES: tuple[str, ...] = ("washing_machine", "washer_dryer")
|
||||
|
||||
|
||||
def phase_model_for(device_type: str | None) -> PhaseModel | None:
|
||||
"""Return the :class:`PhaseModel` for a device type, or ``None`` to fall back.
|
||||
|
||||
``None`` means the device type has no validated phase model and must use the
|
||||
existing whole-cycle pipeline (zero-regression fallback). Returns a model for
|
||||
every type with one defined (incl. dishwasher, for the offline harness).
|
||||
"""
|
||||
if not device_type:
|
||||
return None
|
||||
return _MODELS.get(str(device_type))
|
||||
|
||||
|
||||
def phase_matching_live_supported(device_type: str | None) -> bool:
|
||||
"""True when phase matching is enabled for LIVE use on this device type.
|
||||
|
||||
Stricter than ``phase_model_for`` - only the Phase-0-validated rollout types
|
||||
(washing machine, washer-dryer). Used to gate phase-profile caching and the
|
||||
live ETA path; the offline harness uses ``phase_model_for`` directly.
|
||||
"""
|
||||
return (
|
||||
device_type in LIVE_PHASE_DEVICE_TYPES
|
||||
and phase_model_for(device_type) is not None
|
||||
)
|
||||
|
||||
|
||||
def phase_matching_enabled(options: "Mapping[str, object] | None", device_type: str | None) -> bool:
|
||||
"""True when the user opted in AND the device type is live-supported.
|
||||
|
||||
The opt-in gate for the live phase-resolved ETA blend, mirroring
|
||||
``ml.engine.ml_models_enabled``. Both conditions are required: the per-device
|
||||
``enable_phase_matching`` option and a validated live phase model.
|
||||
"""
|
||||
if not options:
|
||||
return False
|
||||
if not bool(options.get(CONF_ENABLE_PHASE_MATCHING, False)):
|
||||
return False
|
||||
return phase_matching_live_supported(device_type)
|
||||
|
||||
|
||||
def _classify(power: np.ndarray, model: PhaseModel) -> tuple[np.ndarray, float]:
|
||||
"""Per-sample regime tokens + the robust peak used for the HIGH threshold."""
|
||||
robust_peak = float(np.percentile(power, 95)) if power.size else 0.0
|
||||
high_thr = max(model.high_w_floor, model.high_frac * robust_peak)
|
||||
reg = np.full(power.shape, _IDLE, dtype=int)
|
||||
reg[power >= model.active_w] = _ACTIVE
|
||||
reg[power >= high_thr] = _HIGH
|
||||
return reg, robust_peak
|
||||
|
||||
|
||||
def _runs(reg: np.ndarray) -> list[list[int]]:
|
||||
"""Contiguous same-regime runs as ``[regime, start_idx, end_idx]`` (inclusive)."""
|
||||
runs: list[list[int]] = []
|
||||
n = len(reg)
|
||||
i = 0
|
||||
while i < n:
|
||||
j = i
|
||||
while j + 1 < n and reg[j + 1] == reg[i]:
|
||||
j += 1
|
||||
runs.append([int(reg[i]), i, j])
|
||||
i = j + 1
|
||||
return runs
|
||||
|
||||
|
||||
def _merge_short(runs: list[list[int]], t: np.ndarray, min_run_s: float) -> list[list[int]]:
|
||||
"""Absorb runs shorter than ``min_run_s`` into their neighbour.
|
||||
|
||||
A short leading run merges forward; every other short run merges into the
|
||||
preceding (already-accepted) run. This prevents brief motor spikes during
|
||||
tumbling from fragmenting a wash phase, and brief dips from splitting a
|
||||
heating block, without erasing genuine phases.
|
||||
"""
|
||||
if not runs:
|
||||
return runs
|
||||
merged: list[list[int]] = []
|
||||
for reg, a, b in runs:
|
||||
dur = float(t[b] - t[a])
|
||||
if merged and dur < min_run_s:
|
||||
merged[-1][2] = b # extend previous run to absorb this short one
|
||||
else:
|
||||
merged.append([reg, a, b])
|
||||
# A short LEADING run has no preceding run to absorb it, so it would survive
|
||||
# as its own segment (e.g. a startup/inrush HIGH spike becoming a phantom
|
||||
# heating block that pollutes the temperature prior). Fold it FORWARD into
|
||||
# the following run, adopting that run's regime.
|
||||
while len(merged) > 1 and float(t[merged[0][2]] - t[merged[0][1]]) < min_run_s:
|
||||
merged[1][1] = merged[0][1] # extend 2nd run's start back over the lead
|
||||
merged.pop(0)
|
||||
return merged
|
||||
|
||||
|
||||
def segment_cycle(
|
||||
timestamps: "np.ndarray | list[float]",
|
||||
power: "np.ndarray | list[float]",
|
||||
model: PhaseModel,
|
||||
*,
|
||||
partial: bool = False,
|
||||
) -> list[PhaseSegment]:
|
||||
"""Segment a power trace into ordered phases. Never raises.
|
||||
|
||||
Args:
|
||||
timestamps: seconds from cycle start (ascending).
|
||||
power: watts, same length as ``timestamps``.
|
||||
model: the device-type :class:`PhaseModel`.
|
||||
partial: when True the trace is an observed-so-far prefix of a running
|
||||
cycle; the final segment is marked ``open=True``.
|
||||
|
||||
Returns:
|
||||
List of :class:`PhaseSegment` in time order, or ``[]`` when the input is
|
||||
too short/degenerate to segment. Any internal error also yields ``[]``.
|
||||
"""
|
||||
try:
|
||||
return _segment_impl(timestamps, power, model, partial=partial)
|
||||
except Exception: # noqa: BLE001 - segmentation must never break a live cycle
|
||||
return []
|
||||
|
||||
|
||||
def _segment_impl(
|
||||
timestamps: "np.ndarray | list[float]",
|
||||
power: "np.ndarray | list[float]",
|
||||
model: PhaseModel,
|
||||
*,
|
||||
partial: bool = False,
|
||||
) -> list[PhaseSegment]:
|
||||
t = np.asarray(timestamps, dtype=float)
|
||||
w = np.asarray(power, dtype=float)
|
||||
if t.size < 4 or w.size != t.size:
|
||||
return []
|
||||
if not (np.all(np.isfinite(t)) and np.all(np.isfinite(w))):
|
||||
finite = np.isfinite(t) & np.isfinite(w)
|
||||
t, w = t[finite], w[finite]
|
||||
if t.size < 4:
|
||||
return []
|
||||
# Enforce ascending time.
|
||||
order = np.argsort(t, kind="stable")
|
||||
t, w = t[order], w[order]
|
||||
|
||||
reg, _peak = _classify(w, model)
|
||||
runs = _merge_short(_runs(reg), t, model.min_run_s)
|
||||
if not runs:
|
||||
return []
|
||||
|
||||
gap_s = energy_gap_threshold_s(t)
|
||||
total = float(t[-1] - t[0])
|
||||
spin_zone_start = t[0] + (1.0 - model.spin_tail_frac) * total if total > 0 else t[-1]
|
||||
|
||||
# First pass: build raw segments with stats.
|
||||
raw: list[dict] = []
|
||||
for reg_tok, a, b in runs:
|
||||
seg_t = t[a:b + 1]
|
||||
seg_w = w[a:b + 1]
|
||||
dur = float(seg_t[-1] - seg_t[0]) if seg_t.size > 1 else 0.0
|
||||
energy = integrate_wh(seg_t, seg_w, max_gap_s=gap_s) if seg_t.size > 1 else 0.0
|
||||
raw.append({
|
||||
"reg": reg_tok, "a": a, "b": b,
|
||||
"t0": float(seg_t[0]), "t1": float(seg_t[-1]),
|
||||
"dur": dur, "energy": float(energy),
|
||||
"mean": float(np.mean(seg_w)), "peak": float(np.max(seg_w)),
|
||||
})
|
||||
|
||||
# Determine which ACTIVE run (if any) is the spin: the last non-idle run,
|
||||
# elevated and starting in the terminal zone. Only on a completed cycle -
|
||||
# a partial cycle can't know its terminal segment yet.
|
||||
spin_idx: Optional[int] = None
|
||||
if not partial:
|
||||
for idx in range(len(raw) - 1, -1, -1):
|
||||
seg = raw[idx]
|
||||
if seg["reg"] == _IDLE:
|
||||
continue
|
||||
if (seg["reg"] == _ACTIVE and seg["mean"] >= model.spin_min_w
|
||||
and seg["t0"] >= spin_zone_start):
|
||||
spin_idx = idx
|
||||
break # only inspect the last non-idle run
|
||||
|
||||
out: list[PhaseSegment] = []
|
||||
for idx, seg in enumerate(raw):
|
||||
if seg["reg"] == _HIGH:
|
||||
role = ROLE_HEATING
|
||||
elif seg["reg"] == _IDLE:
|
||||
role = ROLE_IDLE
|
||||
else: # _ACTIVE
|
||||
role = ROLE_SPIN if idx == spin_idx else ROLE_WASH
|
||||
out.append(PhaseSegment(
|
||||
role=role, t_start=seg["t0"], t_end=seg["t1"],
|
||||
duration_s=seg["dur"], energy_wh=seg["energy"],
|
||||
mean_w=seg["mean"], peak_w=seg["peak"],
|
||||
open=(partial and idx == len(raw) - 1),
|
||||
))
|
||||
return out
|
||||
File diff suppressed because it is too large
Load Diff
@@ -42,6 +42,11 @@ from .const import (
|
||||
MAINTENANCE_EVENT_TYPES,
|
||||
MAINTENANCE_RECENT_SUPPRESS_DAYS,
|
||||
MATCH_AMBIGUITY_MARGIN,
|
||||
PHASE_CONSISTENCY_MIN_CYCLES,
|
||||
PHASE_PROFILE_MIN_CYCLES,
|
||||
PHASE_HEAT_CV_WARN,
|
||||
PHASE_HEAT_OCC_MIXED_LO,
|
||||
PHASE_HEAT_OCC_MIXED_HI,
|
||||
REFERENCE_PROFILE_CURVE_POINTS,
|
||||
SHAPE_DRIFT_MIN_CYCLES,
|
||||
SHAPE_DRIFT_RESAMPLE_N,
|
||||
@@ -69,6 +74,14 @@ from .phase_catalog import (
|
||||
merge_phase_catalog,
|
||||
normalize_phase_name,
|
||||
)
|
||||
from .phase_segmenter import phase_matching_live_supported, phase_model_for, segment_cycle
|
||||
from .phase_match import (
|
||||
build_phase_profile,
|
||||
match_phase_profiles,
|
||||
phase_eta,
|
||||
phase_profile_from_dict,
|
||||
phase_profile_to_dict,
|
||||
)
|
||||
from .log_utils import DeviceLoggerAdapter
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
@@ -461,6 +474,24 @@ def device_active_peak_range(
|
||||
return (min(peaks), max(peaks))
|
||||
|
||||
|
||||
def terminal_drop_baseline(
|
||||
cycles: list[CycleDict],
|
||||
stop_threshold_w: float,
|
||||
min_quiet_span_s: float,
|
||||
min_clean_cycles: int,
|
||||
) -> tuple[float | None, tuple[float, float] | None]:
|
||||
"""Combined ``(earliest_quiet_offset, peak_range)`` baseline.
|
||||
|
||||
Pure (no store / no I/O beyond decompressing the passed-in cycle traces), so
|
||||
the manager can offload the whole per-cycle scan to an executor thread in one
|
||||
hop instead of decompressing every trace on the event loop (issue #311)."""
|
||||
earliest = earliest_sustained_quiet_offset(
|
||||
cycles, stop_threshold_w, min_quiet_span_s, min_clean_cycles
|
||||
)
|
||||
peak_range = device_active_peak_range(cycles, min_clean_cycles)
|
||||
return earliest, peak_range
|
||||
|
||||
|
||||
def is_terminal_drop(
|
||||
points: list[tuple[float, float]],
|
||||
earliest_quiet: float | None,
|
||||
@@ -783,57 +814,19 @@ class WashDataStore(Store[JSONDict]):
|
||||
_LOGGER.info("Migrating storage from v%s to v10", old_major_version)
|
||||
old_data.setdefault("reference_cycles", [])
|
||||
|
||||
if old_major_version < 11:
|
||||
# Marker-only bump. Per-phase profiles (envelope["phase_profile"], used
|
||||
# by phase-segmented matching / phase-resolved ETA) are DERIVED CACHE
|
||||
# built by async_rebuild_envelope, not stored data - so there is nothing
|
||||
# to migrate. They self-populate on the next envelope rebuild (which
|
||||
# runs on every cycle end / label change); until then consumers fall
|
||||
# back to the existing estimator via lazy absent-key handling. No data
|
||||
# is added, removed, or altered here.
|
||||
_LOGGER.info("Migrating storage from v%s to v11 (phase-profile cache marker)",
|
||||
old_major_version)
|
||||
|
||||
return old_data
|
||||
|
||||
async def get_storage_stats(self) -> dict[str, Any]:
|
||||
"""Get storage usage statistics."""
|
||||
data = self._data # pylint: disable=protected-access
|
||||
if not data:
|
||||
data = await self.async_load() or {}
|
||||
|
||||
# Rough file size estimation if possible, else 0
|
||||
file_size_kb = 0
|
||||
try:
|
||||
path = self.path # pylint: disable=no-member
|
||||
if os.path.exists(path):
|
||||
file_size_kb = os.path.getsize(path) / 1024
|
||||
except Exception: # pylint: disable=broad-exception-caught
|
||||
pass
|
||||
|
||||
cycles = data.get("past_cycles", [])
|
||||
profiles = data.get("profiles", {})
|
||||
|
||||
debug_traces_count = sum(1 for c in cycles if c.get("debug_data"))
|
||||
|
||||
return {
|
||||
"file_size_kb": round(file_size_kb, 1),
|
||||
"total_cycles": len(cycles),
|
||||
"total_profiles": len(profiles),
|
||||
"debug_traces_count": debug_traces_count,
|
||||
}
|
||||
|
||||
async def async_clear_debug_data(self) -> int:
|
||||
"""Clear granular debug data from all cycles to free space."""
|
||||
if not self._data:
|
||||
await self.async_load()
|
||||
|
||||
if self._data is None:
|
||||
return 0
|
||||
|
||||
cycles = self._data.get("past_cycles", [])
|
||||
count = 0
|
||||
for cycle in cycles:
|
||||
if "debug_data" in cycle:
|
||||
del cycle["debug_data"]
|
||||
count += 1
|
||||
|
||||
if count > 0:
|
||||
await self.async_save(self._data)
|
||||
_LOGGER.info("Cleared debug data from %s cycles", count)
|
||||
|
||||
return count
|
||||
|
||||
|
||||
def _ambiguity_from_candidates(candidates: list[dict]) -> tuple[float, bool]:
|
||||
"""Top1-vs-top2 score margin and whether the match is ambiguous.
|
||||
|
||||
@@ -2245,6 +2238,16 @@ class ProfileStore:
|
||||
except Exception: # noqa: BLE001
|
||||
continue
|
||||
|
||||
# Most-recent unmatched cycle id, so the setup advisor's phase-2
|
||||
# "unmatched" nudge can deep-link straight to it (open_cycle:<id>)
|
||||
# instead of always falling back to the whole unlabelled list.
|
||||
last_unmatched_cycle_id = None
|
||||
for c in reversed(unmatched):
|
||||
cid = c.get("id")
|
||||
if cid:
|
||||
last_unmatched_cycle_id = cid
|
||||
break
|
||||
|
||||
return {
|
||||
"unmatched_count": n_unmatched,
|
||||
"low_confidence_count": len(low_conf),
|
||||
@@ -2252,6 +2255,7 @@ class ProfileStore:
|
||||
"suggest_create": bool(n_unmatched >= min_unmatched and rate >= min_unmatched_rate),
|
||||
"duration_clusters": clusters,
|
||||
"profile_suggestions": profile_suggestions, # NEW (A3)
|
||||
"last_unmatched_cycle_id": last_unmatched_cycle_id,
|
||||
}
|
||||
except Exception: # noqa: BLE001
|
||||
return {}
|
||||
@@ -2438,6 +2442,47 @@ class ProfileStore:
|
||||
"message_params": {"name": name, "pct": f"{pct:.0f}"},
|
||||
})
|
||||
|
||||
# Phase-structure consistency (phase-matching device types only). Uses
|
||||
# the cached per-role phase profile: a profile whose member cycles heat
|
||||
# for wildly different times, or where only some cycles heat at all,
|
||||
# most likely mixes different programs/temperatures under one label -
|
||||
# which hurts both matching and the phase-resolved ETA. Advisory only
|
||||
# (Profiles tab); no relabeling (phase matching does not label better).
|
||||
_sd = getattr(self, "_data", None)
|
||||
_envs = _sd.get("envelopes") if isinstance(_sd, dict) else None
|
||||
for pname, penv in (_envs if isinstance(_envs, dict) else {}).items():
|
||||
if health.get(pname, {}).get("health_status") == "poor":
|
||||
continue # avoid double advice
|
||||
pp = penv.get("phase_profile") if isinstance(penv, dict) else None
|
||||
if not isinstance(pp, dict):
|
||||
continue
|
||||
try:
|
||||
if int(pp.get("n_cycles") or 0) < PHASE_CONSISTENCY_MIN_CYCLES:
|
||||
continue
|
||||
heat = (pp.get("roles") or {}).get("heating") or {}
|
||||
heat_mean = float(heat.get("dur_mean") or 0.0)
|
||||
heat_std = float(heat.get("dur_std") or 0.0)
|
||||
heat_occ = float(heat.get("occurrence") or 0.0)
|
||||
heat_cv = (heat_std / heat_mean) if heat_mean > 60.0 else 0.0
|
||||
mixed_temp = heat_cv > PHASE_HEAT_CV_WARN
|
||||
mixed_prog = PHASE_HEAT_OCC_MIXED_LO <= heat_occ <= PHASE_HEAT_OCC_MIXED_HI
|
||||
if not (mixed_temp or mixed_prog):
|
||||
continue
|
||||
advisories.append({
|
||||
"profile": pname, "severity": "warning",
|
||||
"code": "phase_inconsistent",
|
||||
"message": (
|
||||
f"'{pname}' looks like it mixes different programs or "
|
||||
"temperatures - its cycles heat for very different lengths "
|
||||
"of time. Splitting it into separate profiles (e.g. per "
|
||||
"temperature) will improve matching and time estimates."
|
||||
),
|
||||
"message_key": "msg.advisory_phase_inconsistent",
|
||||
"message_params": {"name": pname},
|
||||
})
|
||||
except (TypeError, ValueError):
|
||||
continue
|
||||
|
||||
# E1: suppress the "needs maintenance" nag (duration-trending-longer /
|
||||
# shape-drift/poor-fit) when the user recently logged a descale, filter
|
||||
# clean, or drum clean — any recent maintenance clears the reminder.
|
||||
@@ -3270,6 +3315,16 @@ class ProfileStore:
|
||||
if c.get("id") in pending_feedback_ids:
|
||||
continue
|
||||
|
||||
# EXEMPTION: Never strip power data from user-pinned "golden" cycles.
|
||||
# The matcher uses a golden trace as the sharp single-cycle template
|
||||
# (has_golden in the snapshot builder), and golden_profiles membership
|
||||
# is gated on the trace still being present — trimming it would flip
|
||||
# has_golden false and silently drop the profile back to the smeared
|
||||
# envelope average.
|
||||
rev = c.get("ml_review")
|
||||
if isinstance(rev, dict) and rev.get("golden"):
|
||||
continue
|
||||
|
||||
if c.get("power_data"):
|
||||
c.pop("power_data", None)
|
||||
c.pop("sampling_interval", None)
|
||||
@@ -3895,12 +3950,163 @@ class ProfileStore:
|
||||
"updated": dt_util.now().isoformat(),
|
||||
}
|
||||
|
||||
# Derived cache: per-phase profile (per-role duration/energy priors) used by
|
||||
# phase-segmented matching / phase-resolved ETA. Built only for device types
|
||||
# phase matching is live-supported for; absent otherwise (consumers fall back
|
||||
# to the whole-cycle pipeline). Pure/cheap - segmentation is O(samples).
|
||||
device_type = str(
|
||||
self._data.get("profiles", {}).get(profile_name, {}).get("device_type") or ""
|
||||
)
|
||||
# Offload the per-cycle segmentation to the executor (it can be tens of ms
|
||||
# for very long traces; keep it off the event loop, like the envelope DTW).
|
||||
phase_profile = await self.hass.async_add_executor_job(
|
||||
self._compute_phase_profile, profile_name, shape_cycles, device_type
|
||||
)
|
||||
if phase_profile is not None:
|
||||
envelope_data["phase_profile"] = phase_profile
|
||||
|
||||
if "envelopes" not in self._data:
|
||||
self._data["envelopes"] = {}
|
||||
self._data["envelopes"][profile_name] = envelope_data
|
||||
|
||||
return True
|
||||
|
||||
def _compute_phase_profile(
|
||||
self, profile_name: str, cycles: list[CycleDict], device_type: str
|
||||
) -> dict[str, Any] | None:
|
||||
"""Segment each member cycle and aggregate a per-role phase profile.
|
||||
|
||||
Returns a JSON-safe dict for ``envelope["phase_profile"]`` or ``None`` when
|
||||
phase matching is not live-supported for this device type or no cycle could
|
||||
be segmented. Never raises (phase support must never break envelope rebuild).
|
||||
"""
|
||||
try:
|
||||
if not phase_matching_live_supported(device_type):
|
||||
return None
|
||||
model = phase_model_for(device_type)
|
||||
if model is None:
|
||||
return None
|
||||
segmented: list = []
|
||||
for cycle in cycles:
|
||||
offsets = power_data_to_offsets(cycle.get("power_data") or [])
|
||||
if len(offsets) < 4:
|
||||
continue
|
||||
t = [float(o) for o, _ in offsets]
|
||||
w = [float(p) for _, p in offsets]
|
||||
segs = segment_cycle(t, w, model)
|
||||
if segs:
|
||||
segmented.append(segs)
|
||||
if not segmented:
|
||||
return None
|
||||
profile = build_phase_profile(profile_name, segmented)
|
||||
return phase_profile_to_dict(profile) if profile is not None else None
|
||||
except Exception: # noqa: BLE001 - phase caching must never break rebuild
|
||||
self._logger.debug("phase-profile build failed for %s", profile_name, exc_info=True)
|
||||
return None
|
||||
|
||||
def _group_scope(self, program: str) -> set[str] | None:
|
||||
"""Phase-narrowing scope for the matched ``program``:
|
||||
|
||||
* If ``program`` is in a group with >= 2 members, return that group's
|
||||
members - narrow WITHIN the family (design §9). This is both coherent
|
||||
(same program family as the displayed program) and accurate (picks the
|
||||
right temperature/spin variant among siblings).
|
||||
* Otherwise return ``None`` = no scope filter (consider ALL of the
|
||||
device's phase profiles). The Phase-0 gate showed that constraining an
|
||||
UNGROUPED cycle to only the whole-cycle-matched program regresses the
|
||||
ETA whenever that match is wrong (common on mislabeled data): the best
|
||||
ETA comes from letting the phase matcher pick the best-fitting profile,
|
||||
bounded by the ambiguity gate + cold-start floor. Grouping variants is
|
||||
the recommended workflow and restores full coherence.
|
||||
"""
|
||||
try:
|
||||
for grp in self.get_profile_groups().values():
|
||||
members = grp.get("members") if isinstance(grp, dict) else None
|
||||
if isinstance(members, list) and program in members:
|
||||
sib = {m for m in members if isinstance(m, str)}
|
||||
if len(sib) >= 2:
|
||||
return sib
|
||||
except Exception: # noqa: BLE001
|
||||
self._logger.debug("_group_scope failed for %r", program, exc_info=True)
|
||||
return None
|
||||
|
||||
def _candidate_phase_profiles(self, scope: set[str] | None = None) -> list:
|
||||
"""Cached per-profile PhaseProfiles (from envelope['phase_profile']).
|
||||
|
||||
Restricted to ``scope`` (profile names) when given, and always filtered to
|
||||
profiles with >= ``PHASE_PROFILE_MIN_CYCLES`` member cycles so a noisy
|
||||
single-cycle prior can't drive the ETA (cold-start floor).
|
||||
"""
|
||||
out = []
|
||||
for name, env in (self._data.get("envelopes") or {}).items():
|
||||
if scope is not None and name not in scope:
|
||||
continue
|
||||
if isinstance(env, dict):
|
||||
pp = phase_profile_from_dict(env.get("phase_profile"))
|
||||
if pp is not None and pp.n_cycles >= PHASE_PROFILE_MIN_CYCLES:
|
||||
out.append(pp)
|
||||
return out
|
||||
|
||||
def phase_remaining(
|
||||
self,
|
||||
power_data: list,
|
||||
device_type: str,
|
||||
program: str | None = None,
|
||||
) -> dict[str, Any] | None:
|
||||
"""Phase-resolved remaining-time for a running cycle. Never raises.
|
||||
|
||||
Segments the observed-so-far trace and matches it against the matched
|
||||
``program``'s phase profile (and its group siblings, design §9), returning
|
||||
the winning member's per-role budget remaining. Returns ``None`` (caller
|
||||
keeps the current estimate) when: phase matching is not live-supported for
|
||||
the device type; ``program`` is unknown / has no cached phase profile
|
||||
(or too few cycles - cold-start floor); segmentation is degenerate; or the
|
||||
top two candidates are within ``MATCH_AMBIGUITY_MARGIN`` (ambiguous - do
|
||||
not commit a variant, design §7).
|
||||
|
||||
This is the *phase* half of the blended ETA; the blend with the current
|
||||
estimator lives in ``progress.compute_progress`` (single source of truth).
|
||||
Pure and cheap (segmentation + per-role agreement, no DTW) - safe to call
|
||||
inline from the async matching path.
|
||||
"""
|
||||
try:
|
||||
if not phase_matching_live_supported(device_type):
|
||||
return None
|
||||
model = phase_model_for(device_type)
|
||||
if model is None or not program:
|
||||
return None
|
||||
candidates = self._candidate_phase_profiles(self._group_scope(program))
|
||||
if not candidates:
|
||||
return None
|
||||
offsets = power_data_to_offsets(power_data or [])
|
||||
if len(offsets) < 4:
|
||||
return None
|
||||
t = [float(o) for o, _ in offsets]
|
||||
w = [float(p) for _, p in offsets]
|
||||
segs = segment_cycle(t, w, model, partial=True)
|
||||
if not segs:
|
||||
return None
|
||||
ranked = match_phase_profiles(segs, candidates, {})
|
||||
if not ranked:
|
||||
return None
|
||||
# Ambiguity gate: a near-tie among group members is not a confident
|
||||
# variant call - fall back rather than swing the ETA between budgets.
|
||||
if (len(ranked) >= 2
|
||||
and (ranked[0].score - ranked[1].score) < MATCH_AMBIGUITY_MARGIN):
|
||||
return None
|
||||
best = next((c for c in candidates if c.name == ranked[0].name), None)
|
||||
remaining = phase_eta(segs, best) if best is not None else None
|
||||
if remaining is None:
|
||||
return None
|
||||
return {
|
||||
"remaining_s": float(remaining),
|
||||
"matched": ranked[0].name,
|
||||
"score": float(ranked[0].score),
|
||||
}
|
||||
except Exception: # noqa: BLE001 - phase ETA must never break the estimate
|
||||
self._logger.debug("phase_remaining failed", exc_info=True)
|
||||
return None
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -3977,6 +4183,66 @@ class ProfileStore:
|
||||
except Exception: # pragma: no cover - defensive; never break the sensor
|
||||
return None
|
||||
|
||||
def get_profile_power_profile(
|
||||
self, profile_name: str, interval_s: float = 900.0
|
||||
) -> list[float]:
|
||||
"""Average power (W) per fixed interval across a profile's learned shape.
|
||||
|
||||
Resamples the profile envelope's average power-over-time curve into
|
||||
consecutive ``interval_s`` buckets (default 15 min) and returns the mean
|
||||
watts in each, e.g. ``[2200, 2200, 800, 800, 1500, 500, 400, 200]`` - the
|
||||
flat per-slot array external planners such as tibber_prices'
|
||||
``power_profile`` consume to pick the cheapest window to run the appliance
|
||||
(issue #272). Unlike :meth:`reference_curve` (a downsampled time/watt shape
|
||||
surfaced on the running-program sensor), this is a fixed-interval average
|
||||
exposed per profile so it can be read for planning before a cycle starts.
|
||||
|
||||
The final bucket is averaged only over the part of the cycle that actually
|
||||
falls inside it. Pure statistics; never raises. Returns an empty list when
|
||||
the profile has no learned envelope yet.
|
||||
"""
|
||||
try:
|
||||
if interval_s <= 0:
|
||||
return []
|
||||
env = self.get_envelope(profile_name)
|
||||
if not isinstance(env, dict):
|
||||
return []
|
||||
avg = env.get("avg")
|
||||
if (
|
||||
not isinstance(avg, list)
|
||||
or len(avg) < 2
|
||||
or not isinstance(avg[0], (list, tuple))
|
||||
or len(avg[0]) < 2
|
||||
):
|
||||
return []
|
||||
ts = np.asarray([float(p[0]) for p in avg], dtype=float)
|
||||
ws = np.asarray([float(p[1]) for p in avg], dtype=float)
|
||||
if ts.size < 2 or not (np.all(np.isfinite(ts)) and np.all(np.isfinite(ws))):
|
||||
return []
|
||||
if ts[-1] <= ts[0]:
|
||||
return []
|
||||
total = float(env.get("target_duration") or 0.0)
|
||||
if total <= 0:
|
||||
total = float(ts[-1])
|
||||
if total <= 0:
|
||||
return []
|
||||
n_buckets = int(math.ceil(total / interval_s))
|
||||
out: list[float] = []
|
||||
for k in range(n_buckets):
|
||||
lo = k * interval_s
|
||||
hi = min(lo + interval_s, total)
|
||||
if hi <= lo:
|
||||
break
|
||||
# Time-average the curve over the half-open slot [lo, hi) on a fine
|
||||
# interpolated grid, so the result is independent of the envelope's
|
||||
# grid spacing. endpoint=False keeps a slot boundary from being
|
||||
# double-counted into the adjacent slot.
|
||||
fine = np.linspace(lo, hi, 16, endpoint=False)
|
||||
out.append(round(float(np.mean(np.interp(fine, ts, ws))), 1))
|
||||
return out
|
||||
except Exception: # pragma: no cover - defensive; never break the sensor
|
||||
return []
|
||||
|
||||
def compute_envelope_conformance(
|
||||
self,
|
||||
profile_name: str,
|
||||
@@ -4315,39 +4581,48 @@ class ProfileStore:
|
||||
# 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", []))
|
||||
# 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
|
||||
# auto-label (many matches x many cycles) - issue #311. Selections are
|
||||
# byte-identical: cycles_by_id keeps the FIRST occurrence (== next()),
|
||||
# labeled_by_profile keeps the first eligible cycle in all_cycles order,
|
||||
# and golden_profiles mirrors the any(...) golden test.
|
||||
cycles_by_id: dict[str, CycleDict] = {}
|
||||
labeled_by_profile: dict[str, CycleDict] = {}
|
||||
golden_profiles: set[str] = set()
|
||||
for c in all_cycles:
|
||||
cid = c.get("id")
|
||||
if cid is not None and cid not in cycles_by_id:
|
||||
cycles_by_id[cid] = c
|
||||
pname = c.get("profile_name")
|
||||
if not pname or not c.get("power_data"):
|
||||
continue
|
||||
if (
|
||||
pname not in labeled_by_profile
|
||||
and c.get("status") in ("completed", "force_stopped")
|
||||
):
|
||||
labeled_by_profile[pname] = c
|
||||
rev = c.get("ml_review")
|
||||
if isinstance(rev, dict) and rev.get("golden"):
|
||||
golden_profiles.add(pname)
|
||||
|
||||
snapshots: list[dict[str, Any]] = []
|
||||
skipped_profiles: list[str] = []
|
||||
for name, profile in self._data["profiles"].items():
|
||||
# Try sample_cycle_id first, fall back to any labeled cycle
|
||||
sample_id = profile.get("sample_cycle_id")
|
||||
sample_cycle = None
|
||||
if sample_id:
|
||||
sample_cycle = next(
|
||||
(c for c in all_cycles if c["id"] == sample_id),
|
||||
None
|
||||
)
|
||||
sample_cycle = cycles_by_id.get(sample_id) if sample_id else None
|
||||
# Fallback: find ANY completed cycle labeled with this profile
|
||||
if not sample_cycle:
|
||||
sample_cycle = next(
|
||||
(c for c in all_cycles
|
||||
if c.get("profile_name") == name
|
||||
and c.get("status") in ("completed", "force_stopped")
|
||||
and c.get("power_data")),
|
||||
None
|
||||
)
|
||||
sample_cycle = labeled_by_profile.get(name)
|
||||
# Boost user-pinned "golden" cycles: when a profile has one, use
|
||||
# its sharp single-cycle trace as the matching template instead
|
||||
# of the envelope average. The envelope average smears the
|
||||
# wash-phase peaks (each cycle's spikes land at slightly
|
||||
# different times), which hurts correlation for sharply-shaped
|
||||
# programs; a trusted golden cycle preserves that shape.
|
||||
has_golden = any(
|
||||
c.get("profile_name") == name
|
||||
and isinstance(c.get("ml_review"), dict)
|
||||
and c["ml_review"].get("golden")
|
||||
and c.get("power_data")
|
||||
for c in all_cycles
|
||||
)
|
||||
has_golden = name in golden_profiles
|
||||
|
||||
# Prefer envelope avg curve when ≥2 labeled cycles have been
|
||||
# confirmed - it gives a more representative reference signal
|
||||
@@ -4717,6 +4992,34 @@ class ProfileStore:
|
||||
# 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.
|
||||
|
||||
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.
|
||||
"""
|
||||
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", [])
|
||||
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))
|
||||
|
||||
def list_profiles(self) -> list[dict[str, Any]]:
|
||||
"""List all profiles with metadata."""
|
||||
profiles: list[JSONDict] = []
|
||||
@@ -5768,8 +6071,21 @@ class ProfileStore:
|
||||
if p_data and p_data.get("sample_cycle_id") == original_sample_id:
|
||||
p_data["sample_cycle_id"] = best_replacement_id
|
||||
|
||||
# Rebuild envelope because dataset changed
|
||||
await self.async_rebuild_envelope(original_profile)
|
||||
# Rebuild envelopes ONLY for the profiles whose dataset actually changed:
|
||||
# the original profile (it lost the parent cycle) plus any profile a labeled
|
||||
# segment was assigned to. This replaces a blanket rebuild-all-envelopes in
|
||||
# the caller, which re-scanned every profile serially and stalled low-power
|
||||
# hosts on a split (issue #311 follow-up).
|
||||
touched: set[str] = set()
|
||||
if original_profile:
|
||||
touched.add(original_profile)
|
||||
for seg in segments:
|
||||
if isinstance(seg, dict):
|
||||
seg_prof = seg.get("profile")
|
||||
if seg_prof:
|
||||
touched.add(seg_prof)
|
||||
for name in touched:
|
||||
await self.async_rebuild_envelope(name)
|
||||
|
||||
await self.async_save()
|
||||
self._logger.info("Interactive Split Applied to %s -> %s", cycle_id, new_ids)
|
||||
|
||||
@@ -448,7 +448,7 @@ def estimate_phase_progress(
|
||||
return (best_progress, best_variance)
|
||||
|
||||
|
||||
def compute_progress(
|
||||
def _compute_progress_base(
|
||||
device_type: str,
|
||||
matched_duration: float,
|
||||
duration_so_far: float,
|
||||
@@ -549,6 +549,76 @@ def compute_progress(
|
||||
return ProgressResult(progress, smoothed, remaining, total, None, "linear")
|
||||
|
||||
|
||||
def compute_progress(
|
||||
device_type: str,
|
||||
matched_duration: float,
|
||||
duration_so_far: float,
|
||||
prev_smoothed: float,
|
||||
phase_result: tuple[float, float] | None,
|
||||
ml_pct: float | None,
|
||||
logger: logging.Logger | None = None,
|
||||
phase_remaining_s: float | None = None,
|
||||
) -> ProgressResult | None:
|
||||
"""Progress/remaining estimate, optionally blended with a phase-resolved ETA.
|
||||
|
||||
When ``phase_remaining_s`` is provided (opt-in phase matching for a supported
|
||||
device type), the phase-budget remaining is converted to a completion PERCENT
|
||||
and blended into the phase-progress signal **before** delegating to
|
||||
:func:`_compute_progress_base` - so the blend rides the proven, golden-locked
|
||||
EMA + monotonicity + back-calculation guards (design §8, "one smoothing
|
||||
implementation"), rather than re-deriving a raw, unsmoothed progress. The
|
||||
blend leans on the phase budget early (low base progress) and on the proven
|
||||
phase estimate late::
|
||||
|
||||
phase_pct = duration_so_far / (duration_so_far + phase_remaining_s) * 100
|
||||
f = base_phase_progress / 100
|
||||
blended = (1 - f) * phase_pct + f * base_phase_progress
|
||||
|
||||
Because this feeds the percent-domain smoothing, the displayed progress stays
|
||||
monotone/smoothed (no tick-to-tick jitter or collapse-to-99%), and remaining
|
||||
is re-derived by the base from ``matched_duration``.
|
||||
|
||||
Behaviour is BYTE-IDENTICAL to before when ``phase_remaining_s is None`` (the
|
||||
default) - the golden progress snapshot and every existing caller are
|
||||
unaffected. This is the single implementation of the blend; the manager and
|
||||
the Playground SimRunner both go through it.
|
||||
"""
|
||||
blended = False
|
||||
if phase_remaining_s is not None and matched_duration and matched_duration > 0:
|
||||
try:
|
||||
pr = float(phase_remaining_s)
|
||||
except (TypeError, ValueError):
|
||||
pr = float("nan")
|
||||
if math.isfinite(pr) and pr >= 0.0:
|
||||
denom = duration_so_far + pr
|
||||
phase_pct = (duration_so_far / denom * 100.0) if denom > 0 else 0.0
|
||||
phase_pct = max(0.0, min(100.0, phase_pct))
|
||||
if phase_result is not None:
|
||||
base_pp, variance = phase_result
|
||||
f = max(0.0, min(1.0, float(base_pp) / 100.0))
|
||||
phase_result = ((1.0 - f) * phase_pct + f * float(base_pp), variance)
|
||||
else:
|
||||
# No envelope phase-progress: blend the phase budget's implied
|
||||
# percent with the linear (elapsed/matched) percent, still leaning
|
||||
# on the phase budget early and the linear estimate late.
|
||||
lin_pct = max(0.0, min(100.0, duration_so_far / matched_duration * 100.0))
|
||||
f = lin_pct / 100.0
|
||||
phase_result = ((1.0 - f) * phase_pct + f * lin_pct, 0.0)
|
||||
blended = True
|
||||
|
||||
base = _compute_progress_base(
|
||||
device_type, matched_duration, duration_so_far, prev_smoothed,
|
||||
phase_result, ml_pct, logger,
|
||||
)
|
||||
if base is None or not blended:
|
||||
return base
|
||||
# Relabel the source for diagnostics; values already reflect the blend.
|
||||
return ProgressResult(
|
||||
base.progress, base.smoothed, base.remaining, base.total,
|
||||
base.phase_progress, "phase_blend",
|
||||
)
|
||||
|
||||
|
||||
def current_phase(
|
||||
store: Any,
|
||||
state: str,
|
||||
|
||||
@@ -745,6 +745,16 @@ class WasherProfileCountSensor(WasherBaseSensor):
|
||||
"min_length_min": _to_min(profile.get("min_duration", 0)),
|
||||
"max_length_min": _to_min(profile.get("max_duration", 0)),
|
||||
"consistency_min": consistency_min,
|
||||
# Average power (W) per 15-min slot of this profile's learned shape,
|
||||
# e.g. [2200, 2200, 800, ...] - the flat array external planners such
|
||||
# as tibber_prices' `power_profile` consume to pick the cheapest run
|
||||
# window (issue #272). Empty until the profile has a learned envelope.
|
||||
# Refreshes with the profile: the envelope is rebuilt on each new
|
||||
# labelled cycle, which bumps this sensor's cycle_count state.
|
||||
"power_profile": self._manager.profile_store.get_profile_power_profile(
|
||||
self._profile_name
|
||||
),
|
||||
"power_profile_interval_min": 15,
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@ auto_label_cycles:
|
||||
name: Confidence Threshold
|
||||
description: Minimum match confidence (0.50-0.95) to apply labels.
|
||||
required: false
|
||||
default: 0.70
|
||||
default: 0.75
|
||||
selector:
|
||||
number:
|
||||
min: 0.50
|
||||
|
||||
@@ -0,0 +1,237 @@
|
||||
"""Pure phase computation for the adoption guidance system.
|
||||
|
||||
No HA imports. No side effects. Testable in isolation.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass, field
|
||||
from datetime import datetime, timezone
|
||||
|
||||
|
||||
@dataclass
|
||||
class SetupPhaseResult:
|
||||
phase: str # phase0 | phase1a | phase1b | phase1c | phase2 | phase3 | phase4
|
||||
message_key: str
|
||||
message_params: dict = field(default_factory=dict)
|
||||
cta_label_key: str = "setup.cta.start_recording"
|
||||
cta_action: str = "open_recorder"
|
||||
secondary_label_key: str | None = None
|
||||
secondary_action: str | None = None
|
||||
skippable: bool = False
|
||||
dismissible: bool = False
|
||||
step_key: str | None = None # key used in skipped_steps dict
|
||||
|
||||
|
||||
def compute_setup_phase(
|
||||
device_type: str,
|
||||
profile_names: list[str],
|
||||
past_cycles: list[dict],
|
||||
ref_profile_names: set[str],
|
||||
coverage_gap: dict | None,
|
||||
suggestions: list[dict],
|
||||
profile_groups: list[dict],
|
||||
skipped_steps: dict[str, str | None],
|
||||
now: datetime,
|
||||
) -> SetupPhaseResult:
|
||||
"""Compute the current adoption phase for a device.
|
||||
|
||||
Args:
|
||||
device_type: HA device type string (washing_machine, dishwasher, ...).
|
||||
profile_names: All profile names stored for this device.
|
||||
past_cycles: All past cycles (each may have profile_name and meta.source).
|
||||
ref_profile_names: Profile names that have reference cycles (store-adopted).
|
||||
coverage_gap: Result of profile_store.suggest_coverage_gaps(), or None.
|
||||
suggestions: Actionable suggestions from SuggestionEngine (empty list = none).
|
||||
profile_groups: Profile groups list from store (empty list = none pending).
|
||||
skipped_steps: Dict of step_key -> "never" | ISO timestamp | None.
|
||||
now: Current aware datetime for snooze comparisons.
|
||||
"""
|
||||
real = _real_profile_names(profile_names, past_cycles)
|
||||
has_real = bool(real)
|
||||
has_recorded = _has_recorded_cycles(past_cycles, real)
|
||||
has_store = bool(ref_profile_names)
|
||||
has_self_cycles = bool(real) # any cycle assigned to a real profile
|
||||
|
||||
# ── Phase 0 ──────────────────────────────────────────────────────────────
|
||||
if not has_real and not has_store:
|
||||
msg_key = {
|
||||
"washing_machine": "setup.phase0.washer",
|
||||
"dryer": "setup.phase0.washer",
|
||||
"washer_dryer": "setup.phase0.washer",
|
||||
"dishwasher": "setup.phase0.dishwasher",
|
||||
}.get(device_type, "setup.phase0.generic")
|
||||
return SetupPhaseResult(
|
||||
phase="phase0",
|
||||
message_key=msg_key,
|
||||
cta_label_key="setup.cta.start_recording",
|
||||
cta_action="open_recorder",
|
||||
secondary_label_key="setup.cta.label_detected_cycle",
|
||||
secondary_action="open_cycles_unlabeled",
|
||||
skippable=False,
|
||||
dismissible=False,
|
||||
)
|
||||
|
||||
# ── Phase 1c — store download, no self cycles yet ─────────────────────────
|
||||
if has_store and not has_self_cycles:
|
||||
return SetupPhaseResult(
|
||||
phase="phase1c",
|
||||
message_key="setup.phase1c.verify",
|
||||
message_params={"count": len(ref_profile_names)},
|
||||
cta_label_key="setup.cta.view_profiles",
|
||||
cta_action="open_profiles",
|
||||
skippable=False,
|
||||
dismissible=False,
|
||||
)
|
||||
|
||||
# ── Phase 2 — coverage gaps / unmatched nudges ───────────────────────────
|
||||
if _phase2_active(coverage_gap, skipped_steps, now):
|
||||
cg = coverage_gap or {}
|
||||
clusters = cg.get("profile_suggestions") or []
|
||||
if clusters:
|
||||
first = clusters[0]
|
||||
return SetupPhaseResult(
|
||||
phase="phase2",
|
||||
message_key="setup.phase2.cluster",
|
||||
message_params={"count": cg.get("unmatched_count", 0),
|
||||
"cycle_ids": first.get("cycle_ids", []),
|
||||
"name": first.get("suggested_name", "")},
|
||||
cta_label_key="setup.cta.create_from_cluster",
|
||||
cta_action="create_profile_from_cluster",
|
||||
skippable=True,
|
||||
dismissible=False,
|
||||
step_key="setup_skip_phase2",
|
||||
)
|
||||
last_id = cg.get("last_unmatched_cycle_id")
|
||||
return SetupPhaseResult(
|
||||
phase="phase2",
|
||||
message_key="setup.phase2.unmatched",
|
||||
message_params={"cycle_id": last_id or ""},
|
||||
cta_label_key="setup.cta.create_profile",
|
||||
cta_action=f"open_cycle:{last_id}" if last_id else "open_cycles_unlabeled",
|
||||
skippable=True,
|
||||
dismissible=False,
|
||||
step_key="setup_skip_phase2",
|
||||
)
|
||||
|
||||
# ── Phase 3 — tuning items ────────────────────────────────────────────────
|
||||
item = _phase3_pending_item(suggestions, profile_groups, skipped_steps, now)
|
||||
if item:
|
||||
return item
|
||||
|
||||
# ── Phase 1a / 1b — early guidance (device has not yet seen coverage stats) ─
|
||||
# Only shown while the gap analyser has not yet flagged a coverage gap:
|
||||
# suggest_coverage_gaps() returns {} (empty) when there are no cycles or not
|
||||
# enough unmatched cycles, and a dict with suggest_create=True once the device
|
||||
# has accumulated enough cycles for the gap to be actionable. We treat any
|
||||
# non-empty dict where suggest_create is True as "past the early stage".
|
||||
# None is also accepted (function signature allows it) and treated as no gap.
|
||||
# Also skipped once the user has permanently dismissed ("never") or snoozed the
|
||||
# Phase 1 guidance via setup_skip_phase1.
|
||||
if has_real and not (coverage_gap and coverage_gap.get("suggest_create")) and not _is_step_suppressed("setup_skip_phase1", skipped_steps, now):
|
||||
if has_recorded:
|
||||
first_recorded_profile = _first_recorded_profile_name(past_cycles, real)
|
||||
return SetupPhaseResult(
|
||||
phase="phase1b",
|
||||
message_key="setup.phase1b.recorded",
|
||||
message_params={"profile_name": first_recorded_profile or ""},
|
||||
cta_label_key="setup.cta.start_recording",
|
||||
cta_action="open_recorder",
|
||||
secondary_label_key="setup.cta.browse_cycles",
|
||||
secondary_action="open_cycles",
|
||||
skippable=True,
|
||||
dismissible=False,
|
||||
step_key="setup_skip_phase1",
|
||||
)
|
||||
return SetupPhaseResult(
|
||||
phase="phase1a",
|
||||
message_key="setup.phase1a.labelled",
|
||||
cta_label_key="setup.cta.start_recording",
|
||||
cta_action="open_recorder",
|
||||
secondary_label_key="setup.cta.browse_cycles",
|
||||
secondary_action="open_cycles",
|
||||
skippable=True,
|
||||
dismissible=False,
|
||||
step_key="setup_skip_phase1",
|
||||
)
|
||||
|
||||
# ── Phase 4 — healthy ─────────────────────────────────────────────────────
|
||||
return SetupPhaseResult(
|
||||
phase="phase4",
|
||||
message_key="setup.phase4.healthy",
|
||||
message_params={"profile_count": len(real)},
|
||||
skippable=False,
|
||||
dismissible=True,
|
||||
)
|
||||
|
||||
|
||||
# ── Private helpers ───────────────────────────────────────────────────────────
|
||||
|
||||
def _real_profile_names(profile_names: list[str], past_cycles: list[dict]) -> set[str]:
|
||||
named = {c.get("profile_name") for c in past_cycles if c.get("profile_name")}
|
||||
return {n for n in profile_names if n in named}
|
||||
|
||||
|
||||
def _has_recorded_cycles(past_cycles: list[dict], real: set[str]) -> bool:
|
||||
return any(
|
||||
(c.get("meta") or {}).get("source") == "recorder"
|
||||
for c in past_cycles
|
||||
if c.get("profile_name") in real
|
||||
)
|
||||
|
||||
|
||||
def _first_recorded_profile_name(past_cycles: list[dict], real: set[str]) -> str | None:
|
||||
for c in past_cycles:
|
||||
if (c.get("profile_name") in real
|
||||
and (c.get("meta") or {}).get("source") == "recorder"):
|
||||
return c["profile_name"]
|
||||
return None
|
||||
|
||||
|
||||
def _is_step_suppressed(step_key: str, skipped_steps: dict, now: datetime) -> bool:
|
||||
val = skipped_steps.get(step_key)
|
||||
if not val:
|
||||
return False
|
||||
if val == "never":
|
||||
return True
|
||||
try:
|
||||
until = datetime.fromisoformat(val)
|
||||
if until.tzinfo is None:
|
||||
until = until.replace(tzinfo=timezone.utc)
|
||||
return now < until
|
||||
except (ValueError, TypeError):
|
||||
return False
|
||||
|
||||
|
||||
def _phase2_active(coverage_gap: dict | None, skipped_steps: dict, now: datetime) -> bool:
|
||||
if not coverage_gap or not coverage_gap.get("suggest_create"):
|
||||
return False
|
||||
return not _is_step_suppressed("setup_skip_phase2", skipped_steps, now)
|
||||
|
||||
|
||||
def _phase3_pending_item(
|
||||
suggestions: list[dict],
|
||||
profile_groups: list[dict],
|
||||
skipped_steps: dict,
|
||||
now: datetime,
|
||||
) -> SetupPhaseResult | None:
|
||||
if suggestions and not _is_step_suppressed("setup_skip_phase3_suggestions", skipped_steps, now):
|
||||
return SetupPhaseResult(
|
||||
phase="phase3",
|
||||
message_key="setup.phase3.suggestions",
|
||||
cta_label_key="setup.cta.review_suggestions",
|
||||
cta_action="open_suggestions",
|
||||
skippable=True,
|
||||
dismissible=True,
|
||||
step_key="setup_skip_phase3_suggestions",
|
||||
)
|
||||
if profile_groups and not _is_step_suppressed("setup_skip_phase3_groups", skipped_steps, now):
|
||||
return SetupPhaseResult(
|
||||
phase="phase3",
|
||||
message_key="setup.phase3.groups",
|
||||
cta_label_key="setup.cta.organise_profiles",
|
||||
cta_action="open_profiles_groups",
|
||||
skippable=True,
|
||||
dismissible=True,
|
||||
step_key="setup_skip_phase3_groups",
|
||||
)
|
||||
return None
|
||||
@@ -160,6 +160,21 @@ class StoreBridge:
|
||||
self._ps = profile_store
|
||||
self._client = StoreClient(hass)
|
||||
|
||||
def _fire_download_telemetry(self, cycle_ids: list[str]) -> None:
|
||||
"""Fire best-effort download/adoption telemetry as a detached background task.
|
||||
|
||||
Awaiting these store round-trips inline would add their HTTP latency (up to the
|
||||
15s per-request timeout when the store is slow/unreachable) to the user-facing
|
||||
adopt response. Their outcome does not affect the result, and both bump_* calls
|
||||
swallow their own errors, so a detached task can never surface an exception.
|
||||
"""
|
||||
async def _bump() -> None:
|
||||
if cycle_ids:
|
||||
await self._client.bump_downloads(cycle_ids)
|
||||
await self._client.bump_analytics("downloads", 1)
|
||||
|
||||
self._hass.async_create_background_task(_bump(), "washdata_store_telemetry")
|
||||
|
||||
# ── account / status (global) ───────────────────────────────────────────────
|
||||
|
||||
def status(self) -> dict[str, Any]:
|
||||
@@ -243,6 +258,10 @@ class StoreBridge:
|
||||
})
|
||||
if not local_id: # trace failed validation in add_reference_cycle
|
||||
return {"error": "invalid_trace"}
|
||||
# Credit the download on the source store cycle + record one community-wide
|
||||
# adoption for the store's usage dashboard (the real "someone used it" metric).
|
||||
# Fired in the background so store latency never delays the adopt response.
|
||||
self._fire_download_telemetry([cyc["id"]] if cyc.get("id") else [])
|
||||
return {"profile": profile, "cycle_id": local_id}
|
||||
|
||||
async def share_cycle(
|
||||
@@ -378,6 +397,7 @@ class StoreBridge:
|
||||
profiles_adopted = 0
|
||||
cycles_imported = 0
|
||||
phases_applied = 0
|
||||
imported_store_ids: list[str] = []
|
||||
for prof in bundle.get("profiles", []) or []:
|
||||
program = str(prof.get("program") or prof.get("program_lc") or "").strip()
|
||||
if not program:
|
||||
@@ -398,6 +418,8 @@ class StoreBridge:
|
||||
if local_id:
|
||||
cycles_imported += 1
|
||||
adopted_any = True
|
||||
if store_cid:
|
||||
imported_store_ids.append(store_cid)
|
||||
if adopted_any:
|
||||
profiles_adopted += 1
|
||||
# Stage 2: apply the bundled phase map (replace) + reconcile labels. Never
|
||||
@@ -406,6 +428,14 @@ class StoreBridge:
|
||||
# re-download with no new cycles still reconciles updated phase ranges.
|
||||
if prof.get("phases") and await self._apply_phases(program, prof.get("phases"), device_type):
|
||||
phases_applied += 1
|
||||
# Credit a download on every reference cycle actually adopted this run (each
|
||||
# underlying object, not just one). Skipped/duplicate cycles aren't re-counted,
|
||||
# so re-downloading the same device doesn't inflate the counters. Also record one
|
||||
# community-wide "download" (adoption) for the store's usage dashboard -- the real
|
||||
# metric of how many people actually pulled this into their integration. Fired in
|
||||
# the background so store latency never delays the adopt-bundle response.
|
||||
if imported_store_ids:
|
||||
self._fire_download_telemetry(imported_store_ids)
|
||||
settings = bundle.get("settings") if isinstance(bundle.get("settings"), dict) else {}
|
||||
return {
|
||||
"profiles_adopted": profiles_adopted,
|
||||
|
||||
@@ -36,6 +36,7 @@ from typing import Any
|
||||
|
||||
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 (
|
||||
SHAREABLE_SETTING_KEYS,
|
||||
@@ -334,7 +335,9 @@ class StoreClient:
|
||||
"structuredQuery": {"from": [{"collectionId": "ratings"}]},
|
||||
"aggregations": [
|
||||
{"alias": "cnt", "count": {}},
|
||||
{"alias": "avg", "average": {"field": {"fieldPath": "rating"}}},
|
||||
# NB: the Firestore aggregation operator is `avg`, NOT `average` --
|
||||
# the wrong name 400s the whole query and silently zeroes ratings.
|
||||
{"alias": "avg", "avg": {"field": {"fieldPath": "rating"}}},
|
||||
],
|
||||
}}
|
||||
try:
|
||||
@@ -800,3 +803,59 @@ class StoreClient:
|
||||
if not ok:
|
||||
_LOGGER.warning("Store rate_device failed: %s", body[:200])
|
||||
return ok
|
||||
|
||||
async def bump_downloads(self, cycle_ids: list[str]) -> None:
|
||||
"""Best-effort +1 to each cycle's public ``downloads`` counter. The store rule
|
||||
allows an anonymous ``downloads++`` (unauthenticated), so this needs no token --
|
||||
it mirrors the website's per-download bump. Chunked to stay under Firestore's
|
||||
500-writes-per-commit limit. Never raises."""
|
||||
# Deduplicate (order-preserving): Firestore :commit rejects a batch (HTTP 400)
|
||||
# if it contains two writes to the same document, which a bundle referencing
|
||||
# the same shared cycle across profiles can produce.
|
||||
ids = list(dict.fromkeys(c for c in (cycle_ids or []) if c))
|
||||
for start in range(0, len(ids), 400):
|
||||
writes = [
|
||||
{"transform": {
|
||||
"document": self._doc_path(f"cycles/{cid}"),
|
||||
"fieldTransforms": [{"fieldPath": "downloads", "increment": _encode(1)}],
|
||||
}}
|
||||
for cid in ids[start:start + 400]
|
||||
]
|
||||
try:
|
||||
async with self._sess().post(
|
||||
f"{self._base}:commit", json={"writes": writes}, timeout=15,
|
||||
) as resp:
|
||||
if resp.status != 200:
|
||||
_LOGGER.debug("Store bump_downloads HTTP %s: %s", resp.status, (await resp.text())[:200])
|
||||
except Exception as exc: # noqa: BLE001
|
||||
_LOGGER.debug("Store bump_downloads error: %s", exc)
|
||||
|
||||
async def bump_analytics(self, field: str, n: int = 1) -> None:
|
||||
"""Best-effort +n to an aggregate usage counter the store's admin dashboard reads
|
||||
(``analytics/totals`` + ``analytics/daily_YYYYMMDD``). This is how integration
|
||||
downloads become a real, community-wide usage metric -- the website has no
|
||||
download action, so the integration is the source of truth for "someone adopted
|
||||
this". Unauthenticated (the analytics rule allows anonymous counter writes) and
|
||||
never raises. The daily doc id is UTC to line up with the website's own writes.
|
||||
"""
|
||||
if not field or n <= 0:
|
||||
return
|
||||
day = dt_util.utcnow().strftime("%Y%m%d") # UTC to match the website's daily docs
|
||||
writes = [
|
||||
{"transform": {
|
||||
"document": self._doc_path(f"analytics/daily_{day}"),
|
||||
"fieldTransforms": [{"fieldPath": field, "increment": _encode(n)}],
|
||||
}},
|
||||
{"transform": {
|
||||
"document": self._doc_path("analytics/totals"),
|
||||
"fieldTransforms": [{"fieldPath": field, "increment": _encode(n)}],
|
||||
}},
|
||||
]
|
||||
try:
|
||||
async with self._sess().post(
|
||||
f"{self._base}:commit", json={"writes": writes}, timeout=15,
|
||||
) as resp:
|
||||
if resp.status != 200:
|
||||
_LOGGER.debug("Store bump_analytics HTTP %s: %s", resp.status, (await resp.text())[:200])
|
||||
except Exception as exc: # noqa: BLE001
|
||||
_LOGGER.debug("Store bump_analytics error: %s", exc)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"step": {
|
||||
"user": {
|
||||
"title": "WashData Setup",
|
||||
"description": "Configure your washing machine or other appliance.\n\nPower sensor is required.\n\n**Next, you will be asked if you want to create your first profile.**",
|
||||
"description": "Configure your washing machine or other appliance.\n\nPower sensor is required.",
|
||||
"data": {
|
||||
"name": "Device Name",
|
||||
"device_type": "Device Type",
|
||||
@@ -17,14 +17,6 @@
|
||||
"min_power": "Power readings above this threshold (in watts) indicate the appliance is running. Start with 2W for most devices."
|
||||
}
|
||||
},
|
||||
"first_profile": {
|
||||
"title": "Create First Profile",
|
||||
"description": "A **Cycle** is a complete run of your appliance (e.g., a load of laundry). A **Profile** groups these cycles by type (e.g., 'Cotton', 'Quick Wash'). Creating a profile now helps the integration estimate duration immediately.\n\nYou can manually select this profile in the device controls if it's not detected automatically.\n\n**Leave 'Profile Name' empty to skip this step.**",
|
||||
"data": {
|
||||
"profile_name": "Profile Name (Optional)",
|
||||
"manual_duration": "Estimated Duration (minutes)"
|
||||
}
|
||||
},
|
||||
"reconfigure": {
|
||||
"title": "Reconfigure WashData",
|
||||
"description": "Update the device name, appliance type, or power sensor.",
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"step": {
|
||||
"user": {
|
||||
"title": "WashData Setup",
|
||||
"description": "Configure your washing machine or other appliance.\n\nPower sensor is required.\n\n**Next, you will be asked if you want to create your first profile.**",
|
||||
"description": "Configure your washing machine or other appliance.\n\nPower sensor is required.",
|
||||
"data": {
|
||||
"name": "Device Name",
|
||||
"device_type": "Device Type",
|
||||
@@ -17,14 +17,6 @@
|
||||
"min_power": "Power readings above this threshold (in watts) indicate the appliance is running. Start with 2W for most devices."
|
||||
}
|
||||
},
|
||||
"first_profile": {
|
||||
"title": "Create First Profile",
|
||||
"description": "A **Cycle** is a complete run of your appliance (e.g., a load of laundry). A **Profile** groups these cycles by type (e.g., 'Cotton', 'Quick Wash'). Creating a profile now helps the integration estimate duration immediately.\n\nYou can manually select this profile in the device controls if it's not detected automatically.\n\n**Leave 'Profile Name' empty to skip this step.**",
|
||||
"data": {
|
||||
"profile_name": "Profile Name (Optional)",
|
||||
"manual_duration": "Estimated Duration (minutes)"
|
||||
}
|
||||
},
|
||||
"reconfigure": {
|
||||
"title": "Reconfigure WashData",
|
||||
"description": "Update the device name, appliance type, or power sensor.",
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
{
|
||||
"badge": {
|
||||
"artifact_tip": "{n} открити аномалии (напр. отворена врата по средата на цикъла) — отворете, за да ги видите на графиката",
|
||||
"artifact_tip": "{n} открити аномалии (напр. отворена врата по средата на цикъла) – отворете, за да ги видите на графиката",
|
||||
"auto": "(автоматично разпознато)",
|
||||
"built_in_tag": "вградена",
|
||||
"declining": "↘ намалява",
|
||||
"energy_low": "По-ниска енергия от обичайното",
|
||||
"energy_spike": "По-висока енергия от обичайното",
|
||||
"fair_fit": "приемливо качество",
|
||||
"fair_fit_tip": "Умерена последователност на съвпадението — някои цикли, присвоени на този профил, имат по-ниски резултати за доверие. Маркирайте повече цикли или запишете отново профила, за да подобрите точността.",
|
||||
"fair_fit_tip": "Умерена последователност на съвпадението – някои цикли, присвоени на този профил, имат по-ниски резултати за доверие. Маркирайте повече цикли или запишете отново профила, за да подобрите точността.",
|
||||
"feedback_requested": "Иска се обратна връзка",
|
||||
"golden_cycle": "Записан референтен цикъл",
|
||||
"improving": "↗ подобряване",
|
||||
@@ -16,7 +16,7 @@
|
||||
"overrun": "Бяга по-дълго от обикновено",
|
||||
"underrun": "Завърши по-бързо от обикновено",
|
||||
"poor_fit": "лошо качество",
|
||||
"poor_fit_tip": "Непоследователна история на съвпаденията — помислете за възстановяване на този профил",
|
||||
"poor_fit_tip": "Непоследователна история на съвпаденията – помислете за възстановяване на този профил",
|
||||
"restart_gap_tip": "{n} HA пропуск при рестартиране: графиката на мощността има дупка",
|
||||
"reviewed": "Прегледано",
|
||||
"steady": "→ стабилен",
|
||||
@@ -87,7 +87,7 @@
|
||||
"on_cycle_finished": "При завършен цикъл",
|
||||
"on_cycle_started": "При стартиране на цикъла",
|
||||
"pause_cycle": "Пауза",
|
||||
"pause_cycle_tip": "Постави на пауза текущия цикъл — уредът ще продължи от там, където е спрял",
|
||||
"pause_cycle_tip": "Постави на пауза текущия цикъл – уредът ще продължи от там, където е спрял",
|
||||
"pg_apply_device": "Приложи към устройството",
|
||||
"pg_autofill": "Автоматично попълване",
|
||||
"play": "Възпроизведи",
|
||||
@@ -97,8 +97,8 @@
|
||||
"process_tip": "Запази записаната следа като нов или съществуващ профил",
|
||||
"rebuild": "Възстановете пликовете",
|
||||
"rebuild_envelope": "Възстановяване на плика",
|
||||
"rebuild_tip": "Преизчисли очаквания плик на мощността (мин./макс. лента) за всички профили от техните маркирани цикли — стартирай след маркиране на нови цикли или коригиране на стари",
|
||||
"rec_start_tip": "Начни запис на следата на мощността на уреда — стартирай малко преди да пуснеш цикъл",
|
||||
"rebuild_tip": "Преизчисли очаквания плик на мощността (мин./макс. лента) за всички профили от техните маркирани цикли – стартирай след маркиране на нови цикли или коригиране на стари",
|
||||
"rec_start_tip": "Начни запис на следата на мощността на уреда – стартирай малко преди да пуснеш цикъл",
|
||||
"rec_stop": "Спрете",
|
||||
"rec_stop_tip": "Спри записа и задръж записаната следа за преглед",
|
||||
"record": "Започнете запис",
|
||||
@@ -182,7 +182,7 @@
|
||||
},
|
||||
"attn_sub": "Поправете конфликтите преди запазване",
|
||||
"attn_title": "{n} конфликт{s} в настройките",
|
||||
"settings_banner": "{n} конфликт{s} в настройките — проверете маркираните раздели и поправете преди запазване.",
|
||||
"settings_banner": "{n} конфликт{s} в настройките – проверете маркираните раздели и поправете преди запазване.",
|
||||
"settings_banner_btn": "Към първия",
|
||||
"confidence": {
|
||||
"auto": "Трябва да е на или над Праг на Съвпадение ({match})",
|
||||
@@ -451,9 +451,9 @@
|
||||
"show_expected": "Показване на очакваното наслагване на крива (съвпадащ профил, оранжево)",
|
||||
"show_raw": "Показване на превключвателя за необработени данни от контакта в живия графикон на мощността",
|
||||
"sparkline": "Тенденция на продължителността на последните цикли",
|
||||
"stage2": "Етап 2 — основно сходство",
|
||||
"stage3": "Етап 3 — DTW",
|
||||
"stage4": "Етап 4 — съответствие",
|
||||
"stage2": "Етап 2 – основно сходство",
|
||||
"stage3": "Етап 3 – DTW",
|
||||
"stage4": "Етап 4 – съответствие",
|
||||
"status": "Статус",
|
||||
"tail_trim": "Подстригване на опашката",
|
||||
"timer_auto_pause": "Автоматична пауза",
|
||||
@@ -561,7 +561,12 @@
|
||||
"flags": "Маркери",
|
||||
"include_phase_map": "Включи карта на фазите",
|
||||
"include_settings": "Включи настройките",
|
||||
"show_contributor": "Покажи сътрудника"
|
||||
"show_contributor": "Покажи сътрудника",
|
||||
"task_pg_detail": "Симулиране на цикъл",
|
||||
"task_split": "Разделяне на цикъл",
|
||||
"task_trim": "Изрязване на цикъл",
|
||||
"task_merge": "Обединяване на цикли",
|
||||
"task_rebuild": "Преизчисляване на обвивките"
|
||||
},
|
||||
"log": {
|
||||
"all_levels": "Всички нива",
|
||||
@@ -645,19 +650,19 @@
|
||||
"artifact_dip_detail": "Падна под обичайния диапазон на мощността за ~{n} сек.",
|
||||
"artifact_footer": "Подчертано на графиката по-горе. Това са преходни артефакти (напр. вратата се отвори по средата на цикъла), а не непременно проблеми.",
|
||||
"artifact_header": "{n} аномалии, открити по време на този цикъл",
|
||||
"artifact_pause_detail": "Мощността падна до почти нула за ~{n} сек. и след това се възобнови — вероятно вратата е отворена по средата на цикъла или цикълът е бил поставен на пауза.",
|
||||
"artifact_pause_detail": "Мощността падна до почти нула за ~{n} сек. и след това се възобнови – вероятно вратата е отворена по средата на цикъла или цикълът е бил поставен на пауза.",
|
||||
"artifact_spike_detail": "Надвиши обичайния диапазон на мощността за ~{n} сек.",
|
||||
"auto_label_intro": "Присвояване на профили към немаркирани цикли, чиято степен на достоверност на съвпадението надвишава прага.",
|
||||
"automations_intro": "WashData задейства събития {start} / {end} и предоставя обекти, затова известията и действията най-добре се изграждат като обикновени автоматизации на Home Assistant. По-долу са показани автоматизациите, използващи това устройство.",
|
||||
"cleanup_intro": "Всеки етикетиран цикъл е насложен. Отбележете отклоненията и изтрийте, за да почистите профила.",
|
||||
"clear_debug_hint": "Премахнете съхранените данни за отстраняване на грешки, за да освободите място.",
|
||||
"collecting_data": "Събиране на данни — нужни са още {need} цикъл{plural} преди да може да започне прецизната настройка ({current}/{min}).",
|
||||
"collecting_data": "Събиране на данни – нужни са още {need} цикъл{plural} преди да може да започне прецизната настройка ({current}/{min}).",
|
||||
"compare_overlay_profiles": "Профили на наслагване (бледи)",
|
||||
"compare_profiles_tip": "Наслагнете други профилни пликове върху диаграмата по-горе, за да видите кой най-добре пасва на този цикъл.",
|
||||
"compare_selected_cycles": "Избрани цикли (плътни) — показване / скриване",
|
||||
"compare_selected_cycles": "Избрани цикли (плътни) – показване / скриване",
|
||||
"consider_new_profile": "Помислете за създаване на нов профил.",
|
||||
"coverage_gap": "последните цикли нямат съответстващ профил ({pct}% от последните 30).",
|
||||
"coverage_gap_similar_cycles": "{count} сходни немаркирани цикъла намерени — създайте профил, за да започнете тяхното съпоставяне.",
|
||||
"coverage_gap_similar_cycles": "{count} сходни немаркирани цикъла намерени – създайте профил, за да започнете тяхното съпоставяне.",
|
||||
"cycles_deleted": "Изтрити цикли: {count}",
|
||||
"enough_data": "Достатъчно данни за обучение ({current}/{min} цикъла).",
|
||||
"export_description": "Експортирайте всички профили и цикли в JSON или възстановете от предишен експорт.",
|
||||
@@ -686,7 +691,7 @@
|
||||
"ml_learned_intro": "Модели, прецизно настроени към тази машина.",
|
||||
"ml_loading": "зареждане на ML...",
|
||||
"ml_settings_intro": "Два независими превключвателя: единият прилага моделите, докато цикълът работи, другият позволява на WashData да ги прецизира към вашата машина с течение на времето.",
|
||||
"name_first_program": "Имате достатъчно цикли — наименувайте първата си програма, за да започне съвпадението.",
|
||||
"name_first_program": "Имате достатъчно цикли – наименувайте първата си програма, за да започне съвпадението.",
|
||||
"near_duplicate_cluster": "открит почти дублиращ се профилен клъстер. Групирането позволява съпоставянето надеждно да избира между сходни програми (напр. същата програма при различна температура/центрофуга).",
|
||||
"no_cycles_match": "Няма цикли, съответстващи на текущия филтър.",
|
||||
"no_cycles_profile": "Няма цикли за този профил.",
|
||||
@@ -696,7 +701,7 @@
|
||||
"no_devices": "Все още няма конфигурирани устройства WashData.",
|
||||
"no_envelope": "Все още няма плик - изградете отново след цикли на етикетиране.",
|
||||
"no_envelope_overlay": "Няма наличен плик за наслагване.",
|
||||
"no_fine_tuned": "Все още нищо фино настроено — WashData използва своите вградени модели.",
|
||||
"no_fine_tuned": "Все още нищо фино настроено – WashData използва своите вградени модели.",
|
||||
"no_logs": "Все още няма буферирани записи в журнала.",
|
||||
"no_maintenance": "Все още няма записана поддръжка.",
|
||||
"no_match_yet": "Все още няма опит за съвпадение - това се попълва по време на цикъл на изпълнение.",
|
||||
@@ -713,7 +718,7 @@
|
||||
"notify_services_hint": "Използвайте ID на услугите {entity} (разделени със запетая за повече). Променливи на шаблона: {vars}.",
|
||||
"old_actions_warning": "Конфигуриран със стария редактор на действия (вече премахнат). Те все още се задействат при събития от цикъл, но вече не могат да се редактират тук. Преобразувайте ги в нормална автоматизация или ги премахнете.",
|
||||
"onboarding_progress": "{n} / 3 наблюдавани цикъла",
|
||||
"onboarding_watching": "Оставете уреда да работи нормално — WashData наблюдава. След 3 цикъла ще започне съвпадението на програми.",
|
||||
"onboarding_watching": "Оставете уреда да работи нормално – WashData наблюдава. След 3 цикъла ще започне съвпадението на програми.",
|
||||
"pending_feedback": "Очаква се обратна връзка за откриване",
|
||||
"performance_trend": "Тенденция на ефективността ({n} цикъла)",
|
||||
"pg_analysis_empty": "Заредете цикъл, за да видите анализ на съвпадението.",
|
||||
@@ -763,7 +768,7 @@
|
||||
"setting_changed": "Променено от {old} на {new} на {date}",
|
||||
"settings_basic_note": "Показват се основните настройки. Превключете на Разширени за пълния списък.",
|
||||
"shape_drift_advisory": "⚠ Дрейф на формата",
|
||||
"shape_drift_detail": "Моделът на мощността за този профил се е изместил с времето — вероятно износване на уреда или необходима поддръжка (напр. отстраняване на котлен камък, почистване на филтъра).",
|
||||
"shape_drift_detail": "Моделът на мощността за този профил се е изместил с времето – вероятно износване на уреда или необходима поддръжка (напр. отстраняване на котлен камък, почистване на филтъра).",
|
||||
"show_all_settings": "Показване на всички настройки",
|
||||
"showing_suggestions": "Показване на {count} настройка с предложения.",
|
||||
"split_intro": "Щракнете върху графиката, за да добавите или премахнете точка на разделяне или автоматично откриване по неактивни празнини. Всеки получен сегмент може да получи свой собствен профил.",
|
||||
@@ -789,10 +794,10 @@
|
||||
"toast_revert_failed": "Отмяната е неуспешна: {error}",
|
||||
"toast_reverted": "{key} е върнато",
|
||||
"toast_save_failed": "Запазването е неуспешно: {error}",
|
||||
"trend_duration_longer": "Продължителност с по-голяма тенденция ({pct}%/цикъл) — скорошно средно {avg}",
|
||||
"trend_duration_shorter": "Продължителността се понижава ({pct}%/цикъл) — скорошно средно {avg}",
|
||||
"trend_duration_longer": "Продължителност с по-голяма тенденция ({pct}%/цикъл) – скорошно средно {avg}",
|
||||
"trend_duration_shorter": "Продължителността се понижава ({pct}%/цикъл) – скорошно средно {avg}",
|
||||
"trend_energy_down": "Енергията намалява ({pct}%/цикъл)",
|
||||
"trend_energy_up": "Тенденция към нарастване на енергията ({pct}%/цикъл) — скорошно средно {avg}",
|
||||
"trend_energy_up": "Тенденция към нарастване на енергията ({pct}%/цикъл) – скорошно средно {avg}",
|
||||
"trim_intro": "Плъзнете червените манипулатори или въведете стойности. Всичко извън прозореца се премахва.",
|
||||
"tuning_suggestions_available": "{count} предложение за настройка налично от наблюдавани цикли. Те се появяват до съответните полета.",
|
||||
"unsure_detected_prefix": "WashData не е сигурен, че е открит",
|
||||
@@ -857,7 +862,9 @@
|
||||
"share_guidelines_title": "Преди споделяне",
|
||||
"store_download_device_intro": "Изтеглете настройките на устройство от общността и ги приложете към ново или съществуващо устройство",
|
||||
"store_share_device_intro": "Споделете програмите на вашето устройство (профили + референтни цикли) с общността. Настройките са незадължителни.",
|
||||
"share_profile_no_cycles": "Профилът '{p}' няма ⭐ референтни цикли -- ще бъде пропуснат, освен ако нямате {n}+ потвърдени стартирания"
|
||||
"share_profile_no_cycles": "Профилът '{p}' няма ⭐ референтни цикли -- ще бъде пропуснат, освен ако нямате {n}+ потвърдени стартирания",
|
||||
"advisory_phase_inconsistent": "Изглежда, че '{name}' смесва различни програми или температури - циклите му загряват за много различно време. Разделянето му на отделни профили (напр. по температура) ще подобри съпоставянето и оценките на времето.",
|
||||
"advisory_phase_inconsistent_title": "⚠ Възможно смесени програми"
|
||||
},
|
||||
"phase_desc": {
|
||||
"anti_crease": "Случайни кратки движения след завършване за намаляване на бръчките.",
|
||||
@@ -940,6 +947,10 @@
|
||||
"triggers": {
|
||||
"intro": "Незадължителни външни сигнали: задействане на края, сензор за врата, превключвател за пауза и напомнянето за разтоварване.",
|
||||
"label": "Задействания и врати"
|
||||
},
|
||||
"phase_eta": {
|
||||
"label": "Оставащо време",
|
||||
"intro": "Оценка на оставащото време, съобразена с фазите, за машини, чиято продължителност на цикъла зависи от температурата или центрофугирането."
|
||||
}
|
||||
},
|
||||
"setting": {
|
||||
@@ -1023,6 +1034,10 @@
|
||||
"doc": "Фиксирана цена за kWh, използвана за стойности на разходите, когато по-горе не е зададен обект на реална цена.",
|
||||
"label": "Статична цена на енергия (на kWh)"
|
||||
},
|
||||
"energy_sensor": {
|
||||
"doc": "Незадължителен натрупващ брояч на енергия (total_increasing kWh/Wh, напр. собственият брояч за общото потребление на контакта). Когато е зададен, енергията, отчитана за всеки цикъл, се взема от разликата в показанията на този брояч между началото и края, което избягва подценяването, което се получава при интегриране на бавно докладващ сензор за мощност. Връща се към интегрираната стойност, ако показанието липсва, мерната му единица е неизвестна или разликата не е положителна. Оставете празно, за да продължите да интегрирате сензора за мощност.",
|
||||
"label": "Обект на измервателен уред за енергия"
|
||||
},
|
||||
"expose_debug_entities": {
|
||||
"doc": "Публикувайте допълнителни диагностични HA обекти (доверие на съвпадението, неяснота, вътрешно състояние). Off поддържа списъка с обекти чист за нормална употреба.",
|
||||
"label": "Изложи обекти за отстраняване на грешки"
|
||||
@@ -1305,6 +1320,38 @@
|
||||
},
|
||||
"show_contributor": {
|
||||
"doc": "Покажи името на сътрудника в профилите, изтеглени от магазина на общността"
|
||||
},
|
||||
"enable_phase_matching": {
|
||||
"label": "Оставащо време съобразено с фазите",
|
||||
"doc": "Разделя всеки активен цикъл на фази (нагряване, пране, центрофугиране) и разпределя оставащото време по фази, съчетано с класическата оценка - като разчита на разпределението по фази в началото на цикъла и на класическата оценка към края. Това персонализира обратното броене спрямо това колко всъщност загрява и работи вашата машина, което е най-осезаемо през първата половина на цикъла. Изключено = само класическата оценка. Засяга се само показването на оставащото време; съпоставянето на програми и откриването на цикли остават непроменени."
|
||||
},
|
||||
"keep_min_score": {
|
||||
"label": "Мин. резултат на съвпадение",
|
||||
"doc": "Минимален резултат на сходство, необходим на кандидата, за да остане в надпреварата. Стойността по подразбиране 0,1 е умишлено щедра - допуска дори слаби кандидати и разчита на по-късните етапи за намиране на най-доброто съвпадение. Увеличете за по-ранно отхвърляне на малко вероятни профили; намалете за разширяване на началния набор от кандидати."
|
||||
},
|
||||
"dtw_blend": {
|
||||
"label": "Смесване на деформация",
|
||||
"doc": "Колко DTW резултатът от изравняването замества основния резултат от Етап 2. 0 = използвай само резултата от Етап 2, 1 = използвай само DTW резултата, 0,5 (по подразбиране) = равно смесване. Увеличете за по-голямо разчитане на warp изравняване, когато програмите имат подобни нива на мощност, но различни времеви модели."
|
||||
},
|
||||
"dtw_ensemble_w": {
|
||||
"label": "Микс на комбинация DTW",
|
||||
"doc": "В режим на ансамбъл DTW (по подразбиране), тежест на мащабиран L1 срещу производен DTW (DDTW). 1,0 = само мащабиран L1, 0 = само DDTW, 0,7 = по подразбиране. Мащабираният вариант L1 сравнява нивата на мощност; производният вариант реагира на промените на мощността във времето. Ансамблът обединява и двете."
|
||||
},
|
||||
"dtw_ddtw_scale": {
|
||||
"label": "Скала на производна деформация",
|
||||
"doc": "Разстояние на полунасищане за оценяване с производен DTW. Резултатът се намалява наполовина, когато разстоянието DDTW е равно на тази стойност. По-малко = по-чувствително към разлики в формата. Стойността по подразбиране 30 е калибрирана за типични следи на мощност на домакински уреди. Засяга само режимите ensemble и ddtw на DTW."
|
||||
},
|
||||
"dtw_refine_top_n": {
|
||||
"label": "Брой прецизирани кандидати",
|
||||
"doc": "Колко от водещите кандидати от Етап 2 DTW преоценява. DTW е по-скъп, затова се прилага само за N-те най-добри кандидати. По подразбиране 5. Увеличете (до 7-9), ако правилният профил понякога достига само 4-то или 5-то място след Етап 2 - DTW може да го спаси. Намаляването леко ускорява съпоставянето."
|
||||
},
|
||||
"duration_scale": {
|
||||
"label": "Острота на продължителност",
|
||||
"doc": "Острота на санкцията за несъответствие на продължителността в Етап 4. Това е лог-съотношение, при което резултатът на съответствие се намалява наполовина. По-малко = по-строго: несъответствието на продължителността снижава резултата повече. Стойността по подразбиране 0,175 съответства на толеранс на продължителността от около 18% при половинна тежест. Комбинирайте с Тежестта на продължителността."
|
||||
},
|
||||
"energy_scale": {
|
||||
"label": "Острота на енергия",
|
||||
"doc": "Острота на санкцията за несъответствие на енергията в Етап 4. По-малко = по-строго: несъответствието на енергията снижава резултата повече. Стойността по подразбиране 0,25 е умишлено по-щедра от Остротата на продължителността, тъй като енергията варира с натоварването. Комбинирайте с Тежестта на енергията."
|
||||
}
|
||||
},
|
||||
"setting_group": {
|
||||
@@ -1553,24 +1600,24 @@
|
||||
"lower": "Означава повече цикли автоматично; някои може да са грешно идентифицирани"
|
||||
},
|
||||
"duration_tolerance": {
|
||||
"higher": "Приема по-широк диапазон на продължителност — по-гъвкаво съвпадение",
|
||||
"lower": "Изисква по-точно съвпадение на продължителността — по-строго, но може да отхвърли необичайни цикли"
|
||||
"higher": "Приема по-широк диапазон на продължителност – по-гъвкаво съвпадение",
|
||||
"lower": "Изисква по-точно съвпадение на продължителността – по-строго, но може да отхвърли необичайни цикли"
|
||||
},
|
||||
"end_energy_threshold": {
|
||||
"higher": "Затваря само цикли, използвали значителна енергия",
|
||||
"lower": "Затваря и по-кратки или по-малко енергийни цикли"
|
||||
},
|
||||
"end_repeat_count": {
|
||||
"higher": "Изисква сигналът за край да се повтори повече пъти — по-надеждно, малко по-бавно",
|
||||
"lower": "Завършва след по-малко повторения — по-бързо откриване, по-висок риск от фалшиво завършване"
|
||||
"higher": "Изисква сигналът за край да се повтори повече пъти – по-надеждно, малко по-бавно",
|
||||
"lower": "Завършва след по-малко повторения – по-бързо откриване, по-висок риск от фалшиво завършване"
|
||||
},
|
||||
"learning_confidence": {
|
||||
"higher": "Учи само от много уверени съвпадения — по-бавно, но по-надеждно",
|
||||
"higher": "Учи само от много уверени съвпадения – по-бавно, но по-надеждно",
|
||||
"lower": "Учи от повече цикли; моделът може да е по-зашумен"
|
||||
},
|
||||
"min_off_gap": {
|
||||
"higher": "Необходим е по-дълъг период на неактивност преди нов цикъл",
|
||||
"lower": "Кратък период на неактивност стартира нов цикъл — последователните работи може да се разделят"
|
||||
"lower": "Кратък период на неактивност стартира нов цикъл – последователните работи може да се разделят"
|
||||
},
|
||||
"min_power": {
|
||||
"higher": "По-малко чувствителен към фоновата консумация; може да пропусне тихи програми",
|
||||
@@ -1581,24 +1628,24 @@
|
||||
"lower": "По-бързо принудително спиране на заседнал цикъл"
|
||||
},
|
||||
"off_delay": {
|
||||
"higher": "Повече време за паузи на уреда — справя се с дълги накисвания или сушене",
|
||||
"lower": "По-бързо засичане на края — подходящо за уреди с ясно вкл./изкл."
|
||||
"higher": "Повече време за паузи на уреда – справя се с дълги накисвания или сушене",
|
||||
"lower": "По-бързо засичане на края – подходящо за уреди с ясно вкл./изкл."
|
||||
},
|
||||
"profile_match_threshold": {
|
||||
"higher": "Потвърждава само съвпадения с висока увереност; повече цикли остават без етикет",
|
||||
"lower": "Съпоставя повече цикли; някои може да са леко грешни"
|
||||
},
|
||||
"running_dead_zone": {
|
||||
"higher": "Игнорира кратките скокове на мощност в режим на готовност — по-малко чувствителен към шум",
|
||||
"lower": "Реагира на по-кратки изблици на мощност — улавя бързи преходни активности"
|
||||
"higher": "Игнорира кратките скокове на мощност в режим на готовност – по-малко чувствителен към шум",
|
||||
"lower": "Реагира на по-кратки изблици на мощност – улавя бързи преходни активности"
|
||||
},
|
||||
"start_threshold_w": {
|
||||
"higher": "Избягва фалшиви стартове от кратковременни скокове на мощност",
|
||||
"lower": "Улавя програми с ниска мощност; може да се задейства от смущения"
|
||||
},
|
||||
"stop_threshold_w": {
|
||||
"higher": "Завършва цикъла по-бързо — може да затвори при пауза",
|
||||
"lower": "Изчаква по-дълго за завършване — по-малко преждевременни завършвания"
|
||||
"higher": "Завършва цикъла по-бързо – може да затвори при пауза",
|
||||
"lower": "Изчаква по-дълго за завършване – по-малко преждевременни завършвания"
|
||||
},
|
||||
"watchdog_interval": {
|
||||
"higher": "Разрешени по-дълги тихи фази; по-малко фалшиви принудни спирания",
|
||||
@@ -1676,12 +1723,19 @@
|
||||
"start_duration_threshold": "Секунди над прага за потвърждаване на старта",
|
||||
"start_threshold_w": "Минимални ватове, за да се счита за стартирал",
|
||||
"stop_threshold_w": "Под тази стойност машината се счита за изключена",
|
||||
"dtw_bandwidth": "Колко разтягане във времето допуска съпоставянето по форма",
|
||||
"corr_weight": "Тегло на формата на кривата спрямо нивото на мощността при съпоставянето",
|
||||
"duration_weight": "Колко съвпадението по продължителност влияе на съпоставянето",
|
||||
"energy_weight": "Колко съвпадението по енергия влияе на съпоставянето",
|
||||
"profile_match_min_duration_ratio": "Най-краткото изпълнение (спрямо профила), което все още може да съвпадне",
|
||||
"profile_match_max_duration_ratio": "Най-дългото изпълнение (спрямо профила), което все още може да съвпадне"
|
||||
"dtw_bandwidth": "Етап 3: лента за деформация на Sakoe-Chiba (0 = DTW изключено; по подразбиране 0,2 = 20% от дължината на цикъла)",
|
||||
"corr_weight": "Етап 2: баланс между формата на кривата (корелация) и нивото на мощността (MAE); по подразбиране 0,45",
|
||||
"duration_weight": "Етап 4: колко силно съответствието на продължителността влияе върху крайния резултат (по подразбиране 0,22)",
|
||||
"energy_weight": "Етап 4: колко силно съответствието на енергията влияе върху крайния резултат (по подразбиране 0,22)",
|
||||
"profile_match_min_duration_ratio": "Етап 1: минимална дължина на цикъла като дял от продължителността на профила; по подразбиране 0,1 (10%)",
|
||||
"profile_match_max_duration_ratio": "Етап 1: максимална дължина на цикъла като дял от продължителността на профила; по подразбиране 1,5 (150%)",
|
||||
"keep_min_score": "Етап 2: минимален резултат за оставане в надпреварата; по подразбиране 0,1 допуска слаби съвпадения, по-късните етапи избират най-доброто",
|
||||
"dtw_blend": "Етап 3: 0 = само основен резултат, 1 = само DTW резултат, 0,5 = равно смесване (по подразбиране)",
|
||||
"dtw_ensemble_w": "Етап 3 (режим на ансамбъл): тежест на мащабиран L1 срещу производен DTW; по подразбиране 0,7 дава предимство на нивото",
|
||||
"dtw_ddtw_scale": "Етап 3: разстояние на полунасищане на DDTW; по-малко = по-чувствително към форма (по подразбиране 30)",
|
||||
"dtw_refine_top_n": "Етап 3: кандидати, преоценени от DTW; увеличете до 7-9, ако правилният профил заема 4.-5. място (по подразбиране 5)",
|
||||
"duration_scale": "Етап 4: лог-съотношение, при което съответствието на продължителността се намалява наполовина; по-малко = по-строга санкция (по подразбиране 0,175)",
|
||||
"energy_scale": "Етап 4: лог-съотношение, при което съответствието на енергията се намалява наполовина; по-малко = по-строга санкция (по подразбиране 0,25)"
|
||||
},
|
||||
"col": {
|
||||
"profile_tip": "Име на съпоставената програма. „Без етикет“ означава, че в края на цикъла не е съвпаднал нито един профил.",
|
||||
@@ -1766,6 +1820,69 @@
|
||||
},
|
||||
"pg_sweep": {
|
||||
"optimize": "Оптимизиране: {param}"
|
||||
},
|
||||
"pg_detail": {
|
||||
"simulate": "Симулиране на цикъл"
|
||||
},
|
||||
"split": {
|
||||
"apply": "Разделяне на цикъл"
|
||||
},
|
||||
"trim": {
|
||||
"apply": "Изрязване на цикъл"
|
||||
},
|
||||
"merge": {
|
||||
"apply": "Обединяване на цикли"
|
||||
},
|
||||
"rebuild": {
|
||||
"envelopes": "Преизчисляване на обвивките"
|
||||
},
|
||||
"cancelling": "Отмяна..."
|
||||
},
|
||||
"setup": {
|
||||
"hdr": {
|
||||
"card": "Настройка на устройството",
|
||||
"healthy_chip": "Настройката е завършена"
|
||||
},
|
||||
"phase0": {
|
||||
"washer": "WashData вече открива вашите цикли. Запишете първия цикъл, за да активирате имена на програми и прогнози за времето.",
|
||||
"dishwasher": "WashData наблюдава. Съдомиялните машини имат сложни цикли – записването на първия цикъл е настоятелно препоръчително. Ако открит цикъл тече прекалено дълго, използвайте редактора на цикли, за да го изрежете преди запазване като профил.",
|
||||
"generic": "WashData наблюдава. Запишете или маркирайте открит цикъл, за да започнете да изграждате профили."
|
||||
},
|
||||
"phase1a": {
|
||||
"labelled": "Добро начало – вашата първа програма е запазена. За най-чисти данни обмислете записването на следващия цикъл с джаджата за запис."
|
||||
},
|
||||
"phase1b": {
|
||||
"recorded": "Вашият запис е запазен като {profile_name}. Сега запишете или маркирайте другите чести програми, за да разширите покритието."
|
||||
},
|
||||
"phase1c": {
|
||||
"verify": "Имате {count} програми от общността. Стартирайте цикъл, за да проверите дали WashData ги разпознава правилно – съвпадението ще се подобрява с натрупването на собствена история от устройството."
|
||||
},
|
||||
"phase2": {
|
||||
"cluster": "WashData е видял {count} цикъла, които не съответстват на нито една запазена програма – те си приличат. Искате ли да създадете нов профил за тях?",
|
||||
"unmatched": "Последният ви цикъл не съответства на нито една запазена програма. Това нова програма ли е?"
|
||||
},
|
||||
"phase3": {
|
||||
"suggestions": "WashData има препоръки за настройки въз основа на историята на вашите цикли – прегледайте ги за подобряване на точността на разпознаване.",
|
||||
"groups": "Някои от профилите ви изглеждат като една и съща програма при различни температури. Организирайте ги в група за по-добро съвпадение.",
|
||||
"phases": "Добавете фази на програмата към {profile_name} за по-точни прогнози за оставащото време."
|
||||
},
|
||||
"phase4": {
|
||||
"healthy": "Това устройство е напълно настроено ({profile_count} профила)."
|
||||
},
|
||||
"cta": {
|
||||
"start_recording": "Стартирай запис",
|
||||
"label_detected_cycle": "Вече имам открит цикъл – маркирай го вместо това",
|
||||
"browse_cycles": "Преглед на цикли за маркиране на следващ",
|
||||
"view_profiles": "Вижте вашите профили",
|
||||
"create_from_cluster": "Създай профил от тези цикли",
|
||||
"create_profile": "Създай за него профил",
|
||||
"review_suggestions": "Прегледай препоръките",
|
||||
"organise_profiles": "Организирай профилите",
|
||||
"configure_phases": "Конфигурирай фазите",
|
||||
"skip_step": "Пропусни тази стъпка",
|
||||
"skip_forever": "Не показвай отново",
|
||||
"hide_guidance": "Скрий насоките",
|
||||
"show_guidance": "Покажи насоките"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
{
|
||||
"badge": {
|
||||
"artifact_tip": "Otkrivene su {n} anomalije (npr. vrata otvorena sredinom ciklusa) — otvorite da ih vidite na grafikonu",
|
||||
"artifact_tip": "Otkrivene su {n} anomalije (npr. vrata otvorena sredinom ciklusa) – otvorite da ih vidite na grafikonu",
|
||||
"auto": "(automatski otkriveno)",
|
||||
"built_in_tag": "ugrađen",
|
||||
"declining": "↘ u opadanju",
|
||||
"energy_low": "Niža potrošnja energije nego inače",
|
||||
"energy_spike": "Viša potrošnja energije nego inače",
|
||||
"fair_fit": "prihvatljiva kvaliteta",
|
||||
"fair_fit_tip": "Umjerena konzistentnost podudaranja — neki ciklusi dodijeljeni ovom profilu imaju niže rezultate pouzdanosti. Označite više ciklusa ili ponovo snimite profil da biste poboljšali preciznost.",
|
||||
"fair_fit_tip": "Umjerena konzistentnost podudaranja – neki ciklusi dodijeljeni ovom profilu imaju niže rezultate pouzdanosti. Označite više ciklusa ili ponovo snimite profil da biste poboljšali preciznost.",
|
||||
"feedback_requested": "Zatražena je povratna informacija",
|
||||
"golden_cycle": "Snimljeni referentni ciklus",
|
||||
"improving": "↗ poboljšanje",
|
||||
@@ -87,7 +87,7 @@
|
||||
"on_cycle_finished": "Završen ciklus",
|
||||
"on_cycle_started": "Započeo ciklus",
|
||||
"pause_cycle": "Pauza",
|
||||
"pause_cycle_tip": "Pauzirajte aktivni ciklus — uređaj će se nastaviti od mjesta na kojem je stao",
|
||||
"pause_cycle_tip": "Pauzirajte aktivni ciklus – uređaj će se nastaviti od mjesta na kojem je stao",
|
||||
"pg_apply_device": "Primijeni na uređaj",
|
||||
"pg_autofill": "Automatsko popunjavanje",
|
||||
"play": "Reproduciraj",
|
||||
@@ -97,8 +97,8 @@
|
||||
"process_tip": "Sačuvajte snimljeni trag kao novi ili postojeći profil",
|
||||
"rebuild": "Obnovi koverte",
|
||||
"rebuild_envelope": "Obnovi kovertu",
|
||||
"rebuild_tip": "Preračunajte očekivanu kovertu snage (min/maks pojas) za sve profile iz njihovih označenih ciklusa — pokrenite nakon označavanja novih ciklusa ili ispravljanja starih",
|
||||
"rec_start_tip": "Počnite snimanje traga snage uređaja — pokrenite neposredno prije pokretanja ciklusa",
|
||||
"rebuild_tip": "Preračunajte očekivanu kovertu snage (min/maks pojas) za sve profile iz njihovih označenih ciklusa – pokrenite nakon označavanja novih ciklusa ili ispravljanja starih",
|
||||
"rec_start_tip": "Počnite snimanje traga snage uređaja – pokrenite neposredno prije pokretanja ciklusa",
|
||||
"rec_stop": "Zaustavi",
|
||||
"rec_stop_tip": "Zaustavite snimanje i zadržite snimljeni trag radi pregleda",
|
||||
"record": "Započni snimanje",
|
||||
@@ -231,7 +231,7 @@
|
||||
"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": "{n} konflikt{s} postavki – provjerite istaknute sekcije i ispravite prije pohrane.",
|
||||
"settings_banner_btn": "Idi na prvi"
|
||||
},
|
||||
"hdr": {
|
||||
@@ -451,9 +451,9 @@
|
||||
"show_expected": "Prikaži očekivani prekrivač krivulje (podudarni profil, narandžasta)",
|
||||
"show_raw": "Prikaži prekidač sirovih očitanja utičnice u živom grafu snage",
|
||||
"sparkline": "Trend trajanja posljednjih ciklusa",
|
||||
"stage2": "Faza 2 — osnovna sličnost",
|
||||
"stage3": "Faza 3 — DTW",
|
||||
"stage4": "Faza 4 — slaganje",
|
||||
"stage2": "Faza 2 – osnovna sličnost",
|
||||
"stage3": "Faza 3 – DTW",
|
||||
"stage4": "Faza 4 – slaganje",
|
||||
"status": "Status",
|
||||
"tail_trim": "Obrub repa (s)",
|
||||
"timer_auto_pause": "Automatska pauza",
|
||||
@@ -561,7 +561,12 @@
|
||||
"flags": "Oznake",
|
||||
"include_phase_map": "Uključi mapu faza",
|
||||
"include_settings": "Uključi postavke",
|
||||
"show_contributor": "Prikaži doprinositelja"
|
||||
"show_contributor": "Prikaži doprinositelja",
|
||||
"task_pg_detail": "Simuliraj ciklus",
|
||||
"task_split": "Dijeljenje ciklusa",
|
||||
"task_trim": "Obrezivanje ciklusa",
|
||||
"task_merge": "Spajanje ciklusa",
|
||||
"task_rebuild": "Ponovna izgradnja omotača"
|
||||
},
|
||||
"log": {
|
||||
"all_levels": "Svi nivoi",
|
||||
@@ -645,7 +650,7 @@
|
||||
"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.",
|
||||
"artifact_header": "{n} anomalija otkrivenih tokom ovog ciklusa",
|
||||
"artifact_pause_detail": "Snaga je pala na gotovo nulu za ~{n}s, a zatim se nastavila — vjerovatno su vrata otvorena sredinom ciklusa ili je ciklus pauziran.",
|
||||
"artifact_pause_detail": "Snaga je pala na gotovo nulu za ~{n}s, a zatim se nastavila – vjerovatno su vrata otvorena sredinom ciklusa ili je ciklus pauziran.",
|
||||
"artifact_spike_detail": "Prešao iznad uobičajenog pojasa snage za ~{n}s.",
|
||||
"auto_label_intro": "Dodijelite profile neoznačenim ciklusima čija pouzdanost podudaranja briše prag.",
|
||||
"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.",
|
||||
@@ -654,10 +659,10 @@
|
||||
"collecting_data": "Prikupljanje podataka: još {need} ciklusa do početka finog podešavanja ({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",
|
||||
"compare_selected_cycles": "Odabrani ciklusi (puni) – prikaži / sakrij",
|
||||
"consider_new_profile": "Razmislite o kreiranju novog profila.",
|
||||
"coverage_gap": "nedavni ciklusi nemaju odgovarajući profil ({pct}% od posljednjih 30).",
|
||||
"coverage_gap_similar_cycles": "Pronađeno {count} sličnih neoznačenih ciklusa — kreirajte profil da počnete s njihovim uparivanjem.",
|
||||
"coverage_gap_similar_cycles": "Pronađeno {count} sličnih neoznačenih ciklusa – kreirajte profil da počnete s njihovim uparivanjem.",
|
||||
"cycles_deleted": "Izbrisano ciklusa: {count}",
|
||||
"enough_data": "Dovoljno podataka za učenje ({current}/{min} ciklusa).",
|
||||
"export_description": "Izvezite sve profile i cikluse u JSON ili vratite iz prethodnog izvoza.",
|
||||
@@ -686,7 +691,7 @@
|
||||
"ml_learned_intro": "Modeli fino prilagođeni ovoj mašini.",
|
||||
"ml_loading": "učitavanje ML-a…",
|
||||
"ml_settings_intro": "Dva nezavisna prekidača: jedan primenjuje modele dok ciklus traje, drugi omogućava WashData da ih fino podesi prema vašoj mašini tokom vremena.",
|
||||
"name_first_program": "Imate dovoljno ciklusa — imenujte svoj prvi program da započnete podudaranje.",
|
||||
"name_first_program": "Imate dovoljno ciklusa – imenujte svoj prvi program da započnete podudaranje.",
|
||||
"near_duplicate_cluster": "otkriven skoro duplirani klaster profila. Grupisanje omogućava pouzdano uparivanje biranja između sličnih (npr. isti program na različitoj temperaturi/centrifikaciji).",
|
||||
"no_cycles_match": "Nijedan ciklus ne odgovara trenutnom filteru.",
|
||||
"no_cycles_profile": "Nema ciklusa za ovaj profil.",
|
||||
@@ -696,7 +701,7 @@
|
||||
"no_devices": "Još nema konfiguriranih uređaja WashData.",
|
||||
"no_envelope": "Još nema koverte - obnovite nakon ciklusa označavanja.",
|
||||
"no_envelope_overlay": "Nema dostupne koverte za preklapanje.",
|
||||
"no_fine_tuned": "Još ništa fino podešeno — WashData koristi svoje ugrađene modele.",
|
||||
"no_fine_tuned": "Još ništa fino podešeno – WashData koristi svoje ugrađene modele.",
|
||||
"no_logs": "Još uvijek nema memorisanih zapisa dnevnika.",
|
||||
"no_maintenance": "Održavanje još nije zabilježeno.",
|
||||
"no_match_yet": "Još nema pokušaja podudaranja - ovo se popunjava tokom ciklusa trčanja.",
|
||||
@@ -713,7 +718,7 @@
|
||||
"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.",
|
||||
"onboarding_progress": "{n} / 3 ciklusa promatrano",
|
||||
"onboarding_watching": "Pustite uređaj da radi normalno — WashData prati. Nakon 3 ciklusa počinje podudaranje programa.",
|
||||
"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",
|
||||
"performance_trend": "Trend performansi ({n} ciklusa)",
|
||||
"pg_analysis_empty": "Učitajte ciklus da vidite analizu podudaranja.",
|
||||
@@ -763,7 +768,7 @@
|
||||
"setting_changed": "Promijenjeno sa {old} na {new} dana {date}",
|
||||
"settings_basic_note": "Prikazuju se osnovne postavke. Prebacite na Napredno za potpunu listu.",
|
||||
"shape_drift_advisory": "⚠ Drift oblika",
|
||||
"shape_drift_detail": "Obrazac snage za ovaj profil je promijenjen tokom vremena — mogući habanje uređaja ili potrebno održavanje (npr. uklanjanje kamenca, čišćenje filtera).",
|
||||
"shape_drift_detail": "Obrazac snage za ovaj profil je promijenjen tokom vremena – mogući habanje uređaja ili potrebno održavanje (npr. uklanjanje kamenca, čišćenje filtera).",
|
||||
"show_all_settings": "Prikaži sve postavke",
|
||||
"showing_suggestions": "Prikazana je postavka {count} s prijedlozima.",
|
||||
"split_intro": "Kliknite na grafikon da biste dodali ili uklonili tačku razdvajanja, ili automatsko otkrivanje po prazninama u mirovanju. Svaki rezultujući segment može dobiti svoj profil.",
|
||||
@@ -789,10 +794,10 @@
|
||||
"toast_revert_failed": "Povrat neuspješan: {error}",
|
||||
"toast_reverted": "{key} vraćeno",
|
||||
"toast_save_failed": "Snimanje neuspješno: {error}",
|
||||
"trend_duration_longer": "Trajanje u trendu duže ({pct}%/ciklus) — nedavno prosječno {avg}",
|
||||
"trend_duration_shorter": "Trajanje trenda kraće ({pct}%/ciklus) — nedavno prosječno {avg}",
|
||||
"trend_duration_longer": "Trajanje u trendu duže ({pct}%/ciklus) – nedavno prosječno {avg}",
|
||||
"trend_duration_shorter": "Trajanje trenda kraće ({pct}%/ciklus) – nedavno prosječno {avg}",
|
||||
"trend_energy_down": "Opadanje energije ({pct}%/ciklus)",
|
||||
"trend_energy_up": "Energetski trend porasta ({pct}%/ciklus) — nedavni prosjek {avg}",
|
||||
"trend_energy_up": "Energetski trend porasta ({pct}%/ciklus) – nedavni prosjek {avg}",
|
||||
"trim_intro": "Prevucite crvene ručke ili unesite vrijednosti. Sve van prozora je uklonjeno.",
|
||||
"tuning_suggestions_available": "{count} prijedlog podešavanja dostupan je iz posmatranih ciklusa. Pojavljuju se pored relevantnih polja.",
|
||||
"unsure_detected_prefix": "WashData nije siguran da je otkriven",
|
||||
@@ -857,7 +862,9 @@
|
||||
"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"
|
||||
"share_profile_no_cycles": "Profil '{p}' nema ⭐ referentnih ciklusa -- bit će preskočen osim ako nemate {n}+ potvrđenih pokretanja",
|
||||
"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"
|
||||
},
|
||||
"phase_desc": {
|
||||
"anti_crease": "Povremena kratka spuštanja nakon završetka za smanjenje bora.",
|
||||
@@ -940,6 +947,10 @@
|
||||
"triggers": {
|
||||
"intro": "Opcioni vanjski signali: okidač kraja, senzor vrata, prekidač za pauzu i podsjetnik za istovar.",
|
||||
"label": "Okidači i vrata"
|
||||
},
|
||||
"phase_eta": {
|
||||
"label": "Preostalo vrijeme",
|
||||
"intro": "Preostalo vrijeme koje uzima u obzir faze, za uređaje čija dužina ciklusa ovisi o temperaturi ili centrifugi."
|
||||
}
|
||||
},
|
||||
"setting": {
|
||||
@@ -1023,6 +1034,10 @@
|
||||
"doc": "Fiksna cijena po kWh koja se koristi za brojke troškova kada nije postavljen nijedan entitet cijene uživo iznad.",
|
||||
"label": "Statična cijena energije (po kWh)"
|
||||
},
|
||||
"energy_sensor": {
|
||||
"doc": "Opcionalno kumulativno brojilo energije (total_increasing kWh/Wh, npr. vlastito brojilo ukupne potrošnje utičnice). Kada je postavljeno, energija prijavljena za svaki ciklus uzima se iz razlike očitanja ovog brojila između početka i kraja, čime se izbjegava podbrojavanje koje nastaje integriranjem sporo izvještavajućeg senzora snage. Vraća se na integriranu vrijednost ako očitanje nedostaje, njegova jedinica je nepoznata ili razlika nije pozitivna. Ostavite prazno da nastavite integrirati senzor snage.",
|
||||
"label": "Entitet brojila energije"
|
||||
},
|
||||
"expose_debug_entities": {
|
||||
"doc": "Objavite dodatne dijagnostičke HA entitete (pouzdanost podudaranja, dvosmislenost, unutrašnje karakteristike stanja). Isključeno održava listu entiteta čistom za normalnu upotrebu.",
|
||||
"label": "Izložiti entitete za otklanjanje grešaka"
|
||||
@@ -1305,6 +1320,38 @@
|
||||
},
|
||||
"show_contributor": {
|
||||
"doc": "Prikaži ime doprinositelja na profilima preuzetim iz prodavnice zajednice"
|
||||
},
|
||||
"enable_phase_matching": {
|
||||
"label": "Preostalo vrijeme prema fazama",
|
||||
"doc": "Svaki aktivni ciklus dijeli na faze (grijanje, pranje, centrifuga) i raspoređuje preostalo vrijeme po fazama, spojeno s klasičnom procjenom - na početku ciklusa oslanja se na budžet faza, a pri kraju na klasičnu procjenu. To prilagođava odbrojavanje tome koliko se vaš uređaj stvarno grije i radi, što je najuočljivije u prvoj polovini ciklusa. Isključeno = samo klasična procjena. Utječe samo na prikaz preostalog vremena; podudaranje programa i detekcija ciklusa ostaju nepromijenjeni."
|
||||
},
|
||||
"keep_min_score": {
|
||||
"label": "Min. ocjena podudaranja",
|
||||
"doc": "Minimalna ocjena sličnosti potrebna kandidatu za ostanak u utrci podudaranja. Zadana vrijednost 0,1 je namjerno blaga - dopušta čak i slabe kandidate i oslanja se na kasnijе faze za pronalazak najboljeg podudaranja. Povećajte za ranije odbacivanje neprobabilnih profila; smanjite za proširenje početnog skupa kandidata."
|
||||
},
|
||||
"dtw_blend": {
|
||||
"label": "Miješanje deformacije",
|
||||
"doc": "Koliko DTW ocjena poravnanja zamjenjuje osnovnu ocjenu Faze 2. 0 = koristi samo ocjenu Faze 2, 1 = koristi samo DTW ocjenu, 0,5 (zadano) = jednako miješanje. Povećajte za veće oslanjanje na warp poravnanje kada programi imaju slične nivoe snage ali različite obrasce tajminga."
|
||||
},
|
||||
"dtw_ensemble_w": {
|
||||
"label": "Miks kombinacije DTW",
|
||||
"doc": "U kombiniranom DTW načinu (zadanom), težina skaliranog L1 nasuprot derivatnog DTW (DDTW). 1,0 = sve skalirano L1, 0 = sve DDTW, 0,7 = zadano. Skalirana L1 varijanta uspoređuje nivoe snage; derivatna varijanta reagira na promjene snage kroz vrijeme. Kombinirani način spaja oboje."
|
||||
},
|
||||
"dtw_ddtw_scale": {
|
||||
"label": "Skala derivatne deformacije",
|
||||
"doc": "Udaljenost polu-zasićenja za ocjenjivanje derivatnim DTW. Ocjena se prepolovi kada je DDTW udaljenost jednaka ovoj vrijednosti. Manje = osjetljivije na razlike u obliku. Zadana vrijednost 30 je kalibrirana za tipične tragove snage kućanskih uređaja. Utječe samo na kombinirani i ddtw DTW način."
|
||||
},
|
||||
"dtw_refine_top_n": {
|
||||
"label": "Broj preciziranih kandidata",
|
||||
"doc": "Koliko prvih kandidata Faze 2 DTW ponovo ocjenjuje. DTW je skuplji pa se primjenjuje samo na N najboljih kandidata. Zadano 5. Povećajte (na 7-9) ako ispravni profil ponekad dostigne samo 4. ili 5. mjesto nakon Faze 2 - DTW ga može spasiti. Smanjenje malo ubrzava podudaranje."
|
||||
},
|
||||
"duration_scale": {
|
||||
"label": "Ostrina trajanja",
|
||||
"doc": "Oštrina kazne za nepodudaranje trajanja u Fazi 4. Ovo je omjer logaritma pri kojemu se ocjena slaganja prepolovi. Manje = strože: nepodudaranje trajanja više snižava ocjenu. Zadana vrijednost 0,175 odgovara toleranciji trajanja od oko 18% pri polu-težini. Koristite zajedno s Težinom trajanja."
|
||||
},
|
||||
"energy_scale": {
|
||||
"label": "Ostrina energije",
|
||||
"doc": "Oštrina kazne za nepodudaranje energije u Fazi 4. Manje = strože: nepodudaranje energije više snižava ocjenu. Zadana vrijednost 0,25 je namjerno blaža od Oštrine trajanja jer energija varira s opterećenjem. Koristite zajedno s Težinom energije."
|
||||
}
|
||||
},
|
||||
"setting_group": {
|
||||
@@ -1424,24 +1471,24 @@
|
||||
"lower": "Više ciklusa se automatski označava; neki mogu biti pogrešno identificirani"
|
||||
},
|
||||
"duration_tolerance": {
|
||||
"higher": "Prihvata širi raspon trajanja — fleksibilnije podudaranje",
|
||||
"lower": "Zahtijeva bliže podudaranje trajanja — strože, ali može odbiti neobične cikluse"
|
||||
"higher": "Prihvata širi raspon trajanja – fleksibilnije podudaranje",
|
||||
"lower": "Zahtijeva bliže podudaranje trajanja – strože, ali može odbiti neobične cikluse"
|
||||
},
|
||||
"end_energy_threshold": {
|
||||
"higher": "Zatvara samo cikluse sa značajnom potrošnjom energije",
|
||||
"lower": "Zatvara i kraće ili manje energetske cikluse"
|
||||
},
|
||||
"end_repeat_count": {
|
||||
"higher": "Zahtijeva više ponavljanja signala kraja — pouzdanije, malo sporije",
|
||||
"lower": "Završava nakon manje ponavljanja — brže otkrivanje, veći rizik lažnog završetka"
|
||||
"higher": "Zahtijeva više ponavljanja signala kraja – pouzdanije, malo sporije",
|
||||
"lower": "Završava nakon manje ponavljanja – brže otkrivanje, veći rizik lažnog završetka"
|
||||
},
|
||||
"learning_confidence": {
|
||||
"higher": "Uči samo iz visoko pouzdanih podudaranja — sporije, ali pouzdanije",
|
||||
"higher": "Uči samo iz visoko pouzdanih podudaranja – sporije, ali pouzdanije",
|
||||
"lower": "Uči iz više ciklusa; model može biti manje precizan"
|
||||
},
|
||||
"min_off_gap": {
|
||||
"higher": "Potreban je duži odmor prije početka novog ciklusa",
|
||||
"lower": "Kratak odmor pokreće novi ciklus — uzastopni ciklusi se mogu razdijeliti"
|
||||
"lower": "Kratak odmor pokreće novi ciklus – uzastopni ciklusi se mogu razdijeliti"
|
||||
},
|
||||
"min_power": {
|
||||
"higher": "Manje osjetljiv na potrošnju u mirovanju; može propustiti tihe programe",
|
||||
@@ -1452,24 +1499,24 @@
|
||||
"lower": "Zaglavljeni ciklus se prisilno zaustavlja ranije"
|
||||
},
|
||||
"off_delay": {
|
||||
"higher": "Više vremena za pauze uređaja — prikladno za duge faze namakanja ili sušenja",
|
||||
"lower": "Brže otkrivanje kraja — dobro za uređaje s čistim uključivanjem/isključivanjem"
|
||||
"higher": "Više vremena za pauze uređaja – prikladno za duge faze namakanja ili sušenja",
|
||||
"lower": "Brže otkrivanje kraja – dobro za uređaje s čistim uključivanjem/isključivanjem"
|
||||
},
|
||||
"profile_match_threshold": {
|
||||
"higher": "Potvrđuje samo visoko pouzdana podudaranja; više ciklusa ostaje neoznačeno",
|
||||
"lower": "Podudara više ciklusa; neki mogu biti blago pogrešni"
|
||||
},
|
||||
"running_dead_zone": {
|
||||
"higher": "Zanemaruje kratke skokove snage tokom mirovanja — manje osjetljiv na šum",
|
||||
"lower": "Reagira na kraće impulse snage — otkriva brzu prolaznu aktivnost"
|
||||
"higher": "Zanemaruje kratke skokove snage tokom mirovanja – manje osjetljiv na šum",
|
||||
"lower": "Reagira na kraće impulse snage – otkriva brzu prolaznu aktivnost"
|
||||
},
|
||||
"start_threshold_w": {
|
||||
"higher": "Sprečava lažne startove od kratkih skokova snage",
|
||||
"lower": "Otkriva programe s niskom snagom; može reagirati na šum"
|
||||
},
|
||||
"stop_threshold_w": {
|
||||
"higher": "Završava ciklus brže — može zatvoriti tokom pauze",
|
||||
"lower": "Dulje čeka na završetak — manje prijevremenih završetaka"
|
||||
"higher": "Završava ciklus brže – može zatvoriti tokom pauze",
|
||||
"lower": "Dulje čeka na završetak – manje prijevremenih završetaka"
|
||||
},
|
||||
"watchdog_interval": {
|
||||
"higher": "Dopušta dulje tihe faze; manje lažnih prisilnih zaustavljanja",
|
||||
@@ -1676,12 +1723,19 @@
|
||||
"start_duration_threshold": "Sekundi iznad praga za potvrdu pokretanja",
|
||||
"start_threshold_w": "Minimum vati da bi se računalo kao pokrenuto",
|
||||
"stop_threshold_w": "Ispod ovoga mašina se računa kao isključena",
|
||||
"dtw_bandwidth": "Koliko vremenskog izobličenja dopušta podudaranje oblika",
|
||||
"corr_weight": "Težina oblika krive u odnosu na nivo snage pri podudaranju",
|
||||
"duration_weight": "Koliko slaganje trajanja utječe na podudaranje",
|
||||
"energy_weight": "Koliko slaganje potrošnje energije utječe na podudaranje",
|
||||
"profile_match_min_duration_ratio": "Najkraće izvođenje (u odnosu na profil) koje se još može podudarati",
|
||||
"profile_match_max_duration_ratio": "Najduže izvođenje (u odnosu na profil) koje se još može podudarati"
|
||||
"dtw_bandwidth": "Faza 3: warp opseg Sakoe-Chiba (0 = DTW isključen; zadano 0,2 = 20% dužine ciklusa)",
|
||||
"corr_weight": "Faza 2: ravnoteža između oblika krivulje (korelacija) i nivoa snage (MAE); zadano 0,45",
|
||||
"duration_weight": "Faza 4: koliko jako slaganje trajanja utječe na konačnu ocjenu (zadano 0,22)",
|
||||
"energy_weight": "Faza 4: koliko jako slaganje energije utječe na konačnu ocjenu (zadano 0,22)",
|
||||
"profile_match_min_duration_ratio": "Faza 1: minimalna dužina ciklusa kao udio trajanja profila; zadano 0,1 (10%)",
|
||||
"profile_match_max_duration_ratio": "Faza 1: maksimalna dužina ciklusa kao udio trajanja profila; zadano 1,5 (150%)",
|
||||
"keep_min_score": "Faza 2: minimalna ocjena za ostanak u utrci; zadano 0,1 dopušta slabe podudarnosti, kasniji koraci biraju najbolje",
|
||||
"dtw_blend": "Faza 3: 0 = samo osnovna ocjena, 1 = samo DTW ocjena, 0,5 = jednako miješanje (zadano)",
|
||||
"dtw_ensemble_w": "Faza 3 (kombinirani način): težina skaliranog L1 nasuprot derivatnog DTW; zadano 0,7 favorizira nivo",
|
||||
"dtw_ddtw_scale": "Faza 3: udaljenost polu-zasićenja DDTW; manja = osjetljivija na oblik (zadano 30)",
|
||||
"dtw_refine_top_n": "Faza 3: kandidati koje DTW ponovo ocjenjuje; povećajte na 7-9 ako ispravni profil zauzme 4.-5. mjesto (zadano 5)",
|
||||
"duration_scale": "Faza 4: omjer logaritma gdje se slaganje trajanja prepolovi; manje = stroža kazna (zadano 0,175)",
|
||||
"energy_scale": "Faza 4: omjer logaritma gdje se slaganje energije prepolovi; manje = stroža kazna (zadano 0,25)"
|
||||
},
|
||||
"col": {
|
||||
"profile_tip": "Naziv podudarnog programa. Bez oznake znači da se na kraju ciklusa nijedan profil nije podudarao.",
|
||||
@@ -1766,6 +1820,68 @@
|
||||
},
|
||||
"pg_sweep": {
|
||||
"optimize": "Optimizacija: {param}"
|
||||
},
|
||||
"pg_detail": {
|
||||
"simulate": "Simuliraj ciklus"
|
||||
},
|
||||
"split": {
|
||||
"apply": "Dijeljenje ciklusa"
|
||||
},
|
||||
"trim": {
|
||||
"apply": "Obrezivanje ciklusa"
|
||||
},
|
||||
"merge": {
|
||||
"apply": "Spajanje ciklusa"
|
||||
},
|
||||
"rebuild": {
|
||||
"envelopes": "Ponovna izgradnja omotača"
|
||||
}
|
||||
},
|
||||
"setup": {
|
||||
"hdr": {
|
||||
"card": "Postavljanje uređaja",
|
||||
"healthy_chip": "Postavljanje dovršeno"
|
||||
},
|
||||
"phase0": {
|
||||
"washer": "WashData već otkriva vaše cikluse. Snimite prvi ciklus kako biste omogućili nazive programa i procjene vremena.",
|
||||
"dishwasher": "WashData prati. Mašine za pranje posuđa imaju složene cikluse – snimanje prvog ciklusa je izrazito preporučeno. Ako otkriveni ciklus traje predugo, koristite uređivač ciklusa za rezanje prije pohrane kao profila.",
|
||||
"generic": "WashData prati. Snimite ili označite otkriveni ciklus kako biste počeli graditi profile."
|
||||
},
|
||||
"phase1a": {
|
||||
"labelled": "Dobar početak – vaš prvi program je pohranjen. Za najčišće podatke razmislite o snimanju sljedećeg ciklusa pomoću widgeta snimača."
|
||||
},
|
||||
"phase1b": {
|
||||
"recorded": "Vaša snimka pohranjena je kao {profile_name}. Sada snimite ili označite ostale uobičajene programe za izgradnju pokrivenosti."
|
||||
},
|
||||
"phase1c": {
|
||||
"verify": "Imate {count} programa od zajednice. Pokrenite ciklus kako biste provjerili prepoznaje li ih WashData ispravno – podudaranje će se poboljšati kako vaš uređaj gradi vlastitu historiju."
|
||||
},
|
||||
"phase2": {
|
||||
"cluster": "WashData je vidio {count} ciklusa koji ne odgovaraju nijednom pohranjenome programu – nalikuju jedni drugima. Želite li za njih stvoriti novi profil?",
|
||||
"unmatched": "Vaš zadnji ciklus nije odgovarao nijednom pohranjenome programu. Je li to novi program?"
|
||||
},
|
||||
"phase3": {
|
||||
"suggestions": "WashData ima preporuke postavki temeljene na vašoj historiji ciklusa – pregledajte ih kako biste poboljšali tačnost otkrivanja.",
|
||||
"groups": "Neki vaši profili izgledaju kao isti program pri različitim temperaturama. Organizujte ih u grupu za bolje podudaranje.",
|
||||
"phases": "Dodajte faze programa u {profile_name} za tačnije procjene preostalog vremena."
|
||||
},
|
||||
"phase4": {
|
||||
"healthy": "Ovaj uređaj je u potpunosti postavljen ({profile_count} profila)."
|
||||
},
|
||||
"cta": {
|
||||
"start_recording": "Pokreni snimanje",
|
||||
"label_detected_cycle": "Već imam otkriven ciklus – umjesto toga ga označi",
|
||||
"browse_cycles": "Pregledaj cikluse za označavanje sljedećeg",
|
||||
"view_profiles": "Prikaži svoje profile",
|
||||
"create_from_cluster": "Napravi profil od ovih ciklusa",
|
||||
"create_profile": "Napravi za njega profil",
|
||||
"review_suggestions": "Preglej prijedloge",
|
||||
"organise_profiles": "Organizuj profile",
|
||||
"configure_phases": "Konfiguriraj faze",
|
||||
"skip_step": "Preskoči ovaj korak",
|
||||
"skip_forever": "Ne prikazuj više",
|
||||
"hide_guidance": "Sakrij upute",
|
||||
"show_guidance": "Prikaži upute"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
"on_cycle_finished": "Po dokončení cyklu",
|
||||
"on_cycle_started": "Na začátku cyklu",
|
||||
"pause_cycle": "Pauza",
|
||||
"pause_cycle_tip": "Pozastavit běžící cyklus — spotřebič pokračuje tam, kde skončil",
|
||||
"pause_cycle_tip": "Pozastavit běžící cyklus – spotřebič pokračuje tam, kde skončil",
|
||||
"pg_apply_device": "Použít na zařízení",
|
||||
"pg_autofill": "Automaticky vyplnit",
|
||||
"play": "Přehrát",
|
||||
@@ -97,8 +97,8 @@
|
||||
"process_tip": "Uložit zaznamenaný průběh jako nový nebo existující profil",
|
||||
"rebuild": "Obnovit obálky",
|
||||
"rebuild_envelope": "Znovu sestavit obálku",
|
||||
"rebuild_tip": "Přepočítat očekávanou výkonovou obálku (pásmo min/max) pro všechny profily z jejich označených cyklů — spustit po označení nových cyklů nebo opravě starých",
|
||||
"rec_start_tip": "Zahájit záznam průběhu výkonu spotřebiče — spustit těsně před spuštěním cyklu",
|
||||
"rebuild_tip": "Přepočítat očekávanou výkonovou obálku (pásmo min/max) pro všechny profily z jejich označených cyklů – spustit po označení nových cyklů nebo opravě starých",
|
||||
"rec_start_tip": "Zahájit záznam průběhu výkonu spotřebiče – spustit těsně před spuštěním cyklu",
|
||||
"rec_stop": "Zastavit",
|
||||
"rec_stop_tip": "Zastavit nahrávání a podržet zachycený průběh ke kontrole",
|
||||
"record": "Spustit nahrávání",
|
||||
@@ -231,7 +231,7 @@
|
||||
"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": "{n} konflikt{s} nastavení – zkontrolujte zvýrazněné sekce a opravte před uložením.",
|
||||
"settings_banner_btn": "Přejít na první"
|
||||
},
|
||||
"hdr": {
|
||||
@@ -451,9 +451,9 @@
|
||||
"show_expected": "Zobrazit očekávané překrytí křivky (shodný profil, oranžová)",
|
||||
"show_raw": "Zobrazit přepínač surových dat zásuvky v živém grafu výkonu",
|
||||
"sparkline": "Trend délky posledních cyklů",
|
||||
"stage2": "Fáze 2 — jádrová podobnost",
|
||||
"stage3": "Fáze 3 — DTW",
|
||||
"stage4": "Fáze 4 — shoda",
|
||||
"stage2": "Fáze 2 – jádrová podobnost",
|
||||
"stage3": "Fáze 3 – DTW",
|
||||
"stage4": "Fáze 4 – shoda",
|
||||
"status": "Stav",
|
||||
"tail_trim": "Trimování ocasu (y)",
|
||||
"timer_auto_pause": "Automatická pauza",
|
||||
@@ -561,7 +561,12 @@
|
||||
"flags": "Příznaky",
|
||||
"include_phase_map": "Zahrnout mapu fází",
|
||||
"include_settings": "Zahrnout nastavení",
|
||||
"show_contributor": "Zobrazit přispěvatele"
|
||||
"show_contributor": "Zobrazit přispěvatele",
|
||||
"task_pg_detail": "Simulovat cyklus",
|
||||
"task_split": "Rozdělování cyklu",
|
||||
"task_trim": "Ořezávání cyklu",
|
||||
"task_merge": "Slučování cyklů",
|
||||
"task_rebuild": "Přepočítávání obálek"
|
||||
},
|
||||
"log": {
|
||||
"all_levels": "Všechny úrovně",
|
||||
@@ -645,7 +650,7 @@
|
||||
"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.",
|
||||
"artifact_header": "Během tohoto cyklu bylo zjištěno {n} anomálií",
|
||||
"artifact_pause_detail": "Výkon klesl téměř na nulu po dobu ~{n} s a poté se obnovil — pravděpodobně byla otevřena dvířka nebo byl cyklus pozastaven.",
|
||||
"artifact_pause_detail": "Výkon klesl téměř na nulu po dobu ~{n} s a poté se obnovil – pravděpodobně byla otevřena dvířka nebo byl cyklus pozastaven.",
|
||||
"artifact_spike_detail": "Překročil obvyklé pásmo výkonu po dobu ~{n} s.",
|
||||
"auto_label_intro": "Přiřaďte profily neoznačeným cyklům, jejichž spolehlivost shody překročí prahovou hodnotu.",
|
||||
"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.",
|
||||
@@ -654,10 +659,10 @@
|
||||
"collecting_data": "Shromažďování dat: ještě {need} cyklů do zahájení jemného doladění ({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",
|
||||
"compare_selected_cycles": "Vybrané cykly (plné) – zobrazit / skrýt",
|
||||
"consider_new_profile": "Zvažte vytvoření nového profilu.",
|
||||
"coverage_gap": "nedávné cykly nemají žádný odpovídající profil ({pct} % z posledních 30).",
|
||||
"coverage_gap_similar_cycles": "Nalezeno {count} podobných neoznačených cyklů — vytvořte profil, abyste je začali párovat.",
|
||||
"coverage_gap_similar_cycles": "Nalezeno {count} podobných neoznačených cyklů – vytvořte profil, abyste je začali párovat.",
|
||||
"cycles_deleted": "Smazáno cyklů: {count}",
|
||||
"enough_data": "Dostatek dat k učení ({current}/{min} cyklů).",
|
||||
"export_description": "Exportujte všechny profily a cykly do JSON nebo obnovte z předchozího exportu.",
|
||||
@@ -686,7 +691,7 @@
|
||||
"ml_learned_intro": "Modely vyladěné na tento stroj.",
|
||||
"ml_loading": "načítání ML…",
|
||||
"ml_settings_intro": "Dva nezávislé přepínače: jeden použije modely během cyklu, druhý umožňuje programu WashData je v průběhu času jemně doladit na váš stroj.",
|
||||
"name_first_program": "Máte dostatek cyklů — pojmenujte svůj první program a zahajte párování.",
|
||||
"name_first_program": "Máte dostatek cyklů – pojmenujte svůj první program a zahajte párování.",
|
||||
"near_duplicate_cluster": "zjištěn téměř duplicitní shluk profilů. Seskupování umožňuje spárování spolehlivě vybrat mezi podobnými (např. stejný program při různé teplotě/odstřeďování).",
|
||||
"no_cycles_match": "Žádné cykly neodpovídají aktuálnímu filtru.",
|
||||
"no_cycles_profile": "Žádné cykly pro tento profil.",
|
||||
@@ -696,7 +701,7 @@
|
||||
"no_devices": "Zatím nejsou nakonfigurována žádná zařízení WashData.",
|
||||
"no_envelope": "Zatím bez obálky - po cyklech štítkování znovu sestavit.",
|
||||
"no_envelope_overlay": "Není k dispozici žádná obálka k překrytí.",
|
||||
"no_fine_tuned": "Zatím není nic doladěno — WashData využívá své vestavěné modely.",
|
||||
"no_fine_tuned": "Zatím není nic doladěno – WashData využívá své vestavěné modely.",
|
||||
"no_logs": "Dosud nebyly uloženy žádné záznamy protokolu.",
|
||||
"no_maintenance": "Zatím není zaznamenána žádná údržba.",
|
||||
"no_match_yet": "Zatím žádný pokus o shodu – toto se naplní během běžícího cyklu.",
|
||||
@@ -713,7 +718,7 @@
|
||||
"notify_services_hint": "Zadejte ID služeb {entity} (více oddělete čárkou). Proměnné šablony: {vars}.",
|
||||
"old_actions_warning": "Nakonfigurováno pomocí starého editoru akcí (nyní odstraněno). Stále se spouštějí při událostech cyklu, ale zde je již nelze upravovat. Převeďte je na normální automatizaci nebo je odstraňte.",
|
||||
"onboarding_progress": "{n} / 3 sledovaných cyklů",
|
||||
"onboarding_watching": "Nechte spotřebič běžet normálně — WashData sleduje. Po 3 cyklech začne párování programů.",
|
||||
"onboarding_watching": "Nechte spotřebič běžet normálně – WashData sleduje. Po 3 cyklech začne párování programů.",
|
||||
"pending_feedback": "Čeká na zpětnou vazbu detekce",
|
||||
"performance_trend": "Trend výkonu ({n} cyklů)",
|
||||
"pg_analysis_empty": "Načtěte cyklus pro zobrazení analýzy shody.",
|
||||
@@ -763,7 +768,7 @@
|
||||
"setting_changed": "Změněno z {old} na {new} dne {date}",
|
||||
"settings_basic_note": "Zobrazují se základní nastavení. Přepněte na Pokročilé pro úplný seznam.",
|
||||
"shape_drift_advisory": "⚠ Drift tvaru",
|
||||
"shape_drift_detail": "Vzor příkonu pro tento profil se časem posunul — možné opotřebení spotřebiče nebo potřebná údržba (např. odvápnění, čištění filtru).",
|
||||
"shape_drift_detail": "Vzor příkonu pro tento profil se časem posunul – možné opotřebení spotřebiče nebo potřebná údržba (např. odvápnění, čištění filtru).",
|
||||
"show_all_settings": "Zobrazit všechna nastavení",
|
||||
"showing_suggestions": "Zobrazuje se nastavení {count} s návrhy.",
|
||||
"split_intro": "Kliknutím na graf přidáte nebo odstraníte dělicí bod nebo automaticky rozpoznáte mezery v nečinnosti. Každý výsledný segment může získat svůj vlastní profil.",
|
||||
@@ -857,7 +862,9 @@
|
||||
"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í"
|
||||
"share_profile_no_cycles": "Profil '{p}' nemá žádné ⭐ referenční cykly -- bude přeskočen, pokud nemáte {n}+ potvrzených spuštění",
|
||||
"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"
|
||||
},
|
||||
"phase_desc": {
|
||||
"anti_crease": "Občasné krátké otáčení bubnu po dokončení cyklu pro prevenci mačkání.",
|
||||
@@ -940,6 +947,10 @@
|
||||
"triggers": {
|
||||
"intro": "Volitelné externí signály: spouštěč konce, senzor dveří, přepínač pauzy a připomínka vyložení.",
|
||||
"label": "Spouštěče a dveře"
|
||||
},
|
||||
"phase_eta": {
|
||||
"label": "Zbývající čas",
|
||||
"intro": "Zbývající čas zohledňující fáze, pro spotřebiče, jejichž délka cyklu závisí na teplotě nebo odstřeďování."
|
||||
}
|
||||
},
|
||||
"setting": {
|
||||
@@ -1023,6 +1034,10 @@
|
||||
"doc": "Pevná cena za kWh používaná pro ukazatele nákladů, pokud není nastavena živá entita ceny výše.",
|
||||
"label": "Statická cena energie (za kWh)"
|
||||
},
|
||||
"energy_sensor": {
|
||||
"doc": "Volitelné kumulativní počítadlo energie (total_increasing kWh/Wh, např. vlastní celoživotní měřič zásuvky). Když je nastaveno, energie hlášená za každý cyklus se odvozuje z rozdílu tohoto počítadla mezi začátkem a koncem, což zabraňuje podhodnocení, které vzniká integrací pomalu hlásícího senzoru výkonu. Vrátí se k integrované hodnotě, pokud údaj chybí, jeho jednotka je neznámá nebo rozdíl není kladný. Ponechte prázdné, chcete-li dále integrovat senzor výkonu.",
|
||||
"label": "Entita měřiče energie"
|
||||
},
|
||||
"expose_debug_entities": {
|
||||
"doc": "Publikujte extra diagnostické entity HA (spolehlivost shody, nejednoznačnost, interní stav). Vypnuto udržuje seznam entit čistý pro normální použití.",
|
||||
"label": "Zobrazit ladící entity"
|
||||
@@ -1305,6 +1320,38 @@
|
||||
},
|
||||
"show_contributor": {
|
||||
"doc": "Zobrazit jméno přispěvatele u profilů stažených z komunitního obchodu"
|
||||
},
|
||||
"enable_phase_matching": {
|
||||
"label": "Zbývající čas zohledňující fáze",
|
||||
"doc": "Rozdělí každý běžící cyklus do fází (ohřev, praní, odstřeďování) a rozpočítá zbývající čas na jednotlivé fáze, smíchaný s klasickým odhadem - na začátku cyklu se opírá o rozpočet fází a ke konci o klasický odhad. Přizpůsobí odpočet tomu, jak dlouho se váš spotřebič skutečně ohřívá a běží, což je nejvíce patrné v první polovině cyklu. Vypnuto = pouze klasický odhad. Ovlivněno je jen zobrazení zbývajícího času; shoda programů a detekce cyklu se nemění."
|
||||
},
|
||||
"keep_min_score": {
|
||||
"label": "Min. skore shody",
|
||||
"doc": "Minimální skóre podobnosti, které musí kandidát mít, aby zůstal v závodu o shodu. Výchozí hodnota 0,1 je záměrně benevolentní - připouští i slabé kandidáty a spoléhá na pozdější fáze při výběru nejlepší shody. Zvyšte ji pro dřívější vyřazení nepravděpodobných profilů; snižte ji pro rozšíření počáteční skupiny kandidátů."
|
||||
},
|
||||
"dtw_blend": {
|
||||
"label": "Mísení deformace",
|
||||
"doc": "Jak moc skóre zarovnání DTW nahrazuje základní skóre Fáze 2. 0 = použij pouze skóre Fáze 2, 1 = použij pouze skóre DTW, 0,5 (výchozí) = rovnoměrné míchání. Zvyšte, chcete-li se více spoléhat na zarovnání, když mají programy podobné úrovně výkonu, ale různé časové vzory."
|
||||
},
|
||||
"dtw_ensemble_w": {
|
||||
"label": "Mix kombinace DTW",
|
||||
"doc": "V režimu kombinace DTW (výchozím) je to váha škálovaného L1 oproti derivátnímu DTW (DDTW). 1,0 = vše škálované L1, 0 = vše DDTW, 0,7 = výchozí. Škálovaná varianta L1 porovnává úrovně výkonu; derivátní varianta reaguje na změny výkonu v čase. Kombinace spojuje obě."
|
||||
},
|
||||
"dtw_ddtw_scale": {
|
||||
"label": "Škála derivátní deformace",
|
||||
"doc": "Vzdálenost polosaturace pro hodnocení derivátním DTW. Skóre se sníží na polovinu, když vzdálenost DDTW rovná se této hodnotě. Menší = citlivější na rozdíly ve tvaru. Výchozí hodnota 30 je zkalibrována pro typické průběhy výkonu spotřebičů. Ovlivňuje pouze kombinační a ddtw režimy DTW."
|
||||
},
|
||||
"dtw_refine_top_n": {
|
||||
"label": "Pocet zpresnenych kandidatu",
|
||||
"doc": "Kolik nejlepších kandidátů z Fáze 2 je přehodnoceno DTW. DTW je nákladnější, takže se používá pouze pro N nejlepších kandidátů. Výchozí 5. Zvyšte (na 7-9), pokud správný profil po Fázi 2 někdy dosáhne pouze 4. nebo 5. místa - DTW ho může zachránit. Snížení mírně urychlí porovnávání."
|
||||
},
|
||||
"duration_scale": {
|
||||
"label": "Ostrost délky trvání",
|
||||
"doc": "Ostrost penalizace za neshodu délky trvání ve Fázi 4. Jedná se o logaritmický poměr, při kterém se skóre shody sníží na polovinu. Menší = přísnější: neshoda délky trvání více snižuje skóre. Výchozí hodnota 0,175 odpovídá přibližně 18% toleranci délky trvání při poloviční váze. Kombinujte s Váhou délky trvání."
|
||||
},
|
||||
"energy_scale": {
|
||||
"label": "Ostrost energie",
|
||||
"doc": "Ostrost penalizace za neshodu energie ve Fázi 4. Menší = přísnější: neshoda energie více snižuje skóre. Výchozí hodnota 0,25 je záměrně benevolentnější než Ostrost délky trvání, protože energie se liší podle zátěže. Kombinujte s Váhou energie."
|
||||
}
|
||||
},
|
||||
"setting_group": {
|
||||
@@ -1424,24 +1471,24 @@
|
||||
"lower": "Více cyklů je označeno automaticky; některé mohou být nesprávně určeny"
|
||||
},
|
||||
"duration_tolerance": {
|
||||
"higher": "Přijímá širší rozsah délky — flexibilnější shoda",
|
||||
"lower": "Vyžaduje bližší shodu délky — přísnější, ale může odmítnout neobvyklé cykly"
|
||||
"higher": "Přijímá širší rozsah délky – flexibilnější shoda",
|
||||
"lower": "Vyžaduje bližší shodu délky – přísnější, ale může odmítnout neobvyklé cykly"
|
||||
},
|
||||
"end_energy_threshold": {
|
||||
"higher": "Uzavírá pouze cykly se značnou spotřebou energie",
|
||||
"lower": "Uzavírá i kratší nebo méně energetické cykly"
|
||||
},
|
||||
"end_repeat_count": {
|
||||
"higher": "Vyžaduje více opakování signálu konce — spolehlivější, mírně pomalejší",
|
||||
"lower": "Ukončí po méně opakováních — rychlejší detekce, větší riziko předčasného ukončení"
|
||||
"higher": "Vyžaduje více opakování signálu konce – spolehlivější, mírně pomalejší",
|
||||
"lower": "Ukončí po méně opakováních – rychlejší detekce, větší riziko předčasného ukončení"
|
||||
},
|
||||
"learning_confidence": {
|
||||
"higher": "Učí se pouze z velmi jistých shod — pomalejší, ale spolehlivější",
|
||||
"higher": "Učí se pouze z velmi jistých shod – pomalejší, ale spolehlivější",
|
||||
"lower": "Učí se z více cyklů; model může být méně přesný"
|
||||
},
|
||||
"min_off_gap": {
|
||||
"higher": "Potřebuje delší klid před začátkem nového cyklu",
|
||||
"lower": "Krátký klid spustí nový cyklus — cykly za sebou se mohou rozdělit"
|
||||
"lower": "Krátký klid spustí nový cyklus – cykly za sebou se mohou rozdělit"
|
||||
},
|
||||
"min_power": {
|
||||
"higher": "Méně citlivý na klidový příkon; může přehlédnout velmi tichý program",
|
||||
@@ -1452,24 +1499,24 @@
|
||||
"lower": "Zaseklý cyklus je ukončen dříve"
|
||||
},
|
||||
"off_delay": {
|
||||
"higher": "Více času pro pauzy spotřebiče — vhodné pro dlouhé máchání nebo sušení",
|
||||
"lower": "Rychlejší detekce konce — vhodné pro spotřebiče s čistým zapínáním/vypínáním"
|
||||
"higher": "Více času pro pauzy spotřebiče – vhodné pro dlouhé máchání nebo sušení",
|
||||
"lower": "Rychlejší detekce konce – vhodné pro spotřebiče s čistým zapínáním/vypínáním"
|
||||
},
|
||||
"profile_match_threshold": {
|
||||
"higher": "Potvrzuje pouze vysoce jisté shody; více cyklů zůstane neoznačených",
|
||||
"lower": "Páruje více cyklů; některé mohou být mírně nesprávné"
|
||||
},
|
||||
"running_dead_zone": {
|
||||
"higher": "Ignoruje krátké výkonové špičky během klidu — méně citlivý na šum",
|
||||
"lower": "Reaguje na kratší výkonové impulzy — zachytí rychlou přechodnou aktivitu"
|
||||
"higher": "Ignoruje krátké výkonové špičky během klidu – méně citlivý na šum",
|
||||
"lower": "Reaguje na kratší výkonové impulzy – zachytí rychlou přechodnou aktivitu"
|
||||
},
|
||||
"start_threshold_w": {
|
||||
"higher": "Zabraňuje falešným startům z krátkých výkonových špiček",
|
||||
"lower": "Zachytí programy s nízkým příkonem; může reagovat na rušení"
|
||||
},
|
||||
"stop_threshold_w": {
|
||||
"higher": "Ukončí cyklus rychleji — může uzavřít v průběhu pauzy",
|
||||
"lower": "Čeká déle na ukončení — méně předčasných dokončení"
|
||||
"higher": "Ukončí cyklus rychleji – může uzavřít v průběhu pauzy",
|
||||
"lower": "Čeká déle na ukončení – méně předčasných dokončení"
|
||||
},
|
||||
"watchdog_interval": {
|
||||
"higher": "Povoluje delší tichá úseky; méně falešných vynucených ukončení",
|
||||
@@ -1676,12 +1723,19 @@
|
||||
"start_duration_threshold": "Sekundy nad prahem pro potvrzení spuštění",
|
||||
"start_threshold_w": "Minimální výkon ve wattech pro započtení spuštění",
|
||||
"stop_threshold_w": "Pod touto hodnotou se stroj počítá jako vypnutý",
|
||||
"dtw_bandwidth": "Jak velké časové deformace shoda tvaru umožňuje",
|
||||
"corr_weight": "Váha tvaru křivky vs. úrovně výkonu při přiřazování",
|
||||
"duration_weight": "Jak moc shoda délky trvání ovlivňuje přiřazení",
|
||||
"energy_weight": "Jak moc shoda spotřeby energie ovlivňuje přiřazení",
|
||||
"profile_match_min_duration_ratio": "Nejkratší běh (oproti profilu), který ještě může odpovídat",
|
||||
"profile_match_max_duration_ratio": "Nejdelší běh (oproti profilu), který ještě může odpovídat"
|
||||
"dtw_bandwidth": "Fáze 3: pásmo deformace Sakoe-Chiba (0 = DTW vypnuto; výchozí 0,2 = 20 % délky cyklu)",
|
||||
"corr_weight": "Fáze 2: rovnováha mezi tvarem křivky (korelace) a úrovní výkonu (MAE); výchozí 0,45",
|
||||
"duration_weight": "Fáze 4: jak silně shoda délky trvání ovlivňuje výsledné skóre (výchozí 0,22)",
|
||||
"energy_weight": "Fáze 4: jak silně shoda energie ovlivňuje výsledné skóre (výchozí 0,22)",
|
||||
"profile_match_min_duration_ratio": "Fáze 1: minimální délka cyklu jako zlomek doby trvání profilu; výchozí 0,1 (10 %)",
|
||||
"profile_match_max_duration_ratio": "Fáze 1: maximální délka cyklu jako zlomek doby trvání profilu; výchozí 1,5 (150 %)",
|
||||
"keep_min_score": "Fáze 2: minimální skóre pro setrvání v závodu; výchozí 0,1 připouští slabé shody, pozdější fáze vyberou nejlepší",
|
||||
"dtw_blend": "Fáze 3: 0 = pouze základní skóre, 1 = pouze skóre DTW, 0,5 = rovnoměrné míchání (výchozí)",
|
||||
"dtw_ensemble_w": "Fáze 3 (režim kombinace): váha škálovaného L1 oproti derivátnímu DTW; výchozí 0,7 upřednostňuje úroveň",
|
||||
"dtw_ddtw_scale": "Fáze 3: vzdálenost polosaturace DDTW; menší = citlivější na tvar (výchozí 30)",
|
||||
"dtw_refine_top_n": "Fáze 3: kandidáti, které DTW přehodnotí; zvyšte na 7-9, pokud správný profil skončí na 4.-5. místě (výchozí 5)",
|
||||
"duration_scale": "Fáze 4: logaritmický poměr, při kterém se shoda délky trvání sníží na polovinu; menší = přísnější penalizace (výchozí 0,175)",
|
||||
"energy_scale": "Fáze 4: logaritmický poměr, při kterém se shoda energie sníží na polovinu; menší = přísnější penalizace (výchozí 0,25)"
|
||||
},
|
||||
"col": {
|
||||
"profile_tip": "Název odpovídajícího programu. Bez štítku znamená, že na konci cyklu nebyl nalezen žádný profil.",
|
||||
@@ -1766,6 +1820,69 @@
|
||||
},
|
||||
"pg_sweep": {
|
||||
"optimize": "Optimalizace: {param}"
|
||||
},
|
||||
"pg_detail": {
|
||||
"simulate": "Simulovat cyklus"
|
||||
},
|
||||
"split": {
|
||||
"apply": "Rozdělování cyklu"
|
||||
},
|
||||
"trim": {
|
||||
"apply": "Ořezávání cyklu"
|
||||
},
|
||||
"merge": {
|
||||
"apply": "Slučování cyklů"
|
||||
},
|
||||
"rebuild": {
|
||||
"envelopes": "Přepočítávání obálek"
|
||||
},
|
||||
"cancelling": "Ruším..."
|
||||
},
|
||||
"setup": {
|
||||
"hdr": {
|
||||
"card": "Nastavení zařízení",
|
||||
"healthy_chip": "Nastavení dokončeno"
|
||||
},
|
||||
"phase0": {
|
||||
"washer": "WashData již detekuje vaše cykly. Zaznamenejte první cyklus, abyste povolili názvy programů a odhady doby trvání.",
|
||||
"dishwasher": "WashData sleduje. Myčky nádobí mají složité cykly – nahrání prvního cyklu je silně doporučeno. Pokud detekovaný cyklus běží příliš dlouho, ořízněte ho v editoru cyklů před uložením jako profil.",
|
||||
"generic": "WashData sleduje. Zaznamenejte nebo označte detekovaný cyklus a začněte vytvářet profily."
|
||||
},
|
||||
"phase1a": {
|
||||
"labelled": "Dobrý začátek – váš první program je uložen. Pro nejčistší data zvažte nahrání dalšího cyklu pomocí widgetu rekordéru."
|
||||
},
|
||||
"phase1b": {
|
||||
"recorded": "Váš záznam byl uložen jako {profile_name}. Nyní nahrajte nebo označte další běžné programy, abyste rozšířili pokrytí."
|
||||
},
|
||||
"phase1c": {
|
||||
"verify": "Máte {count} programů od komunity. Spusťte cyklus, abyste ověřili, že je WashData správně rozpoznává – párování se bude zlepšovat, jak zařízení buduje vlastní historii."
|
||||
},
|
||||
"phase2": {
|
||||
"cluster": "WashData zaznamenal {count} cyklů, které neodpovídají žádnému uloženému programu – vypadají si navzájem podobně. Chcete pro ně vytvořit nový profil?",
|
||||
"unmatched": "Váš poslední cyklus neodpovídal žádnému uloženému programu. Je to nový program?"
|
||||
},
|
||||
"phase3": {
|
||||
"suggestions": "WashData má doporučení k nastavení na základě vaší historie cyklů – zkontrolujte je pro zlepšení přesnosti detekce.",
|
||||
"groups": "Některé vaše profily vypadají jako stejný program při různých teplotách. Uspořádejte je do skupiny pro lepší párování.",
|
||||
"phases": "Přidejte fáze programu k {profile_name} pro přesnější odhady zbývajícího času."
|
||||
},
|
||||
"phase4": {
|
||||
"healthy": "Toto zařízení je plně nastaveno ({profile_count} profilů)."
|
||||
},
|
||||
"cta": {
|
||||
"start_recording": "Spustit nahrávání",
|
||||
"label_detected_cycle": "Již mám detekovaný cyklus – místo toho ho označte",
|
||||
"browse_cycles": "Procházet cykly a označit další",
|
||||
"view_profiles": "Zobrazit vaše profily",
|
||||
"create_from_cluster": "Vytvořit profil z těchto cyklů",
|
||||
"create_profile": "Vytvořit pro něj profil",
|
||||
"review_suggestions": "Zkontrolovat návrhy",
|
||||
"organise_profiles": "Uspořádat profily",
|
||||
"configure_phases": "Konfigurovat fáze",
|
||||
"skip_step": "Přeskočit tento krok",
|
||||
"skip_forever": "Nezobrazovat znovu",
|
||||
"hide_guidance": "Skrýt pokyny",
|
||||
"show_guidance": "Zobrazit pokyny"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
"on_cycle_finished": "På cyklus færdig",
|
||||
"on_cycle_started": "På cyklus startet",
|
||||
"pause_cycle": "Pause",
|
||||
"pause_cycle_tip": "Sæt den kørende cyklus på pause — apparatet genoptager, hvor det slap",
|
||||
"pause_cycle_tip": "Sæt den kørende cyklus på pause – apparatet genoptager, hvor det slap",
|
||||
"pg_apply_device": "Anvend på enhed",
|
||||
"pg_autofill": "Autoudfyld",
|
||||
"play": "Afspil",
|
||||
@@ -97,8 +97,8 @@
|
||||
"process_tip": "Gem det optagede spor som en ny eller eksisterende profil",
|
||||
"rebuild": "Genopbyg konvolutter",
|
||||
"rebuild_envelope": "Genopbyg konvolut",
|
||||
"rebuild_tip": "Genberegn den forventede effektkonvolut (min/max-bånd) for alle profiler fra deres mærkede cyklusser — kør efter mærkning af nye cyklusser eller korrigering af gamle",
|
||||
"rec_start_tip": "Begynd at optage apparatets effektspor — start umiddelbart inden du kører en cyklus",
|
||||
"rebuild_tip": "Genberegn den forventede effektkonvolut (min/max-bånd) for alle profiler fra deres mærkede cyklusser – kør efter mærkning af nye cyklusser eller korrigering af gamle",
|
||||
"rec_start_tip": "Begynd at optage apparatets effektspor – start umiddelbart inden du kører en cyklus",
|
||||
"rec_stop": "Stop",
|
||||
"rec_stop_tip": "Stop optagelsen og behold det indfangede spor til gennemgang",
|
||||
"record": "Start optagelse",
|
||||
@@ -231,7 +231,7 @@
|
||||
"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": "{n} indstillingskonflikt{s} – tjek de fremhævede sektioner og ret dem inden du gemmer.",
|
||||
"settings_banner_btn": "Gå til første"
|
||||
},
|
||||
"hdr": {
|
||||
@@ -451,9 +451,9 @@
|
||||
"show_expected": "Vis forventet kurveoverlejring (matchet profil, orange)",
|
||||
"show_raw": "Vis kontakt for råe stikkontaktværdier i live strømgraf",
|
||||
"sparkline": "Tendens for seneste cyklusvarigheder",
|
||||
"stage2": "Trin 2 — kerneligning",
|
||||
"stage3": "Trin 3 — DTW",
|
||||
"stage4": "Trin 4 — overensstemmelse",
|
||||
"stage2": "Trin 2 – kerneligning",
|
||||
"stage3": "Trin 3 – DTW",
|
||||
"stage4": "Trin 4 – overensstemmelse",
|
||||
"status": "Status",
|
||||
"tail_trim": "Beskær slut (s)",
|
||||
"timer_auto_pause": "Auto-pause",
|
||||
@@ -561,7 +561,12 @@
|
||||
"flags": "Flags",
|
||||
"include_phase_map": "Inkludér fasekort",
|
||||
"include_settings": "Inkludér detektions- og matchindstillinger",
|
||||
"show_contributor": "Vis bidragydernes navne"
|
||||
"show_contributor": "Vis bidragydernes navne",
|
||||
"task_pg_detail": "Simulér cyklus",
|
||||
"task_split": "Opdeler cyklus",
|
||||
"task_trim": "Beskærer cyklus",
|
||||
"task_merge": "Sammenfletter cyklusser",
|
||||
"task_rebuild": "Genopbygger envelopes"
|
||||
},
|
||||
"log": {
|
||||
"all_levels": "Alle niveauer",
|
||||
@@ -645,7 +650,7 @@
|
||||
"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.",
|
||||
"artifact_header": "{n} uregelmæssigheder opdaget i denne cyklus",
|
||||
"artifact_pause_detail": "Effekten faldt til næsten nul i ~{n}s og genoptog derefter — sandsynligvis blev døren åbnet midt i cyklussen, eller cyklussen blev sat på pause.",
|
||||
"artifact_pause_detail": "Effekten faldt til næsten nul i ~{n}s og genoptog derefter – sandsynligvis blev døren åbnet midt i cyklussen, eller cyklussen blev sat på pause.",
|
||||
"artifact_spike_detail": "Steg over det normale effektbånd i ~{n}s.",
|
||||
"auto_label_intro": "Tildel profiler til umærkede cyklusser, hvis matchkonfidens rydder tærsklen.",
|
||||
"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.",
|
||||
@@ -654,10 +659,10 @@
|
||||
"collecting_data": "Indsamler data: {need} cyklus{plural} mere, før finjustering kan starte ({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",
|
||||
"compare_selected_cycles": "Valgte cyklusser (fast) – vis/skjul",
|
||||
"consider_new_profile": "Overvej at oprette en ny profil.",
|
||||
"coverage_gap": "seneste cyklusser har ingen matchende profil ({pct}% af sidste 30).",
|
||||
"coverage_gap_similar_cycles": "{count} lignende umærkede cyklusser fundet — opret en profil for at begynde at matche dem.",
|
||||
"coverage_gap_similar_cycles": "{count} lignende umærkede cyklusser fundet – opret en profil for at begynde at matche dem.",
|
||||
"cycles_deleted": "{count} cyklus(ser) slettet",
|
||||
"enough_data": "Nok data til at lære af ({current}/{min} cyklusser).",
|
||||
"export_description": "Eksporter alle profiler og cyklusser til JSON, eller gendan fra en tidligere eksport.",
|
||||
@@ -686,7 +691,7 @@
|
||||
"ml_learned_intro": "Modeller finjusteret til denne maskine.",
|
||||
"ml_loading": "indlæser ML...",
|
||||
"ml_settings_intro": "To uafhængige kontakter: Den ene anvender modellerne, mens en cyklus kører, den anden lader WashData finjustere dem til din maskine over tid.",
|
||||
"name_first_program": "Du har nok cyklusser — navngiv dit første program for at begynde matchning.",
|
||||
"name_first_program": "Du har nok cyklusser – navngiv dit første program for at begynde matchning.",
|
||||
"near_duplicate_cluster": "næsten dublet profilklynge fundet. Gruppering gør det muligt for matchning pålideligt at vælge mellem look-alikes (f.eks. samme program ved forskellig temperatur/spin).",
|
||||
"no_cycles_match": "Ingen cyklusser matcher det aktuelle filter.",
|
||||
"no_cycles_profile": "Ingen cyklusser for denne profil.",
|
||||
@@ -713,7 +718,7 @@
|
||||
"notify_services_hint": "Brug {entity}-service-ID'er (kommaseparerede for flere). Skabelonvariabler: {vars}.",
|
||||
"old_actions_warning": "Konfigureret med den gamle handlingseditor (nu fjernet). De skyder stadig på cyklusbegivenheder, men kan ikke længere redigeres her. Konverter dem til en normal automatisering, eller fjern dem.",
|
||||
"onboarding_progress": "{n} / 3 cyklusser observeret",
|
||||
"onboarding_watching": "Lad dit apparat køre normalt — WashData holder øje. Efter 3 cyklusser begynder programmatchning.",
|
||||
"onboarding_watching": "Lad dit apparat køre normalt – WashData holder øje. Efter 3 cyklusser begynder programmatchning.",
|
||||
"pending_feedback": "Afventer detektionsfeedback",
|
||||
"performance_trend": "Præstationstendens ({n} cyklusser)",
|
||||
"pg_analysis_empty": "Indlæs en cyklus for at se matchanalyse.",
|
||||
@@ -763,7 +768,7 @@
|
||||
"setting_changed": "Ændret fra {old} til {new} den {date}",
|
||||
"settings_basic_note": "Viser væsentlige indstillinger. Skift til Avanceret for hele listen.",
|
||||
"shape_drift_advisory": "⚠ Formdrift",
|
||||
"shape_drift_detail": "Effektmønsteret for denne profil har ændret sig over tid — mulig slid på apparatet eller vedligeholdelse nødvendig (f.eks. afkalkning, filterrensning).",
|
||||
"shape_drift_detail": "Effektmønsteret for denne profil har ændret sig over tid – mulig slid på apparatet eller vedligeholdelse nødvendig (f.eks. afkalkning, filterrensning).",
|
||||
"show_all_settings": "Vis alle indstillinger",
|
||||
"showing_suggestions": "Viser indstillingen {count} med forslag.",
|
||||
"split_intro": "Klik på grafen for at tilføje eller fjerne et opdelingspunkt, eller automatisk detektere ved inaktive huller. Hvert resulterende segment kan få sin egen profil.",
|
||||
@@ -789,10 +794,10 @@
|
||||
"toast_revert_failed": "Tilbagerulning mislykkedes: {error}",
|
||||
"toast_reverted": "{key} tilbageført",
|
||||
"toast_save_failed": "Lagring mislykkedes: {error}",
|
||||
"trend_duration_longer": "Varighed, der trender længere ({pct}%/cyklus) — seneste gennemsnit {avg}",
|
||||
"trend_duration_shorter": "Varighed, der trender kortere ({pct}%/cyklus) — seneste gennemsnit {avg}",
|
||||
"trend_duration_longer": "Varighed, der trender længere ({pct}%/cyklus) – seneste gennemsnit {avg}",
|
||||
"trend_duration_shorter": "Varighed, der trender kortere ({pct}%/cyklus) – seneste gennemsnit {avg}",
|
||||
"trend_energy_down": "Energi på vej ned ({pct} %/cyklus)",
|
||||
"trend_energy_up": "Energitrends op ({pct} %/cyklus) — seneste gennemsnit {avg}",
|
||||
"trend_energy_up": "Energitrends op ({pct} %/cyklus) – seneste gennemsnit {avg}",
|
||||
"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.",
|
||||
"unsure_detected_prefix": "WashData er usikker på, om det er registreret",
|
||||
@@ -857,7 +862,9 @@
|
||||
"share_guidelines_title": "Inden du deler",
|
||||
"store_download_device_intro": "Overtag alle delte programmer og deres referencecyklusser til dit apparat. Dine egne optagede cyklusser og statistik påvirkes ikke.",
|
||||
"store_share_device_intro": "Upload {brand} {model} med de referencecyklusser, du vælger. Andre med samme apparat kan overtage dine programmer. Bidrag gennemgås inden offentliggørelse.",
|
||||
"share_profile_no_cycles": "Ingen referencecyklusser -- markér en cyklus som ⭐ under fanen Cyklusser for at inkludere denne profil"
|
||||
"share_profile_no_cycles": "Ingen referencecyklusser -- markér en cyklus som ⭐ under fanen Cyklusser for at inkludere denne profil",
|
||||
"advisory_phase_inconsistent": "'{name}' ser ud til at blande forskellige programmer eller temperaturer - dens cyklusser varmer op i meget forskellige tidsrum. Hvis du deler den op i separate profiler (f.eks. pr. temperatur), forbedres matchningen og tidsestimaterne.",
|
||||
"advisory_phase_inconsistent_title": "⚠ Muligvis blandede programmer"
|
||||
},
|
||||
"pg_desc": {
|
||||
"abrupt_drop_watts": "Pludseligt fald behandlet som øjeblikkelig afslutning",
|
||||
@@ -869,12 +876,19 @@
|
||||
"start_duration_threshold": "Sekunder over tærsklen for at bekræfte start",
|
||||
"start_threshold_w": "Minimum watt for at tælle som startet",
|
||||
"stop_threshold_w": "Under dette tælles maskinen som slukket",
|
||||
"dtw_bandwidth": "Hvor meget tidsforvrængning formgenkendelsen tillader",
|
||||
"corr_weight": "Vægt på kurveform kontra effektniveau i genkendelsen",
|
||||
"duration_weight": "Hvor meget overensstemmelse i køretid påvirker genkendelsen",
|
||||
"energy_weight": "Hvor meget overensstemmelse i energiforbrug påvirker genkendelsen",
|
||||
"profile_match_min_duration_ratio": "Korteste kørsel (i forhold til profilen), der stadig må matche",
|
||||
"profile_match_max_duration_ratio": "Længste kørsel (i forhold til profilen), der stadig må matche"
|
||||
"dtw_bandwidth": "Trin 3: Sakoe-Chiba-tidsforvrængningsband (0 = DTW slukket; standard 0,2 = 20% af cykellængde)",
|
||||
"corr_weight": "Trin 2: balance mellem kurveform (korrelation) og effektniveau (MAE); standard 0,45",
|
||||
"duration_weight": "Trin 4: hvor stærkt varighedsoverensstemmelse påvirker slutscoren (standard 0,22)",
|
||||
"energy_weight": "Trin 4: hvor stærkt energioverensstemmelse påvirker slutscoren (standard 0,22)",
|
||||
"profile_match_min_duration_ratio": "Trin 1: korteste cykellængde som brøkdel af profilvarighed; standard 0,1 (10%)",
|
||||
"profile_match_max_duration_ratio": "Trin 1: længste cykellængde som brøkdel af profilvarighed; standard 1,5 (150%)",
|
||||
"keep_min_score": "Trin 2: laveste score for at forblive i kampen; standard 0,1 tillader svage kandidater, senere trin vælger bedst",
|
||||
"dtw_blend": "Trin 3: 0 = kun kernescore, 1 = kun DTW-score, 0,5 = ligelig blanding (standard)",
|
||||
"dtw_ensemble_w": "Trin 3 (ensemble-tilstand): vægt på skaleret L1 kontra derivativ DTW; standard 0,7 foretrækker niveaubevidst",
|
||||
"dtw_ddtw_scale": "Trin 3: DDTW-halvmætningsafstand; mindre = mere formfølsom (standard 30)",
|
||||
"dtw_refine_top_n": "Trin 3: kandidater DTW gen-scorer; hæv til 7-9 hvis korrekt profil placerer sig 4.-5. (standard 5)",
|
||||
"duration_scale": "Trin 4: log-forhold der varighedsoverensstemmelse halveres; lavere = strengere straf (standard 0,175)",
|
||||
"energy_scale": "Trin 4: log-forhold der energioverensstemmelse halveres; lavere = strengere straf (standard 0,25)"
|
||||
},
|
||||
"phase_desc": {
|
||||
"anti_crease": "Lejlighedsvis korte tumblinger efter færdiggørelse for at reducere rynker.",
|
||||
@@ -957,6 +971,10 @@
|
||||
"triggers": {
|
||||
"intro": "Valgfrie eksterne signaler: en slutudløser, en dørsensor, en pausekontakt og aflæsningspåmindelsen.",
|
||||
"label": "Udløsere og døre"
|
||||
},
|
||||
"phase_eta": {
|
||||
"label": "Resterende tid",
|
||||
"intro": "Fasebevidst resterende tid, til maskiner hvis cykluslængde afhænger af temperatur eller centrifugering."
|
||||
}
|
||||
},
|
||||
"setting": {
|
||||
@@ -1040,6 +1058,10 @@
|
||||
"doc": "Fast pris pr. kWh brugt til omkostningstal, når der ikke er angivet en levende prisenhed ovenfor.",
|
||||
"label": "Statisk energipris (per kWh)"
|
||||
},
|
||||
"energy_sensor": {
|
||||
"doc": "Valgfri kumulativ energitæller (total_increasing i kWh/Wh, f.eks. stikkets egen levetidsmåler). Når den er angivet, tages hver cyklus' rapporterede energi fra denne tællers forskel mellem start og slut, hvilket undgår den undertælling, du får ved at integrere en langsomt rapporterende effektsensor. Falder tilbage til den integrerede værdi, hvis aflæsningen mangler, dens enhed er ukendt, eller forskellen ikke er positiv. Lad feltet stå tomt for at fortsætte med at integrere effektsensoren.",
|
||||
"label": "Energimålerenhed"
|
||||
},
|
||||
"expose_debug_entities": {
|
||||
"doc": "Udgiv ekstra diagnostiske HA-enheder (match konfidens, tvetydighed, interne tilstande). Fra holder enhedslisten ren til normal brug.",
|
||||
"label": "Vis fejlretningsenheder"
|
||||
@@ -1322,6 +1344,38 @@
|
||||
},
|
||||
"show_contributor": {
|
||||
"doc": "Viser tilskrivningen 'af <contributor>' på fællesskabsapparater og referencecyklusser."
|
||||
},
|
||||
"enable_phase_matching": {
|
||||
"label": "Fasebevidst resterende tid",
|
||||
"doc": "Opdel hver kørende cyklus i faser (opvarmning, vask, centrifugering) og budgettér den resterende tid pr. fase, blandet med det klassiske estimat - tidligt i cyklussen læner den sig op ad fasebudgettet og mod slutningen op ad det klassiske estimat. Dette tilpasser nedtællingen til, hvor længe din maskine faktisk varmer op og kører, hvilket er mest mærkbart i den første halvdel af en cyklus. Fra = kun det klassiske estimat. Kun visningen af resterende tid påvirkes; programmatchning og cyklusregistrering er uændrede."
|
||||
},
|
||||
"keep_min_score": {
|
||||
"label": "Min. matchingsscore",
|
||||
"doc": "Laveste lighedsscore en kandidat behøver for at forblive i matcheprocessen. Standard 0,1 er bevidst tillåtende – det tillader selv svage kandidater og stoler på at senere trin finder den bedste match. Hæv for at skære usandsynlige profiler fra tidligere; sænk for at udvide den indledende kandidatpulje."
|
||||
},
|
||||
"dtw_blend": {
|
||||
"label": "DTW-blanding",
|
||||
"doc": "Hvor meget DTW-justeringsscoren erstatter kerneresultatet fra Trin 2. 0 = brug kun Trin 2-scoren, 1 = brug kun DTW-scoren, 0,5 (standard) = ligelig blanding. Hæv for at stole mere på tidsjustering når programmer har ensartede effektniveauer men forskellige timingmønstre."
|
||||
},
|
||||
"dtw_ensemble_w": {
|
||||
"label": "DTW-ensemblemiks",
|
||||
"doc": "I ensemble-DTW-tilstand (standard) er dette vægten på skaleret L1 kontra derivativ DTW (DDTW). 1,0 = kun skaleret L1, 0 = kun DDTW, 0,7 = standard. Den skalerede variant sammenligner effektniveauer; den derivative reagerer på hvordan effekten ændres over tid. Ensemble blander begge."
|
||||
},
|
||||
"dtw_ddtw_scale": {
|
||||
"label": "Derivativ DTW-skala",
|
||||
"doc": "Halvmætningsafstand for derivativ DTW-scoring. Scoren halveres når DDTW-afstanden er lig denne værdi. Lavere = mere følsom for formforskelle. Standard 30 er kalibreret til typiske husholdningsapparaters effektprofiler. Påvirker kun ensemble- og ddtw-DTW-tilstande."
|
||||
},
|
||||
"dtw_refine_top_n": {
|
||||
"label": "DTW-forfiningsnummer",
|
||||
"doc": "Hvor mange topkandidater fra Trin 2 der gen-scores af DTW. DTW er mere kostbar så det anvendes kun på de N bedste. Standard 5. Hæv (til 7-9) hvis den korrekte profil sommetider kun når 4. eller 5. plads efter Trin 2 – DTW kan redde den. Lavere giver lidt hurtigere matching."
|
||||
},
|
||||
"duration_scale": {
|
||||
"label": "Varighedsskarphed",
|
||||
"doc": "Skarphed i Trin 4's straf for varighedsoverensstemmelse. Det er log-forholdet ved hvilket overensstemmelses-scoren halveres. Lavere = strengere: et varighedsafvigelse skader mere. Standard 0,175 svarer til omtrent 18% varighedstolerens ved halvvægt. Par med Varighedsvægt."
|
||||
},
|
||||
"energy_scale": {
|
||||
"label": "Energiskarphed",
|
||||
"doc": "Skarphed i Trin 4's straf for energioverensstemmelse. Lavere = strengere: et energiafvigelse skader mere. Standard 0,25 er bevidst mere tillåtende end varighedsskarphed fordi energi varierer med belastning. Par med Energivægt."
|
||||
}
|
||||
},
|
||||
"setting_group": {
|
||||
@@ -1766,6 +1820,69 @@
|
||||
},
|
||||
"pg_sweep": {
|
||||
"optimize": "Optimér: {param}"
|
||||
},
|
||||
"pg_detail": {
|
||||
"simulate": "Simulér cyklus"
|
||||
},
|
||||
"split": {
|
||||
"apply": "Opdeler cyklus"
|
||||
},
|
||||
"trim": {
|
||||
"apply": "Beskærer cyklus"
|
||||
},
|
||||
"merge": {
|
||||
"apply": "Sammenfletter cyklusser"
|
||||
},
|
||||
"rebuild": {
|
||||
"envelopes": "Genopbygger envelopes"
|
||||
},
|
||||
"cancelling": "Annullerer..."
|
||||
},
|
||||
"setup": {
|
||||
"hdr": {
|
||||
"card": "Apparatopsætning",
|
||||
"healthy_chip": "Opsætning fuldført"
|
||||
},
|
||||
"phase0": {
|
||||
"washer": "WashData registrerer allerede dine cyklusser. Optag din første cyklus for at aktivere programnavne og tidsestimater.",
|
||||
"dishwasher": "WashData holder øje. Opvaskemaskiner har komplekse cyklusser – det anbefales stærkt at optage din første cyklus. Hvis en registreret cyklus kører for længe, brug cyklus-editoren til at beskære den, inden du gemmer den som en profil.",
|
||||
"generic": "WashData holder øje. Optag eller mærk en registreret cyklus for at begynde at opbygge profiler."
|
||||
},
|
||||
"phase1a": {
|
||||
"labelled": "Godt gået – dit første program er gemt. For de reneste data kan du overveje at optage din næste cyklus med optagelses-widgetten."
|
||||
},
|
||||
"phase1b": {
|
||||
"recorded": "Din optagelse blev gemt som {profile_name}. Optag nu eller mærk dine andre hyppigt brugte programmer for at opbygge dækning."
|
||||
},
|
||||
"phase1c": {
|
||||
"verify": "Du har {count} programmer fra fællesskabet. Kør en cyklus for at bekræfte, at WashData genkender den korrekt – matchningen forbedres, efterhånden som din enhed opbygger sin egen historik."
|
||||
},
|
||||
"phase2": {
|
||||
"cluster": "WashData har set {count} cyklusser, der ikke matcher noget gemt program – de ligner hinanden. Vil du oprette en ny profil til dem?",
|
||||
"unmatched": "Din seneste cyklus matchede ikke noget gemt program. Er det et nyt program?"
|
||||
},
|
||||
"phase3": {
|
||||
"suggestions": "WashData har indstillingsanbefalinger baseret på din cyklushistorik – gennemgå dem for at forbedre registreringens nøjagtighed.",
|
||||
"groups": "Nogle af dine profiler ligner det samme program ved forskellige temperaturer. Organiser dem i en gruppe for bedre matchning.",
|
||||
"phases": "Tilføj programfaser til {profile_name} for mere præcise estimater af den resterende tid."
|
||||
},
|
||||
"phase4": {
|
||||
"healthy": "Dette apparat er fuldt opsat ({profile_count} profiler)."
|
||||
},
|
||||
"cta": {
|
||||
"start_recording": "Start optagelse",
|
||||
"label_detected_cycle": "Jeg har allerede en registreret cyklus – mærk den i stedet",
|
||||
"browse_cycles": "Gennemse cyklusser for at mærke en anden",
|
||||
"view_profiles": "Se dine profiler",
|
||||
"create_from_cluster": "Opret profil fra disse cyklusser",
|
||||
"create_profile": "Opret en profil til den",
|
||||
"review_suggestions": "Gennemgå anbefalinger",
|
||||
"organise_profiles": "Organiser profiler",
|
||||
"configure_phases": "Konfigurer faser",
|
||||
"skip_step": "Spring dette trin over",
|
||||
"skip_forever": "Vis ikke igen",
|
||||
"hide_guidance": "Skjul vejledning",
|
||||
"show_guidance": "Vis vejledning"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
"on_cycle_finished": "Ein Zyklus beendet",
|
||||
"on_cycle_started": "Ein Zyklus gestartet",
|
||||
"pause_cycle": "Pause",
|
||||
"pause_cycle_tip": "Laufenden Zyklus anhalten — das Gerät setzt dort fort, wo es aufgehört hat",
|
||||
"pause_cycle_tip": "Laufenden Zyklus anhalten – das Gerät setzt dort fort, wo es aufgehört hat",
|
||||
"pg_apply_device": "Auf Gerät anwenden",
|
||||
"pg_autofill": "Automatisch ausfüllen",
|
||||
"play": "Abspielen",
|
||||
@@ -97,8 +97,8 @@
|
||||
"process_tip": "Aufgezeichnete Datenspur als neues oder vorhandenes Profil speichern",
|
||||
"rebuild": "Umschläge neu erstellen",
|
||||
"rebuild_envelope": "Umschlag neu erstellen",
|
||||
"rebuild_tip": "Erwarteten Leistungsumschlag (Min./Max.-Band) für alle Profile aus deren beschrifteten Zyklen neu berechnen — nach dem Beschriften neuer oder Korrigieren alter Zyklen ausführen",
|
||||
"rec_start_tip": "Leistungsaufzeichnung des Geräts starten — kurz vor dem Starten eines Zyklus beginnen",
|
||||
"rebuild_tip": "Erwarteten Leistungsumschlag (Min./Max.-Band) für alle Profile aus deren beschrifteten Zyklen neu berechnen – nach dem Beschriften neuer oder Korrigieren alter Zyklen ausführen",
|
||||
"rec_start_tip": "Leistungsaufzeichnung des Geräts starten – kurz vor dem Starten eines Zyklus beginnen",
|
||||
"rec_stop": "Stoppen",
|
||||
"rec_stop_tip": "Aufnahme stoppen und die erfasste Datenspur zur Überprüfung bereitstellen",
|
||||
"record": "Aufnahme starten",
|
||||
@@ -231,7 +231,7 @@
|
||||
"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": "{n} Einstellungskonflikt{s} – markierte Abschnitte prüfen und vor dem Speichern beheben.",
|
||||
"settings_banner_btn": "Zum ersten"
|
||||
},
|
||||
"hdr": {
|
||||
@@ -451,9 +451,9 @@
|
||||
"show_expected": "Erwartete Kurvenüberlagerung anzeigen (angepasstes Profil, orange)",
|
||||
"show_raw": "Umschalter für rohe Steckdosenwerte im Live-Leistungsdiagramm anzeigen",
|
||||
"sparkline": "Trend der letzten Zyklusdauern",
|
||||
"stage2": "Stufe 2 — Kernähnlichkeit",
|
||||
"stage3": "Stufe 3 — DTW",
|
||||
"stage4": "Stufe 4 — Übereinstimmung",
|
||||
"stage2": "Stufe 2 – Kernähnlichkeit",
|
||||
"stage3": "Stufe 3 – DTW",
|
||||
"stage4": "Stufe 4 – Übereinstimmung",
|
||||
"status": "Status",
|
||||
"tail_trim": "Ende kürzen (s)",
|
||||
"timer_auto_pause": "Automatische Pause",
|
||||
@@ -561,7 +561,12 @@
|
||||
"flags": "Flags",
|
||||
"include_phase_map": "Phasenkarte einbeziehen",
|
||||
"include_settings": "Erkennungs- und Abgleicheinstellungen einbeziehen",
|
||||
"show_contributor": "Beiträgernamen anzeigen"
|
||||
"show_contributor": "Beiträgernamen anzeigen",
|
||||
"task_pg_detail": "Zyklus simulieren",
|
||||
"task_split": "Zyklus wird geteilt",
|
||||
"task_trim": "Zyklus wird zugeschnitten",
|
||||
"task_merge": "Zyklen werden zusammengeführt",
|
||||
"task_rebuild": "Hüllkurven werden neu aufgebaut"
|
||||
},
|
||||
"log": {
|
||||
"all_levels": "Alle Ebenen",
|
||||
@@ -645,7 +650,7 @@
|
||||
"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.",
|
||||
"artifact_header": "{n} Anomalien wurden während dieses Zyklus erkannt",
|
||||
"artifact_pause_detail": "Die Leistung fiel für ~{n}s nahezu auf null und wurde dann wieder aufgenommen — wahrscheinlich wurde die Tür während des Zyklus geöffnet oder der Zyklus wurde angehalten.",
|
||||
"artifact_pause_detail": "Die Leistung fiel für ~{n}s nahezu auf null und wurde dann wieder aufgenommen – wahrscheinlich wurde die Tür während des Zyklus geöffnet oder der Zyklus wurde angehalten.",
|
||||
"artifact_spike_detail": "Überstieg das übliche Leistungsband für ~{n}s.",
|
||||
"auto_label_intro": "Weisen Sie Profile unbeschrifteten Zyklen zu, deren Übereinstimmungskonfidenz den Schwellenwert überschreitet.",
|
||||
"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.",
|
||||
@@ -657,7 +662,7 @@
|
||||
"compare_selected_cycles": "Ausgewählte Zyklen (durchgehend) – ein-/ausblenden",
|
||||
"consider_new_profile": "Erwägen Sie die Erstellung eines neuen Profils.",
|
||||
"coverage_gap": "Die letzten Zyklen haben kein passendes Profil ({pct} % der letzten 30).",
|
||||
"coverage_gap_similar_cycles": "{count} ähnliche unbeschriftete Zyklen gefunden — erstellen Sie ein Profil, um diese zu erkennen.",
|
||||
"coverage_gap_similar_cycles": "{count} ähnliche unbeschriftete Zyklen gefunden – erstellen Sie ein Profil, um diese zu erkennen.",
|
||||
"cycles_deleted": "{count} Zyklen gelöscht",
|
||||
"enough_data": "Genügend Daten zum Lernen ({current}/{min} Zyklen).",
|
||||
"export_description": "Exportieren Sie alle Profile und Zyklen nach JSON oder stellen Sie einen vorherigen Export wieder her.",
|
||||
@@ -686,7 +691,7 @@
|
||||
"ml_learned_intro": "Auf diese Maschine abgestimmte Modelle.",
|
||||
"ml_loading": "ML wird geladen…",
|
||||
"ml_settings_intro": "Zwei unabhängige Schalter: Einer wendet die Modelle an, während ein Zyklus läuft, der andere ermöglicht es WashData, sie im Laufe der Zeit an Ihre Maschine anzupassen.",
|
||||
"name_first_program": "Sie haben genügend Zyklen — benennen Sie Ihr erstes Programm, um den Abgleich zu starten.",
|
||||
"name_first_program": "Sie haben genügend Zyklen – benennen Sie Ihr erstes Programm, um den Abgleich zu starten.",
|
||||
"near_duplicate_cluster": "Beinahe doppelter Profilcluster erkannt. Durch die Gruppierung kann beim Matching zuverlässig zwischen Doppelgängern ausgewählt werden (z. B. dasselbe Programm bei unterschiedlicher Temperatur/Schleuder).",
|
||||
"no_cycles_match": "Keine Zyklen entsprechen dem aktuellen Filter.",
|
||||
"no_cycles_profile": "Keine Zyklen für dieses Profil.",
|
||||
@@ -713,7 +718,7 @@
|
||||
"notify_services_hint": "Verwenden Sie {entity}-Dienst-IDs (kommagetrennt für mehrere). Template-Variablen: {vars}.",
|
||||
"old_actions_warning": "Konfiguriert mit dem alten Aktionseditor (jetzt entfernt). Sie werden weiterhin auf Zyklusereignisse ausgelöst, können hier jedoch nicht mehr bearbeitet werden. Wandeln Sie in eine normale Automatisierung um oder entfernen Sie sie.",
|
||||
"onboarding_progress": "{n} / 3 Zyklen beobachtet",
|
||||
"onboarding_watching": "Lassen Sie Ihr Gerät normal laufen — WashData beobachtet. Nach 3 Zyklen beginnt der Programmabgleich.",
|
||||
"onboarding_watching": "Lassen Sie Ihr Gerät normal laufen – WashData beobachtet. Nach 3 Zyklen beginnt der Programmabgleich.",
|
||||
"pending_feedback": "Ausstehende Rückmeldung zur Erkennung",
|
||||
"performance_trend": "Leistungstrend ({n} Zyklen)",
|
||||
"pg_analysis_empty": "Laden Sie einen Zyklus, um die Zuordnungsanalyse anzuzeigen.",
|
||||
@@ -763,7 +768,7 @@
|
||||
"setting_changed": "Geändert von {old} zu {new} am {date}",
|
||||
"settings_basic_note": "Es werden die wesentlichen Einstellungen angezeigt. Wechseln Sie zu Erweitert für die vollständige Liste.",
|
||||
"shape_drift_advisory": "⚠ Musterdrift",
|
||||
"shape_drift_detail": "Das Leistungsmuster dieses Profils hat sich im Laufe der Zeit verändert — möglicher Geräteverschleiß oder Wartung erforderlich (z. B. Entkalken, Filterreinigung).",
|
||||
"shape_drift_detail": "Das Leistungsmuster dieses Profils hat sich im Laufe der Zeit verändert – möglicher Geräteverschleiß oder Wartung erforderlich (z. B. Entkalken, Filterreinigung).",
|
||||
"show_all_settings": "Alle Einstellungen anzeigen",
|
||||
"showing_suggestions": "{count} Einstellung mit Vorschlägen wird angezeigt.",
|
||||
"split_intro": "Klicken Sie auf das Diagramm, um einen Teilungspunkt hinzuzufügen oder zu entfernen oder eine automatische Erkennung anhand von Leerlauflücken durchzuführen. Jedes resultierende Segment kann ein eigenes Profil erhalten.",
|
||||
@@ -857,7 +862,9 @@
|
||||
"share_guidelines_title": "Vor dem Teilen",
|
||||
"store_download_device_intro": "Übernehmen Sie alle geteilten Programme und deren Referenzzyklen auf Ihr Gerät. Ihre eigenen aufgezeichneten Zyklen und Statistiken bleiben unberührt.",
|
||||
"store_share_device_intro": "Laden Sie {brand} {model} mit den von Ihnen ausgewählten Referenzzyklen hoch. Andere mit demselben Gerät können Ihre Programme übernehmen. Einträge werden vor der öffentlichen Erscheinung geprüft.",
|
||||
"share_profile_no_cycles": "Keine Referenzzyklen -- markieren Sie einen Zyklus als ⭐ im Tab Zyklen, um dieses Profil einzubeziehen"
|
||||
"share_profile_no_cycles": "Keine Referenzzyklen -- markieren Sie einen Zyklus als ⭐ im Tab Zyklen, um dieses Profil einzubeziehen",
|
||||
"advisory_phase_inconsistent": "'{name}' scheint verschiedene Programme oder Temperaturen zu vermischen - seine Zyklen heizen unterschiedlich lange. Wenn Sie es in separate Profile aufteilen (z. B. pro Temperatur), verbessern sich Abgleich und Zeitschätzungen.",
|
||||
"advisory_phase_inconsistent_title": "⚠ Möglicherweise gemischte Programme"
|
||||
},
|
||||
"pg_desc": {
|
||||
"abrupt_drop_watts": "Plötzlicher Abfall gilt als sofortiges Ende",
|
||||
@@ -869,12 +876,19 @@
|
||||
"start_duration_threshold": "Sekunden über dem Schwellenwert, um den Start zu bestätigen",
|
||||
"start_threshold_w": "Mindestwattzahl, um als gestartet zu gelten",
|
||||
"stop_threshold_w": "Darunter gilt die Maschine als aus",
|
||||
"dtw_bandwidth": "Wie viel Zeitverzerrung der Formabgleich zulässt",
|
||||
"corr_weight": "Gewichtung von Kurvenform gegenüber Leistungspegel bei der Zuordnung",
|
||||
"duration_weight": "Wie stark die Übereinstimmung der Laufzeit die Zuordnung beeinflusst",
|
||||
"energy_weight": "Wie stark die Übereinstimmung des Energieverbrauchs die Zuordnung beeinflusst",
|
||||
"profile_match_min_duration_ratio": "Kürzester Durchlauf (im Vergleich zum Profil), der noch zugeordnet werden darf",
|
||||
"profile_match_max_duration_ratio": "Längster Durchlauf (im Vergleich zum Profil), der noch zugeordnet werden darf"
|
||||
"dtw_bandwidth": "Stufe 3: Sakoe-Chiba-Verzerrungsband (0 = DTW aus; Standard 0,2 = 20% der Zykluslänge)",
|
||||
"corr_weight": "Stufe 2: Balance zwischen Kurvenform (Korrelation) und Leistungspegel (MAE); Standard 0,45",
|
||||
"duration_weight": "Stufe 4: wie stark die Dauerübereinstimmung den Endscore beeinflusst (Standard 0,22)",
|
||||
"energy_weight": "Stufe 4: wie stark die Energieübereinstimmung den Endscore beeinflusst (Standard 0,22)",
|
||||
"profile_match_min_duration_ratio": "Stufe 1: minimale Zyklusdauer als Bruchteil der Profildauer; Standard 0,1 (10%)",
|
||||
"profile_match_max_duration_ratio": "Stufe 1: maximale Zyklusdauer als Bruchteil der Profildauer; Standard 1,5 (150%)",
|
||||
"keep_min_score": "Stufe 2: Mindest-Score, um im Auswahlverfahren zu bleiben; Standard 0,1 lässt schwache Kandidaten zu, spätere Stufen wählen den besten",
|
||||
"dtw_blend": "Stufe 3: 0 = nur Kernscore, 1 = nur DTW-Score, 0,5 = gleiche Mischung (Standard)",
|
||||
"dtw_ensemble_w": "Stufe 3 (Ensemble-Modus): Gewicht auf skaliertem L1 gegenüber Ableitungs-DTW; Standard 0,7 bevorzugt pegelabhängige Erkennung",
|
||||
"dtw_ddtw_scale": "Stufe 3: DDTW-Halbsättigungsabstand; kleiner = formempfindlicher (Standard 30)",
|
||||
"dtw_refine_top_n": "Stufe 3: per DTW neu bewertete Kandidaten; auf 7-9 erhöhen, wenn das richtige Profil auf Platz 4-5 liegt (Standard 5)",
|
||||
"duration_scale": "Stufe 4: Log-Verhältnis, bei dem die Dauerübereinstimmung halbiert wird; kleiner = strengere Strafe (Standard 0,175)",
|
||||
"energy_scale": "Stufe 4: Log-Verhältnis, bei dem die Energieübereinstimmung halbiert wird; kleiner = strengere Strafe (Standard 0,25)"
|
||||
},
|
||||
"phase_desc": {
|
||||
"anti_crease": "Gelegentliche kurze Trommelumwälzungen nach Abschluss, um Knitterung zu vermeiden.",
|
||||
@@ -957,6 +971,10 @@
|
||||
"triggers": {
|
||||
"intro": "Optionale externe Signale: ein Endauslöser, ein Türsensor, ein Pause-Schalter und die Entladeerinnerung.",
|
||||
"label": "Auslöser & Türen"
|
||||
},
|
||||
"phase_eta": {
|
||||
"label": "Verbleibende Zeit",
|
||||
"intro": "Phasenbewusste Restzeit, für Maschinen, deren Zyklusdauer von Temperatur oder Schleuderdrehzahl abhängt."
|
||||
}
|
||||
},
|
||||
"setting": {
|
||||
@@ -1040,6 +1058,10 @@
|
||||
"doc": "Fester Preis pro kWh, der für Kostenzahlen verwendet wird, wenn oben keine Live-Preiseinheit festgelegt ist.",
|
||||
"label": "Statischer Energiepreis (pro kWh)"
|
||||
},
|
||||
"energy_sensor": {
|
||||
"doc": "Optionaler kumulativer Energiezähler (total_increasing in kWh/Wh, z. B. der eigene Lebensdauerzähler der Steckdose). Wenn gesetzt, wird die gemeldete Energie jedes Zyklus aus der Differenz dieses Zählers zwischen Anfang und Ende ermittelt, was die Untererfassung vermeidet, die beim Integrieren eines langsam meldenden Leistungssensors entsteht. Greift auf den integrierten Wert zurück, wenn der Messwert fehlt, seine Einheit unbekannt ist oder die Differenz nicht positiv ausfällt. Leer lassen, um weiterhin den Leistungssensor zu integrieren.",
|
||||
"label": "Energiezähler-Entität"
|
||||
},
|
||||
"expose_debug_entities": {
|
||||
"doc": "Veröffentlichen Sie zusätzliche diagnostische HA-Entitäten (Übereinstimmungskonfidenz, Mehrdeutigkeit, Zustandsinterna). Aus sorgt dafür, dass die Entitätsliste für den normalen Gebrauch sauber bleibt.",
|
||||
"label": "Debug-Entitäten anzeigen"
|
||||
@@ -1322,6 +1344,38 @@
|
||||
},
|
||||
"show_contributor": {
|
||||
"doc": "Zeigt die Nennung 'von <contributor>' bei Community-Geräten und Referenzzyklen an."
|
||||
},
|
||||
"enable_phase_matching": {
|
||||
"label": "Phasenbewusste Restzeit",
|
||||
"doc": "Teilt jeden laufenden Zyklus in Phasen auf (Heizen, Waschen, Schleudern) und veranschlagt die verbleibende Zeit pro Phase, gemischt mit der klassischen Schätzung - zu Beginn des Zyklus stützt sie sich auf das Phasenbudget, gegen Ende auf die klassische Schätzung. Dadurch wird der Countdown darauf abgestimmt, wie lange Ihre Maschine tatsächlich heizt und läuft, was in der ersten Hälfte eines Zyklus am deutlichsten spürbar ist. Aus = nur die klassische Schätzung. Betroffen ist ausschließlich die Anzeige der verbleibenden Zeit; Programmabgleich und Zykluserkennung bleiben unverändert."
|
||||
},
|
||||
"keep_min_score": {
|
||||
"label": "Min. Match-Score",
|
||||
"doc": "Mindest-Ähnlichkeitsscore, den ein Kandidat benötigt, um im Auswahlverfahren zu bleiben. Der Standard 0,1 ist absichtlich permissiv - er lässt auch schwache Kandidaten zu und verlässt sich auf spätere Stufen, um die beste Übereinstimmung zu finden. Erhöhen, um unwahrscheinliche Profile früher auszuschließen; verringern, um den anfänglichen Kandidatenpool zu erweitern."
|
||||
},
|
||||
"dtw_blend": {
|
||||
"label": "Warp-Mischgewicht",
|
||||
"doc": "Wie stark der Zeitverzerrungsscore (DTW) den Kernscore der Stufe 2 ersetzt. 0 = nur Stufe-2-Score, 1 = nur DTW-Score, 0,5 (Standard) = gleiche Mischung. Erhöhen, um sich mehr auf die Warp-Ausrichtung zu verlassen, wenn Programme ähnliche Leistungspegel, aber unterschiedliche Zeitmuster aufweisen."
|
||||
},
|
||||
"dtw_ensemble_w": {
|
||||
"label": "Warp-Ensemble-Anteil",
|
||||
"doc": "Im Ensemble-DTW-Modus (Standard) das Gewicht auf skaliertem L1 gegenüber Ableitungs-DTW (DDTW). 1,0 = nur skaliertes L1, 0 = nur DDTW, 0,7 = Standard. Die skalierte L1-Variante vergleicht Leistungspegel; die Ableitungsvariante reagiert auf Leistungsänderungen im Zeitverlauf. Ensemble kombiniert beide."
|
||||
},
|
||||
"dtw_ddtw_scale": {
|
||||
"label": "Ableitungs-Warp-Skalierung",
|
||||
"doc": "Halbsättigungsabstand für die Ableitungs-DTW-Bewertung. Der Score halbiert sich, wenn die DDTW-Distanz diesen Wert erreicht. Kleiner = empfindlicher gegenüber Formunterschieden. Standard 30 ist auf typische Geräteleistungsverläufe kalibriert. Betrifft nur Ensemble- und DDTW-DTW-Modi."
|
||||
},
|
||||
"dtw_refine_top_n": {
|
||||
"label": "Warp-Verfeinerungsanzahl",
|
||||
"doc": "Anzahl der besten Stufe-2-Kandidaten, die per DTW neu bewertet werden. DTW ist aufwendiger, daher wird es nur auf die besten N Kandidaten angewendet. Standard 5. Erhöhen (auf 7-9), wenn das richtige Profil nach Stufe 2 manchmal nur auf Platz 4 oder 5 landet - DTW kann es noch retten. Verringern beschleunigt das Matching leicht."
|
||||
},
|
||||
"duration_scale": {
|
||||
"label": "Laufzeit-Trennschärfe",
|
||||
"doc": "Schärfe der Dauerübereinstimmungsstrafe in Stufe 4. Dies ist das Log-Verhältnis, bei dem der Übereinstimmungsscore halbiert wird. Kleiner = strenger: eine Dauerabweichung schadet mehr. Standard 0,175 entspricht etwa 18% Dauertoleranz beim halben Gewicht. Gemeinsam mit der Dauergewichtung anpassen."
|
||||
},
|
||||
"energy_scale": {
|
||||
"label": "Energie-Trennschärfe",
|
||||
"doc": "Schärfe der Energieübereinstimmungsstrafe. Kleiner = strenger: eine Energieabweichung schadet mehr. Standard 0,25 ist absichtlich nachsichtiger als die Dauerschärfe, da Energie lastabhängig schwankt. Gemeinsam mit der Energiegewichtung anpassen."
|
||||
}
|
||||
},
|
||||
"setting_group": {
|
||||
@@ -1766,6 +1820,69 @@
|
||||
},
|
||||
"pg_sweep": {
|
||||
"optimize": "Optimieren: {param}"
|
||||
},
|
||||
"pg_detail": {
|
||||
"simulate": "Zyklus simulieren"
|
||||
},
|
||||
"split": {
|
||||
"apply": "Zyklus wird geteilt"
|
||||
},
|
||||
"trim": {
|
||||
"apply": "Zyklus wird zugeschnitten"
|
||||
},
|
||||
"merge": {
|
||||
"apply": "Zyklen werden zusammengeführt"
|
||||
},
|
||||
"rebuild": {
|
||||
"envelopes": "Hüllkurven werden neu aufgebaut"
|
||||
},
|
||||
"cancelling": "Wird abgebrochen..."
|
||||
},
|
||||
"setup": {
|
||||
"hdr": {
|
||||
"card": "Gerät einrichten",
|
||||
"healthy_chip": "Einrichtung abgeschlossen"
|
||||
},
|
||||
"phase0": {
|
||||
"washer": "WashData erkennt bereits Ihre Zyklen. Nehmen Sie Ihren ersten Zyklus auf, um Programmnamen und Zeitschätzungen zu aktivieren.",
|
||||
"dishwasher": "WashData beobachtet. Geschirrspüler haben komplexe Zyklen – es wird dringend empfohlen, Ihren ersten Zyklus aufzunehmen. Falls ein erkannter Zyklus zu lang läuft, kürzen Sie ihn im Zyklus-Editor, bevor Sie ihn als Profil speichern.",
|
||||
"generic": "WashData beobachtet. Nehmen Sie einen Zyklus auf oder beschriften Sie einen erkannten Zyklus, um mit dem Aufbau von Profilen zu beginnen."
|
||||
},
|
||||
"phase1a": {
|
||||
"labelled": "Guter Start – Ihr erstes Programm ist gespeichert. Für die saubersten Daten empfiehlt es sich, den nächsten Zyklus mit dem Aufnahme-Widget aufzuzeichnen."
|
||||
},
|
||||
"phase1b": {
|
||||
"recorded": "Ihre Aufnahme wurde als {profile_name} gespeichert. Nehmen Sie nun Ihre anderen häufig verwendeten Programme auf oder beschriften Sie sie, um die Abdeckung zu verbessern."
|
||||
},
|
||||
"phase1c": {
|
||||
"verify": "Sie haben {count} Programme aus der Community. Führen Sie einen Zyklus durch, um zu überprüfen, ob WashData ihn korrekt erkennt – die Erkennung verbessert sich, je mehr Verlauf Ihr Gerät aufbaut."
|
||||
},
|
||||
"phase2": {
|
||||
"cluster": "WashData hat {count} Zyklen gesehen, die keinem gespeicherten Programm entsprechen – sie sehen einander ähnlich aus. Möchten Sie ein neues Profil dafür erstellen?",
|
||||
"unmatched": "Ihr letzter Zyklus hat keinem gespeicherten Programm entsprochen. Ist es ein neues Programm?"
|
||||
},
|
||||
"phase3": {
|
||||
"suggestions": "WashData hat Einstellungsempfehlungen basierend auf Ihrem Zyklusverlauf – überprüfen Sie sie, um die Erkennungsgenauigkeit zu verbessern.",
|
||||
"groups": "Einige Ihrer Profile sehen aus wie dasselbe Programm bei unterschiedlichen Temperaturen. Organisieren Sie sie in einer Gruppe für eine bessere Erkennung.",
|
||||
"phases": "Fügen Sie {profile_name} Programmphasen hinzu, um genauere Schätzungen der verbleibenden Zeit zu erhalten."
|
||||
},
|
||||
"phase4": {
|
||||
"healthy": "Dieses Gerät ist vollständig eingerichtet ({profile_count} Profile)."
|
||||
},
|
||||
"cta": {
|
||||
"start_recording": "Aufnahme starten",
|
||||
"label_detected_cycle": "Ich habe bereits einen erkannten Zyklus – stattdessen beschriften",
|
||||
"browse_cycles": "Zyklen durchsuchen, um einen weiteren zu beschriften",
|
||||
"view_profiles": "Ihre Profile anzeigen",
|
||||
"create_from_cluster": "Profil aus diesen Zyklen erstellen",
|
||||
"create_profile": "Ein Profil dafür erstellen",
|
||||
"review_suggestions": "Empfehlungen überprüfen",
|
||||
"organise_profiles": "Profile organisieren",
|
||||
"configure_phases": "Phasen konfigurieren",
|
||||
"skip_step": "Diesen Schritt überspringen",
|
||||
"skip_forever": "Nicht mehr anzeigen",
|
||||
"hide_guidance": "Anleitung ausblenden",
|
||||
"show_guidance": "Anleitung einblenden"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
{
|
||||
"badge": {
|
||||
"artifact_tip": "Εντοπίστηκαν {n} ανωμαλίες (π.χ. η πόρτα άνοιξε στα μέσα του κύκλου) — ανοίξτε για να τις δείτε στο γράφημα",
|
||||
"artifact_tip": "Εντοπίστηκαν {n} ανωμαλίες (π.χ. η πόρτα άνοιξε στα μέσα του κύκλου) – ανοίξτε για να τις δείτε στο γράφημα",
|
||||
"auto": "(αυτόματη ανίχνευση)",
|
||||
"built_in_tag": "ενσωματωμένο",
|
||||
"declining": "↘ φθίνουσα",
|
||||
"energy_low": "Χαμηλότερη κατανάλωση ενέργειας από το συνηθισμένο",
|
||||
"energy_spike": "Υψηλότερη κατανάλωση ενέργειας από το συνηθισμένο",
|
||||
"fair_fit": "αποδεκτή ποιότητα",
|
||||
"fair_fit_tip": "Μέτρια συνέπεια αντιστοίχισης — ορισμένοι κύκλοι που έχουν εκχωρηθεί σε αυτό το προφίλ έχουν χαμηλότερους βαθμούς εμπιστοσύνης. Επισημάνετε περισσότερους κύκλους ή εγγράψτε ξανά το προφίλ για να βελτιώσετε την ακρίβεια.",
|
||||
"fair_fit_tip": "Μέτρια συνέπεια αντιστοίχισης – ορισμένοι κύκλοι που έχουν εκχωρηθεί σε αυτό το προφίλ έχουν χαμηλότερους βαθμούς εμπιστοσύνης. Επισημάνετε περισσότερους κύκλους ή εγγράψτε ξανά το προφίλ για να βελτιώσετε την ακρίβεια.",
|
||||
"feedback_requested": "Ζητήθηκαν σχόλια",
|
||||
"golden_cycle": "Καταγεγραμμένος κύκλος αναφοράς",
|
||||
"improving": "↗ βελτίωση",
|
||||
@@ -16,7 +16,7 @@
|
||||
"overrun": "Έτρεξε περισσότερο από το συνηθισμένο",
|
||||
"underrun": "Ολοκληρώθηκε γρηγορότερα από το συνηθισμένο",
|
||||
"poor_fit": "κακή ποιότητα",
|
||||
"poor_fit_tip": "Ασυνεπές ιστορικό αντιστοίχισης — σκεφτείτε να δημιουργήσετε ξανά αυτό το προφίλ",
|
||||
"poor_fit_tip": "Ασυνεπές ιστορικό αντιστοίχισης – σκεφτείτε να δημιουργήσετε ξανά αυτό το προφίλ",
|
||||
"restart_gap_tip": "{n} κενό επανεκκίνησης HA: το ίχνος ισχύος έχει ένα κενό",
|
||||
"reviewed": "Αξιολογήθηκε",
|
||||
"steady": "→ σταθερό",
|
||||
@@ -87,7 +87,7 @@
|
||||
"on_cycle_finished": "Ο κύκλος ολοκληρώθηκε",
|
||||
"on_cycle_started": "Ο κύκλος ξεκίνησε",
|
||||
"pause_cycle": "Παύση",
|
||||
"pause_cycle_tip": "Παύση του εν λειτουργία κύκλου — η συσκευή θα συνεχίσει από εκεί που σταμάτησε",
|
||||
"pause_cycle_tip": "Παύση του εν λειτουργία κύκλου – η συσκευή θα συνεχίσει από εκεί που σταμάτησε",
|
||||
"pg_apply_device": "Εφαρμογή στη συσκευή",
|
||||
"pg_autofill": "Αυτόματη συμπλήρωση",
|
||||
"play": "Αναπαραγωγή",
|
||||
@@ -97,8 +97,8 @@
|
||||
"process_tip": "Αποθήκευση του καταγεγραμμένου ίχνους ως νέο ή υπάρχον προφίλ",
|
||||
"rebuild": "Ανακατασκευή φακέλων",
|
||||
"rebuild_envelope": "Ανακατασκευή φακέλου",
|
||||
"rebuild_tip": "Επανυπολογισμός του αναμενόμενου φακέλου ισχύος (ελάχιστο/μέγιστο εύρος) για όλα τα προφίλ από τους επισημασμένους τους κύκλους — εκτελέστε μετά από επισήμανση νέων κύκλων ή διόρθωση παλιών",
|
||||
"rec_start_tip": "Έναρξη καταγραφής του ίχνους ισχύος της συσκευής — ξεκινήστε λίγο πριν τη λειτουργία του κύκλου",
|
||||
"rebuild_tip": "Επανυπολογισμός του αναμενόμενου φακέλου ισχύος (ελάχιστο/μέγιστο εύρος) για όλα τα προφίλ από τους επισημασμένους τους κύκλους – εκτελέστε μετά από επισήμανση νέων κύκλων ή διόρθωση παλιών",
|
||||
"rec_start_tip": "Έναρξη καταγραφής του ίχνους ισχύος της συσκευής – ξεκινήστε λίγο πριν τη λειτουργία του κύκλου",
|
||||
"rec_stop": "Στάση",
|
||||
"rec_stop_tip": "Διακοπή εγγραφής και διατήρηση του καταγεγραμμένου ίχνους για αναθεώρηση",
|
||||
"record": "Ξεκινήστε την εγγραφή",
|
||||
@@ -182,7 +182,7 @@
|
||||
},
|
||||
"attn_sub": "Διορθώστε τις συγκρούσεις πριν αποθηκεύσετε",
|
||||
"attn_title": "{n} σύγκρουση{s} ρυθμίσεων",
|
||||
"settings_banner": "{n} σύγκρουση{s} ρυθμίσεων — ελέγξτε τα επισημασμένα τμήματα και διορθώστε πριν αποθηκεύσετε.",
|
||||
"settings_banner": "{n} σύγκρουση{s} ρυθμίσεων – ελέγξτε τα επισημασμένα τμήματα και διορθώστε πριν αποθηκεύσετε.",
|
||||
"settings_banner_btn": "Μετάβαση στο πρώτο",
|
||||
"confidence": {
|
||||
"auto": "Πρέπει να είναι μεγαλύτερο ή ίσο με το Κατώφλι Αντιστοίχισης ({match})",
|
||||
@@ -451,9 +451,9 @@
|
||||
"show_expected": "Εμφάνιση αναμενόμενης επικάλυψης καμπύλης (αντιστοιχισμένο προφίλ, πορτοκαλί)",
|
||||
"show_raw": "Εμφάνιση εναλλακτή ακατέργαστης πρίζας στο γράφημα ζωντανής ισχύος",
|
||||
"sparkline": "Τάση διάρκειας πρόσφατων κύκλων",
|
||||
"stage2": "Στάδιο 2 — βασική ομοιότητα",
|
||||
"stage3": "Στάδιο 3 — DTW",
|
||||
"stage4": "Στάδιο 4 — συμφωνία",
|
||||
"stage2": "Στάδιο 2 – βασική ομοιότητα",
|
||||
"stage3": "Στάδιο 3 – DTW",
|
||||
"stage4": "Στάδιο 4 – συμφωνία",
|
||||
"status": "Κατάσταση",
|
||||
"tail_trim": "Περικοπή ουράς",
|
||||
"timer_auto_pause": "Αυτόματη παύση",
|
||||
@@ -561,7 +561,12 @@
|
||||
"flags": "Σημαίες",
|
||||
"include_phase_map": "Συμπερίληψη χάρτη φάσεων",
|
||||
"include_settings": "Συμπερίληψη ρυθμίσεων ανίχνευσης & αντιστοίχισης",
|
||||
"show_contributor": "Εμφάνιση ονομάτων συνεισφερόντων"
|
||||
"show_contributor": "Εμφάνιση ονομάτων συνεισφερόντων",
|
||||
"task_pg_detail": "Προσομοίωση κύκλου",
|
||||
"task_split": "Διαχωρισμός κύκλου",
|
||||
"task_trim": "Περικοπή κύκλου",
|
||||
"task_merge": "Συγχώνευση κύκλων",
|
||||
"task_rebuild": "Ανακατασκευή φακέλων"
|
||||
},
|
||||
"log": {
|
||||
"all_levels": "Όλα τα επίπεδα",
|
||||
@@ -645,7 +650,7 @@
|
||||
"artifact_dip_detail": "Έπεσε κάτω από το συνηθισμένο εύρος ισχύος για ~{n}s.",
|
||||
"artifact_footer": "Επισημαίνεται στο παραπάνω γράφημα. Αυτά είναι παροδικά τεχνουργήματα (π.χ. η πόρτα άνοιξε στα μέσα του κύκλου), όχι απαραίτητα προβλήματα.",
|
||||
"artifact_header": "{n} ανωμαλίες που εντοπίστηκαν κατά τη διάρκεια αυτού του κύκλου",
|
||||
"artifact_pause_detail": "Η ισχύς έπεσε σχεδόν στο μηδέν για ~{n}s και μετά ανέκαμψε — πιθανώς η πόρτα άνοιξε στα μέσα του κύκλου ή ο κύκλος τέθηκε σε παύση.",
|
||||
"artifact_pause_detail": "Η ισχύς έπεσε σχεδόν στο μηδέν για ~{n}s και μετά ανέκαμψε – πιθανώς η πόρτα άνοιξε στα μέσα του κύκλου ή ο κύκλος τέθηκε σε παύση.",
|
||||
"artifact_spike_detail": "Υπερέβη το συνηθισμένο εύρος ισχύος για ~{n}s.",
|
||||
"auto_label_intro": "Εκχωρήστε προφίλ σε κύκλους χωρίς ετικέτα, των οποίων η εμπιστοσύνη αντιστοίχισης εξαλείφει το όριο.",
|
||||
"automations_intro": "Το WashData ενεργοποιεί συμβάντα {start} / {end} και εκθέτει οντότητες, οπότε οι ειδοποιήσεις και οι ενέργειες κατασκευάζονται καλύτερα ως κανονικοί αυτοματισμοί του Home Assistant. Οι αυτοματισμοί που χρησιμοποιούν αυτή τη συσκευή εμφανίζονται παρακάτω.",
|
||||
@@ -654,10 +659,10 @@
|
||||
"collecting_data": "Συλλογή δεδομένων: απαιτούνται ακόμη {need} κύκλος{plural} πριν ξεκινήσει η βελτιστοποίηση ({current}/{min}).",
|
||||
"compare_overlay_profiles": "Προφίλ επικάλυψης (ασθενώς)",
|
||||
"compare_profiles_tip": "Επικαλύψτε άλλους φακέλους προφίλ στο παραπάνω γράφημα για να δείτε ποιος ταιριάζει καλύτερα σε αυτόν τον κύκλο.",
|
||||
"compare_selected_cycles": "Επιλεγμένοι κύκλοι (συμπαγής) — εμφάνιση / απόκρυψη",
|
||||
"compare_selected_cycles": "Επιλεγμένοι κύκλοι (συμπαγής) – εμφάνιση / απόκρυψη",
|
||||
"consider_new_profile": "Σκεφτείτε να δημιουργήσετε ένα νέο προφίλ.",
|
||||
"coverage_gap": "οι πρόσφατοι κύκλοι δεν έχουν αντίστοιχο προφίλ ({pct}% των τελευταίων 30).",
|
||||
"coverage_gap_similar_cycles": "Βρέθηκαν {count} παρόμοιοι κύκλοι χωρίς ετικέτα — δημιουργήστε ένα προφίλ για να αρχίσετε την αντιστοίχισή τους.",
|
||||
"coverage_gap_similar_cycles": "Βρέθηκαν {count} παρόμοιοι κύκλοι χωρίς ετικέτα – δημιουργήστε ένα προφίλ για να αρχίσετε την αντιστοίχισή τους.",
|
||||
"cycles_deleted": "Διαγράφηκαν {count} κύκλοι",
|
||||
"enough_data": "Αρκετά δεδομένα για εκμάθηση ({current}/{min} κύκλοι).",
|
||||
"export_description": "Εξαγωγή όλων των προφίλ και των κύκλων σε JSON ή επαναφορά από προηγούμενη εξαγωγή.",
|
||||
@@ -686,7 +691,7 @@
|
||||
"ml_learned_intro": "Μοντέλα προσαρμοσμένα σε αυτό το μηχάνημα.",
|
||||
"ml_loading": "φόρτωση ML…",
|
||||
"ml_settings_intro": "Δύο ανεξάρτητοι διακόπτες: ο ένας εφαρμόζει τα μοντέλα ενώ εκτελείται ένας κύκλος, ο άλλος επιτρέπει στην WashData να τα ρυθμίσει με ακρίβεια στο μηχάνημά σας με την πάροδο του χρόνου.",
|
||||
"name_first_program": "Έχετε αρκετούς κύκλους — ονομάστε το πρώτο σας πρόγραμμα για να ξεκινήσει η αντιστοίχιση.",
|
||||
"name_first_program": "Έχετε αρκετούς κύκλους – ονομάστε το πρώτο σας πρόγραμμα για να ξεκινήσει η αντιστοίχιση.",
|
||||
"near_duplicate_cluster": "Εντοπίστηκε σχεδόν διπλό σύμπλεγμα προφίλ. Η ομαδοποίηση επιτρέπει την αξιόπιστη επιλογή αντιστοίχισης μεταξύ ομοίων (π.χ. ίδιο πρόγραμμα σε διαφορετική θερμοκρασία/περιστροφή).",
|
||||
"no_cycles_match": "Κανένας κύκλος δεν ταιριάζει με το τρέχον φίλτρο.",
|
||||
"no_cycles_profile": "Δεν υπάρχουν κύκλοι για αυτό το προφίλ.",
|
||||
@@ -696,7 +701,7 @@
|
||||
"no_devices": "Δεν έχουν διαμορφωθεί ακόμη συσκευές WashData.",
|
||||
"no_envelope": "Δεν υπάρχει ακόμη φάκελος - ανακατασκευή μετά από κύκλους ετικετών.",
|
||||
"no_envelope_overlay": "Δεν υπάρχει διαθέσιμος φάκελος για επικάλυψη.",
|
||||
"no_fine_tuned": "Τίποτα δεν έχει βελτιωθεί ακόμα — Η WashData χρησιμοποιεί τα ενσωματωμένα μοντέλα της.",
|
||||
"no_fine_tuned": "Τίποτα δεν έχει βελτιωθεί ακόμα – Η WashData χρησιμοποιεί τα ενσωματωμένα μοντέλα της.",
|
||||
"no_logs": "Δεν υπάρχουν ακόμα εγγραφές καταγραφής στην προσωρινή μνήμη.",
|
||||
"no_maintenance": "Δεν έχει καταγραφεί συντήρηση ακόμα.",
|
||||
"no_match_yet": "Καμία προσπάθεια αγώνα ακόμα - συμπληρώνεται κατά τη διάρκεια ενός κύκλου τρεξίματος.",
|
||||
@@ -713,7 +718,7 @@
|
||||
"notify_services_hint": "Χρησιμοποιήστε αναγνωριστικά υπηρεσιών {entity} (χωρισμένα με κόμμα για πολλαπλά). Μεταβλητές προτύπου: {vars}.",
|
||||
"old_actions_warning": "Διαμορφώθηκε με το παλιό πρόγραμμα επεξεργασίας ενεργειών (τώρα καταργήθηκε). Εξακολουθούν να ενεργοποιούνται σε συμβάντα κύκλου, αλλά δεν είναι πλέον δυνατή η επεξεργασία τους εδώ. Μετατρέψτε τα σε κανονικό αυτοματισμό ή αφαιρέστε τα.",
|
||||
"onboarding_progress": "{n} / 3 κύκλοι παρατηρήθηκαν",
|
||||
"onboarding_watching": "Αφήστε τη συσκευή σας να λειτουργεί κανονικά — το WashData παρακολουθεί. Μετά από 3 κύκλους, θα ξεκινήσει η αντιστοίχιση προγραμμάτων.",
|
||||
"onboarding_watching": "Αφήστε τη συσκευή σας να λειτουργεί κανονικά – το WashData παρακολουθεί. Μετά από 3 κύκλους, θα ξεκινήσει η αντιστοίχιση προγραμμάτων.",
|
||||
"pending_feedback": "Εκκρεμεί σχόλια ανίχνευσης",
|
||||
"performance_trend": "Τάση απόδοσης ({n} κύκλοι)",
|
||||
"pg_analysis_empty": "Φορτώστε έναν κύκλο για να δείτε την ανάλυση αντιστοίχισης.",
|
||||
@@ -763,7 +768,7 @@
|
||||
"setting_changed": "Άλλαξε από {old} σε {new} στις {date}",
|
||||
"settings_basic_note": "Εμφανίζονται οι βασικές ρυθμίσεις. Μεταβείτε στο Για προχωρημένους για την πλήρη λίστα.",
|
||||
"shape_drift_advisory": "⚠ Απόκλιση σχήματος",
|
||||
"shape_drift_detail": "Το μοτίβο ισχύος αυτού του προφίλ έχει αλλάξει με την πάροδο του χρόνου — πιθανή φθορά της συσκευής ή απαιτείται συντήρηση (π.χ. αφαλάτωση, καθαρισμός φίλτρου).",
|
||||
"shape_drift_detail": "Το μοτίβο ισχύος αυτού του προφίλ έχει αλλάξει με την πάροδο του χρόνου – πιθανή φθορά της συσκευής ή απαιτείται συντήρηση (π.χ. αφαλάτωση, καθαρισμός φίλτρου).",
|
||||
"show_all_settings": "Εμφάνιση όλων των ρυθμίσεων",
|
||||
"showing_suggestions": "Εμφάνιση ρύθμισης {count} με προτάσεις.",
|
||||
"split_intro": "Κάντε κλικ στο γράφημα για να προσθέσετε ή να αφαιρέσετε ένα σημείο διαίρεσης ή για αυτόματη ανίχνευση με κενά αδράνειας. Κάθε τμήμα που προκύπτει μπορεί να αποκτήσει το δικό του προφίλ.",
|
||||
@@ -789,10 +794,10 @@
|
||||
"toast_revert_failed": "Η επαναφορά απέτυχε: {error}",
|
||||
"toast_reverted": "Έγινε επαναφορά: {key}",
|
||||
"toast_save_failed": "Η αποθήκευση απέτυχε: {error}",
|
||||
"trend_duration_longer": "Μεγαλύτερη τάση διάρκειας ({pct}%/κύκλος) — πρόσφατος μέσος όρος {avg}",
|
||||
"trend_duration_shorter": "Μικρότερη τάση διάρκειας ({pct}%/κύκλος) — πρόσφατος μέσος όρος {avg}",
|
||||
"trend_duration_longer": "Μεγαλύτερη τάση διάρκειας ({pct}%/κύκλος) – πρόσφατος μέσος όρος {avg}",
|
||||
"trend_duration_shorter": "Μικρότερη τάση διάρκειας ({pct}%/κύκλος) – πρόσφατος μέσος όρος {avg}",
|
||||
"trend_energy_down": "Πτωτική τάση ενέργειας ({pct}%/κύκλος)",
|
||||
"trend_energy_up": "Ανοδικές τάσεις ενέργειας ({pct}%/κύκλος) — πρόσφατος μέσος όρος {avg}",
|
||||
"trend_energy_up": "Ανοδικές τάσεις ενέργειας ({pct}%/κύκλος) – πρόσφατος μέσος όρος {avg}",
|
||||
"trim_intro": "Σύρετε τις κόκκινες λαβές ή εισαγάγετε τιμές. Όλα έξω από το παράθυρο αφαιρούνται.",
|
||||
"tuning_suggestions_available": "{count} πρόταση συντονισμού διαθέσιμη από παρατηρούμενους κύκλους. Εμφανίζονται δίπλα στα σχετικά πεδία.",
|
||||
"unsure_detected_prefix": "Το WashData δεν είναι βέβαιο ότι εντόπισε",
|
||||
@@ -857,7 +862,9 @@
|
||||
"share_guidelines_title": "Πριν κοινοποιήσετε",
|
||||
"store_download_device_intro": "Υιοθετήστε κάθε κοινοποιημένο πρόγραμμα και τους κύκλους αναφοράς του στη συσκευή σας. Οι δικοί σας καταγεγραμμένοι κύκλοι και στατιστικά δεν επηρεάζονται.",
|
||||
"store_share_device_intro": "Ανεβάστε {brand} {model} με τους κύκλους αναφοράς που επιλέγετε. Άλλοι με την ίδια συσκευή μπορούν να υιοθετήσουν τα προγράμματά σας. Οι καταχωρίσεις ελέγχονται πριν εμφανιστούν δημόσια.",
|
||||
"share_profile_no_cycles": "Δεν υπάρχουν κύκλοι αναφοράς -- επισημάνετε έναν κύκλο ως ⭐ στην καρτέλα Κύκλοι για να συμπεριλάβετε αυτό το προφίλ"
|
||||
"share_profile_no_cycles": "Δεν υπάρχουν κύκλοι αναφοράς -- επισημάνετε έναν κύκλο ως ⭐ στην καρτέλα Κύκλοι για να συμπεριλάβετε αυτό το προφίλ",
|
||||
"advisory_phase_inconsistent": "Το '{name}' φαίνεται να αναμειγνύει διαφορετικά προγράμματα ή θερμοκρασίες - οι κύκλοι του θερμαίνονται για πολύ διαφορετικά χρονικά διαστήματα. Ο διαχωρισμός του σε ξεχωριστά προφίλ (π.χ. ανά θερμοκρασία) θα βελτιώσει την αντιστοίχιση και τις εκτιμήσεις χρόνου.",
|
||||
"advisory_phase_inconsistent_title": "⚠ Πιθανώς μεικτά προγράμματα"
|
||||
},
|
||||
"phase_desc": {
|
||||
"anti_crease": "Περιστασιακά σύντομες ανατροπές μετά την ολοκλήρωση για μείωση των ρυτίδων.",
|
||||
@@ -940,6 +947,10 @@
|
||||
"triggers": {
|
||||
"intro": "Προαιρετικά εξωτερικά σήματα: ενεργοποιητής τέλους, αισθητήρας πόρτας, διακόπτης παύσης και υπενθύμιση αποφόρτωσης.",
|
||||
"label": "Ενεργοποιητές & Πόρτες"
|
||||
},
|
||||
"phase_eta": {
|
||||
"label": "Υπολειπόμενος Χρόνος",
|
||||
"intro": "Υπολειπόμενος χρόνος με επίγνωση φάσεων, για μηχανές των οποίων η διάρκεια κύκλου εξαρτάται από τη θερμοκρασία ή το στύψιμο."
|
||||
}
|
||||
},
|
||||
"setting": {
|
||||
@@ -1023,6 +1034,10 @@
|
||||
"doc": "Σταθερή τιμή ανά kWh που χρησιμοποιείται για τα στοιχεία κόστους όταν δεν έχει οριστεί παραπάνω οντότητα ζωντανής τιμής.",
|
||||
"label": "Στατική Τιμή Ενέργειας (ανά kWh)"
|
||||
},
|
||||
"energy_sensor": {
|
||||
"doc": "Προαιρετικός αθροιστικός μετρητής ενέργειας (total_increasing kWh/Wh, π.χ. ο ίδιος ο μετρητής συνολικής κατανάλωσης της πρίζας). Όταν οριστεί, η αναφερόμενη ενέργεια κάθε κύκλου λαμβάνεται από τη διαφορά αυτού του μετρητή από την αρχή έως το τέλος, γεγονός που αποφεύγει την υποκαταμέτρηση που προκύπτει από την ολοκλήρωση ενός αισθητήρα ισχύος που αναφέρει αργά. Επανέρχεται στην ολοκληρωμένη τιμή αν η ένδειξη λείπει, η μονάδα της είναι άγνωστη ή η διαφορά δεν είναι θετική. Αφήστε το κενό για να συνεχιστεί η ολοκλήρωση του αισθητήρα ισχύος.",
|
||||
"label": "Οντότητα Μετρητή Ενέργειας"
|
||||
},
|
||||
"expose_debug_entities": {
|
||||
"doc": "Δημοσιεύστε επιπλέον διαγνωστικές οντότητες HA (εμπιστοσύνη αντιστοίχισης, ασάφεια, εσωτερικά στοιχεία κατάστασης). Το Off διατηρεί τη λίστα οντοτήτων καθαρή για κανονική χρήση.",
|
||||
"label": "Εμφάνιση Οντοτήτων Αποσφαλμάτωσης"
|
||||
@@ -1305,6 +1320,38 @@
|
||||
},
|
||||
"show_contributor": {
|
||||
"doc": "Εμφάνιση της ένδειξης \"από <συνεισφέρων>\" στις κοινοτικές συσκευές και τους κύκλους αναφοράς."
|
||||
},
|
||||
"enable_phase_matching": {
|
||||
"label": "Υπολειπόμενος χρόνος με επίγνωση φάσεων",
|
||||
"doc": "Χωρίστε κάθε κύκλο που εκτελείται σε φάσεις (θέρμανση, πλύση, στύψιμο) και κατανείμετε τον υπολειπόμενο χρόνο ανά φάση, συνδυασμένο με την κλασική εκτίμηση - στηριζόμενοι στην κατανομή ανά φάση στην αρχή του κύκλου και στην κλασική εκτίμηση κοντά στο τέλος. Αυτό προσαρμόζει την αντίστροφη μέτρηση στο πόση ώρα πραγματικά θερμαίνεται και λειτουργεί η μηχανή σας, κάτι που είναι πιο εμφανές στο πρώτο μισό ενός κύκλου. Off = μόνο η κλασική εκτίμηση. Επηρεάζεται μόνο η ένδειξη υπολειπόμενου χρόνου· η αντιστοίχιση προγραμμάτων και η ανίχνευση κύκλου παραμένουν αμετάβλητες."
|
||||
},
|
||||
"keep_min_score": {
|
||||
"label": "Ελάχ. Βαθμός Αντιστοίχισης",
|
||||
"doc": "Ελάχιστη βαθμολογία ομοιότητας για παραμονή υποψηφίου στον αγώνα αντιστοίχισης. Η προεπιλογή 0.1 είναι εκ προθέσεως επιεικής - επιτρέπει ακόμη και αδύναμους υποψηφίους, αφήνοντας τα επόμενα στάδια να βρουν το καλύτερο ταίριασμα. Αυξήστε για πρώιμο αποκλεισμό απίθανων προφίλ; μειώστε για διεύρυνση της αρχικής ομάδας υποψηφίων."
|
||||
},
|
||||
"dtw_blend": {
|
||||
"label": "Ανάμειξη DTW",
|
||||
"doc": "Σε ποιο βαθμό ο βαθμός ευθυγράμμισης DTW αντικαθιστά τον βαθμό πυρήνα Σταδίου 2. 0 = μόνο ο βαθμός Σταδίου 2, 1 = μόνο ο βαθμός DTW, 0.5 (προεπιλογή) = ισόρροπη ανάμειξη. Αυξήστε για μεγαλύτερη εξάρτηση από ευθυγράμμιση παραμόρφωσης όταν τα προγράμματα έχουν παρόμοια επίπεδα ισχύος αλλά διαφορετικά χρονικά πρότυπα."
|
||||
},
|
||||
"dtw_ensemble_w": {
|
||||
"label": "Σύνολο DTW",
|
||||
"doc": "Στη λειτουργία συνόλου DTW (η προεπιλογή), το βάρος στο κλιμακωμένο L1 έναντι παραγώγου DTW (DDTW). 1.0 = πλήρως κλιμακωμένο-L1, 0 = πλήρως DDTW, 0.7 = προεπιλογή. Η παραλλαγή κλιμακωμένου-L1 συγκρίνει επίπεδα ισχύος; η παραγώγου παραλλαγή ανταποκρίνεται στο πώς μεταβάλλεται η ισχύς. Το σύνολο συνδυάζει και τα δύο."
|
||||
},
|
||||
"dtw_ddtw_scale": {
|
||||
"label": "Κλίμακα DDTW",
|
||||
"doc": "Απόσταση ημίσεος κορεσμού για τη βαθμολόγηση παραγώγου DTW. Η βαθμολογία υποδιπλασιάζεται όταν η απόσταση DDTW ισούται με αυτήν την τιμή. Μικρότερη = μεγαλύτερη ευαισθησία σε διαφορές σχήματος. Η προεπιλογή 30 είναι βαθμονομημένη στα τυπικά ίχνη ισχύος οικιακών συσκευών. Επηρεάζει μόνο τις λειτουργίες DTW συνόλου και ddtw."
|
||||
},
|
||||
"dtw_refine_top_n": {
|
||||
"label": "Αριθμός Εκλέπτυνσης DTW",
|
||||
"doc": "Πόσοι κορυφαίοι υποψήφιοι Σταδίου 2 επαναβαθμολογούνται από DTW. Η DTW είναι πιο ακριβή υπολογιστικά, οπότε εφαρμόζεται μόνο στους καλύτερους N υποψηφίους. Προεπιλογή 5. Αυξήστε (σε 7-9) αν το σωστό προφίλ φτάνει μερικές φορές μόνο στη 4η ή 5η θέση μετά το Στάδιο 2 - η DTW μπορεί να το σώσει. Η μείωση επιταχύνει ελαφρώς την αντιστοίχιση."
|
||||
},
|
||||
"duration_scale": {
|
||||
"label": "Ευαισθησία Διάρκειας",
|
||||
"doc": "Αυστηρότητα της ποινής συμφωνίας διάρκειας Σταδίου 4. Αυτός είναι ο λόγος λογαρίθμου στον οποίο ο βαθμός συμφωνίας υποδιπλασιάζεται. Μικρότερος = αυστηρότερος: μια ασυμφωνία διάρκειας επηρεάζει περισσότερο. Η προεπιλογή 0.175 αντιστοιχεί σε ανοχή διάρκειας περίπου 18% στο μισό βάρος. Χρησιμοποιήστε μαζί με το Βάρος Διάρκειας."
|
||||
},
|
||||
"energy_scale": {
|
||||
"label": "Ευαισθησία Ενέργειας",
|
||||
"doc": "Αυστηρότητα της ποινής συμφωνίας ενέργειας Σταδίου 4. Μικρότερος = αυστηρότερος: μια ασυμφωνία ενέργειας επηρεάζει περισσότερο. Η προεπιλογή 0.25 είναι εκ προθέσεως πιο επιεικής από την Ευαισθησία Διάρκειας επειδή η ενέργεια ποικίλλει με το φορτίο. Χρησιμοποιήστε μαζί με το Βάρος Ενέργειας."
|
||||
}
|
||||
},
|
||||
"setting_group": {
|
||||
@@ -1553,24 +1600,24 @@
|
||||
"lower": "Επισημαίνει αυτόματα περισσότερους κύκλους; κάποιοι ενδέχεται να αναγνωριστούν λανθασμένα"
|
||||
},
|
||||
"duration_tolerance": {
|
||||
"higher": "Αποδέχεται ευρύτερο εύρος διάρκειας — πιο ευέλικτη αντιστοίχιση",
|
||||
"lower": "Απαιτεί πιο ακριβή αντιστοίχιση διάρκειας — αυστηρότερο, μπορεί να απορρίψει ασυνήθεις κύκλους"
|
||||
"higher": "Αποδέχεται ευρύτερο εύρος διάρκειας – πιο ευέλικτη αντιστοίχιση",
|
||||
"lower": "Απαιτεί πιο ακριβή αντιστοίχιση διάρκειας – αυστηρότερο, μπορεί να απορρίψει ασυνήθεις κύκλους"
|
||||
},
|
||||
"end_energy_threshold": {
|
||||
"higher": "Κλείνει μόνο κύκλους που κατανάλωσαν σημαντική ενέργεια",
|
||||
"lower": "Κλείνει και συντομότερους ή χαμηλής ενέργειας κύκλους"
|
||||
},
|
||||
"end_repeat_count": {
|
||||
"higher": "Απαιτεί επανάληψη του σήματος λήξης περισσότερες φορές — πιο αξιόπιστο, ελαφρώς πιο αργό",
|
||||
"lower": "Τερματίζει μετά από λιγότερες επαναλήψεις — ταχύτερη ανίχνευση, μεγαλύτερος κίνδυνος ψευδούς λήξης"
|
||||
"higher": "Απαιτεί επανάληψη του σήματος λήξης περισσότερες φορές – πιο αξιόπιστο, ελαφρώς πιο αργό",
|
||||
"lower": "Τερματίζει μετά από λιγότερες επαναλήψεις – ταχύτερη ανίχνευση, μεγαλύτερος κίνδυνος ψευδούς λήξης"
|
||||
},
|
||||
"learning_confidence": {
|
||||
"higher": "Μαθαίνει μόνο από πολύ σίγουρες αντιστοιχίσεις — πιο αργό αλλά πιο αξιόπιστο",
|
||||
"higher": "Μαθαίνει μόνο από πολύ σίγουρες αντιστοιχίσεις – πιο αργό αλλά πιο αξιόπιστο",
|
||||
"lower": "Μαθαίνει από περισσότερους κύκλους; το μοντέλο μπορεί να έχει περισσότερο θόρυβο"
|
||||
},
|
||||
"min_off_gap": {
|
||||
"higher": "Απαιτείται μεγαλύτερη αδράνεια πριν ξεκινήσει νέος κύκλος",
|
||||
"lower": "Σύντομη αδράνεια εκκινεί νέο κύκλο — διαδοχικές λειτουργίες μπορεί να διαχωριστούν"
|
||||
"lower": "Σύντομη αδράνεια εκκινεί νέο κύκλο – διαδοχικές λειτουργίες μπορεί να διαχωριστούν"
|
||||
},
|
||||
"min_power": {
|
||||
"higher": "Λιγότερο ευαίσθητο στην κατανάλωση αδράνειας; μπορεί να χάσει ήσυχα προγράμματα",
|
||||
@@ -1581,24 +1628,24 @@
|
||||
"lower": "Αναγκαστική διακοπή κολλημένου κύκλου νωρίτερα"
|
||||
},
|
||||
"off_delay": {
|
||||
"higher": "Περισσότερος χρόνος για παύσεις συσκευής — χειρίζεται μακρά εμποτίσματα ή φάσεις στεγνώματος",
|
||||
"lower": "Ταχύτερη ανίχνευση λήξης — καλό για συσκευές με καθαρό ενεργό/ανενεργό"
|
||||
"higher": "Περισσότερος χρόνος για παύσεις συσκευής – χειρίζεται μακρά εμποτίσματα ή φάσεις στεγνώματος",
|
||||
"lower": "Ταχύτερη ανίχνευση λήξης – καλό για συσκευές με καθαρό ενεργό/ανενεργό"
|
||||
},
|
||||
"profile_match_threshold": {
|
||||
"higher": "Επιβεβαιώνει μόνο αντιστοιχίσεις υψηλής εμπιστοσύνης; περισσότεροι κύκλοι παραμένουν χωρίς ετικέτα",
|
||||
"lower": "Αντιστοιχεί περισσότερους κύκλους; κάποιοι μπορεί να είναι ελαφρώς λανθασμένοι"
|
||||
},
|
||||
"running_dead_zone": {
|
||||
"higher": "Αγνοεί σύντομες αιχμές ισχύος κατά την αδράνεια — λιγότερο ευαίσθητο σε θόρυβο",
|
||||
"lower": "Ανταποκρίνεται σε συντομότερες αναλαμπές ισχύος — εντοπίζει γρήγορη παροδική δραστηριότητα"
|
||||
"higher": "Αγνοεί σύντομες αιχμές ισχύος κατά την αδράνεια – λιγότερο ευαίσθητο σε θόρυβο",
|
||||
"lower": "Ανταποκρίνεται σε συντομότερες αναλαμπές ισχύος – εντοπίζει γρήγορη παροδική δραστηριότητα"
|
||||
},
|
||||
"start_threshold_w": {
|
||||
"higher": "Αποφεύγει ψευδείς εκκινήσεις από σύντομες αιχμές ισχύος",
|
||||
"lower": "Εντοπίζει προγράμματα χαμηλής ισχύος; μπορεί να ενεργοποιηθεί από θόρυβο"
|
||||
},
|
||||
"stop_threshold_w": {
|
||||
"higher": "Τερματίζει τον κύκλο γρηγορότερα — μπορεί να κλείσει κατά τη διάρκεια παύσης",
|
||||
"lower": "Αναμένει περισσότερο για τερματισμό — λιγότερες πρόωρες ολοκληρώσεις"
|
||||
"higher": "Τερματίζει τον κύκλο γρηγορότερα – μπορεί να κλείσει κατά τη διάρκεια παύσης",
|
||||
"lower": "Αναμένει περισσότερο για τερματισμό – λιγότερες πρόωρες ολοκληρώσεις"
|
||||
},
|
||||
"watchdog_interval": {
|
||||
"higher": "Επιτρέπονται μακρύτερες ήσυχες φάσεις; λιγότερες ψευδείς αναγκαστικές διακοπές",
|
||||
@@ -1676,12 +1723,19 @@
|
||||
"start_duration_threshold": "Δευτερόλεπτα πάνω από το κατώφλι για επιβεβαίωση εκκίνησης",
|
||||
"start_threshold_w": "Ελάχιστα watt για να θεωρηθεί ότι ξεκίνησε",
|
||||
"stop_threshold_w": "Κάτω από αυτό, το μηχάνημα θεωρείται εκτός λειτουργίας",
|
||||
"dtw_bandwidth": "Πόση χρονική παραμόρφωση επιτρέπει η αντιστοίχιση σχήματος",
|
||||
"corr_weight": "Βάρος του σχήματος καμπύλης έναντι του επιπέδου ισχύος στην αντιστοίχιση",
|
||||
"duration_weight": "Πόσο επηρεάζει η συμφωνία διάρκειας την αντιστοίχιση",
|
||||
"energy_weight": "Πόσο επηρεάζει η συμφωνία ενέργειας την αντιστοίχιση",
|
||||
"profile_match_min_duration_ratio": "Ο συντομότερος κύκλος (σε σχέση με το προφίλ) που επιτρέπεται ακόμη να ταιριάξει",
|
||||
"profile_match_max_duration_ratio": "Ο μακρύτερος κύκλος (σε σχέση με το προφίλ) που επιτρέπεται ακόμη να ταιριάξει"
|
||||
"dtw_bandwidth": "Στάδιο 3: ζώνη παραμόρφωσης Sakoe-Chiba (0 = DTW ανενεργό; προεπιλογή 0.2 = 20% μήκους κύκλου)",
|
||||
"corr_weight": "Στάδιο 2: ισορροπία μεταξύ σχήματος καμπύλης (συσχέτιση) και επιπέδου ισχύος (MAE); προεπιλογή 0.45",
|
||||
"duration_weight": "Στάδιο 4: πόσο επηρεάζει η συμφωνία διάρκειας τον τελικό βαθμό (προεπιλογή 0.22)",
|
||||
"energy_weight": "Στάδιο 4: πόσο επηρεάζει η συμφωνία ενέργειας τον τελικό βαθμό (προεπιλογή 0.22)",
|
||||
"profile_match_min_duration_ratio": "Στάδιο 1: ελάχιστο μήκος κύκλου ως κλάσμα της διάρκειας προφίλ; προεπιλογή 0.1 (10%)",
|
||||
"profile_match_max_duration_ratio": "Στάδιο 1: μέγιστο μήκος κύκλου ως κλάσμα της διάρκειας προφίλ; προεπιλογή 1.5 (150%)",
|
||||
"keep_min_score": "Στάδιο 2: κατώτατο όριο βαθμολογίας για παραμονή στον αγώνα; προεπιλογή 0.1 επιτρέπει αδύναμα ταιριάσματα, τα επόμενα στάδια επιλέγουν το καλύτερο",
|
||||
"dtw_blend": "Στάδιο 3: 0 = μόνο βαθμός πυρήνα, 1 = μόνο βαθμός DTW, 0.5 = ισόρροπη ανάμειξη (προεπιλογή)",
|
||||
"dtw_ensemble_w": "Στάδιο 3 (λειτουργία συνόλου): βάρος στο κλιμακωμένο-L1 έναντι παραγώγου DTW; προεπιλογή 0.7 ευνοεί το επίπεδο ισχύος",
|
||||
"dtw_ddtw_scale": "Στάδιο 3: απόσταση ημίσεος κορεσμού DDTW; μικρότερη = μεγαλύτερη ευαισθησία σχήματος (προεπιλογή 30)",
|
||||
"dtw_refine_top_n": "Στάδιο 3: υποψήφιοι που επαναβαθμολογεί η DTW; αυξήστε σε 7-9 αν το σωστό προφίλ βρίσκεται στη 4η-5η θέση (προεπιλογή 5)",
|
||||
"duration_scale": "Στάδιο 4: λόγος λογαρίθμου όπου η συμφωνία διάρκειας υποδιπλασιάζεται; μικρότερος = αυστηρότερη ποινή (προεπιλογή 0.175)",
|
||||
"energy_scale": "Στάδιο 4: λόγος λογαρίθμου όπου η συμφωνία ενέργειας υποδιπλασιάζεται; μικρότερος = αυστηρότερη ποινή (προεπιλογή 0.25)"
|
||||
},
|
||||
"col": {
|
||||
"profile_tip": "Όνομα αντιστοιχισμένου προγράμματος. Χωρίς ετικέτα σημαίνει ότι κανένα προφίλ δεν αντιστοιχίστηκε στο τέλος του κύκλου.",
|
||||
@@ -1766,6 +1820,69 @@
|
||||
},
|
||||
"pg_sweep": {
|
||||
"optimize": "Βελτιστοποίηση: {param}"
|
||||
},
|
||||
"pg_detail": {
|
||||
"simulate": "Προσομοίωση κύκλου"
|
||||
},
|
||||
"split": {
|
||||
"apply": "Διαχωρισμός κύκλου"
|
||||
},
|
||||
"trim": {
|
||||
"apply": "Περικοπή κύκλου"
|
||||
},
|
||||
"merge": {
|
||||
"apply": "Συγχώνευση κύκλων"
|
||||
},
|
||||
"rebuild": {
|
||||
"envelopes": "Ανακατασκευή φακέλων"
|
||||
},
|
||||
"cancelling": "Ακύρωση..."
|
||||
},
|
||||
"setup": {
|
||||
"hdr": {
|
||||
"card": "Ρύθμιση συσκευής",
|
||||
"healthy_chip": "Ρύθμιση ολοκληρώθηκε"
|
||||
},
|
||||
"phase0": {
|
||||
"washer": "Το WashData ανιχνεύει ήδη τους κύκλους σας. Εγγράψτε τον πρώτο κύκλο για να ενεργοποιήσετε ονόματα προγραμμάτων και εκτιμήσεις χρόνου.",
|
||||
"dishwasher": "Το WashData παρακολουθεί. Τα πλυντήρια πιάτων έχουν σύνθετους κύκλους – συνιστάται ανεπιφύλακτα η εγγραφή του πρώτου κύκλου. Αν ένας ανιχνευθείς κύκλος διαρκεί πολύ, χρησιμοποιήστε το πρόγραμμα επεξεργασίας κύκλων για να τον περικόψετε πριν αποθηκευτεί ως προφίλ.",
|
||||
"generic": "Το WashData παρακολουθεί. Εγγράψτε ή επισημάνετε έναν ανιχνευθέντα κύκλο για να ξεκινήσετε να δημιουργείτε προφίλ."
|
||||
},
|
||||
"phase1a": {
|
||||
"labelled": "Καλή αρχή – το πρώτο πρόγραμμά σας αποθηκεύτηκε. Για τα πιο καθαρά δεδομένα, σκεφτείτε να εγγράψετε τον επόμενο κύκλο με το widget εγγραφής."
|
||||
},
|
||||
"phase1b": {
|
||||
"recorded": "Η εγγραφή σας αποθηκεύτηκε ως {profile_name}. Τώρα εγγράψτε ή επισημάνετε τα άλλα συνηθισμένα προγράμματά σας για να διευρύνετε την κάλυψη."
|
||||
},
|
||||
"phase1c": {
|
||||
"verify": "Έχετε {count} προγράμματα από την κοινότητα. Εκτελέστε έναν κύκλο για να επαληθεύσετε ότι το WashData τα αναγνωρίζει σωστά – η αντιστοίχιση θα βελτιώνεται καθώς η συσκευή σας δημιουργεί το δικό της ιστορικό."
|
||||
},
|
||||
"phase2": {
|
||||
"cluster": "Το WashData έχει δει {count} κύκλους που δεν αντιστοιχούν σε κανένα αποθηκευμένο πρόγραμμα – μοιάζουν μεταξύ τους. Θέλετε να δημιουργήσετε ένα νέο προφίλ για αυτούς;",
|
||||
"unmatched": "Ο τελευταίος κύκλος δεν αντιστοιχεί σε κανένα αποθηκευμένο πρόγραμμα. Είναι νέο πρόγραμμα;"
|
||||
},
|
||||
"phase3": {
|
||||
"suggestions": "Το WashData έχει προτάσεις ρυθμίσεων βάσει του ιστορικού κύκλων σας – ελέγξτε τις για βελτίωση της ακρίβειας ανίχνευσης.",
|
||||
"groups": "Μερικά από τα προφίλ σας μοιάζουν με το ίδιο πρόγραμμα σε διαφορετικές θερμοκρασίες. Οργανώστε τα σε μια ομάδα για καλύτερη αντιστοίχιση.",
|
||||
"phases": "Προσθέστε φάσεις προγράμματος στο {profile_name} για πιο ακριβείς εκτιμήσεις χρόνου που απομένει."
|
||||
},
|
||||
"phase4": {
|
||||
"healthy": "Αυτή η συσκευή έχει ρυθμιστεί πλήρως ({profile_count} προφίλ)."
|
||||
},
|
||||
"cta": {
|
||||
"start_recording": "Έναρξη εγγραφής",
|
||||
"label_detected_cycle": "Έχω ήδη ανιχνευθέντα κύκλο – επισήμανσή του",
|
||||
"browse_cycles": "Αναζήτηση κύκλων για επισήμανση άλλου",
|
||||
"view_profiles": "Προβολή προφίλ",
|
||||
"create_from_cluster": "Δημιουργία προφίλ από αυτούς τους κύκλους",
|
||||
"create_profile": "Δημιουργία προφίλ για αυτόν",
|
||||
"review_suggestions": "Έλεγχος προτάσεων",
|
||||
"organise_profiles": "Οργάνωση προφίλ",
|
||||
"configure_phases": "Διαμόρφωση φάσεων",
|
||||
"skip_step": "Παράλειψη βήματος",
|
||||
"skip_forever": "Να μην εμφανιστεί ξανά",
|
||||
"hide_guidance": "Απόκρυψη οδηγιών",
|
||||
"show_guidance": "Εμφάνιση οδηγιών"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"badge": {
|
||||
"artifact_tip": "{n} anomalies detected (e.g. door opened mid-cycle) — open to see them on the graph",
|
||||
"artifact_tip": "{n} anomalies detected (e.g. door opened mid-cycle) – open to see them on the graph",
|
||||
"auto": "(auto-detected)",
|
||||
"built_in_tag": "built-in",
|
||||
"declining": "↘ declining",
|
||||
"fair_fit": "acceptable quality",
|
||||
"fair_fit_tip": "Moderate match consistency — some cycles assigned to this profile have lower confidence scores. Label more cycles or re-record the profile to improve accuracy.",
|
||||
"fair_fit_tip": "Moderate match consistency – some cycles assigned to this profile have lower confidence scores. Label more cycles or re-record the profile to improve accuracy.",
|
||||
"feedback_requested": "Feedback requested",
|
||||
"golden_cycle": "Recorded reference cycle",
|
||||
"improving": "↗ improving",
|
||||
@@ -16,7 +16,7 @@
|
||||
"energy_spike": "Higher energy than usual",
|
||||
"energy_low": "Lower energy than usual",
|
||||
"poor_fit": "poor quality",
|
||||
"poor_fit_tip": "Inconsistent match history — consider rebuilding this profile",
|
||||
"poor_fit_tip": "Inconsistent match history – consider rebuilding this profile",
|
||||
"restart_gap_tip": "{n} HA restart gap: power trace has a hole",
|
||||
"reviewed": "Reviewed",
|
||||
"steady": "→ steady",
|
||||
@@ -87,7 +87,7 @@
|
||||
"on_cycle_finished": "On cycle finished",
|
||||
"on_cycle_started": "On cycle started",
|
||||
"pause_cycle": "Pause",
|
||||
"pause_cycle_tip": "Pause the running cycle — the appliance will resume where it left off",
|
||||
"pause_cycle_tip": "Pause the running cycle – the appliance will resume where it left off",
|
||||
"pg_apply_device": "Apply to device",
|
||||
"pg_autofill": "Auto-fill",
|
||||
"play": "Play",
|
||||
@@ -97,8 +97,8 @@
|
||||
"process_tip": "Save the recorded trace as a new or existing profile",
|
||||
"rebuild": "Rebuild Envelopes",
|
||||
"rebuild_envelope": "Rebuild Envelope",
|
||||
"rebuild_tip": "Recompute the expected power envelope (min/max band) for all profiles from their labelled cycles — run after labelling new cycles or correcting old ones",
|
||||
"rec_start_tip": "Begin recording the appliance's power trace — start just before running a cycle",
|
||||
"rebuild_tip": "Recompute the expected power envelope (min/max band) for all profiles from their labelled cycles – run after labelling new cycles or correcting old ones",
|
||||
"rec_start_tip": "Begin recording the appliance's power trace – start just before running a cycle",
|
||||
"rec_stop": "Stop",
|
||||
"rec_stop_tip": "Stop recording and hold the captured trace for review",
|
||||
"record": "Start Recording",
|
||||
@@ -181,7 +181,7 @@
|
||||
},
|
||||
"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.",
|
||||
"settings_banner": "{n} setting conflict{s} – check the highlighted sections and fix before saving.",
|
||||
"settings_banner_btn": "Go to first",
|
||||
"confidence": {
|
||||
"auto": "Must be at or above Match Threshold ({match})",
|
||||
@@ -448,9 +448,9 @@
|
||||
"show_expected": "Show expected curve overlay (matched profile, orange)",
|
||||
"show_raw": "Show raw socket toggle in live power graph",
|
||||
"sparkline": "Recent cycle-duration trend",
|
||||
"stage2": "Stage 2 — core similarity",
|
||||
"stage3": "Stage 3 — DTW",
|
||||
"stage4": "Stage 4 — agreement",
|
||||
"stage2": "Stage 2 – core similarity",
|
||||
"stage3": "Stage 3 – DTW",
|
||||
"stage4": "Stage 4 – agreement",
|
||||
"status": "Status",
|
||||
"tail_trim": "Tail Trim (s)",
|
||||
"timer_auto_pause": "Auto-pause",
|
||||
@@ -495,6 +495,11 @@
|
||||
"pg_alert_indefinite": "Would run indefinitely",
|
||||
"task_pg_history": "Test on history",
|
||||
"task_pg_sweep": "Optimize",
|
||||
"task_pg_detail": "Simulate cycle",
|
||||
"task_split": "Splitting cycle",
|
||||
"task_trim": "Trimming cycle",
|
||||
"task_merge": "Merging cycles",
|
||||
"task_rebuild": "Rebuilding envelopes",
|
||||
"task_reprocess": "Reprocessing",
|
||||
"task_ml_training": "Learning",
|
||||
"eta_secs": "~{n}s left",
|
||||
@@ -540,7 +545,7 @@
|
||||
"personalized": "● Personalized to this machine",
|
||||
"better_than_baseline": "{pct}% better than the baseline estimate ({metric})",
|
||||
"trend_improving_tip": "This model's fit has improved across recent re-checks.",
|
||||
"trend_declining_tip": "This model's fit has slipped across recent re-checks — reviewing more cycles may help it re-learn.",
|
||||
"trend_declining_tip": "This model's fit has slipped across recent re-checks – reviewing more cycles may help it re-learn.",
|
||||
"trend_steady_tip": "This model's fit has held roughly steady across recent re-checks.",
|
||||
"cap_label": {
|
||||
"end": "Cycle-end detection",
|
||||
@@ -605,19 +610,19 @@
|
||||
"artifact_dip_detail": "Dropped below the usual power band for ~{n}s.",
|
||||
"artifact_footer": "Highlighted on the graph above. These are transient artifacts (e.g. the door opened mid-cycle), not necessarily problems.",
|
||||
"artifact_header": "{n} anomalies detected during this cycle",
|
||||
"artifact_pause_detail": "Power dropped to near zero for ~{n}s then resumed — likely the door was opened mid-cycle or the cycle was paused.",
|
||||
"artifact_pause_detail": "Power dropped to near zero for ~{n}s then resumed – likely the door was opened mid-cycle or the cycle was paused.",
|
||||
"artifact_spike_detail": "Drew above the usual power band for ~{n}s.",
|
||||
"auto_label_intro": "Assign profiles to unlabelled cycles whose match confidence clears the threshold.",
|
||||
"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 – {need} more cycle{plural} before fine-tuning can start ({current}/{min}).",
|
||||
"compare_overlay_profiles": "Overlay profiles (faint)",
|
||||
"compare_profiles_tip": "Overlay other profile envelopes on the chart above to see which one best fits this cycle.",
|
||||
"compare_selected_cycles": "Selected cycles (solid) — show / hide",
|
||||
"compare_selected_cycles": "Selected cycles (solid) – show / hide",
|
||||
"consider_new_profile": "Consider creating a new profile.",
|
||||
"coverage_gap": "recent cycles have no matching profile ({pct}% of last 30).",
|
||||
"coverage_gap_similar_cycles": "{count} similar unlabelled cycles found — create a profile to start matching them.",
|
||||
"coverage_gap_similar_cycles": "{count} similar unlabelled cycles found – create a profile to start matching them.",
|
||||
"cycles_deleted": "{count} cycle(s) deleted",
|
||||
"enough_data": "Enough data to learn from ({current}/{min} cycles).",
|
||||
"export_description": "Export all profiles and cycles to JSON, or restore from a previous export.",
|
||||
@@ -646,7 +651,7 @@
|
||||
"ml_learned_intro": "Models fine-tuned to this machine.",
|
||||
"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.",
|
||||
"name_first_program": "You have enough cycles — name your first program to start matching.",
|
||||
"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.",
|
||||
"no_cycles_profile": "No cycles for this profile.",
|
||||
@@ -658,7 +663,7 @@
|
||||
"no_devices": "No WashData devices configured yet.",
|
||||
"no_envelope": "No envelope yet - rebuild after labelling cycles.",
|
||||
"no_envelope_overlay": "No envelope available to overlay.",
|
||||
"no_fine_tuned": "Nothing fine-tuned yet — WashData is using its built-in models.",
|
||||
"no_fine_tuned": "Nothing fine-tuned yet – WashData is using its built-in models.",
|
||||
"no_logs": "No log records buffered yet.",
|
||||
"no_maintenance": "No maintenance recorded yet.",
|
||||
"no_match_yet": "No match attempt yet - this populates during a running cycle.",
|
||||
@@ -675,7 +680,7 @@
|
||||
"notify_services_hint": "Use {entity} service IDs (comma-separated for multiple). Template variables: {vars}.",
|
||||
"old_actions_warning": "Configured with the old actions editor (now removed). They still fire on cycle events but can no longer be edited here. Convert them into a normal automation, or remove them.",
|
||||
"onboarding_progress": "{n} / 3 cycles observed",
|
||||
"onboarding_watching": "Run your appliance normally — WashData is watching. After 3 cycles, program matching will begin.",
|
||||
"onboarding_watching": "Run your appliance normally – WashData is watching. After 3 cycles, program matching will begin.",
|
||||
"pending_feedback": "Pending detection feedback",
|
||||
"performance_trend": "Performance trend ({n} cycles)",
|
||||
"pg_analysis_empty": "Load a cycle to see match analysis.",
|
||||
@@ -725,7 +730,7 @@
|
||||
"setting_changed": "Changed from {old} to {new} on {date}",
|
||||
"settings_basic_note": "Showing essential settings. Switch to Advanced for the full list.",
|
||||
"shape_drift_advisory": "⚠ Shape drifting",
|
||||
"shape_drift_detail": "The power pattern for this profile has shifted over time — possible appliance wear or maintenance needed (e.g. descaling, filter cleaning).",
|
||||
"shape_drift_detail": "The power pattern for this profile has shifted over time – possible appliance wear or maintenance needed (e.g. descaling, filter cleaning).",
|
||||
"show_all_settings": "Show all settings",
|
||||
"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.",
|
||||
@@ -753,10 +758,10 @@
|
||||
"toast_revert_failed": "Revert failed: {error}",
|
||||
"toast_reverted": "{key} reverted",
|
||||
"toast_save_failed": "Save failed: {error}",
|
||||
"trend_duration_longer": "Duration trending longer ({pct}%/cycle) — recent avg {avg}",
|
||||
"trend_duration_shorter": "Duration trending shorter ({pct}%/cycle) — recent avg {avg}",
|
||||
"trend_duration_longer": "Duration trending longer ({pct}%/cycle) – recent avg {avg}",
|
||||
"trend_duration_shorter": "Duration trending shorter ({pct}%/cycle) – recent avg {avg}",
|
||||
"trend_energy_down": "Energy trending down ({pct}%/cycle)",
|
||||
"trend_energy_up": "Energy trending up ({pct}%/cycle) — recent avg {avg}",
|
||||
"trend_energy_up": "Energy trending up ({pct}%/cycle) – recent avg {avg}",
|
||||
"trim_intro": "Drag the red handles, or enter values. Everything outside the window is removed.",
|
||||
"tuning_suggestions_available": "{count} tuning suggestion available from observed cycles. They appear beside the relevant fields.",
|
||||
"unsure_detected_prefix": "WashData is unsure it detected",
|
||||
@@ -774,12 +779,14 @@
|
||||
"pg_sweep_progress": "Step {done} / {total}",
|
||||
"pg_analysis_hint": "Select a cycle and click ↺ to load analysis.",
|
||||
"diagnostics_load_failed": "Could not load diagnostics: {error}",
|
||||
"manual_duration_ref_hint": "Only used when no reference cycle is selected — a reference cycle sets the duration from its own length.",
|
||||
"manual_duration_ref_hint": "Only used when no reference cycle is selected – a reference cycle sets the duration from its own length.",
|
||||
"advisory_poor_health": "'{name}' has a low fit score - its recent cycles vary a lot or match weakly. Review its cycles or re-record the profile so matching and time estimates stay accurate.",
|
||||
"advisory_shape_drift": "'{name}' has drifted significantly from its original power shape. The appliance may have changed behaviour over time (e.g. limescale, wear). Consider re-recording this profile with recent cycles.",
|
||||
"advisory_shape_drift_corr": "'{name}' has drifted significantly from its original power shape (correlation {corr}). The appliance may have changed behaviour over time (e.g. limescale, wear). Consider re-recording this profile with recent cycles.",
|
||||
"advisory_duration_trend_up": "'{name}' cycles are running progressively longer (about +{pct}% per cycle). If the appliance's behaviour changed, re-record or rebuild this profile.",
|
||||
"advisory_energy_trend_up": "'{name}' is drawing progressively more energy (about +{pct}% per cycle) - worth checking the appliance if that is unexpected.",
|
||||
"advisory_phase_inconsistent": "'{name}' looks like it mixes different programs or temperatures - its cycles heat for very different lengths of time. Splitting it into separate profiles (e.g. per temperature) will improve matching and time estimates.",
|
||||
"advisory_phase_inconsistent_title": "⚠ Possibly mixed programs",
|
||||
"pg_running_history": "Replaying your cycles…",
|
||||
"pg_running_sweep": "Testing values across your cycles…",
|
||||
"pg_row_load_hint": "Load this cycle in the graph above",
|
||||
@@ -810,7 +817,7 @@
|
||||
"share_guideline_quality": "Only share cycles that completed normally -- no mid-cycle interruptions, door-open events, or power blips.",
|
||||
"share_guideline_review": "Your upload starts as pending and appears publicly once enough community members confirm it.",
|
||||
"share_consent": "I confirm these cycles ran to normal completion without interruption",
|
||||
"share_profile_no_cycles": "No reference cycles — mark a cycle as ⭐ in the Cycles tab to include this profile"
|
||||
"share_profile_no_cycles": "No reference cycles – mark a cycle as ⭐ in the Cycles tab to include this profile"
|
||||
},
|
||||
"pg_desc": {
|
||||
"abrupt_drop_watts": "Sudden drop treated as immediate end",
|
||||
@@ -822,12 +829,19 @@
|
||||
"start_duration_threshold": "Seconds above threshold to confirm start",
|
||||
"start_threshold_w": "Minimum watts to count as started",
|
||||
"stop_threshold_w": "Below this, machine counts as off",
|
||||
"dtw_bandwidth": "How much time-warping the shape match allows",
|
||||
"corr_weight": "Weight on curve-shape vs power level in the match",
|
||||
"duration_weight": "How much run-length agreement affects the match",
|
||||
"energy_weight": "How much energy agreement affects the match",
|
||||
"profile_match_min_duration_ratio": "Shortest run (vs the profile) still allowed to match",
|
||||
"profile_match_max_duration_ratio": "Longest run (vs the profile) still allowed to match"
|
||||
"dtw_bandwidth": "Stage 3: Sakoe-Chiba warp band (0 = DTW off; default 0.2 = 20% of cycle length)",
|
||||
"corr_weight": "Stage 2: balance between curve shape (correlation) and power level (MAE); default 0.45",
|
||||
"duration_weight": "Stage 4: how strongly run-length agreement affects the final score (default 0.22)",
|
||||
"energy_weight": "Stage 4: how strongly energy agreement affects the final score (default 0.22)",
|
||||
"profile_match_min_duration_ratio": "Stage 1: minimum cycle length as a fraction of profile duration; default 0.1 (10%)",
|
||||
"profile_match_max_duration_ratio": "Stage 1: maximum cycle length as a fraction of profile duration; default 1.5 (150%)",
|
||||
"keep_min_score": "Stage 2: floor score to stay in the race; default 0.1 admits weak matches, later stages pick the best",
|
||||
"dtw_blend": "Stage 3: 0 = core score only, 1 = DTW score only, 0.5 = equal blend (default)",
|
||||
"dtw_ensemble_w": "Stage 3 (ensemble mode): weight on scaled-L1 vs derivative DTW; default 0.7 favours level-aware",
|
||||
"dtw_ddtw_scale": "Stage 3: DDTW half-saturation distance; smaller = more shape-sensitive (default 30)",
|
||||
"dtw_refine_top_n": "Stage 3: candidates DTW re-scores; raise to 7-9 if correct profile ranks 4th-5th (default 5)",
|
||||
"duration_scale": "Stage 4: log-ratio where duration agreement halves; smaller = stricter penalty (default 0.175)",
|
||||
"energy_scale": "Stage 4: log-ratio where energy agreement halves; smaller = stricter penalty (default 0.25)"
|
||||
},
|
||||
"phase_desc": {
|
||||
"anti_crease": "Occasional short tumbles after completion to reduce wrinkles.",
|
||||
@@ -910,6 +924,10 @@
|
||||
"triggers": {
|
||||
"intro": "Optional external signals: an end trigger, a door sensor, a pause switch, and the unload reminder.",
|
||||
"label": "Triggers & Doors"
|
||||
},
|
||||
"phase_eta": {
|
||||
"intro": "Phase-aware time-remaining, for machines whose cycle length depends on temperature or spin.",
|
||||
"label": "Time Remaining"
|
||||
}
|
||||
},
|
||||
"setting": {
|
||||
@@ -993,6 +1011,10 @@
|
||||
"doc": "Fixed price per kWh used for cost figures when no live price entity is set above.",
|
||||
"label": "Static Energy Price (per kWh)"
|
||||
},
|
||||
"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"
|
||||
},
|
||||
"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"
|
||||
@@ -1275,6 +1297,38 @@
|
||||
},
|
||||
"show_contributor": {
|
||||
"doc": "Show the \"by <contributor>\" attribution on community appliances and reference cycles."
|
||||
},
|
||||
"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."
|
||||
}
|
||||
},
|
||||
"setting_group": {
|
||||
@@ -1394,24 +1448,24 @@
|
||||
"lower": "Labels more cycles automatically; some may be misidentified"
|
||||
},
|
||||
"duration_tolerance": {
|
||||
"higher": "Accepts a wider duration range — more flexible matching",
|
||||
"lower": "Requires closer duration match — stricter but may reject unusual cycles"
|
||||
"higher": "Accepts a wider duration range – more flexible matching",
|
||||
"lower": "Requires closer duration match – stricter but may reject unusual cycles"
|
||||
},
|
||||
"end_energy_threshold": {
|
||||
"higher": "Closes only cycles that used substantial energy",
|
||||
"lower": "Closes shorter or lower-energy cycles too"
|
||||
},
|
||||
"end_repeat_count": {
|
||||
"higher": "Requires the end signal to repeat more times — more robust, slightly slower",
|
||||
"lower": "Ends after fewer repetitions — faster detection, more false-end risk"
|
||||
"higher": "Requires the end signal to repeat more times – more robust, slightly slower",
|
||||
"lower": "Ends after fewer repetitions – faster detection, more false-end risk"
|
||||
},
|
||||
"learning_confidence": {
|
||||
"higher": "Learns only from very confident matches — slower but more reliable",
|
||||
"higher": "Learns only from very confident matches – slower but more reliable",
|
||||
"lower": "Learns from more cycles; model may be noisier"
|
||||
},
|
||||
"min_off_gap": {
|
||||
"higher": "Longer idle needed before a new cycle starts",
|
||||
"lower": "Brief idle triggers a new cycle — back-to-back runs may split"
|
||||
"lower": "Brief idle triggers a new cycle – back-to-back runs may split"
|
||||
},
|
||||
"min_power": {
|
||||
"higher": "Less sensitive to idle power draw; may miss very quiet programs",
|
||||
@@ -1422,24 +1476,24 @@
|
||||
"lower": "Force-stops a stuck cycle sooner"
|
||||
},
|
||||
"off_delay": {
|
||||
"higher": "More time for appliance pauses — handles long soak or drying phases",
|
||||
"lower": "Faster end detection — works well for clean on/off appliances"
|
||||
"higher": "More time for appliance pauses – handles long soak or drying phases",
|
||||
"lower": "Faster end detection – works well for clean on/off appliances"
|
||||
},
|
||||
"profile_match_threshold": {
|
||||
"higher": "Commits only high-confidence matches; more cycles stay unlabelled",
|
||||
"lower": "Matches more cycles; some may be slightly wrong"
|
||||
},
|
||||
"running_dead_zone": {
|
||||
"higher": "Ignores brief power spikes during idle — less noise-sensitive",
|
||||
"lower": "Responds to shorter power bursts — catches fast transient activity"
|
||||
"higher": "Ignores brief power spikes during idle – less noise-sensitive",
|
||||
"lower": "Responds to shorter power bursts – catches fast transient activity"
|
||||
},
|
||||
"start_threshold_w": {
|
||||
"higher": "Avoids false starts from brief power spikes",
|
||||
"lower": "Catches low-power programs; may trigger on noise"
|
||||
},
|
||||
"stop_threshold_w": {
|
||||
"higher": "Ends cycle faster — may close during a pause",
|
||||
"lower": "Waits longer to end — fewer premature completions"
|
||||
"higher": "Ends cycle faster – may close during a pause",
|
||||
"lower": "Waits longer to end – fewer premature completions"
|
||||
},
|
||||
"watchdog_interval": {
|
||||
"higher": "Longer quiet phases allowed; fewer false force-stops",
|
||||
@@ -1712,6 +1766,69 @@
|
||||
},
|
||||
"pg_sweep": {
|
||||
"optimize": "Optimize: {param}"
|
||||
},
|
||||
"pg_detail": {
|
||||
"simulate": "Simulate cycle"
|
||||
},
|
||||
"split": {
|
||||
"apply": "Splitting cycle"
|
||||
},
|
||||
"trim": {
|
||||
"apply": "Trimming cycle"
|
||||
},
|
||||
"merge": {
|
||||
"apply": "Merging cycles"
|
||||
},
|
||||
"rebuild": {
|
||||
"envelopes": "Rebuilding envelopes"
|
||||
},
|
||||
"cancelling": "Cancelling..."
|
||||
},
|
||||
"setup": {
|
||||
"hdr": {
|
||||
"card": "Device Setup",
|
||||
"healthy_chip": "Setup complete"
|
||||
},
|
||||
"phase0": {
|
||||
"washer": "WashData is already detecting your cycles. Record your first cycle to enable program names and time estimates.",
|
||||
"dishwasher": "WashData is watching. Dishwashers have complex cycles – recording your first cycle is strongly recommended. If a detected cycle runs too long, use the cycle editor to trim it before saving as a profile.",
|
||||
"generic": "WashData is watching. Record or label a detected cycle to start building profiles."
|
||||
},
|
||||
"phase1a": {
|
||||
"labelled": "Good start – your first program is saved. For the cleanest data, consider recording your next cycle with the recorder widget."
|
||||
},
|
||||
"phase1b": {
|
||||
"recorded": "Your recording was saved as {profile_name}. Now record or label your other common programs to build coverage."
|
||||
},
|
||||
"phase1c": {
|
||||
"verify": "You have {count} programs from the community. Run a cycle to verify WashData recognises it correctly – matching will improve as your device builds its own history."
|
||||
},
|
||||
"phase2": {
|
||||
"cluster": "WashData has seen {count} cycles that don't match any saved program – they look similar to each other. Want to create a new profile for them?",
|
||||
"unmatched": "Your last cycle didn't match any saved program. Is it a new program?"
|
||||
},
|
||||
"phase3": {
|
||||
"suggestions": "WashData has settings recommendations based on your cycle history – review them to improve detection accuracy.",
|
||||
"groups": "Some of your profiles look like the same program at different temperatures. Organise them into a group for better matching.",
|
||||
"phases": "Add program phases to {profile_name} for more accurate time-remaining estimates."
|
||||
},
|
||||
"phase4": {
|
||||
"healthy": "This device is fully set up ({profile_count} profiles)."
|
||||
},
|
||||
"cta": {
|
||||
"start_recording": "Start Recording",
|
||||
"label_detected_cycle": "I already have a detected cycle – label it instead",
|
||||
"browse_cycles": "Browse cycles to label another",
|
||||
"view_profiles": "View your profiles",
|
||||
"create_from_cluster": "Create profile from these cycles",
|
||||
"create_profile": "Create a profile for it",
|
||||
"review_suggestions": "Review suggestions",
|
||||
"organise_profiles": "Organise profiles",
|
||||
"configure_phases": "Configure phases",
|
||||
"skip_step": "Skip this step",
|
||||
"skip_forever": "Don't show again",
|
||||
"hide_guidance": "Hide guidance",
|
||||
"show_guidance": "Show guidance"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -87,7 +87,7 @@
|
||||
"on_cycle_finished": "En ciclo terminado",
|
||||
"on_cycle_started": "En ciclo iniciado",
|
||||
"pause_cycle": "Pausa",
|
||||
"pause_cycle_tip": "Pausar el ciclo en curso — el electrodoméstico reanudará donde lo dejó",
|
||||
"pause_cycle_tip": "Pausar el ciclo en curso – el electrodoméstico reanudará donde lo dejó",
|
||||
"pg_apply_device": "Aplicar al dispositivo",
|
||||
"pg_autofill": "Autocompletar",
|
||||
"play": "Reproducir",
|
||||
@@ -97,8 +97,8 @@
|
||||
"process_tip": "Guardar la grabación capturada como un perfil nuevo o existente",
|
||||
"rebuild": "Reconstruir sobres",
|
||||
"rebuild_envelope": "Reconstruir envolvente",
|
||||
"rebuild_tip": "Recalcular la envolvente de potencia esperada (banda mín/máx) para todos los perfiles a partir de sus ciclos etiquetados — ejecutar después de etiquetar nuevos ciclos o corregir los existentes",
|
||||
"rec_start_tip": "Comenzar a grabar la traza de potencia del electrodoméstico — iniciar justo antes de ejecutar un ciclo",
|
||||
"rebuild_tip": "Recalcular la envolvente de potencia esperada (banda mín/máx) para todos los perfiles a partir de sus ciclos etiquetados – ejecutar después de etiquetar nuevos ciclos o corregir los existentes",
|
||||
"rec_start_tip": "Comenzar a grabar la traza de potencia del electrodoméstico – iniciar justo antes de ejecutar un ciclo",
|
||||
"rec_stop": "Detener",
|
||||
"rec_stop_tip": "Detener la grabación y retener la traza capturada para revisión",
|
||||
"record": "Iniciar grabación",
|
||||
@@ -182,7 +182,7 @@
|
||||
},
|
||||
"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.",
|
||||
"settings_banner": "{n} conflicto{s} de ajustes – 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})",
|
||||
@@ -451,9 +451,9 @@
|
||||
"show_expected": "Mostrar superposición de curva esperada (perfil coincidente, naranja)",
|
||||
"show_raw": "Mostrar el interruptor de señal bruta del enchufe en el gráfico de potencia en vivo",
|
||||
"sparkline": "Tendencia reciente de duración de ciclos",
|
||||
"stage2": "Etapa 2 — similitud principal",
|
||||
"stage3": "Etapa 3 — DTW",
|
||||
"stage4": "Etapa 4 — concordancia",
|
||||
"stage2": "Etapa 2 – similitud principal",
|
||||
"stage3": "Etapa 3 – DTW",
|
||||
"stage4": "Etapa 4 – concordancia",
|
||||
"status": "Estado",
|
||||
"tail_trim": "Recorte de fin (s)",
|
||||
"timer_auto_pause": "Pausa automática",
|
||||
@@ -561,7 +561,12 @@
|
||||
"flags": "Indicadores",
|
||||
"include_phase_map": "Incluir mapa de fases",
|
||||
"include_settings": "Incluir ajustes de detección y reconocimiento",
|
||||
"show_contributor": "Mostrar nombres de colaboradores"
|
||||
"show_contributor": "Mostrar nombres de colaboradores",
|
||||
"task_pg_detail": "Simular ciclo",
|
||||
"task_split": "Dividiendo el ciclo",
|
||||
"task_trim": "Recortando el ciclo",
|
||||
"task_merge": "Combinando ciclos",
|
||||
"task_rebuild": "Reconstruyendo envolventes"
|
||||
},
|
||||
"log": {
|
||||
"all_levels": "Todos los niveles",
|
||||
@@ -645,7 +650,7 @@
|
||||
"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.",
|
||||
"artifact_header": "{n} anomalías detectadas durante este ciclo",
|
||||
"artifact_pause_detail": "La potencia cayó a casi cero durante ~{n}s y luego se reanudó — probablemente la puerta se abrió a mitad del ciclo o el ciclo fue pausado.",
|
||||
"artifact_pause_detail": "La potencia cayó a casi cero durante ~{n}s y luego se reanudó – probablemente la puerta se abrió a mitad del ciclo o el ciclo fue pausado.",
|
||||
"artifact_spike_detail": "Superó la banda de potencia habitual durante ~{n}s.",
|
||||
"auto_label_intro": "Asigne perfiles a ciclos sin etiquetar cuya confianza de coincidencia supere el umbral.",
|
||||
"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.",
|
||||
@@ -657,7 +662,7 @@
|
||||
"compare_selected_cycles": "Ciclos seleccionados (sólidos): mostrar/ocultar",
|
||||
"consider_new_profile": "Considere la posibilidad de crear un nuevo perfil.",
|
||||
"coverage_gap": "Los ciclos recientes no tienen ningún perfil coincidente ({pct}% de los últimos 30).",
|
||||
"coverage_gap_similar_cycles": "{count} ciclos similares sin etiquetar encontrados — cree un perfil para comenzar a identificarlos.",
|
||||
"coverage_gap_similar_cycles": "{count} ciclos similares sin etiquetar encontrados – cree un perfil para comenzar a identificarlos.",
|
||||
"cycles_deleted": "{count} ciclo(s) eliminado(s)",
|
||||
"enough_data": "Suficientes datos para aprender ({current}/{min} ciclos).",
|
||||
"export_description": "Exporte todos los perfiles y ciclos a JSON o restaure desde una exportación anterior.",
|
||||
@@ -686,7 +691,7 @@
|
||||
"ml_learned_intro": "Modelos adaptados a esta máquina.",
|
||||
"ml_loading": "cargando ML...",
|
||||
"ml_settings_intro": "Dos interruptores independientes: uno aplica los modelos mientras se ejecuta un ciclo, el otro permite que WashData los ajuste a su máquina con el tiempo.",
|
||||
"name_first_program": "Ya tiene suficientes ciclos — nombre su primer programa para empezar a hacer coincidencias.",
|
||||
"name_first_program": "Ya tiene suficientes ciclos – nombre su primer programa para empezar a hacer coincidencias.",
|
||||
"near_duplicate_cluster": "Se detectó un grupo de perfiles casi duplicados. La agrupación permite elegir de manera confiable entre elementos similares (por ejemplo, el mismo programa a diferente temperatura/centrifugado).",
|
||||
"no_cycles_match": "Ningún ciclo coincide con el filtro actual.",
|
||||
"no_cycles_profile": "No hay ciclos para este perfil.",
|
||||
@@ -713,7 +718,7 @@
|
||||
"notify_services_hint": "Use los IDs de servicio {entity} (separados por comas para varios). Variables de plantilla: {vars}.",
|
||||
"old_actions_warning": "Configurado con el antiguo editor de acciones (ahora eliminado). Todavía se activan en eventos de ciclo pero ya no se pueden editar aquí. Conviértalos en una automatización normal o elimínelos.",
|
||||
"onboarding_progress": "{n} / 3 ciclos observados",
|
||||
"onboarding_watching": "Use su electrodoméstico con normalidad — WashData está observando. Después de 3 ciclos, comenzará la coincidencia de programas.",
|
||||
"onboarding_watching": "Use su electrodoméstico con normalidad – WashData está observando. Después de 3 ciclos, comenzará la coincidencia de programas.",
|
||||
"pending_feedback": "Comentarios de detección pendientes",
|
||||
"performance_trend": "Tendencia de rendimiento ({n} ciclos)",
|
||||
"pg_analysis_empty": "Cargue un ciclo para ver el análisis de coincidencia.",
|
||||
@@ -763,7 +768,7 @@
|
||||
"setting_changed": "Cambiado de {old} a {new} el {date}",
|
||||
"settings_basic_note": "Mostrando ajustes esenciales. Cambie a Avanzado para ver la lista completa.",
|
||||
"shape_drift_advisory": "⚠ Forma a la deriva",
|
||||
"shape_drift_detail": "El patrón de potencia de este perfil ha cambiado con el tiempo — posible desgaste del electrodoméstico o mantenimiento necesario (p. ej., descalcificación, limpieza del filtro).",
|
||||
"shape_drift_detail": "El patrón de potencia de este perfil ha cambiado con el tiempo – posible desgaste del electrodoméstico o mantenimiento necesario (p. ej., descalcificación, limpieza del filtro).",
|
||||
"show_all_settings": "Mostrar todas las configuraciones",
|
||||
"showing_suggestions": "Mostrando configuración {count} con sugerencias.",
|
||||
"split_intro": "Haga clic en el gráfico para agregar o eliminar un punto de división, o detectar automáticamente por espacios inactivos. Cada segmento resultante puede obtener su propio perfil.",
|
||||
@@ -857,7 +862,9 @@
|
||||
"share_guidelines_title": "Antes de compartir",
|
||||
"store_download_device_intro": "Adopta todos los programas compartidos y sus ciclos de referencia en tu dispositivo. Tus propios ciclos grabados y estadísticas no se ven afectados.",
|
||||
"store_share_device_intro": "Sube {brand} {model} con los ciclos de referencia que selecciones. Otros con el mismo electrodoméstico podrán adoptar tus programas. Las entradas se revisan antes de aparecer públicamente.",
|
||||
"share_profile_no_cycles": "Sin ciclos de referencia -- marca un ciclo como ⭐ en la pestaña Ciclos para incluir este perfil"
|
||||
"share_profile_no_cycles": "Sin ciclos de referencia -- marca un ciclo como ⭐ en la pestaña Ciclos para incluir este perfil",
|
||||
"advisory_phase_inconsistent": "'{name}' parece mezclar diferentes programas o temperaturas - sus ciclos calientan durante tiempos muy distintos. Dividirlo en perfiles separados (p. ej. por temperatura) mejorará la coincidencia y las estimaciones de tiempo.",
|
||||
"advisory_phase_inconsistent_title": "⚠ Posibles programas mezclados"
|
||||
},
|
||||
"pg_desc": {
|
||||
"abrupt_drop_watts": "Caída repentina tratada como fin inmediato",
|
||||
@@ -869,12 +876,19 @@
|
||||
"start_duration_threshold": "Segundos por encima del umbral para confirmar el inicio",
|
||||
"start_threshold_w": "Vatios mínimos para contar como iniciado",
|
||||
"stop_threshold_w": "Por debajo de esto, la máquina cuenta como apagada",
|
||||
"dtw_bandwidth": "Cuánta deformación temporal permite la coincidencia de forma",
|
||||
"corr_weight": "Peso de la forma de la curva frente al nivel de potencia en la coincidencia",
|
||||
"duration_weight": "Cuánto influye la concordancia de duración en la coincidencia",
|
||||
"energy_weight": "Cuánto influye la concordancia de energía en la coincidencia",
|
||||
"profile_match_min_duration_ratio": "Ciclo más corto (frente al perfil) que aún puede coincidir",
|
||||
"profile_match_max_duration_ratio": "Ciclo más largo (frente al perfil) que aún puede coincidir"
|
||||
"dtw_bandwidth": "Etapa 3: banda de deformación Sakoe-Chiba (0 = DTW desactivado; predeterminado 0,2 = 20% de la longitud del ciclo)",
|
||||
"corr_weight": "Etapa 2: equilibrio entre la forma de la curva (correlación) y el nivel de potencia (MAE); predeterminado 0,45",
|
||||
"duration_weight": "Etapa 4: cuánto influye la concordancia de duración en la puntuación final (predeterminado 0,22)",
|
||||
"energy_weight": "Etapa 4: cuánto influye la concordancia de energía en la puntuación final (predeterminado 0,22)",
|
||||
"profile_match_min_duration_ratio": "Etapa 1: duración mínima del ciclo como fracción de la duración del perfil; predeterminado 0,1 (10%)",
|
||||
"profile_match_max_duration_ratio": "Etapa 1: duración máxima del ciclo como fracción de la duración del perfil; predeterminado 1,5 (150%)",
|
||||
"keep_min_score": "Etapa 2: puntuación mínima para seguir en la carrera; el valor predeterminado 0,1 admite coincidencias débiles, las etapas posteriores seleccionan la mejor",
|
||||
"dtw_blend": "Etapa 3: 0 = solo puntuación central, 1 = solo puntuación DTW, 0,5 = mezcla igual (predeterminado)",
|
||||
"dtw_ensemble_w": "Etapa 3 (modo ensemble): peso en L1 escalado frente a DTW derivado; el predeterminado 0,7 favorece la sensibilidad al nivel",
|
||||
"dtw_ddtw_scale": "Etapa 3: distancia de semisaturación DDTW; menor = mayor sensibilidad a la forma (predeterminado 30)",
|
||||
"dtw_refine_top_n": "Etapa 3: candidatos que DTW vuelve a puntuar; aumente a 7-9 si el perfil correcto se sitúa en 4.º-5.º lugar (predeterminado 5)",
|
||||
"duration_scale": "Etapa 4: log-razón donde la concordancia de duración se reduce a la mitad; menor = penalización más estricta (predeterminado 0,175)",
|
||||
"energy_scale": "Etapa 4: log-razón donde la concordancia de energía se reduce a la mitad; menor = penalización más estricta (predeterminado 0,25)"
|
||||
},
|
||||
"phase_desc": {
|
||||
"anti_crease": "Volteos breves ocasionales tras finalizar para evitar que la ropa se arrugue.",
|
||||
@@ -957,6 +971,10 @@
|
||||
"triggers": {
|
||||
"intro": "Señales externas opcionales: un disparador de fin, un sensor de puerta, un interruptor de pausa y el recordatorio de descarga.",
|
||||
"label": "Disparadores y puertas"
|
||||
},
|
||||
"phase_eta": {
|
||||
"label": "Tiempo restante",
|
||||
"intro": "Tiempo restante según las fases, para máquinas cuya duración de ciclo depende de la temperatura o el centrifugado."
|
||||
}
|
||||
},
|
||||
"setting": {
|
||||
@@ -1040,6 +1058,10 @@
|
||||
"doc": "Precio fijo por kWh utilizado para cifras de costos cuando no se establece ninguna entidad de precio en vivo arriba.",
|
||||
"label": "Precio de energía estático (por kWh)"
|
||||
},
|
||||
"energy_sensor": {
|
||||
"doc": "Contador de energía acumulada opcional (total_increasing en kWh/Wh, p. ej. el propio medidor de consumo total del enchufe). Cuando se establece, la energía indicada de cada ciclo se toma de la diferencia de este contador entre el inicio y el final, lo que evita la subestimación que se produce al integrar un sensor de potencia que informa lentamente. Recurre al valor integrado si falta la lectura, si su unidad es desconocida o si el delta no es positivo. Deje en blanco para seguir integrando el sensor de potencia.",
|
||||
"label": "Entidad del medidor de energía"
|
||||
},
|
||||
"expose_debug_entities": {
|
||||
"doc": "Publicar entidades HA de diagnóstico adicionales (confianza de coincidencia, ambigüedad, estados internos). Desactivado mantiene la lista de entidades limpia para un uso normal.",
|
||||
"label": "Exponer entidades de depuración"
|
||||
@@ -1322,6 +1344,38 @@
|
||||
},
|
||||
"show_contributor": {
|
||||
"doc": "Mostrar la atribución \"por <colaborador>\" en los electrodomésticos de la comunidad y los ciclos de referencia."
|
||||
},
|
||||
"enable_phase_matching": {
|
||||
"label": "Tiempo restante según las fases",
|
||||
"doc": "Divide cada ciclo en curso en fases (calentamiento, lavado, centrifugado) y reparte el tiempo restante por fase, combinado con la estimación clásica - apoyándose en el reparto por fases al principio del ciclo y en la estimación clásica cerca del final. Esto personaliza la cuenta atrás según cuánto calienta y funciona realmente tu máquina, lo que se nota más en la primera mitad del ciclo. Desactivado = solo la estimación clásica. Solo se ve afectada la visualización del tiempo restante; la coincidencia de programas y la detección de ciclos no cambian."
|
||||
},
|
||||
"keep_min_score": {
|
||||
"label": "Score mín de coincidencia",
|
||||
"doc": "Puntuación de similitud mínima que necesita un candidato para seguir en la carrera de coincidencia. El valor predeterminado 0,1 es deliberadamente permisivo - admite incluso candidatos débiles y se basa en etapas posteriores para encontrar la mejor coincidencia. Auméntelo para eliminar perfiles improbables antes; redúzcalo para ampliar el pool de candidatos inicial."
|
||||
},
|
||||
"dtw_blend": {
|
||||
"label": "Fusión Warp",
|
||||
"doc": "Cuánto reemplaza la puntuación de alineación por deformación temporal (DTW) a la puntuación central de la Etapa 2. 0 = usar solo la puntuación de la Etapa 2, 1 = usar solo la puntuación DTW, 0,5 (predeterminado) = mezcla igual. Auméntelo para confiar más en el alineamiento Warp cuando los programas tienen niveles de potencia similares pero diferentes patrones de temporización."
|
||||
},
|
||||
"dtw_ensemble_w": {
|
||||
"label": "Mix ensemble Warp",
|
||||
"doc": "En el modo DTW ensemble (el predeterminado), el peso en L1 escalado frente a DTW derivado (DDTW). 1,0 = todo L1 escalado, 0 = todo DDTW, 0,7 = predeterminado. La variante L1 escalado compara niveles de potencia; la variante derivada reacciona a cómo cambia la potencia con el tiempo. Ensemble combina ambas."
|
||||
},
|
||||
"dtw_ddtw_scale": {
|
||||
"label": "Escala Warp derivada",
|
||||
"doc": "Distancia de semisaturación para la puntuación DTW derivada. La puntuación se reduce a la mitad cuando la distancia DDTW es igual a este valor. Menor = más sensible a las diferencias de forma. El predeterminado 30 está calibrado para trazas de potencia típicas de electrodomésticos. Solo afecta a los modos DTW ensemble y ddtw."
|
||||
},
|
||||
"dtw_refine_top_n": {
|
||||
"label": "Contador de refinamiento Warp",
|
||||
"doc": "Cuántos candidatos principales de la Etapa 2 son repuntuados por DTW. DTW es más costoso, por lo que solo se aplica a los mejores N candidatos. Predeterminado 5. Auméntelo (a 7-9) si el perfil correcto a veces solo alcanza el 4.º o 5.º lugar tras la Etapa 2 - DTW puede rescatarlo. Reducirlo acelera ligeramente la coincidencia."
|
||||
},
|
||||
"duration_scale": {
|
||||
"label": "Nitidez de duración",
|
||||
"doc": "Precisión de la penalización por concordancia de duración en la Etapa 4. Este es el log-ratio en el que el score de concordancia se reduce a la mitad. Menor = más estricto: una discordancia de duración penaliza más. El predeterminado 0,175 corresponde a aproximadamente el 18% de tolerancia de duración a medio peso. Combinar con Peso de duración."
|
||||
},
|
||||
"energy_scale": {
|
||||
"label": "Nitidez de energía",
|
||||
"doc": "Precisión de la penalización por concordancia de energía. Menor = más estricto: una discordancia de energía penaliza más. El predeterminado 0,25 es intencionalmente más indulgente que la Precisión de duración, porque la energía varía con la carga. Combinar con Peso de energía."
|
||||
}
|
||||
},
|
||||
"setting_group": {
|
||||
@@ -1570,24 +1624,24 @@
|
||||
"lower": "Etiqueta más ciclos automáticamente; algunos pueden ser mal identificados"
|
||||
},
|
||||
"duration_tolerance": {
|
||||
"higher": "Acepta un rango de duración más amplio — correspondencia más flexible",
|
||||
"lower": "Exige una duración más cercana — más estricto, puede rechazar ciclos inusuales"
|
||||
"higher": "Acepta un rango de duración más amplio – correspondencia más flexible",
|
||||
"lower": "Exige una duración más cercana – más estricto, puede rechazar ciclos inusuales"
|
||||
},
|
||||
"end_energy_threshold": {
|
||||
"higher": "Solo cierra ciclos que usaron energía significativa",
|
||||
"lower": "También cierra ciclos cortos o de baja energía"
|
||||
},
|
||||
"end_repeat_count": {
|
||||
"higher": "Exige que la señal de fin se repita más veces — más robusto, ligeramente más lento",
|
||||
"lower": "Termina tras menos repeticiones — detección más rápida, mayor riesgo de fin falso"
|
||||
"higher": "Exige que la señal de fin se repita más veces – más robusto, ligeramente más lento",
|
||||
"lower": "Termina tras menos repeticiones – detección más rápida, mayor riesgo de fin falso"
|
||||
},
|
||||
"learning_confidence": {
|
||||
"higher": "Aprende solo de coincidencias muy confiables — más lento pero más fiable",
|
||||
"higher": "Aprende solo de coincidencias muy confiables – más lento pero más fiable",
|
||||
"lower": "Aprende de más ciclos; el modelo puede ser menos preciso"
|
||||
},
|
||||
"min_off_gap": {
|
||||
"higher": "Se necesita más tiempo de inactividad antes de iniciar un nuevo ciclo",
|
||||
"lower": "Un breve reposo inicia un nuevo ciclo — ejecuciones consecutivas pueden dividirse"
|
||||
"lower": "Un breve reposo inicia un nuevo ciclo – ejecuciones consecutivas pueden dividirse"
|
||||
},
|
||||
"min_power": {
|
||||
"higher": "Menos sensible al consumo en reposo; puede perder programas muy silenciosos",
|
||||
@@ -1598,24 +1652,24 @@
|
||||
"lower": "Detiene un ciclo atascado antes"
|
||||
},
|
||||
"off_delay": {
|
||||
"higher": "Más tiempo para pausas del electrodoméstico — gestiona fases largas de remojo o secado",
|
||||
"lower": "Detección de fin más rápida — ideal para electrodomésticos con encendido/apagado limpio"
|
||||
"higher": "Más tiempo para pausas del electrodoméstico – gestiona fases largas de remojo o secado",
|
||||
"lower": "Detección de fin más rápida – ideal para electrodomésticos con encendido/apagado limpio"
|
||||
},
|
||||
"profile_match_threshold": {
|
||||
"higher": "Solo confirma coincidencias de alta confianza; más ciclos quedan sin etiquetar",
|
||||
"lower": "Coincide con más ciclos; algunos pueden ser ligeramente incorrectos"
|
||||
},
|
||||
"running_dead_zone": {
|
||||
"higher": "Ignora breves picos de potencia en reposo — menos sensible al ruido",
|
||||
"lower": "Reacciona a impulsos más cortos — detecta actividad transitoria rápida"
|
||||
"higher": "Ignora breves picos de potencia en reposo – menos sensible al ruido",
|
||||
"lower": "Reacciona a impulsos más cortos – detecta actividad transitoria rápida"
|
||||
},
|
||||
"start_threshold_w": {
|
||||
"higher": "Evita arranques falsos por breves picos de potencia",
|
||||
"lower": "Detecta programas de baja potencia; puede activarse con ruido"
|
||||
},
|
||||
"stop_threshold_w": {
|
||||
"higher": "Termina el ciclo antes — puede cerrarse durante una pausa",
|
||||
"lower": "Espera más para terminar — menos finales prematuros"
|
||||
"higher": "Termina el ciclo antes – puede cerrarse durante una pausa",
|
||||
"lower": "Espera más para terminar – menos finales prematuros"
|
||||
},
|
||||
"watchdog_interval": {
|
||||
"higher": "Se permiten fases silenciosas más largas; menos paradas forzadas falsas",
|
||||
@@ -1766,6 +1820,69 @@
|
||||
},
|
||||
"pg_sweep": {
|
||||
"optimize": "Optimizar: {param}"
|
||||
},
|
||||
"pg_detail": {
|
||||
"simulate": "Simular ciclo"
|
||||
},
|
||||
"split": {
|
||||
"apply": "Dividiendo el ciclo"
|
||||
},
|
||||
"trim": {
|
||||
"apply": "Recortando el ciclo"
|
||||
},
|
||||
"merge": {
|
||||
"apply": "Combinando ciclos"
|
||||
},
|
||||
"rebuild": {
|
||||
"envelopes": "Reconstruyendo envolventes"
|
||||
},
|
||||
"cancelling": "Cancelando..."
|
||||
},
|
||||
"setup": {
|
||||
"hdr": {
|
||||
"card": "Configuración del dispositivo",
|
||||
"healthy_chip": "Configuración completada"
|
||||
},
|
||||
"phase0": {
|
||||
"washer": "WashData ya está detectando tus ciclos. Graba tu primer ciclo para activar los nombres de programas y las estimaciones de tiempo.",
|
||||
"dishwasher": "WashData está observando. Los lavavajillas tienen ciclos complejos – se recomienda encarecidamente grabar el primer ciclo. Si un ciclo detectado se alarga demasiado, usa el editor de ciclos para recortarlo antes de guardarlo como perfil.",
|
||||
"generic": "WashData está observando. Graba o etiqueta un ciclo detectado para empezar a crear perfiles."
|
||||
},
|
||||
"phase1a": {
|
||||
"labelled": "Buen comienzo – tu primer programa está guardado. Para datos más precisos, considera grabar tu próximo ciclo con el widget de grabación."
|
||||
},
|
||||
"phase1b": {
|
||||
"recorded": "Tu grabación se guardó como {profile_name}. Ahora graba o etiqueta tus otros programas habituales para ampliar la cobertura."
|
||||
},
|
||||
"phase1c": {
|
||||
"verify": "Tienes {count} programas de la comunidad. Ejecuta un ciclo para verificar que WashData lo reconoce correctamente – la correspondencia mejorará a medida que tu dispositivo construya su propio historial."
|
||||
},
|
||||
"phase2": {
|
||||
"cluster": "WashData ha observado {count} ciclos que no coinciden con ningún programa guardado – se parecen entre sí. ¿Deseas crear un nuevo perfil para ellos?",
|
||||
"unmatched": "Tu último ciclo no coincidió con ningún programa guardado. ¿Es un nuevo programa?"
|
||||
},
|
||||
"phase3": {
|
||||
"suggestions": "WashData tiene recomendaciones de configuración basadas en tu historial de ciclos – revísalas para mejorar la precisión de detección.",
|
||||
"groups": "Algunos de tus perfiles parecen el mismo programa a diferentes temperaturas. Organízalos en un grupo para una mejor correspondencia.",
|
||||
"phases": "Añade fases de programa a {profile_name} para estimaciones más precisas del tiempo restante."
|
||||
},
|
||||
"phase4": {
|
||||
"healthy": "Este dispositivo está completamente configurado ({profile_count} perfiles)."
|
||||
},
|
||||
"cta": {
|
||||
"start_recording": "Iniciar grabación",
|
||||
"label_detected_cycle": "Ya tengo un ciclo detectado – etiquetarlo en su lugar",
|
||||
"browse_cycles": "Explorar ciclos para etiquetar otro",
|
||||
"view_profiles": "Ver tus perfiles",
|
||||
"create_from_cluster": "Crear perfil a partir de estos ciclos",
|
||||
"create_profile": "Crear un perfil para este programa",
|
||||
"review_suggestions": "Revisar sugerencias",
|
||||
"organise_profiles": "Organizar perfiles",
|
||||
"configure_phases": "Configurar fases",
|
||||
"skip_step": "Omitir este paso",
|
||||
"skip_forever": "No volver a mostrar",
|
||||
"hide_guidance": "Ocultar guía",
|
||||
"show_guidance": "Mostrar guía"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
"on_cycle_finished": "Tsükkel lõppenud",
|
||||
"on_cycle_started": "Tsükkel algas",
|
||||
"pause_cycle": "Paus",
|
||||
"pause_cycle_tip": "Peata käimasolev tsükkel — seade jätkab sealt, kus pooleli jäi",
|
||||
"pause_cycle_tip": "Peata käimasolev tsükkel – seade jätkab sealt, kus pooleli jäi",
|
||||
"pg_apply_device": "Rakenda seadmele",
|
||||
"pg_autofill": "Täida automaatselt",
|
||||
"play": "Esita",
|
||||
@@ -97,8 +97,8 @@
|
||||
"process_tip": "Salvesta salvestatud jälg uue või olemasoleva profiilina",
|
||||
"rebuild": "Ümbrikute ümberehitamine",
|
||||
"rebuild_envelope": "Ümberehitage ümbrik",
|
||||
"rebuild_tip": "Arvuta uuesti kõigi profiilide eeldatav võimsusümbrik (min/max riba) nende märgistatud tsüklite põhjal — käivitage pärast uute tsüklite märgistamist või vanade parandamist",
|
||||
"rec_start_tip": "Alusta seadme võimsusjälje salvestamist — käivita vahetult enne tsükli käivitamist",
|
||||
"rebuild_tip": "Arvuta uuesti kõigi profiilide eeldatav võimsusümbrik (min/max riba) nende märgistatud tsüklite põhjal – käivitage pärast uute tsüklite märgistamist või vanade parandamist",
|
||||
"rec_start_tip": "Alusta seadme võimsusjälje salvestamist – käivita vahetult enne tsükli käivitamist",
|
||||
"rec_stop": "Peatus",
|
||||
"rec_stop_tip": "Peata salvestamine ja hoia jäädvustatud jälg ülevaatamiseks",
|
||||
"record": "Alustage salvestamist",
|
||||
@@ -182,7 +182,7 @@
|
||||
},
|
||||
"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.",
|
||||
"settings_banner": "{n} seadete konflikt{s} – kontrollige esile tõstetud sektsioone ja parandage enne salvestamist.",
|
||||
"settings_banner_btn": "Mine esimesele",
|
||||
"confidence": {
|
||||
"auto": "Peab olema vähemalt vaste läve tasemel ({match})",
|
||||
@@ -451,9 +451,9 @@
|
||||
"show_expected": "Kuva eeldatav kõvera ülekate (sobiv profiil, oranž)",
|
||||
"show_raw": "Kuva töötlemata pistikupesa lülitit reaalajas võimsusgraafikus",
|
||||
"sparkline": "Hiljutine tsükli kestuse trend",
|
||||
"stage2": "Etapp 2 — põhisarnasus",
|
||||
"stage3": "Etapp 3 — DTW",
|
||||
"stage4": "Etapp 4 — kokkulangevus",
|
||||
"stage2": "Etapp 2 – põhisarnasus",
|
||||
"stage3": "Etapp 3 – DTW",
|
||||
"stage4": "Etapp 4 – kokkulangevus",
|
||||
"status": "Olek",
|
||||
"tail_trim": "Saba trimm (id)",
|
||||
"timer_auto_pause": "Automaatne paus",
|
||||
@@ -561,7 +561,12 @@
|
||||
"flags": "Embleemid",
|
||||
"include_phase_map": "Kaasa faasikaart",
|
||||
"include_settings": "Kaasa tuvastus- ja sobitamisseaded",
|
||||
"show_contributor": "Näita kaastöötajate nimesid"
|
||||
"show_contributor": "Näita kaastöötajate nimesid",
|
||||
"task_pg_detail": "Tsükli simuleerimine",
|
||||
"task_split": "Tsükli poolitamine",
|
||||
"task_trim": "Tsükli kärpimine",
|
||||
"task_merge": "Tsüklite ühendamine",
|
||||
"task_rebuild": "Võimsusvahemike taasloomine"
|
||||
},
|
||||
"log": {
|
||||
"all_levels": "Kõik tasemed",
|
||||
@@ -645,7 +650,7 @@
|
||||
"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.",
|
||||
"artifact_header": "Selle tsükli jooksul tuvastati {n} anomaaliat",
|
||||
"artifact_pause_detail": "Võimsus langes peaaegu nulli umbes {n}s jooksul ja taastus seejärel — tõenäoliselt avati uks tsükli keskel või tsükkel peatati.",
|
||||
"artifact_pause_detail": "Võimsus langes peaaegu nulli umbes {n}s jooksul ja taastus seejärel – tõenäoliselt avati uks tsükli keskel või tsükkel peatati.",
|
||||
"artifact_spike_detail": "Ületas tavapärase võimsusriba umbes {n}s jooksul.",
|
||||
"auto_label_intro": "Määrake profiilid märgistamata tsüklitele, mille sobivuse usaldus eemaldab läve.",
|
||||
"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.",
|
||||
@@ -654,10 +659,10 @@
|
||||
"collecting_data": "Andmete kogumine - {need} tsüklit veel enne peenhäälestuse alustamist ({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",
|
||||
"compare_selected_cycles": "Valitud tsüklid (tahked) – näita/peida",
|
||||
"consider_new_profile": "Kaaluge uue profiili loomist.",
|
||||
"coverage_gap": "viimastel tsüklitel pole sobivat profiili ({pct}% viimasest 30-st).",
|
||||
"coverage_gap_similar_cycles": "{count} sarnast märgistamata tsüklit leitud — loo profiil, et neid sobitama hakata.",
|
||||
"coverage_gap_similar_cycles": "{count} sarnast märgistamata tsüklit leitud – loo profiil, et neid sobitama hakata.",
|
||||
"cycles_deleted": "{count} tsüklit kustutatud",
|
||||
"enough_data": "Piisavalt andmeid õppimiseks ({current}/{min} tsüklit).",
|
||||
"export_description": "Eksportige kõik profiilid ja tsüklid JSON-i või taastage eelmisest ekspordist.",
|
||||
@@ -686,7 +691,7 @@
|
||||
"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.",
|
||||
"name_first_program": "Sul on piisavalt tsükleid — pane oma esimesele programmile nimi, et alustada sobitamist.",
|
||||
"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.",
|
||||
"no_cycles_profile": "Sellel profiilil pole tsükleid.",
|
||||
@@ -713,7 +718,7 @@
|
||||
"notify_services_hint": "Kasutage {entity} teenuse ID-sid (mitme korral komadega eraldatult). Malli muutujad: {vars}.",
|
||||
"old_actions_warning": "Seadistatud vana toimingute redaktoriga (nüüd eemaldatud). Need käivituvad endiselt tsüklisündmustele, kuid neid ei saa siin enam redigeerida. Teisendage need tavaliseks automaatikaks või eemaldage need.",
|
||||
"onboarding_progress": "{n} / 3 tsüklit jälgitud",
|
||||
"onboarding_watching": "Kasuta oma seadet tavapäraselt — WashData jälgib. Pärast 3 tsüklit algab programmide sobitamine.",
|
||||
"onboarding_watching": "Kasuta oma seadet tavapäraselt – WashData jälgib. Pärast 3 tsüklit algab programmide sobitamine.",
|
||||
"pending_feedback": "Ootab tuvastamise tagasisidet",
|
||||
"performance_trend": "Toimivuse trend ({n} tsüklit)",
|
||||
"pg_analysis_empty": "Vaste analüüsi nägemiseks laadi tsükkel.",
|
||||
@@ -763,7 +768,7 @@
|
||||
"setting_changed": "Muudetud {old} → {new} kuupäeval {date}",
|
||||
"settings_basic_note": "Kuvatakse olulisi seadeid. Täieliku loendi nägemiseks vali Täpsemalt.",
|
||||
"shape_drift_advisory": "⚠ Kuju triivib",
|
||||
"shape_drift_detail": "Selle profiili võimsusstruktuur on aja jooksul muutunud — võimalik seadme kulumine või vajalik hooldus (nt katlakivi eemaldamine, filtri puhastamine).",
|
||||
"shape_drift_detail": "Selle profiili võimsusstruktuur on aja jooksul muutunud – võimalik seadme kulumine või vajalik hooldus (nt katlakivi eemaldamine, filtri puhastamine).",
|
||||
"show_all_settings": "Kuva kõik seaded",
|
||||
"showing_suggestions": "Kuvatakse seade {count} koos soovitustega.",
|
||||
"split_intro": "Jaotuspunkti lisamiseks või eemaldamiseks või tühikäigu automaatseks tuvastamiseks klõpsake graafikul. Iga saadud segment võib saada oma profiili.",
|
||||
@@ -857,7 +862,9 @@
|
||||
"share_guidelines_title": "Enne jagamist",
|
||||
"store_download_device_intro": "Võtke kasutusele iga jagatud programm ja selle võrdlustsüklid oma seadmel. Teie enda salvestatud tsükleid ja statistikat ei mõjutata.",
|
||||
"store_share_device_intro": "Laadige {brand} {model} üles valitud võrdlustsüklitega. Teised sama kodumasina kasutajad saavad teie programme kasutusele võtta. Kirjeid vaadatakse üle enne avalikustamist.",
|
||||
"share_profile_no_cycles": "Võrdlustsükleid pole -- märkige tsükkel ⭐-ks Tsüklid-vahekaardil, et lisada see profiil"
|
||||
"share_profile_no_cycles": "Võrdlustsükleid pole -- märkige tsükkel ⭐-ks Tsüklid-vahekaardil, et lisada see profiil",
|
||||
"advisory_phase_inconsistent": "'{name}' näib segavat erinevaid programme või temperatuure - selle tsüklid kuumutavad väga erineva aja jooksul. Selle jagamine eraldi profiilideks (nt temperatuuri järgi) parandab sobitamist ja ajahinnanguid.",
|
||||
"advisory_phase_inconsistent_title": "⚠ Võimalik programmide segu"
|
||||
},
|
||||
"pg_desc": {
|
||||
"abrupt_drop_watts": "Järsk langus käsitletakse kohese lõpuna",
|
||||
@@ -869,12 +876,19 @@
|
||||
"start_duration_threshold": "Sekundid üle läve käivituse kinnitamiseks",
|
||||
"start_threshold_w": "Minimaalne vatt, et lugeda käivitunuks",
|
||||
"stop_threshold_w": "Sellest allpool loetakse masin väljalülitatuks",
|
||||
"dtw_bandwidth": "Kui palju ajalist venitamist kuju sobitamine lubab",
|
||||
"corr_weight": "Kõvera kuju vs võimsustaseme kaal sobitamisel",
|
||||
"duration_weight": "Kui palju kestuse kokkulangevus sobitamist mõjutab",
|
||||
"energy_weight": "Kui palju energia kokkulangevus sobitamist mõjutab",
|
||||
"profile_match_min_duration_ratio": "Lühim tsükkel (profiiliga võrreldes), mida veel lubatakse sobitada",
|
||||
"profile_match_max_duration_ratio": "Pikim tsükkel (profiiliga võrreldes), mida veel lubatakse sobitada"
|
||||
"dtw_bandwidth": "Etapp 3: Sakoe-Chiba aja-nihkeriba (0 = DTW väljas; vaikimisi 0,2 = 20% tsükli pikkusest)",
|
||||
"corr_weight": "Etapp 2: tasakaal kõvera kuju (korrelatsioon) ja võimsustaseme (MAE) vahel; vaikimisi 0,45",
|
||||
"duration_weight": "Etapp 4: kui tugevalt kestuse vastavus mõjutab lõppskooris (vaikimisi 0,22)",
|
||||
"energy_weight": "Etapp 4: kui tugevalt energia vastavus mõjutab lõppskooris (vaikimisi 0,22)",
|
||||
"profile_match_min_duration_ratio": "Etapp 1: lühim tsükkel profiili kestuse murdosana; vaikimisi 0,1 (10%)",
|
||||
"profile_match_max_duration_ratio": "Etapp 1: pikim tsükkel profiili kestuse murdosana; vaikimisi 1,5 (150%)",
|
||||
"keep_min_score": "Etapp 2: madalaim skoor võistluses püsimiseks; vaikimisi 0,1 lubab nõrku kandidaate, hilisemad etapid valivad parima",
|
||||
"dtw_blend": "Etapp 3: 0 = ainult põhiskoor, 1 = ainult DTW-skoor, 0,5 = võrdne segu (vaikimisi)",
|
||||
"dtw_ensemble_w": "Etapp 3 (ensemble-režiim): skaleeritud L1 kaal vs tuletise DTW; vaikimisi 0,7 eelistab tasemeteadlikkust",
|
||||
"dtw_ddtw_scale": "Etapp 3: DDTW pool-küllastumiskaugus; väiksem = tundlikum kuju erinevuste suhtes (vaikimisi 30)",
|
||||
"dtw_refine_top_n": "Etapp 3: kandidaadid keda DTW hindab ümber; tõstke 7-9-ni kui õige profiil jõuab 4.-5. kohale (vaikimisi 5)",
|
||||
"duration_scale": "Etapp 4: log-suhe kus kestuse vastavus poolitub; väiksem = rangem karistus (vaikimisi 0,175)",
|
||||
"energy_scale": "Etapp 4: log-suhe kus energia vastavus poolitub; väiksem = rangem karistus (vaikimisi 0,25)"
|
||||
},
|
||||
"phase_desc": {
|
||||
"anti_crease": "Kortsude vähendamiseks tehke aeg-ajalt lühikesi tõmblusi pärast lõpetamist.",
|
||||
@@ -957,6 +971,10 @@
|
||||
"triggers": {
|
||||
"intro": "Valikulised välised signaalid: lõpu päästik, ukse andur, pausi lüliti ja mahalaadimisel meeldetuletaja.",
|
||||
"label": "Päästikud ja Uksed"
|
||||
},
|
||||
"phase_eta": {
|
||||
"label": "Järelejäänud aeg",
|
||||
"intro": "Faasiteadlik järelejäänud aeg masinatele, mille tsükli pikkus sõltub temperatuurist või tsentrifuugimisest."
|
||||
}
|
||||
},
|
||||
"setting": {
|
||||
@@ -1040,6 +1058,10 @@
|
||||
"doc": "Fikseeritud hind kWh kohta, mida kasutatakse kulunäitajate jaoks, kui ülal pole määratud reaalajas hinna olemit.",
|
||||
"label": "Staatiline Energia Hind (kWh kohta)"
|
||||
},
|
||||
"energy_sensor": {
|
||||
"doc": "Valikuline kumulatiivne energialoendur (total_increasing kWh/Wh, nt pistiku enda kogutarbimise arvesti). Kui see on määratud, võetakse iga tsükli energianäit selle loenduri algus- ja lõppnäidu vahest, mis väldib alamõõtmist, mida tekitab aeglaselt uueneva võimsusanduri integreerimine. Kui näit puudub, selle ühik on teadmata või vahe pole positiivne, kasutatakse tagavaraks integreeritud väärtust. Jätke tühjaks, et jätkata võimsusanduri integreerimist.",
|
||||
"label": "Energiaarvesti Olem"
|
||||
},
|
||||
"expose_debug_entities": {
|
||||
"doc": "Avaldage täiendavad diagnostilised HA-üksused (vaste usaldus, mitmetähenduslikkus, oleku sisemised andmed). Väljas hoiab olemiloendi tavakasutuseks puhtana.",
|
||||
"label": "Näita Silumise Olemeid"
|
||||
@@ -1322,6 +1344,38 @@
|
||||
},
|
||||
"show_contributor": {
|
||||
"doc": "Kuva \"<kaastöötaja> poolt\" omistamine kogukonna kodumasinate ja võrdlustsüklite juures."
|
||||
},
|
||||
"enable_phase_matching": {
|
||||
"label": "Faasiteadlik järelejäänud aeg",
|
||||
"doc": "Jaga iga käimasolev tsükkel faasideks (kuumutamine, pesu, tsentrifuugimine) ja eelarvesta järelejäänud aeg faaside kaupa, segatuna klassikalise hinnanguga - toetudes tsükli alguses faasi eelarvele ja lõpu lähedal klassikalisele hinnangule. See kohandab loenduri sellele, kui kaua su masin tegelikult kuumutab ja töötab, mis on kõige märgatavam tsükli esimeses pooles. Väljas = ainult klassikaline hinnang. Mõjutab ainult järelejäänud aja kuva; programmi sobitamine ja tsükli tuvastamine jäävad muutmata."
|
||||
},
|
||||
"keep_min_score": {
|
||||
"label": "Min vastenduse skoor",
|
||||
"doc": "Madalaim sarnasuskoor, mida kandidaat vajab sobitamisel püsimiseks. Vaikimisi 0,1 on tahtlikult lubav – see lubab isegi nõrku kandidaate ja toetub hilisematele etappidele parima vaste leidmiseks. Tõstke, et kärpida ebatõenäolisi profiile varem; langetage algse kandidaatide hulga laiendamiseks."
|
||||
},
|
||||
"dtw_blend": {
|
||||
"label": "DTW-segu",
|
||||
"doc": "Kui palju DTW-joondamise skoor asendab 2. etapi põhiskoorit. 0 = kasuta ainult 2. etapi skoorit, 1 = kasuta ainult DTW-skoorit, 0,5 (vaikimisi) = võrdne segu. Tõstke, et rohkem toetuda aja-joondamisele, kui programmidel on sarnased võimsustasemed kuid erinevad ajastamismustrid."
|
||||
},
|
||||
"dtw_ensemble_w": {
|
||||
"label": "DTW ensemble-miks",
|
||||
"doc": "Ensemble-DTW-režiimis (vaikimisi) on see kaal skaleeritud L1 versus tuletise DTW (DDTW). 1,0 = ainult skaleeritud L1, 0 = ainult DDTW, 0,7 = vaikimisi. Skaleeritud variant võrdleb võimsustasemeid; tuletise variant reageerib sellele, kuidas võimsus aja jooksul muutub. Ensemble ühendab mõlemad."
|
||||
},
|
||||
"dtw_ddtw_scale": {
|
||||
"label": "Tuletise DTW skaala",
|
||||
"doc": "Pool-küllastumiskaugus tuletise DTW hindamisel. Skoor poolitub, kui DDTW-kaugus võrdub selle väärtusega. Väiksem = tundlikum kuju erinevuste suhtes. Vaikimisi 30 on kalibreeritud tüüpiliste seadmete võimsusjälgedele. Mõjutab ainult ensemble- ja ddtw-DTW-režiime."
|
||||
},
|
||||
"dtw_refine_top_n": {
|
||||
"label": "DTW täpsustusarv",
|
||||
"doc": "Mitu parimat 2. etapi kandidaati DTW ümber hindab. DTW on kallim, seega rakendatakse seda ainult N parimale. Vaikimisi 5. Tõstke (7-9-ni), kui õige profiil jõuab mõnikord ainult 4. või 5. kohale pärast 2. etappi – DTW saab selle päästa. Madalama väärtusega sobitumine kiireneb veidi."
|
||||
},
|
||||
"duration_scale": {
|
||||
"label": "Kestuse teravus",
|
||||
"doc": "4. etapi kestuse vastavuse karistuse teravus. See on log-suhe, mille juures vastavuse skoor poolitub. Väiksem = rangem: kestuse mittevastavus teeb rohkem kahju. Vaikimisi 0,175 vastab ligikaudu 18% kestuse tolerantsile poolkaalu juures. Kasutage koos Kestuse kaaluga."
|
||||
},
|
||||
"energy_scale": {
|
||||
"label": "Energia teravus",
|
||||
"doc": "4. etapi energia vastavuse karistuse teravus. Väiksem = rangem: energia mittevastavus teeb rohkem kahju. Vaikimisi 0,25 on tahtlikult andelikum kui kestuse teravus, kuna energia varieerub koormuse järgi. Kasutage koos Energia kaaluga."
|
||||
}
|
||||
},
|
||||
"setting_group": {
|
||||
@@ -1570,24 +1624,24 @@
|
||||
"lower": "Märgistab automaatselt rohkem tsükleid; mõnda võidakse valesti tuvastada"
|
||||
},
|
||||
"duration_tolerance": {
|
||||
"higher": "Aktsepteerib laiemat kestuse vahemikku — paindlikum sobitamine",
|
||||
"lower": "Nõuab täpsemat kestuse vastavust — rangem, kuid võib lükata tagasi ebatavalisi tsükleid"
|
||||
"higher": "Aktsepteerib laiemat kestuse vahemikku – paindlikum sobitamine",
|
||||
"lower": "Nõuab täpsemat kestuse vastavust – rangem, kuid võib lükata tagasi ebatavalisi tsükleid"
|
||||
},
|
||||
"end_energy_threshold": {
|
||||
"higher": "Sulgeb ainult tsüklid, mis kasutasid olulisel määral energiat",
|
||||
"lower": "Sulgeb ka lühemad või madalama energiatarbe tsüklid"
|
||||
},
|
||||
"end_repeat_count": {
|
||||
"higher": "Nõuab lõpusignaali kordamist rohkem kordi — usaldusväärsem, pisut aeglasem",
|
||||
"lower": "Lõpetab pärast vähemat kordust — kiirem tuvastamine, suurem vale lõpu oht"
|
||||
"higher": "Nõuab lõpusignaali kordamist rohkem kordi – usaldusväärsem, pisut aeglasem",
|
||||
"lower": "Lõpetab pärast vähemat kordust – kiirem tuvastamine, suurem vale lõpu oht"
|
||||
},
|
||||
"learning_confidence": {
|
||||
"higher": "Õpib ainult väga kindlatest vastetest — aeglasem, kuid usaldusväärsem",
|
||||
"higher": "Õpib ainult väga kindlatest vastetest – aeglasem, kuid usaldusväärsem",
|
||||
"lower": "Õpib rohkematest tsüklitest; mudel võib olla müraram"
|
||||
},
|
||||
"min_off_gap": {
|
||||
"higher": "Enne uue tsükli algust on vajalik pikem tegevusetus",
|
||||
"lower": "Lühike tegevusetus käivitab uue tsükli — järjestikused käivitused võivad jaguneda"
|
||||
"lower": "Lühike tegevusetus käivitab uue tsükli – järjestikused käivitused võivad jaguneda"
|
||||
},
|
||||
"min_power": {
|
||||
"higher": "Vähem tundlik ooterežiimi tarbimise suhtes; võib vahele jätta vaikse töörežiimi",
|
||||
@@ -1598,24 +1652,24 @@
|
||||
"lower": "Jõudab kinni jäänud tsükli sundpeatamise kiiremini"
|
||||
},
|
||||
"off_delay": {
|
||||
"higher": "Rohkem aega seadme paussideks — käsitleb pikka leotamist või kuivatamist",
|
||||
"lower": "Kiirem lõpu tuvastamine — sobib hästi selge sisse/välja seadmetele"
|
||||
"higher": "Rohkem aega seadme paussideks – käsitleb pikka leotamist või kuivatamist",
|
||||
"lower": "Kiirem lõpu tuvastamine – sobib hästi selge sisse/välja seadmetele"
|
||||
},
|
||||
"profile_match_threshold": {
|
||||
"higher": "Kinnitab ainult suure kindlusega vasteid; rohkem tsükleid jääb märgistamata",
|
||||
"lower": "Sobib rohkema tsükliga; mõnda võib olla veidi vale"
|
||||
},
|
||||
"running_dead_zone": {
|
||||
"higher": "Ignoreerib lühikesi voolutõuse jõudeolekus — vähem müra suhtes tundlik",
|
||||
"lower": "Reageerib lühematele energiapursetele — tabab kiiret mööduvat aktiivsust"
|
||||
"higher": "Ignoreerib lühikesi voolutõuse jõudeolekus – vähem müra suhtes tundlik",
|
||||
"lower": "Reageerib lühematele energiapursetele – tabab kiiret mööduvat aktiivsust"
|
||||
},
|
||||
"start_threshold_w": {
|
||||
"higher": "Väldib lühikestest energiatõusudest tulenevaid valesid käivitusi",
|
||||
"lower": "Tabab madalvõimsusega programmid; võib käivituda müra peale"
|
||||
},
|
||||
"stop_threshold_w": {
|
||||
"higher": "Lõpetab tsükli kiiremini — võib sulgeda pausi ajal",
|
||||
"lower": "Ootab lõpetamisega kauem — vähem enneaegseid lõpetusi"
|
||||
"higher": "Lõpetab tsükli kiiremini – võib sulgeda pausi ajal",
|
||||
"lower": "Ootab lõpetamisega kauem – vähem enneaegseid lõpetusi"
|
||||
},
|
||||
"watchdog_interval": {
|
||||
"higher": "Lubatud pikemad vaiksed faasid; vähem valesid sundpeatusi",
|
||||
@@ -1766,6 +1820,69 @@
|
||||
},
|
||||
"pg_sweep": {
|
||||
"optimize": "Optimeerimine: {param}"
|
||||
},
|
||||
"pg_detail": {
|
||||
"simulate": "Tsükli simuleerimine"
|
||||
},
|
||||
"split": {
|
||||
"apply": "Tsükli poolitamine"
|
||||
},
|
||||
"trim": {
|
||||
"apply": "Tsükli kärpimine"
|
||||
},
|
||||
"merge": {
|
||||
"apply": "Tsüklite ühendamine"
|
||||
},
|
||||
"rebuild": {
|
||||
"envelopes": "Võimsusvahemike taasloomine"
|
||||
},
|
||||
"cancelling": "Katkestan..."
|
||||
},
|
||||
"setup": {
|
||||
"hdr": {
|
||||
"card": "Seadme seadistus",
|
||||
"healthy_chip": "Seadistus lõpetatud"
|
||||
},
|
||||
"phase0": {
|
||||
"washer": "WashData tuvastab juba teie tsükleid. Salvestage esimene tsükkel, et lubada programmide nimed ja ajahinnangud.",
|
||||
"dishwasher": "WashData jälgib. Nõudepesumasinatel on keerukad tsüklid – esimese tsükli salvestamine on tungivalt soovitatav. Kui tuvastatud tsükkel töötab liiga kaua, kasutage tsükli redaktorit selle kärpimiseks enne profiilina salvestamist.",
|
||||
"generic": "WashData jälgib. Salvestage või märgistage tuvastatud tsükkel profiilide loomise alustamiseks."
|
||||
},
|
||||
"phase1a": {
|
||||
"labelled": "Hea algus – teie esimene programm on salvestatud. Puhtaimate andmete saamiseks kaaluge järgmise tsükli salvestamist salvestusvidinaga."
|
||||
},
|
||||
"phase1b": {
|
||||
"recorded": "Teie salvestus on salvestatud kui {profile_name}. Nüüd salvestage või märgistage oma teised sagedased programmid katvuse suurendamiseks."
|
||||
},
|
||||
"phase1c": {
|
||||
"verify": "Teil on {count} programmi kogukonnast. Käivitage tsükkel, et kontrollida, kas WashData tunneb selle õigesti ära – sobitamine paraneb, kui teie seade koostab oma ajaloo."
|
||||
},
|
||||
"phase2": {
|
||||
"cluster": "WashData on näinud {count} tsüklit, mis ei vasta ühelegi salvestatud programmile – need näevad sarnased välja. Kas soovite neile luua uue profiili?",
|
||||
"unmatched": "Viimane tsükkel ei vastanud ühelegi salvestatud programmile. Kas see on uus programm?"
|
||||
},
|
||||
"phase3": {
|
||||
"suggestions": "WashDatal on teie tsüklite ajaloo põhjal seadete soovitusi – vaadake need läbi tuvastustäpsuse parandamiseks.",
|
||||
"groups": "Mõned teie profiilid näevad välja nagu sama programm erinevatel temperatuuridel. Korraldage need rühma parema sobitamise jaoks.",
|
||||
"phases": "Lisage programmifaasid profiilile {profile_name} täpsemate järelejäänud aja hinnangute saamiseks."
|
||||
},
|
||||
"phase4": {
|
||||
"healthy": "See seade on täielikult seadistatud ({profile_count} profiili)."
|
||||
},
|
||||
"cta": {
|
||||
"start_recording": "Alusta salvestamist",
|
||||
"label_detected_cycle": "Mul on juba tuvastatud tsükkel – märgista see",
|
||||
"browse_cycles": "Sirvi tsükleid, et märgistada teine",
|
||||
"view_profiles": "Vaata oma profiile",
|
||||
"create_from_cluster": "Loo profiil nendest tsüklitest",
|
||||
"create_profile": "Loo sellele profiil",
|
||||
"review_suggestions": "Vaata soovitusi läbi",
|
||||
"organise_profiles": "Korralda profiile",
|
||||
"configure_phases": "Seadista faasid",
|
||||
"skip_step": "Jäta see samm vahele",
|
||||
"skip_forever": "Ära näita enam",
|
||||
"hide_guidance": "Peida juhised",
|
||||
"show_guidance": "Näita juhiseid"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
"on_cycle_finished": "Kierros päättyi",
|
||||
"on_cycle_started": "Kierros alkoi",
|
||||
"pause_cycle": "Tauko",
|
||||
"pause_cycle_tip": "Keskeytä käynnissä oleva sykli — laite jatkaa siitä, mihin se jäi",
|
||||
"pause_cycle_tip": "Keskeytä käynnissä oleva sykli – laite jatkaa siitä, mihin se jäi",
|
||||
"pg_apply_device": "Käytä laitteeseen",
|
||||
"pg_autofill": "Autotäyttö",
|
||||
"play": "Toista",
|
||||
@@ -97,8 +97,8 @@
|
||||
"process_tip": "Tallenna tallennettu jälki uutena tai olemassa olevana profiilina",
|
||||
"rebuild": "Rakenna kirjekuoret uudelleen",
|
||||
"rebuild_envelope": "Rakenna kirjekuori uudelleen",
|
||||
"rebuild_tip": "Laske uudelleen kaikkien profiilien odotettu tehokuori (min/maks-alue) merkityistä sykleistä — suorita uusien syklien merkitsemisen tai vanhojen korjaamisen jälkeen",
|
||||
"rec_start_tip": "Aloita laitteen tehojäljen tallentaminen — käynnistä juuri ennen syklin suorittamista",
|
||||
"rebuild_tip": "Laske uudelleen kaikkien profiilien odotettu tehokuori (min/maks-alue) merkityistä sykleistä – suorita uusien syklien merkitsemisen tai vanhojen korjaamisen jälkeen",
|
||||
"rec_start_tip": "Aloita laitteen tehojäljen tallentaminen – käynnistä juuri ennen syklin suorittamista",
|
||||
"rec_stop": "Pysäytä",
|
||||
"rec_stop_tip": "Lopeta tallennus ja pidä tallennettu jälki tarkistettavana",
|
||||
"record": "Aloita tallennus",
|
||||
@@ -231,7 +231,7 @@
|
||||
"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": "{n} asetusten ristiriita{s} – tarkista korostetut osiot ja korjaa ne ennen tallentamista.",
|
||||
"settings_banner_btn": "Siirry ensimmäiseen"
|
||||
},
|
||||
"hdr": {
|
||||
@@ -451,9 +451,9 @@
|
||||
"show_expected": "Näytä odotettu käyrän peittokuva (vastaava profiili, oranssi)",
|
||||
"show_raw": "Näytä raakadatan pistorasiakytkin reaaliaikaisessa tehograafissa",
|
||||
"sparkline": "Viimeaikainen syklin keston suuntaus",
|
||||
"stage2": "Vaihe 2 — ydinsamankaltaisuus",
|
||||
"stage3": "Vaihe 3 — DTW",
|
||||
"stage4": "Vaihe 4 — vastaavuus",
|
||||
"stage2": "Vaihe 2 – ydinsamankaltaisuus",
|
||||
"stage3": "Vaihe 3 – DTW",
|
||||
"stage4": "Vaihe 4 – vastaavuus",
|
||||
"status": "Tila",
|
||||
"tail_trim": "Hännän leikkaus (s)",
|
||||
"timer_auto_pause": "Automaattinen tauko",
|
||||
@@ -561,7 +561,12 @@
|
||||
"flags": "Liput",
|
||||
"include_phase_map": "Sisällytä vaihdekartta",
|
||||
"include_settings": "Sisällytä tunnistus- ja täsmäytysasetukset",
|
||||
"show_contributor": "Näytä osallistujien nimet"
|
||||
"show_contributor": "Näytä osallistujien nimet",
|
||||
"task_pg_detail": "Simuloidaan sykliä",
|
||||
"task_split": "Jaetaan sykliä",
|
||||
"task_trim": "Rajataan sykliä",
|
||||
"task_merge": "Yhdistetään syklejä",
|
||||
"task_rebuild": "Rakennetaan tehoalueita uudelleen"
|
||||
},
|
||||
"log": {
|
||||
"all_levels": "Kaikki tasot",
|
||||
@@ -645,7 +650,7 @@
|
||||
"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.",
|
||||
"artifact_header": "{n} poikkeavaa havaittu tämän jakson aikana",
|
||||
"artifact_pause_detail": "Teho laski lähes nollaan noin {n} sekunniksi ja jatkui sitten — todennäköisesti ovi avattiin syklin aikana tai sykli pysäytettiin.",
|
||||
"artifact_pause_detail": "Teho laski lähes nollaan noin {n} sekunniksi ja jatkui sitten – todennäköisesti ovi avattiin syklin aikana tai sykli pysäytettiin.",
|
||||
"artifact_spike_detail": "Ylitti tavallisen tehon ylärajan noin {n} sekunnin ajan.",
|
||||
"auto_label_intro": "Määritä profiilit nimeämättömille sykleille, joiden osuvuusvarmuus tyhjentää kynnyksen.",
|
||||
"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.",
|
||||
@@ -654,10 +659,10 @@
|
||||
"collecting_data": "Kerätään tietoja - vielä {need} sykliä tarvitaan ennen hienosäädön käynnistymistä ({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",
|
||||
"compare_selected_cycles": "Valitut jaksot (kiinteä) – näytä/piilota",
|
||||
"consider_new_profile": "Harkitse uuden profiilin luomista.",
|
||||
"coverage_gap": "viimeaikaisilla jaksoilla ei ole vastaavaa profiilia ({pct} % viimeisestä 30:stä).",
|
||||
"coverage_gap_similar_cycles": "{count} samanlaista merkitsemätöntä sykliä löydetty — luo profiili, jotta voit aloittaa niiden täsmäämisen.",
|
||||
"coverage_gap_similar_cycles": "{count} samanlaista merkitsemätöntä sykliä löydetty – luo profiili, jotta voit aloittaa niiden täsmäämisen.",
|
||||
"cycles_deleted": "{count} sykli(ä) poistettu",
|
||||
"enough_data": "Tarpeeksi tietoja oppimiseen ({current}/{min} sykliä).",
|
||||
"export_description": "Vie kaikki profiilit ja syklit JSONiin tai palauta edellisestä viennistä.",
|
||||
@@ -686,7 +691,7 @@
|
||||
"ml_learned_intro": "Mallit hienosäädetty tälle koneelle.",
|
||||
"ml_loading": "ladataan ML…",
|
||||
"ml_settings_intro": "Kaksi erillistä kytkintä: toinen käyttää malleja syklin aikana, toinen antaa WashDatan hienosäätää ne koneellesi ajan myötä.",
|
||||
"name_first_program": "Sinulla on tarpeeksi syklejä — nimeä ensimmäinen ohjelma aloittaaksesi täsmäyksen.",
|
||||
"name_first_program": "Sinulla on tarpeeksi syklejä – nimeä ensimmäinen ohjelma aloittaaksesi täsmäyksen.",
|
||||
"near_duplicate_cluster": "lähes kaksoiskappale profiiliklusteri havaittu. Ryhmittely mahdollistaa täsmäämisen luotettavasti valitsemaan samankaltaisten ohjelmien välillä (esim. sama ohjelma eri lämpötilassa/linkouksessa).",
|
||||
"no_cycles_match": "Yksikään jakso ei vastaa nykyistä suodatinta.",
|
||||
"no_cycles_profile": "Ei jaksoja tälle profiilille.",
|
||||
@@ -713,7 +718,7 @@
|
||||
"notify_services_hint": "Käytä {entity}-palvelun tunnuksia (pilkulla eroteltuna usealle). Mallimuuttujat: {vars}.",
|
||||
"old_actions_warning": "Määritetty vanhalla toimintoeditorilla (nyt poistettu). Ne käynnistyvät edelleen syklitapahtumissa, mutta niitä ei voi enää muokata täällä. Muunna ne normaaliksi automaatioksi tai poista ne.",
|
||||
"onboarding_progress": "{n} / 3 sykliä havaittu",
|
||||
"onboarding_watching": "Käytä laitettasi normaalisti — WashData tarkkailee. Kolmen syklin jälkeen ohjelmien täsmäys alkaa.",
|
||||
"onboarding_watching": "Käytä laitettasi normaalisti – WashData tarkkailee. Kolmen syklin jälkeen ohjelmien täsmäys alkaa.",
|
||||
"pending_feedback": "Odottaa tunnistuspalautetta",
|
||||
"performance_trend": "Tehotrendi ({n} jaksoa)",
|
||||
"pg_analysis_empty": "Lataa sykli nähdäksesi osuma-analyysin.",
|
||||
@@ -763,7 +768,7 @@
|
||||
"setting_changed": "Muutettu {old} → {new} {date}",
|
||||
"settings_basic_note": "Näytetään olennaiset asetukset. Vaihda Edistynyt-tilaan nähdäksesi koko luettelon.",
|
||||
"shape_drift_advisory": "⚠ Muoto ajautuu",
|
||||
"shape_drift_detail": "Tämän profiilin tehomuoto on muuttunut ajan myötä — mahdollinen laitteen kuluminen tai huolto tarvitaan (esim. kalkinpoisto, suodattimen puhdistus).",
|
||||
"shape_drift_detail": "Tämän profiilin tehomuoto on muuttunut ajan myötä – mahdollinen laitteen kuluminen tai huolto tarvitaan (esim. kalkinpoisto, suodattimen puhdistus).",
|
||||
"show_all_settings": "Näytä kaikki asetukset",
|
||||
"showing_suggestions": "Näytetään asetus {count} ja ehdotuksia.",
|
||||
"split_intro": "Napsauta kaaviota lisätäksesi tai poistaaksesi jakopisteen tai tunnistaa automaattisesti tyhjäkäynnin väliltä. Jokainen tuloksena oleva segmentti voi saada oman profiilinsa.",
|
||||
@@ -857,7 +862,9 @@
|
||||
"share_guidelines_title": "Ennen jakamista",
|
||||
"store_download_device_intro": "Ota käyttöön jokainen jaettu ohjelma ja sen viitesyklit laitteellesi. Omat tallennetut syklisi ja tilastosi eivät vaikutu.",
|
||||
"store_share_device_intro": "Lataa {brand} {model} valitsemiesi viitesyklien kanssa. Muut saman laitteen omistajat voivat ottaa ohjelmiasi käyttöön. Merkinnät tarkistetaan ennen julkaisua.",
|
||||
"share_profile_no_cycles": "Ei viitesyklejä -- merkitse sykli ⭐:ksi Syklit-välilehdessä sisällyttääksesi tämän profiilin"
|
||||
"share_profile_no_cycles": "Ei viitesyklejä -- merkitse sykli ⭐:ksi Syklit-välilehdessä sisällyttääksesi tämän profiilin",
|
||||
"advisory_phase_inconsistent": "'{name}' vaikuttaa sekoittavan eri ohjelmia tai lämpötiloja - sen syklit lämmittävät hyvin eripituisia aikoja. Sen jakaminen erillisiin profiileihin (esim. lämpötilan mukaan) parantaa täsmäytystä ja aika-arvioita.",
|
||||
"advisory_phase_inconsistent_title": "⚠ Mahdollisesti sekoittuneet ohjelmat"
|
||||
},
|
||||
"pg_desc": {
|
||||
"abrupt_drop_watts": "Äkillinen pudotus tulkitaan välittömäksi lopuksi",
|
||||
@@ -869,12 +876,19 @@
|
||||
"start_duration_threshold": "Sekunteja kynnyksen yläpuolella käynnistyksen vahvistamiseksi",
|
||||
"start_threshold_w": "Vähimmäiswatit, jotta lasketaan käynnistyneeksi",
|
||||
"stop_threshold_w": "Tämän alapuolella laite lasketaan pois päältä olevaksi",
|
||||
"dtw_bandwidth": "Kuinka paljon ajan venytystä muodon täsmäytys sallii",
|
||||
"corr_weight": "Käyrän muodon ja tehotason painotus täsmäytyksessä",
|
||||
"duration_weight": "Kuinka paljon keston yhteensopivuus vaikuttaa täsmäytykseen",
|
||||
"energy_weight": "Kuinka paljon energian yhteensopivuus vaikuttaa täsmäytykseen",
|
||||
"profile_match_min_duration_ratio": "Lyhin sykli (profiiliin verrattuna), joka voi vielä täsmätä",
|
||||
"profile_match_max_duration_ratio": "Pisin sykli (profiiliin verrattuna), joka voi vielä täsmätä"
|
||||
"dtw_bandwidth": "Vaihe 3: Sakoe-Chiba-ajankäyristyskaista (0 = DTW pois; oletus 0,2 = 20% syklinpituudesta)",
|
||||
"corr_weight": "Vaihe 2: tasapaino käyrän muodon (korrelaatio) ja tehotason (MAE) välillä; oletus 0,45",
|
||||
"duration_weight": "Vaihe 4: kuinka vahvasti keston yhdenmukaisuus vaikuttaa lopullisiin pisteisiin (oletus 0,22)",
|
||||
"energy_weight": "Vaihe 4: kuinka vahvasti energian yhdenmukaisuus vaikuttaa lopullisiin pisteisiin (oletus 0,22)",
|
||||
"profile_match_min_duration_ratio": "Vaihe 1: lyhin sykli profiilinkeston murto-osana; oletus 0,1 (10%)",
|
||||
"profile_match_max_duration_ratio": "Vaihe 1: pisin sykli profiilinkeston murto-osana; oletus 1,5 (150%)",
|
||||
"keep_min_score": "Vaihe 2: alin pisteet pysyäkseen mukana; oletus 0,1 sallii heikot ehdokkaat, myöhemmät vaiheet valitsevat parhaan",
|
||||
"dtw_blend": "Vaihe 3: 0 = vain ydinpisteet, 1 = vain DTW-pisteet, 0,5 = tasainen sekoitus (oletus)",
|
||||
"dtw_ensemble_w": "Vaihe 3 (ensemble-tila): skaloidun L1 paino vs. derivatiivinen DTW; oletus 0,7 suosii tasonhavainnoivaa",
|
||||
"dtw_ddtw_scale": "Vaihe 3: DDTW:n puolikyllästymisetäisyys; pienempi = herkempi muodon eroille (oletus 30)",
|
||||
"dtw_refine_top_n": "Vaihe 3: ehdokkaat joille DTW laskee pisteet uudelleen; nosta 7-9:ään jos oikea profiili sijoittuu 4.-5. (oletus 5)",
|
||||
"duration_scale": "Vaihe 4: log-suhde jossa keston yhdenmukaisuus puolittuu; pienempi = tiukempi rangaistus (oletus 0,175)",
|
||||
"energy_scale": "Vaihe 4: log-suhde jossa energian yhdenmukaisuus puolittuu; pienempi = tiukempi rangaistus (oletus 0,25)"
|
||||
},
|
||||
"phase_desc": {
|
||||
"anti_crease": "Satunnaisia lyhyitä rumpujaksia valmistumisen jälkeen vaatteiden rypistyistä ehkäisemiseksi.",
|
||||
@@ -957,6 +971,10 @@
|
||||
"triggers": {
|
||||
"intro": "Valinnaiset ulkoiset signaalit: päätyssignaali, ovianturi, taukokytkin ja purkamismuistutus.",
|
||||
"label": "Käynnistysimpulssit ja ovet"
|
||||
},
|
||||
"phase_eta": {
|
||||
"label": "Jäljellä oleva aika",
|
||||
"intro": "Vaihetietoinen jäljellä oleva aika koneille, joiden syklin pituus riippuu lämpötilasta tai linkouksesta."
|
||||
}
|
||||
},
|
||||
"setting": {
|
||||
@@ -1040,6 +1058,10 @@
|
||||
"doc": "Kiinteää kWh-hintaa käytetään kustannusluvuissa, kun yllä ei ole asetettu reaaliaikaista hintakokonaisuutta.",
|
||||
"label": "Kiinteä energiahinta (per kWh)"
|
||||
},
|
||||
"energy_sensor": {
|
||||
"doc": "Valinnainen kumulatiivinen energialaskuri (total_increasing kWh/Wh, esim. pistokkeen oma kokonaismittari). Kun tämä on asetettu, kunkin syklin raportoitu energia otetaan tämän laskurin alku- ja loppuarvon erotuksesta, mikä välttää alilaskennan, jonka saat integroimalla hitaasti raportoivaa tehoanturia. Palaa integroituun arvoon, jos lukema puuttuu, sen yksikkö on tuntematon tai erotus ei ole positiivinen. Jätä tyhjäksi jatkaaksesi tehoanturin integrointia.",
|
||||
"label": "Energiamittarin entiteetti"
|
||||
},
|
||||
"expose_debug_entities": {
|
||||
"doc": "Julkaise ylimääräisiä diagnostisia HA-kokonaisuuksia (osumavarmuus, moniselitteisyys, tilan sisäiset tiedot). Pois päältä pitää entiteettiluettelon puhtaana normaalia käyttöä varten.",
|
||||
"label": "Näytä virheenkorjausentiteetit"
|
||||
@@ -1322,6 +1344,38 @@
|
||||
},
|
||||
"show_contributor": {
|
||||
"doc": "Näytä \"tekijä <osallistuja>\" -merkintä yhteisön laitteissa ja viitesykleissä."
|
||||
},
|
||||
"enable_phase_matching": {
|
||||
"label": "Vaihetietoinen jäljellä oleva aika",
|
||||
"doc": "Jaa jokainen käynnissä oleva sykli vaiheisiin (lämmitys, pesu, linkous) ja budjetoi jäljellä oleva aika vaihekohtaisesti, yhdistettynä klassiseen arvioon - nojaten syklin alkuvaiheessa vaihebudjettiin ja lopussa klassiseen arvioon. Tämä mukauttaa laskurin siihen, kuinka kauan koneesi todella lämmittää ja käy, mikä näkyy selvimmin syklin alkupuoliskolla. Pois = vain klassinen arvio. Vaikuttaa vain jäljellä olevan ajan näyttöön; ohjelman täsmäytys ja syklin tunnistus pysyvät ennallaan."
|
||||
},
|
||||
"keep_min_score": {
|
||||
"label": "Vähim. vastaavuuspisteet",
|
||||
"doc": "Alin samankaltaisuuspisteet, jotka ehdokas tarvitsee pysyäkseen täsmäytyksessä mukana. Oletus 0,1 on tarkoituksellisesti salliva – se sallii jopa heikot ehdokkaat ja luottaa myöhempiin vaiheisiin parhaan löytämiseksi. Nosta leikkaamaan epätodennäköiset profiilit aikaisemmin; laske laajentamaan alkuperäistä ehdokaspoolia."
|
||||
},
|
||||
"dtw_blend": {
|
||||
"label": "DTW-sekoitus",
|
||||
"doc": "Kuinka paljon DTW-kohdistuspisteet korvaavat Vaiheen 2 ydinpisteet. 0 = käytä vain Vaiheen 2 pisteitä, 1 = käytä vain DTW-pisteitä, 0,5 (oletus) = tasainen sekoitus. Nosta luottamaan enemmän aikakohdistukseen kun ohjelmilla on samanlaiset tehotasot mutta erilaiset ajoitusmustrit."
|
||||
},
|
||||
"dtw_ensemble_w": {
|
||||
"label": "DTW-ensemble-miksaus",
|
||||
"doc": "Ensemble-DTW-tilassa (oletus) tämä on skaloidun L1:n paino verrattuna derivatiiviseen DTW:hen (DDTW). 1,0 = vain skaloitu L1, 0 = vain DDTW, 0,7 = oletus. Skaloitu muunnelma vertaa tehotasoja; derivatiivinen reagoi siihen miten teho muuttuu ajan kuluessa. Ensemble yhdistää molemmat."
|
||||
},
|
||||
"dtw_ddtw_scale": {
|
||||
"label": "Deriv. DTW-skala",
|
||||
"doc": "Derivatiivisen DTW-pisteytyksen puolikyllästymisetäisyys. Pisteet puolittuvat kun DDTW-etäisyys on yhtä suuri kuin tämä arvo. Pienempi = herkempi muodon eroille. Oletus 30 on kalibroitu tyypillisten laitteiden tehokäyrille. Vaikuttaa vain ensemble- ja ddtw-DTW-tiloihin."
|
||||
},
|
||||
"dtw_refine_top_n": {
|
||||
"label": "DTW-tarkistusmäärä",
|
||||
"doc": "Kuinka monelle Vaiheen 2 parhaalle ehdokkaalle DTW laskee pisteet uudelleen. DTW on kalliimpaa joten se sovelletaan vain N parhaaseen. Oletus 5. Nosta (7-9:ään) jos oikea profiili pääsee joskus vain 4. tai 5. sijalle Vaiheen 2 jälkeen – DTW voi pelastaa sen. Pienempi arvo nopeuttaa täsmäytystä hieman."
|
||||
},
|
||||
"duration_scale": {
|
||||
"label": "Keston tarkkuus",
|
||||
"doc": "Vaiheen 4 keston yhdenmukaisuusrangaistuksen tarkkuus. Tämä on log-suhde jossa yhdenmukaisuuspisteet puolittuvat. Pienempi = tiukempi: keston poikkeama haittaa enemmän. Oletus 0,175 vastaa noin 18% kestontoleranssia puolipainolla. Yhdistä Kestopaino-asetukseen."
|
||||
},
|
||||
"energy_scale": {
|
||||
"label": "Energian tarkkuus",
|
||||
"doc": "Vaiheen 4 energian yhdenmukaisuusrangaistuksen tarkkuus. Pienempi = tiukempi: energian poikkeama haittaa enemmän. Oletus 0,25 on tarkoituksellisesti sallivampi kuin kestotarkkuus koska energia vaihtelee kuorman mukaan. Yhdistä Energiapaino-asetukseen."
|
||||
}
|
||||
},
|
||||
"setting_group": {
|
||||
@@ -1766,6 +1820,69 @@
|
||||
},
|
||||
"pg_sweep": {
|
||||
"optimize": "Optimointi: {param}"
|
||||
},
|
||||
"pg_detail": {
|
||||
"simulate": "Simuloidaan sykliä"
|
||||
},
|
||||
"split": {
|
||||
"apply": "Jaetaan sykliä"
|
||||
},
|
||||
"trim": {
|
||||
"apply": "Rajataan sykliä"
|
||||
},
|
||||
"merge": {
|
||||
"apply": "Yhdistetään syklejä"
|
||||
},
|
||||
"rebuild": {
|
||||
"envelopes": "Rakennetaan tehoalueita uudelleen"
|
||||
},
|
||||
"cancelling": "Perutaan..."
|
||||
},
|
||||
"setup": {
|
||||
"hdr": {
|
||||
"card": "Laitteen asetukset",
|
||||
"healthy_chip": "Asetukset valmiit"
|
||||
},
|
||||
"phase0": {
|
||||
"washer": "WashData tunnistaa jo syklisi. Tallenna ensimmäinen sykli ottaaksesi käyttöön ohjelmanimet ja aikaarviot.",
|
||||
"dishwasher": "WashData tarkkailee. Astianpesukoneilla on monimutkaisia syklejä – ensimmäisen syklin tallentaminen on erittäin suositeltavaa. Jos tunnistettu sykli kestää liian kauan, käytä syklin editoria sen leikkaamiseen ennen profiilina tallentamista.",
|
||||
"generic": "WashData tarkkailee. Tallenna tai merkitse tunnistettu sykli aloittaaksesi profiilien luomisen."
|
||||
},
|
||||
"phase1a": {
|
||||
"labelled": "Hyvä alku – ensimmäinen ohjelmasi on tallennettu. Puhtaimman datan saamiseksi harkitse seuraavan syklin tallentamista tallennuswidgetillä."
|
||||
},
|
||||
"phase1b": {
|
||||
"recorded": "Tallennuksesi on tallennettu nimellä {profile_name}. Tallenna tai merkitse nyt muut yleisimmät ohjelmasi kattavuuden rakentamiseksi."
|
||||
},
|
||||
"phase1c": {
|
||||
"verify": "Sinulla on {count} ohjelmaa yhteisöltä. Suorita sykli tarkistaaksesi, tunnistaako WashData sen oikein – täsmäytys paranee laitteen kerätessä omaa historiaansa."
|
||||
},
|
||||
"phase2": {
|
||||
"cluster": "WashData on havainnut {count} sykliä, jotka eivät täsmää mihinkään tallennettuun ohjelmaan – ne näyttävät samanlaisilta keskenään. Haluatko luoda niille uuden profiilin?",
|
||||
"unmatched": "Viimeisin sykli ei täsmännyt mihinkään tallennettuun ohjelmaan. Onko se uusi ohjelma?"
|
||||
},
|
||||
"phase3": {
|
||||
"suggestions": "WashDatalla on asetussuosituksia syklihistoriasi perusteella – tarkista ne tunnistustarkkuuden parantamiseksi.",
|
||||
"groups": "Jotkut profiileistasi näyttävät samalta ohjelmalta eri lämpötiloissa. Järjestä ne ryhmään parempaa täsmäytystä varten.",
|
||||
"phases": "Lisää ohjelman vaiheet profiiliin {profile_name} tarkempien jäljellä olevan ajan arvioiden saamiseksi."
|
||||
},
|
||||
"phase4": {
|
||||
"healthy": "Tämä laite on täysin asennettu ({profile_count} profiilia)."
|
||||
},
|
||||
"cta": {
|
||||
"start_recording": "Aloita tallennus",
|
||||
"label_detected_cycle": "Minulla on jo tunnistettu sykli – merkitse se sen sijaan",
|
||||
"browse_cycles": "Selaa syklejä merkitäksesi toisen",
|
||||
"view_profiles": "Näytä profiilit",
|
||||
"create_from_cluster": "Luo profiili näistä sykleistä",
|
||||
"create_profile": "Luo sille profiili",
|
||||
"review_suggestions": "Tarkista ehdotukset",
|
||||
"organise_profiles": "Järjestä profiilit",
|
||||
"configure_phases": "Määritä vaiheet",
|
||||
"skip_step": "Ohita tämä vaihe",
|
||||
"skip_forever": "Älä näytä enää",
|
||||
"hide_guidance": "Piilota opastus",
|
||||
"show_guidance": "Näytä opastus"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
"on_cycle_finished": "Le cycle terminé",
|
||||
"on_cycle_started": "Le cycle a démarré",
|
||||
"pause_cycle": "Pause",
|
||||
"pause_cycle_tip": "Mettre en pause le cycle en cours — l'appareil reprendra là où il s'est arrêté",
|
||||
"pause_cycle_tip": "Mettre en pause le cycle en cours – l'appareil reprendra là où il s'est arrêté",
|
||||
"pg_apply_device": "Appliquer à l'appareil",
|
||||
"pg_autofill": "Remplissage automatique",
|
||||
"play": "Lire",
|
||||
@@ -97,8 +97,8 @@
|
||||
"process_tip": "Enregistrer la trace capturée en tant que profil nouveau ou existant",
|
||||
"rebuild": "Reconstruire les enveloppes",
|
||||
"rebuild_envelope": "Reconstruire l'enveloppe",
|
||||
"rebuild_tip": "Recalculer l'enveloppe de puissance attendue (bande min/max) pour tous les profils à partir de leurs cycles étiquetés — à exécuter après l'étiquetage de nouveaux cycles ou la correction d'anciens",
|
||||
"rec_start_tip": "Commencer l'enregistrement de la trace de puissance de l'appareil — démarrer juste avant de lancer un cycle",
|
||||
"rebuild_tip": "Recalculer l'enveloppe de puissance attendue (bande min/max) pour tous les profils à partir de leurs cycles étiquetés – à exécuter après l'étiquetage de nouveaux cycles ou la correction d'anciens",
|
||||
"rec_start_tip": "Commencer l'enregistrement de la trace de puissance de l'appareil – démarrer juste avant de lancer un cycle",
|
||||
"rec_stop": "Arrêt",
|
||||
"rec_stop_tip": "Arrêter l'enregistrement et conserver la trace capturée pour révision",
|
||||
"record": "Commencer l'enregistrement",
|
||||
@@ -182,7 +182,7 @@
|
||||
},
|
||||
"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.",
|
||||
"settings_banner": "{n} conflit{s} de paramètres – vérifiez les sections surlignées et corrigez avant d'enregistrer.",
|
||||
"settings_banner_btn": "Aller au premier",
|
||||
"confidence": {
|
||||
"auto": "Doit être supérieur ou égal au Seuil de correspondance ({match})",
|
||||
@@ -451,9 +451,9 @@
|
||||
"show_expected": "Afficher la superposition de courbe attendue (profil correspondant, orange)",
|
||||
"show_raw": "Afficher le commutateur de signal brut de la prise dans le graphique de puissance en direct",
|
||||
"sparkline": "Tendance récente de la durée des cycles",
|
||||
"stage2": "Étape 2 — similarité principale",
|
||||
"stage3": "Étape 3 — DTW",
|
||||
"stage4": "Étape 4 — concordance",
|
||||
"stage2": "Étape 2 – similarité principale",
|
||||
"stage3": "Étape 3 – DTW",
|
||||
"stage4": "Étape 4 – concordance",
|
||||
"status": "Statut",
|
||||
"tail_trim": "Rognage de fin (s)",
|
||||
"timer_auto_pause": "Pause automatique",
|
||||
@@ -561,7 +561,12 @@
|
||||
"flags": "Indicateurs",
|
||||
"include_phase_map": "Inclure la carte des phases",
|
||||
"include_settings": "Inclure les paramètres de détection et de reconnaissance",
|
||||
"show_contributor": "Afficher les noms des contributeurs"
|
||||
"show_contributor": "Afficher les noms des contributeurs",
|
||||
"task_pg_detail": "Simuler le cycle",
|
||||
"task_split": "Division du cycle",
|
||||
"task_trim": "Rognage du cycle",
|
||||
"task_merge": "Fusion des cycles",
|
||||
"task_rebuild": "Reconstruction des enveloppes"
|
||||
},
|
||||
"log": {
|
||||
"all_levels": "Tous niveaux",
|
||||
@@ -645,7 +650,7 @@
|
||||
"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 s’agit d’artefacts transitoires (par exemple la porte ouverte en cours de cycle), pas nécessairement de problèmes.",
|
||||
"artifact_header": "{n} anomalies détectées au cours de ce cycle",
|
||||
"artifact_pause_detail": "La puissance a chuté près de zéro pendant environ {n} s puis a repris — la porte a probablement été ouverte en cours de cycle ou le cycle a été mis en pause.",
|
||||
"artifact_pause_detail": "La puissance a chuté près de zéro pendant environ {n} s puis a repris – la porte a probablement été ouverte en cours de cycle ou le cycle a été mis en pause.",
|
||||
"artifact_spike_detail": "A dépassé la bande de puissance habituelle pendant environ {n} s.",
|
||||
"auto_label_intro": "Attribuez des profils à des cycles non étiquetés dont la confiance de correspondance efface le seuil.",
|
||||
"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.",
|
||||
@@ -654,10 +659,10 @@
|
||||
"collecting_data": "Collecte de données - encore {need} cycle{plural} avant que l'affinage puisse commencer ({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",
|
||||
"compare_selected_cycles": "Cycles sélectionnés (solides) – afficher/masquer",
|
||||
"consider_new_profile": "Pensez à créer un nouveau profil.",
|
||||
"coverage_gap": "les cycles récents n'ont pas de profil correspondant ({pct} % des 30 derniers).",
|
||||
"coverage_gap_similar_cycles": "{count} cycles similaires non étiquetés trouvés — créez un profil pour commencer à les identifier.",
|
||||
"coverage_gap_similar_cycles": "{count} cycles similaires non étiquetés trouvés – créez un profil pour commencer à les identifier.",
|
||||
"cycles_deleted": "{count} cycle(s) supprimé(s)",
|
||||
"enough_data": "Suffisamment de données pour apprendre ({current}/{min} cycles).",
|
||||
"export_description": "Exportez tous les profils et cycles vers JSON, ou restaurez à partir d'une exportation précédente.",
|
||||
@@ -686,7 +691,7 @@
|
||||
"ml_learned_intro": "Modèles adaptés à cette machine.",
|
||||
"ml_loading": "chargement de ML…",
|
||||
"ml_settings_intro": "Deux commutateurs indépendants : l'un applique les modèles pendant l'exécution d'un cycle, l'autre permet à WashData de les ajuster avec précision à votre machine au fil du temps.",
|
||||
"name_first_program": "Vous avez assez de cycles — nommez votre premier programme pour lancer la correspondance.",
|
||||
"name_first_program": "Vous avez assez de cycles – nommez votre premier programme pour lancer la correspondance.",
|
||||
"near_duplicate_cluster": "Cluster de profils quasi-dupliqué détecté. Le regroupement permet de choisir de manière fiable entre des sosies (par exemple, le même programme à différentes températures/essorages).",
|
||||
"no_cycles_match": "Aucun cycle ne correspond au filtre actuel.",
|
||||
"no_cycles_profile": "Aucun cycle pour ce profil.",
|
||||
@@ -713,7 +718,7 @@
|
||||
"notify_services_hint": "Utilisez les IDs de service {entity} (séparés par des virgules pour plusieurs). Variables de gabarit : {vars}.",
|
||||
"old_actions_warning": "Configuré avec l'ancien éditeur d'actions (maintenant supprimé). Ils se déclenchent toujours sur les événements du cycle mais ne peuvent plus être modifiés ici. Convertissez-les en une automatisation normale ou supprimez-les.",
|
||||
"onboarding_progress": "{n} / 3 cycles observés",
|
||||
"onboarding_watching": "Utilisez votre appareil normalement — WashData observe. Après 3 cycles, la correspondance des programmes commencera.",
|
||||
"onboarding_watching": "Utilisez votre appareil normalement – WashData observe. Après 3 cycles, la correspondance des programmes commencera.",
|
||||
"pending_feedback": "En attente de retour de détection",
|
||||
"performance_trend": "Tendance des performances ({n} cycles)",
|
||||
"pg_analysis_empty": "Chargez un cycle pour voir l'analyse de correspondance.",
|
||||
@@ -763,7 +768,7 @@
|
||||
"setting_changed": "Modifié de {old} à {new} le {date}",
|
||||
"settings_basic_note": "Affichage des paramètres essentiels. Passez à Avancé pour la liste complète.",
|
||||
"shape_drift_advisory": "⚠ Dérive de forme",
|
||||
"shape_drift_detail": "Le profil de puissance a évolué au fil du temps — usure possible de l'appareil ou entretien nécessaire (p. ex. détartrage, nettoyage du filtre).",
|
||||
"shape_drift_detail": "Le profil de puissance a évolué au fil du temps – usure possible de l'appareil ou entretien nécessaire (p. ex. détartrage, nettoyage du filtre).",
|
||||
"show_all_settings": "Afficher tous les paramètres",
|
||||
"showing_suggestions": "Affichage du paramètre {count} avec des suggestions.",
|
||||
"split_intro": "Cliquez sur le graphique pour ajouter ou supprimer un point de partage, ou détecter automatiquement les espaces inactifs. Chaque segment résultant peut avoir son propre profil.",
|
||||
@@ -857,7 +862,9 @@
|
||||
"share_guidelines_title": "Avant de partager",
|
||||
"store_download_device_intro": "Adoptez chaque programme partagé et ses cycles de référence sur votre appareil. Vos propres cycles enregistrés et statistiques ne sont pas affectés.",
|
||||
"store_share_device_intro": "Envoyez {brand} {model} avec les cycles de référence que vous sélectionnez. D'autres utilisateurs du même appareil peuvent adopter vos programmes. Les entrées sont examinées avant d'apparaître publiquement.",
|
||||
"share_profile_no_cycles": "Aucun cycle de référence -- marquez un cycle comme ⭐ dans l'onglet Cycles pour inclure ce profil"
|
||||
"share_profile_no_cycles": "Aucun cycle de référence -- marquez un cycle comme ⭐ dans l'onglet Cycles pour inclure ce profil",
|
||||
"advisory_phase_inconsistent": "'{name}' semble mélanger différents programmes ou températures - ses cycles chauffent pendant des durées très variables. Le diviser en profils distincts (p. ex. par température) améliorera la reconnaissance et les estimations de temps.",
|
||||
"advisory_phase_inconsistent_title": "⚠ Programmes peut-être mélangés"
|
||||
},
|
||||
"pg_desc": {
|
||||
"abrupt_drop_watts": "Chute soudaine traitée comme une fin immédiate",
|
||||
@@ -869,12 +876,19 @@
|
||||
"start_duration_threshold": "Secondes au-dessus du seuil pour confirmer le démarrage",
|
||||
"start_threshold_w": "Watts minimum pour être compté comme démarré",
|
||||
"stop_threshold_w": "En dessous, la machine est comptée comme éteinte",
|
||||
"dtw_bandwidth": "Quantité de déformation temporelle autorisée par la correspondance de forme",
|
||||
"corr_weight": "Poids de la forme de la courbe par rapport au niveau de puissance dans la correspondance",
|
||||
"duration_weight": "Influence de la concordance de durée sur la correspondance",
|
||||
"energy_weight": "Influence de la concordance d'énergie sur la correspondance",
|
||||
"profile_match_min_duration_ratio": "Cycle le plus court (par rapport au profil) encore autorisé à correspondre",
|
||||
"profile_match_max_duration_ratio": "Cycle le plus long (par rapport au profil) encore autorisé à correspondre"
|
||||
"dtw_bandwidth": "Étape 3 : bande de déformation Sakoe-Chiba (0 = DTW désactivé ; défaut 0,2 = 20 % de la longueur du cycle)",
|
||||
"corr_weight": "Étape 2 : équilibre entre la forme de la courbe (corrélation) et le niveau de puissance (MAE) ; défaut 0,45",
|
||||
"duration_weight": "Étape 4 : force avec laquelle la concordance de durée affecte le score final (défaut 0,22)",
|
||||
"energy_weight": "Étape 4 : force avec laquelle la concordance d'énergie affecte le score final (défaut 0,22)",
|
||||
"profile_match_min_duration_ratio": "Étape 1 : durée de cycle minimale en fraction de la durée du profil ; défaut 0,1 (10 %)",
|
||||
"profile_match_max_duration_ratio": "Étape 1 : durée de cycle maximale en fraction de la durée du profil ; défaut 1,5 (150 %)",
|
||||
"keep_min_score": "Étape 2 : score plancher pour rester en lice ; le défaut 0,1 admet les candidats faibles, les étapes suivantes sélectionnent le meilleur",
|
||||
"dtw_blend": "Étape 3 : 0 = score central uniquement, 1 = score DTW uniquement, 0,5 = mélange égal (défaut)",
|
||||
"dtw_ensemble_w": "Étape 3 (mode ensemble) : poids sur L1 normalisé vs DTW dérivé ; le défaut 0,7 favorise la sensibilité au niveau",
|
||||
"dtw_ddtw_scale": "Étape 3 : distance de demi-saturation DDTW ; plus petit = plus sensible à la forme (défaut 30)",
|
||||
"dtw_refine_top_n": "Étape 3 : candidats réévalués par DTW ; augmentez à 7-9 si le profil correct se classe 4e ou 5e (défaut 5)",
|
||||
"duration_scale": "Étape 4 : log-ratio où la concordance de durée est divisée par deux ; plus petit = pénalité plus stricte (défaut 0,175)",
|
||||
"energy_scale": "Étape 4 : log-ratio où la concordance d'énergie est divisée par deux ; plus petit = pénalité plus stricte (défaut 0,25)"
|
||||
},
|
||||
"phase_desc": {
|
||||
"anti_crease": "Courts culbutages occasionnels après completion pour réduire le froissement du linge.",
|
||||
@@ -957,6 +971,10 @@
|
||||
"triggers": {
|
||||
"intro": "Signaux externes optionnels : déclencheur de fin, capteur de porte, interrupteur de pause et rappel de déchargement.",
|
||||
"label": "Déclencheurs et portes"
|
||||
},
|
||||
"phase_eta": {
|
||||
"label": "Temps restant",
|
||||
"intro": "Temps restant tenant compte des phases, pour les machines dont la durée de cycle dépend de la température ou de l'essorage."
|
||||
}
|
||||
},
|
||||
"setting": {
|
||||
@@ -1040,6 +1058,10 @@
|
||||
"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": {
|
||||
"doc": "Compteur d'énergie cumulé facultatif (total_increasing en kWh/Wh, par ex. le compteur de consommation totale de la prise elle-même). Lorsqu'il est défini, l'énergie indiquée pour chaque cycle provient de la différence de ce compteur entre le début et la fin, ce qui évite le sous-comptage provoqué par l'intégration d'un capteur de puissance qui se met à jour lentement. Revient à la valeur intégrée si la lecture est absente, si son unité est inconnue ou si le delta n'est pas positif. Laissez vide pour continuer à intégrer le capteur de puissance.",
|
||||
"label": "Entité du compteur d'énergie"
|
||||
},
|
||||
"expose_debug_entities": {
|
||||
"doc": "Publiez des entités HA de diagnostic supplémentaires (correspondance à la confiance, à l'ambiguïté, aux éléments internes de l'état). Désactivé maintient la liste des entités propre pour une utilisation normale.",
|
||||
"label": "Exposer les entités de débogage"
|
||||
@@ -1323,6 +1345,38 @@
|
||||
"show_contributor": {
|
||||
"label": "Afficher les noms des contributeurs",
|
||||
"doc": "Afficher l'attribution « par <contributeur> » sur les appareils de la communauté et les cycles de référence."
|
||||
},
|
||||
"enable_phase_matching": {
|
||||
"label": "Temps restant tenant compte des phases",
|
||||
"doc": "Découpe chaque cycle en cours en phases (chauffage, lavage, essorage) et répartit le temps restant par phase, mélangé à l'estimation classique - en s'appuyant sur la répartition par phases en début de cycle et sur l'estimation classique vers la fin. Cela personnalise le compte à rebours en fonction de la durée réelle de chauffage et de fonctionnement de votre machine, ce qui est le plus perceptible dans la première moitié du cycle. Désactivé = uniquement l'estimation classique. Seul l'affichage du temps restant est concerné ; la reconnaissance des programmes et la détection des cycles restent inchangées."
|
||||
},
|
||||
"keep_min_score": {
|
||||
"label": "Score min de correspondance",
|
||||
"doc": "Score de similarité minimum qu'un candidat doit atteindre pour rester dans la course. Le défaut 0,1 est délibérément permissif - il admet même les candidats faibles et s'appuie sur les étapes suivantes pour trouver la meilleure correspondance. Augmentez-le pour éliminer les profils improbables plus tôt ; réduisez-le pour élargir le pool de candidats initial."
|
||||
},
|
||||
"dtw_blend": {
|
||||
"label": "Fusion Warp",
|
||||
"doc": "Dans quelle mesure le score d'alignement par déformation temporelle (DTW) remplace le score central de l'étape 2. 0 = utiliser uniquement le score de l'étape 2, 1 = utiliser uniquement le score DTW, 0,5 (défaut) = mélange égal. Augmentez-le pour vous fier davantage à l'alignement Warp lorsque les programmes ont des niveaux de puissance similaires mais des schémas temporels différents."
|
||||
},
|
||||
"dtw_ensemble_w": {
|
||||
"label": "Mix Warp ensemble",
|
||||
"doc": "En mode DTW ensemble (le défaut), le poids sur L1 normalisé par rapport au DTW dérivé (DDTW). 1,0 = tout L1 normalisé, 0 = tout DDTW, 0,7 = défaut. La variante L1 normalisée compare les niveaux de puissance ; la variante dérivée réagit à la façon dont la puissance évolue dans le temps. Ensemble mélange les deux."
|
||||
},
|
||||
"dtw_ddtw_scale": {
|
||||
"label": "Échelle Warp dérivé",
|
||||
"doc": "Distance de demi-saturation pour la notation DTW dérivé. Le score est divisé par deux quand la distance DDTW atteint cette valeur. Plus petit = plus sensible aux différences de forme. Le défaut 30 est calibré sur les traces de puissance typiques des appareils. N'affecte que les modes DTW ensemble et ddtw."
|
||||
},
|
||||
"dtw_refine_top_n": {
|
||||
"label": "Nb candidats affinés Warp",
|
||||
"doc": "Nombre de candidats de l'étape 2 réévalués par DTW. DTW est plus coûteux, il n'est donc appliqué qu'aux N meilleurs candidats. Défaut 5. Augmentez-le (à 7-9) si le profil correct n'atteint parfois que la 4e ou 5e place après l'étape 2 - DTW peut le sauver. Baisser accélère légèrement la mise en correspondance."
|
||||
},
|
||||
"duration_scale": {
|
||||
"label": "Précision durée",
|
||||
"doc": "Précision de la pénalité de concordance de durée à l'étape 4. C'est le log-ratio auquel le score de concordance est divisé par deux. Plus petit = plus strict : un écart de durée pénalise davantage. Le défaut 0,175 correspond à environ 18 % de tolérance de durée à mi-poids. À combiner avec la Pondération de durée."
|
||||
},
|
||||
"energy_scale": {
|
||||
"label": "Précision énergie",
|
||||
"doc": "Précision de la pénalité de concordance d'énergie. Plus petit = plus strict : un écart d'énergie pénalise davantage. Le défaut 0,25 est intentionnellement plus indulgent que la Précision de durée, car l'énergie varie avec la charge. À combiner avec la Pondération d'énergie."
|
||||
}
|
||||
},
|
||||
"setting_group": {
|
||||
@@ -1571,24 +1625,24 @@
|
||||
"lower": "Étiquette plus de cycles automatiquement ; certains peuvent être mal identifiés"
|
||||
},
|
||||
"duration_tolerance": {
|
||||
"higher": "Accepte une plage de durée plus large — correspondance plus flexible",
|
||||
"lower": "Exige une durée plus proche — plus strict, peut rejeter des cycles inhabituels"
|
||||
"higher": "Accepte une plage de durée plus large – correspondance plus flexible",
|
||||
"lower": "Exige une durée plus proche – plus strict, peut rejeter des cycles inhabituels"
|
||||
},
|
||||
"end_energy_threshold": {
|
||||
"higher": "Clôture uniquement les cycles ayant consommé une énergie significative",
|
||||
"lower": "Clôture aussi les cycles courts ou à faible consommation"
|
||||
},
|
||||
"end_repeat_count": {
|
||||
"higher": "Exige que le signal de fin se répète davantage — plus robuste, légèrement plus lent",
|
||||
"lower": "Termine après moins de répétitions — détection plus rapide, risque de fausse fin accru"
|
||||
"higher": "Exige que le signal de fin se répète davantage – plus robuste, légèrement plus lent",
|
||||
"lower": "Termine après moins de répétitions – détection plus rapide, risque de fausse fin accru"
|
||||
},
|
||||
"learning_confidence": {
|
||||
"higher": "N'apprend que des correspondances très confiantes — plus lent mais plus fiable",
|
||||
"higher": "N'apprend que des correspondances très confiantes – plus lent mais plus fiable",
|
||||
"lower": "Apprend à partir de plus de cycles ; le modèle peut être moins précis"
|
||||
},
|
||||
"min_off_gap": {
|
||||
"higher": "Repos plus long requis avant le démarrage d'un nouveau cycle",
|
||||
"lower": "Un bref repos déclenche un nouveau cycle — des cycles successifs peuvent être scindés"
|
||||
"lower": "Un bref repos déclenche un nouveau cycle – des cycles successifs peuvent être scindés"
|
||||
},
|
||||
"min_power": {
|
||||
"higher": "Moins sensible à la consommation au repos ; peut manquer des programmes très silencieux",
|
||||
@@ -1599,24 +1653,24 @@
|
||||
"lower": "Arrête un cycle bloqué plus tôt"
|
||||
},
|
||||
"off_delay": {
|
||||
"higher": "Plus de temps pour les pauses de l'appareil — gère les longues phases de trempage ou de séchage",
|
||||
"lower": "Détection de fin plus rapide — adapté aux appareils marche/arrêt nets"
|
||||
"higher": "Plus de temps pour les pauses de l'appareil – gère les longues phases de trempage ou de séchage",
|
||||
"lower": "Détection de fin plus rapide – adapté aux appareils marche/arrêt nets"
|
||||
},
|
||||
"profile_match_threshold": {
|
||||
"higher": "Ne valide que les correspondances très confiantes ; plus de cycles restent non étiquetés",
|
||||
"lower": "Fait correspondre plus de cycles ; certains peuvent être légèrement erronés"
|
||||
},
|
||||
"running_dead_zone": {
|
||||
"higher": "Ignore les brèves pointes de puissance au repos — moins sensible au bruit",
|
||||
"lower": "Réagit à des impulsions plus courtes — capte les activités transitoires rapides"
|
||||
"higher": "Ignore les brèves pointes de puissance au repos – moins sensible au bruit",
|
||||
"lower": "Réagit à des impulsions plus courtes – capte les activités transitoires rapides"
|
||||
},
|
||||
"start_threshold_w": {
|
||||
"higher": "Évite les faux démarrages dus à de brèves pointes de puissance",
|
||||
"lower": "Capte les programmes à faible puissance ; peut se déclencher sur du bruit"
|
||||
},
|
||||
"stop_threshold_w": {
|
||||
"higher": "Termine le cycle plus vite — peut se clôturer lors d'une pause",
|
||||
"lower": "Attend plus longtemps pour terminer — moins de fins prématurées"
|
||||
"higher": "Termine le cycle plus vite – peut se clôturer lors d'une pause",
|
||||
"lower": "Attend plus longtemps pour terminer – moins de fins prématurées"
|
||||
},
|
||||
"watchdog_interval": {
|
||||
"higher": "Phases silencieuses plus longues autorisées ; moins de faux arrêts forcés",
|
||||
@@ -1767,6 +1821,69 @@
|
||||
},
|
||||
"pg_sweep": {
|
||||
"optimize": "Optimiser : {param}"
|
||||
},
|
||||
"pg_detail": {
|
||||
"simulate": "Simuler le cycle"
|
||||
},
|
||||
"split": {
|
||||
"apply": "Division du cycle"
|
||||
},
|
||||
"trim": {
|
||||
"apply": "Rognage du cycle"
|
||||
},
|
||||
"merge": {
|
||||
"apply": "Fusion des cycles"
|
||||
},
|
||||
"rebuild": {
|
||||
"envelopes": "Reconstruction des enveloppes"
|
||||
},
|
||||
"cancelling": "Annulation..."
|
||||
},
|
||||
"setup": {
|
||||
"hdr": {
|
||||
"card": "Configuration de l'appareil",
|
||||
"healthy_chip": "Configuration terminée"
|
||||
},
|
||||
"phase0": {
|
||||
"washer": "WashData détecte déjà vos cycles. Enregistrez votre premier cycle pour activer les noms de programmes et les estimations de durée.",
|
||||
"dishwasher": "WashData surveille. Les lave-vaisselle ont des cycles complexes – l'enregistrement du premier cycle est fortement recommandé. Si un cycle détecté dure trop longtemps, utilisez l'éditeur de cycles pour le rogner avant de l'enregistrer comme profil.",
|
||||
"generic": "WashData surveille. Enregistrez ou étiquetez un cycle détecté pour commencer à créer des profils."
|
||||
},
|
||||
"phase1a": {
|
||||
"labelled": "Bon début – votre premier programme est enregistré. Pour des données optimales, envisagez d'enregistrer votre prochain cycle avec le widget d'enregistrement."
|
||||
},
|
||||
"phase1b": {
|
||||
"recorded": "Votre enregistrement a été sauvegardé sous {profile_name}. Enregistrez ou étiquetez maintenant vos autres programmes courants pour améliorer la couverture."
|
||||
},
|
||||
"phase1c": {
|
||||
"verify": "Vous avez {count} programmes de la communauté. Lancez un cycle pour vérifier que WashData le reconnaît correctement – la correspondance s'améliorera au fil de l'historique de votre appareil."
|
||||
},
|
||||
"phase2": {
|
||||
"cluster": "WashData a observé {count} cycles qui ne correspondent à aucun programme enregistré – ils se ressemblent entre eux. Voulez-vous créer un nouveau profil pour eux ?",
|
||||
"unmatched": "Votre dernier cycle ne correspond à aucun programme enregistré. S'agit-il d'un nouveau programme ?"
|
||||
},
|
||||
"phase3": {
|
||||
"suggestions": "WashData a des recommandations de paramètres basées sur votre historique de cycles – examinez-les pour améliorer la précision de détection.",
|
||||
"groups": "Certains de vos profils ressemblent au même programme à différentes températures. Organisez-les en groupe pour une meilleure correspondance.",
|
||||
"phases": "Ajoutez des phases de programme à {profile_name} pour des estimations de temps restant plus précises."
|
||||
},
|
||||
"phase4": {
|
||||
"healthy": "Cet appareil est entièrement configuré ({profile_count} profils)."
|
||||
},
|
||||
"cta": {
|
||||
"start_recording": "Démarrer l'enregistrement",
|
||||
"label_detected_cycle": "J'ai déjà un cycle détecté – l'étiqueter à la place",
|
||||
"browse_cycles": "Parcourir les cycles pour en étiqueter un autre",
|
||||
"view_profiles": "Voir vos profils",
|
||||
"create_from_cluster": "Créer un profil à partir de ces cycles",
|
||||
"create_profile": "Créer un profil pour ce programme",
|
||||
"review_suggestions": "Examiner les suggestions",
|
||||
"organise_profiles": "Organiser les profils",
|
||||
"configure_phases": "Configurer les phases",
|
||||
"skip_step": "Ignorer cette étape",
|
||||
"skip_forever": "Ne plus afficher",
|
||||
"hide_guidance": "Masquer le guide",
|
||||
"show_guidance": "Afficher le guide"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
{
|
||||
"badge": {
|
||||
"artifact_tip": "Otkrivene su {n} anomalije (npr. vrata otvorena usred ciklusa) — otvorite da ih vidite na grafikonu",
|
||||
"artifact_tip": "Otkrivene su {n} anomalije (npr. vrata otvorena usred ciklusa) – otvorite da ih vidite na grafikonu",
|
||||
"auto": "(automatski otkriveno)",
|
||||
"built_in_tag": "ugrađeni",
|
||||
"declining": "↘ u opadanju",
|
||||
"energy_low": "Manja energija nego inače",
|
||||
"energy_spike": "Veća energija nego inače",
|
||||
"fair_fit": "prihvatljiva kvaliteta",
|
||||
"fair_fit_tip": "Umjerena dosljednost podudaranja — neki ciklusi dodijeljeni ovom profilu imaju niže rezultate pouzdanosti. Označite više ciklusa ili ponovno snimite profil kako biste poboljšali točnost.",
|
||||
"fair_fit_tip": "Umjerena dosljednost podudaranja – neki ciklusi dodijeljeni ovom profilu imaju niže rezultate pouzdanosti. Označite više ciklusa ili ponovno snimite profil kako biste poboljšali točnost.",
|
||||
"feedback_requested": "Zatražene povratne informacije",
|
||||
"golden_cycle": "Snimljeni referentni ciklus",
|
||||
"improving": "↗ poboljšanje",
|
||||
@@ -87,7 +87,7 @@
|
||||
"on_cycle_finished": "Na ciklusu završen",
|
||||
"on_cycle_started": "Na početku ciklusa",
|
||||
"pause_cycle": "Pauza",
|
||||
"pause_cycle_tip": "Pauziraj pokrenuti ciklus — uređaj će se nastaviti od mjesta na kojem je stao",
|
||||
"pause_cycle_tip": "Pauziraj pokrenuti ciklus – uređaj će se nastaviti od mjesta na kojem je stao",
|
||||
"pg_apply_device": "Primijeni na uređaj",
|
||||
"pg_autofill": "Automatski popuni",
|
||||
"play": "Reproduciraj",
|
||||
@@ -97,8 +97,8 @@
|
||||
"process_tip": "Spremi snimljeni trag kao novi ili postojeći profil",
|
||||
"rebuild": "Ponovno izgradite omotnice",
|
||||
"rebuild_envelope": "Obnovite omotnicu",
|
||||
"rebuild_tip": "Ponovo izračunaj očekivanu omotnicu snage (min/maks pojas) za sve profile iz njihovih označenih ciklusa — pokrenite nakon označavanja novih ciklusa ili ispravljanja starih",
|
||||
"rec_start_tip": "Počni snimanje traga snage uređaja — pokrenite neposredno prije pokretanja ciklusa",
|
||||
"rebuild_tip": "Ponovo izračunaj očekivanu omotnicu snage (min/maks pojas) za sve profile iz njihovih označenih ciklusa – pokrenite nakon označavanja novih ciklusa ili ispravljanja starih",
|
||||
"rec_start_tip": "Počni snimanje traga snage uređaja – pokrenite neposredno prije pokretanja ciklusa",
|
||||
"rec_stop": "Zaustavi",
|
||||
"rec_stop_tip": "Zaustavi snimanje i zadrži snimljeni trag radi pregleda",
|
||||
"record": "Započnite snimanje",
|
||||
@@ -231,7 +231,7 @@
|
||||
"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": "{n} sukob{s} postavki – provjerite istaknute odjeljke i ispravite prije pohrane.",
|
||||
"settings_banner_btn": "Idi na prvi"
|
||||
},
|
||||
"hdr": {
|
||||
@@ -451,9 +451,9 @@
|
||||
"show_expected": "Prikaži očekivani sloj krivulje (podudarni profil, narančasto)",
|
||||
"show_raw": "Prikaži prekidač sirovih očitanja utičnice u živom grafu snage",
|
||||
"sparkline": "Nedavni trend trajanja ciklusa",
|
||||
"stage2": "Faza 2 — osnovna sličnost",
|
||||
"stage3": "Faza 3 — DTW",
|
||||
"stage4": "Faza 4 — podudaranje",
|
||||
"stage2": "Faza 2 – osnovna sličnost",
|
||||
"stage3": "Faza 3 – DTW",
|
||||
"stage4": "Faza 4 – podudaranje",
|
||||
"status": "Status",
|
||||
"tail_trim": "Podrezivanje repa",
|
||||
"timer_auto_pause": "Automatska pauza",
|
||||
@@ -561,7 +561,12 @@
|
||||
"flags": "Oznake",
|
||||
"include_phase_map": "Uključi kartu faza",
|
||||
"include_settings": "Uključi postavke",
|
||||
"show_contributor": "Prikaži suradnika"
|
||||
"show_contributor": "Prikaži suradnika",
|
||||
"task_pg_detail": "Simuliraj ciklus",
|
||||
"task_split": "Dijeljenje ciklusa",
|
||||
"task_trim": "Obrezivanje ciklusa",
|
||||
"task_merge": "Spajanje ciklusa",
|
||||
"task_rebuild": "Ponovna izgradnja ovojnica"
|
||||
},
|
||||
"log": {
|
||||
"all_levels": "Sve razine",
|
||||
@@ -645,7 +650,7 @@
|
||||
"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.",
|
||||
"artifact_header": "Tijekom ovog ciklusa otkriveno je {n} anomalija",
|
||||
"artifact_pause_detail": "Snaga je pala na gotovo nulu za ~{n}s, a zatim se nastavila — vjerojatno su vrata otvorena usred ciklusa ili je ciklus bio pauziran.",
|
||||
"artifact_pause_detail": "Snaga je pala na gotovo nulu za ~{n}s, a zatim se nastavila – vjerojatno su vrata otvorena usred ciklusa ili je ciklus bio pauziran.",
|
||||
"artifact_spike_detail": "Poraslo iznad uobičajenog pojasa snage ~{n}s.",
|
||||
"auto_label_intro": "Dodijelite profile neoznačenim ciklusima čija pouzdanost podudaranja prelazi prag.",
|
||||
"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.",
|
||||
@@ -654,10 +659,10 @@
|
||||
"collecting_data": "Prikupljanje podataka: još {need} ciklusa prije početka finog podešavanja ({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",
|
||||
"compare_selected_cycles": "Odabrani ciklusi (puno) – prikaži / sakrij",
|
||||
"consider_new_profile": "Razmislite o stvaranju novog profila.",
|
||||
"coverage_gap": "nedavni ciklusi nemaju odgovarajući profil ({pct}% od zadnjih 30).",
|
||||
"coverage_gap_similar_cycles": "Pronađeno {count} sličnih neoznačenih ciklusa — izradite profil da biste ih počeli podudarati.",
|
||||
"coverage_gap_similar_cycles": "Pronađeno {count} sličnih neoznačenih ciklusa – izradite profil da biste ih počeli podudarati.",
|
||||
"cycles_deleted": "{count} ciklus(a) izbrisano",
|
||||
"enough_data": "Dovoljno podataka za učenje ({current}/{min} ciklusa).",
|
||||
"export_description": "Izvezite sve profile i cikluse u JSON ili vratite iz prethodnog izvoza.",
|
||||
@@ -686,7 +691,7 @@
|
||||
"ml_learned_intro": "Modeli prilagođeni ovom stroju.",
|
||||
"ml_loading": "učitavanje ML-a…",
|
||||
"ml_settings_intro": "Dva neovisna prekidača: jedan primjenjuje modele dok ciklus radi, drugi omogućuje WashData da ih fino prilagodi vašem stroju tijekom vremena.",
|
||||
"name_first_program": "Imate dovoljno ciklusa — imenujte svoj prvi program da započnete podudaranje.",
|
||||
"name_first_program": "Imate dovoljno ciklusa – imenujte svoj prvi program da započnete podudaranje.",
|
||||
"near_duplicate_cluster": "otkriven je skoro duplikat profila. Grupiranje omogućuje uparivanje pouzdanog odabira sličnih programa (npr. isti program na različitoj temperaturi/centrifugi).",
|
||||
"no_cycles_match": "Nijedan ciklus ne odgovara trenutnom filtru.",
|
||||
"no_cycles_profile": "Nema ciklusa za ovaj profil.",
|
||||
@@ -696,7 +701,7 @@
|
||||
"no_devices": "Još nije konfiguriran nijedan WashData uređaj.",
|
||||
"no_envelope": "Još nema omotnice - obnovite nakon ciklusa označavanja.",
|
||||
"no_envelope_overlay": "Nema dostupnih omotnica za preklapanje.",
|
||||
"no_fine_tuned": "Još ništa fino podešeno — WashData koristi svoje ugrađene modele.",
|
||||
"no_fine_tuned": "Još ništa fino podešeno – WashData koristi svoje ugrađene modele.",
|
||||
"no_logs": "Još nema zapisa u međuspremniku.",
|
||||
"no_maintenance": "Još nema zabilježenog održavanja.",
|
||||
"no_match_yet": "Još nema pokušaja podudaranja - ovo se popunjava tijekom ciklusa izvođenja.",
|
||||
@@ -713,7 +718,7 @@
|
||||
"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.",
|
||||
"onboarding_progress": "{n} / 3 ciklusa promatrano",
|
||||
"onboarding_watching": "Koristite uređaj uobičajeno — WashData promatra. Nakon 3 ciklusa započet će podudaranje programa.",
|
||||
"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",
|
||||
"performance_trend": "Trend izvedbe ({n} ciklusa)",
|
||||
"pg_analysis_empty": "Učitajte ciklus za prikaz analize podudaranja.",
|
||||
@@ -763,7 +768,7 @@
|
||||
"setting_changed": "Promijenjeno s {old} na {new} dana {date}",
|
||||
"settings_basic_note": "Prikazuju se osnovne postavke. Prebacite na Napredno za cijeli popis.",
|
||||
"shape_drift_advisory": "⚠ Oblik se mijenja",
|
||||
"shape_drift_detail": "Uzorak snage ovog profila promijenio se s vremenom — moguće habanje uređaja ili potrebno održavanje (npr. uklanjanje kamenca, čišćenje filtera).",
|
||||
"shape_drift_detail": "Uzorak snage ovog profila promijenio se s vremenom – moguće habanje uređaja ili potrebno održavanje (npr. uklanjanje kamenca, čišćenje filtera).",
|
||||
"show_all_settings": "Prikaži sve postavke",
|
||||
"showing_suggestions": "Prikazuje se {count} postavka s prijedlozima.",
|
||||
"split_intro": "Pritisnite grafikon da biste dodali ili uklonili točku razdvajanja ili automatsko otkrivanje praznina u mirovanju. Svaki rezultirajući segment može dobiti svoj profil.",
|
||||
@@ -789,10 +794,10 @@
|
||||
"toast_revert_failed": "Vraćanje neuspješno: {error}",
|
||||
"toast_reverted": "{key} vraćeno",
|
||||
"toast_save_failed": "Spremanje neuspješno: {error}",
|
||||
"trend_duration_longer": "Dulje trajanje ({pct}%/ciklus) — nedavni prosjek {avg}",
|
||||
"trend_duration_shorter": "Trajanje je sve kraće ({pct}%/ciklus) — nedavni prosjek {avg}",
|
||||
"trend_duration_longer": "Dulje trajanje ({pct}%/ciklus) – nedavni prosjek {avg}",
|
||||
"trend_duration_shorter": "Trajanje je sve kraće ({pct}%/ciklus) – nedavni prosjek {avg}",
|
||||
"trend_energy_down": "Energija opada ({pct}%/ciklus)",
|
||||
"trend_energy_up": "Energija raste ({pct}%/ciklus) — nedavni prosjek {avg}",
|
||||
"trend_energy_up": "Energija raste ({pct}%/ciklus) – nedavni prosjek {avg}",
|
||||
"trim_intro": "Povucite crvene ručice ili unesite vrijednosti. Sve izvan prozora je uklonjeno.",
|
||||
"tuning_suggestions_available": "{count} prijedlog podešavanja dostupan iz promatranih ciklusa. Pojavljuju se pored relevantnih polja.",
|
||||
"unsure_detected_prefix": "WashData nije siguran da je otkriven",
|
||||
@@ -857,7 +862,9 @@
|
||||
"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"
|
||||
"share_profile_no_cycles": "Profil '{p}' nema ⭐ referentnih ciklusa -- bit će preskočen osim ako nemate {n}+ potvrđenih pokretanja",
|
||||
"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"
|
||||
},
|
||||
"phase_desc": {
|
||||
"anti_crease": "Povremena kratka prevrtanja nakon završetka kako bi se smanjile bore.",
|
||||
@@ -940,6 +947,10 @@
|
||||
"triggers": {
|
||||
"intro": "Neobavezni vanjski signali: okidač završetka, senzor vrata, prekidač za pauzu i podsjetnik za istovar.",
|
||||
"label": "Okidači i vrata"
|
||||
},
|
||||
"phase_eta": {
|
||||
"label": "Preostalo vrijeme",
|
||||
"intro": "Preostalo vrijeme koje uzima u obzir faze, za uređaje čija duljina ciklusa ovisi o temperaturi ili centrifugi."
|
||||
}
|
||||
},
|
||||
"setting": {
|
||||
@@ -1023,6 +1034,10 @@
|
||||
"doc": "Fiksna cijena po kWh koja se koristi za podatke o troškovima kada iznad nije postavljen entitet stvarne cijene.",
|
||||
"label": "Statička cijena energije (po kWh)"
|
||||
},
|
||||
"energy_sensor": {
|
||||
"doc": "Neobavezno kumulativno brojilo energije (total_increasing kWh/Wh, npr. vlastito brojilo ukupne potrošnje utičnice). Kada je postavljeno, energija prijavljena za svaki ciklus uzima se iz razlike očitanja ovog brojila između početka i kraja, čime se izbjegava podbrojavanje koje nastaje integriranjem sporo izvještavajućeg senzora snage. Vraća se na integriranu vrijednost ako očitanje nedostaje, njegova je jedinica nepoznata ili razlika nije pozitivna. Ostavite prazno da nastavite integrirati senzor snage.",
|
||||
"label": "Entitet brojila energije"
|
||||
},
|
||||
"expose_debug_entities": {
|
||||
"doc": "Objavite dodatne dijagnostičke HA entitete (povjerenje podudaranja, dvosmislenost, interno stanje). Isključeno održava popis entiteta čistim za normalnu upotrebu.",
|
||||
"label": "Izloži entitete za otklanjanje pogrešaka"
|
||||
@@ -1305,6 +1320,38 @@
|
||||
},
|
||||
"show_contributor": {
|
||||
"doc": "Prikaži ime suradnika na profilima preuzetim iz trgovine zajednice"
|
||||
},
|
||||
"enable_phase_matching": {
|
||||
"label": "Preostalo vrijeme prema fazama",
|
||||
"doc": "Svaki aktivni ciklus dijeli na faze (grijanje, pranje, centrifuga) i raspoređuje preostalo vrijeme po fazama, spojeno s klasičnom procjenom - na početku ciklusa oslanja se na proračun faza, a pri kraju na klasičnu procjenu. To prilagođava odbrojavanje tome koliko se vaš uređaj stvarno grije i radi, što je najuočljivije u prvoj polovici ciklusa. Isključeno = samo klasična procjena. Utječe samo na prikaz preostalog vremena; podudaranje programa i otkrivanje ciklusa ostaju nepromijenjeni."
|
||||
},
|
||||
"keep_min_score": {
|
||||
"label": "Min. ocjena podudaranja",
|
||||
"doc": "Minimalna ocjena sličnosti potrebna kandidatu za ostanak u utrci podudaranja. Zadana vrijednost 0,1 je namjerno blaga - dopušta čak i slabe kandidate i oslanja se na kasnijе faze za pronalazak najboljeg podudaranja. Povećajte za ranije odbacivanje neprobabilnih profila; smanjite za proširenje početnog skupa kandidata."
|
||||
},
|
||||
"dtw_blend": {
|
||||
"label": "Miješanje deformacije",
|
||||
"doc": "Koliko DTW ocjena poravnanja zamjenjuje osnovnu ocjenu Faze 2. 0 = koristi samo ocjenu Faze 2, 1 = koristi samo DTW ocjenu, 0,5 (zadano) = jednako miješanje. Povećajte za veće oslanjanje na warp poravnanje kada programi imaju slične razine snage ali različite obrasce tajminga."
|
||||
},
|
||||
"dtw_ensemble_w": {
|
||||
"label": "Miks kombinacije DTW",
|
||||
"doc": "U kombiniranom DTW načinu (zadanom), težina skaliranog L1 nasuprot derivatnog DTW (DDTW). 1,0 = sve skalirano L1, 0 = sve DDTW, 0,7 = zadano. Skalirana L1 varijanta uspoređuje razine snage; derivatna varijanta reagira na promjene snage kroz vrijeme. Kombinirani način spaja oboje."
|
||||
},
|
||||
"dtw_ddtw_scale": {
|
||||
"label": "Skala derivatne deformacije",
|
||||
"doc": "Udaljenost polu-zasićenja za ocjenjivanje derivatnim DTW. Ocjena se prepolovi kada je DDTW udaljenost jednaka ovoj vrijednosti. Manje = osjetljivije na razlike u obliku. Zadana vrijednost 30 je kalibrirana za tipične tragove snage kućanskih aparata. Utječe samo na kombinirani i ddtw DTW način."
|
||||
},
|
||||
"dtw_refine_top_n": {
|
||||
"label": "Broj preciziranih kandidata",
|
||||
"doc": "Koliko prvih kandidata Faze 2 DTW ponovo ocjenjuje. DTW je skuplji pa se primjenjuje samo na N najboljih kandidata. Zadano 5. Povećajte (na 7-9) ako ispravni profil ponekad dostigne samo 4. ili 5. mjesto nakon Faze 2 - DTW ga može spasiti. Smanjenje malo ubrzava podudaranje."
|
||||
},
|
||||
"duration_scale": {
|
||||
"label": "Oštrість trajanja",
|
||||
"doc": "Oštrina kazne za nepodudaranje trajanja u Fazi 4. Ovo je omjer logaritma pri kojemu se ocjena slaganja prepolovi. Manje = strože: nepodudaranje trajanja više snižava ocjenu. Zadana vrijednost 0,175 odgovara toleranciji trajanja od oko 18% pri polu-težini. Koristite zajedno s Težinom trajanja."
|
||||
},
|
||||
"energy_scale": {
|
||||
"label": "Oštrina energije",
|
||||
"doc": "Oštrina kazne za nepodudaranje energije u Fazi 4. Manje = strože: nepodudaranje energije više snižava ocjenu. Zadana vrijednost 0,25 je namjerno blaža od Oštrine trajanja jer energija varira s opterećenjem. Koristite zajedno s Težinom energije."
|
||||
}
|
||||
},
|
||||
"setting_group": {
|
||||
@@ -1424,24 +1471,24 @@
|
||||
"lower": "Više ciklusa se automatski označava; neki mogu biti pogrešno identificirani"
|
||||
},
|
||||
"duration_tolerance": {
|
||||
"higher": "Prihvaća širi raspon trajanja — fleksibilnije podudaranje",
|
||||
"lower": "Zahtijeva bliže podudaranje trajanja — strože, ali može odbiti neobične cikluse"
|
||||
"higher": "Prihvaća širi raspon trajanja – fleksibilnije podudaranje",
|
||||
"lower": "Zahtijeva bliže podudaranje trajanja – strože, ali može odbiti neobične cikluse"
|
||||
},
|
||||
"end_energy_threshold": {
|
||||
"higher": "Zatvara samo cikluse sa značajnom potrošnjom energije",
|
||||
"lower": "Zatvara i kraće ili manje energetske cikluse"
|
||||
},
|
||||
"end_repeat_count": {
|
||||
"higher": "Zahtijeva više ponavljanja signala kraja — pouzdanije, malo sporije",
|
||||
"lower": "Završava nakon manje ponavljanja — brže otkrivanje, veći rizik od lažnog kraja"
|
||||
"higher": "Zahtijeva više ponavljanja signala kraja – pouzdanije, malo sporije",
|
||||
"lower": "Završava nakon manje ponavljanja – brže otkrivanje, veći rizik od lažnog kraja"
|
||||
},
|
||||
"learning_confidence": {
|
||||
"higher": "Uči samo iz visoko pouzdanih podudaranja — sporije, ali pouzdanije",
|
||||
"higher": "Uči samo iz visoko pouzdanih podudaranja – sporije, ali pouzdanije",
|
||||
"lower": "Uči iz više ciklusa; model može biti manje precizan"
|
||||
},
|
||||
"min_off_gap": {
|
||||
"higher": "Potreban je duži odmor prije početka novog ciklusa",
|
||||
"lower": "Kratki odmor pokreće novi ciklus — uzastopni ciklusi se mogu razdijeliti"
|
||||
"lower": "Kratki odmor pokreće novi ciklus – uzastopni ciklusi se mogu razdijeliti"
|
||||
},
|
||||
"min_power": {
|
||||
"higher": "Manje osjetljiv na potrošnju u mirovanju; može propustiti tihe programe",
|
||||
@@ -1452,24 +1499,24 @@
|
||||
"lower": "Zaglavljeni ciklus se prisilno zaustavlja ranije"
|
||||
},
|
||||
"off_delay": {
|
||||
"higher": "Više vremena za pauze uređaja — prikladno za duge faze namakanja ili sušenja",
|
||||
"lower": "Brže otkrivanje kraja — dobro za uređaje s čistim uključivanjem/isključivanjem"
|
||||
"higher": "Više vremena za pauze uređaja – prikladno za duge faze namakanja ili sušenja",
|
||||
"lower": "Brže otkrivanje kraja – dobro za uređaje s čistim uključivanjem/isključivanjem"
|
||||
},
|
||||
"profile_match_threshold": {
|
||||
"higher": "Potvrđuje samo visoko pouzdana podudaranja; više ciklusa ostaje neoznačeno",
|
||||
"lower": "Podudara više ciklusa; neki mogu biti blago pogrešni"
|
||||
},
|
||||
"running_dead_zone": {
|
||||
"higher": "Zanemaruje kratke skokove snage u mirovanju — manje osjetljiv na šum",
|
||||
"lower": "Reagira na kraće impulse snage — otkriva brzu prolaznu aktivnost"
|
||||
"higher": "Zanemaruje kratke skokove snage u mirovanju – manje osjetljiv na šum",
|
||||
"lower": "Reagira na kraće impulse snage – otkriva brzu prolaznu aktivnost"
|
||||
},
|
||||
"start_threshold_w": {
|
||||
"higher": "Sprječava lažne startove od kratkih skokova snage",
|
||||
"lower": "Otkriva programe s niskom snagom; može reagirati na šum"
|
||||
},
|
||||
"stop_threshold_w": {
|
||||
"higher": "Završava ciklus brže — može zatvoriti za vrijeme pauze",
|
||||
"lower": "Dulje čeka na završetak — manje prijevremenih završetaka"
|
||||
"higher": "Završava ciklus brže – može zatvoriti za vrijeme pauze",
|
||||
"lower": "Dulje čeka na završetak – manje prijevremenih završetaka"
|
||||
},
|
||||
"watchdog_interval": {
|
||||
"higher": "Dopušta dulje tihe faze; manje lažnih prisilnih zaustavljanja",
|
||||
@@ -1676,12 +1723,19 @@
|
||||
"start_duration_threshold": "Sekunde iznad praga za potvrdu pokretanja",
|
||||
"start_threshold_w": "Najmanja snaga u vatima da se broji kao pokrenuto",
|
||||
"stop_threshold_w": "Ispod ovoga uređaj se broji kao isključen",
|
||||
"dtw_bandwidth": "Koliko vremenskog iskrivljenja dopušta podudaranje oblika",
|
||||
"corr_weight": "Težina oblika krivulje u odnosu na razinu snage pri podudaranju",
|
||||
"duration_weight": "Koliko slaganje trajanja utječe na podudaranje",
|
||||
"energy_weight": "Koliko slaganje potrošnje energije utječe na podudaranje",
|
||||
"profile_match_min_duration_ratio": "Najkraće izvođenje (u odnosu na profil) koje se još može podudarati",
|
||||
"profile_match_max_duration_ratio": "Najdulje izvođenje (u odnosu na profil) koje se još može podudarati"
|
||||
"dtw_bandwidth": "Faza 3: warp opseg Sakoe-Chiba (0 = DTW isključen; zadano 0,2 = 20% duljine ciklusa)",
|
||||
"corr_weight": "Faza 2: ravnoteža između oblika krivulje (korelacija) i razine snage (MAE); zadano 0,45",
|
||||
"duration_weight": "Faza 4: koliko jako slaganje trajanja utječe na konačnu ocjenu (zadano 0,22)",
|
||||
"energy_weight": "Faza 4: koliko jako slaganje energije utječe na konačnu ocjenu (zadano 0,22)",
|
||||
"profile_match_min_duration_ratio": "Faza 1: minimalna duljina ciklusa kao udio trajanja profila; zadano 0,1 (10%)",
|
||||
"profile_match_max_duration_ratio": "Faza 1: maksimalna duljina ciklusa kao udio trajanja profila; zadano 1,5 (150%)",
|
||||
"keep_min_score": "Faza 2: minimalna ocjena za ostanak u utrci; zadano 0,1 dopušta slabe podudarnosti, kasniji koraci biraju najboljeg",
|
||||
"dtw_blend": "Faza 3: 0 = samo osnovna ocjena, 1 = samo DTW ocjena, 0,5 = jednako miješanje (zadano)",
|
||||
"dtw_ensemble_w": "Faza 3 (kombinirani način): težina skaliranog L1 nasuprot derivatnog DTW; zadano 0,7 favorizira razinu",
|
||||
"dtw_ddtw_scale": "Faza 3: udaljenost polu-zasićenja DDTW; manja = osjetljivija na oblik (zadano 30)",
|
||||
"dtw_refine_top_n": "Faza 3: kandidati koje DTW ponovo ocjenjuje; povećajte na 7-9 ako ispravni profil zauzme 4.-5. mjesto (zadano 5)",
|
||||
"duration_scale": "Faza 4: omjer logaritma gdje se slaganje trajanja prepolovi; manje = stroža kazna (zadano 0,175)",
|
||||
"energy_scale": "Faza 4: omjer logaritma gdje se slaganje energije prepolovi; manje = stroža kazna (zadano 0,25)"
|
||||
},
|
||||
"col": {
|
||||
"profile_tip": "Naziv podudarnog programa. Bez oznake znači da se na kraju ciklusa nijedan profil nije podudarao.",
|
||||
@@ -1766,6 +1820,69 @@
|
||||
},
|
||||
"pg_sweep": {
|
||||
"optimize": "Optimizacija: {param}"
|
||||
},
|
||||
"pg_detail": {
|
||||
"simulate": "Simuliraj ciklus"
|
||||
},
|
||||
"split": {
|
||||
"apply": "Dijeljenje ciklusa"
|
||||
},
|
||||
"trim": {
|
||||
"apply": "Obrezivanje ciklusa"
|
||||
},
|
||||
"merge": {
|
||||
"apply": "Spajanje ciklusa"
|
||||
},
|
||||
"rebuild": {
|
||||
"envelopes": "Ponovna izgradnja ovojnica"
|
||||
},
|
||||
"cancelling": "Otkazujem..."
|
||||
},
|
||||
"setup": {
|
||||
"hdr": {
|
||||
"card": "Postavljanje uređaja",
|
||||
"healthy_chip": "Postavljanje dovršeno"
|
||||
},
|
||||
"phase0": {
|
||||
"washer": "WashData već otkriva vaše cikluse. Snimite prvi ciklus kako biste omogućili nazive programa i procjene vremena.",
|
||||
"dishwasher": "WashData prati. Perilice posuđa imaju složene cikluse – snimanje prvog ciklusa je izrazito preporučeno. Ako otkriveni ciklus traje predugo, upotrijebite uređivač ciklusa za obrezivanje prije pohrane kao profila.",
|
||||
"generic": "WashData prati. Snimite ili označite otkriveni ciklus kako biste počeli graditi profile."
|
||||
},
|
||||
"phase1a": {
|
||||
"labelled": "Dobar početak – vaš prvi program je pohranjen. Za najčišće podatke razmislite o snimanju sljedećeg ciklusa pomoću widgeta snimača."
|
||||
},
|
||||
"phase1b": {
|
||||
"recorded": "Vaše snimanje pohranjeno je kao {profile_name}. Sada snimite ili označite ostale uobičajene programe za izgradnju pokrivenosti."
|
||||
},
|
||||
"phase1c": {
|
||||
"verify": "Imate {count} programa od zajednice. Pokrenite ciklus kako biste provjerili prepoznaje li ih WashData ispravno – podudaranje će se poboljšati kako vaš uređaj gradi vlastitu povijest."
|
||||
},
|
||||
"phase2": {
|
||||
"cluster": "WashData je vidio {count} ciklusa koji ne odgovaraju nijednom pohranjenome programu – nalikuju jedni drugima. Želite li za njih stvoriti novi profil?",
|
||||
"unmatched": "Vaš zadnji ciklus nije odgovarao nijednom pohranjenome programu. Je li to novi program?"
|
||||
},
|
||||
"phase3": {
|
||||
"suggestions": "WashData ima preporuke postavki temeljene na vašoj povijesti ciklusa – pregledajte ih kako biste poboljšali točnost otkrivanja.",
|
||||
"groups": "Neki vaši profili izgledaju kao isti program pri različitim temperaturama. Organizirajte ih u grupu za bolje podudaranje.",
|
||||
"phases": "Dodajte faze programa u {profile_name} za točnije procjene preostalog vremena."
|
||||
},
|
||||
"phase4": {
|
||||
"healthy": "Ovaj uređaj je potpuno postavljen ({profile_count} profila)."
|
||||
},
|
||||
"cta": {
|
||||
"start_recording": "Pokreni snimanje",
|
||||
"label_detected_cycle": "Već imam otkriven ciklus – umjesto toga ga označi",
|
||||
"browse_cycles": "Pregledaj cikluse za označavanje sljedećeg",
|
||||
"view_profiles": "Prikaži svoje profile",
|
||||
"create_from_cluster": "Stvori profil od ovih ciklusa",
|
||||
"create_profile": "Stvori za njega profil",
|
||||
"review_suggestions": "Preglej prijedloge",
|
||||
"organise_profiles": "Organiziraj profile",
|
||||
"configure_phases": "Konfiguriraj faze",
|
||||
"skip_step": "Preskoči ovaj korak",
|
||||
"skip_forever": "Ne prikazuj više",
|
||||
"hide_guidance": "Sakrij upute",
|
||||
"show_guidance": "Prikaži upute"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
"on_cycle_finished": "A ciklus végén",
|
||||
"on_cycle_started": "Beindult a ciklus",
|
||||
"pause_cycle": "Szünet",
|
||||
"pause_cycle_tip": "Szüneteltesse a futó ciklust — a készülék onnan folytatja, ahol abbahagyta",
|
||||
"pause_cycle_tip": "Szüneteltesse a futó ciklust – a készülék onnan folytatja, ahol abbahagyta",
|
||||
"pg_apply_device": "Alkalmazás az eszközre",
|
||||
"pg_autofill": "Automatikus kitöltés",
|
||||
"play": "Lejátszás",
|
||||
@@ -97,8 +97,8 @@
|
||||
"process_tip": "Mentse el a rögzített nyomot új vagy meglévő profilként",
|
||||
"rebuild": "Borítékok újjáépítése",
|
||||
"rebuild_envelope": "Boríték újraépítése",
|
||||
"rebuild_tip": "Számítsa újra az elvárt energiaburkolót (min/max sáv) az összes profilhoz a felcímkézett ciklusaik alapján — futtassa új ciklusok felcímkézése vagy régiek javítása után",
|
||||
"rec_start_tip": "Kezdje el rögzíteni a készülék teljesítménynyomát — indítsa közvetlenül a ciklus futtatása előtt",
|
||||
"rebuild_tip": "Számítsa újra az elvárt energiaburkolót (min/max sáv) az összes profilhoz a felcímkézett ciklusaik alapján – futtassa új ciklusok felcímkézése vagy régiek javítása után",
|
||||
"rec_start_tip": "Kezdje el rögzíteni a készülék teljesítménynyomát – indítsa közvetlenül a ciklus futtatása előtt",
|
||||
"rec_stop": "Leállítás",
|
||||
"rec_stop_tip": "Állítsa le a rögzítést, és tartsa fenn a rögzített nyomot áttekintésre",
|
||||
"record": "Indítsa el a Felvételt",
|
||||
@@ -182,7 +182,7 @@
|
||||
},
|
||||
"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.",
|
||||
"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.",
|
||||
"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})",
|
||||
@@ -451,9 +451,9 @@
|
||||
"show_expected": "Várható görbefedvény megjelenítése (egyező profil, narancssárga)",
|
||||
"show_raw": "Nyers csatlakozó kapcsoló megjelenítése az élő teljesítménygrafikonon",
|
||||
"sparkline": "Legutóbbi ciklusidőtartam-trend",
|
||||
"stage2": "2. szakasz — alapvető hasonlóság",
|
||||
"stage3": "3. szakasz — DTW",
|
||||
"stage4": "4. szakasz — egyezés",
|
||||
"stage2": "2. szakasz – alapvető hasonlóság",
|
||||
"stage3": "3. szakasz – DTW",
|
||||
"stage4": "4. szakasz – egyezés",
|
||||
"status": "Állapot",
|
||||
"tail_trim": "Farokszegély(ek)",
|
||||
"timer_auto_pause": "Automatikus szünet",
|
||||
@@ -561,7 +561,12 @@
|
||||
"flags": "Jelzők",
|
||||
"include_phase_map": "Fázistérkép belefoglalása",
|
||||
"include_settings": "Érzékelési és párosítási beállítások belefoglalása",
|
||||
"show_contributor": "Közreműködők nevének megjelenítése"
|
||||
"show_contributor": "Közreműködők nevének megjelenítése",
|
||||
"task_pg_detail": "Ciklus szimulálása",
|
||||
"task_split": "Ciklus felosztása",
|
||||
"task_trim": "Ciklus levágása",
|
||||
"task_merge": "Ciklusok egyesítése",
|
||||
"task_rebuild": "Burkológörbék újraépítése"
|
||||
},
|
||||
"log": {
|
||||
"all_levels": "Minden szinten",
|
||||
@@ -645,7 +650,7 @@
|
||||
"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.",
|
||||
"artifact_header": "{n} rendellenesség észlelve ebben a ciklusban",
|
||||
"artifact_pause_detail": "A teljesítmény ~{n}s-re közel nullára esett, majd visszatért — valószínűleg kinyílt az ajtó a ciklus közben, vagy a ciklus szünetelt.",
|
||||
"artifact_pause_detail": "A teljesítmény ~{n}s-re közel nullára esett, majd visszatért – valószínűleg kinyílt az ajtó a ciklus közben, vagy a ciklus szünetelt.",
|
||||
"artifact_spike_detail": "~{n}s-re a szokásos energiasáv felett volt.",
|
||||
"auto_label_intro": "Rendeljen hozzá profilokat címkézetlen ciklusokhoz, amelyek egyezési megbízhatósága törli a küszöböt.",
|
||||
"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.",
|
||||
@@ -654,10 +659,10 @@
|
||||
"collecting_data": "Adatgyűjtés folyamatban - még {need} ciklus szükséges a finomhangolás megkezdéséhez ({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",
|
||||
"compare_selected_cycles": "Kiválasztott ciklusok (folytonos) – megjelenítés/elrejtés",
|
||||
"consider_new_profile": "Fontolja meg egy új profil létrehozását.",
|
||||
"coverage_gap": "a legutóbbi ciklusoknak nincs megfelelő profilja (az utolsó 30 {pct}%-a).",
|
||||
"coverage_gap_similar_cycles": "{count} hasonló felcímkézetlen ciklus található — hozzon létre egy profilt az egyeztetés megkezdéséhez.",
|
||||
"coverage_gap_similar_cycles": "{count} hasonló felcímkézetlen ciklus található – hozzon létre egy profilt az egyeztetés megkezdéséhez.",
|
||||
"cycles_deleted": "{count} ciklus törölve",
|
||||
"enough_data": "Elegendő adat a tanuláshoz ({current}/{min} ciklus).",
|
||||
"export_description": "Exportálja az összes profilt és ciklust JSON-ba, vagy állítsa vissza az előző exportálásból.",
|
||||
@@ -686,7 +691,7 @@
|
||||
"ml_learned_intro": "Ehhez a géphez finomhangolt modellek.",
|
||||
"ml_loading": "ML betöltése…",
|
||||
"ml_settings_intro": "Két független kapcsoló: az egyik a ciklus futása közben alkalmazza a modelleket, a másik lehetővé teszi, hogy a WashData idővel finomhangolja őket a gépére.",
|
||||
"name_first_program": "Elég ciklusa van — nevezze el az első programját az egyeztetés elindításához.",
|
||||
"name_first_program": "Elég ciklusa van – nevezze el az első programját az egyeztetés elindításához.",
|
||||
"near_duplicate_cluster": "majdnem ismétlődő profilfürt észlelve. A csoportosítás lehetővé teszi, hogy a párosítás megbízhatóan válasszon a hasonlók között (pl. ugyanaz a program különböző hőmérsékleten/centrifugáláson).",
|
||||
"no_cycles_match": "Egyetlen ciklus sem felel meg az aktuális szűrőnek.",
|
||||
"no_cycles_profile": "Nincs ciklus ehhez a profilhoz.",
|
||||
@@ -713,7 +718,7 @@
|
||||
"notify_services_hint": "Használja a(z) {entity} szolgáltatásazonosítókat (több esetén vesszővel elválasztva). Sablonváltozók: {vars}.",
|
||||
"old_actions_warning": "A régi műveletszerkesztővel konfigurálva (most eltávolítva). Továbbra is aktiválják a cikluseseményeket, de már nem szerkeszthetők itt. Alakítsa át őket normál automatizálássá, vagy távolítsa el őket.",
|
||||
"onboarding_progress": "{n} / 3 ciklus megfigyelve",
|
||||
"onboarding_watching": "Használja a készülékét a szokásos módon — a WashData figyel. 3 ciklus után elindul a programegyeztetés.",
|
||||
"onboarding_watching": "Használja a készülékét a szokásos módon – a WashData figyel. 3 ciklus után elindul a programegyeztetés.",
|
||||
"pending_feedback": "Függőben lévő észlelési visszajelzés",
|
||||
"performance_trend": "Teljesítménytrend ({n} ciklus)",
|
||||
"pg_analysis_empty": "Töltsön be egy ciklust az egyezéselemzés megtekintéséhez.",
|
||||
@@ -763,7 +768,7 @@
|
||||
"setting_changed": "Módosítva: {old} → {new} ekkor: {date}",
|
||||
"settings_basic_note": "Az alapvető beállítások láthatók. Váltson Fejlett nézetre a teljes listához.",
|
||||
"shape_drift_advisory": "⚠ Alakváltás",
|
||||
"shape_drift_detail": "Ennek a profilnak a teljesítménymintázata idővel megváltozott — lehetséges készülékhasználat okozta kopás vagy szükséges karbantartás (pl. vízkőmentesítés, szűrőtisztítás).",
|
||||
"shape_drift_detail": "Ennek a profilnak a teljesítménymintázata idővel megváltozott – lehetséges készülékhasználat okozta kopás vagy szükséges karbantartás (pl. vízkőmentesítés, szűrőtisztítás).",
|
||||
"show_all_settings": "Minden beállítás megjelenítése",
|
||||
"showing_suggestions": "{count} beállítás megjelenítése javaslatokkal.",
|
||||
"split_intro": "Kattintson a diagramra egy osztási pont hozzáadásához vagy eltávolításához, vagy az üresjárati hézagok automatikus észleléséhez. Minden eredményül kapott szegmens saját profilt kaphat.",
|
||||
@@ -857,7 +862,9 @@
|
||||
"share_guidelines_title": "Megosztás előtt",
|
||||
"store_download_device_intro": "Vegyen át minden megosztott programot és annak referenciaciklusait az eszközére. A saját rögzített ciklusait és statisztikáit nem érinti.",
|
||||
"store_share_device_intro": "Töltse fel a(z) {brand} {model} eszközt a kiválasztott referenciaciklusokkal. Más, ugyanolyan készülékkel rendelkezők átvehetik programjait. A bejegyzések felülvizsgálatra kerülnek nyilvánossá válás előtt.",
|
||||
"share_profile_no_cycles": "Nincsenek referenciaciklusok -- jelöljön meg egy ciklust ⭐-gal a Ciklusok lapon, hogy belefoglalhassa ezt a profilt"
|
||||
"share_profile_no_cycles": "Nincsenek referenciaciklusok -- jelöljön meg egy ciklust ⭐-gal a Ciklusok lapon, hogy belefoglalhassa ezt a profilt",
|
||||
"advisory_phase_inconsistent": "Úgy tűnik, hogy a(z) '{name}' különböző programokat vagy hőmérsékleteket kever - ciklusai nagyon eltérő ideig fűtenek. Ha külön profilokra bontja (pl. hőmérsékletenként), az javítja a párosítást és az időbecsléseket.",
|
||||
"advisory_phase_inconsistent_title": "⚠ Esetleg kevert programok"
|
||||
},
|
||||
"phase_desc": {
|
||||
"anti_crease": "Alkalmankénti rövid bukdácsolás a befejezés után a ráncok csökkentése érdekében.",
|
||||
@@ -940,6 +947,10 @@
|
||||
"triggers": {
|
||||
"intro": "Opcionális külső jelek: záró trigger, ajtóérzékelő, szünetkapcsoló és a kirakodási emlékeztető.",
|
||||
"label": "Triggerek és ajtók"
|
||||
},
|
||||
"phase_eta": {
|
||||
"label": "Hátralévő idő",
|
||||
"intro": "Fázistudatos hátralévő idő olyan gépekhez, amelyek ciklushossza a hőmérséklettől vagy a centrifugálástól függ."
|
||||
}
|
||||
},
|
||||
"setting": {
|
||||
@@ -1023,6 +1034,10 @@
|
||||
"doc": "Rögzített kWh-nkénti ár a költségadatokhoz használatos, ha nincs fent beállítva élő ár entitás.",
|
||||
"label": "Statikus energiaár (kWh-nként)"
|
||||
},
|
||||
"energy_sensor": {
|
||||
"doc": "Opcionális kumulatív energiaszámláló (total_increasing kWh/Wh, pl. a konnektor saját élettartam-mérője). Ha be van állítva, minden ciklus jelentett energiája ennek a számlálónak a kezdő- és záróértéke közötti különbségéből származik, ami elkerüli azt az alulmérést, amit egy lassan jelentő teljesítményérzékelő integrálásából kapna. Visszavált az integrált értékre, ha a leolvasás hiányzik, mértékegysége ismeretlen, vagy a különbség nem pozitív. Hagyja üresen, hogy továbbra is a teljesítményérzékelőt integrálja.",
|
||||
"label": "Energiamérő entitás"
|
||||
},
|
||||
"expose_debug_entities": {
|
||||
"doc": "Extra diagnosztikai HA entitások közzététele (egyezési megbízhatóság, kétértelműség, belső állapot). Az Off (Kikapcsolva) funkció tisztán tartja az entitáslistát normál használathoz.",
|
||||
"label": "Hibakeresési entitások közzététele"
|
||||
@@ -1305,6 +1320,38 @@
|
||||
},
|
||||
"show_contributor": {
|
||||
"doc": "Jelenítse meg a \"<közreműködő> által\" jelölést a közösségi készülékeken és referenciaciklusokon."
|
||||
},
|
||||
"enable_phase_matching": {
|
||||
"label": "Fázistudatos hátralévő idő",
|
||||
"doc": "Bontsa minden futó ciklust fázisokra (fűtés, mosás, centrifugálás), és a hátralévő időt fázisonként ossza be, a klasszikus becsléssel keverve - a ciklus elején a fázisbeosztásra, a vége felé pedig a klasszikus becslésre támaszkodva. Ez a visszaszámlálót ahhoz igazítja, hogy a gépe ténylegesen mennyi ideig fűt és működik, ami leginkább a ciklus első felében figyelhető meg. Ki = csak a klasszikus becslés. Csak a hátralévő idő kijelzését érinti; a program párosítása és a ciklusérzékelés változatlan marad."
|
||||
},
|
||||
"keep_min_score": {
|
||||
"label": "Min. Egyezési Pontszám",
|
||||
"doc": "A minimális hasonlósági pontszám, amelyre egy jelöltnek szüksége van az egyezési versenyben való maradáshoz. Az alapértelmezett 0.1 szándékosan megengedő - még a gyenge jelölteket is beengedi, és a következő szakaszokra bízza a legjobb egyezés megtalálását. Növelje a valószínűtlen profilok korábbi kizárásához; csökkentse a kezdeti jelöltállomány bővítéséhez."
|
||||
},
|
||||
"dtw_blend": {
|
||||
"label": "Torzítás Keverék",
|
||||
"doc": "Mennyire helyettesíti az időtorzítás (DTW) igazítási pontszám a 2. szakasz alappontszámát. 0 = csak a 2. szakasz pontszáma, 1 = csak a DTW-pontszám, 0.5 (alapértelmezett) = egyenlő keverék. Növelje, hogy jobban támaszkodjon a torzítási igazításra, ha a programoknak hasonló a teljesítményszintjük, de eltérő az időbeli mintájuk."
|
||||
},
|
||||
"dtw_ensemble_w": {
|
||||
"label": "Torzítás Együttes Mix",
|
||||
"doc": "Együttes DTW módban (az alapértelmezett), a súly a skálázott L1 és a derivált DTW (DDTW) között. 1.0 = kizárólag skálázott-L1, 0 = kizárólag DDTW, 0.7 = alapértelmezett. A skálázott-L1 változat a teljesítményszinteket hasonlítja össze; a derivált változat arra reagál, ahogyan a teljesítmény változik az idő során. Az együttes mindkettőt kombinálja."
|
||||
},
|
||||
"dtw_ddtw_scale": {
|
||||
"label": "Derivált Torzítás Skála",
|
||||
"doc": "Féltelítési távolság a derivált DTW pontozáshoz. A pontszám megfeleződik, ha a DDTW-távolság eléri ezt az értéket. Kisebb = érzékenyebb az alakkülönbségekre. Az alapértelmezett 30 a tipikus háztartási gépek teljesítménynyomaihoz van kalibrálva. Csak az együttes és ddtw DTW-módokat érinti."
|
||||
},
|
||||
"dtw_refine_top_n": {
|
||||
"label": "Torzítás Finomítás Szám",
|
||||
"doc": "Hány legjobb 2. szakasz jelöltet pontozza újra a DTW. A DTW számításigényesebb, ezért csak a legjobb N jelöltre alkalmazzák. Alapértelmezett 5. Növelje (7-9-re), ha a helyes profil néha csak a 4. vagy 5. helyen végez a 2. szakasz után - a DTW meg tudja menteni. A csökkentés enyhén felgyorsítja az egyeztetést."
|
||||
},
|
||||
"duration_scale": {
|
||||
"label": "Időtartam Élesség",
|
||||
"doc": "A 4. szakasz időtartam-egyezési büntetésének élessége. Ez az a logaritmikus arány, amelynél az egyezési pontszám megfeleződik. Kisebb = szigorúbb: egy időtartam-eltérés jobban büntet. Az alapértelmezett 0.175 nagyjából 18%-os időtartam-toleranciának felel meg a félsúlynál. Párosítsa az Időtartam Súlyával."
|
||||
},
|
||||
"energy_scale": {
|
||||
"label": "Energia Élesség",
|
||||
"doc": "A 4. szakasz energia-egyezési büntetésének élessége. Kisebb = szigorúbb: egy energia-eltérés jobban büntet. Az alapértelmezett 0.25 szándékosan megengedőbb az Időtartam Élességénél, mivel az energia változik a terheléssel. Párosítsa az Energia Súlyával."
|
||||
}
|
||||
},
|
||||
"setting_group": {
|
||||
@@ -1553,24 +1600,24 @@
|
||||
"lower": "Automatikusan több ciklust jelöl; néhány félre lehet azonosítva"
|
||||
},
|
||||
"duration_tolerance": {
|
||||
"higher": "Szélesebb időtartomány elfogadása — rugalmasabb egyeztetés",
|
||||
"lower": "Pontosabb időtartam-egyezést igényel — szigorúbb, de szokatlan ciklusokat elutasíthat"
|
||||
"higher": "Szélesebb időtartomány elfogadása – rugalmasabb egyeztetés",
|
||||
"lower": "Pontosabb időtartam-egyezést igényel – szigorúbb, de szokatlan ciklusokat elutasíthat"
|
||||
},
|
||||
"end_energy_threshold": {
|
||||
"higher": "Csak jelentős energiát felhasználó ciklusokat zár be",
|
||||
"lower": "Rövidebb vagy alacsony energiájú ciklusokat is bezár"
|
||||
},
|
||||
"end_repeat_count": {
|
||||
"higher": "A befejezési jelet több ismétlés után fogadja el — megbízhatóbb, kissé lassabb",
|
||||
"lower": "Kevesebb ismétlés után ér véget — gyorsabb érzékelés, több hamis befejezési kockázat"
|
||||
"higher": "A befejezési jelet több ismétlés után fogadja el – megbízhatóbb, kissé lassabb",
|
||||
"lower": "Kevesebb ismétlés után ér véget – gyorsabb érzékelés, több hamis befejezési kockázat"
|
||||
},
|
||||
"learning_confidence": {
|
||||
"higher": "Csak nagyon magabiztos egyezésekből tanul — lassabb, de megbízhatóbb",
|
||||
"higher": "Csak nagyon magabiztos egyezésekből tanul – lassabb, de megbízhatóbb",
|
||||
"lower": "Több ciklusból tanul; a modell zajosabb lehet"
|
||||
},
|
||||
"min_off_gap": {
|
||||
"higher": "Hosszabb tétlenség szükséges az új ciklus indulása előtt",
|
||||
"lower": "Rövid tétlenség új ciklust indít — egymást követő futások szétválhatnak"
|
||||
"lower": "Rövid tétlenség új ciklust indít – egymást követő futások szétválhatnak"
|
||||
},
|
||||
"min_power": {
|
||||
"higher": "Kevésbé érzékeny a tétlenségi fogyasztásra; nagyon csendes programokat elszalaszthat",
|
||||
@@ -1581,24 +1628,24 @@
|
||||
"lower": "Elakadt ciklust gyorsabban kényszerít leállítani"
|
||||
},
|
||||
"off_delay": {
|
||||
"higher": "Több idő a készülék szüneteire — hosszú áztatás vagy szárítás kezelése",
|
||||
"lower": "Gyorsabb vége érzékelés — egyértelmű be/ki készülékekhez jól működik"
|
||||
"higher": "Több idő a készülék szüneteire – hosszú áztatás vagy szárítás kezelése",
|
||||
"lower": "Gyorsabb vége érzékelés – egyértelmű be/ki készülékekhez jól működik"
|
||||
},
|
||||
"profile_match_threshold": {
|
||||
"higher": "Csak nagy magabiztosságú egyezéseket erősít meg; több ciklus marad jelöletlen",
|
||||
"lower": "Több ciklust egyeztet; néhány kissé helytelen lehet"
|
||||
},
|
||||
"running_dead_zone": {
|
||||
"higher": "Figyelmen kívül hagyja a rövid teljesítménycsúcsokat tétlenség közben — zajra kevésbé érzékeny",
|
||||
"lower": "Rövidebb teljesítménylökésekre reagál — gyors átmeneti aktivitást észlel"
|
||||
"higher": "Figyelmen kívül hagyja a rövid teljesítménycsúcsokat tétlenség közben – zajra kevésbé érzékeny",
|
||||
"lower": "Rövidebb teljesítménylökésekre reagál – gyors átmeneti aktivitást észlel"
|
||||
},
|
||||
"start_threshold_w": {
|
||||
"higher": "Elkerüli a rövid teljesítménycsúcsokból eredő hamis indításokat",
|
||||
"lower": "Kis teljesítményű programokat is érzékel; zajra is aktiválódhat"
|
||||
},
|
||||
"stop_threshold_w": {
|
||||
"higher": "Gyorsabban fejezi be a ciklust — szünet közben is zárhat",
|
||||
"lower": "Hosszabb ideig vár a befejezésre — kevesebb idő előtti befejezés"
|
||||
"higher": "Gyorsabban fejezi be a ciklust – szünet közben is zárhat",
|
||||
"lower": "Hosszabb ideig vár a befejezésre – kevesebb idő előtti befejezés"
|
||||
},
|
||||
"watchdog_interval": {
|
||||
"higher": "Hosszabb csendes fázisok megengedett; kevesebb hamis kényszeres leállítás",
|
||||
@@ -1676,12 +1723,19 @@
|
||||
"start_duration_threshold": "A küszöb feletti másodpercek az indulás megerősítéséhez",
|
||||
"start_threshold_w": "Minimális wattérték az indulás elismeréséhez",
|
||||
"stop_threshold_w": "Ez alatt a gép kikapcsoltnak számít",
|
||||
"dtw_bandwidth": "Mennyi időbeli torzítást engedélyez az alakillesztés",
|
||||
"corr_weight": "A görbe alakjának és a teljesítményszintnek a súlya az illesztésben",
|
||||
"duration_weight": "Mennyire befolyásolja az időtartam egyezése az illesztést",
|
||||
"energy_weight": "Mennyire befolyásolja az energia egyezése az illesztést",
|
||||
"profile_match_min_duration_ratio": "A legrövidebb ciklus (a profilhoz képest), amely még egyezhet",
|
||||
"profile_match_max_duration_ratio": "A leghosszabb ciklus (a profilhoz képest), amely még egyezhet"
|
||||
"dtw_bandwidth": "3. szakasz: Sakoe-Chiba torzítási sáv (0 = DTW kikapcsolva; alapértelmezett 0.2 = a ciklushossz 20%-a)",
|
||||
"corr_weight": "2. szakasz: egyensúly a görbe alakja (korreláció) és a teljesítményszint (MAE) között; alapértelmezett 0.45",
|
||||
"duration_weight": "4. szakasz: mennyire befolyásolja a futási idő egyezése a végső pontszámot (alapértelmezett 0.22)",
|
||||
"energy_weight": "4. szakasz: mennyire befolyásolja az energia-egyezés a végső pontszámot (alapértelmezett 0.22)",
|
||||
"profile_match_min_duration_ratio": "1. szakasz: minimális ciklushossz a profil időtartamának törtjeként; alapértelmezett 0.1 (10%)",
|
||||
"profile_match_max_duration_ratio": "1. szakasz: maximális ciklushossz a profil időtartamának törtjeként; alapértelmezett 1.5 (150%)",
|
||||
"keep_min_score": "2. szakasz: minimális pontszám a versenyben maradáshoz; az alapértelmezett 0.1 gyenge egyezéseket is beenged, a következő szakaszok választják ki a legjobbat",
|
||||
"dtw_blend": "3. szakasz: 0 = csak alappontszám, 1 = csak DTW-pontszám, 0.5 = egyenlő keverék (alapértelmezett)",
|
||||
"dtw_ensemble_w": "3. szakasz (együttes mód): súly a skálázott-L1 és derivált DTW között; alapértelmezett 0.7 a szintfüggőt részesíti előnyben",
|
||||
"dtw_ddtw_scale": "3. szakasz: DDTW féltelítési távolság; kisebb = érzékenyebb az alakra (alapértelmezett 30)",
|
||||
"dtw_refine_top_n": "3. szakasz: DTW által újrapontozandó jelöltek; növelje 7-9-re, ha a helyes profil a 4-5. helyen végez (alapértelmezett 5)",
|
||||
"duration_scale": "4. szakasz: logaritmikus arány, ahol az időtartam-egyezés megfeleződik; kisebb = szigorúbb büntetés (alapértelmezett 0.175)",
|
||||
"energy_scale": "4. szakasz: logaritmikus arány, ahol az energia-egyezés megfeleződik; kisebb = szigorúbb büntetés (alapértelmezett 0.25)"
|
||||
},
|
||||
"col": {
|
||||
"profile_tip": "Az egyezést mutató program neve. A címkézetlen azt jelenti, hogy a ciklus végén egyetlen profil sem egyezett.",
|
||||
@@ -1766,6 +1820,69 @@
|
||||
},
|
||||
"pg_sweep": {
|
||||
"optimize": "Optimalizálás: {param}"
|
||||
},
|
||||
"pg_detail": {
|
||||
"simulate": "Ciklus szimulálása"
|
||||
},
|
||||
"split": {
|
||||
"apply": "Ciklus felosztása"
|
||||
},
|
||||
"trim": {
|
||||
"apply": "Ciklus levágása"
|
||||
},
|
||||
"merge": {
|
||||
"apply": "Ciklusok egyesítése"
|
||||
},
|
||||
"rebuild": {
|
||||
"envelopes": "Burkológörbék újraépítése"
|
||||
},
|
||||
"cancelling": "Megszakítás..."
|
||||
},
|
||||
"setup": {
|
||||
"hdr": {
|
||||
"card": "Eszköz beállítása",
|
||||
"healthy_chip": "Beállítás kész"
|
||||
},
|
||||
"phase0": {
|
||||
"washer": "A WashData már észleli a ciklusait. Rögzítse az első ciklust a programnevek és az időbecslések engedélyezéséhez.",
|
||||
"dishwasher": "A WashData figyel. A mosogatógépek összetett ciklusokkal rendelkeznek – az első ciklus rögzítése erősen ajánlott. Ha egy észlelt ciklus túl hosszú ideig tart, a profilként való mentés előtt a ciklusszerkesztővel kurtítsa le.",
|
||||
"generic": "A WashData figyel. Rögzítsen vagy jelöljön meg egy észlelt ciklust a profilok létrehozásának megkezdéséhez."
|
||||
},
|
||||
"phase1a": {
|
||||
"labelled": "Jó kezdés – az első programja el van mentve. A legtisztább adatokhoz érdemes a következő ciklust a rögzítő widgettel felvenni."
|
||||
},
|
||||
"phase1b": {
|
||||
"recorded": "A felvétele {profile_name} névvel lett elmentve. Most rögzítse vagy jelölje meg a többi gyakran használt programját a lefedettség növeléséhez."
|
||||
},
|
||||
"phase1c": {
|
||||
"verify": "Önnek {count} program van a közösségtől. Futtasson egy ciklust, hogy ellenőrizze, a WashData helyesen ismeri-e fel – az egyeztetés javul, ahogy az eszköz saját előzményeket gyűjt."
|
||||
},
|
||||
"phase2": {
|
||||
"cluster": "A WashData {count} ciklust látott, amelyek nem felelnek meg egyetlen mentett programnak sem – hasonlítanak egymásra. Szeretne létrehozni nekik egy új profilt?",
|
||||
"unmatched": "Az utolsó ciklus nem felelt meg egyetlen mentett programnak sem. Ez egy új program?"
|
||||
},
|
||||
"phase3": {
|
||||
"suggestions": "A WashData a ciklustörténete alapján beállítási javaslatokkal rendelkezik – tekintse át ezeket az észlelési pontosság javítása érdekében.",
|
||||
"groups": "Néhány profilja ugyanolyannak tűnik, mint ugyanaz a program különböző hőmérsékleteken. Rendezze csoportba a jobb egyeztetés érdekében.",
|
||||
"phases": "Adjon programfázisokat a(z) {profile_name} profilhoz a pontosabb hátralévő idő becslések érdekében."
|
||||
},
|
||||
"phase4": {
|
||||
"healthy": "Ez az eszköz teljesen be van állítva ({profile_count} profil)."
|
||||
},
|
||||
"cta": {
|
||||
"start_recording": "Felvétel indítása",
|
||||
"label_detected_cycle": "Már van egy észlelt ciklusom – inkább jelöljük meg",
|
||||
"browse_cycles": "Ciklusok böngészése egy másik megjelöléséhez",
|
||||
"view_profiles": "Profilok megtekintése",
|
||||
"create_from_cluster": "Profil létrehozása ezekből a ciklusokból",
|
||||
"create_profile": "Profil létrehozása hozzá",
|
||||
"review_suggestions": "Javaslatok áttekintése",
|
||||
"organise_profiles": "Profilok rendezése",
|
||||
"configure_phases": "Fázisok konfigurálása",
|
||||
"skip_step": "Lépés kihagyása",
|
||||
"skip_forever": "Ne mutasd újra",
|
||||
"hide_guidance": "Útmutatás elrejtése",
|
||||
"show_guidance": "Útmutatás megjelenítése"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"badge": {
|
||||
"artifact_tip": "{n} frávik fundust (t.d. hurð opnuð í miðjum lotu) — opnaðu til að sjá þau á línuritinu",
|
||||
"artifact_tip": "{n} frávik fundust (t.d. hurð opnuð í miðjum lotu) – opnaðu til að sjá þau á línuritinu",
|
||||
"auto": "(sjálfvirkt greint)",
|
||||
"built_in_tag": "innbyggður",
|
||||
"declining": "↘ minnkandi",
|
||||
@@ -87,7 +87,7 @@
|
||||
"on_cycle_finished": "Á hringrás lokið",
|
||||
"on_cycle_started": "Á hringrás byrjaði",
|
||||
"pause_cycle": "Gera hlé",
|
||||
"pause_cycle_tip": "Gerðu hlé á gengandi lotu — tækið mun halda áfram þar sem það stoppaði",
|
||||
"pause_cycle_tip": "Gerðu hlé á gengandi lotu – tækið mun halda áfram þar sem það stoppaði",
|
||||
"pg_apply_device": "Beita á tæki",
|
||||
"pg_autofill": "Fylla sjálfkrafa",
|
||||
"play": "Spila",
|
||||
@@ -97,8 +97,8 @@
|
||||
"process_tip": "Vistaðu skráð sporið sem nýjan eða núverandi prófíl",
|
||||
"rebuild": "Endurbyggja umslög",
|
||||
"rebuild_envelope": "Endurbyggja umslag",
|
||||
"rebuild_tip": "Endurreiknaðu vænt orkuumslag (min/max bil) fyrir öll snið úr merktu lotum þeirra — keyrðu eftir að hafa merkt nýjar lotur eða leiðrétt gamlar",
|
||||
"rec_start_tip": "Byrjaðu að taka upp aflferil tækisins — byrjaðu rétt áður en lota er keyrð",
|
||||
"rebuild_tip": "Endurreiknaðu vænt orkuumslag (min/max bil) fyrir öll snið úr merktu lotum þeirra – keyrðu eftir að hafa merkt nýjar lotur eða leiðrétt gamlar",
|
||||
"rec_start_tip": "Byrjaðu að taka upp aflferil tækisins – byrjaðu rétt áður en lota er keyrð",
|
||||
"rec_stop": "Hættu",
|
||||
"rec_stop_tip": "Stöðvaðu upptöku og geymdu fangna ferilinn til skoðunar",
|
||||
"record": "Byrjaðu upptöku",
|
||||
@@ -231,7 +231,7 @@
|
||||
"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": "{n} stillingarárekstur{s} – skoðaðu auðkenndu hlutana og lagaðu þá áður en þú vistar.",
|
||||
"settings_banner_btn": "Fara á fyrsta"
|
||||
},
|
||||
"hdr": {
|
||||
@@ -451,9 +451,9 @@
|
||||
"show_expected": "Sýna væntanleg ferilyfirlag (samsvörun snið, appelsínugult)",
|
||||
"show_raw": "Sýna hráan innstunga-víxlara í rauntíma aflsriti",
|
||||
"sparkline": "Nýleg þróun lotulengdar",
|
||||
"stage2": "Þrep 2 — kjarnalíkindi",
|
||||
"stage3": "Þrep 3 — DTW",
|
||||
"stage4": "Þrep 4 — samræmi",
|
||||
"stage2": "Þrep 2 – kjarnalíkindi",
|
||||
"stage3": "Þrep 3 – DTW",
|
||||
"stage4": "Þrep 4 – samræmi",
|
||||
"status": "Staða",
|
||||
"tail_trim": "Snyrta enda (s)",
|
||||
"timer_auto_pause": "Sjálfvirk hlé",
|
||||
@@ -561,7 +561,12 @@
|
||||
"flags": "Flagg",
|
||||
"include_phase_map": "Hafa fassakort með",
|
||||
"include_settings": "Hafa greiningar- og samsvörunarstillingar með",
|
||||
"show_contributor": "Sýna nöfn framleggjenda"
|
||||
"show_contributor": "Sýna nöfn framleggjenda",
|
||||
"task_pg_detail": "Herma eftir lotu",
|
||||
"task_split": "Skipti lotu upp",
|
||||
"task_trim": "Klippi lotu til",
|
||||
"task_merge": "Sameina lotur",
|
||||
"task_rebuild": "Endurreikna aflhjúpa"
|
||||
},
|
||||
"log": {
|
||||
"all_levels": "Öll stig",
|
||||
@@ -645,7 +650,7 @@
|
||||
"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.",
|
||||
"artifact_header": "{n} frávik fundust í þessari lotu",
|
||||
"artifact_pause_detail": "Afl féll nærri núlli í ~{n}s og hækkaði svo aftur — líklega var hurðin opnuð um miðja lotu eða lota sett í bið.",
|
||||
"artifact_pause_detail": "Afl féll nærri núlli í ~{n}s og hækkaði svo aftur – líklega var hurðin opnuð um miðja lotu eða lota sett í bið.",
|
||||
"artifact_spike_detail": "Fór yfir venjulegt aflband í ~{n}s.",
|
||||
"auto_label_intro": "Úthlutaðu sniðum á ómerktar lotur þar sem samsvörun þeirra hreinsar þröskuldinn.",
|
||||
"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.",
|
||||
@@ -654,10 +659,10 @@
|
||||
"collecting_data": "Safnar gögnum: {need} lota{plural} til viðbótar áður en fínstilling getur hafist ({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",
|
||||
"compare_selected_cycles": "Valdar lotur (fastar) – sýna / fela",
|
||||
"consider_new_profile": "Íhugaðu að búa til nýjan prófíl.",
|
||||
"coverage_gap": "Nýlegar lotur hafa ekkert samsvarandi prófíl ({pct}% af síðustu 30).",
|
||||
"coverage_gap_similar_cycles": "{count} svipaðar ómerktar lotur fundust — búðu til prófíl til að byrja að samstemma þær.",
|
||||
"coverage_gap_similar_cycles": "{count} svipaðar ómerktar lotur fundust – búðu til prófíl til að byrja að samstemma þær.",
|
||||
"cycles_deleted": "{count} lotu(m) eytt",
|
||||
"enough_data": "Nóg gögn til að læra af ({current}/{min} lotur).",
|
||||
"export_description": "Flyttu út öll snið og lotur í JSON, eða endurheimtu frá fyrri útflutningi.",
|
||||
@@ -686,7 +691,7 @@
|
||||
"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.",
|
||||
"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).",
|
||||
"no_cycles_match": "Engar lotur passa við núverandi síu.",
|
||||
"no_cycles_profile": "Engar lotur fyrir þetta snið.",
|
||||
@@ -713,7 +718,7 @@
|
||||
"notify_services_hint": "Notaðu {entity} þjónustuauðkenni (aðskilin með kommum fyrir mörg). Sniðmátsbreytur: {vars}.",
|
||||
"old_actions_warning": "Stillt með gamla aðgerðaritlinum (nú fjarlægður). Þeir virkjast enn við hringrásarviðburði en ekki er lengur hægt að breyta þeim hér. Umbreyttu þeim í venjulega sjálfvirkni eða fjarlægðu þau.",
|
||||
"onboarding_progress": "{n} / 3 lotur skoðaðar",
|
||||
"onboarding_watching": "Notaðu tækið eins og venjulega — WashData fylgist með. Eftir 3 lotur hefst samsvörun prógramma.",
|
||||
"onboarding_watching": "Notaðu tækið eins og venjulega – WashData fylgist með. Eftir 3 lotur hefst samsvörun prógramma.",
|
||||
"pending_feedback": "Bíður viðbrögð við uppgötvunum",
|
||||
"performance_trend": "Árangursþróun ({n} lotur)",
|
||||
"pg_analysis_empty": "Hladdu lotu til að sjá samsvörunargreiningu.",
|
||||
@@ -763,7 +768,7 @@
|
||||
"setting_changed": "Breytt úr {old} í {new} þann {date}",
|
||||
"settings_basic_note": "Sýni nauðsynlegar stillingar. Skiptu yfir í Ítarlegri fyrir allan listann.",
|
||||
"shape_drift_advisory": "⚠ Lögun að breytast",
|
||||
"shape_drift_detail": "Aflmynstur þessa prófíls hefur breyst yfir tíma — mögulegt slit á tæki eða viðhald þarf (t.d. kalkhreinsa, hreinsa síu).",
|
||||
"shape_drift_detail": "Aflmynstur þessa prófíls hefur breyst yfir tíma – mögulegt slit á tæki eða viðhald þarf (t.d. kalkhreinsa, hreinsa síu).",
|
||||
"show_all_settings": "Sýna allar stillingar",
|
||||
"showing_suggestions": "Sýnir {count} stillingu með tillögum.",
|
||||
"split_intro": "Smelltu á línuritið til að bæta við eða fjarlægja skiptingarpunkt, eða greina sjálfvirkt með aðgerðalausum eyðum. Hver hluti sem myndast getur fengið sinn eigin prófíl.",
|
||||
@@ -789,10 +794,10 @@
|
||||
"toast_revert_failed": "Endurstilling mistókst: {error}",
|
||||
"toast_reverted": "{key} afturkallað",
|
||||
"toast_save_failed": "Vistun mistókst: {error}",
|
||||
"trend_duration_longer": "Tímalengd í vændum lengri ({pct}%/lotu) — nýleg meðaltal {avg}",
|
||||
"trend_duration_shorter": "Tímalengd styttist ({pct}%/lotu) — nýleg meðaltal {avg}",
|
||||
"trend_duration_longer": "Tímalengd í vændum lengri ({pct}%/lotu) – nýleg meðaltal {avg}",
|
||||
"trend_duration_shorter": "Tímalengd styttist ({pct}%/lotu) – nýleg meðaltal {avg}",
|
||||
"trend_energy_down": "Orka á niðurleið ({pct}%/lotu)",
|
||||
"trend_energy_up": "Orka hækkar ({pct}%/lotu) — nýleg meðaltal {avg}",
|
||||
"trend_energy_up": "Orka hækkar ({pct}%/lotu) – nýleg meðaltal {avg}",
|
||||
"trim_intro": "Dragðu rauðu handföngin eða sláðu inn gildi. Allt fyrir utan gluggann 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",
|
||||
@@ -857,7 +862,9 @@
|
||||
"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.",
|
||||
"share_profile_no_cycles": "Engar viðmiðunarlotir -- merktu lotu sem ⭐ í flipanum Lotir til að hafa þennan prófíl með"
|
||||
"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"
|
||||
},
|
||||
"pg_desc": {
|
||||
"abrupt_drop_watts": "Skyndilegt fall meðhöndlað sem tafarlaus endir",
|
||||
@@ -869,12 +876,19 @@
|
||||
"start_duration_threshold": "Sekúndur yfir þröskuldi til að staðfesta ræsingu",
|
||||
"start_threshold_w": "Lágmarksvött til að teljast ræst",
|
||||
"stop_threshold_w": "Undir þessu telst vélin af",
|
||||
"dtw_bandwidth": "Hversu mikla tímabjögun formsamsvörunin leyfir",
|
||||
"corr_weight": "Vægi á ferilform á móti aflstigi í samsvöruninni",
|
||||
"duration_weight": "Hversu mikið samræmi í keyrslutíma hefur áhrif á samsvörunina",
|
||||
"energy_weight": "Hversu mikið samræmi í orkunotkun hefur áhrif á samsvörunina",
|
||||
"profile_match_min_duration_ratio": "Stysta keyrsla (miðað við sniðið) sem enn má samsvara",
|
||||
"profile_match_max_duration_ratio": "Lengsta keyrsla (miðað við sniðið) sem enn má samsvara"
|
||||
"dtw_bandwidth": "Þrep 3: Sakoe-Chiba-tímabjögunarband (0 = DTW af; sjálfgefið 0,2 = 20% af lotulegð)",
|
||||
"corr_weight": "Þrep 2: jafnvægi milli ferilforms (fylgni) og aflstigs (MAE); sjálfgefið 0,45",
|
||||
"duration_weight": "Þrep 4: hversu sterklega samræmi í keyrslulengd hefur áhrif á lokaskorið (sjálfgefið 0,22)",
|
||||
"energy_weight": "Þrep 4: hversu sterklega samræmi í orkunotkun hefur áhrif á lokaskorið (sjálfgefið 0,22)",
|
||||
"profile_match_min_duration_ratio": "Þrep 1: stysta lota sem hlutfall af lotulegð sniðs; sjálfgefið 0,1 (10%)",
|
||||
"profile_match_max_duration_ratio": "Þrep 1: lengsta lota sem hlutfall af lotulegð sniðs; sjálfgefið 1,5 (150%)",
|
||||
"keep_min_score": "Þrep 2: lægsta einkunn til að vera eftir í samsvöruninni; sjálfgefið 0,1 leyfir veika frambjóðendur, síðari þrep velja best",
|
||||
"dtw_blend": "Þrep 3: 0 = aðeins kjarnaskor, 1 = aðeins DTW-skor, 0,5 = jöfn blanda (sjálfgefið)",
|
||||
"dtw_ensemble_w": "Þrep 3 (ensemble-hamur): þunginn á skaluðum L1 gagnvart afleiðu-DTW; sjálfgefið 0,7 hlynnar að stiga-meðvitund",
|
||||
"dtw_ddtw_scale": "Þrep 3: DDTW hálf-mettunarfjarlægð; minna = meira formnæmt (sjálfgefið 30)",
|
||||
"dtw_refine_top_n": "Þrep 3: frambjóðendur sem DTW endurgerir skor fyrir; hækkið í 7-9 ef rétt snið lendir á 4.-5. sæti (sjálfgefið 5)",
|
||||
"duration_scale": "Þrep 4: log-hlutfall þar sem samræmi í keyrslulengd helmingast; minna = strangara viðurlög (sjálfgefið 0,175)",
|
||||
"energy_scale": "Þrep 4: log-hlutfall þar sem samræmi í orkunotkun helmingast; minna = strangara viðurlög (sjálfgefið 0,25)"
|
||||
},
|
||||
"phase_desc": {
|
||||
"anti_crease": "Stundum hrynur stutt eftir að því er lokið til að draga úr hrukkum.",
|
||||
@@ -957,6 +971,10 @@
|
||||
"triggers": {
|
||||
"intro": "Valfrjálsir ytri merkar: lokakveikin, dyraskynjari, hlébilaskipti og losunarminnir.",
|
||||
"label": "Kveikjar og dyr"
|
||||
},
|
||||
"phase_eta": {
|
||||
"label": "Tími sem eftir er",
|
||||
"intro": "Tími sem eftir er sem tekur mið af fösum, fyrir vélar þar sem lengd lotu ræðst af hitastigi eða vindingu."
|
||||
}
|
||||
},
|
||||
"setting": {
|
||||
@@ -1040,6 +1058,10 @@
|
||||
"doc": "Fast verð á kWst notað fyrir kostnaðartölur þegar engin lifandi verðeining er stillt hér að ofan.",
|
||||
"label": "Fast orkuverð (á kWh)"
|
||||
},
|
||||
"energy_sensor": {
|
||||
"doc": "Valfrjáls uppsafnaður orkuteljari (total_increasing í kWh/Wh, t.d. eigin líftímamælir innstungunnar). Þegar hann er stilltur er uppgefin orka hverrar lotu tekin úr mismun þessa teljara milli upphafs og enda, sem kemur í veg fyrir vantalninguna sem hlýst af því að heilda hægvirkan aflskynjara. Fer aftur í heildaða gildið ef mælingin vantar, eining hennar er óþekkt eða mismunurinn er ekki jákvæður. Skildu eftir autt til að halda áfram að heilda aflskynjarann.",
|
||||
"label": "Orkumælieining"
|
||||
},
|
||||
"expose_debug_entities": {
|
||||
"doc": "Birtu auka greiningar HA einingar (samsvörun, tvíræðni, innri hluti ríkisins). Slökkt heldur einingarlistanum hreinum fyrir venjulega notkun.",
|
||||
"label": "Birta villuleitareiningar"
|
||||
@@ -1322,6 +1344,38 @@
|
||||
},
|
||||
"show_contributor": {
|
||||
"doc": "Sýnir tilvísunina 'eftir <contributor>' á samfélagstækjum og viðmiðunarlotum."
|
||||
},
|
||||
"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."
|
||||
},
|
||||
"keep_min_score": {
|
||||
"label": "Lágm. samsvörunareinkunn",
|
||||
"doc": "Lægsta likhetseinkunn sem frambjóðandi þarf til að vera eftir í samsvöruninni. Sjálfgefið 0,1 er vísvitandi rýmt – það leyfir jafnvel veika frambjóðendur og treystir á síðari þrep til að finna besta samsvörun. Hækkið til að sía út ósennilegar sniðmát fyrr; lækkkið til að víkka upphaflega frambjóðendasafnið."
|
||||
},
|
||||
"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."
|
||||
},
|
||||
"dtw_ensemble_w": {
|
||||
"label": "DTW-ensemble-blanda",
|
||||
"doc": "Í ensemble-DTW-ham (sjálfgefinn) er þetta þunginn á skaluðum L1 gagnvart afleiðu-DTW (DDTW). 1,0 = aðeins skalað L1, 0 = aðeins DDTW, 0,7 = sjálfgefið. Skalade útgáfan ber saman aflstig; afleiðuútgáfan bregst við því hvernig afl breytist með tíma. Ensemble blandar bæði."
|
||||
},
|
||||
"dtw_ddtw_scale": {
|
||||
"label": "Afleiðu-DTW-kvarði",
|
||||
"doc": "Hálf-mettunarfjarlægð fyrir afleiðu-DTW-stigagjöf. Einkunnin helmingast þegar DDTW-fjarlægðin er jöfn þessu gildi. Minna = næmara fyrir formmunur. Sjálfgefið 30 er kvarðað fyrir dæmigerðar aflferil tækja. Hefur aðeins áhrif á ensemble- og ddtw-DTW-hama."
|
||||
},
|
||||
"dtw_refine_top_n": {
|
||||
"label": "DTW-fínstillingarfjöldi",
|
||||
"doc": "Hversu marga toppframbjóðendur frá Þrepi 2 DTW endurgerir skor fyrir. DTW er dýrara svo það er aðeins beitt á bestu N frambjóðendurna. Sjálfgefið 5. Hækkið (í 7-9) ef rétt snið lendir stundum aðeins á 4. eða 5. sæti eftir Þrep 2 – DTW getur bjargað því. Lægra gildi hraðar samsvörun lítið."
|
||||
},
|
||||
"duration_scale": {
|
||||
"label": "Lengdarskerpa",
|
||||
"doc": "Skerpa í viðurlögum Þreps 4 vegna samræmis í keyrslulengd. Þetta er log-hlutfallið þar sem samræmisskorið helmingast. Minna = strangara: frávik í keyrslulengd skemmir meira. Sjálfgefið 0,175 samsvarar um 18% þolmörkum í keyrslulengd við hálft þyngd. Notaðu með Keyrslulengdarþyngd."
|
||||
},
|
||||
"energy_scale": {
|
||||
"label": "Orkuskerpa",
|
||||
"doc": "Skerpa í viðurlögum Þreps 4 vegna samræmis í orkunotkun. Minna = strangara: frávik í orkunotkun skemmir meira. Sjálfgefið 0,25 er vísvitandi rýmra en keyrslulengdarskerpan vegna þess að orka breytist með álagi. Notaðu með Orkuþyngd."
|
||||
}
|
||||
},
|
||||
"setting_group": {
|
||||
@@ -1766,6 +1820,68 @@
|
||||
},
|
||||
"pg_sweep": {
|
||||
"optimize": "Bestun: {param}"
|
||||
},
|
||||
"pg_detail": {
|
||||
"simulate": "Herma eftir lotu"
|
||||
},
|
||||
"split": {
|
||||
"apply": "Skipti lotu upp"
|
||||
},
|
||||
"trim": {
|
||||
"apply": "Klippi lotu til"
|
||||
},
|
||||
"merge": {
|
||||
"apply": "Sameina lotur"
|
||||
},
|
||||
"rebuild": {
|
||||
"envelopes": "Endurreikna aflhjúpa"
|
||||
}
|
||||
},
|
||||
"setup": {
|
||||
"hdr": {
|
||||
"card": "Uppsetning tækis",
|
||||
"healthy_chip": "Uppsetningu lokið"
|
||||
},
|
||||
"phase0": {
|
||||
"washer": "WashData greinir nú þegar lotur þínar. Taktu upp fyrstu lotuna til að virkja forritsheiti 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."
|
||||
},
|
||||
"phase1b": {
|
||||
"recorded": "Upptakan þín var vistuð sem {profile_name}. Taktu nú upp eða merktu önnur algeng forrit þí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."
|
||||
},
|
||||
"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?"
|
||||
},
|
||||
"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."
|
||||
},
|
||||
"phase4": {
|
||||
"healthy": "Þetta tæki er að fullu sett upp ({profile_count} snið)."
|
||||
},
|
||||
"cta": {
|
||||
"start_recording": "Byrjaðu upptöku",
|
||||
"label_detected_cycle": "Ég er nú þegar með greinda lotu – merkja hana í staðinn",
|
||||
"browse_cycles": "Skoðaðu lotur til að merkja aðra",
|
||||
"view_profiles": "Skoðaðu snið þín",
|
||||
"create_from_cluster": "Búa til snið úr þessum lotum",
|
||||
"create_profile": "Búðu til snið fyrir hana",
|
||||
"review_suggestions": "Yfirfara tillögur",
|
||||
"organise_profiles": "Skipuleggja snið",
|
||||
"configure_phases": "Stilla fasa",
|
||||
"skip_step": "Sleppa þessu skrefi",
|
||||
"skip_forever": "Sýna ekki aftur",
|
||||
"hide_guidance": "Fela leiðbeiningar",
|
||||
"show_guidance": "Sýna leiðbeiningar"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
"on_cycle_finished": "Il ciclo è terminato",
|
||||
"on_cycle_started": "Il ciclo è iniziato",
|
||||
"pause_cycle": "Pausa",
|
||||
"pause_cycle_tip": "Metti in pausa il ciclo in corso — l'elettrodomestico riprenderà da dove si era fermato",
|
||||
"pause_cycle_tip": "Metti in pausa il ciclo in corso – l'elettrodomestico riprenderà da dove si era fermato",
|
||||
"pg_apply_device": "Applica al dispositivo",
|
||||
"pg_autofill": "Compilazione automatica",
|
||||
"play": "Riproduci",
|
||||
@@ -97,8 +97,8 @@
|
||||
"process_tip": "Salva la traccia registrata come profilo nuovo o esistente",
|
||||
"rebuild": "Ricostruisci le buste",
|
||||
"rebuild_envelope": "Ricostruisci la busta",
|
||||
"rebuild_tip": "Ricalcola la busta di potenza attesa (banda min/max) per tutti i profili dai loro cicli etichettati — eseguire dopo aver etichettato nuovi cicli o corretto quelli esistenti",
|
||||
"rec_start_tip": "Avvia la registrazione della traccia di potenza dell'elettrodomestico — avvia appena prima di eseguire un ciclo",
|
||||
"rebuild_tip": "Ricalcola la busta di potenza attesa (banda min/max) per tutti i profili dai loro cicli etichettati – eseguire dopo aver etichettato nuovi cicli o corretto quelli esistenti",
|
||||
"rec_start_tip": "Avvia la registrazione della traccia di potenza dell'elettrodomestico – avvia appena prima di eseguire un ciclo",
|
||||
"rec_stop": "Fermare",
|
||||
"rec_stop_tip": "Ferma la registrazione e mantieni la traccia acquisita per la revisione",
|
||||
"record": "Inizia a registrare",
|
||||
@@ -182,7 +182,7 @@
|
||||
},
|
||||
"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.",
|
||||
"settings_banner": "{n} conflitto{s} nelle impostazioni – 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})",
|
||||
@@ -451,9 +451,9 @@
|
||||
"show_expected": "Mostra sovrapposizione curva prevista (profilo corrispondente, arancione)",
|
||||
"show_raw": "Mostra l'interruttore del segnale grezzo della presa nel grafico di potenza in tempo reale",
|
||||
"sparkline": "Andamento recente durata cicli",
|
||||
"stage2": "Fase 2 — somiglianza di base",
|
||||
"stage3": "Fase 3 — DTW",
|
||||
"stage4": "Fase 4 — concordanza",
|
||||
"stage2": "Fase 2 – somiglianza di base",
|
||||
"stage3": "Fase 3 – DTW",
|
||||
"stage4": "Fase 4 – concordanza",
|
||||
"status": "Stato",
|
||||
"tail_trim": "Taglio(i) di coda",
|
||||
"timer_auto_pause": "Pausa automatica",
|
||||
@@ -561,7 +561,12 @@
|
||||
"flags": "Indicatori",
|
||||
"include_phase_map": "Includi mappa delle fasi",
|
||||
"include_settings": "Includi impostazioni di rilevamento e riconoscimento",
|
||||
"show_contributor": "Mostra i nomi dei collaboratori"
|
||||
"show_contributor": "Mostra i nomi dei collaboratori",
|
||||
"task_pg_detail": "Simula ciclo",
|
||||
"task_split": "Divisione del ciclo",
|
||||
"task_trim": "Ritaglio del ciclo",
|
||||
"task_merge": "Unione dei cicli",
|
||||
"task_rebuild": "Ricostruzione degli inviluppi"
|
||||
},
|
||||
"log": {
|
||||
"all_levels": "Tutti i livelli",
|
||||
@@ -645,7 +650,7 @@
|
||||
"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.",
|
||||
"artifact_header": "{n} anomalie rilevate durante questo ciclo",
|
||||
"artifact_pause_detail": "La potenza è scesa quasi a zero per ~{n}s poi è ripresa — probabilmente la porta è stata aperta a metà ciclo o il ciclo è stato messo in pausa.",
|
||||
"artifact_pause_detail": "La potenza è scesa quasi a zero per ~{n}s poi è ripresa – probabilmente la porta è stata aperta a metà ciclo o il ciclo è stato messo in pausa.",
|
||||
"artifact_spike_detail": "Ha superato la banda di potenza normale per ~{n}s.",
|
||||
"auto_label_intro": "Assegnare profili a cicli senza etichetta la cui confidenza di corrispondenza supera la soglia.",
|
||||
"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.",
|
||||
@@ -654,10 +659,10 @@
|
||||
"collecting_data": "Raccolta dati - ancora {need} ciclo{plural} prima che l'ottimizzazione possa iniziare ({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",
|
||||
"compare_selected_cycles": "Cicli selezionati (fissi) – mostra/nascondi",
|
||||
"consider_new_profile": "Valuta la possibilità di creare un nuovo profilo.",
|
||||
"coverage_gap": "i cicli recenti non hanno un profilo corrispondente ({pct}% degli ultimi 30).",
|
||||
"coverage_gap_similar_cycles": "{count} cicli simili senza etichetta trovati — crea un profilo per iniziare a trovare corrispondenze.",
|
||||
"coverage_gap_similar_cycles": "{count} cicli simili senza etichetta trovati – crea un profilo per iniziare a trovare corrispondenze.",
|
||||
"cycles_deleted": "{count} ciclo/i eliminato/i",
|
||||
"enough_data": "Dati sufficienti per apprendere ({current}/{min} cicli).",
|
||||
"export_description": "Esporta tutti i profili e i cicli in JSON o ripristina da un'esportazione precedente.",
|
||||
@@ -686,7 +691,7 @@
|
||||
"ml_learned_intro": "Modelli ottimizzati per questa macchina.",
|
||||
"ml_loading": "caricamento ML...",
|
||||
"ml_settings_intro": "Due interruttori indipendenti: uno applica i modelli durante l'esecuzione di un ciclo, l'altro consente a WashData di adattarli alla tua macchina nel tempo.",
|
||||
"name_first_program": "Hai cicli sufficienti — assegna un nome al tuo primo programma per iniziare l'abbinamento.",
|
||||
"name_first_program": "Hai cicli sufficienti – assegna un nome al tuo primo programma per iniziare l'abbinamento.",
|
||||
"near_duplicate_cluster": "rilevato cluster di profili quasi duplicati. Il raggruppamento consente all'abbinamento di scegliere in modo affidabile tra sosia (ad esempio lo stesso programma a temperatura/centrifuga diversa).",
|
||||
"no_cycles_match": "Nessun ciclo corrisponde al filtro corrente.",
|
||||
"no_cycles_profile": "Nessun ciclo per questo profilo.",
|
||||
@@ -713,7 +718,7 @@
|
||||
"notify_services_hint": "Usa gli ID servizio {entity} (separati da virgole per più servizi). Variabili del modello: {vars}.",
|
||||
"old_actions_warning": "Configurato con il vecchio editor delle azioni (ora rimosso). Si attivano ancora durante gli eventi del ciclo ma non possono più essere modificati qui. Convertili in una normale automazione o rimuovili.",
|
||||
"onboarding_progress": "{n} / 3 cicli osservati",
|
||||
"onboarding_watching": "Usa l'elettrodomestico normalmente — WashData sta osservando. Dopo 3 cicli inizierà l'abbinamento dei programmi.",
|
||||
"onboarding_watching": "Usa l'elettrodomestico normalmente – WashData sta osservando. Dopo 3 cicli inizierà l'abbinamento dei programmi.",
|
||||
"pending_feedback": "In attesa di feedback sul rilevamento",
|
||||
"performance_trend": "Andamento delle prestazioni ({n} cicli)",
|
||||
"pg_analysis_empty": "Carica un ciclo per vedere l'analisi di abbinamento.",
|
||||
@@ -763,7 +768,7 @@
|
||||
"setting_changed": "Modificato da {old} a {new} il {date}",
|
||||
"settings_basic_note": "Vengono mostrate le impostazioni essenziali. Passa ad Avanzato per l'elenco completo.",
|
||||
"shape_drift_advisory": "⚠ Forma in deriva",
|
||||
"shape_drift_detail": "Il profilo di potenza per questo profilo è cambiato nel tempo — possibile usura dell'apparecchio o manutenzione necessaria (es. decalcificazione, pulizia del filtro).",
|
||||
"shape_drift_detail": "Il profilo di potenza per questo profilo è cambiato nel tempo – possibile usura dell'apparecchio o manutenzione necessaria (es. decalcificazione, pulizia del filtro).",
|
||||
"show_all_settings": "Mostra tutte le impostazioni",
|
||||
"showing_suggestions": "Visualizzazione dell'impostazione {count} con suggerimenti.",
|
||||
"split_intro": "Fare clic sul grafico per aggiungere o rimuovere un punto di divisione o per rilevare automaticamente gli spazi inattivi. Ogni segmento risultante può ottenere il proprio profilo.",
|
||||
@@ -789,10 +794,10 @@
|
||||
"toast_revert_failed": "Ripristino fallito: {error}",
|
||||
"toast_reverted": "{key} ripristinato",
|
||||
"toast_save_failed": "Salvataggio fallito: {error}",
|
||||
"trend_duration_longer": "Durata tendenzialmente più lunga ({pct}%/ciclo) — media recente {avg}",
|
||||
"trend_duration_shorter": "La durata tendenzialmente è più breve ({pct}%/ciclo) — media recente {avg}",
|
||||
"trend_duration_longer": "Durata tendenzialmente più lunga ({pct}%/ciclo) – media recente {avg}",
|
||||
"trend_duration_shorter": "La durata tendenzialmente è più breve ({pct}%/ciclo) – media recente {avg}",
|
||||
"trend_energy_down": "Energia in diminuzione ({pct}%/ciclo)",
|
||||
"trend_energy_up": "Energia in aumento ({pct}%/ciclo) — media recente {avg}",
|
||||
"trend_energy_up": "Energia in aumento ({pct}%/ciclo) – media recente {avg}",
|
||||
"trim_intro": "Trascina le maniglie rosse o inserisci i valori. Tutto fuori dalla finestra viene rimosso.",
|
||||
"tuning_suggestions_available": "{count} suggerimento di ottimizzazione disponibile dai cicli osservati. Appaiono accanto ai campi pertinenti.",
|
||||
"unsure_detected_prefix": "WashData non è sicuro di averlo rilevato",
|
||||
@@ -857,7 +862,9 @@
|
||||
"share_guidelines_title": "Prima di condividere",
|
||||
"store_download_device_intro": "Adotta ogni programma condiviso e i suoi cicli di riferimento sul tuo dispositivo. I tuoi cicli registrati e le tue statistiche non vengono modificati.",
|
||||
"store_share_device_intro": "Carica {brand} {model} con i cicli di riferimento che selezioni. Altri con lo stesso elettrodomestico possono adottare i tuoi programmi. Le voci vengono revisionate prima di apparire pubblicamente.",
|
||||
"share_profile_no_cycles": "Nessun ciclo di riferimento -- contrassegna un ciclo come ⭐ nella scheda Cicli per includere questo profilo"
|
||||
"share_profile_no_cycles": "Nessun ciclo di riferimento -- contrassegna un ciclo come ⭐ nella scheda Cicli per includere questo profilo",
|
||||
"advisory_phase_inconsistent": "'{name}' sembra mescolare programmi o temperature diversi - i suoi cicli riscaldano per intervalli di tempo molto diversi. Dividerlo in profili separati (ad es. per temperatura) migliorerà la corrispondenza e le stime dei tempi.",
|
||||
"advisory_phase_inconsistent_title": "⚠ Possibili programmi misti"
|
||||
},
|
||||
"pg_desc": {
|
||||
"abrupt_drop_watts": "Calo improvviso trattato come fine immediata",
|
||||
@@ -869,12 +876,19 @@
|
||||
"start_duration_threshold": "Secondi sopra la soglia per confermare l'avvio",
|
||||
"start_threshold_w": "Watt minimi per contare come avviato",
|
||||
"stop_threshold_w": "Al di sotto, la macchina è considerata spenta",
|
||||
"dtw_bandwidth": "Quanta deformazione temporale consente la corrispondenza della forma",
|
||||
"corr_weight": "Peso della forma della curva rispetto al livello di potenza nella corrispondenza",
|
||||
"duration_weight": "Quanto la concordanza della durata influisce sulla corrispondenza",
|
||||
"energy_weight": "Quanto la concordanza dell'energia influisce sulla corrispondenza",
|
||||
"profile_match_min_duration_ratio": "Ciclo più breve (rispetto al profilo) che può ancora corrispondere",
|
||||
"profile_match_max_duration_ratio": "Ciclo più lungo (rispetto al profilo) che può ancora corrispondere"
|
||||
"dtw_bandwidth": "Fase 3: banda di deformazione Sakoe-Chiba (0 = DTW disattivato; predefinito 0,2 = 20% della lunghezza del ciclo)",
|
||||
"corr_weight": "Fase 2: equilibrio tra forma della curva (correlazione) e livello di potenza (MAE); predefinito 0,45",
|
||||
"duration_weight": "Fase 4: quanto la concordanza di durata influisce sul punteggio finale (predefinito 0,22)",
|
||||
"energy_weight": "Fase 4: quanto la concordanza di energia influisce sul punteggio finale (predefinito 0,22)",
|
||||
"profile_match_min_duration_ratio": "Fase 1: durata minima del ciclo come frazione della durata del profilo; predefinito 0,1 (10%)",
|
||||
"profile_match_max_duration_ratio": "Fase 1: durata massima del ciclo come frazione della durata del profilo; predefinito 1,5 (150%)",
|
||||
"keep_min_score": "Fase 2: punteggio minimo per restare in gara; il predefinito 0,1 ammette candidati deboli, le fasi successive scelgono il migliore",
|
||||
"dtw_blend": "Fase 3: 0 = solo punteggio centrale, 1 = solo punteggio DTW, 0,5 = mix equilibrato (predefinito)",
|
||||
"dtw_ensemble_w": "Fase 3 (modalità ensemble): peso su L1 scalato rispetto a DTW derivato; il predefinito 0,7 favorisce la sensibilità al livello",
|
||||
"dtw_ddtw_scale": "Fase 3: distanza di semi-saturazione DDTW; minore = maggiore sensibilità alla forma (predefinito 30)",
|
||||
"dtw_refine_top_n": "Fase 3: candidati rivalutati da DTW; aumentare a 7-9 se il profilo corretto si classifica 4°-5° (predefinito 5)",
|
||||
"duration_scale": "Fase 4: log-rapporto in cui la concordanza di durata si dimezza; minore = penalità più severa (predefinito 0,175)",
|
||||
"energy_scale": "Fase 4: log-rapporto in cui la concordanza di energia si dimezza; minore = penalità più severa (predefinito 0,25)"
|
||||
},
|
||||
"phase_desc": {
|
||||
"anti_crease": "Brevi tumble occasionali dopo il completamento per ridurre le grinze del bucato.",
|
||||
@@ -957,6 +971,10 @@
|
||||
"triggers": {
|
||||
"intro": "Segnali esterni opzionali: un trigger di fine, un sensore di porta, un interruttore di pausa e il promemoria di scarico.",
|
||||
"label": "Trigger e porte"
|
||||
},
|
||||
"phase_eta": {
|
||||
"label": "Tempo rimanente",
|
||||
"intro": "Tempo rimanente in base alle fasi, per le macchine la cui durata del ciclo dipende dalla temperatura o dalla centrifuga."
|
||||
}
|
||||
},
|
||||
"setting": {
|
||||
@@ -1040,6 +1058,10 @@
|
||||
"doc": "Prezzo fisso per kWh utilizzato per i dati sui costi quando non è impostata alcuna entità di prezzo in tempo reale sopra.",
|
||||
"label": "Prezzo energia statico (per kWh)"
|
||||
},
|
||||
"energy_sensor": {
|
||||
"doc": "Contatore di energia cumulativa opzionale (total_increasing in kWh/Wh, ad es. il contatore di consumo totale della presa stessa). Quando è impostato, l'energia riportata di ogni ciclo viene ricavata dalla differenza di questo contatore tra inizio e fine, il che evita la sottostima che si ottiene integrando un sensore di potenza che aggiorna lentamente. Ripiega sul valore integrato se la lettura manca, se la sua unità è sconosciuta o se il delta non è positivo. Lascia vuoto per continuare a integrare il sensore di potenza.",
|
||||
"label": "Entità del contatore di energia"
|
||||
},
|
||||
"expose_debug_entities": {
|
||||
"doc": "Pubblica entità HA diagnostiche aggiuntive (confidenza della corrispondenza, ambiguità, stati interni). Disattivato mantiene l'elenco delle entità pulito per l'uso normale.",
|
||||
"label": "Esponi entità di debug"
|
||||
@@ -1322,6 +1344,38 @@
|
||||
},
|
||||
"show_contributor": {
|
||||
"doc": "Mostra l'attribuzione \"di <collaboratore>\" sugli elettrodomestici della community e sui cicli di riferimento."
|
||||
},
|
||||
"enable_phase_matching": {
|
||||
"label": "Tempo rimanente in base alle fasi",
|
||||
"doc": "Suddivide ogni ciclo in corso in fasi (riscaldamento, lavaggio, centrifuga) e distribuisce il tempo rimanente per fase, combinato con la stima classica - basandosi sulla ripartizione per fasi all'inizio del ciclo e sulla stima classica verso la fine. Questo personalizza il conto alla rovescia in base a quanto la tua macchina riscalda e funziona realmente, cosa più evidente nella prima metà di un ciclo. Disattivato = solo la stima classica. È interessata solo la visualizzazione del tempo rimanente; la corrispondenza dei programmi e il rilevamento dei cicli restano invariati."
|
||||
},
|
||||
"keep_min_score": {
|
||||
"label": "Score min corrispondenza",
|
||||
"doc": "Punteggio di similarità minimo che un candidato deve avere per restare in gara. Il predefinito 0,1 è volutamente permissivo - ammette anche candidati deboli e si affida alle fasi successive per trovare la migliore corrispondenza. Aumentarlo per eliminare prima i profili improbabili; ridurlo per ampliare il pool iniziale di candidati."
|
||||
},
|
||||
"dtw_blend": {
|
||||
"label": "Fusione Warp",
|
||||
"doc": "Quanto il punteggio di allineamento per deformazione temporale (DTW) sostituisce il punteggio centrale della fase 2. 0 = usa solo il punteggio della fase 2, 1 = usa solo il punteggio DTW, 0,5 (predefinito) = mix equilibrato. Aumentarlo per affidarsi maggiormente all'allineamento Warp quando i programmi hanno livelli di potenza simili ma schemi temporali diversi."
|
||||
},
|
||||
"dtw_ensemble_w": {
|
||||
"label": "Mix Warp ensemble",
|
||||
"doc": "In modalità DTW ensemble (la predefinita), il peso su L1 scalato rispetto a DTW derivato (DDTW). 1,0 = solo L1 scalato, 0 = solo DDTW, 0,7 = predefinito. La variante L1 scalata confronta i livelli di potenza; la variante derivata reagisce a come la potenza cambia nel tempo. Ensemble li combina entrambi."
|
||||
},
|
||||
"dtw_ddtw_scale": {
|
||||
"label": "Scala Warp derivata",
|
||||
"doc": "Distanza di semi-saturazione per la valutazione DTW derivata. Il punteggio si dimezza quando la distanza DDTW è uguale a questo valore. Minore = maggiore sensibilità alle differenze di forma. Il predefinito 30 è calibrato su tracce di potenza tipiche degli elettrodomestici. Influisce solo sulle modalità DTW ensemble e ddtw."
|
||||
},
|
||||
"dtw_refine_top_n": {
|
||||
"label": "Conteggio affinamento Warp",
|
||||
"doc": "Quanti candidati principali della fase 2 vengono rivalutati da DTW. DTW è più costoso, quindi viene applicato solo agli N migliori candidati. Predefinito 5. Aumentarlo (a 7-9) se il profilo corretto a volte raggiunge solo il 4° o 5° posto dopo la fase 2 - DTW può recuperarlo. Ridurlo velocizza leggermente il matching."
|
||||
},
|
||||
"duration_scale": {
|
||||
"label": "Nitidezza durata",
|
||||
"doc": "Precisione della penalità di concordanza di durata nella fase 4. È il log-rapporto in cui il punteggio di concordanza si dimezza. Minore = più severo: una discordanza di durata penalizza di più. Il predefinito 0,175 corrisponde a circa il 18% di tolleranza di durata a metà peso. Combinare con Peso durata."
|
||||
},
|
||||
"energy_scale": {
|
||||
"label": "Nitidezza energia",
|
||||
"doc": "Precisione della penalità di concordanza di energia. Minore = più severo: una discordanza di energia penalizza di più. Il predefinito 0,25 è intenzionalmente più indulgente della Precisione di durata, perché l'energia varia con il carico. Combinare con Peso energia."
|
||||
}
|
||||
},
|
||||
"setting_group": {
|
||||
@@ -1570,24 +1624,24 @@
|
||||
"lower": "Etichetta più cicli automaticamente; alcuni possono essere mal identificati"
|
||||
},
|
||||
"duration_tolerance": {
|
||||
"higher": "Accetta un intervallo di durata più ampio — corrispondenza più flessibile",
|
||||
"lower": "Richiede una durata più vicina — più rigoroso, può rifiutare cicli insoliti"
|
||||
"higher": "Accetta un intervallo di durata più ampio – corrispondenza più flessibile",
|
||||
"lower": "Richiede una durata più vicina – più rigoroso, può rifiutare cicli insoliti"
|
||||
},
|
||||
"end_energy_threshold": {
|
||||
"higher": "Chiude solo i cicli che hanno consumato energia sostanziale",
|
||||
"lower": "Chiude anche cicli brevi o a basso consumo energetico"
|
||||
},
|
||||
"end_repeat_count": {
|
||||
"higher": "Richiede che il segnale di fine si ripeta più volte — più robusto, leggermente più lento",
|
||||
"lower": "Termina dopo meno ripetizioni — rilevamento più rapido, maggior rischio di fine falsa"
|
||||
"higher": "Richiede che il segnale di fine si ripeta più volte – più robusto, leggermente più lento",
|
||||
"lower": "Termina dopo meno ripetizioni – rilevamento più rapido, maggior rischio di fine falsa"
|
||||
},
|
||||
"learning_confidence": {
|
||||
"higher": "Impara solo da corrispondenze molto affidabili — più lento ma più preciso",
|
||||
"higher": "Impara solo da corrispondenze molto affidabili – più lento ma più preciso",
|
||||
"lower": "Impara da più cicli; il modello potrebbe essere meno preciso"
|
||||
},
|
||||
"min_off_gap": {
|
||||
"higher": "Richiede più tempo di inattività prima di avviare un nuovo ciclo",
|
||||
"lower": "Una breve inattività avvia un nuovo ciclo — esecuzioni consecutive possono dividersi"
|
||||
"lower": "Una breve inattività avvia un nuovo ciclo – esecuzioni consecutive possono dividersi"
|
||||
},
|
||||
"min_power": {
|
||||
"higher": "Meno sensibile al consumo in standby; potrebbe non rilevare programmi a bassa potenza",
|
||||
@@ -1598,24 +1652,24 @@
|
||||
"lower": "Interrompe prima un ciclo bloccato"
|
||||
},
|
||||
"off_delay": {
|
||||
"higher": "Più tempo per le pause dell'elettrodomestico — gestisce lunghe fasi di ammollo o asciugatura",
|
||||
"lower": "Rilevamento della fine più rapido — ideale per elettrodomestici con on/off netto"
|
||||
"higher": "Più tempo per le pause dell'elettrodomestico – gestisce lunghe fasi di ammollo o asciugatura",
|
||||
"lower": "Rilevamento della fine più rapido – ideale per elettrodomestici con on/off netto"
|
||||
},
|
||||
"profile_match_threshold": {
|
||||
"higher": "Conferma solo le corrispondenze ad alta affidabilità; più cicli rimangono senza etichetta",
|
||||
"lower": "Corrisponde a più cicli; alcuni potrebbero essere leggermente errati"
|
||||
},
|
||||
"running_dead_zone": {
|
||||
"higher": "Ignora brevi picchi di potenza durante il riposo — meno sensibile al rumore",
|
||||
"lower": "Risponde a impulsi più brevi — rileva attività transitorie rapide"
|
||||
"higher": "Ignora brevi picchi di potenza durante il riposo – meno sensibile al rumore",
|
||||
"lower": "Risponde a impulsi più brevi – rileva attività transitorie rapide"
|
||||
},
|
||||
"start_threshold_w": {
|
||||
"higher": "Evita avvii falsi causati da brevi picchi di potenza",
|
||||
"lower": "Rileva programmi a bassa potenza; può attivarsi con il rumore"
|
||||
},
|
||||
"stop_threshold_w": {
|
||||
"higher": "Termina il ciclo prima — potrebbe chiudersi durante una pausa",
|
||||
"lower": "Attende più a lungo per terminare — meno completamenti prematuri"
|
||||
"higher": "Termina il ciclo prima – potrebbe chiudersi durante una pausa",
|
||||
"lower": "Attende più a lungo per terminare – meno completamenti prematuri"
|
||||
},
|
||||
"watchdog_interval": {
|
||||
"higher": "Fasi silenziose più lunghe consentite; meno false fermate forzate",
|
||||
@@ -1766,6 +1820,69 @@
|
||||
},
|
||||
"pg_sweep": {
|
||||
"optimize": "Ottimizza: {param}"
|
||||
},
|
||||
"pg_detail": {
|
||||
"simulate": "Simula ciclo"
|
||||
},
|
||||
"split": {
|
||||
"apply": "Divisione del ciclo"
|
||||
},
|
||||
"trim": {
|
||||
"apply": "Ritaglio del ciclo"
|
||||
},
|
||||
"merge": {
|
||||
"apply": "Unione dei cicli"
|
||||
},
|
||||
"rebuild": {
|
||||
"envelopes": "Ricostruzione degli inviluppi"
|
||||
},
|
||||
"cancelling": "Annullamento..."
|
||||
},
|
||||
"setup": {
|
||||
"hdr": {
|
||||
"card": "Configurazione dispositivo",
|
||||
"healthy_chip": "Configurazione completata"
|
||||
},
|
||||
"phase0": {
|
||||
"washer": "WashData sta già rilevando i tuoi cicli. Registra il tuo primo ciclo per abilitare i nomi dei programmi e le stime dei tempi.",
|
||||
"dishwasher": "WashData sta monitorando. Le lavastoviglie hanno cicli complessi – è vivamente consigliato registrare il primo ciclo. Se un ciclo rilevato dura troppo a lungo, usa l'editor dei cicli per ritagliarlo prima di salvarlo come profilo.",
|
||||
"generic": "WashData sta monitorando. Registra o etichetta un ciclo rilevato per iniziare a creare profili."
|
||||
},
|
||||
"phase1a": {
|
||||
"labelled": "Buon inizio – il tuo primo programma è salvato. Per dati più precisi, considera di registrare il prossimo ciclo con il widget di registrazione."
|
||||
},
|
||||
"phase1b": {
|
||||
"recorded": "La tua registrazione è stata salvata come {profile_name}. Ora registra o etichetta gli altri programmi che usi di solito per ampliare la copertura."
|
||||
},
|
||||
"phase1c": {
|
||||
"verify": "Hai {count} programmi dalla community. Esegui un ciclo per verificare che WashData li riconosca correttamente – l'abbinamento migliorerà man mano che il dispositivo accumula il proprio storico."
|
||||
},
|
||||
"phase2": {
|
||||
"cluster": "WashData ha rilevato {count} cicli che non corrispondono a nessun programma salvato – si assomigliano tra loro. Vuoi creare un nuovo profilo per essi?",
|
||||
"unmatched": "L'ultimo ciclo non ha corrisposto a nessun programma salvato. È un nuovo programma?"
|
||||
},
|
||||
"phase3": {
|
||||
"suggestions": "WashData ha raccomandazioni sulle impostazioni basate sulla cronologia dei cicli – revisionale per migliorare la precisione di rilevamento.",
|
||||
"groups": "Alcuni dei tuoi profili sembrano lo stesso programma a temperature diverse. Organizzali in un gruppo per un abbinamento più affidabile.",
|
||||
"phases": "Aggiungi le fasi del programma a {profile_name} per stime più accurate del tempo rimanente."
|
||||
},
|
||||
"phase4": {
|
||||
"healthy": "Questo dispositivo è completamente configurato ({profile_count} profili)."
|
||||
},
|
||||
"cta": {
|
||||
"start_recording": "Avvia registrazione",
|
||||
"label_detected_cycle": "Ho già un ciclo rilevato – etichettalo invece",
|
||||
"browse_cycles": "Sfoglia i cicli per etichettarne un altro",
|
||||
"view_profiles": "Visualizza i tuoi profili",
|
||||
"create_from_cluster": "Crea profilo da questi cicli",
|
||||
"create_profile": "Crea un profilo per questo programma",
|
||||
"review_suggestions": "Rivedi i suggerimenti",
|
||||
"organise_profiles": "Organizza i profili",
|
||||
"configure_phases": "Configura le fasi",
|
||||
"skip_step": "Salta questo passaggio",
|
||||
"skip_forever": "Non mostrare più",
|
||||
"hide_guidance": "Nascondi guida",
|
||||
"show_guidance": "Mostra guida"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"badge": {
|
||||
"artifact_tip": "{n} 個の異常が検出されました (例: サイクルの途中でドアが開いた) — 開いてグラフ上で確認します",
|
||||
"artifact_tip": "{n} 個の異常が検出されました (例: サイクルの途中でドアが開いた) – 開いてグラフ上で確認します",
|
||||
"auto": "(自動検出)",
|
||||
"built_in_tag": "内蔵",
|
||||
"declining": "↘ 減少",
|
||||
@@ -87,7 +87,7 @@
|
||||
"on_cycle_finished": "サイクルが終了しました",
|
||||
"on_cycle_started": "サイクル開始時",
|
||||
"pause_cycle": "一時停止",
|
||||
"pause_cycle_tip": "実行中のサイクルを一時停止します — 家電は停止した場所から再開します",
|
||||
"pause_cycle_tip": "実行中のサイクルを一時停止します – 家電は停止した場所から再開します",
|
||||
"pg_apply_device": "デバイスに適用",
|
||||
"pg_autofill": "自動入力",
|
||||
"play": "再生",
|
||||
@@ -97,8 +97,8 @@
|
||||
"process_tip": "録音されたトレースを新しいまたは既存のプロファイルとして保存します",
|
||||
"rebuild": "エンベロープを再構築する",
|
||||
"rebuild_envelope": "エンベロープの再構築",
|
||||
"rebuild_tip": "ラベル付きサイクルからすべてのプロファイルの予想電力エンベロープ(最小/最大バンド)を再計算します — 新しいサイクルにラベルを付けた後や古いラベルを修正した後に実行します",
|
||||
"rec_start_tip": "家電の電力トレースの録音を開始します — サイクルを実行する直前に開始します",
|
||||
"rebuild_tip": "ラベル付きサイクルからすべてのプロファイルの予想電力エンベロープ(最小/最大バンド)を再計算します – 新しいサイクルにラベルを付けた後や古いラベルを修正した後に実行します",
|
||||
"rec_start_tip": "家電の電力トレースの録音を開始します – サイクルを実行する直前に開始します",
|
||||
"rec_stop": "停止",
|
||||
"rec_stop_tip": "録音を停止し、キャプチャされたトレースをレビューのために保持します",
|
||||
"record": "録音を開始する",
|
||||
@@ -231,7 +231,7 @@
|
||||
"interval": "サンプリング間隔 ({si} 秒) の少なくとも 2 倍である必要があります",
|
||||
"sampling": "サンプリング間隔はウォッチドッグ間隔 ({wi} 秒) の半分以下である必要があります"
|
||||
},
|
||||
"settings_banner": "{n} 件の設定競合{s} — 強調表示されたセクションを確認し、保存前に修正してください。",
|
||||
"settings_banner": "{n} 件の設定競合{s} – 強調表示されたセクションを確認し、保存前に修正してください。",
|
||||
"settings_banner_btn": "最初へ"
|
||||
},
|
||||
"hdr": {
|
||||
@@ -451,9 +451,9 @@
|
||||
"show_expected": "予想される曲線オーバーレイを表示 (一致したプロファイル、オレンジ色)",
|
||||
"show_raw": "ライブ電力グラフに生ソケット切替を表示",
|
||||
"sparkline": "最近のサイクル継続時間の傾向",
|
||||
"stage2": "ステージ 2 — コア類似度",
|
||||
"stage3": "ステージ 3 — DTW",
|
||||
"stage4": "ステージ 4 — 一致度",
|
||||
"stage2": "ステージ 2 – コア類似度",
|
||||
"stage3": "ステージ 3 – DTW",
|
||||
"stage4": "ステージ 4 – 一致度",
|
||||
"status": "状態",
|
||||
"tail_trim": "テールトリム (複数可)",
|
||||
"timer_auto_pause": "自動一時停止",
|
||||
@@ -561,7 +561,12 @@
|
||||
"flags": "フラグ",
|
||||
"include_phase_map": "フェーズマップを含める",
|
||||
"include_settings": "検出・マッチング設定を含める",
|
||||
"show_contributor": "投稿者名を表示"
|
||||
"show_contributor": "投稿者名を表示",
|
||||
"task_pg_detail": "サイクルをシミュレート",
|
||||
"task_split": "サイクルを分割中",
|
||||
"task_trim": "サイクルをトリミング中",
|
||||
"task_merge": "サイクルを結合中",
|
||||
"task_rebuild": "エンベロープを再構築中"
|
||||
},
|
||||
"log": {
|
||||
"all_levels": "すべてのレベル",
|
||||
@@ -654,10 +659,10 @@
|
||||
"collecting_data": "データを収集中です。微調整を開始するにはあと {need} サイクル{plural}必要です({current}/{min})。",
|
||||
"compare_overlay_profiles": "オーバーレイプロファイル (淡い)",
|
||||
"compare_profiles_tip": "他のプロファイル エンベロープを上のチャートに重ねて、どれがこのサイクルに最も適合するかを確認します。",
|
||||
"compare_selected_cycles": "選択されたサイクル (実線) — 表示/非表示",
|
||||
"compare_selected_cycles": "選択されたサイクル (実線) – 表示/非表示",
|
||||
"consider_new_profile": "新しいプロファイルの作成を検討してください。",
|
||||
"coverage_gap": "最近のサイクルには一致するプロファイルがありません (過去 30 回の {pct}%)。",
|
||||
"coverage_gap_similar_cycles": "{count} 件の類似した未ラベルサイクルが見つかりました — プロファイルを作成してマッチングを開始してください。",
|
||||
"coverage_gap_similar_cycles": "{count} 件の類似した未ラベルサイクルが見つかりました – プロファイルを作成してマッチングを開始してください。",
|
||||
"cycles_deleted": "{count} 件のサイクルを削除しました",
|
||||
"enough_data": "学習に十分なデータがあります({current}/{min} サイクル)。",
|
||||
"export_description": "すべてのプロファイルとサイクルを JSON にエクスポートするか、以前のエクスポートから復元します。",
|
||||
@@ -686,7 +691,7 @@
|
||||
"ml_learned_intro": "本機に合わせてチューニングされたモデル。",
|
||||
"ml_loading": "ML を読み込み中…",
|
||||
"ml_settings_intro": "2 つの独立したスイッチ: 1 つはサイクルの実行中にモデルを適用し、もう 1 つは WashData が時間の経過とともにモデルをマシンに合わせて微調整します。",
|
||||
"name_first_program": "十分なサイクルがそろいました — 最初のプログラムに名前を付けて一致を開始しましょう。",
|
||||
"name_first_program": "十分なサイクルがそろいました – 最初のプログラムに名前を付けて一致を開始しましょう。",
|
||||
"near_duplicate_cluster": "ほぼ重複したプロファイル クラスターが検出されました。グループ化により、類似したもの (例: 異なる温度/スピンの同じプログラム) の間でマッチングを確実に選択できるようになります。",
|
||||
"no_cycles_match": "現在のフィルターに一致するサイクルはありません。",
|
||||
"no_cycles_profile": "このプロファイルにはサイクルがありません。",
|
||||
@@ -713,7 +718,7 @@
|
||||
"notify_services_hint": "{entity} サービス ID を使用してください(複数はカンマ区切り)。テンプレート変数:{vars}。",
|
||||
"old_actions_warning": "古いアクション エディター (現在は削除されています) で構成されています。これらは引き続きサイクル イベントで起動されますが、ここでは編集できなくなりました。それらを通常のオートメーションに変換するか、削除します。",
|
||||
"onboarding_progress": "{n} / 3 サイクルを観測",
|
||||
"onboarding_watching": "家電をいつも通り使用してください — WashData が監視しています。3 サイクル後にプログラムの一致が始まります。",
|
||||
"onboarding_watching": "家電をいつも通り使用してください – WashData が監視しています。3 サイクル後にプログラムの一致が始まります。",
|
||||
"pending_feedback": "保留中の検出フィードバック",
|
||||
"performance_trend": "パフォーマンスの傾向 ({n} サイクル)",
|
||||
"pg_analysis_empty": "マッチ分析を見るにはサイクルを読み込んでください。",
|
||||
@@ -763,7 +768,7 @@
|
||||
"setting_changed": "{date} に {old} から {new} に変更",
|
||||
"settings_basic_note": "必須の設定のみ表示しています。すべての一覧は「高度な」に切り替えてください。",
|
||||
"shape_drift_advisory": "⚠ 形状がずれています",
|
||||
"shape_drift_detail": "このプロファイルの電力パターンが時間とともに変化しました — 家電の劣化またはメンテナンスが必要な可能性があります(例:スケール除去、フィルター清掃)。",
|
||||
"shape_drift_detail": "このプロファイルの電力パターンが時間とともに変化しました – 家電の劣化またはメンテナンスが必要な可能性があります(例:スケール除去、フィルター清掃)。",
|
||||
"show_all_settings": "すべての設定を表示",
|
||||
"showing_suggestions": "{count} 設定を候補とともに表示しています。",
|
||||
"split_intro": "グラフをクリックして分割ポイントを追加または削除するか、アイドル ギャップを自動検出します。結果として得られる各セグメントは、独自のプロファイルを取得できます。",
|
||||
@@ -857,7 +862,9 @@
|
||||
"share_guidelines_title": "共有前に",
|
||||
"store_download_device_intro": "共有されたすべてのプログラムとそのリファレンスサイクルをデバイスに引き継ぎます。ご自身の記録済みサイクルと統計には影響しません。",
|
||||
"store_share_device_intro": "選択したリファレンスサイクルとともに{brand} {model}をアップロードします。同じ機器を持つ他のユーザーがあなたのプログラムを引き継ぐことができます。エントリは公開前に審査されます。",
|
||||
"share_profile_no_cycles": "リファレンスサイクルなし -- サイクルタブでサイクルを⭐としてマークしてこのプロファイルを含めてください"
|
||||
"share_profile_no_cycles": "リファレンスサイクルなし -- サイクルタブでサイクルを⭐としてマークしてこのプロファイルを含めてください",
|
||||
"advisory_phase_inconsistent": "'{name}' は異なるプログラムや温度が混在しているようです。加熱時間がサイクルごとに大きく異なります。温度ごとなど別々のプロファイルに分割すると、マッチングと時間推定が改善されます。",
|
||||
"advisory_phase_inconsistent_title": "⚠ プログラム混在の可能性"
|
||||
},
|
||||
"pg_desc": {
|
||||
"abrupt_drop_watts": "急激な低下は即時終了として扱う",
|
||||
@@ -869,12 +876,19 @@
|
||||
"start_duration_threshold": "開始を確定するしきい値超えの秒数",
|
||||
"start_threshold_w": "開始とみなす最小ワット数",
|
||||
"stop_threshold_w": "これを下回ると停止とみなす",
|
||||
"dtw_bandwidth": "形状マッチングで許容する時間ワーピングの量",
|
||||
"corr_weight": "マッチングにおける曲線形状と電力レベルの重み",
|
||||
"duration_weight": "実行時間の一致がマッチングに与える影響の大きさ",
|
||||
"energy_weight": "消費電力量の一致がマッチングに与える影響の大きさ",
|
||||
"profile_match_min_duration_ratio": "一致対象として許可される最短の運転時間(プロファイル比)",
|
||||
"profile_match_max_duration_ratio": "一致対象として許可される最長の運転時間(プロファイル比)"
|
||||
"dtw_bandwidth": "ステージ 3: Sakoe-Chiba ワープバンド (0 = DTW 無効; デフォルト 0.2 = サイクル長の 20%)",
|
||||
"corr_weight": "ステージ 2: 曲線形状(相関)と電力レベル(MAE)のバランス; デフォルト 0.45",
|
||||
"duration_weight": "ステージ 4: 運転時間の一致が最終スコアにどれだけ影響するか(デフォルト 0.22)",
|
||||
"energy_weight": "ステージ 4: エネルギーの一致が最終スコアにどれだけ影響するか(デフォルト 0.22)",
|
||||
"profile_match_min_duration_ratio": "ステージ 1: プロファイル所要時間に対するサイクルの最短許容比率; デフォルト 0.1 (10%)",
|
||||
"profile_match_max_duration_ratio": "ステージ 1: プロファイル所要時間に対するサイクルの最長許容比率; デフォルト 1.5 (150%)",
|
||||
"keep_min_score": "ステージ 2: 競合に残るための最低スコア; デフォルト 0.1 は弱い候補も許可し、後のステージが最良を選ぶ",
|
||||
"dtw_blend": "ステージ 3: 0 = コアスコアのみ、1 = DTW スコアのみ、0.5 = 等割合ブレンド(デフォルト)",
|
||||
"dtw_ensemble_w": "ステージ 3 (アンサンブルモード): スケール付き-L1 と微分 DTW の重み; デフォルト 0.7 はレベル考慮を優先",
|
||||
"dtw_ddtw_scale": "ステージ 3: DDTW 半飽和距離; 小さいほど形状に敏感(デフォルト 30)",
|
||||
"dtw_refine_top_n": "ステージ 3: DTW が再スコアリングする候補数; 正しいプロファイルが 4-5 位になる場合は 7-9 に増やす(デフォルト 5)",
|
||||
"duration_scale": "ステージ 4: 運転時間の一致スコアが半分になる対数比率; 小さいほど厳格なペナルティ(デフォルト 0.175)",
|
||||
"energy_scale": "ステージ 4: エネルギーの一致スコアが半分になる対数比率; 小さいほど厳格なペナルティ(デフォルト 0.25)"
|
||||
},
|
||||
"phase_desc": {
|
||||
"anti_crease": "メインサイクル後にドラムが断続的に回転し、衣類のシワを防止します。",
|
||||
@@ -957,6 +971,10 @@
|
||||
"triggers": {
|
||||
"intro": "オプションの外部信号:終了トリガー、ドアセンサー、一時停止スイッチ、取り出しリマインダー。",
|
||||
"label": "トリガーとドア"
|
||||
},
|
||||
"phase_eta": {
|
||||
"label": "残り時間",
|
||||
"intro": "サイクルの長さが温度や脱水に左右される機器向けの、フェーズを考慮した残り時間。"
|
||||
}
|
||||
},
|
||||
"setting": {
|
||||
@@ -1040,6 +1058,10 @@
|
||||
"doc": "上記のライブ価格エンティティが設定されていない場合、コスト数値に使用される kWh あたりの固定価格。",
|
||||
"label": "静的エネルギー価格(kWhあたり)"
|
||||
},
|
||||
"energy_sensor": {
|
||||
"doc": "積算エネルギーカウンター(total_increasing の kWh/Wh。例: プラグ自身の積算メーター)を任意で指定します。設定すると、各サイクルの表示エネルギーはこのカウンターの開始時から終了時までの差分から算出され、更新の遅い電力センサーを積分する際に生じる過少計上を回避できます。読み取り値が欠落している場合、単位が不明な場合、または差分が正でない場合は、積分値にフォールバックします。空欄のままにすると、電力センサーの積分を継続します。",
|
||||
"label": "エネルギーメーターエンティティ"
|
||||
},
|
||||
"expose_debug_entities": {
|
||||
"doc": "追加の診断 HA エンティティ (一致信頼性、曖昧性、状態内部) を公開します。オフにすると、通常の使用のためにエンティティ リストがクリーンな状態に保たれます。",
|
||||
"label": "デバッグエンティティを公開"
|
||||
@@ -1322,6 +1344,38 @@
|
||||
},
|
||||
"show_contributor": {
|
||||
"doc": "コミュニティの家電および基準サイクルに「by <contributor>」のクレジット表示をします。"
|
||||
},
|
||||
"enable_phase_matching": {
|
||||
"label": "フェーズを考慮した残り時間",
|
||||
"doc": "実行中の各サイクルをフェーズ(加熱、洗い、脱水)に分割し、フェーズごとに残り時間を見積もって従来の推定値とブレンドします。サイクルの序盤ではフェーズごとの見積もりを重視し、終盤に近づくにつれて従来の推定値を重視します。これにより、お使いの機器が実際に加熱・運転する時間に合わせてカウントダウンが調整され、サイクルの前半で最も効果が表れます。オフ = 従来の推定値のみ。影響を受けるのは残り時間の表示だけで、プログラムのマッチングとサイクル検出は変わりません。"
|
||||
},
|
||||
"keep_min_score": {
|
||||
"label": "最低マッチスコア",
|
||||
"doc": "候補がマッチング競合に残るために必要な最低類似度スコア。デフォルトの 0.1 は意図的に緩やかで、弱い候補も許可し、最良のマッチングを後のステージに委ねます。可能性の低いプロファイルを早期に除外するには値を上げ、候補プールを広げるには値を下げてください。"
|
||||
},
|
||||
"dtw_blend": {
|
||||
"label": "ワープブレンド",
|
||||
"doc": "時間ワーピング (DTW) アライメントスコアがステージ 2 コアスコアをどれほど置き換えるか。0 = ステージ 2 スコアのみ使用、1 = DTW スコアのみ使用、0.5 (デフォルト) = 等割合ブレンド。プログラムの電力レベルが似ていても時間パターンが異なる場合、ワープアライメントへの依存度を高めるために値を上げてください。"
|
||||
},
|
||||
"dtw_ensemble_w": {
|
||||
"label": "ワープアンサンブル混合",
|
||||
"doc": "アンサンブル DTW モード(デフォルト)において、スケール付き L1 と微分 DTW (DDTW) の重み配分。1.0 = スケール付き-L1 のみ、0 = DDTW のみ、0.7 = デフォルト。スケール付き-L1 変種は電力レベルを比較し、微分変種は電力がどう変化するかに反応します。アンサンブルは両者を組み合わせます。"
|
||||
},
|
||||
"dtw_ddtw_scale": {
|
||||
"label": "微分ワープスケール",
|
||||
"doc": "微分 DTW スコアリングの半飽和距離。DDTW 距離がこの値と等しいとき、スコアが半分になります。小さいほど形状の差異に敏感になります。デフォルトの 30 は一般的な家電製品の電力トレースに合わせて調整されています。アンサンブルおよび ddtw DTW モードのみに影響します。"
|
||||
},
|
||||
"dtw_refine_top_n": {
|
||||
"label": "ワープ精製候補数",
|
||||
"doc": "DTW によって再スコアリングされるステージ 2 上位候補の数。DTW は計算コストが高いため、上位 N 候補にのみ適用されます。デフォルト 5。ステージ 2 後に正しいプロファイルが 4 位または 5 位にしかならない場合は値を上げてください (7-9 程度) - DTW がそれを救えます。値を下げるとマッチングが若干速くなります。"
|
||||
},
|
||||
"duration_scale": {
|
||||
"label": "継続時間シャープネス",
|
||||
"doc": "ステージ 4 の運転時間一致ペナルティの厳格さ。一致スコアが半分になる対数比率を指します。小さいほど厳格で、時間のズレはより大きな影響を与えます。デフォルト 0.175 は半ウェイト時に約 18% の許容誤差に相当します。運転時間の重みと組み合わせて使用してください。"
|
||||
},
|
||||
"energy_scale": {
|
||||
"label": "エネルギーシャープネス",
|
||||
"doc": "ステージ 4 のエネルギー一致ペナルティの厳格さ。小さいほど厳格で、エネルギーのズレはより大きな影響を与えます。デフォルト 0.25 はエネルギーが負荷によって変動するため、時間の厳格さよりも意図的に緩やかに設定されています。エネルギーの重みと組み合わせて使用してください。"
|
||||
}
|
||||
},
|
||||
"setting_group": {
|
||||
@@ -1766,6 +1820,68 @@
|
||||
},
|
||||
"pg_sweep": {
|
||||
"optimize": "最適化: {param}"
|
||||
},
|
||||
"pg_detail": {
|
||||
"simulate": "サイクルをシミュレート"
|
||||
},
|
||||
"split": {
|
||||
"apply": "サイクルを分割中"
|
||||
},
|
||||
"trim": {
|
||||
"apply": "サイクルをトリミング中"
|
||||
},
|
||||
"merge": {
|
||||
"apply": "サイクルを結合中"
|
||||
},
|
||||
"rebuild": {
|
||||
"envelopes": "エンベロープを再構築中"
|
||||
}
|
||||
},
|
||||
"setup": {
|
||||
"hdr": {
|
||||
"card": "デバイスのセットアップ",
|
||||
"healthy_chip": "セットアップ完了"
|
||||
},
|
||||
"phase0": {
|
||||
"washer": "WashData はすでにサイクルを検出しています。プログラム名と残り時間の推定を有効にするには、最初のサイクルを記録してください。",
|
||||
"dishwasher": "WashData は監視しています。食器洗い機のサイクルは複雑です – 最初のサイクルの記録を強くお勧めします。検出されたサイクルが長すぎる場合は、プロファイルとして保存する前にサイクル編集ツールで切り詰めてください。",
|
||||
"generic": "WashData は監視しています。プロファイルの構築を始めるには、検出されたサイクルを記録またはラベル付けしてください。"
|
||||
},
|
||||
"phase1a": {
|
||||
"labelled": "良いスタートです – 最初のプログラムが保存されました。より正確なデータを得るには、レコーダーウィジェットで次のサイクルを記録することをご検討ください。"
|
||||
},
|
||||
"phase1b": {
|
||||
"recorded": "記録が {profile_name} として保存されました。カバレッジを広げるために、他のよく使うプログラムも記録またはラベル付けしてください。"
|
||||
},
|
||||
"phase1c": {
|
||||
"verify": "コミュニティから {count} 個のプログラムがあります。WashData が正しく認識するか確認するためにサイクルを実行してください – デバイスが独自の履歴を積み重ねるにつれ、マッチングが向上します。"
|
||||
},
|
||||
"phase2": {
|
||||
"cluster": "WashData は、保存されているプログラムに一致しない {count} 件のサイクルを確認しました – それらは互いに似ています。これらのための新しいプロファイルを作成しますか?",
|
||||
"unmatched": "直前のサイクルはどの保存済みプログラムにも一致しませんでした。新しいプログラムでしょうか?"
|
||||
},
|
||||
"phase3": {
|
||||
"suggestions": "WashData はサイクル履歴に基づいた設定の推奨事項があります – 検出精度を向上させるために確認してください。",
|
||||
"groups": "いくつかのプロファイルが異なる温度の同じプログラムのように見えます。より良いマッチングのためにグループに整理してください。",
|
||||
"phases": "より正確な残り時間の推定のために {profile_name} にプログラムフェーズを追加してください。"
|
||||
},
|
||||
"phase4": {
|
||||
"healthy": "このデバイスは完全にセットアップされています({profile_count} 個のプロファイル)。"
|
||||
},
|
||||
"cta": {
|
||||
"start_recording": "記録を開始",
|
||||
"label_detected_cycle": "すでに検出済みのサイクルがあります – それをラベル付けする",
|
||||
"browse_cycles": "別のサイクルをラベル付けするために閲覧する",
|
||||
"view_profiles": "プロファイルを表示",
|
||||
"create_from_cluster": "これらのサイクルからプロファイルを作成",
|
||||
"create_profile": "これのプロファイルを作成",
|
||||
"review_suggestions": "提案を確認",
|
||||
"organise_profiles": "プロファイルを整理",
|
||||
"configure_phases": "フェーズを設定",
|
||||
"skip_step": "このステップをスキップ",
|
||||
"skip_forever": "今後表示しない",
|
||||
"hide_guidance": "ガイダンスを非表示",
|
||||
"show_guidance": "ガイダンスを表示"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
"needs_review": "검토 필요",
|
||||
"overrun": "평소보다 더 오래 달렸어요",
|
||||
"poor_fit": "적합하지 않음",
|
||||
"poor_fit_tip": "일치하지 않는 일치 기록 — 이 프로필을 다시 작성하는 것이 좋습니다.",
|
||||
"poor_fit_tip": "일치하지 않는 일치 기록 – 이 프로필을 다시 작성하는 것이 좋습니다.",
|
||||
"restart_gap_tip": "{n} HA 재시작 공백: 전력 그래프에 빈 구간이 있습니다",
|
||||
"reviewed": "검토됨",
|
||||
"steady": "→ 꾸준한",
|
||||
@@ -87,7 +87,7 @@
|
||||
"on_cycle_finished": "사이클 완료됨",
|
||||
"on_cycle_started": "주기 시작됨",
|
||||
"pause_cycle": "정지시키다",
|
||||
"pause_cycle_tip": "실행 중인 사이클을 일시 중지합니다 — 기기가 중단된 지점부터 재개됩니다",
|
||||
"pause_cycle_tip": "실행 중인 사이클을 일시 중지합니다 – 기기가 중단된 지점부터 재개됩니다",
|
||||
"pg_apply_device": "장치에 적용",
|
||||
"pg_autofill": "자동 채우기",
|
||||
"play": "재생",
|
||||
@@ -97,8 +97,8 @@
|
||||
"process_tip": "기록된 트레이스를 새 프로필 또는 기존 프로필로 저장합니다",
|
||||
"rebuild": "봉투 다시 작성",
|
||||
"rebuild_envelope": "봉투 재구축",
|
||||
"rebuild_tip": "라벨이 지정된 주기에서 모든 프로필의 예상 전력 포락선(최소/최대 범위)을 다시 계산합니다 — 새 주기에 라벨을 지정하거나 기존 주기를 수정한 후 실행합니다",
|
||||
"rec_start_tip": "기기의 전력 트레이스 기록을 시작합니다 — 주기를 실행하기 직전에 시작합니다",
|
||||
"rebuild_tip": "라벨이 지정된 주기에서 모든 프로필의 예상 전력 포락선(최소/최대 범위)을 다시 계산합니다 – 새 주기에 라벨을 지정하거나 기존 주기를 수정한 후 실행합니다",
|
||||
"rec_start_tip": "기기의 전력 트레이스 기록을 시작합니다 – 주기를 실행하기 직전에 시작합니다",
|
||||
"rec_stop": "멈추다",
|
||||
"rec_stop_tip": "녹음을 중지하고 캡처된 트레이스를 검토를 위해 보관합니다",
|
||||
"record": "녹음 시작",
|
||||
@@ -231,7 +231,7 @@
|
||||
"interval": "샘플링 간격 ({si} 초)의 최소 2배이어야 합니다",
|
||||
"sampling": "샘플링 간격은 워치독 간격 ({wi} 초)의 절반 이하이어야 합니다"
|
||||
},
|
||||
"settings_banner": "{n}건의 설정 충돌{s} — 강조 표시된 섹션을 확인하고 저장 전에 수정하세요.",
|
||||
"settings_banner": "{n}건의 설정 충돌{s} – 강조 표시된 섹션을 확인하고 저장 전에 수정하세요.",
|
||||
"settings_banner_btn": "첫 번째로"
|
||||
},
|
||||
"hdr": {
|
||||
@@ -451,9 +451,9 @@
|
||||
"show_expected": "예상 곡선 오버레이 표시(일치하는 프로필, 주황색)",
|
||||
"show_raw": "라이브 전력 그래프에 원시 소켓 토글 표시",
|
||||
"sparkline": "최근 사이클 지속 시간 추세",
|
||||
"stage2": "2단계 — 핵심 유사도",
|
||||
"stage3": "3단계 — DTW",
|
||||
"stage4": "4단계 — 일치도",
|
||||
"stage2": "2단계 – 핵심 유사도",
|
||||
"stage3": "3단계 – DTW",
|
||||
"stage4": "4단계 – 일치도",
|
||||
"status": "상태",
|
||||
"tail_trim": "테일 트림(들)",
|
||||
"timer_auto_pause": "자동 일시중지",
|
||||
@@ -561,7 +561,12 @@
|
||||
"flags": "플래그",
|
||||
"include_phase_map": "페이즈 맵 포함",
|
||||
"include_settings": "감지 및 매칭 설정 포함",
|
||||
"show_contributor": "기여자 이름 표시"
|
||||
"show_contributor": "기여자 이름 표시",
|
||||
"task_pg_detail": "사이클 시뮬레이션",
|
||||
"task_split": "사이클 분할 중",
|
||||
"task_trim": "사이클 트리밍 중",
|
||||
"task_merge": "사이클 병합 중",
|
||||
"task_rebuild": "엔벨로프 재구성 중"
|
||||
},
|
||||
"log": {
|
||||
"all_levels": "모든 레벨",
|
||||
@@ -654,10 +659,10 @@
|
||||
"collecting_data": "데이터 수집 중입니다. 미세 조정을 시작하려면 {need}번의 사이클{plural}이 더 필요합니다({current}/{min})。",
|
||||
"compare_overlay_profiles": "오버레이 프로필(희미함)",
|
||||
"compare_profiles_tip": "위 차트에 다른 프로필 봉투를 겹쳐서 어느 것이 이 주기에 가장 적합한지 확인하세요.",
|
||||
"compare_selected_cycles": "선택한 주기(단색) — 표시/숨기기",
|
||||
"compare_selected_cycles": "선택한 주기(단색) – 표시/숨기기",
|
||||
"consider_new_profile": "새 프로필을 만드는 것을 고려해 보세요.",
|
||||
"coverage_gap": "최근 주기에 일치하는 프로필이 없습니다(지난 30개 중 {pct}%).",
|
||||
"coverage_gap_similar_cycles": "유사한 미라벨 사이클 {count}개를 발견했습니다 — 프로필을 만들어 매칭을 시작하세요.",
|
||||
"coverage_gap_similar_cycles": "유사한 미라벨 사이클 {count}개를 발견했습니다 – 프로필을 만들어 매칭을 시작하세요.",
|
||||
"cycles_deleted": "{count}개 사이클이 삭제되었습니다",
|
||||
"enough_data": "학습할 충분한 데이터가 있습니다({current}/{min}사이클)。",
|
||||
"export_description": "모든 프로필과 사이클을 JSON으로 내보내거나 이전 내보내기에서 복원합니다.",
|
||||
@@ -686,7 +691,7 @@
|
||||
"ml_learned_intro": "이 기계에 맞게 미세 조정된 모델입니다.",
|
||||
"ml_loading": "ML 로드 중…",
|
||||
"ml_settings_intro": "두 개의 독립적인 스위치: 하나는 사이클이 실행되는 동안 모델을 적용하고 다른 하나는 WashData가 시간이 지남에 따라 기계에 맞게 미세 조정할 수 있도록 합니다.",
|
||||
"name_first_program": "충분한 사이클이 모였습니다 — 첫 프로그램에 이름을 지정하여 일치를 시작하세요.",
|
||||
"name_first_program": "충분한 사이클이 모였습니다 – 첫 프로그램에 이름을 지정하여 일치를 시작하세요.",
|
||||
"near_duplicate_cluster": "거의 중복된 프로필 클러스터가 감지되었습니다. 그룹화를 통해 일치하는 항목을 유사 항목(예: 서로 다른 온도/회전의 동일한 프로그램) 중에서 안정적으로 선택할 수 있습니다.",
|
||||
"no_cycles_match": "현재 필터와 일치하는 사이클이 없습니다.",
|
||||
"no_cycles_profile": "이 프로필에는 사이클이 없습니다.",
|
||||
@@ -713,7 +718,7 @@
|
||||
"notify_services_hint": "{entity} 서비스 ID를 사용하세요(여러 개는 쉼표로 구분)。템플릿 변수:{vars}。",
|
||||
"old_actions_warning": "이전 작업 편집기로 구성되었습니다(현재 제거됨). 사이클 이벤트에서는 여전히 실행되지만 여기에서는 더 이상 편집할 수 없습니다. 일반 자동화로 변환하거나 제거하십시오.",
|
||||
"onboarding_progress": "{n} / 3개 사이클 관찰됨",
|
||||
"onboarding_watching": "가전을 평소처럼 사용하세요 — WashData가 관찰하고 있습니다. 3개 사이클 후 프로그램 일치가 시작됩니다.",
|
||||
"onboarding_watching": "가전을 평소처럼 사용하세요 – WashData가 관찰하고 있습니다. 3개 사이클 후 프로그램 일치가 시작됩니다.",
|
||||
"pending_feedback": "보류 중인 감지 피드백",
|
||||
"performance_trend": "실적 추세({n}주기)",
|
||||
"pg_analysis_empty": "매칭 분석을 보려면 사이클을 불러오세요.",
|
||||
@@ -763,7 +768,7 @@
|
||||
"setting_changed": "{date}에 {old}에서 {new}(으)로 변경됨",
|
||||
"settings_basic_note": "필수 설정만 표시하고 있습니다. 전체 목록을 보려면 고급으로 전환하세요.",
|
||||
"shape_drift_advisory": "⚠ 형태 변화 감지됨",
|
||||
"shape_drift_detail": "이 프로필의 전력 패턴이 시간이 지남에 따라 변화했습니다 — 가전제품 마모 또는 유지보수가 필요할 수 있습니다 (예: 스케일 제거, 필터 청소).",
|
||||
"shape_drift_detail": "이 프로필의 전력 패턴이 시간이 지남에 따라 변화했습니다 – 가전제품 마모 또는 유지보수가 필요할 수 있습니다 (예: 스케일 제거, 필터 청소).",
|
||||
"show_all_settings": "모든 설정 표시",
|
||||
"showing_suggestions": "제안사항과 함께 {count} 설정을 표시합니다.",
|
||||
"split_intro": "그래프를 클릭하여 분할 지점을 추가 또는 제거하거나 유휴 간격으로 자동 감지합니다. 각 결과 세그먼트는 자체 프로필을 얻을 수 있습니다.",
|
||||
@@ -789,10 +794,10 @@
|
||||
"toast_revert_failed": "되돌리기 실패: {error}",
|
||||
"toast_reverted": "{key}을(를) 되돌렸습니다",
|
||||
"toast_save_failed": "저장 실패: {error}",
|
||||
"trend_duration_longer": "기간이 길어지는 추세({pct}%/주기) — 최근 평균 {avg}",
|
||||
"trend_duration_shorter": "기간이 짧아지는 추세({pct}%/주기) — 최근 평균 {avg}",
|
||||
"trend_duration_longer": "기간이 길어지는 추세({pct}%/주기) – 최근 평균 {avg}",
|
||||
"trend_duration_shorter": "기간이 짧아지는 추세({pct}%/주기) – 최근 평균 {avg}",
|
||||
"trend_energy_down": "에너지 감소 추세({pct}%/주기)",
|
||||
"trend_energy_up": "에너지 상승 추세({pct}%/주기) — 최근 평균 {avg}",
|
||||
"trend_energy_up": "에너지 상승 추세({pct}%/주기) – 최근 평균 {avg}",
|
||||
"trim_intro": "빨간색 핸들을 드래그하거나 값을 입력합니다. 창 밖의 모든 것이 제거됩니다.",
|
||||
"tuning_suggestions_available": "관찰된 주기에서 사용할 수 있는 {count} 조정 제안입니다. 관련 필드 옆에 표시됩니다.",
|
||||
"unsure_detected_prefix": "WashData가 감지되었는지 확실하지 않습니다.",
|
||||
@@ -857,7 +862,9 @@
|
||||
"share_guidelines_title": "공유하기 전에",
|
||||
"store_download_device_intro": "공유된 모든 프로그램과 해당 참조 사이클을 기기에 채택합니다. 직접 기록한 사이클과 통계는 영향을 받지 않습니다.",
|
||||
"store_share_device_intro": "선택한 참조 사이클과 함께 {brand} {model}을 업로드합니다. 같은 가전제품을 가진 다른 사용자가 프로그램을 채택할 수 있습니다. 항목은 공개 전에 검토됩니다.",
|
||||
"share_profile_no_cycles": "참조 사이클 없음 -- 이 프로파일을 포함하려면 사이클 탭에서 사이클을 ⭐로 표시하세요"
|
||||
"share_profile_no_cycles": "참조 사이클 없음 -- 이 프로파일을 포함하려면 사이클 탭에서 사이클을 ⭐로 표시하세요",
|
||||
"advisory_phase_inconsistent": "'{name}'은(는) 서로 다른 프로그램이나 온도가 섞여 있는 것 같습니다. 사이클마다 가열 시간이 크게 다릅니다. 온도별 등으로 별도의 프로필로 나누면 매칭과 시간 추정이 개선됩니다.",
|
||||
"advisory_phase_inconsistent_title": "⚠ 프로그램이 섞였을 수 있음"
|
||||
},
|
||||
"pg_desc": {
|
||||
"abrupt_drop_watts": "급격한 강하는 즉시 종료로 처리",
|
||||
@@ -869,12 +876,19 @@
|
||||
"start_duration_threshold": "시작 확정을 위한 임계값 초과 초",
|
||||
"start_threshold_w": "시작으로 간주할 최소 와트",
|
||||
"stop_threshold_w": "이 값 미만이면 기기가 꺼진 것으로 간주",
|
||||
"dtw_bandwidth": "형상 매칭에서 허용하는 시간 왜곡의 정도",
|
||||
"corr_weight": "매칭에서 곡선 형상과 전력 레벨의 가중치",
|
||||
"duration_weight": "실행 시간 일치가 매칭에 미치는 영향의 정도",
|
||||
"energy_weight": "에너지 일치가 매칭에 미치는 영향의 정도",
|
||||
"profile_match_min_duration_ratio": "일치 대상으로 허용되는 최단 실행 시간(프로파일 대비)",
|
||||
"profile_match_max_duration_ratio": "일치 대상으로 허용되는 최장 실행 시간(프로파일 대비)"
|
||||
"dtw_bandwidth": "Stage 3: Sakoe-Chiba 워프 대역폭 (0 = DTW 비활성; 기본값 0.2 = 사이클 길이의 20%)",
|
||||
"corr_weight": "Stage 2: 곡선 형태(상관관계)와 전력 수준(MAE) 사이의 균형; 기본값 0.45",
|
||||
"duration_weight": "Stage 4: 실행 시간 일치가 최종 점수에 미치는 영향(기본값 0.22)",
|
||||
"energy_weight": "Stage 4: 에너지 일치가 최종 점수에 미치는 영향(기본값 0.22)",
|
||||
"profile_match_min_duration_ratio": "Stage 1: 프로파일 지속 시간의 분수로서 최소 사이클 길이; 기본값 0.1 (10%)",
|
||||
"profile_match_max_duration_ratio": "Stage 1: 프로파일 지속 시간의 분수로서 최대 사이클 길이; 기본값 1.5 (150%)",
|
||||
"keep_min_score": "Stage 2: 경쟁에 남기 위한 최소 점수; 기본값 0.1은 약한 후보도 허용하며, 이후 단계에서 최선을 선택",
|
||||
"dtw_blend": "Stage 3: 0 = 핵심 점수만, 1 = DTW 점수만, 0.5 = 동등 혼합(기본값)",
|
||||
"dtw_ensemble_w": "Stage 3 (앙상블 모드): 스케일 L1 대 도함수 DTW 가중치; 기본값 0.7은 수준 인식 방식을 선호",
|
||||
"dtw_ddtw_scale": "Stage 3: DDTW 반포화 거리; 작을수록 형상에 민감(기본값 30)",
|
||||
"dtw_refine_top_n": "Stage 3: DTW가 재점수화하는 후보 수; 올바른 프로파일이 4-5위면 7-9로 높임(기본값 5)",
|
||||
"duration_scale": "Stage 4: 지속 시간 일치 점수가 반으로 줄어드는 로그 비율; 작을수록 엄격한 패널티(기본값 0.175)",
|
||||
"energy_scale": "Stage 4: 에너지 일치 점수가 반으로 줄어드는 로그 비율; 작을수록 엄격한 패널티(기본값 0.25)"
|
||||
},
|
||||
"phase_desc": {
|
||||
"anti_crease": "메인 사이클 후 드럼이 간헐적으로 회전하여 의류 구김을 방지합니다.",
|
||||
@@ -957,6 +971,10 @@
|
||||
"triggers": {
|
||||
"intro": "선택적 외부 신호: 종료 트리거, 문 센서, 일시 정지 스위치, 꺼내기 알림.",
|
||||
"label": "트리거와 문"
|
||||
},
|
||||
"phase_eta": {
|
||||
"label": "남은 시간",
|
||||
"intro": "사이클 길이가 온도나 탈수에 따라 달라지는 기기를 위한, 단계를 고려한 남은 시간."
|
||||
}
|
||||
},
|
||||
"setting": {
|
||||
@@ -1040,6 +1058,10 @@
|
||||
"doc": "위에 실시간 가격 엔터티가 설정되지 않은 경우 비용 수치에 사용되는 kWh당 고정 가격입니다.",
|
||||
"label": "고정 에너지 가격 (kWh당)"
|
||||
},
|
||||
"energy_sensor": {
|
||||
"doc": "선택적 누적 에너지 카운터(total_increasing kWh/Wh, 예: 플러그 자체의 누적 계량기)입니다. 설정하면 각 사이클의 표시 에너지가 이 카운터의 시작부터 종료까지의 차이(delta)에서 계산되므로, 보고 주기가 느린 전력 센서를 적분할 때 발생하는 과소 집계를 방지합니다. 판독값이 없거나 단위를 알 수 없거나 차이가 양수가 아닌 경우 적분된 값으로 대체됩니다. 비워 두면 전력 센서를 계속 적분합니다.",
|
||||
"label": "에너지 계량기 엔티티"
|
||||
},
|
||||
"expose_debug_entities": {
|
||||
"doc": "추가 진단 HA 엔터티를 게시합니다(신뢰도, 모호성, 상태 내부 일치). 끄면 일반적인 사용을 위해 엔터티 목록을 깨끗하게 유지합니다.",
|
||||
"label": "디버그 엔티티 노출"
|
||||
@@ -1322,6 +1344,38 @@
|
||||
},
|
||||
"show_contributor": {
|
||||
"doc": "커뮤니티 가전제품 및 참조 사이클에 \"by <contributor>\" 기여자 표시를 보여줍니다."
|
||||
},
|
||||
"enable_phase_matching": {
|
||||
"label": "단계 기반 남은 시간",
|
||||
"doc": "실행 중인 각 사이클을 단계(가열, 세탁, 탈수)로 나누고 단계별로 남은 시간을 배분하여 기존 추정값과 혼합합니다. 사이클 초반에는 단계별 배분을, 종료에 가까워질수록 기존 추정값을 더 중시합니다. 이렇게 하면 기기가 실제로 가열하고 작동하는 시간에 맞춰 카운트다운이 개인화되며, 사이클 전반부에서 가장 뚜렷하게 나타납니다. 꺼짐 = 기존 추정값만 사용. 남은 시간 표시에만 영향을 미치며, 프로그램 매칭과 사이클 감지는 변경되지 않습니다."
|
||||
},
|
||||
"keep_min_score": {
|
||||
"label": "최소 매칭 점수",
|
||||
"doc": "후보가 매칭 경쟁에 남기 위해 필요한 최소 유사도 점수입니다. 기본값 0.1은 의도적으로 허용적입니다. 약한 후보도 허용하고 이후 단계에서 최선을 찾도록 합니다. 가능성이 낮은 프로파일을 더 일찍 제거하려면 높이고, 초기 후보 풀을 넓히려면 낮추세요."
|
||||
},
|
||||
"dtw_blend": {
|
||||
"label": "워프 블렌드",
|
||||
"doc": "시간 워프(DTW) 정렬 점수가 Stage 2 핵심 점수를 얼마나 대체하는지 나타냅니다. 0 = Stage 2 점수만 사용, 1 = DTW 점수만 사용, 0.5 (기본값) = 동등 혼합. 프로그램들이 유사한 전력 수준이지만 다른 타이밍 패턴을 가질 때 워프 정렬에 더 의존하려면 높이세요."
|
||||
},
|
||||
"dtw_ensemble_w": {
|
||||
"label": "워프 앙상블 혼합",
|
||||
"doc": "앙상블 DTW 모드(기본값)에서 스케일 L1과 도함수 DTW(DDTW)의 가중치 배분입니다. 1.0 = 모두 스케일-L1, 0 = 모두 DDTW, 0.7 = 기본값. 스케일-L1 방식은 전력 수준을 비교하고, 도함수 방식은 전력이 시간에 따라 변하는 방식에 반응합니다. 앙상블은 두 가지를 결합합니다."
|
||||
},
|
||||
"dtw_ddtw_scale": {
|
||||
"label": "미분 워프 스케일",
|
||||
"doc": "도함수 DTW 점수화를 위한 반포화 거리입니다. DDTW 거리가 이 값과 같을 때 점수가 반으로 줄어듭니다. 작을수록 형상 차이에 민감합니다. 기본값 30은 일반적인 가전제품 전력 추적에 맞게 보정되어 있습니다. 앙상블 및 ddtw DTW 모드에만 영향을 미칩니다."
|
||||
},
|
||||
"dtw_refine_top_n": {
|
||||
"label": "워프 정제 개수",
|
||||
"doc": "DTW가 재점수화하는 Stage 2 상위 후보 수입니다. DTW는 계산 비용이 높아 상위 N개 후보에만 적용됩니다. 기본값 5. 올바른 프로파일이 Stage 2 후 4위나 5위에 그치는 경우 값을 높이세요(7-9) - DTW가 이를 구할 수 있습니다. 낮추면 매칭 속도가 약간 빨라집니다."
|
||||
},
|
||||
"duration_scale": {
|
||||
"label": "지속 시간 선명도",
|
||||
"doc": "Stage 4 지속 시간 일치 패널티의 날카로움입니다. 이것은 일치 점수가 반으로 줄어드는 로그 비율입니다. 작을수록 엄격합니다. 지속 시간 불일치가 더 큰 영향을 미칩니다. 기본값 0.175는 반가중치에서 약 18%의 지속 시간 허용 오차에 해당합니다. 지속 시간 가중치와 함께 사용하세요."
|
||||
},
|
||||
"energy_scale": {
|
||||
"label": "에너지 선명도",
|
||||
"doc": "Stage 4 에너지 일치 패널티의 날카로움입니다. 작을수록 엄격합니다. 에너지 불일치가 더 큰 영향을 미칩니다. 기본값 0.25는 에너지가 부하에 따라 변하기 때문에 지속 시간 날카로움보다 의도적으로 더 허용적입니다. 에너지 가중치와 함께 사용하세요."
|
||||
}
|
||||
},
|
||||
"setting_group": {
|
||||
@@ -1766,6 +1820,69 @@
|
||||
},
|
||||
"pg_sweep": {
|
||||
"optimize": "최적화: {param}"
|
||||
},
|
||||
"pg_detail": {
|
||||
"simulate": "사이클 시뮬레이션"
|
||||
},
|
||||
"split": {
|
||||
"apply": "사이클 분할 중"
|
||||
},
|
||||
"trim": {
|
||||
"apply": "사이클 트리밍 중"
|
||||
},
|
||||
"merge": {
|
||||
"apply": "사이클 병합 중"
|
||||
},
|
||||
"rebuild": {
|
||||
"envelopes": "엔벨로프 재구성 중"
|
||||
},
|
||||
"cancelling": "취소 중..."
|
||||
},
|
||||
"setup": {
|
||||
"hdr": {
|
||||
"card": "기기 설정",
|
||||
"healthy_chip": "설정 완료"
|
||||
},
|
||||
"phase0": {
|
||||
"washer": "WashData가 이미 사이클을 감지하고 있습니다. 프로그램 이름과 시간 추정을 활성화하려면 첫 번째 사이클을 기록하세요.",
|
||||
"dishwasher": "WashData가 관찰 중입니다. 식기세척기 사이클은 복잡합니다 – 첫 번째 사이클을 기록하는 것이 강력히 권장됩니다. 감지된 사이클이 너무 길게 실행되면 프로필로 저장하기 전에 사이클 편집기를 사용하여 다듬으세요.",
|
||||
"generic": "WashData가 관찰 중입니다. 프로필 구축을 시작하려면 감지된 사이클을 기록하거나 라벨을 지정하세요."
|
||||
},
|
||||
"phase1a": {
|
||||
"labelled": "좋은 시작입니다 – 첫 번째 프로그램이 저장되었습니다. 가장 정확한 데이터를 위해 녹음기 위젯으로 다음 사이클을 기록하는 것을 고려해 보세요."
|
||||
},
|
||||
"phase1b": {
|
||||
"recorded": "녹음이 {profile_name}으로 저장되었습니다. 이제 다른 자주 사용하는 프로그램을 기록하거나 라벨을 지정하여 커버리지를 구축하세요."
|
||||
},
|
||||
"phase1c": {
|
||||
"verify": "커뮤니티에서 {count}개의 프로그램이 있습니다. WashData가 올바르게 인식하는지 확인하기 위해 사이클을 실행하세요 – 기기가 자체 기록을 쌓으면서 매칭이 개선됩니다."
|
||||
},
|
||||
"phase2": {
|
||||
"cluster": "WashData가 저장된 프로그램과 일치하지 않는 {count}개의 사이클을 발견했습니다 – 서로 비슷해 보입니다. 이를 위한 새 프로필을 만들고 싶으신가요?",
|
||||
"unmatched": "마지막 사이클이 저장된 프로그램과 일치하지 않았습니다. 새 프로그램인가요?"
|
||||
},
|
||||
"phase3": {
|
||||
"suggestions": "WashData가 사이클 기록을 기반으로 설정 권장 사항을 제안합니다 – 감지 정확도를 높이기 위해 검토하세요.",
|
||||
"groups": "일부 프로필이 다른 온도의 동일한 프로그램처럼 보입니다. 더 나은 매칭을 위해 그룹으로 구성하세요.",
|
||||
"phases": "더 정확한 잔여 시간 추정을 위해 {profile_name}에 프로그램 단계를 추가하세요."
|
||||
},
|
||||
"phase4": {
|
||||
"healthy": "이 기기는 완전히 설정되었습니다 ({profile_count}개 프로필)."
|
||||
},
|
||||
"cta": {
|
||||
"start_recording": "녹음 시작",
|
||||
"label_detected_cycle": "이미 감지된 사이클이 있습니다 – 대신 라벨 지정",
|
||||
"browse_cycles": "다른 사이클에 라벨을 지정하려면 찾아보기",
|
||||
"view_profiles": "프로필 보기",
|
||||
"create_from_cluster": "이 사이클들로 프로필 만들기",
|
||||
"create_profile": "이를 위한 프로필 만들기",
|
||||
"review_suggestions": "제안 검토",
|
||||
"organise_profiles": "프로필 구성",
|
||||
"configure_phases": "단계 구성",
|
||||
"skip_step": "이 단계 건너뛰기",
|
||||
"skip_forever": "다시 표시 안 함",
|
||||
"hide_guidance": "안내 숨기기",
|
||||
"show_guidance": "안내 표시"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
"on_cycle_finished": "Ciklas baigtas",
|
||||
"on_cycle_started": "Prasidėjus ciklui",
|
||||
"pause_cycle": "Pauzė",
|
||||
"pause_cycle_tip": "Pristabdyti veikiantį ciklą — prietaisas tęsis nuo tos vietos, kur sustojo",
|
||||
"pause_cycle_tip": "Pristabdyti veikiantį ciklą – prietaisas tęsis nuo tos vietos, kur sustojo",
|
||||
"pg_apply_device": "Taikyti įrenginiui",
|
||||
"pg_autofill": "Automatinis užpildymas",
|
||||
"play": "Leisti",
|
||||
@@ -97,8 +97,8 @@
|
||||
"process_tip": "Išsaugoti įrašytą seką kaip naują arba esamą profilį",
|
||||
"rebuild": "Atstatyti vokus",
|
||||
"rebuild_envelope": "Atstatyti voką",
|
||||
"rebuild_tip": "Perskaičiuoti laukiamą galios voką (min/maks juosta) visiems profiliams iš jų pažymėtų ciklų — paleiskite pažymėję naujus ciklus arba pataisę senus",
|
||||
"rec_start_tip": "Pradėti įrašyti prietaiso galios seką — pradėkite prieš pat paleidžiant ciklą",
|
||||
"rebuild_tip": "Perskaičiuoti laukiamą galios voką (min/maks juosta) visiems profiliams iš jų pažymėtų ciklų – paleiskite pažymėję naujus ciklus arba pataisę senus",
|
||||
"rec_start_tip": "Pradėti įrašyti prietaiso galios seką – pradėkite prieš pat paleidžiant ciklą",
|
||||
"rec_stop": "Stabdyti",
|
||||
"rec_stop_tip": "Sustabdyti įrašymą ir laikyti užfiksuotą seką peržiūrai",
|
||||
"record": "Pradėti įrašymą",
|
||||
@@ -182,7 +182,7 @@
|
||||
},
|
||||
"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.",
|
||||
"settings_banner": "{n} nustatymų konfliktas{s} – patikrinkite pažymėtas sekcijas ir ištaisykite prieš išsaugant.",
|
||||
"settings_banner_btn": "Eiti į pirmą",
|
||||
"confidence": {
|
||||
"auto": "Turi būti lygus arba aukščiau atitikimo slenksčio ({match})",
|
||||
@@ -451,9 +451,9 @@
|
||||
"show_expected": "Rodyti numatomą kreivės perdangą (atitinkantį profilį, oranžinė)",
|
||||
"show_raw": "Rodyti neapdoroto lizdo perjungiklį tiesioginiame galios grafike",
|
||||
"sparkline": "Naujausia ciklų trukmės tendencija",
|
||||
"stage2": "2 etapas — pagrindinis panašumas",
|
||||
"stage3": "3 etapas — DTW",
|
||||
"stage4": "4 etapas — atitikimas",
|
||||
"stage2": "2 etapas – pagrindinis panašumas",
|
||||
"stage3": "3 etapas – DTW",
|
||||
"stage4": "4 etapas – atitikimas",
|
||||
"status": "Būsena",
|
||||
"tail_trim": "Uodegos apdaila (-ai)",
|
||||
"timer_auto_pause": "Automatinis pristabdymas",
|
||||
@@ -561,7 +561,12 @@
|
||||
"flags": "Žymės",
|
||||
"include_phase_map": "Įtraukti fazių žemėlapį",
|
||||
"include_settings": "Įtraukti aptikimo ir atitikties nustatymus",
|
||||
"show_contributor": "Rodyti dalyvių vardus"
|
||||
"show_contributor": "Rodyti dalyvių vardus",
|
||||
"task_pg_detail": "Simuliuojamas ciklas",
|
||||
"task_split": "Padalijamas ciklas",
|
||||
"task_trim": "Apkarpomas ciklas",
|
||||
"task_merge": "Sujungiami ciklai",
|
||||
"task_rebuild": "Perkuriamos gaubtinės"
|
||||
},
|
||||
"log": {
|
||||
"all_levels": "Visi lygiai",
|
||||
@@ -657,7 +662,7 @@
|
||||
"compare_selected_cycles": "Pasirinkti ciklai (vientisas) – rodyti / slėpti",
|
||||
"consider_new_profile": "Apsvarstykite galimybę sukurti naują profilį.",
|
||||
"coverage_gap": "paskutiniai ciklai neturi atitinkančio profilio ({pct} % iš paskutinių 30).",
|
||||
"coverage_gap_similar_cycles": "Rasti {count} panašūs nepažymėti ciklai — sukurkite profilį, kad pradėtumėte juos atpažinti.",
|
||||
"coverage_gap_similar_cycles": "Rasti {count} panašūs nepažymėti ciklai – sukurkite profilį, kad pradėtumėte juos atpažinti.",
|
||||
"cycles_deleted": "Ištrinta ciklų: {count}",
|
||||
"enough_data": "Pakankamai duomenų mokymui ({current}/{min} ciklų).",
|
||||
"export_description": "Eksportuokite visus profilius ir ciklus į JSON arba atkurkite iš ankstesnio eksportavimo.",
|
||||
@@ -686,7 +691,7 @@
|
||||
"ml_learned_intro": "Modeliai, pritaikyti šiai mašinai.",
|
||||
"ml_loading": "įkeliamas ML…",
|
||||
"ml_settings_intro": "Du nepriklausomi jungikliai: vienas pritaiko modelius, kol veikia ciklas, kitas leidžia WashData laikui bėgant tiksliai suderinti juos su jūsų aparatu.",
|
||||
"name_first_program": "Turite pakankamai ciklų — pavadinkite pirmąją programą, kad prasidėtų suderinimas.",
|
||||
"name_first_program": "Turite pakankamai ciklų – pavadinkite pirmąją programą, kad prasidėtų suderinimas.",
|
||||
"near_duplicate_cluster": "Aptikta beveik pasikartojanti profilių grupė. Grupavimas leidžia suderinti patikimai pasirinkti panašius dalykus (pvz., ta pati programa esant skirtingai temperatūrai / sukimuisi).",
|
||||
"no_cycles_match": "Nė vienas ciklas neatitinka esamo filtro.",
|
||||
"no_cycles_profile": "Šiam profiliui nėra ciklų.",
|
||||
@@ -710,10 +715,10 @@
|
||||
"no_settings_match": "Jokie nustatymai neatitinka „{q}“",
|
||||
"no_split_points": "Dar nėra padalintų taškų.",
|
||||
"no_suggestions": "Nėra aktyvių pasiūlymų.",
|
||||
"notify_services_hint": "Naudokite {entity} paslaugų ID (keliems — atskirkite kableliais). Šablono kintamieji: {vars}.",
|
||||
"notify_services_hint": "Naudokite {entity} paslaugų ID (keliems – atskirkite kableliais). Šablono kintamieji: {vars}.",
|
||||
"old_actions_warning": "Sukonfigūruota naudojant seną veiksmų rengyklę (dabar pašalinta). Jie vis dar suaktyvinami ciklo įvykiuose, bet čia jų redaguoti nebegalima. Konvertuokite juos į įprastą automatiką arba pašalinkite.",
|
||||
"onboarding_progress": "Stebėta ciklų: {n} / 3",
|
||||
"onboarding_watching": "Naudokite prietaisą įprastai — „WashData“ stebi. Po 3 ciklų prasidės programų suderinimas.",
|
||||
"onboarding_watching": "Naudokite prietaisą įprastai – „WashData“ stebi. Po 3 ciklų prasidės programų suderinimas.",
|
||||
"pending_feedback": "Laukiama aptikimo atsiliepimo",
|
||||
"performance_trend": "Našumo tendencija ({n} ciklai)",
|
||||
"pg_analysis_empty": "Įkelkite ciklą, kad pamatytumėte atitikties analizę.",
|
||||
@@ -763,7 +768,7 @@
|
||||
"setting_changed": "Pakeista iš {old} į {new} {date}",
|
||||
"settings_basic_note": "Rodomi esminiai nustatymai. Norėdami pamatyti visą sąrašą, perjunkite į „Išplėstinė“.",
|
||||
"shape_drift_advisory": "⚠ Formos dreifas",
|
||||
"shape_drift_detail": "Šio profilio galios šablonas laikui bėgant pasikeitė — galimas prietaiso susidėvėjimas arba reikalinga priežiūra (pvz., nukalkinimas, filtro valymas).",
|
||||
"shape_drift_detail": "Šio profilio galios šablonas laikui bėgant pasikeitė – galimas prietaiso susidėvėjimas arba reikalinga priežiūra (pvz., nukalkinimas, filtro valymas).",
|
||||
"show_all_settings": "Rodyti visus nustatymus",
|
||||
"showing_suggestions": "Rodomas {count} nustatymas su pasiūlymais.",
|
||||
"split_intro": "Spustelėkite diagramą, kad pridėtumėte arba pašalintumėte padalijimo tašką, arba automatiškai aptiktumėte pagal tuščiosios eigos tarpus. Kiekvienas gautas segmentas gali gauti savo profilį.",
|
||||
@@ -857,7 +862,9 @@
|
||||
"share_guidelines_title": "Prieš dalijantis",
|
||||
"store_download_device_intro": "Perimkite kiekvieną bendrą programą ir jos etalonius ciklus į savo įrenginį. Jūsų pačių įrašyti ciklai ir statistika neįtakojami.",
|
||||
"store_share_device_intro": "Įkelkite {brand} {model} su pasirinktais etaloniniais ciklais. Kiti, turintys tą patį prietaisą, gali perimti jūsų programas. Įrašai peržiūrimi prieš viešinant.",
|
||||
"share_profile_no_cycles": "Nėra etaloninių ciklų -- pažymėkite ciklą kaip ⭐ Ciklų skirtuke, kad įtrauktumėte šį profilį"
|
||||
"share_profile_no_cycles": "Nėra etaloninių ciklų -- pažymėkite ciklą kaip ⭐ Ciklų skirtuke, kad įtrauktumėte šį profilį",
|
||||
"advisory_phase_inconsistent": "Atrodo, kad '{name}' maišo skirtingas programas ar temperatūras - jo ciklai kaista labai skirtingą laiką. Padalijus jį į atskirus profilius (pvz., pagal temperatūrą), pagerės atitikimas ir laiko įverčiai.",
|
||||
"advisory_phase_inconsistent_title": "⚠ Galimai sumaišytos programos"
|
||||
},
|
||||
"phase_desc": {
|
||||
"anti_crease": "Po pagrindinio ciklo būgnas intermitiškai sukasi, kad išvengtų audinių raukšlių.",
|
||||
@@ -940,6 +947,10 @@
|
||||
"triggers": {
|
||||
"intro": "Pasirenkami išoriniai signalai: pabaigos trigeris, durų jutiklis, pauzės jungiklis ir iškrovimo priminimas.",
|
||||
"label": "Trigeriai ir durys"
|
||||
},
|
||||
"phase_eta": {
|
||||
"label": "Likęs laikas",
|
||||
"intro": "Į fazes atsižvelgiantis likęs laikas mašinoms, kurių ciklo trukmė priklauso nuo temperatūros ar gręžimo."
|
||||
}
|
||||
},
|
||||
"setting": {
|
||||
@@ -1023,6 +1034,10 @@
|
||||
"doc": "Fiksuota kaina už kWh, naudojama sąnaudų skaičiams, kai aukščiau nenustatytas joks tiesioginės kainos subjektas.",
|
||||
"label": "Statinė energijos kaina (už kWh)"
|
||||
},
|
||||
"energy_sensor": {
|
||||
"doc": "Neprivalomas kaupiamasis energijos skaitiklis (total_increasing kWh/Wh, pvz., paties kištuko viso laikotarpio skaitiklis). Kai nustatytas, kiekvieno ciklo pateikiama energija imama iš šio skaitiklio rodmens pokyčio nuo pradžios iki pabaigos, taip išvengiama per mažo skaičiavimo, kurį gaunate integruodami lėtai duomenis pateikiantį galios jutiklį. Grįžta prie integruotos reikšmės, jei rodmens nėra, jo vienetas nežinomas arba skirtumas nėra teigiamas. Palikite tuščią, kad būtų ir toliau integruojamas galios jutiklis.",
|
||||
"label": "Energijos skaitiklio objektas"
|
||||
},
|
||||
"expose_debug_entities": {
|
||||
"doc": "Paskelbkite papildomus diagnostinius HA objektus (atitikties patikimumą, dviprasmiškumą, būsenos vidines savybes). Išjungta objektų sąrašas išlieka švarus normaliam naudojimui.",
|
||||
"label": "Rodyti derinimo objektus"
|
||||
@@ -1305,6 +1320,38 @@
|
||||
},
|
||||
"show_contributor": {
|
||||
"doc": "Rodyti \"autorius: <dalyvis>\" priskyrimą bendruomenės prietaisuose ir etaloniniuose cikluose."
|
||||
},
|
||||
"enable_phase_matching": {
|
||||
"label": "Į fazes atsižvelgiantis likęs laikas",
|
||||
"doc": "Padalykite kiekvieną vykstantį ciklą į fazes (šildymas, plovimas, gręžimas) ir paskirstykite likusį laiką kiekvienai fazei, sumaišydami su klasikiniu įverčiu - ciklo pradžioje remdamiesi fazių paskirstymu, o pabaigoje - klasikiniu įverčiu. Tai pritaiko laikmatį prie to, kiek laiko jūsų mašina iš tikrųjų kaista ir veikia, o tai labiausiai pastebima pirmoje ciklo pusėje. Išjungta = tik klasikinis įvertis. Paveikiamas tik likusio laiko rodinys; programų atitikimas ir ciklų aptikimas nekeičiami."
|
||||
},
|
||||
"keep_min_score": {
|
||||
"label": "Min. atitikties balas",
|
||||
"doc": "Žemiausias panašumo balas, kurio kandidatui reikia likti derinimo procese. Numatytoji 0,1 yra sąmoningai leistina – ji leidžia net silpnus kandidatus ir pasitiki vėlesniais etapais rasti geriausią atitiktį. Padidinkite, kad anksčiau filtruotumėte mažai tikėtinus profilius; sumažinkite pradiniam kandidatų telkiniui išplėsti."
|
||||
},
|
||||
"dtw_blend": {
|
||||
"label": "DTW mišinys",
|
||||
"doc": "Kiek DTW lygiavimo balas pakeičia 2 etapo pagrindinį balą. 0 = naudokite tik 2 etapo balą, 1 = naudokite tik DTW balą, 0,5 (numatytoji) = lygus mišinys. Padidinkite, kad labiau pasikliauti laiko lygiavimo, kai programos turi panašius galios lygius, bet skirtingus laiko modelius."
|
||||
},
|
||||
"dtw_ensemble_w": {
|
||||
"label": "DTW ansamblio mišinys",
|
||||
"doc": "Ansamblio DTW režime (numatytoji) tai yra skalieroto L1 svoris lyginant su išvestiniu DTW (DDTW). 1,0 = tik skalierota L1, 0 = tik DDTW, 0,7 = numatytoji. Skalierota variacija lygina galios lygius; išvestinė variacija reaguoja į tai, kaip galia keičiasi bėgant laikui. Ansamblis derina abi."
|
||||
},
|
||||
"dtw_ddtw_scale": {
|
||||
"label": "Išvest. DTW skalė",
|
||||
"doc": "Pusiau prisotinimo atstumas išvestiniam DTW vertinimui. Balas perpus sumažėja, kai DDTW atstumas lygus šiai reikšmei. Mažesnis = jautresnis formos skirtumams. Numatytoji 30 sukalibruota tipiškai buitinių prietaisų galios kreivėms. Veikia tik ansamblio ir ddtw DTW režimus."
|
||||
},
|
||||
"dtw_refine_top_n": {
|
||||
"label": "DTW tikslinimo skaičius",
|
||||
"doc": "Kiek geriausių 2 etapo kandidatų DTW perskaičiuoja balus. DTW yra brangesnė operacija, todėl taikoma tik N geriausiems. Numatytoji 5. Padidinkite (iki 7-9), jei teisingas profilis kartais po 2 etapo patenka tik į 4 arba 5 vietą – DTW gali jį išgelbėti. Mažesnė reikšmė šiek tiek pagreitina derinimą."
|
||||
},
|
||||
"duration_scale": {
|
||||
"label": "Trukmės ryškumas",
|
||||
"doc": "4 etapo trukmės atitikimo bausmės ryškumas. Tai yra logaritmas, ties kuriuo atitikimo balas perpus sumažėja. Mažesnis = griežtesnis: trukmės neatitikimas kenkia labiau. Numatytoji 0,175 atitinka maždaug 18% trukmės toleranciją ties pusiau svoriu. Naudokite su Trukmės svoriu."
|
||||
},
|
||||
"energy_scale": {
|
||||
"label": "Energijos ryškumas",
|
||||
"doc": "4 etapo energijos atitikimo bausmės ryškumas. Mažesnis = griežtesnis: energijos neatitikimas kenkia labiau. Numatytoji 0,25 sąmoningai atlaidesnė nei trukmės ryškumas, nes energija kinta priklausomai nuo apkrovos. Naudokite su Energijos svoriu."
|
||||
}
|
||||
},
|
||||
"setting_group": {
|
||||
@@ -1553,24 +1600,24 @@
|
||||
"lower": "Automatiškai pažymi daugiau ciklų; kai kurie gali būti neteisingai identifikuoti"
|
||||
},
|
||||
"duration_tolerance": {
|
||||
"higher": "Priima platesnį trukmės diapazoną — lankstesnis atitikimas",
|
||||
"lower": "Reikalauja tikslesnio trukmės atitikimo — griežtesnė, bet gali atmesti neįprastus ciklus"
|
||||
"higher": "Priima platesnį trukmės diapazoną – lankstesnis atitikimas",
|
||||
"lower": "Reikalauja tikslesnio trukmės atitikimo – griežtesnė, bet gali atmesti neįprastus ciklus"
|
||||
},
|
||||
"end_energy_threshold": {
|
||||
"higher": "Uždaro tik ciklus, kurie sunaudojo daug energijos",
|
||||
"lower": "Uždaro ir trumpesnius arba mažiau energijos naudojančius ciklus"
|
||||
},
|
||||
"end_repeat_count": {
|
||||
"higher": "Reikalauja, kad pabaigos signalas kartotųsi daugiau kartų — patikimesnis, šiek tiek lėtesnis",
|
||||
"lower": "Baigia po mažiau pasikartojimų — greitesnis aptikimas, didesnis klaidingo pabaigos pavojus"
|
||||
"higher": "Reikalauja, kad pabaigos signalas kartotųsi daugiau kartų – patikimesnis, šiek tiek lėtesnis",
|
||||
"lower": "Baigia po mažiau pasikartojimų – greitesnis aptikimas, didesnis klaidingo pabaigos pavojus"
|
||||
},
|
||||
"learning_confidence": {
|
||||
"higher": "Mokosi tik iš labai tikrų atitikimų — lėčiau, bet patikimiau",
|
||||
"higher": "Mokosi tik iš labai tikrų atitikimų – lėčiau, bet patikimiau",
|
||||
"lower": "Mokosi iš daugiau ciklų; modelis gali būti triukšmingesnis"
|
||||
},
|
||||
"min_off_gap": {
|
||||
"higher": "Prieš naują ciklą reikia ilgesnio neveiklumo laikotarpio",
|
||||
"lower": "Trumpas neveiklumas paleidžia naują ciklą — vienas po kito einantys paleidimai gali išsiskirti"
|
||||
"lower": "Trumpas neveiklumas paleidžia naują ciklą – vienas po kito einantys paleidimai gali išsiskirti"
|
||||
},
|
||||
"min_power": {
|
||||
"higher": "Mažiau jautrus budėjimo galiai; gali praleisti labai tylias programas",
|
||||
@@ -1581,24 +1628,24 @@
|
||||
"lower": "Greičiau priverstinai sustabdo įstrigusį ciklą"
|
||||
},
|
||||
"off_delay": {
|
||||
"higher": "Daugiau laiko prietaiso pauzėms — valdo ilgas mirkymo arba džiovinimo fazes",
|
||||
"lower": "Greitesnis pabaigos aptikimas — tinka aiškiems įjungimo/išjungimo prietaisams"
|
||||
"higher": "Daugiau laiko prietaiso pauzėms – valdo ilgas mirkymo arba džiovinimo fazes",
|
||||
"lower": "Greitesnis pabaigos aptikimas – tinka aiškiems įjungimo/išjungimo prietaisams"
|
||||
},
|
||||
"profile_match_threshold": {
|
||||
"higher": "Patvirtina tik aukšto pasitikėjimo atitikimus; daugiau ciklų lieka nepažymėtų",
|
||||
"lower": "Atitinka daugiau ciklų; kai kurie gali būti šiek tiek neteisingi"
|
||||
},
|
||||
"running_dead_zone": {
|
||||
"higher": "Ignoruoja trumpus galios šuolius neveiklumo metu — mažiau jautrus triukšmui",
|
||||
"lower": "Reaguoja į trumpesnius galios pliūpsnius — aptinka greitą trumpalaikę veiklą"
|
||||
"higher": "Ignoruoja trumpus galios šuolius neveiklumo metu – mažiau jautrus triukšmui",
|
||||
"lower": "Reaguoja į trumpesnius galios pliūpsnius – aptinka greitą trumpalaikę veiklą"
|
||||
},
|
||||
"start_threshold_w": {
|
||||
"higher": "Išvengia netikrų paleidimų dėl trumpų galios šuolių",
|
||||
"lower": "Aptinka mažos galios programas; gali suaktyvėti nuo triukšmo"
|
||||
},
|
||||
"stop_threshold_w": {
|
||||
"higher": "Greičiau baigia ciklą — gali uždaryti pauzės metu",
|
||||
"lower": "Laukia ilgiau prieš baigiant — mažiau ankstyvų pabaigimų"
|
||||
"higher": "Greičiau baigia ciklą – gali uždaryti pauzės metu",
|
||||
"lower": "Laukia ilgiau prieš baigiant – mažiau ankstyvų pabaigimų"
|
||||
},
|
||||
"watchdog_interval": {
|
||||
"higher": "Leidžiamos ilgesnės tylios fazės; mažiau klaidingų priverstinių sustabdymų",
|
||||
@@ -1676,12 +1723,19 @@
|
||||
"start_duration_threshold": "Sekundės virš slenksčio startui patvirtinti",
|
||||
"start_threshold_w": "Mažiausia galia (W), kad būtų skaičiuojama kaip prasidėjęs",
|
||||
"stop_threshold_w": "Žemiau šios ribos aparatas laikomas išjungtu",
|
||||
"dtw_bandwidth": "Kiek laiko iškraipymo leidžia formos atitiktis",
|
||||
"corr_weight": "Kreivės formos ir galios lygio svoris atitikime",
|
||||
"duration_weight": "Kiek trukmės sutapimas veikia atitiktį",
|
||||
"energy_weight": "Kiek energijos sutapimas veikia atitiktį",
|
||||
"profile_match_min_duration_ratio": "Trumpiausias ciklas (palyginti su profiliu), kuriam dar leidžiama atitikti",
|
||||
"profile_match_max_duration_ratio": "Ilgiausias ciklas (palyginti su profiliu), kuriam dar leidžiama atitikti"
|
||||
"dtw_bandwidth": "3 etapas: Sakoe-Chiba laiko lankstymo juosta (0 = DTW išjungtas; numatytoji 0,2 = 20% ciklo ilgio)",
|
||||
"corr_weight": "2 etapas: balansas tarp kreivės formos (koreliacija) ir galios lygio (MAE); numatytoji 0,45",
|
||||
"duration_weight": "4 etapas: kaip stipriai trukmės atitikimas veikia galutinį balą (numatytoji 0,22)",
|
||||
"energy_weight": "4 etapas: kaip stipriai energijos atitikimas veikia galutinį balą (numatytoji 0,22)",
|
||||
"profile_match_min_duration_ratio": "1 etapas: trumpiausias ciklas kaip profilio trukmės dalis; numatytoji 0,1 (10%)",
|
||||
"profile_match_max_duration_ratio": "1 etapas: ilgiausias ciklas kaip profilio trukmės dalis; numatytoji 1,5 (150%)",
|
||||
"keep_min_score": "2 etapas: žemiausias balas likti lenktynėse; numatytoji 0,1 leidžia silpnus kandidatus, vėlesni etapai parenka geriausią",
|
||||
"dtw_blend": "3 etapas: 0 = tik pagrindinis balas, 1 = tik DTW balas, 0,5 = lygus mišinys (numatytoji)",
|
||||
"dtw_ensemble_w": "3 etapas (ansamblio režimas): skalieroto L1 svoris prieš išvestinės DTW; numatytoji 0,7 teikia pirmenybę lygio sąmoningumui",
|
||||
"dtw_ddtw_scale": "3 etapas: DDTW pusiau prisotinimo atstumas; mažesnis = jautresnis formos skirtumams (numatytoji 30)",
|
||||
"dtw_refine_top_n": "3 etapas: kandidatai, kuriems DTW perskaičiuoja balus; padidinkite iki 7-9 jei teisingas profilis patenka į 4-5 vietą (numatytoji 5)",
|
||||
"duration_scale": "4 etapas: logaritmas, ties kuriuo trukmės atitikimas perpus sumažėja; mažesnis = griežtesnė bausmė (numatytoji 0,175)",
|
||||
"energy_scale": "4 etapas: logaritmas, ties kuriuo energijos atitikimas perpus sumažėja; mažesnis = griežtesnė bausmė (numatytoji 0,25)"
|
||||
},
|
||||
"col": {
|
||||
"profile_tip": "Atitikusios programos pavadinimas. Nepažymėta reiškia, kad ciklo pabaigoje neatitiko joks profilis.",
|
||||
@@ -1766,6 +1820,69 @@
|
||||
},
|
||||
"pg_sweep": {
|
||||
"optimize": "Optimizavimas: {param}"
|
||||
},
|
||||
"pg_detail": {
|
||||
"simulate": "Simuliuojamas ciklas"
|
||||
},
|
||||
"split": {
|
||||
"apply": "Padalijamas ciklas"
|
||||
},
|
||||
"trim": {
|
||||
"apply": "Apkarpomas ciklas"
|
||||
},
|
||||
"merge": {
|
||||
"apply": "Sujungiami ciklai"
|
||||
},
|
||||
"rebuild": {
|
||||
"envelopes": "Perkuriamos gaubtinės"
|
||||
},
|
||||
"cancelling": "Atšaukiama..."
|
||||
},
|
||||
"setup": {
|
||||
"hdr": {
|
||||
"card": "Įrenginio sąranka",
|
||||
"healthy_chip": "Sąranka baigta"
|
||||
},
|
||||
"phase0": {
|
||||
"washer": "WashData jau aptinka jūsų ciklus. Įrašykite pirmąjį ciklą, kad galėtumėte naudoti programų pavadinimus ir laiko įverčius.",
|
||||
"dishwasher": "WashData stebi. Indaplovių ciklai yra sudėtingi – labai rekomenduojame įrašyti pirmąjį ciklą. Jei aptiktas ciklas trunka per ilgai, prieš išsaugant kaip profilį, apkarpykite jį ciklo redaktoriuje.",
|
||||
"generic": "WashData stebi. Įrašykite arba pažymėkite aptiktą ciklą, kad pradėtumėte kurti profilius."
|
||||
},
|
||||
"phase1a": {
|
||||
"labelled": "Gera pradžia – jūsų pirmoji programa išsaugota. Kad duomenys būtų kuo švaresni, apsvarstykite galimybę įrašyti kitą ciklą naudodami įrašymo valdiklį."
|
||||
},
|
||||
"phase1b": {
|
||||
"recorded": "Jūsų įrašas išsaugotas kaip {profile_name}. Dabar įrašykite arba pažymėkite kitas dažniausiai naudojamas programas, kad padidintumėte aprėptį."
|
||||
},
|
||||
"phase1c": {
|
||||
"verify": "Turite {count} bendruomenės programas. Paleiskite ciklą, kad patikrintumėte, ar WashData jas teisingai atpažįsta – atitikimas gerės, kai jūsų įrenginys sukaupia savo istoriją."
|
||||
},
|
||||
"phase2": {
|
||||
"cluster": "WashData aptiko {count} ciklus, kurie neatitinka jokios išsaugotos programos – jie yra panašūs vienas į kitą. Ar norite sukurti jiems naują profilį?",
|
||||
"unmatched": "Paskutinis ciklas neatitiko jokios išsaugotos programos. Ar tai nauja programa?"
|
||||
},
|
||||
"phase3": {
|
||||
"suggestions": "WashData pateikia nustatymų rekomendacijas pagal jūsų ciklų istoriją – peržiūrėkite jas, kad pagerintumėte aptikimo tikslumą.",
|
||||
"groups": "Kai kurie jūsų profiliai atrodo kaip ta pati programa skirtingose temperatūrose. Sugrupuokite juos, kad atitikimas būtų tikslesnis.",
|
||||
"phases": "Pridėkite programų fazes prie {profile_name}, kad likusio laiko įverčiai būtų tikslesni."
|
||||
},
|
||||
"phase4": {
|
||||
"healthy": "Šis įrenginys yra visiškai sukonfigūruotas ({profile_count} profiliai)."
|
||||
},
|
||||
"cta": {
|
||||
"start_recording": "Pradėti įrašymą",
|
||||
"label_detected_cycle": "Jau turiu aptiktą ciklą – vietoj to pažymėti jį",
|
||||
"browse_cycles": "Naršyti ciklus, kad pažymėtumėte kitą",
|
||||
"view_profiles": "Peržiūrėti profilius",
|
||||
"create_from_cluster": "Sukurti profilį iš šių ciklų",
|
||||
"create_profile": "Sukurti jam profilį",
|
||||
"review_suggestions": "Peržiūrėti pasiūlymus",
|
||||
"organise_profiles": "Tvarkyti profilius",
|
||||
"configure_phases": "Konfigūruoti fazes",
|
||||
"skip_step": "Praleisti šį žingsnį",
|
||||
"skip_forever": "Daugiau nerodyti",
|
||||
"hide_guidance": "Slėpti nurodymus",
|
||||
"show_guidance": "Rodyti nurodymus"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
{
|
||||
"badge": {
|
||||
"artifact_tip": "Konstatētas {n} anomālijas (piemēram, durvis atvērtas cikla vidū) — atveriet, lai tās skatītu diagrammā",
|
||||
"artifact_tip": "Konstatētas {n} anomālijas (piemēram, durvis atvērtas cikla vidū) – atveriet, lai tās skatītu diagrammā",
|
||||
"auto": "(noteikts automātiski)",
|
||||
"built_in_tag": "iebūvēts",
|
||||
"declining": "↘ samazinās",
|
||||
"energy_low": "Zemāka enerģija nekā parasti",
|
||||
"energy_spike": "Augstāka enerģija nekā parasti",
|
||||
"fair_fit": "godīga atbilstība",
|
||||
"fair_fit_tip": "Mērena atbilstības konsekvence — dažiem šim profilam piešķirtajiem cikliem ir zemāki ticamības rādītāji. Iezīmējiet vairāk ciklu vai atkārtoti ierakstiet profilu, lai uzlabotu precizitāti.",
|
||||
"fair_fit_tip": "Mērena atbilstības konsekvence – dažiem šim profilam piešķirtajiem cikliem ir zemāki ticamības rādītāji. Iezīmējiet vairāk ciklu vai atkārtoti ierakstiet profilu, lai uzlabotu precizitāti.",
|
||||
"feedback_requested": "Pieprasītas atsauksmes",
|
||||
"golden_cycle": "Reģistrēts atskaites cikls",
|
||||
"improving": "↗ uzlabošanās",
|
||||
@@ -15,7 +15,7 @@
|
||||
"needs_review": "Nepieciešama pārskatīšana",
|
||||
"overrun": "Skrēja ilgāk nekā parasti",
|
||||
"poor_fit": "slikta atbilstība",
|
||||
"poor_fit_tip": "Nekonsekventa spēļu vēsture — apsveriet iespēju atjaunot šo profilu",
|
||||
"poor_fit_tip": "Nekonsekventa spēļu vēsture – apsveriet iespēju atjaunot šo profilu",
|
||||
"restart_gap_tip": "{n} HA restartēšanas atstarpe: jaudas trasē ir caurums",
|
||||
"reviewed": "Pārskatīts",
|
||||
"steady": "→ stabils",
|
||||
@@ -57,7 +57,7 @@
|
||||
"create_profile": "+ Izveidojiet profilu",
|
||||
"delete": "Dzēst",
|
||||
"delete_group": "Dzēst grupu",
|
||||
"delete_group_tip": "Dzēst tikai šo grupu — dalībnieku profili tiek saglabāti",
|
||||
"delete_group_tip": "Dzēst tikai šo grupu – dalībnieku profili tiek saglabāti",
|
||||
"delete_profile": "Dzēst profilu",
|
||||
"discard": "Izmest",
|
||||
"discard_tip": "Izmest ierakstīto trasē bez saglabāšanas",
|
||||
@@ -87,7 +87,7 @@
|
||||
"on_cycle_finished": "Cikls ir pabeigts",
|
||||
"on_cycle_started": "Cikls sākās",
|
||||
"pause_cycle": "Pauze",
|
||||
"pause_cycle_tip": "Pauzēt pašreizējo ciklu — ierīce turpinās no pārtraukuma vietas",
|
||||
"pause_cycle_tip": "Pauzēt pašreizējo ciklu – ierīce turpinās no pārtraukuma vietas",
|
||||
"pg_apply_device": "Lietot ierīcei",
|
||||
"pg_autofill": "Automātiskā aizpilde",
|
||||
"play": "Atskaņot",
|
||||
@@ -97,8 +97,8 @@
|
||||
"process_tip": "Saglabāt ierakstīto trasē kā jaunu vai esošu profilu",
|
||||
"rebuild": "Pārbūvēt aploksnes",
|
||||
"rebuild_envelope": "Pārbūvēt aploksni",
|
||||
"rebuild_tip": "Pārrēķināt paredzamo jaudas aploksni (min/maks josla) visiem profiliem no to iezīmētajiem cikliem — palaidiet pēc jaunu ciklu iezīmēšanas vai veco labošanas",
|
||||
"rec_start_tip": "Sākt ierīces jaudas trasē ierakstīšanu — sāciet tieši pirms cikla palaišanas",
|
||||
"rebuild_tip": "Pārrēķināt paredzamo jaudas aploksni (min/maks josla) visiem profiliem no to iezīmētajiem cikliem – palaidiet pēc jaunu ciklu iezīmēšanas vai veco labošanas",
|
||||
"rec_start_tip": "Sākt ierīces jaudas trasē ierakstīšanu – sāciet tieši pirms cikla palaišanas",
|
||||
"rec_stop": "Apturēt",
|
||||
"rec_stop_tip": "Pārtraukt ierakstīšanu un saglabāt uzņemto trasē pārskatīšanai",
|
||||
"record": "Sāciet ierakstīšanu",
|
||||
@@ -182,7 +182,7 @@
|
||||
},
|
||||
"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.",
|
||||
"settings_banner": "{n} iestatījumu konflikts{s} – pārbaudiet iezīmētās sadaļas un labojiet pirms saglabāšanas.",
|
||||
"settings_banner_btn": "Doties uz pirmo",
|
||||
"confidence": {
|
||||
"auto": "Jābūt vienādam vai virs atbilstības sliekšņa ({match})",
|
||||
@@ -451,9 +451,9 @@
|
||||
"show_expected": "Rādīt paredzamo līknes pārklājumu (atbilstošs profils, oranžs)",
|
||||
"show_raw": "Rādīt neapstrādātas kontaktligzdas pārslēgu tiešraides jaudas grafikā",
|
||||
"sparkline": "Neseno ciklu ilguma tendence",
|
||||
"stage2": "2. posms — galvenā līdzība",
|
||||
"stage3": "3. posms — DTW",
|
||||
"stage4": "4. posms — atbilstība",
|
||||
"stage2": "2. posms – galvenā līdzība",
|
||||
"stage3": "3. posms – DTW",
|
||||
"stage4": "4. posms – atbilstība",
|
||||
"status": "Statuss",
|
||||
"tail_trim": "Astes apdare (-es)",
|
||||
"timer_auto_pause": "Automātiska pauze",
|
||||
@@ -561,7 +561,12 @@
|
||||
"flags": "Karodziņi",
|
||||
"include_phase_map": "Iekļaut fāžu karti",
|
||||
"include_settings": "Iekļaut noteikšanas un saskaņošanas iestatījumus",
|
||||
"show_contributor": "Rādīt līdzautoru vārdus"
|
||||
"show_contributor": "Rādīt līdzautoru vārdus",
|
||||
"task_pg_detail": "Cikla simulēšana",
|
||||
"task_split": "Cikla sadalīšana",
|
||||
"task_trim": "Cikla apgriešana",
|
||||
"task_merge": "Ciklu apvienošana",
|
||||
"task_rebuild": "Apvalklīkņu pārbūve"
|
||||
},
|
||||
"log": {
|
||||
"all_levels": "Visi līmeņi",
|
||||
@@ -645,7 +650,7 @@
|
||||
"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.",
|
||||
"artifact_header": "Šajā ciklā konstatētas {n} anomālijas",
|
||||
"artifact_pause_detail": "Jauda krita gandrīz līdz nullei ~{n}s, pēc tam atjaunojās — visticamāk, durvis tika atvērtas cikla vidū vai cikls tika pauzēts.",
|
||||
"artifact_pause_detail": "Jauda krita gandrīz līdz nullei ~{n}s, pēc tam atjaunojās – visticamāk, durvis tika atvērtas cikla vidū vai cikls tika pauzēts.",
|
||||
"artifact_spike_detail": "Pārsniedza parasto jaudas joslu ~{n}s.",
|
||||
"auto_label_intro": "Piešķiriet profilus nemarķētiem cikliem, kuru atbilstības pārliecība notīra slieksni.",
|
||||
"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.",
|
||||
@@ -654,10 +659,10 @@
|
||||
"collecting_data": "Datu vākšana - nepieciešami vēl {need} cikli, lai varētu sākt precizēšanu ({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",
|
||||
"compare_selected_cycles": "Atlasītie cikli (pastāvīgi) – parādīt/slēpt",
|
||||
"consider_new_profile": "Apsveriet iespēju izveidot jaunu profilu.",
|
||||
"coverage_gap": "pēdējiem cikliem nav atbilstoša profila ({pct}% no pēdējiem 30).",
|
||||
"coverage_gap_similar_cycles": "Atrasti {count} līdzīgi nemarķēti cikli — izveidojiet profilu, lai sāktu tos saskaņot.",
|
||||
"coverage_gap_similar_cycles": "Atrasti {count} līdzīgi nemarķēti cikli – izveidojiet profilu, lai sāktu tos saskaņot.",
|
||||
"cycles_deleted": "Dzēsti cikli: {count}",
|
||||
"enough_data": "Pietiek datu mācīšanai ({current}/{min} cikli).",
|
||||
"export_description": "Eksportējiet visus profilus un ciklus uz JSON vai atjaunojiet no iepriekšējās eksportēšanas.",
|
||||
@@ -686,7 +691,7 @@
|
||||
"ml_learned_intro": "Modeļi, kas precīzi pielāgoti šai iekārtai.",
|
||||
"ml_loading": "tiek ielādēts ML…",
|
||||
"ml_settings_intro": "Divi neatkarīgi slēdži: viens piemēro modeļus, kamēr darbojas cikls, otrs ļauj WashData laika gaitā precīzi noregulēt tos jūsu mašīnai.",
|
||||
"name_first_program": "Jums ir pietiekami daudz ciklu — nosauciet savu pirmo programmu, lai sāktu saskaņošanu.",
|
||||
"name_first_program": "Jums ir pietiekami daudz ciklu – nosauciet savu pirmo programmu, lai sāktu saskaņošanu.",
|
||||
"near_duplicate_cluster": "Konstatēts gandrīz dublikāts profilu kopa. Grupēšana ļauj saskaņošanai droši izvēlēties starp līdzīgiem (piemēram, viena un tā pati programma atšķirīgā temperatūrā/griešanā).",
|
||||
"no_cycles_match": "Neviens cikls neatbilst pašreizējam filtram.",
|
||||
"no_cycles_profile": "Šim profilam nav ciklu.",
|
||||
@@ -694,12 +699,12 @@
|
||||
"no_cycles_yet": "Vēl nav reģistrēts neviens cikls.",
|
||||
"no_device_selected": "Nav atlasīta neviena ierīce.",
|
||||
"no_devices": "Vēl nav konfigurēta neviena WashData ierīce.",
|
||||
"no_envelope": "Vēl nav aploksnes — pēc marķēšanas cikliem pārbūvēt.",
|
||||
"no_envelope": "Vēl nav aploksnes – pēc marķēšanas cikliem pārbūvēt.",
|
||||
"no_envelope_overlay": "Pārklāšanai nav pieejama neviena aploksne.",
|
||||
"no_fine_tuned": "Vēl nekas nav precīzi noregulēts — WashData izmanto savus iebūvētos modeļus.",
|
||||
"no_fine_tuned": "Vēl nekas nav precīzi noregulēts – WashData izmanto savus iebūvētos modeļus.",
|
||||
"no_logs": "Vēl nav buferizēts neviens žurnāla ieraksts.",
|
||||
"no_maintenance": "Vēl nav reģistrēta neviena apkope.",
|
||||
"no_match_yet": "Vēl nav saskaņošanas mēģinājuma — tas tiek aizpildīts darbības cikla laikā.",
|
||||
"no_match_yet": "Vēl nav saskaņošanas mēģinājuma – tas tiek aizpildīts darbības cikla laikā.",
|
||||
"no_other_users": "Nav atrasts neviens cits mājas palīga lietotājs.",
|
||||
"no_phases": "Nav noteiktas fāzes.",
|
||||
"no_phases_assigned": "Nav piešķirtas fāzes.",
|
||||
@@ -710,10 +715,10 @@
|
||||
"no_settings_match": "Neviens iestatījums neatbilst \"{q}\"",
|
||||
"no_split_points": "Vēl nav sadalīti punkti.",
|
||||
"no_suggestions": "Nav aktīvu ieteikumu.",
|
||||
"notify_services_hint": "Izmantojiet {entity} pakalpojumu ID (vairākiem — atdaliet ar komatiem). Veidnes mainīgie: {vars}.",
|
||||
"notify_services_hint": "Izmantojiet {entity} pakalpojumu ID (vairākiem – atdaliet ar komatiem). Veidnes mainīgie: {vars}.",
|
||||
"old_actions_warning": "Konfigurēts ar veco darbību redaktoru (tagad noņemts). Tie joprojām aktivizē cikla notikumus, taču tos vairs nevar rediģēt šeit. Pārvērtiet tos par parastu automatizāciju vai noņemiet tos.",
|
||||
"onboarding_progress": "Novēroti cikli: {n} / 3",
|
||||
"onboarding_watching": "Lietojiet ierīci kā parasti — WashData vēro. Pēc 3 cikliem sāksies programmu saskaņošana.",
|
||||
"onboarding_watching": "Lietojiet ierīci kā parasti – WashData vēro. Pēc 3 cikliem sāksies programmu saskaņošana.",
|
||||
"pending_feedback": "Gaida atsauksmes par noteikšanu",
|
||||
"performance_trend": "Veiktspējas tendence ({n} cikli)",
|
||||
"pg_analysis_empty": "Ielādējiet ciklu, lai redzētu atbilstības analīzi.",
|
||||
@@ -748,13 +753,13 @@
|
||||
"restart_gap_footer": "Izcelts diagrammā. Jaudas dati trūkst šiem intervāliem; atbilstības noteikšana izmantoja tikai faktiskos rādījumus.",
|
||||
"restart_gap_header": "{n} HA restartēšanas atstarpe šī cikla laikā",
|
||||
"restart_gap_item": "{dur} atstarpe",
|
||||
"review_confirm_help": "Apstipriniet, vai šis cikls tika noteikts pareizi. Jūsu atsauksmes apmāca modeli jūsu mašīnā — jo vairāk ciklu apstiprināsit, jo labāks atbilstības un veselības novērtējums. Pietiek ar ātru Labu/Sliktu.",
|
||||
"review_confirm_help": "Apstipriniet, vai šis cikls tika noteikts pareizi. Jūsu atsauksmes apmāca modeli jūsu mašīnā – jo vairāk ciklu apstiprināsit, jo labāks atbilstības un veselības novērtējums. Pietiek ar ātru Labu/Sliktu.",
|
||||
"review_in_settings": "Pārskatiet sadaļā Iestatījumi",
|
||||
"review_notes_placeholder": "Piezīmes (pēc izvēles)",
|
||||
"review_notes_tip": "Brīvā teksta piezīmes jūsu uzziņai. Netiek izmantots saskaņošanā vai apmācībā.",
|
||||
"review_profile_tip": "Šī cikla programma ir apzīmēta kā. Ja automātiski noteikta programma bija nepareiza, izlabojiet to šeit — marķējums māca noteikt atbilstību nākamajiem cikliem.",
|
||||
"review_profile_tip": "Šī cikla programma ir apzīmēta kā. Ja automātiski noteikta programma bija nepareiza, izlabojiet to šeit – marķējums māca noteikt atbilstību nākamajiem cikliem.",
|
||||
"review_quality_tip": "Cik tīrs ir šis cikls. Labi = šīs programmas mācību grāmatas piemērs; Slikti = atklāts, bet trokšņains vai netipisks; Nelietojams = nepareizi noteikts (sapludināts, saīsināts vai viltots). Vada veselības rādītāju un to, kuri cikli ir atļauti, lai apmācītu modeli.",
|
||||
"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_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",
|
||||
"saving_triggers_reload": "Saglabāšana aktivizē integrācijas atkārtotu ielādi. HA entītijas var īslaicīgi parādīties kā nepieejamas.",
|
||||
@@ -763,7 +768,7 @@
|
||||
"setting_changed": "Mainīts no {old} uz {new} {date}",
|
||||
"settings_basic_note": "Tiek rādīti būtiskākie iestatījumi. Pārslēdzieties uz Papildu, lai skatītu pilnu sarakstu.",
|
||||
"shape_drift_advisory": "⚠ Formas novirze",
|
||||
"shape_drift_detail": "Šī profila jaudas raksts laika gaitā ir mainījies — iespējama ierīces nodilšana vai nepieciešama apkope (piemēram, atkaļķošana, filtru tīrīšana).",
|
||||
"shape_drift_detail": "Šī profila jaudas raksts laika gaitā ir mainījies – iespējama ierīces nodilšana vai nepieciešama apkope (piemēram, atkaļķošana, filtru tīrīšana).",
|
||||
"show_all_settings": "Rādīt visus iestatījumus",
|
||||
"showing_suggestions": "Tiek rādīts {count} iestatījums ar ieteikumiem.",
|
||||
"split_intro": "Noklikšķiniet uz diagrammas, lai pievienotu vai noņemtu šķelšanās punktu, vai automātiski noteiktu dīkstāves spraugas. Katrs iegūtais segments var iegūt savu profilu.",
|
||||
@@ -789,10 +794,10 @@
|
||||
"toast_revert_failed": "Atgriešana neizdevās: {error}",
|
||||
"toast_reverted": "{key} atgriezts",
|
||||
"toast_save_failed": "Saglabāšana neizdevās: {error}",
|
||||
"trend_duration_longer": "Ilgums kļūst arvien garāks ({pct}%/ciklā) — nesenā vidējā {avg}",
|
||||
"trend_duration_shorter": "Ilguma tendence ir īsāka ({pct}%/cikls) — nesenā vidējā {avg}",
|
||||
"trend_duration_longer": "Ilgums kļūst arvien garāks ({pct}%/ciklā) – nesenā vidējā {avg}",
|
||||
"trend_duration_shorter": "Ilguma tendence ir īsāka ({pct}%/cikls) – nesenā vidējā {avg}",
|
||||
"trend_energy_down": "Enerģijas tendence samazinās ({pct}%/cikls)",
|
||||
"trend_energy_up": "Enerģijas tendence pieaug ({pct}%/ciklā) — nesenā vidējā {avg}",
|
||||
"trend_energy_up": "Enerģijas tendence pieaug ({pct}%/ciklā) – nesenā vidējā {avg}",
|
||||
"trim_intro": "Velciet sarkanos rokturus vai ievadiet vērtības. Viss, kas atrodas ārpus loga, tiek noņemts.",
|
||||
"tuning_suggestions_available": "No novērotajiem cikliem pieejams {count} regulēšanas ieteikums. Tie parādās blakus attiecīgajiem laukiem.",
|
||||
"unsure_detected_prefix": "WashData nav pārliecināts, ka tas ir atklāts",
|
||||
@@ -857,7 +862,9 @@
|
||||
"share_guidelines_title": "Pirms kopīgošanas",
|
||||
"store_download_device_intro": "Pieņemiet katru kopīgoto programmu un tās atskaites ciklus savā ierīcē. Jūsu pašu ierakstītie cikli un statistika netiek ietekmēti.",
|
||||
"store_share_device_intro": "Augšupielādējiet {brand} {model} ar atlasītajiem atskaites cikliem. Citi ar to pašu ierīci var pieņemt jūsu programmas. Ieraksti tiek pārskatīti pirms publiskošanas.",
|
||||
"share_profile_no_cycles": "Nav atskaites ciklu -- atzīmējiet ciklu kā ⭐ cilnē Cikli, lai iekļautu šo profilu"
|
||||
"share_profile_no_cycles": "Nav atskaites ciklu -- atzīmējiet ciklu kā ⭐ cilnē Cikli, lai iekļautu šo profilu",
|
||||
"advisory_phase_inconsistent": "Šķiet, ka '{name}' sajauc dažādas programmas vai temperatūras - tā cikli sildās ļoti atšķirīgu laiku. Sadalot to atsevišķos profilos (piemēram, pēc temperatūras), tiks uzlabota saskaņošana un laika aprēķini.",
|
||||
"advisory_phase_inconsistent_title": "⚠ Iespējams, jauktas programmas"
|
||||
},
|
||||
"phase_desc": {
|
||||
"anti_crease": "Laiku pa laikam pēc pabeigšanas veiciet īsus gājienus, lai samazinātu grumbiņas.",
|
||||
@@ -940,6 +947,10 @@
|
||||
"triggers": {
|
||||
"intro": "Neobligātie ārējie signāli: beigu aktivators, durvju sensors, pauzes slēdzis un izkraušanas atgādinājums.",
|
||||
"label": "Aktivatori un durvis"
|
||||
},
|
||||
"phase_eta": {
|
||||
"label": "Atlikušais laiks",
|
||||
"intro": "Uz fāzēm balstīts atlikušais laiks mašīnām, kuru cikla ilgums ir atkarīgs no temperatūras vai izgriešanas."
|
||||
}
|
||||
},
|
||||
"setting": {
|
||||
@@ -1008,7 +1019,7 @@
|
||||
"label": "Lietot viedos modeļus cikla laikā"
|
||||
},
|
||||
"end_energy_threshold": {
|
||||
"doc": "Izslēgšanas aizkaves atpakaļskaitīšanas laikā uzkrātā enerģija (vati x laiks) tiek salīdzināta ar šo slieksni. Ja tas tiek pārsniegts, atpakaļskaitīšanas laiks tiek atiestatīts — ciklam tiek pievienotas pretburzīšanās un trauku mazgājamās mašīnas žāvēšanas astes, nevis saīsinātas. Paceliet to, ja atdzišanas laikā cikli beidzas pārāk agri; samaziniet to, ja noteikšana ir gausa.",
|
||||
"doc": "Izslēgšanas aizkaves atpakaļskaitīšanas laikā uzkrātā enerģija (vati x laiks) tiek salīdzināta ar šo slieksni. Ja tas tiek pārsniegts, atpakaļskaitīšanas laiks tiek atiestatīts – ciklam tiek pievienotas pretburzīšanās un trauku mazgājamās mašīnas žāvēšanas astes, nevis saīsinātas. Paceliet to, ja atdzišanas laikā cikli beidzas pārāk agri; samaziniet to, ja noteikšana ir gausa.",
|
||||
"label": "Beigu enerģija"
|
||||
},
|
||||
"end_repeat_count": {
|
||||
@@ -1023,6 +1034,10 @@
|
||||
"doc": "Fiksētā cena par kWh, ko izmanto izmaksu skaitļiem, ja iepriekš nav iestatīta reāllaika cenas vienība.",
|
||||
"label": "Fiksētā enerģijas cena (par kWh)"
|
||||
},
|
||||
"energy_sensor": {
|
||||
"doc": "Neobligāts kumulatīvs enerģijas skaitītājs (total_increasing kWh/Wh, piemēram, paša kontaktdakšas kopējais skaitītājs). Ja iestatīts, katra cikla uzrādītā enerģija tiek ņemta no šī skaitītāja rādījuma starpības no sākuma līdz beigām, kas novērš nepietiekamu uzskaiti, ko rada lēni ziņojoša jaudas sensora integrēšana. Atgriežas pie integrētās vērtības, ja rādījuma nav, tā mērvienība nav zināma vai starpība nav pozitīva. Atstājiet tukšu, lai turpinātu integrēt jaudas sensoru.",
|
||||
"label": "Enerģijas skaitītāja entītija"
|
||||
},
|
||||
"expose_debug_entities": {
|
||||
"doc": "Publicējiet papildu diagnostikas HA entītijas (atbilstības ticamība, neskaidrība, stāvokļa iekšējās vērtības). Izslēgts saglabā entītiju sarakstu tīru normālai lietošanai.",
|
||||
"label": "Atklāt atkļūdošanas entītijas"
|
||||
@@ -1056,7 +1071,7 @@
|
||||
"label": "Minimālā jauda"
|
||||
},
|
||||
"ml_training_enabled": {
|
||||
"doc": "Periodiski izpētiet savus pārskatītos ciklus nakti un precizējiet modeļus šai konkrētajai iekārtai. Izmaiņas tiek saglabātas tikai tad, ja tās patiešām iegūst labākus rezultātus ilgstošajos ciklos, tāpēc tas var tikai palīdzēt vai palikt nemainīgs — nekad neatkāpties.",
|
||||
"doc": "Periodiski izpētiet savus pārskatītos ciklus nakti un precizējiet modeļus šai konkrētajai iekārtai. Izmaiņas tiek saglabātas tikai tad, ja tās patiešām iegūst labākus rezultātus ilgstošajos ciklos, tāpēc tas var tikai palīdzēt vai palikt nemainīgs – nekad neatkāpties.",
|
||||
"label": "Mācīties no šīs mašīnas"
|
||||
},
|
||||
"ml_training_hour": {
|
||||
@@ -1220,7 +1235,7 @@
|
||||
"label": "Darbības mirušā zona"
|
||||
},
|
||||
"sampling_interval": {
|
||||
"doc": "Paredzamais laiks starp sensora rādījumiem — tiek izmantots, lai izlīdzinātu logu un sāktu pareizu atlēcienu. Katrs sensora atjauninājums tiek fiksēts neatkarīgi no šīs vērtības; tas tikai kalibrē pakārtotos aprēķinus. Ieteikumu programma mēra jūsu sensora faktisko ritmu no iepriekšējiem cikliem un iestata to automātiski.",
|
||||
"doc": "Paredzamais laiks starp sensora rādījumiem – tiek izmantots, lai izlīdzinātu logu un sāktu pareizu atlēcienu. Katrs sensora atjauninājums tiek fiksēts neatkarīgi no šīs vērtības; tas tikai kalibrē pakārtotos aprēķinus. Ieteikumu programma mēra jūsu sensora faktisko ritmu no iepriekšējiem cikliem un iestata to automātiski.",
|
||||
"label": "Paraugu ņemšanas intervāls"
|
||||
},
|
||||
"save_debug_traces": {
|
||||
@@ -1244,7 +1259,7 @@
|
||||
"label": "Starta slieksnis"
|
||||
},
|
||||
"stop_threshold_w": {
|
||||
"doc": "Pirms izslēgšanas aizkaves atpakaļskaitīšanas sākuma jaudai ir jāsamazinās zem šī līmeņa. Iestatiet to zem sākuma sliekšņa — atstarpe starp tām ir histerēzes josla, kas novērš mirgošanu. Ja iestatīts pārāk augsts, mazjaudas fāzes (skalošanas aizturēšana, pretburzīšanās) kļūdaini aktivizē beigu secību.",
|
||||
"doc": "Pirms izslēgšanas aizkaves atpakaļskaitīšanas sākuma jaudai ir jāsamazinās zem šī līmeņa. Iestatiet to zem sākuma sliekšņa – atstarpe starp tām ir histerēzes josla, kas novērš mirgošanu. Ja iestatīts pārāk augsts, mazjaudas fāzes (skalošanas aizturēšana, pretburzīšanās) kļūdaini aktivizē beigu secību.",
|
||||
"label": "Apstāšanās slieksnis"
|
||||
},
|
||||
"switch_entity": {
|
||||
@@ -1305,6 +1320,38 @@
|
||||
},
|
||||
"show_contributor": {
|
||||
"doc": "Rādīt \"autors: <līdzautors>\" attiecinājumu kopienas ierīcēs un atskaites ciklos."
|
||||
},
|
||||
"enable_phase_matching": {
|
||||
"label": "Uz fāzēm balstīts atlikušais laiks",
|
||||
"doc": "Sadaliet katru notiekošo ciklu fāzēs (sildīšana, mazgāšana, izgriešana) un plānojiet atlikušo laiku katrai fāzei, sajaucot ar klasisko aprēķinu - cikla sākumā paļaujoties uz fāžu plānojumu, bet beigās uz klasisko aprēķinu. Tas pielāgo atpakaļskaitīšanu tam, cik ilgi jūsu mašīna patiešām sildās un darbojas, kas visvairāk pamanāms cikla pirmajā pusē. Izslēgts = tikai klasiskais aprēķins. Tiek ietekmēts tikai atlikušā laika attēlojums; programmu saskaņošana un ciklu noteikšana paliek nemainīga."
|
||||
},
|
||||
"keep_min_score": {
|
||||
"label": "Min. atbilstības rezultāts",
|
||||
"doc": "Zemākais līdzības rezultāts, kas kandidātam vajadzīgs, lai paliktu saskaņošanas procesā. Noklusējums 0,1 ir apzināti ļaujošs – tas pieļauj pat vājus kandidātus un paļaujas uz vēlākajiem posmiem labākā atbilstības atrašanai. Palieliniet, lai agrāk filtrētu maz ticamos profilus; samaziniet, lai paplašinātu sākotnējo kandidātu kopumu."
|
||||
},
|
||||
"dtw_blend": {
|
||||
"label": "DTW sajaukums",
|
||||
"doc": "Cik daudz DTW izlīdzināšanas rezultāts aizstāj 2. posma pamatrezultātu. 0 = izmantojiet tikai 2. posma rezultātu, 1 = izmantojiet tikai DTW rezultātu, 0,5 (noklusējums) = vienāds sajaukums. Palieliniet, lai vairāk paļautos uz laika izlīdzināšanu, ja programmām ir līdzīgi jaudas līmeņi, bet atšķirīgas laika shēmas."
|
||||
},
|
||||
"dtw_ensemble_w": {
|
||||
"label": "DTW ensemble miks",
|
||||
"doc": "Ensemble-DTW režīmā (noklusējums) tas ir svars skalētajam L1 salīdzinājumā ar atvasināto DTW (DDTW). 1,0 = tikai skalētais L1, 0 = tikai DDTW, 0,7 = noklusējums. Skalētā varianta salīdzina jaudas līmeņus; atvasinātā varianta reaģē uz to, kā jauda mainās laika gaitā. Ensemble apvieno abus."
|
||||
},
|
||||
"dtw_ddtw_scale": {
|
||||
"label": "Atv. DTW skāle",
|
||||
"doc": "Atvasinātās DTW vērtēšanas pusiesātinājuma attālums. Rezultāts uz pusēm samazinās, kad DDTW attālums ir vienāds ar šo vērtību. Mazāks = jutīgāks pret formas atšķirībām. Noklusējums 30 ir kalibrēts tipiskajiem sadzīves tehnikas jaudas profiliem. Ietekmē tikai ensemble un ddtw DTW režīmus."
|
||||
},
|
||||
"dtw_refine_top_n": {
|
||||
"label": "DTW precizēšanas skaits",
|
||||
"doc": "Cik daudz 2. posma labāko kandidātu DTW pārvērtē. DTW ir dārgāks, tāpēc tas tiek piemērots tikai N labākajiem. Noklusējums 5. Palieliniet (līdz 7-9), ja pareizais profils dažreiz pēc 2. posma sasniedz tikai 4. vai 5. vietu – DTW var to glābt. Zemāka vērtība nedaudz paātrina saskaņošanu."
|
||||
},
|
||||
"duration_scale": {
|
||||
"label": "Ilguma asums",
|
||||
"doc": "4. posma ilguma atbilstības soda asums. Tas ir logaritmiskais koeficients, pie kura atbilstības rezultāts uz pusēm samazinās. Mazāks = bargāks: ilguma neatbilstība kaitē vairāk. Noklusējums 0,175 atbilst aptuveni 18% ilguma tolerancei pie pus-svara. Izmantojiet kopā ar Ilguma svaru."
|
||||
},
|
||||
"energy_scale": {
|
||||
"label": "Enerģijas asums",
|
||||
"doc": "4. posma enerģijas atbilstības soda asums. Mazāks = bargāks: enerģijas neatbilstība kaitē vairāk. Noklusējums 0,25 ir apzināti piedodošāks nekā ilguma asums, jo enerģija mainās atkarībā no slodzes. Izmantojiet kopā ar Enerģijas svaru."
|
||||
}
|
||||
},
|
||||
"setting_group": {
|
||||
@@ -1553,24 +1600,24 @@
|
||||
"lower": "Automātiski iezīmē vairāk ciklu; daži var tikt nepareizi identificēti"
|
||||
},
|
||||
"duration_tolerance": {
|
||||
"higher": "Pieņem plašāku ilguma diapazonu — elastīgāka atbilstības noteikšana",
|
||||
"lower": "Prasa precīzāku ilguma atbilstību — stingrāks, bet var noraidīt neparastus ciklus"
|
||||
"higher": "Pieņem plašāku ilguma diapazonu – elastīgāka atbilstības noteikšana",
|
||||
"lower": "Prasa precīzāku ilguma atbilstību – stingrāks, bet var noraidīt neparastus ciklus"
|
||||
},
|
||||
"end_energy_threshold": {
|
||||
"higher": "Aizver tikai ciklus, kas patērēja ievērojamu enerģiju",
|
||||
"lower": "Aizver arī īsākus vai zemas enerģijas ciklus"
|
||||
},
|
||||
"end_repeat_count": {
|
||||
"higher": "Prasa beigu signālu atkārtot vairāk reižu — uzticamāks, nedaudz lēnāks",
|
||||
"lower": "Beidz pēc mazākiem atkārtojumiem — ātrāka atklāšana, lielāks viltus beigu risks"
|
||||
"higher": "Prasa beigu signālu atkārtot vairāk reižu – uzticamāks, nedaudz lēnāks",
|
||||
"lower": "Beidz pēc mazākiem atkārtojumiem – ātrāka atklāšana, lielāks viltus beigu risks"
|
||||
},
|
||||
"learning_confidence": {
|
||||
"higher": "Mācās tikai no ļoti pārliecinošām atbilstībām — lēnāks, bet uzticamāks",
|
||||
"higher": "Mācās tikai no ļoti pārliecinošām atbilstībām – lēnāks, bet uzticamāks",
|
||||
"lower": "Mācās no vairākiem cikliem; modelis var būt trokšņaināks"
|
||||
},
|
||||
"min_off_gap": {
|
||||
"higher": "Pirms jauna cikla nepieciešams ilgāks dīkstāves periods",
|
||||
"lower": "Īsa dīkstāve aktivizē jaunu ciklu — secīgas palaišanas var sadalīties"
|
||||
"lower": "Īsa dīkstāve aktivizē jaunu ciklu – secīgas palaišanas var sadalīties"
|
||||
},
|
||||
"min_power": {
|
||||
"higher": "Mazāk jutīgs pret dīkstāves jaudas patēriņu; var palaist garām klusus režīmus",
|
||||
@@ -1581,24 +1628,24 @@
|
||||
"lower": "Piespiedu kārtā aptur iestrēgušu ciklu ātrāk"
|
||||
},
|
||||
"off_delay": {
|
||||
"higher": "Vairāk laika ierīces pauzēm — apstrādā ilgu mērcēšanu vai žāvēšanu",
|
||||
"lower": "Ātrāka beigu atklāšana — labi darbojas skaidrām ieslēgt/izslēgt ierīcēm"
|
||||
"higher": "Vairāk laika ierīces pauzēm – apstrādā ilgu mērcēšanu vai žāvēšanu",
|
||||
"lower": "Ātrāka beigu atklāšana – labi darbojas skaidrām ieslēgt/izslēgt ierīcēm"
|
||||
},
|
||||
"profile_match_threshold": {
|
||||
"higher": "Apstiprina tikai augstas pārliecības atbilstības; vairāk ciklu paliek bez iezīmes",
|
||||
"lower": "Atbilst vairākiem cikliem; daži var būt nedaudz nepareizi"
|
||||
},
|
||||
"running_dead_zone": {
|
||||
"higher": "Ignorē īsus jaudas pieauguma momentus dīkstāvē — mazāk jutīgs pret troksni",
|
||||
"lower": "Reaģē uz īsākiem jaudas uzliesmojumiem — uztver ātru pārejošu aktivitāti"
|
||||
"higher": "Ignorē īsus jaudas pieauguma momentus dīkstāvē – mazāk jutīgs pret troksni",
|
||||
"lower": "Reaģē uz īsākiem jaudas uzliesmojumiem – uztver ātru pārejošu aktivitāti"
|
||||
},
|
||||
"start_threshold_w": {
|
||||
"higher": "Novērš viltus palaišanas no īslaicīgiem jaudas pieaugumiem",
|
||||
"lower": "Uztver mazjaudas programmas; var reaģēt uz troksni"
|
||||
},
|
||||
"stop_threshold_w": {
|
||||
"higher": "Beidz ciklu ātrāk — var aizvērt pauzes laikā",
|
||||
"lower": "Gaida ilgāk līdz beigām — mazāk priekšlaicīgu pabeigšanu"
|
||||
"higher": "Beidz ciklu ātrāk – var aizvērt pauzes laikā",
|
||||
"lower": "Gaida ilgāk līdz beigām – mazāk priekšlaicīgu pabeigšanu"
|
||||
},
|
||||
"watchdog_interval": {
|
||||
"higher": "Atļautas garākas klusas fāzes; mazāk viltus piespiedu apstāšanās",
|
||||
@@ -1676,12 +1723,19 @@
|
||||
"start_duration_threshold": "Sekundes virs sliekšņa, lai apstiprinātu sākumu",
|
||||
"start_threshold_w": "Minimālais vatu skaits, lai skaitītos kā sācies",
|
||||
"stop_threshold_w": "Zem šīs vērtības iekārta skaitās izslēgta",
|
||||
"dtw_bandwidth": "Cik lielu laika deformāciju pieļauj formas saskaņošana",
|
||||
"corr_weight": "Līknes formas un jaudas līmeņa svars saskaņošanā",
|
||||
"duration_weight": "Cik lielā mērā ilguma atbilstība ietekmē saskaņošanu",
|
||||
"energy_weight": "Cik lielā mērā enerģijas atbilstība ietekmē saskaņošanu",
|
||||
"profile_match_min_duration_ratio": "Īsākais cikls (salīdzinot ar profilu), kuram vēl atļauts atbilst",
|
||||
"profile_match_max_duration_ratio": "Garākais cikls (salīdzinot ar profilu), kuram vēl atļauts atbilst"
|
||||
"dtw_bandwidth": "3. posms: Sakoe-Chiba laika locīšanas josla (0 = DTW izslēgts; noklusējums 0,2 = 20% no cikla garuma)",
|
||||
"corr_weight": "2. posms: līdzsvars starp līknes formu (korelācija) un jaudas līmeni (MAE); noklusējums 0,45",
|
||||
"duration_weight": "4. posms: cik stipri ilguma atbilstība ietekmē galīgo rezultātu (noklusējums 0,22)",
|
||||
"energy_weight": "4. posms: cik stipri enerģijas atbilstība ietekmē galīgo rezultātu (noklusējums 0,22)",
|
||||
"profile_match_min_duration_ratio": "1. posms: īsākais cikls kā profila ilguma daļa; noklusējums 0,1 (10%)",
|
||||
"profile_match_max_duration_ratio": "1. posms: garākais cikls kā profila ilguma daļa; noklusējums 1,5 (150%)",
|
||||
"keep_min_score": "2. posms: zemākais rezultāts, lai paliktu sacensībā; noklusējums 0,1 pieļauj vājus kandidātus, vēlākie posmi izvēlas labāko",
|
||||
"dtw_blend": "3. posms: 0 = tikai pamatrezultāts, 1 = tikai DTW rezultāts, 0,5 = vienāds sajaukums (noklusējums)",
|
||||
"dtw_ensemble_w": "3. posms (ensemble režīms): skalētā L1 svars pret atvasinātās DTW; noklusējums 0,7 dod priekšroku līmeņapziņai",
|
||||
"dtw_ddtw_scale": "3. posms: DDTW pusiesātinājuma attālums; mazāks = jutīgāks pret formas atšķirībām (noklusējums 30)",
|
||||
"dtw_refine_top_n": "3. posms: kandidāti, kurus DTW pārvērtē; palieliniet līdz 7-9, ja pareizais profils ierindojas 4.-5. vietā (noklusējums 5)",
|
||||
"duration_scale": "4. posms: logaritmiskais koeficients, kur ilguma atbilstība uz pusēm; mazāks = bargāks sods (noklusējums 0,175)",
|
||||
"energy_scale": "4. posms: logaritmiskais koeficients, kur enerģijas atbilstība uz pusēm; mazāks = bargāks sods (noklusējums 0,25)"
|
||||
},
|
||||
"col": {
|
||||
"profile_tip": "Atbilstošās programmas nosaukums. Bez birkas nozīmē, ka cikla beigās neatbilda neviens profils.",
|
||||
@@ -1766,6 +1820,69 @@
|
||||
},
|
||||
"pg_sweep": {
|
||||
"optimize": "Optimizēšana: {param}"
|
||||
},
|
||||
"pg_detail": {
|
||||
"simulate": "Cikla simulēšana"
|
||||
},
|
||||
"split": {
|
||||
"apply": "Cikla sadalīšana"
|
||||
},
|
||||
"trim": {
|
||||
"apply": "Cikla apgriešana"
|
||||
},
|
||||
"merge": {
|
||||
"apply": "Ciklu apvienošana"
|
||||
},
|
||||
"rebuild": {
|
||||
"envelopes": "Apvalklīkņu pārbūve"
|
||||
},
|
||||
"cancelling": "Atceļ..."
|
||||
},
|
||||
"setup": {
|
||||
"hdr": {
|
||||
"card": "Ierīces iestatīšana",
|
||||
"healthy_chip": "Iestatīšana pabeigta"
|
||||
},
|
||||
"phase0": {
|
||||
"washer": "WashData jau konstatē jūsu ciklus. Ierakstiet pirmo ciklu, lai aktivizētu programmu nosaukumus un laika aprēķinus.",
|
||||
"dishwasher": "WashData vēro. Trauku mazgājamām mašīnām ir sarežģīti cikli – ir ļoti ieteicams ierakstīt pirmo ciklu. Ja konstatētais cikls darbojas pārāk ilgi, pirms saglabāšanas kā profilu izmantojiet cikla redaktoru, lai to apgrieztu.",
|
||||
"generic": "WashData vēro. Ierakstiet vai iezīmējiet konstatētu ciklu, lai sāktu veidot profilus."
|
||||
},
|
||||
"phase1a": {
|
||||
"labelled": "Labs sākums – jūsu pirmā programma ir saglabāta. Lai iegūtu tīrākos datus, apsveriet iespēju ierakstīt nākamo ciklu ar ierakstīšanas logrīku."
|
||||
},
|
||||
"phase1b": {
|
||||
"recorded": "Jūsu ieraksts ir saglabāts kā {profile_name}. Tagad ierakstiet vai iezīmējiet citas bieži izmantotās programmas, lai paplašinātu pārklājumu."
|
||||
},
|
||||
"phase1c": {
|
||||
"verify": "Jums ir {count} programmas no kopienas. Palaidiet ciklu, lai pārbaudītu, vai WashData to pareizi atpazīst – atbilstība uzlabosies, kad jūsu ierīce veidos savu vēsturi."
|
||||
},
|
||||
"phase2": {
|
||||
"cluster": "WashData ir konstatējis {count} ciklus, kas neatbilst nevienai saglabātai programmai – tie izskatās līdzīgi viens otram. Vai vēlaties tiem izveidot jaunu profilu?",
|
||||
"unmatched": "Pēdējais cikls neatbilda nevienai saglabātai programmai. Vai tā ir jauna programma?"
|
||||
},
|
||||
"phase3": {
|
||||
"suggestions": "WashData ir iestatījumu ieteikumi, pamatojoties uz jūsu ciklu vēsturi – pārskatiet tos, lai uzlabotu noteikšanas precizitāti.",
|
||||
"groups": "Daži jūsu profili izskatās kā viena un tā pati programma dažādās temperatūrās. Sakārtojiet tos grupā labākai atbilstībai.",
|
||||
"phases": "Pievienojiet programmas fāzes profilam {profile_name}, lai iegūtu precīzākus laika atlikuma aprēķinus."
|
||||
},
|
||||
"phase4": {
|
||||
"healthy": "Šī ierīce ir pilnīgi iestatīta ({profile_count} profili)."
|
||||
},
|
||||
"cta": {
|
||||
"start_recording": "Sākt ierakstīšanu",
|
||||
"label_detected_cycle": "Man jau ir konstatēts cikls – iezīmēt to",
|
||||
"browse_cycles": "Pārlūkot ciklus, lai iezīmētu citu",
|
||||
"view_profiles": "Skatīt savus profilus",
|
||||
"create_from_cluster": "Izveidot profilu no šiem cikliem",
|
||||
"create_profile": "Izveidot tam profilu",
|
||||
"review_suggestions": "Pārskatīt ieteikumus",
|
||||
"organise_profiles": "Kārtot profilus",
|
||||
"configure_phases": "Konfigurēt fāzes",
|
||||
"skip_step": "Izlaist šo soli",
|
||||
"skip_forever": "Vairs nerādīt",
|
||||
"hide_guidance": "Slēpt norādījumus",
|
||||
"show_guidance": "Rādīt norādījumus"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
"on_cycle_finished": "На циклус заврши",
|
||||
"on_cycle_started": "На циклус започна",
|
||||
"pause_cycle": "Пауза",
|
||||
"pause_cycle_tip": "Паузирај го тековниот циклус — апаратот ќе продолжи од местото каде застанал",
|
||||
"pause_cycle_tip": "Паузирај го тековниот циклус – апаратот ќе продолжи од местото каде застанал",
|
||||
"pg_apply_device": "Примени на уредот",
|
||||
"pg_autofill": "Автоматско пополнување",
|
||||
"play": "Пушти",
|
||||
@@ -97,8 +97,8 @@
|
||||
"process_tip": "Зачувај го снимениот траг како нов или постоечки профил",
|
||||
"rebuild": "Обновете ги пликовите",
|
||||
"rebuild_envelope": "Обновете го пликот",
|
||||
"rebuild_tip": "Препресметај го очекуваниот плик на моќноста (мин./макс. лента) за сите профили од нивните означени циклуси — извршете после означување на нови циклуси или поправање на стари",
|
||||
"rec_start_tip": "Почнете снимање на трагот на моќноста на апаратот — стартувајте непосредно пред почеток на циклусот",
|
||||
"rebuild_tip": "Препресметај го очекуваниот плик на моќноста (мин./макс. лента) за сите профили од нивните означени циклуси – извршете после означување на нови циклуси или поправање на стари",
|
||||
"rec_start_tip": "Почнете снимање на трагот на моќноста на апаратот – стартувајте непосредно пред почеток на циклусот",
|
||||
"rec_stop": "Стоп",
|
||||
"rec_stop_tip": "Запрете го снимањето и задржете го снимениот траг за преглед",
|
||||
"record": "Започнете со снимање",
|
||||
@@ -182,7 +182,7 @@
|
||||
},
|
||||
"attn_sub": "Поправете ги конфликтите пред зачувување",
|
||||
"attn_title": "{n} конфликт{s} во поставките",
|
||||
"settings_banner": "{n} конфликт{s} во поставките — проверете ги означените раздели и поправете пред зачувување.",
|
||||
"settings_banner": "{n} конфликт{s} во поставките – проверете ги означените раздели и поправете пред зачувување.",
|
||||
"settings_banner_btn": "Оди на прв",
|
||||
"confidence": {
|
||||
"auto": "Мора да е на или над Прагот за Совпаѓање ({match})",
|
||||
@@ -451,9 +451,9 @@
|
||||
"show_expected": "Прикажи очекувано преклопување на кривата (совпаднат профил, портокалова)",
|
||||
"show_raw": "Прикажи прекинувач за необработени отчитувања на приклучокот во живиот графикон на моќноста",
|
||||
"sparkline": "Неодамнешен тренд на времетраење на циклусите",
|
||||
"stage2": "Етапа 2 — основна сличност",
|
||||
"stage3": "Етапа 3 — DTW",
|
||||
"stage4": "Етапа 4 — согласување",
|
||||
"stage2": "Етапа 2 – основна сличност",
|
||||
"stage3": "Етапа 3 – DTW",
|
||||
"stage4": "Етапа 4 – согласување",
|
||||
"status": "Статус",
|
||||
"tail_trim": "Намалување на опашката (и)",
|
||||
"timer_auto_pause": "Автоматска пауза",
|
||||
@@ -561,7 +561,12 @@
|
||||
"flags": "Ознаки",
|
||||
"include_phase_map": "Вклучи карта на фазите",
|
||||
"include_settings": "Вклучи поставки",
|
||||
"show_contributor": "Прикажи соработник"
|
||||
"show_contributor": "Прикажи соработник",
|
||||
"task_pg_detail": "Симулирај циклус",
|
||||
"task_split": "Разделување на циклус",
|
||||
"task_trim": "Отсекување на циклус",
|
||||
"task_merge": "Спојување на циклуси",
|
||||
"task_rebuild": "Повторно градење на обвивки"
|
||||
},
|
||||
"log": {
|
||||
"all_levels": "Сите нивоа",
|
||||
@@ -645,19 +650,19 @@
|
||||
"artifact_dip_detail": "Падна под вообичаениот опсег на моќност за ~{n}с.",
|
||||
"artifact_footer": "Нагласено на графиконот погоре. Ова се минливи артефакти (на пр. вратата отворена во средината на циклусот), а не нужно проблеми.",
|
||||
"artifact_header": "{n} откриени аномалии за време на овој циклус",
|
||||
"artifact_pause_detail": "Моќноста падна до скоро нула за ~{n}с потоа продолжи — веројатно вратата беше отворена во средината на циклусот или циклусот беше паузиран.",
|
||||
"artifact_pause_detail": "Моќноста падна до скоро нула за ~{n}с потоа продолжи – веројатно вратата беше отворена во средината на циклусот или циклусот беше паузиран.",
|
||||
"artifact_spike_detail": "Надмина го вообичаениот опсег на моќност за ~{n}с.",
|
||||
"auto_label_intro": "Доделете профили на неозначени циклуси чијашто доверба за совпаѓање го брише прагот.",
|
||||
"automations_intro": "WashData активира настани {start} / {end} и изложува ентитети, па известувањата и акциите е најдобро да се градат како нормални автоматизации на Home Assistant. Автоматизациите кои го користат овој уред се прикажани подолу.",
|
||||
"cleanup_intro": "Секој означен циклус е преклопен. Штиклирајте ги оддалечените и избришете за да го исчистите профилот.",
|
||||
"clear_debug_hint": "Отстранете ги зачуваните податоци за отстранување грешки за да ослободите простор.",
|
||||
"collecting_data": "Собирање на податоци — уште {need} циклус{plural} пред почетокот на финото подесување ({current}/{min}).",
|
||||
"collecting_data": "Собирање на податоци – уште {need} циклус{plural} пред почетокот на финото подесување ({current}/{min}).",
|
||||
"compare_overlay_profiles": "Преклопени профили (бледо)",
|
||||
"compare_profiles_tip": "Преклопете ги другите пликови на профили на табелата погоре за да видите кој најдобро одговара на овој циклус.",
|
||||
"compare_selected_cycles": "Избрани циклуси (цврсти) - прикажи / скриј",
|
||||
"consider_new_profile": "Размислете за создавање нов профил.",
|
||||
"coverage_gap": "последните циклуси немаат соодветни профили ({pct}% од последните 30).",
|
||||
"coverage_gap_similar_cycles": "{count} слични необележани циклуси пронајдени — направете профил за да започнете да ги совпаѓате.",
|
||||
"coverage_gap_similar_cycles": "{count} слични необележани циклуси пронајдени – направете профил за да започнете да ги совпаѓате.",
|
||||
"cycles_deleted": "Избришани се {count} циклуси",
|
||||
"enough_data": "Доволно податоци за учење ({current}/{min} циклуси).",
|
||||
"export_description": "Извезете ги сите профили и циклуси во JSON или вратете ги од претходен извоз.",
|
||||
@@ -686,7 +691,7 @@
|
||||
"ml_learned_intro": "Модели фино подесени на оваа машина.",
|
||||
"ml_loading": "се вчитува ML…",
|
||||
"ml_settings_intro": "Два независни прекинувачи: едниот ги применува моделите додека работи циклусот, другиот дозволува WashData фино да ги прилагоди на вашата машина со текот на времето.",
|
||||
"name_first_program": "Имате доволно циклуси — именувајте ја вашата прва програма за да започне совпаѓањето.",
|
||||
"name_first_program": "Имате доволно циклуси – именувајте ја вашата прва програма за да започне совпаѓањето.",
|
||||
"near_duplicate_cluster": "Откриена е скоро дупликат профилна група. Групирањето овозможува совпаѓањето со сигурност да се избере помеѓу сличните (на пр. иста програма на различна температура/вртење).",
|
||||
"no_cycles_match": "Ниту еден циклус не одговара на тековниот филтер.",
|
||||
"no_cycles_profile": "Нема циклуси за овој профил.",
|
||||
@@ -713,7 +718,7 @@
|
||||
"notify_services_hint": "Користете ID-ови на сервисите {entity} (одвоени со запирки за повеќе). Варијабли на шаблонот: {vars}.",
|
||||
"old_actions_warning": "Конфигуриран со стариот уредувач на дејства (сега отстранет). Сè уште пукаат на настани од циклусот, но веќе не може да се уредуваат овде. Претворете ги во нормална автоматизација или отстранете ги.",
|
||||
"onboarding_progress": "{n} / 3 набљудувани циклуси",
|
||||
"onboarding_watching": "Користете го апаратот како вообичаено — WashData набљудува. По 3 циклуси, ќе започне совпаѓањето на програми.",
|
||||
"onboarding_watching": "Користете го апаратот како вообичаено – WashData набљудува. По 3 циклуси, ќе започне совпаѓањето на програми.",
|
||||
"pending_feedback": "Во очекување на повратни информации за откривање",
|
||||
"performance_trend": "Тренд на изведба ({n} циклуси)",
|
||||
"pg_analysis_empty": "Вчитајте циклус за да видите анализа на совпаѓање.",
|
||||
@@ -763,7 +768,7 @@
|
||||
"setting_changed": "Променето од {old} на {new} на {date}",
|
||||
"settings_basic_note": "Прикажани се основните поставки. Префрлете се на Напредно за целосната листа.",
|
||||
"shape_drift_advisory": "⚠ Форма дрифт",
|
||||
"shape_drift_detail": "Обрасецот на моќноста за овој профил се промени со текот на времето — можно е трошење на апаратот или потребно е одржување (на пр. одкаменување, чистење на филтерот).",
|
||||
"shape_drift_detail": "Обрасецот на моќноста за овој профил се промени со текот на времето – можно е трошење на апаратот или потребно е одржување (на пр. одкаменување, чистење на филтерот).",
|
||||
"show_all_settings": "Прикажи ги сите поставки",
|
||||
"showing_suggestions": "Се прикажува поставката {count} со предлози.",
|
||||
"split_intro": "Кликнете на графиконот за да додадете или отстраните точка на разделување или автоматско откривање со празнини во мирување. Секој добиен сегмент може да добие свој профил.",
|
||||
@@ -857,7 +862,9 @@
|
||||
"share_guidelines_title": "Пред споделување",
|
||||
"store_download_device_intro": "Преземете поставки на уредот од заедницата и применете ги на нов или постоечки уред",
|
||||
"store_share_device_intro": "Споделете ги програмите на вашиот уред (профили + референтни циклуси) со заедницата. Поставките се опционални.",
|
||||
"share_profile_no_cycles": "Профилот '{p}' нема ⭐ референтни циклуси -- ќе биде прескокнат освен ако немате {n}+ потврдени стартувања"
|
||||
"share_profile_no_cycles": "Профилот '{p}' нема ⭐ референтни циклуси -- ќе биде прескокнат освен ако немате {n}+ потврдени стартувања",
|
||||
"advisory_phase_inconsistent": "Изгледа дека '{name}' меша различни програми или температури - неговите циклуси се загреваат многу различно долго. Поделбата на посебни профили (на пр. по температура) ќе ги подобри совпаѓањето и проценките на времето.",
|
||||
"advisory_phase_inconsistent_title": "⚠ Можеби измешани програми"
|
||||
},
|
||||
"phase_desc": {
|
||||
"anti_crease": "Повремени кратки превртувања по завршувањето за да се намалат брчките.",
|
||||
@@ -940,6 +947,10 @@
|
||||
"triggers": {
|
||||
"intro": "Опционални надворешни сигнали: тригер за крај, сензор за врата, прекинувач за пауза и потсетник за истовар.",
|
||||
"label": "Тригери и врати"
|
||||
},
|
||||
"phase_eta": {
|
||||
"label": "Преостанато време",
|
||||
"intro": "Проценка на преостанатото време, свесна за фазите, за машини чија должина на циклусот зависи од температурата или центрифугирањето."
|
||||
}
|
||||
},
|
||||
"setting": {
|
||||
@@ -1023,6 +1034,10 @@
|
||||
"doc": "Фиксна цена по kWh што се користи за бројките на трошоците кога не е поставен ентитет на цена во живо погоре.",
|
||||
"label": "Статична цена на енергија (по kWh)"
|
||||
},
|
||||
"energy_sensor": {
|
||||
"doc": "Изборен кумулативен бројач на енергија (total_increasing kWh/Wh, на пр. сопствениот бројач за вкупната потрошувачка на приклучокот). Кога е поставен, енергијата пријавена за секој циклус се зема од разликата во отчитувањата на овој бројач меѓу почетокот и крајот, што го избегнува потценувањето што се добива при интегрирање на бавно известувачки сензор за моќност. Се враќа на интегрираната вредност ако отчитувањето недостасува, неговата единица е непозната или разликата не е позитивна. Оставете празно за да продолжите да го интегрирате сензорот за моќност.",
|
||||
"label": "Ентитет на мерач на енергија"
|
||||
},
|
||||
"expose_debug_entities": {
|
||||
"doc": "Објавувајте дополнителни дијагностички HA ентитети (доверба на натпреварот, двосмисленост, внатрешни работи). Исклучено го одржува списокот со ентитети чист за нормална употреба.",
|
||||
"label": "Изложи ентитети за дебагирање"
|
||||
@@ -1305,6 +1320,38 @@
|
||||
},
|
||||
"show_contributor": {
|
||||
"doc": "Прикажи го името на соработникот на профилите преземени од продавницата на заедницата"
|
||||
},
|
||||
"enable_phase_matching": {
|
||||
"label": "Преостанато време според фазите",
|
||||
"doc": "Го дели секој активен циклус на фази (загревање, перење, центрифугирање) и го распределува преостанатото време по фази, во комбинација со класичната проценка - потпирајќи се на распределбата по фази на почетокот на циклусот, а на класичната проценка кон крајот. Ова го прилагодува одбројувањето на тоа колку навистина се загрева и работи вашата машина, што е најзабележливо во првата половина од циклусот. Исклучено = само класичната проценка. Влијае само на приказот на преостанатото време; совпаѓањето на програми и откривањето на циклуси остануваат непроменети."
|
||||
},
|
||||
"keep_min_score": {
|
||||
"label": "Мин. резултат на совпаѓање",
|
||||
"doc": "Минимален резултат на сличност потребен на кандидатот за да остане во трката на совпаѓање. Стандардната вредност 0,1 е намерно попустлива - прифаќа дури и слаби кандидати и се потпира на подоцнежните фази за наоѓање на најдоброто совпаѓање. Зголемете за порано отфрлање на малку веројатни профили; намалете за проширување на почетниот сет на кандидати."
|
||||
},
|
||||
"dtw_blend": {
|
||||
"label": "Мешање на деформација",
|
||||
"doc": "Колку DTW резултатот на порамнување го заменува основниот резултат на Фаза 2. 0 = користи само резултат на Фаза 2, 1 = користи само DTW резултат, 0,5 (стандардно) = еднакво мешање. Зголемете за поголемо потпирање на warp порамнување кога програмите имаат слични нивоа на моќност но различни временски обрасци."
|
||||
},
|
||||
"dtw_ensemble_w": {
|
||||
"label": "Микс на комбинација DTW",
|
||||
"doc": "Во комбинираниот DTW режим (стандардниот), тежина на скалиран L1 наспроти изводен DTW (DDTW). 1,0 = само скалиран L1, 0 = само DDTW, 0,7 = стандардно. Скалираната варијанта L1 ги споредува нивоата на моќност; изводната варијанта реагира на промените на моќноста низ времето. Комбинираниот режим ги спојува двете."
|
||||
},
|
||||
"dtw_ddtw_scale": {
|
||||
"label": "Скала на изводна деформација",
|
||||
"doc": "Растојание на пол-заситување за оценување со изводен DTW. Резултатот се преполовува кога растојанието DDTW е еднакво на оваа вредност. Помало = поосетливо на разлики во форма. Стандардната вредност 30 е калибрирана за типични траги на моќност на домашни апарати. Влијае само на комбинираниот и ddtw режим на DTW."
|
||||
},
|
||||
"dtw_refine_top_n": {
|
||||
"label": "Број на прецизирани кандидати",
|
||||
"doc": "Колку врвни кандидати на Фаза 2 DTW повторно ги оценува. DTW е поскап па се применува само за N најдобри кандидати. Стандардно 5. Зголемете (на 7-9) ако правилниот профил понекогаш достигнува само 4. или 5. место по Фаза 2 - DTW може да го спаси. Намалувањето малку го забрзува совпаѓањето."
|
||||
},
|
||||
"duration_scale": {
|
||||
"label": "Острина на траење",
|
||||
"doc": "Острина на казната за несовпаѓање на траење во Фаза 4. Ова е лог-однос при кој резултатот на согласност се преполовува. Помал = построг: несовпаѓањето на траење повеќе го намалува резултатот. Стандардната вредност 0,175 одговара на толеранција на траење од околу 18% при пол-тежина. Употребувајте заедно со Тежината на траење."
|
||||
},
|
||||
"energy_scale": {
|
||||
"label": "Острина на енергија",
|
||||
"doc": "Острина на казната за несовпаѓање на енергија во Фаза 4. Помал = построг: несовпаѓањето на енергија повеќе го намалува резултатот. Стандардната вредност 0,25 е намерно попустлива отколку Острината на траење бидејќи енергијата варира со оптоварувањето. Употребувајте заедно со Тежината на енергија."
|
||||
}
|
||||
},
|
||||
"setting_group": {
|
||||
@@ -1553,24 +1600,24 @@
|
||||
"lower": "Автоматски означува повеќе циклуси; некои може да бидат погрешно идентификувани"
|
||||
},
|
||||
"duration_tolerance": {
|
||||
"higher": "Прифаќа поширок опсег на траење — пофлексибилно поврзување",
|
||||
"lower": "Бара поточно совпаѓање на траење — построго, но може да ги отфрли невообичаените циклуси"
|
||||
"higher": "Прифаќа поширок опсег на траење – пофлексибилно поврзување",
|
||||
"lower": "Бара поточно совпаѓање на траење – построго, но може да ги отфрли невообичаените циклуси"
|
||||
},
|
||||
"end_energy_threshold": {
|
||||
"higher": "Затвора само циклуси со значителна потрошувачка на енергија",
|
||||
"lower": "Затвора и пократки или понискоенергетски циклуси"
|
||||
},
|
||||
"end_repeat_count": {
|
||||
"higher": "Бара сигналот за крај да се повтори повеќе пати — посигурно, малку побавно",
|
||||
"lower": "Завршува по помалку повторувања — побрзо откривање, поголем ризик од лажен крај"
|
||||
"higher": "Бара сигналот за крај да се повтори повеќе пати – посигурно, малку побавно",
|
||||
"lower": "Завршува по помалку повторувања – побрзо откривање, поголем ризик од лажен крај"
|
||||
},
|
||||
"learning_confidence": {
|
||||
"higher": "Учи само од многу сигурни совпаѓања — побавно, но посигурно",
|
||||
"higher": "Учи само од многу сигурни совпаѓања – побавно, но посигурно",
|
||||
"lower": "Учи од повеќе циклуси; моделот може да биде позашумен"
|
||||
},
|
||||
"min_off_gap": {
|
||||
"higher": "Потребен е подолг период на неактивност пред нов циклус",
|
||||
"lower": "Краток период на неактивност стартува нов циклус — последователните работи може да се поделат"
|
||||
"lower": "Краток период на неактивност стартува нов циклус – последователните работи може да се поделат"
|
||||
},
|
||||
"min_power": {
|
||||
"higher": "Помалку чувствителен на фонска потрошувачка; може да ги пропушти тивките програми",
|
||||
@@ -1581,24 +1628,24 @@
|
||||
"lower": "Принудно запира заглавен циклус побрзо"
|
||||
},
|
||||
"off_delay": {
|
||||
"higher": "Повеќе време за паузи на уредот — управува со долго натопување или сушење",
|
||||
"lower": "Побрзо откривање на крај — добро за уреди со јасно вкл./искл."
|
||||
"higher": "Повеќе време за паузи на уредот – управува со долго натопување или сушење",
|
||||
"lower": "Побрзо откривање на крај – добро за уреди со јасно вкл./искл."
|
||||
},
|
||||
"profile_match_threshold": {
|
||||
"higher": "Потврдува само совпаѓања со висока сигурност; повеќе циклуси остануваат без ознака",
|
||||
"lower": "Поврзува повеќе циклуси; некои може да бидат малку погрешни"
|
||||
},
|
||||
"running_dead_zone": {
|
||||
"higher": "Ги игнорира кратките скокови на моќност во неактивност — помалку чувствителен на шум",
|
||||
"lower": "Реагира на пократки наплив на моќност — ги фаќа брзите преодни активности"
|
||||
"higher": "Ги игнорира кратките скокови на моќност во неактивност – помалку чувствителен на шум",
|
||||
"lower": "Реагира на пократки наплив на моќност – ги фаќа брзите преодни активности"
|
||||
},
|
||||
"start_threshold_w": {
|
||||
"higher": "Избегнува лажни стартови од кратковремени скокови на моќност",
|
||||
"lower": "Ги фаќа програмите со мала моќност; може да се активира на шум"
|
||||
},
|
||||
"stop_threshold_w": {
|
||||
"higher": "Го завршува циклусот побрзо — може да затвори за време на пауза",
|
||||
"lower": "Чека подолго за завршување — помалку предвремени завршувања"
|
||||
"higher": "Го завршува циклусот побрзо – може да затвори за време на пауза",
|
||||
"lower": "Чека подолго за завршување – помалку предвремени завршувања"
|
||||
},
|
||||
"watchdog_interval": {
|
||||
"higher": "Дозволени подолги тивки фази; помалку лажни принудни запирања",
|
||||
@@ -1676,12 +1723,19 @@
|
||||
"start_duration_threshold": "Секунди над прагот за потврда на стартот",
|
||||
"start_threshold_w": "Минимум вати за да се смета за започнато",
|
||||
"stop_threshold_w": "Под ова, машината се смета за исклучена",
|
||||
"dtw_bandwidth": "Колку временско растегнување дозволува совпаѓањето по форма",
|
||||
"corr_weight": "Тежина на формата на кривата наспроти нивото на моќност при совпаѓањето",
|
||||
"duration_weight": "Колку согласувањето на времетраењето влијае на совпаѓањето",
|
||||
"energy_weight": "Колку согласувањето на потрошувачката на енергија влијае на совпаѓањето",
|
||||
"profile_match_min_duration_ratio": "Најкратко извршување (во однос на профилот) што сè уште може да се совпадне",
|
||||
"profile_match_max_duration_ratio": "Најдолго извршување (во однос на профилот) што сè уште може да се совпадне"
|
||||
"dtw_bandwidth": "Фаза 3: warp лента на Sakoe-Chiba (0 = DTW исклучен; стандардно 0,2 = 20% од должината на циклусот)",
|
||||
"corr_weight": "Фаза 2: рамнотежа помеѓу обликот на кривата (корелација) и нивото на моќност (MAE); стандардно 0,45",
|
||||
"duration_weight": "Фаза 4: колку силно согласноста на траење влијае на конечниот резултат (стандардно 0,22)",
|
||||
"energy_weight": "Фаза 4: колку силно согласноста на енергија влијае на конечниот резултат (стандардно 0,22)",
|
||||
"profile_match_min_duration_ratio": "Фаза 1: минимална должина на циклус како дел од траењето на профилот; стандардно 0,1 (10%)",
|
||||
"profile_match_max_duration_ratio": "Фаза 1: максимална должина на циклус како дел од траењето на профилот; стандардно 1,5 (150%)",
|
||||
"keep_min_score": "Фаза 2: минимален резултат за останување во трката; стандардно 0,1 прифаќа слаби совпаѓања, подоцнежните фази го избираат најдоброто",
|
||||
"dtw_blend": "Фаза 3: 0 = само основен резултат, 1 = само DTW резултат, 0,5 = еднакво мешање (стандардно)",
|
||||
"dtw_ensemble_w": "Фаза 3 (комбиниран режим): тежина на скалиран L1 наспроти изводен DTW; стандардно 0,7 ги фаворизира нивоата",
|
||||
"dtw_ddtw_scale": "Фаза 3: растојание на пол-заситување на DDTW; помало = поосетливо на форма (стандардно 30)",
|
||||
"dtw_refine_top_n": "Фаза 3: кандидати кои DTW повторно ги оценува; зголемете на 7-9 ако правилниот профил заземе 4.-5. место (стандардно 5)",
|
||||
"duration_scale": "Фаза 4: лог-однос каде согласноста на траење се преполовува; помал = построга казна (стандардно 0,175)",
|
||||
"energy_scale": "Фаза 4: лог-однос каде согласноста на енергија се преполовува; помал = построга казна (стандардно 0,25)"
|
||||
},
|
||||
"col": {
|
||||
"profile_tip": "Име на совпаднатата програма. „Неозначено“ значи дека на крајот на циклусот не се совпадна ниту еден профил.",
|
||||
@@ -1766,6 +1820,68 @@
|
||||
},
|
||||
"pg_sweep": {
|
||||
"optimize": "Оптимизирање: {param}"
|
||||
},
|
||||
"pg_detail": {
|
||||
"simulate": "Симулирај циклус"
|
||||
},
|
||||
"split": {
|
||||
"apply": "Разделување на циклус"
|
||||
},
|
||||
"trim": {
|
||||
"apply": "Отсекување на циклус"
|
||||
},
|
||||
"merge": {
|
||||
"apply": "Спојување на циклуси"
|
||||
},
|
||||
"rebuild": {
|
||||
"envelopes": "Повторно градење на обвивки"
|
||||
}
|
||||
},
|
||||
"setup": {
|
||||
"hdr": {
|
||||
"card": "Поставување на уред",
|
||||
"healthy_chip": "Поставувањето е завршено"
|
||||
},
|
||||
"phase0": {
|
||||
"washer": "WashData веќе ги открива вашите циклуси. Снимете го првиот циклус за да ги овозможите имињата на програмите и проценките на времето.",
|
||||
"dishwasher": "WashData набљудува. Машините за миење садови имаат сложени циклуси – снимањето на првиот циклус е изразито препорачано. Ако открит циклус трае предолго, користете го уредувачот на циклуси за скратување пред зачувување како профил.",
|
||||
"generic": "WashData набљудува. Снимете или означете откриен циклус за да започнете со градење профили."
|
||||
},
|
||||
"phase1a": {
|
||||
"labelled": "Добар почеток – вашата прва програма е зачувана. За најчисти податоци, размислете за снимање на следниот циклус со додатокот за снимање."
|
||||
},
|
||||
"phase1b": {
|
||||
"recorded": "Вашата снимка е зачувана како {profile_name}. Сега снимете или означете ги другите чести програми за да ја проширите покриеноста."
|
||||
},
|
||||
"phase1c": {
|
||||
"verify": "Имате {count} програми од заедницата. Стартувајте циклус за да проверите дали WashData ги препознава правилно – совпаѓањето ќе се подобрува додека вашиот уред ја гради сопствената историја."
|
||||
},
|
||||
"phase2": {
|
||||
"cluster": "WashData видел {count} циклуси кои не одговараат на ниедна зачувана програма – меѓусебно си наликуваат. Сакате ли за нив да создадете нов профил?",
|
||||
"unmatched": "Вашиот последен циклус не одговараше на ниедна зачувана програма. Дали е тоа нова програма?"
|
||||
},
|
||||
"phase3": {
|
||||
"suggestions": "WashData има препораки за поставки засновани на историјата на вашите циклуси – прегледајте ги за подобрување на точноста на откривање.",
|
||||
"groups": "Некои од вашите профили изгледаат како иста програма на различни температури. Организирајте ги во група за подобро совпаѓање.",
|
||||
"phases": "Додадете фази на програмата кон {profile_name} за попрецизни проценки на преостанатото време."
|
||||
},
|
||||
"phase4": {
|
||||
"healthy": "Овој уред е целосно поставен ({profile_count} профили)."
|
||||
},
|
||||
"cta": {
|
||||
"start_recording": "Започни снимање",
|
||||
"label_detected_cycle": "Веќе имам откриен циклус – означи го наместо тоа",
|
||||
"browse_cycles": "Прелистај циклуси за означување на следниот",
|
||||
"view_profiles": "Погледни ги вашите профили",
|
||||
"create_from_cluster": "Создај профил од овие циклуси",
|
||||
"create_profile": "Создај за него профил",
|
||||
"review_suggestions": "Прегледај препораки",
|
||||
"organise_profiles": "Организирај профили",
|
||||
"configure_phases": "Конфигурирај фази",
|
||||
"skip_step": "Прескокни го овој чекор",
|
||||
"skip_forever": "Не прикажувај повеќе",
|
||||
"hide_guidance": "Скриј насоки",
|
||||
"show_guidance": "Прикажи насоки"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
"on_cycle_finished": "På syklus ferdig",
|
||||
"on_cycle_started": "På syklus startet",
|
||||
"pause_cycle": "Pause",
|
||||
"pause_cycle_tip": "Sett den kjørende syklusen på pause — apparatet fortsetter der det slapp",
|
||||
"pause_cycle_tip": "Sett den kjørende syklusen på pause – apparatet fortsetter der det slapp",
|
||||
"pg_apply_device": "Bruk på enhet",
|
||||
"pg_autofill": "Autofyll",
|
||||
"play": "Spill av",
|
||||
@@ -97,8 +97,8 @@
|
||||
"process_tip": "Lagre det innspilte sporet som en ny eller eksisterende profil",
|
||||
"rebuild": "Gjenoppbygg konvolutter",
|
||||
"rebuild_envelope": "Gjenoppbygg konvolutt",
|
||||
"rebuild_tip": "Beregn den forventede effektkonvolutten (min/maks-bånd) for alle profiler fra deres merkede sykluser på nytt — kjør etter merking av nye sykluser eller korrigering av gamle",
|
||||
"rec_start_tip": "Begynn å spille inn apparatets effektspor — start rett før du kjører en syklus",
|
||||
"rebuild_tip": "Beregn den forventede effektkonvolutten (min/maks-bånd) for alle profiler fra deres merkede sykluser på nytt – kjør etter merking av nye sykluser eller korrigering av gamle",
|
||||
"rec_start_tip": "Begynn å spille inn apparatets effektspor – start rett før du kjører en syklus",
|
||||
"rec_stop": "Stopp",
|
||||
"rec_stop_tip": "Stopp opptaket og behold det fangede sporet for gjennomgang",
|
||||
"record": "Start opptak",
|
||||
@@ -231,7 +231,7 @@
|
||||
"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": "{n} innstillingskonflikt{s} – sjekk de fremhevede seksjonene og rett dem opp før du lagrer.",
|
||||
"settings_banner_btn": "Gå til første"
|
||||
},
|
||||
"hdr": {
|
||||
@@ -451,9 +451,9 @@
|
||||
"show_expected": "Vis forventet kurveoverlegg (matchet profil, oransje)",
|
||||
"show_raw": "Vis veksler for råe stikkontaktverdier i sanntids effektgraf",
|
||||
"sparkline": "Nylig trend for syklusvarighet",
|
||||
"stage2": "Trinn 2 — kjernelikhet",
|
||||
"stage3": "Trinn 3 — DTW",
|
||||
"stage4": "Trinn 4 — samsvar",
|
||||
"stage2": "Trinn 2 – kjernelikhet",
|
||||
"stage3": "Trinn 3 – DTW",
|
||||
"stage4": "Trinn 4 – samsvar",
|
||||
"status": "Status",
|
||||
"tail_trim": "Beskjær slutt (s)",
|
||||
"timer_auto_pause": "Auto-pause",
|
||||
@@ -561,7 +561,12 @@
|
||||
"flags": "Flagg",
|
||||
"include_phase_map": "Inkluder fasekart",
|
||||
"include_settings": "Inkluder deteksjons- og matchinnstillinger",
|
||||
"show_contributor": "Vis bidragsyternavn"
|
||||
"show_contributor": "Vis bidragsyternavn",
|
||||
"task_pg_detail": "Simuler syklus",
|
||||
"task_split": "Deler opp syklus",
|
||||
"task_trim": "Beskjærer syklus",
|
||||
"task_merge": "Slår sammen sykluser",
|
||||
"task_rebuild": "Bygger opp envelopes på nytt"
|
||||
},
|
||||
"log": {
|
||||
"all_levels": "Alle nivåer",
|
||||
@@ -645,7 +650,7 @@
|
||||
"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.",
|
||||
"artifact_header": "{n} uregelmessigheter oppdaget i løpet av denne syklusen",
|
||||
"artifact_pause_detail": "Effekten falt til nær null i ~{n}s og gjenopptok deretter — sannsynligvis ble døren åpnet midt i syklusen eller syklusen ble satt på pause.",
|
||||
"artifact_pause_detail": "Effekten falt til nær null i ~{n}s og gjenopptok deretter – sannsynligvis ble døren åpnet midt i syklusen eller syklusen ble satt på pause.",
|
||||
"artifact_spike_detail": "Gikk over det vanlige effektbåndet i ~{n}s.",
|
||||
"auto_label_intro": "Tilordne profiler til umerkede sykluser hvis matchkonfidens klarerer terskelen.",
|
||||
"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.",
|
||||
@@ -654,10 +659,10 @@
|
||||
"collecting_data": "Samler inn data: {need} syklus{plural} til før finjustering kan starte ({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",
|
||||
"compare_selected_cycles": "Valgte sykluser (fast) – vis / skjul",
|
||||
"consider_new_profile": "Vurder å opprette en ny profil.",
|
||||
"coverage_gap": "nylige sykluser har ingen samsvarende profil ({pct}% av siste 30).",
|
||||
"coverage_gap_similar_cycles": "{count} like umerkede sykluser funnet — opprett en profil for å begynne å matche dem.",
|
||||
"coverage_gap_similar_cycles": "{count} like umerkede sykluser funnet – opprett en profil for å begynne å matche dem.",
|
||||
"cycles_deleted": "{count} syklus(er) slettet",
|
||||
"enough_data": "Nok data til å lære av ({current}/{min} sykluser).",
|
||||
"export_description": "Eksporter alle profiler og sykluser til JSON, eller gjenopprett fra en tidligere eksport.",
|
||||
@@ -686,7 +691,7 @@
|
||||
"ml_learned_intro": "Modeller finjustert til denne maskinen.",
|
||||
"ml_loading": "laster inn ML...",
|
||||
"ml_settings_intro": "To uavhengige brytere: den ene bruker modellene mens en syklus kjører, den andre lar WashData finjustere dem til maskinen din over tid.",
|
||||
"name_first_program": "Du har nok sykluser — gi det første programmet et navn for å starte samsvarssøket.",
|
||||
"name_first_program": "Du har nok sykluser – gi det første programmet et navn for å starte samsvarssøket.",
|
||||
"near_duplicate_cluster": "nesten duplikatprofilklynge oppdaget. Gruppering lar matching pålitelig velge mellom like-like (f.eks. samme program ved forskjellig temperatur/spinn).",
|
||||
"no_cycles_match": "Ingen sykluser samsvarer med gjeldende filter.",
|
||||
"no_cycles_profile": "Ingen sykluser for denne profilen.",
|
||||
@@ -713,7 +718,7 @@
|
||||
"notify_services_hint": "Bruk {entity}-tjeneste-ID-er (kommaseparert for flere). Malvariabler: {vars}.",
|
||||
"old_actions_warning": "Konfigurert med den gamle handlingsredigereren (nå fjernet). De utløses fortsatt ved syklushendelser, men kan ikke lenger redigeres her. Konverter dem til en vanlig automatisering, eller fjern dem.",
|
||||
"onboarding_progress": "{n} / 3 sykluser observert",
|
||||
"onboarding_watching": "Bruk apparatet som normalt — WashData følger med. Etter 3 sykluser starter programsamsvaret.",
|
||||
"onboarding_watching": "Bruk apparatet som normalt – WashData følger med. Etter 3 sykluser starter programsamsvaret.",
|
||||
"pending_feedback": "Venter på tilbakemelding på gjenkjenning",
|
||||
"performance_trend": "Ytelsestrend ({n} sykluser)",
|
||||
"pg_analysis_empty": "Last inn en syklus for å se treffanalyse.",
|
||||
@@ -763,7 +768,7 @@
|
||||
"setting_changed": "Endret fra {old} til {new} den {date}",
|
||||
"settings_basic_note": "Viser de viktigste innstillingene. Bytt til Avansert for hele listen.",
|
||||
"shape_drift_advisory": "⚠ Formavvik",
|
||||
"shape_drift_detail": "Effektmønsteret for denne profilen har endret seg over tid — mulig slitasje på apparatet eller vedlikehold nødvendig (f.eks. avkalking, filterrengjøring).",
|
||||
"shape_drift_detail": "Effektmønsteret for denne profilen har endret seg over tid – mulig slitasje på apparatet eller vedlikehold nødvendig (f.eks. avkalking, filterrengjøring).",
|
||||
"show_all_settings": "Vis alle innstillinger",
|
||||
"showing_suggestions": "Viser {count}-innstilling med forslag.",
|
||||
"split_intro": "Klikk på grafen for å legge til eller fjerne et delt punkt, eller automatisk oppdage ved tomgangshull. Hvert resulterende segment kan få sin egen profil.",
|
||||
@@ -857,7 +862,9 @@
|
||||
"share_guidelines_title": "Før du deler",
|
||||
"store_download_device_intro": "Ta over alle delte programmer og deres referansesykluser til apparatet ditt. Dine egne innspilte sykluser og statistikk påvirkes ikke.",
|
||||
"store_share_device_intro": "Last opp {brand} {model} med referansesyklusene du velger. Andre med samme apparat kan ta i bruk programmene dine. Bidrag gjennomgås før de vises offentlig.",
|
||||
"share_profile_no_cycles": "Ingen referansesykluser -- marker en syklus som ⭐ under fanen Sykluser for å inkludere denne profilen"
|
||||
"share_profile_no_cycles": "Ingen referansesykluser -- marker en syklus som ⭐ under fanen Sykluser for å inkludere denne profilen",
|
||||
"advisory_phase_inconsistent": "'{name}' ser ut til å blande ulike programmer eller temperaturer - syklusene varmer opp i svært ulike tidsrom. Hvis du deler den opp i separate profiler (f.eks. per temperatur), blir samsvar og tidsestimater bedre.",
|
||||
"advisory_phase_inconsistent_title": "⚠ Muligens blandede programmer"
|
||||
},
|
||||
"pg_desc": {
|
||||
"abrupt_drop_watts": "Plutselig fall behandlet som umiddelbar slutt",
|
||||
@@ -869,12 +876,19 @@
|
||||
"start_duration_threshold": "Sekunder over terskelen for å bekrefte start",
|
||||
"start_threshold_w": "Minimum watt for å telle som startet",
|
||||
"stop_threshold_w": "Under dette telles maskinen som av",
|
||||
"dtw_bandwidth": "Hvor mye tidsforvrengning formgjenkjenningen tillater",
|
||||
"corr_weight": "Vekt på kurveform kontra effektnivå i gjenkjenningen",
|
||||
"duration_weight": "Hvor mye samsvar i kjøretid påvirker gjenkjenningen",
|
||||
"energy_weight": "Hvor mye samsvar i energiforbruk påvirker gjenkjenningen",
|
||||
"profile_match_min_duration_ratio": "Korteste kjøring (i forhold til profilen) som fortsatt kan matche",
|
||||
"profile_match_max_duration_ratio": "Lengste kjøring (i forhold til profilen) som fortsatt kan matche"
|
||||
"dtw_bandwidth": "Trinn 3: Sakoe-Chiba-tidsfordreiningsband (0 = DTW av; standard 0,2 = 20% av sykellengde)",
|
||||
"corr_weight": "Trinn 2: balanse mellom kurvform (korrelasjon) og effektnivå (MAE); standard 0,45",
|
||||
"duration_weight": "Trinn 4: hvor sterkt varighetsoverensstemmelse påvirker sluttscoren (standard 0,22)",
|
||||
"energy_weight": "Trinn 4: hvor sterkt energioverensstemmelse påvirker sluttscoren (standard 0,22)",
|
||||
"profile_match_min_duration_ratio": "Trinn 1: korteste sykel som andel av profilvarighet; standard 0,1 (10%)",
|
||||
"profile_match_max_duration_ratio": "Trinn 1: lengste sykel som andel av profilvarighet; standard 1,5 (150%)",
|
||||
"keep_min_score": "Trinn 2: laveste poeng for å bli i matchen; standard 0,1 tillater svake kandidater, senere trinn velger best",
|
||||
"dtw_blend": "Trinn 3: 0 = bare kjernepoengscore, 1 = bare DTW-score, 0,5 = lik blanding (standard)",
|
||||
"dtw_ensemble_w": "Trinn 3 (ensemble-modus): vekt på skalert L1 kontra derivativ DTW; standard 0,7 foretrekker nivåbevisst",
|
||||
"dtw_ddtw_scale": "Trinn 3: DDTW-halvmetningsavstand; mindre = mer formfølsom (standard 30)",
|
||||
"dtw_refine_top_n": "Trinn 3: kandidater DTW beregner på nytt; øk til 7-9 hvis riktig profil rangerer 4.-5. (standard 5)",
|
||||
"duration_scale": "Trinn 4: log-forhold der varighetsoverensstemmelse halveres; lavere = strengere straff (standard 0,175)",
|
||||
"energy_scale": "Trinn 4: log-forhold der energioverensstemmelse halveres; lavere = strengere straff (standard 0,25)"
|
||||
},
|
||||
"phase_desc": {
|
||||
"anti_crease": "Enkelte korte fall etter ferdigstillelse for å redusere rynker.",
|
||||
@@ -957,6 +971,10 @@
|
||||
"triggers": {
|
||||
"intro": "Valgfrie eksterne signaler: en slutt-utløser, en dørensor, en pausebryter og utlastingspåminnelsen.",
|
||||
"label": "Utløsere og dører"
|
||||
},
|
||||
"phase_eta": {
|
||||
"label": "Tid som gjenstår",
|
||||
"intro": "Fasebevisst tid som gjenstår, for maskiner der syklusens lengde avhenger av temperatur eller sentrifugering."
|
||||
}
|
||||
},
|
||||
"setting": {
|
||||
@@ -1040,6 +1058,10 @@
|
||||
"doc": "Fast pris per kWh brukt for kostnadstall når ingen levende prisenhet er satt ovenfor.",
|
||||
"label": "Statisk energipris (per kWh)"
|
||||
},
|
||||
"energy_sensor": {
|
||||
"doc": "Valgfri kumulativ energiteller (total_increasing i kWh/Wh, f.eks. støpselets egen levetidsmåler). Når den er angitt, hentes hver syklus' rapporterte energi fra forskjellen på denne telleren mellom start og slutt, noe som unngår undertellingen du får ved å integrere en tregt rapporterende strømsensor. Faller tilbake til den integrerte verdien hvis avlesningen mangler, enheten er ukjent, eller forskjellen ikke er positiv. La feltet stå tomt for å fortsette å integrere strømsensoren.",
|
||||
"label": "Energimålerenhet"
|
||||
},
|
||||
"expose_debug_entities": {
|
||||
"doc": "Publiser ekstra diagnostiske HA-enheter (match konfidens, tvetydighet, tilstandsinternal). Av holder enhetslisten ren for normal bruk.",
|
||||
"label": "Vis feilsøkingsenheter"
|
||||
@@ -1322,6 +1344,38 @@
|
||||
},
|
||||
"show_contributor": {
|
||||
"doc": "Viser tilskrivningen 'av <contributor>' på fellesskapsapparater og referansesykluser."
|
||||
},
|
||||
"enable_phase_matching": {
|
||||
"label": "Fasebevisst tid som gjenstår",
|
||||
"doc": "Del hver pågående syklus inn i faser (oppvarming, vask, sentrifugering) og budsjetter tiden som gjenstår per fase, blandet med det klassiske estimatet - tidlig i syklusen støtter den seg på fasebudsjettet og mot slutten på det klassiske estimatet. Dette tilpasser nedtellingen til hvor lenge maskinen din faktisk varmer opp og kjører, noe som er mest merkbart i første halvdel av en syklus. Av = bare det klassiske estimatet. Bare visningen av tid som gjenstår påvirkes; programsamsvar og syklusdeteksjon er uendret."
|
||||
},
|
||||
"keep_min_score": {
|
||||
"label": "Min. matchingspoeng",
|
||||
"doc": "Laveste likhetspoeng en kandidat trenger for å bli i matcheprosessen. Standard 0,1 er bevisst tillåtende – det tillater selv svake kandidater og stoler på at senere trinn finner best samsvar. Øk for å luke ut usannsynlige profiler tidligere; senk for å utvide den innledende kandidatpoolen."
|
||||
},
|
||||
"dtw_blend": {
|
||||
"label": "DTW-blanding",
|
||||
"doc": "Hvor mye DTW-justeringsscoren erstatter kjerneresultatet fra Trinn 2. 0 = bruk bare Trinn 2-scoren, 1 = bruk bare DTW-scoren, 0,5 (standard) = lik blanding. Øk for å stole mer på tidsjustering når programmer har like effektnivåer men ulike timingmønstre."
|
||||
},
|
||||
"dtw_ensemble_w": {
|
||||
"label": "DTW-ensemblemiks",
|
||||
"doc": "I ensemble-DTW-modus (standard) er dette vekten på skalert L1 kontra derivativ DTW (DDTW). 1,0 = bare skalert L1, 0 = bare DDTW, 0,7 = standard. Den skalerte varianten sammenligner effektnivåer; den deriverte reagerer på hvordan effekten endres over tid. Ensemble blander begge."
|
||||
},
|
||||
"dtw_ddtw_scale": {
|
||||
"label": "Derivativ DTW-skala",
|
||||
"doc": "Halvmetningsavstand for derivativ DTW-scoring. Scoren halveres når DDTW-avstanden er lik denne verdien. Lavere = mer følsom for formforskjeller. Standard 30 er kalibrert for typiske husholdningsapparaters effektprofiler. Påvirker bare ensemble- og ddtw-DTW-modi."
|
||||
},
|
||||
"dtw_refine_top_n": {
|
||||
"label": "DTW-forfiningsantall",
|
||||
"doc": "Hvor mange toppkandidater fra Trinn 2 som beregnes på nytt av DTW. DTW er mer kostbart, så det brukes bare på de N beste. Standard 5. Øk (til 7-9) hvis riktig profil noen ganger bare når 4. eller 5. plass etter Trinn 2 – DTW kan redde den. Lavere verdi gir litt raskere matching."
|
||||
},
|
||||
"duration_scale": {
|
||||
"label": "Varighetsskarphet",
|
||||
"doc": "Skarphet i Trinn 4 sitt straff for varighetsoverensstemmelse. Det er log-forholdet der overensstemmelsesscoren halveres. Lavere = strengere: en varighetsavvik straffes mer. Standard 0,175 tilsvarer omtrent 18% varighetstolerans ved halvvekt. Par med Varighetsvekt."
|
||||
},
|
||||
"energy_scale": {
|
||||
"label": "Energiskarphet",
|
||||
"doc": "Skarphet i Trinn 4 sitt straff for energioverensstemmelse. Lavere = strengere: et energiavvik straffes mer. Standard 0,25 er bevisst mer tillåtende enn varighetsskarphet fordi energi varierer med last. Par med Energivekt."
|
||||
}
|
||||
},
|
||||
"setting_group": {
|
||||
@@ -1766,6 +1820,69 @@
|
||||
},
|
||||
"pg_sweep": {
|
||||
"optimize": "Optimaliser: {param}"
|
||||
},
|
||||
"pg_detail": {
|
||||
"simulate": "Simuler syklus"
|
||||
},
|
||||
"split": {
|
||||
"apply": "Deler opp syklus"
|
||||
},
|
||||
"trim": {
|
||||
"apply": "Beskjærer syklus"
|
||||
},
|
||||
"merge": {
|
||||
"apply": "Slår sammen sykluser"
|
||||
},
|
||||
"rebuild": {
|
||||
"envelopes": "Bygger opp envelopes på nytt"
|
||||
},
|
||||
"cancelling": "Avbryter..."
|
||||
},
|
||||
"setup": {
|
||||
"hdr": {
|
||||
"card": "Enhetsoppsett",
|
||||
"healthy_chip": "Oppsett fullført"
|
||||
},
|
||||
"phase0": {
|
||||
"washer": "WashData oppdager allerede syklusene dine. Spill inn den første syklusen for å aktivere programnavn og tidsanslag.",
|
||||
"dishwasher": "WashData følger med. Oppvaskmaskiner har komplekse sykluser – det anbefales på det sterkeste å spille inn den første syklusen. Hvis en oppdaget syklus kjører for lenge, bruk syklusredigereren til å trimme den før du lagrer den som en profil.",
|
||||
"generic": "WashData følger med. Spill inn eller merk en oppdaget syklus for å begynne å bygge opp profiler."
|
||||
},
|
||||
"phase1a": {
|
||||
"labelled": "Bra start – det første programmet ditt er lagret. For de reneste dataene kan du vurdere å spille inn neste syklus med opptakswidgeten."
|
||||
},
|
||||
"phase1b": {
|
||||
"recorded": "Opptaket ditt ble lagret som {profile_name}. Spill nå inn eller merk de andre vanlige programmene dine for å bygge opp dekning."
|
||||
},
|
||||
"phase1c": {
|
||||
"verify": "Du har {count} programmer fra fellesskapet. Kjør en syklus for å bekrefte at WashData gjenkjenner den riktig – gjenkjenningen forbedres etter hvert som enheten bygger opp sin egen historikk."
|
||||
},
|
||||
"phase2": {
|
||||
"cluster": "WashData har sett {count} sykluser som ikke samsvarer med noe lagret program – de ligner på hverandre. Vil du opprette en ny profil for dem?",
|
||||
"unmatched": "Den siste syklusen din samsvarte ikke med noe lagret program. Er det et nytt program?"
|
||||
},
|
||||
"phase3": {
|
||||
"suggestions": "WashData har innstillingsanbefalinger basert på syklushistorikken din – gå gjennom dem for å forbedre deteksjonsnøyaktigheten.",
|
||||
"groups": "Noen av profilene dine ser ut som det samme programmet ved forskjellige temperaturer. Organiser dem i en gruppe for bedre gjenkjenning.",
|
||||
"phases": "Legg til programfaser i {profile_name} for mer nøyaktige anslag på gjenværende tid."
|
||||
},
|
||||
"phase4": {
|
||||
"healthy": "Denne enheten er fullt konfigurert ({profile_count} profiler)."
|
||||
},
|
||||
"cta": {
|
||||
"start_recording": "Start opptak",
|
||||
"label_detected_cycle": "Jeg har allerede en oppdaget syklus – merk den i stedet",
|
||||
"browse_cycles": "Bla gjennom sykluser for å merke en til",
|
||||
"view_profiles": "Vis profilene dine",
|
||||
"create_from_cluster": "Opprett profil fra disse syklusene",
|
||||
"create_profile": "Opprett en profil for den",
|
||||
"review_suggestions": "Se gjennom anbefalinger",
|
||||
"organise_profiles": "Organiser profiler",
|
||||
"configure_phases": "Konfigurer faser",
|
||||
"skip_step": "Hopp over dette trinnet",
|
||||
"skip_forever": "Ikke vis igjen",
|
||||
"hide_guidance": "Skjul veiledning",
|
||||
"show_guidance": "Vis veiledning"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"badge": {
|
||||
"artifact_tip": "{n} afwijkingen gedetecteerd (bijvoorbeeld de deur werd halverwege de cyclus geopend) — open om ze in de grafiek te zien",
|
||||
"artifact_tip": "{n} afwijkingen gedetecteerd (bijvoorbeeld de deur werd halverwege de cyclus geopend) – open om ze in de grafiek te zien",
|
||||
"auto": "(automatisch gedetecteerd)",
|
||||
"built_in_tag": "ingebouwd",
|
||||
"declining": "↘ afnemend",
|
||||
@@ -87,7 +87,7 @@
|
||||
"on_cycle_finished": "Op cyclus klaar",
|
||||
"on_cycle_started": "Op cyclus gestart",
|
||||
"pause_cycle": "Pauze",
|
||||
"pause_cycle_tip": "De actieve cyclus pauzeren — het apparaat hervat waar het was gestopt",
|
||||
"pause_cycle_tip": "De actieve cyclus pauzeren – het apparaat hervat waar het was gestopt",
|
||||
"pg_apply_device": "Toepassen op apparaat",
|
||||
"pg_autofill": "Automatisch invullen",
|
||||
"play": "Afspelen",
|
||||
@@ -97,8 +97,8 @@
|
||||
"process_tip": "Sla de geregistreerde trace op als een nieuw of bestaand profiel",
|
||||
"rebuild": "Enveloppen opnieuw opbouwen",
|
||||
"rebuild_envelope": "Envelop opnieuw opbouwen",
|
||||
"rebuild_tip": "Herbereken de verwachte vermogensenvelop (min/max-band) voor alle profielen op basis van hun gelabelde cycli — voer uit na het labelen van nieuwe cycli of het corrigeren van bestaande",
|
||||
"rec_start_tip": "Begin met het opnemen van het vermogensspoor van het apparaat — start vlak voor het uitvoeren van een cyclus",
|
||||
"rebuild_tip": "Herbereken de verwachte vermogensenvelop (min/max-band) voor alle profielen op basis van hun gelabelde cycli – voer uit na het labelen van nieuwe cycli of het corrigeren van bestaande",
|
||||
"rec_start_tip": "Begin met het opnemen van het vermogensspoor van het apparaat – start vlak voor het uitvoeren van een cyclus",
|
||||
"rec_stop": "Stop",
|
||||
"rec_stop_tip": "Stop de opname en bewaar de vastgelegde trace voor beoordeling",
|
||||
"record": "Begin met opnemen",
|
||||
@@ -231,7 +231,7 @@
|
||||
"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": "{n} instellingsconflict{s} – controleer de gemarkeerde secties en los ze op voor het opslaan.",
|
||||
"settings_banner_btn": "Ga naar eerste"
|
||||
},
|
||||
"hdr": {
|
||||
@@ -451,9 +451,9 @@
|
||||
"show_expected": "Verwachte curve-overlay weergeven (overeenkomend profiel, oranje)",
|
||||
"show_raw": "Toon schakelaar voor onbewerkte stopcontactwaarden in live vermogensgrafiek",
|
||||
"sparkline": "Recente trend van cyclusduur",
|
||||
"stage2": "Stap 2 — kerngelijkenis",
|
||||
"stage3": "Stap 3 — DTW",
|
||||
"stage4": "Stap 4 — overeenkomst",
|
||||
"stage2": "Stap 2 – kerngelijkenis",
|
||||
"stage3": "Stap 3 – DTW",
|
||||
"stage4": "Stap 4 – overeenkomst",
|
||||
"status": "Status",
|
||||
"tail_trim": "Einde bijsnijden (s)",
|
||||
"timer_auto_pause": "Automatische pauze",
|
||||
@@ -561,7 +561,12 @@
|
||||
"flags": "Vlaggen",
|
||||
"include_phase_map": "Fasekaart opnemen",
|
||||
"include_settings": "Detectie- en matchinstellingen opnemen",
|
||||
"show_contributor": "Bijdragersnamen weergeven"
|
||||
"show_contributor": "Bijdragersnamen weergeven",
|
||||
"task_pg_detail": "Cyclus simuleren",
|
||||
"task_split": "Cyclus splitsen",
|
||||
"task_trim": "Cyclus bijsnijden",
|
||||
"task_merge": "Cycli samenvoegen",
|
||||
"task_rebuild": "Enveloppen opnieuw opbouwen"
|
||||
},
|
||||
"log": {
|
||||
"all_levels": "Alle niveaus",
|
||||
@@ -645,7 +650,7 @@
|
||||
"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.",
|
||||
"artifact_header": "{n} afwijkingen gedetecteerd tijdens deze cyclus",
|
||||
"artifact_pause_detail": "Vermogen daalde tot bijna nul voor ~{n}s en hervatte vervolgens — waarschijnlijk werd de deur halverwege de cyclus geopend of de cyclus gepauzeerd.",
|
||||
"artifact_pause_detail": "Vermogen daalde tot bijna nul voor ~{n}s en hervatte vervolgens – waarschijnlijk werd de deur halverwege de cyclus geopend of de cyclus gepauzeerd.",
|
||||
"artifact_spike_detail": "Trad boven de gebruikelijke vermogensband voor ~{n}s.",
|
||||
"auto_label_intro": "Wijs profielen toe aan niet-gelabelde cycli waarvan het matchvertrouwen de drempel overschrijdt.",
|
||||
"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.",
|
||||
@@ -654,10 +659,10 @@
|
||||
"collecting_data": "Gegevens worden verzameld: nog {need} cyclus{plural} voordat verfijning kan beginnen ({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",
|
||||
"compare_selected_cycles": "Geselecteerde cycli (vast) – tonen/verbergen",
|
||||
"consider_new_profile": "Overweeg een nieuw profiel aan te maken.",
|
||||
"coverage_gap": "recente cycli hebben geen overeenkomend profiel ({pct}% van de laatste 30).",
|
||||
"coverage_gap_similar_cycles": "{count} vergelijkbare niet-gelabelde cycli gevonden — maak een profiel aan om ze te beginnen matchen.",
|
||||
"coverage_gap_similar_cycles": "{count} vergelijkbare niet-gelabelde cycli gevonden – maak een profiel aan om ze te beginnen matchen.",
|
||||
"cycles_deleted": "{count} cyclus(sen) verwijderd",
|
||||
"enough_data": "Voldoende gegevens om van te leren ({current}/{min} cycli).",
|
||||
"export_description": "Exporteer alle profielen en cycli naar JSON, of herstel vanuit een eerdere export.",
|
||||
@@ -686,7 +691,7 @@
|
||||
"ml_learned_intro": "Modellen die op deze machine zijn afgestemd.",
|
||||
"ml_loading": "ML laden...",
|
||||
"ml_settings_intro": "Twee onafhankelijke schakelaars: de ene past de modellen toe terwijl een cyclus loopt, de andere laat WashData ze in de loop van de tijd nauwkeurig afstemmen op uw machine.",
|
||||
"name_first_program": "Je hebt genoeg cycli — geef je eerste programma een naam om te beginnen met matchen.",
|
||||
"name_first_program": "Je hebt genoeg cycli – geef je eerste programma een naam om te beginnen met matchen.",
|
||||
"near_duplicate_cluster": "bijna dubbel profielcluster gedetecteerd. Door te groeperen kan er op betrouwbare wijze worden gekozen tussen look-alikes (bijvoorbeeld hetzelfde programma op verschillende temperatuur/centrifugeren).",
|
||||
"no_cycles_match": "Er zijn geen cycli die overeenkomen met het huidige filter.",
|
||||
"no_cycles_profile": "Geen cycli voor dit profiel.",
|
||||
@@ -713,7 +718,7 @@
|
||||
"notify_services_hint": "Gebruik {entity}-service-ID's (kommagescheiden voor meerdere). Sjabloonvariabelen: {vars}.",
|
||||
"old_actions_warning": "Geconfigureerd met de oude actie-editor (nu verwijderd). Ze vuren nog steeds op cyclusevenementen, maar kunnen hier niet langer worden bewerkt. Converteer ze naar een normale automatisering of verwijder ze.",
|
||||
"onboarding_progress": "{n} / 3 cycli waargenomen",
|
||||
"onboarding_watching": "Gebruik je apparaat normaal — WashData kijkt mee. Na 3 cycli begint het matchen van programma's.",
|
||||
"onboarding_watching": "Gebruik je apparaat normaal – WashData kijkt mee. Na 3 cycli begint het matchen van programma's.",
|
||||
"pending_feedback": "In afwachting van detectiefeedback",
|
||||
"performance_trend": "Prestatietrend ({n} cycli)",
|
||||
"pg_analysis_empty": "Laad een cyclus om de matchanalyse te bekijken.",
|
||||
@@ -763,7 +768,7 @@
|
||||
"setting_changed": "Gewijzigd van {old} naar {new} op {date}",
|
||||
"settings_basic_note": "Essentiële instellingen worden getoond. Schakel over naar Geavanceerd voor de volledige lijst.",
|
||||
"shape_drift_advisory": "⚠ Vormafwijking",
|
||||
"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).",
|
||||
"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.",
|
||||
@@ -789,10 +794,10 @@
|
||||
"toast_revert_failed": "Terugzetten mislukt: {error}",
|
||||
"toast_reverted": "{key} teruggezet",
|
||||
"toast_save_failed": "Opslaan mislukt: {error}",
|
||||
"trend_duration_longer": "Duur trending langer ({pct}%/cyclus) — recent gemiddelde {avg}",
|
||||
"trend_duration_shorter": "Duur trending korter ({pct}%/cyclus) — recent gemiddelde {avg}",
|
||||
"trend_duration_longer": "Duur trending langer ({pct}%/cyclus) – recent gemiddelde {avg}",
|
||||
"trend_duration_shorter": "Duur trending korter ({pct}%/cyclus) – recent gemiddelde {avg}",
|
||||
"trend_energy_down": "Energietrend omlaag ({pct}%/cyclus)",
|
||||
"trend_energy_up": "Energie stijgt ({pct}%/cyclus) — recent gemiddelde {avg}",
|
||||
"trend_energy_up": "Energie stijgt ({pct}%/cyclus) – recent gemiddelde {avg}",
|
||||
"trim_intro": "Versleep de rode grepen of voer waarden in. Alles buiten het raam 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",
|
||||
@@ -857,7 +862,9 @@
|
||||
"share_guidelines_title": "Voordat u deelt",
|
||||
"store_download_device_intro": "Neem elk gedeeld programma en zijn referentiecycli over op uw apparaat. Uw eigen opgenomen cycli en statistieken worden niet beïnvloed.",
|
||||
"store_share_device_intro": "Upload {brand} {model} met de referentiecycli die u selecteert. Anderen met hetzelfde apparaat kunnen uw programma's overnemen. Vermeldingen worden beoordeeld voordat ze openbaar verschijnen.",
|
||||
"share_profile_no_cycles": "Geen referentiecycli -- markeer een cyclus als ⭐ op het tabblad Cycli om dit profiel op te nemen"
|
||||
"share_profile_no_cycles": "Geen referentiecycli -- markeer een cyclus als ⭐ op het tabblad Cycli om dit profiel op te nemen",
|
||||
"advisory_phase_inconsistent": "'{name}' lijkt verschillende programma's of temperaturen te combineren - de cycli verwarmen gedurende sterk uiteenlopende tijden. Door het op te splitsen in aparte profielen (bijv. per temperatuur) verbeteren de matching en tijdschattingen.",
|
||||
"advisory_phase_inconsistent_title": "⚠ Mogelijk gemengde programma's"
|
||||
},
|
||||
"pg_desc": {
|
||||
"abrupt_drop_watts": "Plotselinge daling behandeld als onmiddellijk einde",
|
||||
@@ -869,12 +876,19 @@
|
||||
"start_duration_threshold": "Seconden boven de drempel om de start te bevestigen",
|
||||
"start_threshold_w": "Minimaal aantal watt om als gestart te tellen",
|
||||
"stop_threshold_w": "Hieronder telt de machine als uit",
|
||||
"dtw_bandwidth": "Hoeveel tijdvervorming de vormherkenning toestaat",
|
||||
"corr_weight": "Gewicht van curvevorm versus vermogensniveau in de herkenning",
|
||||
"duration_weight": "Hoeveel overeenkomst in looptijd de herkenning beïnvloedt",
|
||||
"energy_weight": "Hoeveel overeenkomst in energieverbruik de herkenning beïnvloedt",
|
||||
"profile_match_min_duration_ratio": "Kortste cyclus (t.o.v. het profiel) die nog mag matchen",
|
||||
"profile_match_max_duration_ratio": "Langste cyclus (t.o.v. het profiel) die nog mag matchen"
|
||||
"dtw_bandwidth": "Stap 3: Sakoe-Chiba-vervormingsband (0 = DTW uit; standaard 0,2 = 20% van de cycluslengte)",
|
||||
"corr_weight": "Stap 2: balans tussen curvevorm (correlatie) en vermogensniveau (MAE); standaard 0,45",
|
||||
"duration_weight": "Stap 4: hoe sterk de duurovereenkomst de eindscore beïnvloedt (standaard 0,22)",
|
||||
"energy_weight": "Stap 4: hoe sterk de energieovereenkomst de eindscore beïnvloedt (standaard 0,22)",
|
||||
"profile_match_min_duration_ratio": "Stap 1: minimale cycluslengte als fractie van de profielduur; standaard 0,1 (10%)",
|
||||
"profile_match_max_duration_ratio": "Stap 1: maximale cycluslengte als fractie van de profielduur; standaard 1,5 (150%)",
|
||||
"keep_min_score": "Stap 2: minimale score om in de race te blijven; standaard 0,1 laat zwakke kandidaten toe, latere stappen kiezen de beste",
|
||||
"dtw_blend": "Stap 3: 0 = alleen kernscore, 1 = alleen DTW-score, 0,5 = gelijke mix (standaard)",
|
||||
"dtw_ensemble_w": "Stap 3 (ensemble-modus): gewicht op geschaalde L1 vs afgeleid DTW; standaard 0,7 geeft voorkeur aan niveauafhankelijke herkenning",
|
||||
"dtw_ddtw_scale": "Stap 3: DDTW-halfsaturatieafstand; kleiner = gevoeliger voor vorm (standaard 30)",
|
||||
"dtw_refine_top_n": "Stap 3: kandidaten die door DTW opnieuw beoordeeld worden; verhoog naar 7-9 als het juiste profiel op de 4e-5e plaats staat (standaard 5)",
|
||||
"duration_scale": "Stap 4: log-verhouding waarbij de duurovereenkomst halveert; kleiner = strengere straf (standaard 0,175)",
|
||||
"energy_scale": "Stap 4: log-verhouding waarbij de energieovereenkomst halveert; kleiner = strengere straf (standaard 0,25)"
|
||||
},
|
||||
"phase_desc": {
|
||||
"anti_crease": "Af en toe kort tuimelen na voltooiing om rimpels te verminderen.",
|
||||
@@ -957,6 +971,10 @@
|
||||
"triggers": {
|
||||
"intro": "Optionele externe signalen: een eindtrigger, een deursensor, een pauzeknop en de uitlaadherinnering.",
|
||||
"label": "Triggers & Deuren"
|
||||
},
|
||||
"phase_eta": {
|
||||
"label": "Resterende tijd",
|
||||
"intro": "Fasebewuste resterende tijd, voor machines waarvan de cyclusduur afhangt van temperatuur of centrifugeren."
|
||||
}
|
||||
},
|
||||
"setting": {
|
||||
@@ -1040,6 +1058,10 @@
|
||||
"doc": "Vaste prijs per kWh gebruikt voor kostencijfers wanneer er hierboven geen live prijsentiteit is ingesteld.",
|
||||
"label": "Vaste energieprijs (per kWh)"
|
||||
},
|
||||
"energy_sensor": {
|
||||
"doc": "Optionele cumulatieve energieteller (total_increasing in kWh/Wh, bijvoorbeeld de eigen levensduurteller van de stekker). Indien ingesteld wordt de gerapporteerde energie van elke cyclus genomen uit het verschil van deze teller tussen begin en einde, wat de onderregistratie voorkomt die je krijgt bij het integreren van een traag rapporterende vermogenssensor. Valt terug op de geïntegreerde waarde als de meting ontbreekt, de eenheid onbekend is of het verschil niet positief is. Laat leeg om de vermogenssensor te blijven integreren.",
|
||||
"label": "Energiemeterentiteit"
|
||||
},
|
||||
"expose_debug_entities": {
|
||||
"doc": "Publiceer extra diagnostische HA-entiteiten (matchvertrouwen, ambiguïteit, staatsinternals). Uit houdt de entiteitenlijst schoon voor normaal gebruik.",
|
||||
"label": "Foutopsporingsentiteiten blootstellen"
|
||||
@@ -1322,6 +1344,38 @@
|
||||
},
|
||||
"show_contributor": {
|
||||
"doc": "Toont de vermelding 'door <contributor>' op community-apparaten en referentiecycli."
|
||||
},
|
||||
"enable_phase_matching": {
|
||||
"label": "Fasebewuste resterende tijd",
|
||||
"doc": "Verdeel elke lopende cyclus in fasen (verwarmen, wassen, centrifugeren) en begroot de resterende tijd per fase, gemengd met de klassieke schatting - vroeg in de cyclus leunend op het fasebudget en tegen het einde op de klassieke schatting. Dit stemt het aftellen af op hoe lang uw machine daadwerkelijk verwarmt en draait, wat het meest merkbaar is in de eerste helft van een cyclus. Uit = alleen de klassieke schatting. Alleen de weergave van de resterende tijd wordt beïnvloed; programma-matching en cyclusdetectie blijven ongewijzigd."
|
||||
},
|
||||
"keep_min_score": {
|
||||
"label": "Min. matchscore",
|
||||
"doc": "Minimale gelijkenisscore die een kandidaat nodig heeft om in de race te blijven. De standaard 0,1 is bewust permissief - het laat zelfs zwakke kandidaten toe en vertrouwt op latere stappen om de beste overeenkomst te vinden. Verhoog het om onwaarschijnlijke profielen eerder te verwijderen; verlaag het om de initiële kandidatenpool te verbreden."
|
||||
},
|
||||
"dtw_blend": {
|
||||
"label": "Warp-mengfactor",
|
||||
"doc": "Hoeveel de tijdvervormingsscore (DTW) de kernscore van stap 2 vervangt. 0 = gebruik alleen de stap 2-score, 1 = gebruik alleen de DTW-score, 0,5 (standaard) = gelijke mix. Verhoog het om meer te vertrouwen op warp-uitlijning wanneer programma's vergelijkbare vermogensniveaus maar verschillende tijdpatronen hebben."
|
||||
},
|
||||
"dtw_ensemble_w": {
|
||||
"label": "Warp-ensemblemix",
|
||||
"doc": "In ensemble DTW-modus (de standaard), het gewicht op geschaalde L1 versus afgeleid DTW (DDTW). 1,0 = alleen geschaalde L1, 0 = alleen DDTW, 0,7 = standaard. De geschaalde L1-variant vergelijkt vermogensniveaus; de afgeleide variant reageert op hoe vermogen verandert over de tijd. Ensemble mengt beide."
|
||||
},
|
||||
"dtw_ddtw_scale": {
|
||||
"label": "Afgeleide warp-schaal",
|
||||
"doc": "Halfsaturatieafstand voor de afgeleide DTW-beoordeling. De score halveert wanneer de DDTW-afstand gelijk is aan deze waarde. Kleiner = gevoeliger voor vormverschillen. Standaard 30 is gekalibreerd op typische vermogenssporen van apparaten. Beïnvloedt alleen ensemble- en ddtw DTW-modi."
|
||||
},
|
||||
"dtw_refine_top_n": {
|
||||
"label": "Warp-verfijningsaantal",
|
||||
"doc": "Hoeveel top stap 2-kandidaten opnieuw worden beoordeeld door DTW. DTW is duurder en wordt daarom alleen toegepast op de beste N kandidaten. Standaard 5. Verhoog het (naar 7-9) als het juiste profiel na stap 2 soms alleen de 4e of 5e plaats bereikt - DTW kan het redden. Verlagen versnelt het matchen iets."
|
||||
},
|
||||
"duration_scale": {
|
||||
"label": "Duur-scherpte",
|
||||
"doc": "Scherpte van de duurovereenkomststraf in stap 4. Dit is de log-verhouding waarbij de overeenkomstscore halveert. Kleiner = strenger: een duurafwijking kost meer punten. Standaard 0,175 komt overeen met ongeveer 18% duurtolerантie op half gewicht. Combineer met Duurgewicht."
|
||||
},
|
||||
"energy_scale": {
|
||||
"label": "Energie-scherpte",
|
||||
"doc": "Scherpte van de energieovereenkomststraf. Kleiner = strenger: een energiemismatch kost meer punten. Standaard 0,25 is bewust meer vergevingsgezind dan Duurscherpte, omdat energie varieert met de belasting. Combineer met Energiegewicht."
|
||||
}
|
||||
},
|
||||
"setting_group": {
|
||||
@@ -1766,6 +1820,69 @@
|
||||
},
|
||||
"pg_sweep": {
|
||||
"optimize": "Optimaliseren: {param}"
|
||||
},
|
||||
"pg_detail": {
|
||||
"simulate": "Cyclus simuleren"
|
||||
},
|
||||
"split": {
|
||||
"apply": "Cyclus splitsen"
|
||||
},
|
||||
"trim": {
|
||||
"apply": "Cyclus bijsnijden"
|
||||
},
|
||||
"merge": {
|
||||
"apply": "Cycli samenvoegen"
|
||||
},
|
||||
"rebuild": {
|
||||
"envelopes": "Enveloppen opnieuw opbouwen"
|
||||
},
|
||||
"cancelling": "Annuleren..."
|
||||
},
|
||||
"setup": {
|
||||
"hdr": {
|
||||
"card": "Apparaat instellen",
|
||||
"healthy_chip": "Instelling voltooid"
|
||||
},
|
||||
"phase0": {
|
||||
"washer": "WashData detecteert uw cycli al. Neem uw eerste cyclus op om programmanamen en tijdschattingen in te schakelen.",
|
||||
"dishwasher": "WashData kijkt mee. Vaatwassers hebben complexe cycli – het opnemen van uw eerste cyclus wordt sterk aanbevolen. Als een gedetecteerde cyclus te lang duurt, gebruik dan de cycluseditor om hem bij te snijden vóór het opslaan als profiel.",
|
||||
"generic": "WashData kijkt mee. Neem een cyclus op of label een gedetecteerde cyclus om te beginnen met het opbouwen van profielen."
|
||||
},
|
||||
"phase1a": {
|
||||
"labelled": "Goed begin – uw eerste programma is opgeslagen. Voor de zuiverste gegevens kunt u uw volgende cyclus opnemen met de recorder-widget."
|
||||
},
|
||||
"phase1b": {
|
||||
"recorded": "Uw opname is opgeslagen als {profile_name}. Neem nu uw andere veelgebruikte programma's op of label ze om de dekking uit te breiden."
|
||||
},
|
||||
"phase1c": {
|
||||
"verify": "U heeft {count} programma's van de community. Voer een cyclus uit om te verifiëren dat WashData deze correct herkent – de herkenning verbetert naarmate uw apparaat zijn eigen geschiedenis opbouwt."
|
||||
},
|
||||
"phase2": {
|
||||
"cluster": "WashData heeft {count} cycli gezien die niet overeenkomen met een opgeslagen programma – ze lijken op elkaar. Wilt u een nieuw profiel voor ze aanmaken?",
|
||||
"unmatched": "Uw laatste cyclus kwam niet overeen met een opgeslagen programma. Is het een nieuw programma?"
|
||||
},
|
||||
"phase3": {
|
||||
"suggestions": "WashData heeft instellingsaanbevelingen op basis van uw cyclusgeschiedenis – bekijk ze om de detectienauwkeurigheid te verbeteren.",
|
||||
"groups": "Sommige van uw profielen lijken op hetzelfde programma bij verschillende temperaturen. Organiseer ze in een groep voor betere herkenning.",
|
||||
"phases": "Voeg programmasfases toe aan {profile_name} voor nauwkeurigere schattingen van de resterende tijd."
|
||||
},
|
||||
"phase4": {
|
||||
"healthy": "Dit apparaat is volledig ingesteld ({profile_count} profielen)."
|
||||
},
|
||||
"cta": {
|
||||
"start_recording": "Opname starten",
|
||||
"label_detected_cycle": "Ik heb al een gedetecteerde cyclus – label die in plaats daarvan",
|
||||
"browse_cycles": "Cycli bekijken om een andere te labelen",
|
||||
"view_profiles": "Uw profielen bekijken",
|
||||
"create_from_cluster": "Profiel maken van deze cycli",
|
||||
"create_profile": "Maak er een profiel voor",
|
||||
"review_suggestions": "Aanbevelingen bekijken",
|
||||
"organise_profiles": "Profielen organiseren",
|
||||
"configure_phases": "Fasen configureren",
|
||||
"skip_step": "Sla deze stap over",
|
||||
"skip_forever": "Niet meer weergeven",
|
||||
"hide_guidance": "Begeleiding verbergen",
|
||||
"show_guidance": "Begeleiding weergeven"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
{
|
||||
"badge": {
|
||||
"artifact_tip": "Wykryto {n} anomalii (np. drzwi otwarte w połowie cyklu) — otwórz, aby zobaczyć je na wykresie",
|
||||
"artifact_tip": "Wykryto {n} anomalii (np. drzwi otwarte w połowie cyklu) – otwórz, aby zobaczyć je na wykresie",
|
||||
"auto": "(automatycznie wykryty)",
|
||||
"built_in_tag": "wbudowany",
|
||||
"declining": "↘ maleje",
|
||||
"energy_low": "Niższe zużycie energii niż zwykle",
|
||||
"energy_spike": "Wyższe zużycie energii niż zwykle",
|
||||
"fair_fit": "akceptowalne dopasowanie",
|
||||
"fair_fit_tip": "Umiarkowana spójność dopasowania — niektóre cykle przypisane do tego profilu mają niższy poziom pewności. Oznacz więcej cykli lub ponownie zapisz profil, aby poprawić dokładność.",
|
||||
"fair_fit_tip": "Umiarkowana spójność dopasowania – niektóre cykle przypisane do tego profilu mają niższy poziom pewności. Oznacz więcej cykli lub ponownie zapisz profil, aby poprawić dokładność.",
|
||||
"feedback_requested": "Poproszono o opinię",
|
||||
"golden_cycle": "Zarejestrowany cykl referencyjny",
|
||||
"improving": "↗ poprawa",
|
||||
@@ -57,7 +57,7 @@
|
||||
"create_profile": "+ Utwórz profil",
|
||||
"delete": "Usuń",
|
||||
"delete_group": "Usuń grupę",
|
||||
"delete_group_tip": "Usuń tylko tę grupę — profile członków zostaną zachowane",
|
||||
"delete_group_tip": "Usuń tylko tę grupę – profile członków zostaną zachowane",
|
||||
"delete_profile": "Usuń profil",
|
||||
"discard": "Odrzuć",
|
||||
"discard_tip": "Odrzuć nagranie bez zapisywania",
|
||||
@@ -87,7 +87,7 @@
|
||||
"on_cycle_finished": "Po zakończeniu cyklu",
|
||||
"on_cycle_started": "Po rozpoczęciu cyklu",
|
||||
"pause_cycle": "Pauza",
|
||||
"pause_cycle_tip": "Wstrzymaj bieżący cykl — urządzenie wznowi pracę od miejsca, w którym zostało zatrzymane",
|
||||
"pause_cycle_tip": "Wstrzymaj bieżący cykl – urządzenie wznowi pracę od miejsca, w którym zostało zatrzymane",
|
||||
"pg_apply_device": "Zastosuj do urządzenia",
|
||||
"pg_autofill": "Wypełnij automatycznie",
|
||||
"play": "Odtwórz",
|
||||
@@ -97,8 +97,8 @@
|
||||
"process_tip": "Zapisz zarejestrowany przebieg jako nowy lub istniejący profil",
|
||||
"rebuild": "Odbuduj koperty",
|
||||
"rebuild_envelope": "Odbuduj kopertę",
|
||||
"rebuild_tip": "Przelicz oczekiwaną obwiednię mocy (pasmo min/maks) dla wszystkich profili z ich oznakowanych cykli — uruchom po oznaczeniu nowych cykli lub korekcie starych",
|
||||
"rec_start_tip": "Rozpocznij rejestrowanie przebiegu mocy urządzenia — uruchom tuż przed rozpoczęciem cyklu",
|
||||
"rebuild_tip": "Przelicz oczekiwaną obwiednię mocy (pasmo min/maks) dla wszystkich profili z ich oznakowanych cykli – uruchom po oznaczeniu nowych cykli lub korekcie starych",
|
||||
"rec_start_tip": "Rozpocznij rejestrowanie przebiegu mocy urządzenia – uruchom tuż przed rozpoczęciem cyklu",
|
||||
"rec_stop": "Zatrzymaj",
|
||||
"rec_stop_tip": "Zatrzymaj nagrywanie i zachowaj zarejestrowany przebieg do przeglądu",
|
||||
"record": "Rozpocznij nagrywanie",
|
||||
@@ -231,7 +231,7 @@
|
||||
"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": "{n} konflikt{s} ustawień – sprawdź podświetlone sekcje i popraw przed zapisaniem.",
|
||||
"settings_banner_btn": "Przejdź do pierwszego"
|
||||
},
|
||||
"hdr": {
|
||||
@@ -451,9 +451,9 @@
|
||||
"show_expected": "Pokaż oczekiwaną nakładkę krzywej (dopasowany profil, pomarańczowy)",
|
||||
"show_raw": "Pokaż przełącznik surowych odczytów gniazdka na wykresie mocy na żywo",
|
||||
"sparkline": "Ostatni trend czasu trwania cykli",
|
||||
"stage2": "Etap 2 — podstawowe podobieństwo",
|
||||
"stage3": "Etap 3 — DTW",
|
||||
"stage4": "Etap 4 — zgodność",
|
||||
"stage2": "Etap 2 – podstawowe podobieństwo",
|
||||
"stage3": "Etap 3 – DTW",
|
||||
"stage4": "Etap 4 – zgodność",
|
||||
"status": "Status",
|
||||
"tail_trim": "Trymowanie ogona",
|
||||
"timer_auto_pause": "Automatyczna pauza",
|
||||
@@ -561,7 +561,12 @@
|
||||
"flags": "Flagi",
|
||||
"include_phase_map": "Dołącz mapę faz",
|
||||
"include_settings": "Dołącz ustawienia",
|
||||
"show_contributor": "Pokaż współtwórcę"
|
||||
"show_contributor": "Pokaż współtwórcę",
|
||||
"task_pg_detail": "Symuluj cykl",
|
||||
"task_split": "Dzielenie cyklu",
|
||||
"task_trim": "Przycinanie cyklu",
|
||||
"task_merge": "Scalanie cykli",
|
||||
"task_rebuild": "Przeliczanie obwiedni"
|
||||
},
|
||||
"log": {
|
||||
"all_levels": "Wszystkie poziomy",
|
||||
@@ -645,7 +650,7 @@
|
||||
"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.",
|
||||
"artifact_header": "W tym cyklu wykryto {n} anomalii",
|
||||
"artifact_pause_detail": "Moc spadła prawie do zera przez ~{n}s, a następnie wzrosła — prawdopodobnie drzwi zostały otwarte w trakcie cyklu lub cykl był wstrzymany.",
|
||||
"artifact_pause_detail": "Moc spadła prawie do zera przez ~{n}s, a następnie wzrosła – prawdopodobnie drzwi zostały otwarte w trakcie cyklu lub cykl był wstrzymany.",
|
||||
"artifact_spike_detail": "Moc przekroczyła normalny zakres przez ~{n}s.",
|
||||
"auto_label_intro": "Przypisz profile do nieoznakowanych cykli, których pewność dopasowania przekracza próg.",
|
||||
"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.",
|
||||
@@ -654,10 +659,10 @@
|
||||
"collecting_data": "Zbieranie danych: jeszcze {need} cykli do rozpoczęcia dostrajania ({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",
|
||||
"compare_selected_cycles": "Wybrane cykle (pełne) – pokaż / ukryj",
|
||||
"consider_new_profile": "Rozważ utworzenie nowego profilu.",
|
||||
"coverage_gap": "ostatnie cykle nie mają pasującego profilu ({pct}% z ostatnich 30).",
|
||||
"coverage_gap_similar_cycles": "Znaleziono {count} podobnych nieoznaczonych cykli — utwórz profil, aby zacząć je dopasowywać.",
|
||||
"coverage_gap_similar_cycles": "Znaleziono {count} podobnych nieoznaczonych cykli – utwórz profil, aby zacząć je dopasowywać.",
|
||||
"cycles_deleted": "Usunięto cykle: {count}",
|
||||
"enough_data": "Wystarczająco danych do nauki ({current}/{min} cykli).",
|
||||
"export_description": "Eksportuj wszystkie profile i cykle do formatu JSON lub przywróć dane z poprzedniego eksportu.",
|
||||
@@ -686,7 +691,7 @@
|
||||
"ml_learned_intro": "Modele dopasowane do tej maszyny.",
|
||||
"ml_loading": "ładowanie ML…",
|
||||
"ml_settings_intro": "Dwa niezależne przełączniki: jeden stosuje modele w trakcie trwania cyklu, drugi pozwala WashData dostosować je do Twojej maszyny w miarę upływu czasu.",
|
||||
"name_first_program": "Masz wystarczająco dużo cykli — nadaj nazwę pierwszemu programowi, aby rozpocząć dopasowywanie.",
|
||||
"name_first_program": "Masz wystarczająco dużo cykli – nadaj nazwę pierwszemu programowi, aby rozpocząć dopasowywanie.",
|
||||
"near_duplicate_cluster": "Wykryto prawie zduplikowany klaster profili. Grupowanie umożliwia niezawodne wybieranie podobnych programów (np. tego samego programu w innej temperaturze/wirowaniu).",
|
||||
"no_cycles_match": "Żaden cykl nie pasuje do bieżącego filtra.",
|
||||
"no_cycles_profile": "Brak cykli dla tego profilu.",
|
||||
@@ -696,10 +701,10 @@
|
||||
"no_devices": "Nie skonfigurowano jeszcze żadnych urządzeń WashData.",
|
||||
"no_envelope": "Nie ma jeszcze koperty - odbuduj po cyklach etykietowania.",
|
||||
"no_envelope_overlay": "Brak koperty do nałożenia.",
|
||||
"no_fine_tuned": "Nic jeszcze nie zostało dopracowane — WashData korzysta z wbudowanych modeli.",
|
||||
"no_fine_tuned": "Nic jeszcze nie zostało dopracowane – WashData korzysta z wbudowanych modeli.",
|
||||
"no_logs": "Żadne rekordy dziennika nie zostały jeszcze zbuforowane.",
|
||||
"no_maintenance": "Nie zarejestrowano jeszcze żadnej konserwacji.",
|
||||
"no_match_yet": "Brak jeszcze próby dopasowania — komunikat pojawia się podczas trwającego cyklu.",
|
||||
"no_match_yet": "Brak jeszcze próby dopasowania – komunikat pojawia się podczas trwającego cyklu.",
|
||||
"no_other_users": "Nie znaleziono innych użytkowników Home Assistant.",
|
||||
"no_phases": "Nie zdefiniowano faz.",
|
||||
"no_phases_assigned": "Brak przypisanych faz.",
|
||||
@@ -713,7 +718,7 @@
|
||||
"notify_services_hint": "Użyj identyfikatorów usług {entity} (oddzielonych przecinkami dla kilku). Zmienne szablonu: {vars}.",
|
||||
"old_actions_warning": "Skonfigurowano przy użyciu starego edytora akcji (teraz usuniętego). Nadal uruchamiają się w przypadku wydarzeń cyklicznych, ale nie można ich już tutaj edytować. Przekształć je w normalną automatyzację lub usuń.",
|
||||
"onboarding_progress": "Zaobserwowano {n} / 3 cykli",
|
||||
"onboarding_watching": "Używaj urządzenia normalnie — WashData obserwuje. Po 3 cyklach rozpocznie się dopasowywanie programów.",
|
||||
"onboarding_watching": "Używaj urządzenia normalnie – WashData obserwuje. Po 3 cyklach rozpocznie się dopasowywanie programów.",
|
||||
"pending_feedback": "Oczekuje na informację zwrotną dotyczącą wykrycia",
|
||||
"performance_trend": "Trend wydajności ({n} cykli)",
|
||||
"pg_analysis_empty": "Wczytaj cykl, aby zobaczyć analizę dopasowania.",
|
||||
@@ -748,7 +753,7 @@
|
||||
"restart_gap_footer": "Zaznaczone na wykresie. Dane mocy są niedostępne dla tych przedziałów; dopasowanie używało tylko rzeczywistych odczytów.",
|
||||
"restart_gap_header": "{n} przerwa restartu HA podczas tego cyklu",
|
||||
"restart_gap_item": "{dur} przerwa",
|
||||
"review_confirm_help": "Sprawdź, czy ten cykl został prawidłowo wykryty. Twoje recenzje szkolą model na Twojej maszynie — im więcej cykli potwierdzisz, tym lepsze dopasowanie i punktacja kondycji. Wystarczy szybkie dobre/złe.",
|
||||
"review_confirm_help": "Sprawdź, czy ten cykl został prawidłowo wykryty. Twoje recenzje szkolą model na Twojej maszynie – im więcej cykli potwierdzisz, tym lepsze dopasowanie i punktacja kondycji. Wystarczy szybkie dobre/złe.",
|
||||
"review_in_settings": "Przejrzyj w Ustawieniach",
|
||||
"review_notes_placeholder": "Notatki (opcjonalnie)",
|
||||
"review_notes_tip": "Notatki tekstowe do własnego użytku. Nieużywane podczas dopasowywania lub treningu.",
|
||||
@@ -763,7 +768,7 @@
|
||||
"setting_changed": "Zmieniono z {old} na {new} dnia {date}",
|
||||
"settings_basic_note": "Wyświetlane są podstawowe ustawienia. Przełącz na Zaawansowane, aby zobaczyć pełną listę.",
|
||||
"shape_drift_advisory": "⚠ Dryf kształtu",
|
||||
"shape_drift_detail": "Wzorzec mocy dla tego profilu zmienił się z biegiem czasu — możliwe zużycie urządzenia lub konieczna konserwacja (np. odkamienianie, czyszczenie filtra).",
|
||||
"shape_drift_detail": "Wzorzec mocy dla tego profilu zmienił się z biegiem czasu – możliwe zużycie urządzenia lub konieczna konserwacja (np. odkamienianie, czyszczenie filtra).",
|
||||
"show_all_settings": "Pokaż wszystkie ustawienia",
|
||||
"showing_suggestions": "Wyświetlam ustawienie {count} z sugestiami.",
|
||||
"split_intro": "Kliknij wykres, aby dodać lub usunąć punkt podziału albo automatycznie wykryć na podstawie pustych przerw. Każdy powstały segment może otrzymać swój własny profil.",
|
||||
@@ -789,10 +794,10 @@
|
||||
"toast_revert_failed": "Przywracanie nie powiodło się: {error}",
|
||||
"toast_reverted": "Cofnięto: {key}",
|
||||
"toast_save_failed": "Zapisywanie nie powiodło się: {error}",
|
||||
"trend_duration_longer": "Trwanie w trendzie dłuższym ({pct}%/cykl) — ostatnia średnia {avg}",
|
||||
"trend_duration_shorter": "Trwanie w trendzie krótszym ({pct}%/cykl) — ostatnia średnia {avg}",
|
||||
"trend_duration_longer": "Trwanie w trendzie dłuższym ({pct}%/cykl) – ostatnia średnia {avg}",
|
||||
"trend_duration_shorter": "Trwanie w trendzie krótszym ({pct}%/cykl) – ostatnia średnia {avg}",
|
||||
"trend_energy_down": "Energia wykazuje tendencję spadkową ({pct}%/cykl)",
|
||||
"trend_energy_up": "Trend wzrostowy w zakresie energii ({pct}%/cykl) — ostatnia średnia {avg}",
|
||||
"trend_energy_up": "Trend wzrostowy w zakresie energii ({pct}%/cykl) – ostatnia średnia {avg}",
|
||||
"trim_intro": "Przeciągnij czerwone uchwyty lub wprowadź wartości. Wszystko za 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",
|
||||
@@ -857,7 +862,9 @@
|
||||
"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ń"
|
||||
"share_profile_no_cycles": "Profil '{p}' nie ma ⭐ cykli referencyjnych -- zostanie pominięty, chyba że masz {n}+ potwierdzonych uruchomień",
|
||||
"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"
|
||||
},
|
||||
"phase_desc": {
|
||||
"anti_crease": "Sporadyczne krótkie obroty bębna po zakończeniu w celu zapobiegania gnieceniu tkanin.",
|
||||
@@ -940,6 +947,10 @@
|
||||
"triggers": {
|
||||
"intro": "Opcjonalne zewnętrzne sygnały: wyzwalacz zakończenia, czujnik drzwi, przełącznik pauzy i przypomnienie o rozładunku.",
|
||||
"label": "Wyzwalacze i Drzwi"
|
||||
},
|
||||
"phase_eta": {
|
||||
"label": "Pozostały czas",
|
||||
"intro": "Pozostały czas uwzględniający fazy, dla urządzeń, których długość cyklu zależy od temperatury lub wirowania."
|
||||
}
|
||||
},
|
||||
"setting": {
|
||||
@@ -1023,6 +1034,10 @@
|
||||
"doc": "Stała cena za kWh używana do danych o kosztach, gdy powyżej nie określono żadnej jednostki ceny rzeczywistej.",
|
||||
"label": "Statyczna Cena Energii (za kWh)"
|
||||
},
|
||||
"energy_sensor": {
|
||||
"doc": "Opcjonalny skumulowany licznik energii (total_increasing kWh/Wh, np. własny licznik całkowitego zużycia wtyczki). Po ustawieniu energia raportowana dla każdego cyklu jest pobierana z różnicy wskazań tego licznika między początkiem a końcem, co pozwala uniknąć zaniżania wynikającego z całkowania wolno raportującego czujnika mocy. W razie braku odczytu, nieznanej jednostki lub niedodatniej różnicy następuje powrót do wartości całkowanej. Pozostaw puste, aby nadal całkować czujnik mocy.",
|
||||
"label": "Encja Licznika Energii"
|
||||
},
|
||||
"expose_debug_entities": {
|
||||
"doc": "Publikuj dodatkowe jednostki diagnostyczne HA (pewność dopasowania, niejednoznaczność, elementy wewnętrzne stanu). Opcja Off utrzymuje listę encji w czystości podczas normalnego użytkowania.",
|
||||
"label": "Ujawnij Encje Debugowania"
|
||||
@@ -1220,7 +1235,7 @@
|
||||
"label": "Strefa Martwa"
|
||||
},
|
||||
"sampling_interval": {
|
||||
"doc": "Oczekiwany czas pomiędzy odczytami czujnika — używany do określenia rozmiaru okna wygładzającego i prawidłowego rozpoczęcia odbijania. Każda aktualizacja czujnika jest rejestrowana niezależnie od tej wartości; kalibruje jedynie dalsze obliczenia. Silnik sugestii mierzy rzeczywistą kadencję czujnika z poprzednich cykli i ustawia ją automatycznie.",
|
||||
"doc": "Oczekiwany czas pomiędzy odczytami czujnika – używany do określenia rozmiaru okna wygładzającego i prawidłowego rozpoczęcia odbijania. Każda aktualizacja czujnika jest rejestrowana niezależnie od tej wartości; kalibruje jedynie dalsze obliczenia. Silnik sugestii mierzy rzeczywistą kadencję czujnika z poprzednich cykli i ustawia ją automatycznie.",
|
||||
"label": "Interwał Próbkowania"
|
||||
},
|
||||
"save_debug_traces": {
|
||||
@@ -1305,6 +1320,38 @@
|
||||
},
|
||||
"show_contributor": {
|
||||
"doc": "Pokaż nazwę współtwórcy na profilach pobranych ze sklepu społeczności"
|
||||
},
|
||||
"enable_phase_matching": {
|
||||
"label": "Pozostały czas uwzględniający fazy",
|
||||
"doc": "Dzieli każdy trwający cykl na fazy (podgrzewanie, pranie, wirowanie) i planuje pozostały czas dla każdej fazy, łącząc go z klasycznym szacowaniem - opierając się na budżecie faz na początku cyklu, a na klasycznym szacowaniu pod koniec. Personalizuje to odliczanie do tego, jak długo urządzenie faktycznie się nagrzewa i pracuje, co jest najbardziej zauważalne w pierwszej połowie cyklu. Wyłączone = tylko klasyczne szacowanie. Wpływa to wyłącznie na wyświetlanie pozostałego czasu; dopasowanie programów i wykrywanie cykli pozostają bez zmian."
|
||||
},
|
||||
"keep_min_score": {
|
||||
"label": "Min. wynik dopasowania",
|
||||
"doc": "Minimalny wynik podobieństwa potrzebny kandydatowi, by pozostać w wyścigu dopasowań. Domyślna wartość 0,1 jest celowo łagodna - dopuszcza nawet słabych kandydatów i polega na późniejszych etapach w wyborze najlepszego dopasowania. Zwiększ, by wcześniej odrzucać mało prawdopodobne profile; zmniejsz, by poszerzyć początkową pulę kandydatów."
|
||||
},
|
||||
"dtw_blend": {
|
||||
"label": "Mieszanie znieksztalcenia",
|
||||
"doc": "Jak bardzo wynik wyrównania DTW zastępuje wynik główny Etapu 2. 0 = używaj tylko wyniku Etapu 2, 1 = używaj tylko wyniku DTW, 0,5 (domyślnie) = równe mieszanie. Zwiększ, by bardziej polegać na wyrównaniu, gdy programy mają podobne poziomy mocy, ale różne wzorce czasowe."
|
||||
},
|
||||
"dtw_ensemble_w": {
|
||||
"label": "Mix kombinacji DTW",
|
||||
"doc": "W trybie kombinacji DTW (domyślnym), waga skalowanego L1 względem pochodnego DTW (DDTW). 1,0 = tylko skalowane L1, 0 = tylko DDTW, 0,7 = domyślnie. Wariant skalowany L1 porównuje poziomy mocy; wariant pochodny reaguje na zmiany mocy w czasie. Kombinacja łączy oba."
|
||||
},
|
||||
"dtw_ddtw_scale": {
|
||||
"label": "Skala pochodnej DTW",
|
||||
"doc": "Odległość półnasycenia dla oceniania pochodnym DTW. Wynik spada do połowy, gdy odległość DDTW równa się tej wartości. Mniejsza = większa wrażliwość na różnice kształtu. Domyślna wartość 30 jest skalibrowana do typowych przebiegów mocy urządzeń. Dotyczy tylko trybów DTW kombinacji i ddtw."
|
||||
},
|
||||
"dtw_refine_top_n": {
|
||||
"label": "Liczba doprecyzowanych kandydatow",
|
||||
"doc": "Ile najlepszych kandydatów Etapu 2 jest ponownie ocenianych przez DTW. DTW jest kosztowniejszy, więc stosowany jest tylko do N najlepszych kandydatów. Domyślnie 5. Zwiększ (do 7-9), jeśli właściwy profil czasem zajmuje tylko 4. lub 5. miejsce po Etapie 2 - DTW może go uratować. Zmniejszenie nieznacznie przyspiesza dopasowanie."
|
||||
},
|
||||
"duration_scale": {
|
||||
"label": "Ostrość czasu trwania",
|
||||
"doc": "Ostrość kary za niezgodność czasu trwania w Etapie 4. To logarytm stosunku, przy którym wynik zgodności spada do połowy. Mniejszy = surowszy: niezgodność czasu trwania bardziej obniża wynik. Domyślna wartość 0,175 odpowiada tolerancji ok. 18% przy połowie wagi. Używaj razem z Wagą Czasu Trwania."
|
||||
},
|
||||
"energy_scale": {
|
||||
"label": "Ostrość energii",
|
||||
"doc": "Ostrość kary za niezgodność energii w Etapie 4. Mniejszy = surowszy: niezgodność energii bardziej obniża wynik. Domyślna wartość 0,25 jest celowo bardziej łagodna niż Ostrość Czasu Trwania, ponieważ energia zmienia się z obciążeniem. Używaj razem z Wagą Energii."
|
||||
}
|
||||
},
|
||||
"setting_group": {
|
||||
@@ -1424,24 +1471,24 @@
|
||||
"lower": "Więcej cykli jest oznaczanych automatycznie; niektóre mogą być błędnie zidentyfikowane"
|
||||
},
|
||||
"duration_tolerance": {
|
||||
"higher": "Akceptuje szerszy zakres czasu trwania — bardziej elastyczne dopasowanie",
|
||||
"lower": "Wymaga bliższego dopasowania czasu trwania — bardziej rygorystyczne, ale może odrzucić nietypowe cykle"
|
||||
"higher": "Akceptuje szerszy zakres czasu trwania – bardziej elastyczne dopasowanie",
|
||||
"lower": "Wymaga bliższego dopasowania czasu trwania – bardziej rygorystyczne, ale może odrzucić nietypowe cykle"
|
||||
},
|
||||
"end_energy_threshold": {
|
||||
"higher": "Zamyka tylko cykle o znacznym zużyciu energii",
|
||||
"lower": "Zamyka również krótsze lub mniej energochłonne cykle"
|
||||
},
|
||||
"end_repeat_count": {
|
||||
"higher": "Wymaga więcej powtórzeń sygnału końca — bardziej niezawodne, nieco wolniejsze",
|
||||
"lower": "Kończy po mniejszej liczbie powtórzeń — szybsze wykrywanie, większe ryzyko fałszywego zakończenia"
|
||||
"higher": "Wymaga więcej powtórzeń sygnału końca – bardziej niezawodne, nieco wolniejsze",
|
||||
"lower": "Kończy po mniejszej liczbie powtórzeń – szybsze wykrywanie, większe ryzyko fałszywego zakończenia"
|
||||
},
|
||||
"learning_confidence": {
|
||||
"higher": "Uczy się tylko z bardzo pewnych dopasowań — wolniejsze, ale bardziej niezawodne",
|
||||
"higher": "Uczy się tylko z bardzo pewnych dopasowań – wolniejsze, ale bardziej niezawodne",
|
||||
"lower": "Uczy się z większej liczby cykli; model może być mniej precyzyjny"
|
||||
},
|
||||
"min_off_gap": {
|
||||
"higher": "Potrzeba dłuższego spokoju przed rozpoczęciem nowego cyklu",
|
||||
"lower": "Krótki spokój uruchamia nowy cykl — kolejne uruchomienia mogą się rozdzielić"
|
||||
"lower": "Krótki spokój uruchamia nowy cykl – kolejne uruchomienia mogą się rozdzielić"
|
||||
},
|
||||
"min_power": {
|
||||
"higher": "Mniej wrażliwy na pobór mocy w stanie gotowości; może przeoczyć bardzo ciche programy",
|
||||
@@ -1452,24 +1499,24 @@
|
||||
"lower": "Zablokowany cykl jest kończony wcześniej"
|
||||
},
|
||||
"off_delay": {
|
||||
"higher": "Więcej czasu na przerwy urządzenia — dobre dla długich faz namaczania lub suszenia",
|
||||
"lower": "Szybsze wykrywanie końca — działa dobrze dla urządzeń z czystym włączaniem/wyłączaniem"
|
||||
"higher": "Więcej czasu na przerwy urządzenia – dobre dla długich faz namaczania lub suszenia",
|
||||
"lower": "Szybsze wykrywanie końca – działa dobrze dla urządzeń z czystym włączaniem/wyłączaniem"
|
||||
},
|
||||
"profile_match_threshold": {
|
||||
"higher": "Zatwierdza tylko dopasowania o wysokiej pewności; więcej cykli pozostaje nieoznakowanych",
|
||||
"lower": "Dopasowuje więcej cykli; niektóre mogą być lekko błędne"
|
||||
},
|
||||
"running_dead_zone": {
|
||||
"higher": "Ignoruje krótkie skoki mocy podczas bezczynności — mniej wrażliwy na zakłócenia",
|
||||
"lower": "Reaguje na krótsze impulsy mocy — wykrywa szybką aktywność przejściową"
|
||||
"higher": "Ignoruje krótkie skoki mocy podczas bezczynności – mniej wrażliwy na zakłócenia",
|
||||
"lower": "Reaguje na krótsze impulsy mocy – wykrywa szybką aktywność przejściową"
|
||||
},
|
||||
"start_threshold_w": {
|
||||
"higher": "Zapobiega fałszywym startom z krótkich skoków mocy",
|
||||
"lower": "Wykrywa programy o niskiej mocy; może reagować na zakłócenia"
|
||||
},
|
||||
"stop_threshold_w": {
|
||||
"higher": "Kończy cykl szybciej — może zamknąć w trakcie przerwy",
|
||||
"lower": "Czeka dłużej na zakończenie — mniej przedwczesnych zakończeń"
|
||||
"higher": "Kończy cykl szybciej – może zamknąć w trakcie przerwy",
|
||||
"lower": "Czeka dłużej na zakończenie – mniej przedwczesnych zakończeń"
|
||||
},
|
||||
"watchdog_interval": {
|
||||
"higher": "Dopuszcza dłuższe ciche fazy; mniej fałszywych wymuszeń zatrzymania",
|
||||
@@ -1676,12 +1723,19 @@
|
||||
"start_duration_threshold": "Sekundy powyżej progu, by potwierdzić start",
|
||||
"start_threshold_w": "Minimalna moc w watach, by uznać za rozpoczęty",
|
||||
"stop_threshold_w": "Poniżej tej wartości urządzenie liczone jest jako wyłączone",
|
||||
"dtw_bandwidth": "Jak duże zniekształcenie czasowe dopuszcza dopasowanie kształtu",
|
||||
"corr_weight": "Waga kształtu krzywej względem poziomu mocy w dopasowaniu",
|
||||
"duration_weight": "Jak bardzo zgodność czasu trwania wpływa na dopasowanie",
|
||||
"energy_weight": "Jak bardzo zgodność zużycia energii wpływa na dopasowanie",
|
||||
"profile_match_min_duration_ratio": "Najkrótszy przebieg (względem profilu), który nadal może zostać dopasowany",
|
||||
"profile_match_max_duration_ratio": "Najdłuższy przebieg (względem profilu), który nadal może zostać dopasowany"
|
||||
"dtw_bandwidth": "Etap 3: pasmo zniekształcenia Sakoe-Chiba (0 = DTW wyłączony; domyślnie 0,2 = 20% długości cyklu)",
|
||||
"corr_weight": "Etap 2: balans między kształtem krzywej (korelacja) a poziomem mocy (MAE); domyślnie 0,45",
|
||||
"duration_weight": "Etap 4: jak mocno zgodność czasu trwania wpływa na wynik końcowy (domyślnie 0,22)",
|
||||
"energy_weight": "Etap 4: jak mocno zgodność energii wpływa na wynik końcowy (domyślnie 0,22)",
|
||||
"profile_match_min_duration_ratio": "Etap 1: minimalna długość cyklu jako ułamek czasu trwania profilu; domyślnie 0,1 (10%)",
|
||||
"profile_match_max_duration_ratio": "Etap 1: maksymalna długość cyklu jako ułamek czasu trwania profilu; domyślnie 1,5 (150%)",
|
||||
"keep_min_score": "Etap 2: minimalny wynik, by pozostać w wyścigu; domyślnie 0,1 dopuszcza słabe dopasowania, późniejsze etapy wybierają najlepsze",
|
||||
"dtw_blend": "Etap 3: 0 = tylko wynik główny, 1 = tylko wynik DTW, 0,5 = równe mieszanie (domyślnie)",
|
||||
"dtw_ensemble_w": "Etap 3 (tryb kombinacji): waga skalowanego L1 względem pochodnego DTW; domyślnie 0,7 faworyzuje poziom",
|
||||
"dtw_ddtw_scale": "Etap 3: odległość półnasycenia DDTW; mniejsza = bardziej wrażliwa na kształt (domyślnie 30)",
|
||||
"dtw_refine_top_n": "Etap 3: kandydaci ponownie oceniani przez DTW; zwiększ do 7-9, jeśli właściwy profil zajmuje 4-5 miejsce (domyślnie 5)",
|
||||
"duration_scale": "Etap 4: logarytm stosunku, przy którym zgodność czasu trwania spada do połowy; mniejszy = surowsza kara (domyślnie 0,175)",
|
||||
"energy_scale": "Etap 4: logarytm stosunku, przy którym zgodność energii spada do połowy; mniejszy = surowsza kara (domyślnie 0,25)"
|
||||
},
|
||||
"col": {
|
||||
"profile_tip": "Nazwa dopasowanego programu. Brak etykiety oznacza, że na końcu cyklu nie dopasowano żadnego profilu.",
|
||||
@@ -1766,6 +1820,69 @@
|
||||
},
|
||||
"pg_sweep": {
|
||||
"optimize": "Optymalizacja: {param}"
|
||||
},
|
||||
"pg_detail": {
|
||||
"simulate": "Symuluj cykl"
|
||||
},
|
||||
"split": {
|
||||
"apply": "Dzielenie cyklu"
|
||||
},
|
||||
"trim": {
|
||||
"apply": "Przycinanie cyklu"
|
||||
},
|
||||
"merge": {
|
||||
"apply": "Scalanie cykli"
|
||||
},
|
||||
"rebuild": {
|
||||
"envelopes": "Przeliczanie obwiedni"
|
||||
},
|
||||
"cancelling": "Anulowanie..."
|
||||
},
|
||||
"setup": {
|
||||
"hdr": {
|
||||
"card": "Konfiguracja urządzenia",
|
||||
"healthy_chip": "Konfiguracja ukończona"
|
||||
},
|
||||
"phase0": {
|
||||
"washer": "WashData już wykrywa Twoje cykle. Nagraj pierwszy cykl, aby włączyć nazwy programów i szacunki czasu.",
|
||||
"dishwasher": "WashData obserwuje. Zmywarki mają złożone cykle – nagranie pierwszego cyklu jest zdecydowanie zalecane. Jeśli wykryty cykl trwa zbyt długo, użyj edytora cyklu, aby go przyciąć przed zapisaniem jako profil.",
|
||||
"generic": "WashData obserwuje. Nagraj lub oznacz wykryty cykl, aby zacząć tworzyć profile."
|
||||
},
|
||||
"phase1a": {
|
||||
"labelled": "Dobry początek – Twój pierwszy program jest zapisany. Aby uzyskać najczystsze dane, rozważ nagranie następnego cyklu za pomocą widżetu rejestratora."
|
||||
},
|
||||
"phase1b": {
|
||||
"recorded": "Nagranie zostało zapisane jako {profile_name}. Teraz nagraj lub oznacz inne popularne programy, aby rozszerzyć pokrycie."
|
||||
},
|
||||
"phase1c": {
|
||||
"verify": "Masz {count} programów ze społeczności. Uruchom cykl, aby sprawdzić, czy WashData rozpoznaje go poprawnie – dopasowanie będzie się poprawiać w miarę jak urządzenie buduje własną historię."
|
||||
},
|
||||
"phase2": {
|
||||
"cluster": "WashData zauważył {count} cykli, które nie pasują do żadnego zapisanego programu – wyglądają podobnie do siebie. Chcesz utworzyć dla nich nowy profil?",
|
||||
"unmatched": "Twój ostatni cykl nie pasował do żadnego zapisanego programu. Czy to nowy program?"
|
||||
},
|
||||
"phase3": {
|
||||
"suggestions": "WashData ma zalecenia dotyczące ustawień oparte na historii Twoich cykli – przejrzyj je, aby poprawić dokładność wykrywania.",
|
||||
"groups": "Niektóre Twoje profile wyglądają jak ten sam program w różnych temperaturach. Zorganizuj je w grupę dla lepszego dopasowania.",
|
||||
"phases": "Dodaj fazy programu do {profile_name} dla dokładniejszych szacunków pozostałego czasu."
|
||||
},
|
||||
"phase4": {
|
||||
"healthy": "To urządzenie jest w pełni skonfigurowane ({profile_count} profili)."
|
||||
},
|
||||
"cta": {
|
||||
"start_recording": "Rozpocznij nagrywanie",
|
||||
"label_detected_cycle": "Mam już wykryty cykl – oznacz go zamiast tego",
|
||||
"browse_cycles": "Przeglądaj cykle, aby oznaczyć kolejny",
|
||||
"view_profiles": "Wyświetl swoje profile",
|
||||
"create_from_cluster": "Utwórz profil z tych cykli",
|
||||
"create_profile": "Utwórz dla niego profil",
|
||||
"review_suggestions": "Przejrzyj sugestie",
|
||||
"organise_profiles": "Zorganizuj profile",
|
||||
"configure_phases": "Skonfiguruj fazy",
|
||||
"skip_step": "Pomiń ten krok",
|
||||
"skip_forever": "Nie pokazuj ponownie",
|
||||
"hide_guidance": "Ukryj wskazówki",
|
||||
"show_guidance": "Pokaż wskazówki"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
{
|
||||
"badge": {
|
||||
"artifact_tip": "{n} anomalias detectadas (por exemplo, porta aberta no meio do ciclo) — abra para vê-las no gráfico",
|
||||
"artifact_tip": "{n} anomalias detectadas (por exemplo, porta aberta no meio do ciclo) – abra para vê-las no gráfico",
|
||||
"auto": "(detectado automaticamente)",
|
||||
"built_in_tag": "integrado",
|
||||
"declining": "↘ em declínio",
|
||||
"energy_low": "Energia abaixo do habitual",
|
||||
"energy_spike": "Energia acima do habitual",
|
||||
"fair_fit": "qualidade aceitável",
|
||||
"fair_fit_tip": "Consistência de correspondência moderada — alguns ciclos atribuídos a este perfil têm pontuações de confiança mais baixas. Rotule mais ciclos ou regrave o perfil para melhorar a precisão.",
|
||||
"fair_fit_tip": "Consistência de correspondência moderada – alguns ciclos atribuídos a este perfil têm pontuações de confiança mais baixas. Rotule mais ciclos ou regrave o perfil para melhorar a precisão.",
|
||||
"feedback_requested": "Feedback solicitado",
|
||||
"golden_cycle": "Ciclo de referência gravado",
|
||||
"improving": "↗ melhorando",
|
||||
@@ -15,7 +15,7 @@
|
||||
"needs_review": "Precisa de revisão",
|
||||
"overrun": "Demorou mais tempo que o normal",
|
||||
"poor_fit": "qualidade fraca",
|
||||
"poor_fit_tip": "Histórico de correspondência inconsistente — considere reconstruir este perfil",
|
||||
"poor_fit_tip": "Histórico de correspondência inconsistente – considere reconstruir este perfil",
|
||||
"restart_gap_tip": "{n} lacuna de reinicialização do HA: o rastro de potência tem uma lacuna",
|
||||
"reviewed": "Revisado",
|
||||
"steady": "→ estável",
|
||||
@@ -57,7 +57,7 @@
|
||||
"create_profile": "+ Criar perfil",
|
||||
"delete": "Excluir",
|
||||
"delete_group": "Excluir grupo",
|
||||
"delete_group_tip": "Excluir apenas este grupo — os perfis dos membros são mantidos",
|
||||
"delete_group_tip": "Excluir apenas este grupo – os perfis dos membros são mantidos",
|
||||
"delete_profile": "Excluir perfil",
|
||||
"discard": "Descartar",
|
||||
"discard_tip": "Descartar a gravação capturada sem salvar",
|
||||
@@ -87,7 +87,7 @@
|
||||
"on_cycle_finished": "Ao terminar o ciclo",
|
||||
"on_cycle_started": "Ao iniciar o ciclo",
|
||||
"pause_cycle": "Pausar",
|
||||
"pause_cycle_tip": "Pausar o ciclo em andamento — o eletrodoméstico retomará onde parou",
|
||||
"pause_cycle_tip": "Pausar o ciclo em andamento – o eletrodoméstico retomará onde parou",
|
||||
"pg_apply_device": "Aplicar ao dispositivo",
|
||||
"pg_autofill": "Preencher automaticamente",
|
||||
"play": "Reproduzir",
|
||||
@@ -97,8 +97,8 @@
|
||||
"process_tip": "Salvar o rastro gravado como um perfil novo ou existente",
|
||||
"rebuild": "Reconstruir envelopes",
|
||||
"rebuild_envelope": "Reconstruir envelope",
|
||||
"rebuild_tip": "Recalcular o envelope de potência esperado (faixa mín/máx) para todos os perfis a partir dos seus ciclos rotulados — executar após rotular novos ciclos ou corrigir os existentes",
|
||||
"rec_start_tip": "Iniciar a gravação do rastro de potência do eletrodoméstico — iniciar logo antes de executar um ciclo",
|
||||
"rebuild_tip": "Recalcular o envelope de potência esperado (faixa mín/máx) para todos os perfis a partir dos seus ciclos rotulados – executar após rotular novos ciclos ou corrigir os existentes",
|
||||
"rec_start_tip": "Iniciar a gravação do rastro de potência do eletrodoméstico – iniciar logo antes de executar um ciclo",
|
||||
"rec_stop": "Parar",
|
||||
"rec_stop_tip": "Parar a gravação e manter o rastro capturado para revisão",
|
||||
"record": "Iniciar gravação",
|
||||
@@ -182,7 +182,7 @@
|
||||
},
|
||||
"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.",
|
||||
"settings_banner": "{n} conflito{s} de configurações – verifique as seções destacadas e corrija antes de salvar.",
|
||||
"settings_banner_btn": "Ir para o primeiro",
|
||||
"confidence": {
|
||||
"auto": "Deve ser maior ou igual ao Limiar de correspondência ({match})",
|
||||
@@ -451,9 +451,9 @@
|
||||
"show_expected": "Mostrar sobreposição da curva esperada (perfil correspondente, laranja)",
|
||||
"show_raw": "Mostrar o interruptor de sinal bruto da tomada no gráfico de potência ao vivo",
|
||||
"sparkline": "Tendência recente da duração dos ciclos",
|
||||
"stage2": "Etapa 2 — similaridade principal",
|
||||
"stage3": "Etapa 3 — DTW",
|
||||
"stage4": "Etapa 4 — concordância",
|
||||
"stage2": "Etapa 2 – similaridade principal",
|
||||
"stage3": "Etapa 3 – DTW",
|
||||
"stage4": "Etapa 4 – concordância",
|
||||
"status": "Status",
|
||||
"tail_trim": "Recorte final (s)",
|
||||
"timer_auto_pause": "Pausa automática",
|
||||
@@ -561,7 +561,12 @@
|
||||
"flags": "Sinalizadores",
|
||||
"include_phase_map": "Incluir mapa de fases",
|
||||
"include_settings": "Incluir configurações de detecção e reconhecimento",
|
||||
"show_contributor": "Mostrar nomes dos contribuidores"
|
||||
"show_contributor": "Mostrar nomes dos contribuidores",
|
||||
"task_pg_detail": "Simular ciclo",
|
||||
"task_split": "Dividindo o ciclo",
|
||||
"task_trim": "Recortando o ciclo",
|
||||
"task_merge": "Combinando ciclos",
|
||||
"task_rebuild": "Reconstruindo envelopes"
|
||||
},
|
||||
"log": {
|
||||
"all_levels": "Todos os níveis",
|
||||
@@ -645,7 +650,7 @@
|
||||
"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.",
|
||||
"artifact_header": "{n} anomalias detectadas durante este ciclo",
|
||||
"artifact_pause_detail": "A potência caiu quase a zero por ~{n}s e depois retomou — provavelmente a porta foi aberta no meio do ciclo ou o ciclo foi pausado.",
|
||||
"artifact_pause_detail": "A potência caiu quase a zero por ~{n}s e depois retomou – provavelmente a porta foi aberta no meio do ciclo ou o ciclo foi pausado.",
|
||||
"artifact_spike_detail": "Ultrapassou a banda de potência habitual por ~{n}s.",
|
||||
"auto_label_intro": "Atribua perfis a ciclos sem rótulo cuja confiança de correspondência supere o limite.",
|
||||
"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.",
|
||||
@@ -654,10 +659,10 @@
|
||||
"collecting_data": "Coletando dados - {need} ciclo{plural} a mais antes que o ajuste fino possa começar ({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",
|
||||
"compare_selected_cycles": "Ciclos selecionados (sólido) – mostrar / ocultar",
|
||||
"consider_new_profile": "Considere criar um novo perfil.",
|
||||
"coverage_gap": "os ciclos recentes não têm perfil correspondente ({pct}% dos últimos 30).",
|
||||
"coverage_gap_similar_cycles": "{count} ciclos similares sem rótulo encontrados — crie um perfil para começar a correspondê-los.",
|
||||
"coverage_gap_similar_cycles": "{count} ciclos similares sem rótulo encontrados – crie um perfil para começar a correspondê-los.",
|
||||
"cycles_deleted": "{count} ciclo(s) excluído(s)",
|
||||
"enough_data": "Dados suficientes para aprender ({current}/{min} ciclos).",
|
||||
"export_description": "Exporte todos os perfis e ciclos para JSON ou restaure de uma exportação anterior.",
|
||||
@@ -686,7 +691,7 @@
|
||||
"ml_learned_intro": "Modelos ajustados a esta máquina.",
|
||||
"ml_loading": "carregando ML…",
|
||||
"ml_settings_intro": "Dois botões independentes: um aplica os modelos durante um ciclo, o outro permite ao WashData ajustá-los à sua máquina ao longo do tempo.",
|
||||
"name_first_program": "Você já tem ciclos suficientes — dê um nome ao seu primeiro programa para começar a correspondência.",
|
||||
"name_first_program": "Você já tem ciclos suficientes – dê um nome ao seu primeiro programa para começar a correspondência.",
|
||||
"near_duplicate_cluster": "cluster de perfis quase duplicados detectado. O agrupamento permite que a correspondência escolha de forma confiável entre perfis semelhantes (por exemplo, o mesmo programa em temperatura/centrifugação diferente).",
|
||||
"no_cycles_match": "Nenhum ciclo corresponde ao filtro atual.",
|
||||
"no_cycles_profile": "Nenhum ciclo para este perfil.",
|
||||
@@ -694,12 +699,12 @@
|
||||
"no_cycles_yet": "Nenhum ciclo gravado ainda.",
|
||||
"no_device_selected": "Nenhum dispositivo selecionado.",
|
||||
"no_devices": "Nenhum dispositivo WashData configurado ainda.",
|
||||
"no_envelope": "Nenhum envelope ainda — reconstrua após rotular os ciclos.",
|
||||
"no_envelope": "Nenhum envelope ainda – reconstrua após rotular os ciclos.",
|
||||
"no_envelope_overlay": "Nenhum envelope disponível para sobrepor.",
|
||||
"no_fine_tuned": "Nada ajustado ainda — o WashData está usando seus modelos integrados.",
|
||||
"no_fine_tuned": "Nada ajustado ainda – o WashData está usando seus modelos integrados.",
|
||||
"no_logs": "Nenhum registro em buffer ainda.",
|
||||
"no_maintenance": "Ainda não há manutenções registradas.",
|
||||
"no_match_yet": "Nenhuma tentativa de correspondência ainda — isto é preenchido durante um ciclo em execução.",
|
||||
"no_match_yet": "Nenhuma tentativa de correspondência ainda – isto é preenchido durante um ciclo em execução.",
|
||||
"no_other_users": "Nenhum outro usuário do Home Assistant encontrado.",
|
||||
"no_phases": "Nenhuma fase definida.",
|
||||
"no_phases_assigned": "Nenhuma fase atribuída.",
|
||||
@@ -713,7 +718,7 @@
|
||||
"notify_services_hint": "Use os IDs de serviço de {entity} (separados por vírgula para múltiplos). Variáveis de template: {vars}.",
|
||||
"old_actions_warning": "Configurado com o antigo editor de ações (agora removido). Ainda são acionadas em eventos de ciclo, mas não podem mais ser editadas aqui. Converta-as em uma automação normal ou remova-as.",
|
||||
"onboarding_progress": "{n} / 3 ciclos observados",
|
||||
"onboarding_watching": "Use o eletrodoméstico normalmente — o WashData está observando. Após 3 ciclos, a correspondência de programas começará.",
|
||||
"onboarding_watching": "Use o eletrodoméstico normalmente – o WashData está observando. Após 3 ciclos, a correspondência de programas começará.",
|
||||
"pending_feedback": "Feedback de detecção pendente",
|
||||
"performance_trend": "Tendência de desempenho ({n} ciclos)",
|
||||
"pg_analysis_empty": "Carregue um ciclo para ver a análise de correspondência.",
|
||||
@@ -748,13 +753,13 @@
|
||||
"restart_gap_footer": "Destacado no gráfico. Dados de potência estão ausentes para esses intervalos; o reconhecimento usou apenas leituras reais.",
|
||||
"restart_gap_header": "{n} lacuna de reinicialização do HA durante este ciclo",
|
||||
"restart_gap_item": "{dur} lacuna",
|
||||
"review_confirm_help": "Confirme se este ciclo foi detectado corretamente. Suas revisões treinam o modelo na sua máquina — quanto mais ciclos confirmar, melhor ficam a correspondência e a pontuação de saúde. Um Bom/Ruim rápido é suficiente.",
|
||||
"review_confirm_help": "Confirme se este ciclo foi detectado corretamente. Suas revisões treinam o modelo na sua máquina – quanto mais ciclos confirmar, melhor ficam a correspondência e a pontuação de saúde. Um Bom/Ruim rápido é suficiente.",
|
||||
"review_in_settings": "Revisar em Configurações",
|
||||
"review_notes_placeholder": "Observações (opcional)",
|
||||
"review_notes_tip": "Notas em texto livre para sua própria referência. Não são usadas pela correspondência ou pelo treinamento.",
|
||||
"review_profile_tip": "O programa com que este ciclo está rotulado. Se o programa detectado automaticamente estava errado, corrija-o aqui — a rotulagem ensina a correspondência para ciclos futuros.",
|
||||
"review_profile_tip": "O programa com que este ciclo está rotulado. Se o programa detectado automaticamente estava errado, corrija-o aqui – a rotulagem ensina a correspondência para ciclos futuros.",
|
||||
"review_quality_tip": "A qualidade deste ciclo. Bom = um exemplo perfeito deste programa; Ruim = detectado mas ruidoso ou atípico; Inutilizável = detectado incorretamente (mesclado, truncado ou espúrio). Determina a pontuação de saúde e quais ciclos são permitidos para treinar o modelo.",
|
||||
"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_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",
|
||||
"saving_triggers_reload": "Salvar aciona um recarregamento da integração. As entidades do HA podem ficar brevemente indisponíveis.",
|
||||
@@ -763,7 +768,7 @@
|
||||
"setting_changed": "Alterado de {old} para {new} em {date}",
|
||||
"settings_basic_note": "Mostrando as configurações essenciais. Mude para Avançado para ver a lista completa.",
|
||||
"shape_drift_advisory": "⚠ Desvio de forma",
|
||||
"shape_drift_detail": "O padrão de potência para este perfil mudou ao longo do tempo — possível desgaste do eletrodoméstico ou manutenção necessária (por exemplo, descalcificação, limpeza do filtro).",
|
||||
"shape_drift_detail": "O padrão de potência para este perfil mudou ao longo do tempo – possível desgaste do eletrodoméstico ou manutenção necessária (por exemplo, descalcificação, limpeza do filtro).",
|
||||
"show_all_settings": "Mostrar todas as configurações",
|
||||
"showing_suggestions": "Mostrando a configuração {count} com sugestões.",
|
||||
"split_intro": "Clique no gráfico para adicionar ou remover um ponto de divisão, ou detecte automaticamente por intervalos de inatividade. Cada segmento resultante pode ter seu próprio perfil.",
|
||||
@@ -789,10 +794,10 @@
|
||||
"toast_revert_failed": "Reversão falhou: {error}",
|
||||
"toast_reverted": "{key} revertido",
|
||||
"toast_save_failed": "Salvamento falhou: {error}",
|
||||
"trend_duration_longer": "Duração com tendência crescente ({pct}%/ciclo) — média recente {avg}",
|
||||
"trend_duration_shorter": "Duração com tendência decrescente ({pct}%/ciclo) — média recente {avg}",
|
||||
"trend_duration_longer": "Duração com tendência crescente ({pct}%/ciclo) – média recente {avg}",
|
||||
"trend_duration_shorter": "Duração com tendência decrescente ({pct}%/ciclo) – média recente {avg}",
|
||||
"trend_energy_down": "Energia com tendência decrescente ({pct}%/ciclo)",
|
||||
"trend_energy_up": "Energia com tendência crescente ({pct}%/ciclo) — média recente {avg}",
|
||||
"trend_energy_up": "Energia com tendência crescente ({pct}%/ciclo) – média recente {avg}",
|
||||
"trim_intro": "Arraste as alças vermelhas ou insira valores. Tudo fora da janela é removido.",
|
||||
"tuning_suggestions_available": "{count} sugestão de ajuste disponível a partir dos ciclos observados. Aparecem ao lado dos campos relevantes.",
|
||||
"unsure_detected_prefix": "O WashData não tem certeza se detectou",
|
||||
@@ -857,7 +862,9 @@
|
||||
"share_guidelines_title": "Antes de compartilhar",
|
||||
"store_download_device_intro": "Adote todos os programas compartilhados e seus ciclos de referência neste dispositivo. Seus próprios ciclos gravados e estatísticas não são afetados.",
|
||||
"store_share_device_intro": "Envie {brand} {model} com os ciclos de referência que você selecionar. Outros usuários com o mesmo eletrodoméstico podem adotar seus programas. As entradas são revisadas antes de aparecerem publicamente.",
|
||||
"share_profile_no_cycles": "Nenhum ciclo de referência -- marque um ciclo como ⭐ na aba Ciclos para incluir este perfil"
|
||||
"share_profile_no_cycles": "Nenhum ciclo de referência -- marque um ciclo como ⭐ na aba Ciclos para incluir este perfil",
|
||||
"advisory_phase_inconsistent": "'{name}' parece misturar diferentes programas ou temperaturas - seus ciclos aquecem por períodos de tempo muito diferentes. Dividi-lo em perfis separados (por ex. por temperatura) melhorará a correspondência e as estimativas de tempo.",
|
||||
"advisory_phase_inconsistent_title": "⚠ Possíveis programas misturados"
|
||||
},
|
||||
"phase_desc": {
|
||||
"anti_crease": "Giros curtos ocasionais após a conclusão para reduzir amassados.",
|
||||
@@ -940,6 +947,10 @@
|
||||
"triggers": {
|
||||
"intro": "Sinais externos opcionais: um gatilho de fim, um sensor de porta, um interruptor de pausa e o lembrete de descarga.",
|
||||
"label": "Gatilhos e Portas"
|
||||
},
|
||||
"phase_eta": {
|
||||
"label": "Tempo restante",
|
||||
"intro": "Tempo restante com base nas fases, para máquinas cuja duração do ciclo depende da temperatura ou da centrifugação."
|
||||
}
|
||||
},
|
||||
"setting": {
|
||||
@@ -1023,6 +1034,10 @@
|
||||
"doc": "Preço fixo por kWh usado para valores de custos quando nenhuma entidade de preço real é definida acima.",
|
||||
"label": "Preço Estático de Energia (por kWh)"
|
||||
},
|
||||
"energy_sensor": {
|
||||
"doc": "Contador de energia cumulativo opcional (total_increasing em kWh/Wh, por ex. o medidor de consumo total da própria tomada). Quando definido, a energia informada de cada ciclo é obtida a partir da diferença deste contador entre o início e o fim, o que evita a subcontagem resultante da integração de um sensor de potência que informa lentamente. Recorre ao valor integrado se a leitura estiver ausente, se sua unidade for desconhecida ou se o delta não for positivo. Deixe em branco para continuar integrando o sensor de potência.",
|
||||
"label": "Entidade do Medidor de Energia"
|
||||
},
|
||||
"expose_debug_entities": {
|
||||
"doc": "Publique entidades de HA de diagnóstico extras (confiança de correspondência, ambiguidade, estados internos). Off mantém a lista de entidades limpa para uso normal.",
|
||||
"label": "Expor Entidades de Depuração"
|
||||
@@ -1305,6 +1320,38 @@
|
||||
},
|
||||
"show_contributor": {
|
||||
"doc": "Mostrar a atribuição \"por <contribuidor>\" em eletrodomésticos e ciclos de referência da comunidade."
|
||||
},
|
||||
"enable_phase_matching": {
|
||||
"label": "Tempo restante com base nas fases",
|
||||
"doc": "Divide cada ciclo em andamento em fases (aquecimento, lavagem, centrifugação) e distribui o tempo restante por fase, combinado com a estimativa clássica - apoiando-se na repartição por fases no início do ciclo e na estimativa clássica perto do fim. Isso personaliza a contagem regressiva de acordo com o tempo que sua máquina realmente aquece e funciona, o que é mais perceptível na primeira metade de um ciclo. Desativado = apenas a estimativa clássica. Apenas a exibição do tempo restante é afetada; a correspondência de programas e a detecção de ciclos permanecem inalteradas."
|
||||
},
|
||||
"keep_min_score": {
|
||||
"label": "Score mín de correspondência",
|
||||
"doc": "Pontuação de similaridade mínima que um candidato precisa para permanecer na disputa. O padrão 0,1 é deliberadamente permissivo - admite até candidatos fracos e depende de etapas posteriores para encontrar a melhor correspondência. Aumente para eliminar perfis improváveis mais cedo; reduza para ampliar o pool inicial de candidatos."
|
||||
},
|
||||
"dtw_blend": {
|
||||
"label": "Fusão Warp",
|
||||
"doc": "O quanto o score de alinhamento por deformação temporal (DTW) substitui o score central da etapa 2. 0 = usar apenas o score da etapa 2, 1 = usar apenas o score DTW, 0,5 (padrão) = mistura equilibrada. Aumente para confiar mais no alinhamento Warp quando os programas têm níveis de potência semelhantes mas padrões temporais diferentes."
|
||||
},
|
||||
"dtw_ensemble_w": {
|
||||
"label": "Mix ensemble Warp",
|
||||
"doc": "No modo DTW ensemble (o padrão), o peso em L1 escalado versus DTW derivativo (DDTW). 1,0 = apenas L1 escalado, 0 = apenas DDTW, 0,7 = padrão. A variante L1 escalada compara os níveis de potência; a variante derivativa reage a como a potência muda ao longo do tempo. Ensemble combina ambos."
|
||||
},
|
||||
"dtw_ddtw_scale": {
|
||||
"label": "Escala Warp derivada",
|
||||
"doc": "Distância de meia saturação para a pontuação DTW derivativa. A pontuação é reduzida à metade quando a distância DDTW é igual a este valor. Menor = mais sensível às diferenças de forma. O padrão 30 está calibrado para rastros de potência típicos de eletrodomésticos. Afeta apenas os modos DTW ensemble e ddtw."
|
||||
},
|
||||
"dtw_refine_top_n": {
|
||||
"label": "Contagem de refinamento Warp",
|
||||
"doc": "Quantos candidatos principais da etapa 2 são reavaliados pelo DTW. O DTW é mais caro, por isso é aplicado apenas aos N melhores candidatos. Padrão 5. Aumente (para 7-9) se o perfil correto às vezes só chega ao 4.º ou 5.º lugar após a etapa 2 - o DTW pode recuperá-lo. Reduzir acelera ligeiramente a correspondência."
|
||||
},
|
||||
"duration_scale": {
|
||||
"label": "Nitidez de duração",
|
||||
"doc": "Precisão da penalidade de concordância de duração na etapa 4. Este é o log-razão em que o score de concordância é reduzido à metade. Menor = mais rigoroso: uma discordância de duração penaliza mais. O padrão 0,175 corresponde a cerca de 18% de tolerância de duração a meio peso. Use em conjunto com o Peso de duração."
|
||||
},
|
||||
"energy_scale": {
|
||||
"label": "Nitidez de energia",
|
||||
"doc": "Precisão da penalidade de concordância de energia. Menor = mais rigoroso: uma discordância de energia penaliza mais. O padrão 0,25 é intencionalmente mais permissivo do que a Precisão de duração, porque a energia varia com a carga. Use em conjunto com o Peso de energia."
|
||||
}
|
||||
},
|
||||
"setting_group": {
|
||||
@@ -1553,24 +1600,24 @@
|
||||
"lower": "Rotula mais ciclos automaticamente; alguns podem ser mal identificados"
|
||||
},
|
||||
"duration_tolerance": {
|
||||
"higher": "Aceita um intervalo de duração mais amplo — correspondência mais flexível",
|
||||
"lower": "Exige duração mais próxima — mais rigoroso, pode rejeitar ciclos incomuns"
|
||||
"higher": "Aceita um intervalo de duração mais amplo – correspondência mais flexível",
|
||||
"lower": "Exige duração mais próxima – mais rigoroso, pode rejeitar ciclos incomuns"
|
||||
},
|
||||
"end_energy_threshold": {
|
||||
"higher": "Encerra apenas ciclos que consumiram energia substancial",
|
||||
"lower": "Encerra também ciclos curtos ou de baixa energia"
|
||||
},
|
||||
"end_repeat_count": {
|
||||
"higher": "Exige que o sinal de fim se repita mais vezes — mais robusto, ligeiramente mais lento",
|
||||
"lower": "Termina após menos repetições — detecção mais rápida, maior risco de fim falso"
|
||||
"higher": "Exige que o sinal de fim se repita mais vezes – mais robusto, ligeiramente mais lento",
|
||||
"lower": "Termina após menos repetições – detecção mais rápida, maior risco de fim falso"
|
||||
},
|
||||
"learning_confidence": {
|
||||
"higher": "Aprende apenas com correspondências muito confiantes — mais lento mas mais confiável",
|
||||
"higher": "Aprende apenas com correspondências muito confiantes – mais lento mas mais confiável",
|
||||
"lower": "Aprende com mais ciclos; o modelo pode ser menos preciso"
|
||||
},
|
||||
"min_off_gap": {
|
||||
"higher": "Requer mais tempo inativo antes de iniciar um novo ciclo",
|
||||
"lower": "Um breve repouso inicia um novo ciclo — execuções consecutivas podem ser divididas"
|
||||
"lower": "Um breve repouso inicia um novo ciclo – execuções consecutivas podem ser divididas"
|
||||
},
|
||||
"min_power": {
|
||||
"higher": "Menos sensível ao consumo em repouso; pode não detectar programas muito silenciosos",
|
||||
@@ -1581,24 +1628,24 @@
|
||||
"lower": "Para um ciclo travado mais cedo"
|
||||
},
|
||||
"off_delay": {
|
||||
"higher": "Mais tempo para pausas do eletrodoméstico — gerencia fases longas de molho ou secagem",
|
||||
"lower": "Detecção de fim mais rápida — ideal para eletrodomésticos com liga/desliga limpo"
|
||||
"higher": "Mais tempo para pausas do eletrodoméstico – gerencia fases longas de molho ou secagem",
|
||||
"lower": "Detecção de fim mais rápida – ideal para eletrodomésticos com liga/desliga limpo"
|
||||
},
|
||||
"profile_match_threshold": {
|
||||
"higher": "Confirma apenas correspondências de alta confiança; mais ciclos ficam sem rótulo",
|
||||
"lower": "Corresponde a mais ciclos; alguns podem estar ligeiramente errados"
|
||||
},
|
||||
"running_dead_zone": {
|
||||
"higher": "Ignora breves picos de potência em repouso — menos sensível ao ruído",
|
||||
"lower": "Responde a impulsos mais curtos — detecta atividade transitória rápida"
|
||||
"higher": "Ignora breves picos de potência em repouso – menos sensível ao ruído",
|
||||
"lower": "Responde a impulsos mais curtos – detecta atividade transitória rápida"
|
||||
},
|
||||
"start_threshold_w": {
|
||||
"higher": "Evita partidas falsas por breves picos de potência",
|
||||
"lower": "Detecta programas de baixa potência; pode ser ativado por ruído"
|
||||
},
|
||||
"stop_threshold_w": {
|
||||
"higher": "Encerra o ciclo mais cedo — pode fechar durante uma pausa",
|
||||
"lower": "Aguarda mais para terminar — menos conclusões prematuras"
|
||||
"higher": "Encerra o ciclo mais cedo – pode fechar durante uma pausa",
|
||||
"lower": "Aguarda mais para terminar – menos conclusões prematuras"
|
||||
},
|
||||
"watchdog_interval": {
|
||||
"higher": "Fases silenciosas mais longas permitidas; menos paradas forçadas falsas",
|
||||
@@ -1676,12 +1723,19 @@
|
||||
"start_duration_threshold": "Segundos acima do limite para confirmar o início",
|
||||
"start_threshold_w": "Watts mínimos para contar como iniciado",
|
||||
"stop_threshold_w": "Abaixo disso, a máquina conta como desligada",
|
||||
"dtw_bandwidth": "Quanta deformação temporal a correspondência de forma permite",
|
||||
"corr_weight": "Peso da forma da curva em relação ao nível de potência na correspondência",
|
||||
"duration_weight": "Quanto a concordância de duração afeta a correspondência",
|
||||
"energy_weight": "Quanto a concordância de energia afeta a correspondência",
|
||||
"profile_match_min_duration_ratio": "Ciclo mais curto (em relação ao perfil) ainda permitido para corresponder",
|
||||
"profile_match_max_duration_ratio": "Ciclo mais longo (em relação ao perfil) ainda permitido para corresponder"
|
||||
"dtw_bandwidth": "Etapa 3: banda de deformação Sakoe-Chiba (0 = DTW desativado; padrão 0,2 = 20% do comprimento do ciclo)",
|
||||
"corr_weight": "Etapa 2: equilíbrio entre a forma da curva (correlação) e o nível de potência (MAE); padrão 0,45",
|
||||
"duration_weight": "Etapa 4: o quanto a concordância de duração afeta a pontuação final (padrão 0,22)",
|
||||
"energy_weight": "Etapa 4: o quanto a concordância de energia afeta a pontuação final (padrão 0,22)",
|
||||
"profile_match_min_duration_ratio": "Etapa 1: duração mínima do ciclo como fração da duração do perfil; padrão 0,1 (10%)",
|
||||
"profile_match_max_duration_ratio": "Etapa 1: duração máxima do ciclo como fração da duração do perfil; padrão 1,5 (150%)",
|
||||
"keep_min_score": "Etapa 2: pontuação mínima para permanecer na disputa; o padrão 0,1 admite candidatos fracos, etapas posteriores escolhem o melhor",
|
||||
"dtw_blend": "Etapa 3: 0 = apenas pontuação central, 1 = apenas pontuação DTW, 0,5 = mistura equilibrada (padrão)",
|
||||
"dtw_ensemble_w": "Etapa 3 (modo ensemble): peso em L1 escalado vs DTW derivativo; o padrão 0,7 favorece a sensibilidade ao nível",
|
||||
"dtw_ddtw_scale": "Etapa 3: distância de meia saturação DDTW; menor = mais sensível à forma (padrão 30)",
|
||||
"dtw_refine_top_n": "Etapa 3: candidatos reavaliados pelo DTW; aumente para 7-9 se o perfil correto se classificar em 4.º-5.º (padrão 5)",
|
||||
"duration_scale": "Etapa 4: log-razão em que a concordância de duração é reduzida à metade; menor = penalidade mais severa (padrão 0,175)",
|
||||
"energy_scale": "Etapa 4: log-razão em que a concordância de energia é reduzida à metade; menor = penalidade mais severa (padrão 0,25)"
|
||||
},
|
||||
"col": {
|
||||
"profile_tip": "Nome do programa correspondente. Sem rótulo significa que nenhum perfil correspondeu no fim do ciclo.",
|
||||
@@ -1766,6 +1820,69 @@
|
||||
},
|
||||
"pg_sweep": {
|
||||
"optimize": "Otimizar: {param}"
|
||||
},
|
||||
"pg_detail": {
|
||||
"simulate": "Simular ciclo"
|
||||
},
|
||||
"split": {
|
||||
"apply": "Dividindo o ciclo"
|
||||
},
|
||||
"trim": {
|
||||
"apply": "Recortando o ciclo"
|
||||
},
|
||||
"merge": {
|
||||
"apply": "Combinando ciclos"
|
||||
},
|
||||
"rebuild": {
|
||||
"envelopes": "Reconstruindo envelopes"
|
||||
},
|
||||
"cancelling": "Cancelando..."
|
||||
},
|
||||
"setup": {
|
||||
"hdr": {
|
||||
"card": "Configuração do dispositivo",
|
||||
"healthy_chip": "Configuração concluída"
|
||||
},
|
||||
"phase0": {
|
||||
"washer": "O WashData já está detectando seus ciclos. Grave o primeiro ciclo para ativar os nomes dos programas e as estimativas de tempo.",
|
||||
"dishwasher": "O WashData está monitorando. As máquinas de lavar louça têm ciclos complexos – é altamente recomendável gravar o primeiro ciclo. Se um ciclo detectado demorar muito, use o editor de ciclos para recortá-lo antes de salvá-lo como perfil.",
|
||||
"generic": "O WashData está monitorando. Grave ou rotule um ciclo detectado para começar a criar perfis."
|
||||
},
|
||||
"phase1a": {
|
||||
"labelled": "Ótimo começo – seu primeiro programa está salvo. Para dados mais precisos, considere gravar o próximo ciclo com o widget de gravação."
|
||||
},
|
||||
"phase1b": {
|
||||
"recorded": "Sua gravação foi salva como {profile_name}. Agora grave ou rotule seus outros programas habituais para ampliar a cobertura."
|
||||
},
|
||||
"phase1c": {
|
||||
"verify": "Você tem {count} programas da comunidade. Execute um ciclo para verificar se o WashData os reconhece corretamente – a correspondência vai melhorar à medida que o dispositivo acumula seu próprio histórico."
|
||||
},
|
||||
"phase2": {
|
||||
"cluster": "O WashData encontrou {count} ciclos que não correspondem a nenhum programa salvo – eles se parecem entre si. Deseja criar um novo perfil para eles?",
|
||||
"unmatched": "Seu último ciclo não correspondeu a nenhum programa salvo. É um novo programa?"
|
||||
},
|
||||
"phase3": {
|
||||
"suggestions": "O WashData tem recomendações de configuração baseadas no histórico de ciclos – revise-as para melhorar a precisão da detecção.",
|
||||
"groups": "Alguns dos seus perfis parecem o mesmo programa em temperaturas diferentes. Organize-os em um grupo para uma correspondência mais confiável.",
|
||||
"phases": "Adicione fases de programa a {profile_name} para estimativas mais precisas do tempo restante."
|
||||
},
|
||||
"phase4": {
|
||||
"healthy": "Este dispositivo está totalmente configurado ({profile_count} perfis)."
|
||||
},
|
||||
"cta": {
|
||||
"start_recording": "Iniciar gravação",
|
||||
"label_detected_cycle": "Já tenho um ciclo detectado – rotulá-lo em vez disso",
|
||||
"browse_cycles": "Explorar ciclos para rotular outro",
|
||||
"view_profiles": "Ver seus perfis",
|
||||
"create_from_cluster": "Criar perfil a partir destes ciclos",
|
||||
"create_profile": "Criar um perfil para este programa",
|
||||
"review_suggestions": "Revisar sugestões",
|
||||
"organise_profiles": "Organizar perfis",
|
||||
"configure_phases": "Configurar fases",
|
||||
"skip_step": "Pular esta etapa",
|
||||
"skip_forever": "Não mostrar novamente",
|
||||
"hide_guidance": "Ocultar guia",
|
||||
"show_guidance": "Exibir guia"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
{
|
||||
"badge": {
|
||||
"artifact_tip": "{n} anomalias detectadas (por exemplo, porta aberta a meio do ciclo) — abra para as ver no gráfico",
|
||||
"artifact_tip": "{n} anomalias detectadas (por exemplo, porta aberta a meio do ciclo) – abra para as ver no gráfico",
|
||||
"auto": "(detectado automaticamente)",
|
||||
"built_in_tag": "incorporado",
|
||||
"declining": "↘ a declinar",
|
||||
"energy_low": "Energia abaixo do habitual",
|
||||
"energy_spike": "Energia acima do habitual",
|
||||
"fair_fit": "qualidade aceitável",
|
||||
"fair_fit_tip": "Consistência de correspondência moderada — alguns ciclos atribuídos a este perfil têm pontuações de confiança mais baixas. Rotule mais ciclos ou re-grave o perfil para melhorar a precisão.",
|
||||
"fair_fit_tip": "Consistência de correspondência moderada – alguns ciclos atribuídos a este perfil têm pontuações de confiança mais baixas. Rotule mais ciclos ou re-grave o perfil para melhorar a precisão.",
|
||||
"feedback_requested": "Feedback solicitado",
|
||||
"golden_cycle": "Ciclo de referência gravado",
|
||||
"improving": "↗ a melhorar",
|
||||
@@ -15,7 +15,7 @@
|
||||
"needs_review": "Precisa de revisão",
|
||||
"overrun": "Demorou mais do que o habitual",
|
||||
"poor_fit": "qualidade fraca",
|
||||
"poor_fit_tip": "Histórico de correspondência inconsistente — considere reconstruir este perfil",
|
||||
"poor_fit_tip": "Histórico de correspondência inconsistente – considere reconstruir este perfil",
|
||||
"restart_gap_tip": "{n} lacuna de reinício do HA: o traçado de potência tem uma lacuna",
|
||||
"reviewed": "Revisto",
|
||||
"steady": "→ estável",
|
||||
@@ -57,7 +57,7 @@
|
||||
"create_profile": "+ Criar perfil",
|
||||
"delete": "Eliminar",
|
||||
"delete_group": "Eliminar grupo",
|
||||
"delete_group_tip": "Eliminar apenas este grupo — os perfis dos membros são mantidos",
|
||||
"delete_group_tip": "Eliminar apenas este grupo – os perfis dos membros são mantidos",
|
||||
"delete_profile": "Eliminar perfil",
|
||||
"discard": "Descartar",
|
||||
"discard_tip": "Descartar o traço gravado sem guardar",
|
||||
@@ -87,7 +87,7 @@
|
||||
"on_cycle_finished": "Ao terminar o ciclo",
|
||||
"on_cycle_started": "Ao iniciar o ciclo",
|
||||
"pause_cycle": "Pausar",
|
||||
"pause_cycle_tip": "Pausar o ciclo em curso — o aparelho retomará onde parou",
|
||||
"pause_cycle_tip": "Pausar o ciclo em curso – o aparelho retomará onde parou",
|
||||
"pg_apply_device": "Aplicar ao dispositivo",
|
||||
"pg_autofill": "Preenchimento automático",
|
||||
"play": "Reproduzir",
|
||||
@@ -97,8 +97,8 @@
|
||||
"process_tip": "Guardar o traço gravado como um perfil novo ou existente",
|
||||
"rebuild": "Reconstruir envelopes",
|
||||
"rebuild_envelope": "Reconstruir envelope",
|
||||
"rebuild_tip": "Recalcular o envelope de potência esperado (banda mín/máx) para todos os perfis a partir dos seus ciclos rotulados — executar após rotular novos ciclos ou corrigir os existentes",
|
||||
"rec_start_tip": "Iniciar a gravação do traço de potência do aparelho — iniciar imediatamente antes de executar um ciclo",
|
||||
"rebuild_tip": "Recalcular o envelope de potência esperado (banda mín/máx) para todos os perfis a partir dos seus ciclos rotulados – executar após rotular novos ciclos ou corrigir os existentes",
|
||||
"rec_start_tip": "Iniciar a gravação do traço de potência do aparelho – iniciar imediatamente antes de executar um ciclo",
|
||||
"rec_stop": "Parar",
|
||||
"rec_stop_tip": "Parar a gravação e manter o traço capturado para revisão",
|
||||
"record": "Iniciar gravação",
|
||||
@@ -182,7 +182,7 @@
|
||||
},
|
||||
"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.",
|
||||
"settings_banner": "{n} conflito{s} de definições – verifique as secções realçadas e corrija antes de guardar.",
|
||||
"settings_banner_btn": "Ir para o primeiro",
|
||||
"confidence": {
|
||||
"auto": "Deve ser superior ou igual ao Limiar de correspondência ({match})",
|
||||
@@ -451,9 +451,9 @@
|
||||
"show_expected": "Mostrar sobreposição da curva esperada (perfil correspondente, laranja)",
|
||||
"show_raw": "Mostrar o interruptor de sinal bruto da tomada no gráfico de potência em tempo real",
|
||||
"sparkline": "Tendência recente da duração dos ciclos",
|
||||
"stage2": "Etapa 2 — semelhança principal",
|
||||
"stage3": "Etapa 3 — DTW",
|
||||
"stage4": "Etapa 4 — concordância",
|
||||
"stage2": "Etapa 2 – semelhança principal",
|
||||
"stage3": "Etapa 3 – DTW",
|
||||
"stage4": "Etapa 4 – concordância",
|
||||
"status": "Estado",
|
||||
"tail_trim": "Corte final (s)",
|
||||
"timer_auto_pause": "Pausa automática",
|
||||
@@ -561,7 +561,12 @@
|
||||
"flags": "Indicadores",
|
||||
"include_phase_map": "Incluir mapa de fases",
|
||||
"include_settings": "Incluir definições de deteção e reconhecimento",
|
||||
"show_contributor": "Mostrar nomes dos colaboradores"
|
||||
"show_contributor": "Mostrar nomes dos colaboradores",
|
||||
"task_pg_detail": "Simular ciclo",
|
||||
"task_split": "A dividir o ciclo",
|
||||
"task_trim": "A recortar o ciclo",
|
||||
"task_merge": "A combinar ciclos",
|
||||
"task_rebuild": "A reconstruir envelopes"
|
||||
},
|
||||
"log": {
|
||||
"all_levels": "Todos os níveis",
|
||||
@@ -645,7 +650,7 @@
|
||||
"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.",
|
||||
"artifact_header": "{n} anomalias detectadas durante este ciclo",
|
||||
"artifact_pause_detail": "A potência caiu quase a zero durante ~{n}s e depois retomou — provavelmente a porta foi aberta a meio do ciclo ou o ciclo foi pausado.",
|
||||
"artifact_pause_detail": "A potência caiu quase a zero durante ~{n}s e depois retomou – provavelmente a porta foi aberta a meio do ciclo ou o ciclo foi pausado.",
|
||||
"artifact_spike_detail": "Ultrapassou a banda de potência habitual durante ~{n}s.",
|
||||
"auto_label_intro": "Atribua perfis a ciclos sem rótulo cuja confiança de correspondência ultrapasse o limiar.",
|
||||
"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.",
|
||||
@@ -654,10 +659,10 @@
|
||||
"collecting_data": "A recolher dados - mais {need} ciclo{plural} antes de o ajuste fino poder começar ({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",
|
||||
"compare_selected_cycles": "Ciclos seleccionados (sólido) – mostrar / ocultar",
|
||||
"consider_new_profile": "Considere criar um novo perfil.",
|
||||
"coverage_gap": "os ciclos recentes não têm perfil correspondente ({pct}% dos últimos 30).",
|
||||
"coverage_gap_similar_cycles": "{count} ciclos semelhantes sem rótulo encontrados — crie um perfil para começar a correspondê-los.",
|
||||
"coverage_gap_similar_cycles": "{count} ciclos semelhantes sem rótulo encontrados – crie um perfil para começar a correspondê-los.",
|
||||
"cycles_deleted": "{count} ciclo(s) eliminado(s)",
|
||||
"enough_data": "Dados suficientes para aprender ({current}/{min} ciclos).",
|
||||
"export_description": "Exporte todos os perfis e ciclos para JSON ou restaure a partir de uma exportação anterior.",
|
||||
@@ -686,7 +691,7 @@
|
||||
"ml_learned_intro": "Modelos ajustados a esta máquina.",
|
||||
"ml_loading": "a carregar ML…",
|
||||
"ml_settings_intro": "Dois comutadores independentes: um aplica os modelos durante um ciclo, o outro permite ao WashData ajustá-los à sua máquina ao longo do tempo.",
|
||||
"name_first_program": "Já tem ciclos suficientes — atribua um nome ao seu primeiro programa para começar a corresponder.",
|
||||
"name_first_program": "Já tem ciclos suficientes – atribua um nome ao seu primeiro programa para começar a corresponder.",
|
||||
"near_duplicate_cluster": "cluster de perfis quase duplicados detectado. O agrupamento permite que a correspondência escolha de forma fiável entre perfis semelhantes (por exemplo, o mesmo programa a diferentes temperaturas/centrifugações).",
|
||||
"no_cycles_match": "Nenhum ciclo corresponde ao filtro actual.",
|
||||
"no_cycles_profile": "Nenhum ciclo para este perfil.",
|
||||
@@ -694,12 +699,12 @@
|
||||
"no_cycles_yet": "Nenhum ciclo gravado ainda.",
|
||||
"no_device_selected": "Nenhum dispositivo seleccionado.",
|
||||
"no_devices": "Nenhum dispositivo WashData configurado ainda.",
|
||||
"no_envelope": "Nenhum envelope ainda — reconstrua após rotular os ciclos.",
|
||||
"no_envelope": "Nenhum envelope ainda – reconstrua após rotular os ciclos.",
|
||||
"no_envelope_overlay": "Nenhum envelope disponível para sobrepor.",
|
||||
"no_fine_tuned": "Nada ajustado ainda — o WashData está a usar os seus modelos incorporados.",
|
||||
"no_fine_tuned": "Nada ajustado ainda – o WashData está a usar os seus modelos incorporados.",
|
||||
"no_logs": "Nenhum registo em memória ainda.",
|
||||
"no_maintenance": "Ainda não há manutenções registadas.",
|
||||
"no_match_yet": "Nenhuma tentativa de correspondência ainda — isto é preenchido durante um ciclo em execução.",
|
||||
"no_match_yet": "Nenhuma tentativa de correspondência ainda – isto é preenchido durante um ciclo em execução.",
|
||||
"no_other_users": "Nenhum outro utilizador do Home Assistant encontrado.",
|
||||
"no_phases": "Nenhuma fase definida.",
|
||||
"no_phases_assigned": "Nenhuma fase atribuída.",
|
||||
@@ -713,7 +718,7 @@
|
||||
"notify_services_hint": "Use os IDs de serviço {entity} (separados por vírgulas para múltiplos). Variáveis de modelo: {vars}.",
|
||||
"old_actions_warning": "Configurado com o antigo editor de acções (agora removido). Ainda são accionadas em eventos de ciclo, mas já não podem ser editadas aqui. Converta-as numa automatização normal ou remova-as.",
|
||||
"onboarding_progress": "{n} / 3 ciclos observados",
|
||||
"onboarding_watching": "Utilize o eletrodoméstico normalmente — o WashData está a observar. Após 3 ciclos, a correspondência de programas terá início.",
|
||||
"onboarding_watching": "Utilize o eletrodoméstico normalmente – o WashData está a observar. Após 3 ciclos, a correspondência de programas terá início.",
|
||||
"pending_feedback": "Feedback de detecção pendente",
|
||||
"performance_trend": "Tendência de desempenho ({n} ciclos)",
|
||||
"pg_analysis_empty": "Carregue um ciclo para ver a análise de correspondência.",
|
||||
@@ -748,13 +753,13 @@
|
||||
"restart_gap_footer": "Destacado no gráfico. Dados de potência estão em falta para estes intervalos; a correspondência usou apenas leituras reais.",
|
||||
"restart_gap_header": "{n} lacuna de reinício do HA durante este ciclo",
|
||||
"restart_gap_item": "{dur} lacuna",
|
||||
"review_confirm_help": "Confirme se este ciclo foi detectado correctamente. As suas revisões treinam o modelo na sua máquina — quanto mais ciclos confirmar, melhor ficam a correspondência e a pontuação de saúde. Um Bom/Mau rápido é suficiente.",
|
||||
"review_confirm_help": "Confirme se este ciclo foi detectado correctamente. As suas revisões treinam o modelo na sua máquina – quanto mais ciclos confirmar, melhor ficam a correspondência e a pontuação de saúde. Um Bom/Mau rápido é suficiente.",
|
||||
"review_in_settings": "Rever nas Definições",
|
||||
"review_notes_placeholder": "Notas (opcional)",
|
||||
"review_notes_tip": "Notas em texto livre para sua referência pessoal. Não são usadas pela correspondência ou pelo treino.",
|
||||
"review_profile_tip": "O programa com que este ciclo está rotulado. Se o programa detectado automaticamente estava errado, corrija-o aqui — a rotulagem ensina a correspondência para ciclos futuros.",
|
||||
"review_profile_tip": "O programa com que este ciclo está rotulado. Se o programa detectado automaticamente estava errado, corrija-o aqui – a rotulagem ensina a correspondência para ciclos futuros.",
|
||||
"review_quality_tip": "A qualidade deste ciclo. Bom = um exemplo perfeito deste programa; Mau = detectado mas ruidoso ou atípico; Inutilizável = detectado incorrectamente (combinado, truncado ou espúrio). Determina a pontuação de saúde e quais os ciclos permitidos para treinar o modelo.",
|
||||
"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_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",
|
||||
"saving_triggers_reload": "Guardar desencadeia um recarregamento da integração. As entidades HA podem ficar brevemente indisponíveis.",
|
||||
@@ -763,7 +768,7 @@
|
||||
"setting_changed": "Alterado de {old} para {new} em {date}",
|
||||
"settings_basic_note": "A mostrar as definições essenciais. Mude para Avançado para ver a lista completa.",
|
||||
"shape_drift_advisory": "⚠ Desvio de forma",
|
||||
"shape_drift_detail": "O padrão de potência para este perfil mudou ao longo do tempo — possível desgaste do electrodoméstico ou manutenção necessária (por exemplo, descalcificação, limpeza do filtro).",
|
||||
"shape_drift_detail": "O padrão de potência para este perfil mudou ao longo do tempo – possível desgaste do electrodoméstico ou manutenção necessária (por exemplo, descalcificação, limpeza do filtro).",
|
||||
"show_all_settings": "Mostrar todas as definições",
|
||||
"showing_suggestions": "A mostrar a definição {count} com sugestões.",
|
||||
"split_intro": "Clique no gráfico para adicionar ou remover um ponto de divisão, ou detecte automaticamente por intervalos de inactividade. Cada segmento resultante pode ter o seu próprio perfil.",
|
||||
@@ -789,10 +794,10 @@
|
||||
"toast_revert_failed": "Reversão falhou: {error}",
|
||||
"toast_reverted": "{key} revertido",
|
||||
"toast_save_failed": "Guardar falhou: {error}",
|
||||
"trend_duration_longer": "Duração com tendência crescente ({pct}%/ciclo) — média recente {avg}",
|
||||
"trend_duration_shorter": "Duração com tendência decrescente ({pct}%/ciclo) — média recente {avg}",
|
||||
"trend_duration_longer": "Duração com tendência crescente ({pct}%/ciclo) – média recente {avg}",
|
||||
"trend_duration_shorter": "Duração com tendência decrescente ({pct}%/ciclo) – média recente {avg}",
|
||||
"trend_energy_down": "Energia com tendência decrescente ({pct}%/ciclo)",
|
||||
"trend_energy_up": "Energia com tendência crescente ({pct}%/ciclo) — média recente {avg}",
|
||||
"trend_energy_up": "Energia com tendência crescente ({pct}%/ciclo) – média recente {avg}",
|
||||
"trim_intro": "Arraste os puxadores vermelhos ou introduza valores. Tudo o que estiver fora da janela é removido.",
|
||||
"tuning_suggestions_available": "{count} sugestão de ajuste disponível a partir dos ciclos observados. Aparecem junto dos campos relevantes.",
|
||||
"unsure_detected_prefix": "O WashData não tem a certeza de que detectou",
|
||||
@@ -857,7 +862,9 @@
|
||||
"share_guidelines_title": "Antes de partilhar",
|
||||
"store_download_device_intro": "Adotar todos os programas partilhados e os seus ciclos de referência neste dispositivo. Os seus ciclos gravados e estatísticas não são afetados.",
|
||||
"store_share_device_intro": "Carregar {brand} {model} com os ciclos de referência que selecionar. Outros utilizadores com o mesmo electrodoméstico podem adotar os seus programas. As entradas são revistas antes de aparecerem publicamente.",
|
||||
"share_profile_no_cycles": "Sem ciclos de referência -- marque um ciclo como ⭐ no separador Ciclos para incluir este perfil"
|
||||
"share_profile_no_cycles": "Sem ciclos de referência -- marque um ciclo como ⭐ no separador Ciclos para incluir este perfil",
|
||||
"advisory_phase_inconsistent": "'{name}' parece misturar diferentes programas ou temperaturas - os seus ciclos aquecem durante períodos de tempo muito diferentes. Dividi-lo em perfis separados (p. ex. por temperatura) melhorará a correspondência e as estimativas de tempo.",
|
||||
"advisory_phase_inconsistent_title": "⚠ Possíveis programas misturados"
|
||||
},
|
||||
"pg_desc": {
|
||||
"abrupt_drop_watts": "Queda repentina tratada como fim imediato",
|
||||
@@ -869,12 +876,19 @@
|
||||
"start_duration_threshold": "Segundos acima do limiar para confirmar o início",
|
||||
"start_threshold_w": "Watts mínimos para contar como iniciado",
|
||||
"stop_threshold_w": "Abaixo disto, a máquina conta como desligada",
|
||||
"dtw_bandwidth": "Quanta deformação temporal a correspondência de forma permite",
|
||||
"corr_weight": "Peso da forma da curva face ao nível de potência na correspondência",
|
||||
"duration_weight": "Quanto a concordância de duração afeta a correspondência",
|
||||
"energy_weight": "Quanto a concordância de energia afeta a correspondência",
|
||||
"profile_match_min_duration_ratio": "Ciclo mais curto (face ao perfil) ainda autorizado a corresponder",
|
||||
"profile_match_max_duration_ratio": "Ciclo mais longo (face ao perfil) ainda autorizado a corresponder"
|
||||
"dtw_bandwidth": "Fase 3: banda de deformação Sakoe-Chiba (0 = DTW desativado; predefinição 0,2 = 20% do comprimento do ciclo)",
|
||||
"corr_weight": "Fase 2: equilíbrio entre a forma da curva (correlação) e o nível de potência (MAE); predefinição 0,45",
|
||||
"duration_weight": "Fase 4: o quanto a concordância de duração afeta a pontuação final (predefinição 0,22)",
|
||||
"energy_weight": "Fase 4: o quanto a concordância de energia afeta a pontuação final (predefinição 0,22)",
|
||||
"profile_match_min_duration_ratio": "Fase 1: duração mínima do ciclo como fração da duração do perfil; predefinição 0,1 (10%)",
|
||||
"profile_match_max_duration_ratio": "Fase 1: duração máxima do ciclo como fração da duração do perfil; predefinição 1,5 (150%)",
|
||||
"keep_min_score": "Fase 2: pontuação mínima para permanecer em jogo; a predefinição 0,1 admite candidatos fracos, as fases seguintes escolhem o melhor",
|
||||
"dtw_blend": "Fase 3: 0 = apenas pontuação central, 1 = apenas pontuação DTW, 0,5 = mistura equilibrada (predefinição)",
|
||||
"dtw_ensemble_w": "Fase 3 (modo ensemble): peso em L1 escalado vs DTW derivativo; a predefinição 0,7 favorece a sensibilidade ao nível",
|
||||
"dtw_ddtw_scale": "Fase 3: distância de semissaturação DDTW; menor = maior sensibilidade à forma (predefinição 30)",
|
||||
"dtw_refine_top_n": "Fase 3: candidatos reavaliados pelo DTW; aumente para 7-9 se o perfil correto se classificar em 4.º-5.º (predefinição 5)",
|
||||
"duration_scale": "Fase 4: log-razão em que a concordância de duração é reduzida a metade; menor = penalidade mais severa (predefinição 0,175)",
|
||||
"energy_scale": "Fase 4: log-razão em que a concordância de energia é reduzida a metade; menor = penalidade mais severa (predefinição 0,25)"
|
||||
},
|
||||
"phase_desc": {
|
||||
"anti_crease": "Rotações curtas ocasionais após a conclusão para reduzir vincos.",
|
||||
@@ -957,6 +971,10 @@
|
||||
"triggers": {
|
||||
"intro": "Sinais externos opcionais: um gatilho de fim, um sensor de porta, um interruptor de pausa e o lembrete de descarga.",
|
||||
"label": "Gatilhos e Portas"
|
||||
},
|
||||
"phase_eta": {
|
||||
"label": "Tempo restante",
|
||||
"intro": "Tempo restante com base nas fases, para máquinas cuja duração do ciclo depende da temperatura ou da centrifugação."
|
||||
}
|
||||
},
|
||||
"setting": {
|
||||
@@ -1040,6 +1058,10 @@
|
||||
"doc": "Preço fixo por kWh usado para valores de custos quando nenhuma entidade de preço real é definida acima.",
|
||||
"label": "Preço Estático de Energia (por kWh)"
|
||||
},
|
||||
"energy_sensor": {
|
||||
"doc": "Contador de energia cumulativo opcional (total_increasing em kWh/Wh, por ex. o contador de consumo total da própria tomada). Quando definido, a energia indicada de cada ciclo é obtida a partir da diferença deste contador entre o início e o fim, o que evita a subcontagem resultante da integração de um sensor de potência que reporta lentamente. Recorre ao valor integrado se a leitura estiver em falta, se a sua unidade for desconhecida ou se o delta não for positivo. Deixe em branco para continuar a integrar o sensor de potência.",
|
||||
"label": "Entidade do Contador de Energia"
|
||||
},
|
||||
"expose_debug_entities": {
|
||||
"doc": "Publique entidades de HA de diagnóstico extras (confiança de correspondência, ambiguidade, estados internos). Off mantém a lista de entidades limpa para uso normal.",
|
||||
"label": "Expor Entidades de Depuração"
|
||||
@@ -1322,6 +1344,38 @@
|
||||
},
|
||||
"show_contributor": {
|
||||
"doc": "Mostrar a atribuição \"por <colaborador>\" nos electrodomésticos da comunidade e nos ciclos de referência."
|
||||
},
|
||||
"enable_phase_matching": {
|
||||
"label": "Tempo restante com base nas fases",
|
||||
"doc": "Divide cada ciclo em curso em fases (aquecimento, lavagem, centrifugação) e distribui o tempo restante por fase, combinado com a estimativa clássica - apoiando-se na repartição por fases no início do ciclo e na estimativa clássica perto do fim. Isto personaliza a contagem decrescente de acordo com o tempo que a sua máquina realmente aquece e funciona, o que é mais percetível na primeira metade de um ciclo. Desativado = apenas a estimativa clássica. Apenas a apresentação do tempo restante é afetada; a correspondência de programas e a deteção de ciclos permanecem inalteradas."
|
||||
},
|
||||
"keep_min_score": {
|
||||
"label": "Score mín de correspondência",
|
||||
"doc": "Pontuação de similaridade mínima que um candidato precisa para permanecer em jogo. A predefinição 0,1 é deliberadamente permissiva - admite mesmo candidatos fracos e depende das fases seguintes para encontrar a melhor correspondência. Aumente para eliminar perfis improváveis mais cedo; reduza para ampliar o pool inicial de candidatos."
|
||||
},
|
||||
"dtw_blend": {
|
||||
"label": "Fusão Warp",
|
||||
"doc": "O quanto o score de alinhamento por deformação temporal (DTW) substitui o score central da fase 2. 0 = usar apenas o score da fase 2, 1 = usar apenas o score DTW, 0,5 (predefinição) = mistura equilibrada. Aumente para confiar mais no alinhamento Warp quando os programas têm níveis de potência semelhantes mas padrões temporais diferentes."
|
||||
},
|
||||
"dtw_ensemble_w": {
|
||||
"label": "Mix ensemble Warp",
|
||||
"doc": "No modo DTW ensemble (a predefinição), o peso em L1 escalado versus DTW derivativo (DDTW). 1,0 = apenas L1 escalado, 0 = apenas DDTW, 0,7 = predefinição. A variante L1 escalada compara os níveis de potência; a variante derivativa reage a como a potência muda ao longo do tempo. Ensemble combina ambos."
|
||||
},
|
||||
"dtw_ddtw_scale": {
|
||||
"label": "Escala Warp derivativa",
|
||||
"doc": "Distância de semissaturação para a pontuação DTW derivativa. A pontuação é reduzida a metade quando a distância DDTW é igual a este valor. Menor = mais sensível às diferenças de forma. A predefinição 30 está calibrada para traços de potência típicos de eletrodomésticos. Afeta apenas os modos DTW ensemble e ddtw."
|
||||
},
|
||||
"dtw_refine_top_n": {
|
||||
"label": "Contagem de refinamento Warp",
|
||||
"doc": "Quantos candidatos principais da fase 2 são reavaliados pelo DTW. O DTW é mais dispendioso, por isso é aplicado apenas aos N melhores candidatos. Predefinição 5. Aumente (para 7-9) se o perfil correto às vezes só chega ao 4.º ou 5.º lugar após a fase 2 - o DTW pode recuperá-lo. Reduzir acelera ligeiramente a correspondência."
|
||||
},
|
||||
"duration_scale": {
|
||||
"label": "Nitidez de duração",
|
||||
"doc": "Precisão da penalidade de concordância de duração na fase 4. Este é o log-razão em que o score de concordância é reduzido a metade. Menor = mais rigoroso: uma discordância de duração penaliza mais. A predefinição 0,175 corresponde a cerca de 18% de tolerância de duração a meio peso. Use em conjunto com o Peso de duração."
|
||||
},
|
||||
"energy_scale": {
|
||||
"label": "Nitidez de energia",
|
||||
"doc": "Precisão da penalidade de concordância de energia. Menor = mais rigoroso: uma discordância de energia penaliza mais. A predefinição 0,25 é intencionalmente mais permissiva do que a Precisão de duração, porque a energia varia com a carga. Use em conjunto com o Peso de energia."
|
||||
}
|
||||
},
|
||||
"setting_group": {
|
||||
@@ -1570,24 +1624,24 @@
|
||||
"lower": "Etiqueta mais ciclos automaticamente; alguns podem ser mal identificados"
|
||||
},
|
||||
"duration_tolerance": {
|
||||
"higher": "Aceita um intervalo de duração mais amplo — correspondência mais flexível",
|
||||
"lower": "Exige duração mais próxima — mais rigoroso, pode rejeitar ciclos invulgares"
|
||||
"higher": "Aceita um intervalo de duração mais amplo – correspondência mais flexível",
|
||||
"lower": "Exige duração mais próxima – mais rigoroso, pode rejeitar ciclos invulgares"
|
||||
},
|
||||
"end_energy_threshold": {
|
||||
"higher": "Fecha apenas ciclos que consumiram energia substancial",
|
||||
"lower": "Também fecha ciclos curtos ou de baixa energia"
|
||||
},
|
||||
"end_repeat_count": {
|
||||
"higher": "Exige que o sinal de fim se repita mais vezes — mais robusto, ligeiramente mais lento",
|
||||
"lower": "Termina após menos repetições — deteção mais rápida, maior risco de fim falso"
|
||||
"higher": "Exige que o sinal de fim se repita mais vezes – mais robusto, ligeiramente mais lento",
|
||||
"lower": "Termina após menos repetições – deteção mais rápida, maior risco de fim falso"
|
||||
},
|
||||
"learning_confidence": {
|
||||
"higher": "Aprende apenas com correspondências muito confiantes — mais lento mas mais fiável",
|
||||
"higher": "Aprende apenas com correspondências muito confiantes – mais lento mas mais fiável",
|
||||
"lower": "Aprende com mais ciclos; o modelo pode ser menos preciso"
|
||||
},
|
||||
"min_off_gap": {
|
||||
"higher": "Requer mais tempo inativo antes de iniciar um novo ciclo",
|
||||
"lower": "Um breve repouso inicia um novo ciclo — execuções consecutivas podem ser divididas"
|
||||
"lower": "Um breve repouso inicia um novo ciclo – execuções consecutivas podem ser divididas"
|
||||
},
|
||||
"min_power": {
|
||||
"higher": "Menos sensível ao consumo em repouso; pode não detetar programas muito silenciosos",
|
||||
@@ -1598,24 +1652,24 @@
|
||||
"lower": "Para um ciclo bloqueado mais cedo"
|
||||
},
|
||||
"off_delay": {
|
||||
"higher": "Mais tempo para pausas do aparelho — gere fases longas de molho ou secagem",
|
||||
"lower": "Deteção de fim mais rápida — adequado para aparelhos com ligação/desligação limpa"
|
||||
"higher": "Mais tempo para pausas do aparelho – gere fases longas de molho ou secagem",
|
||||
"lower": "Deteção de fim mais rápida – adequado para aparelhos com ligação/desligação limpa"
|
||||
},
|
||||
"profile_match_threshold": {
|
||||
"higher": "Confirma apenas correspondências de alta confiança; mais ciclos ficam sem etiqueta",
|
||||
"lower": "Corresponde a mais ciclos; alguns podem estar ligeiramente errados"
|
||||
},
|
||||
"running_dead_zone": {
|
||||
"higher": "Ignora breves picos de potência em repouso — menos sensível ao ruído",
|
||||
"lower": "Responde a impulsos mais curtos — deteta atividade transitória rápida"
|
||||
"higher": "Ignora breves picos de potência em repouso – menos sensível ao ruído",
|
||||
"lower": "Responde a impulsos mais curtos – deteta atividade transitória rápida"
|
||||
},
|
||||
"start_threshold_w": {
|
||||
"higher": "Evita arranques falsos por breves picos de potência",
|
||||
"lower": "Deteta programas de baixa potência; pode ser ativado por ruído"
|
||||
},
|
||||
"stop_threshold_w": {
|
||||
"higher": "Termina o ciclo mais cedo — pode fechar durante uma pausa",
|
||||
"lower": "Aguarda mais para terminar — menos conclusões prematuras"
|
||||
"higher": "Termina o ciclo mais cedo – pode fechar durante uma pausa",
|
||||
"lower": "Aguarda mais para terminar – menos conclusões prematuras"
|
||||
},
|
||||
"watchdog_interval": {
|
||||
"higher": "Fases silenciosas mais longas permitidas; menos paragens forçadas falsas",
|
||||
@@ -1766,6 +1820,69 @@
|
||||
},
|
||||
"pg_sweep": {
|
||||
"optimize": "Otimizar: {param}"
|
||||
},
|
||||
"pg_detail": {
|
||||
"simulate": "Simular ciclo"
|
||||
},
|
||||
"split": {
|
||||
"apply": "A dividir o ciclo"
|
||||
},
|
||||
"trim": {
|
||||
"apply": "A recortar o ciclo"
|
||||
},
|
||||
"merge": {
|
||||
"apply": "A combinar ciclos"
|
||||
},
|
||||
"rebuild": {
|
||||
"envelopes": "A reconstruir envelopes"
|
||||
},
|
||||
"cancelling": "A cancelar..."
|
||||
},
|
||||
"setup": {
|
||||
"hdr": {
|
||||
"card": "Configuração do dispositivo",
|
||||
"healthy_chip": "Configuração concluída"
|
||||
},
|
||||
"phase0": {
|
||||
"washer": "O WashData já está a detectar os seus ciclos. Grave o primeiro ciclo para activar os nomes dos programas e as estimativas de tempo.",
|
||||
"dishwasher": "O WashData está a monitorizar. As máquinas de lavar louça têm ciclos complexos – recomenda-se vivamente gravar o primeiro ciclo. Se um ciclo detectado demorar demasiado, utilize o editor de ciclos para o cortar antes de o guardar como perfil.",
|
||||
"generic": "O WashData está a monitorizar. Grave ou rotule um ciclo detectado para começar a criar perfis."
|
||||
},
|
||||
"phase1a": {
|
||||
"labelled": "Bom começo – o seu primeiro programa está guardado. Para dados mais precisos, considere gravar o próximo ciclo com o widget de gravação."
|
||||
},
|
||||
"phase1b": {
|
||||
"recorded": "A sua gravação foi guardada como {profile_name}. Agora grave ou rotule os outros programas que utiliza habitualmente para aumentar a cobertura."
|
||||
},
|
||||
"phase1c": {
|
||||
"verify": "Tem {count} programas da comunidade. Execute um ciclo para verificar se o WashData os reconhece correctamente – a correspondência melhorará à medida que o dispositivo acumula o seu próprio histórico."
|
||||
},
|
||||
"phase2": {
|
||||
"cluster": "O WashData detectou {count} ciclos que não correspondem a nenhum programa guardado – parecem-se entre si. Quer criar um novo perfil para eles?",
|
||||
"unmatched": "O seu último ciclo não correspondeu a nenhum programa guardado. É um novo programa?"
|
||||
},
|
||||
"phase3": {
|
||||
"suggestions": "O WashData tem recomendações de definições baseadas no histórico de ciclos – reveja-as para melhorar a precisão de detecção.",
|
||||
"groups": "Alguns dos seus perfis parecem o mesmo programa a temperaturas diferentes. Organize-os num grupo para uma melhor correspondência.",
|
||||
"phases": "Adicione fases de programa a {profile_name} para estimativas mais precisas do tempo restante."
|
||||
},
|
||||
"phase4": {
|
||||
"healthy": "Este dispositivo está totalmente configurado ({profile_count} perfis)."
|
||||
},
|
||||
"cta": {
|
||||
"start_recording": "Iniciar gravação",
|
||||
"label_detected_cycle": "Já tenho um ciclo detectado – rotulá-lo em vez disso",
|
||||
"browse_cycles": "Explorar ciclos para rotular outro",
|
||||
"view_profiles": "Ver os seus perfis",
|
||||
"create_from_cluster": "Criar perfil a partir destes ciclos",
|
||||
"create_profile": "Criar um perfil para este programa",
|
||||
"review_suggestions": "Rever sugestões",
|
||||
"organise_profiles": "Organizar perfis",
|
||||
"configure_phases": "Configurar fases",
|
||||
"skip_step": "Ignorar este passo",
|
||||
"skip_forever": "Não voltar a mostrar",
|
||||
"hide_guidance": "Ocultar guia",
|
||||
"show_guidance": "Mostrar guia"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
{
|
||||
"badge": {
|
||||
"artifact_tip": "{n} anomalii detectate (de exemplu, ușa deschisă la jumătatea ciclului) — deschideți pentru a le vedea pe grafic",
|
||||
"artifact_tip": "{n} anomalii detectate (de exemplu, ușa deschisă la jumătatea ciclului) – deschideți pentru a le vedea pe grafic",
|
||||
"auto": "(detectat automat)",
|
||||
"built_in_tag": "integrat",
|
||||
"declining": "↘ în scădere",
|
||||
"energy_low": "Energie mai mică decât de obicei",
|
||||
"energy_spike": "Energie mai mare decât de obicei",
|
||||
"fair_fit": "calitate acceptabilă",
|
||||
"fair_fit_tip": "Consistență moderată a potrivirii — unele cicluri atribuite acestui profil au scoruri de încredere mai mici. Etichetați mai multe cicluri sau reînregistrați profilul pentru a îmbunătăți acuratețea.",
|
||||
"fair_fit_tip": "Consistență moderată a potrivirii – unele cicluri atribuite acestui profil au scoruri de încredere mai mici. Etichetați mai multe cicluri sau reînregistrați profilul pentru a îmbunătăți acuratețea.",
|
||||
"feedback_requested": "S-a solicitat feedback",
|
||||
"golden_cycle": "Ciclu de referință înregistrat",
|
||||
"improving": "↗ în îmbunătățire",
|
||||
@@ -15,7 +15,7 @@
|
||||
"needs_review": "Necesită revizuire",
|
||||
"overrun": "A durat mai mult decât de obicei",
|
||||
"poor_fit": "calitate slabă",
|
||||
"poor_fit_tip": "Istoric de potrivire inconsecvent — luați în considerare reconstruirea acestui profil",
|
||||
"poor_fit_tip": "Istoric de potrivire inconsecvent – luați în considerare reconstruirea acestui profil",
|
||||
"restart_gap_tip": "{n} gol la repornirea HA: traseul de putere are o lipsă",
|
||||
"reviewed": "Revizuit",
|
||||
"steady": "→ stabil",
|
||||
@@ -57,7 +57,7 @@
|
||||
"create_profile": "+ Creați profil",
|
||||
"delete": "Ștergeți",
|
||||
"delete_group": "Ștergeți grupul",
|
||||
"delete_group_tip": "Ștergeți numai acest grup — profilurile membrilor sunt păstrate",
|
||||
"delete_group_tip": "Ștergeți numai acest grup – profilurile membrilor sunt păstrate",
|
||||
"delete_profile": "Ștergeți profilul",
|
||||
"discard": "Renunțați",
|
||||
"discard_tip": "Renunțați la urma înregistrată fără a salva",
|
||||
@@ -87,7 +87,7 @@
|
||||
"on_cycle_finished": "La terminarea ciclului",
|
||||
"on_cycle_started": "La pornirea ciclului",
|
||||
"pause_cycle": "Pauză",
|
||||
"pause_cycle_tip": "Puneți în pauză ciclul în curs — aparatul va relua de unde a rămas",
|
||||
"pause_cycle_tip": "Puneți în pauză ciclul în curs – aparatul va relua de unde a rămas",
|
||||
"pg_apply_device": "Aplicați pe dispozitiv",
|
||||
"pg_autofill": "Completare automată",
|
||||
"play": "Redați",
|
||||
@@ -97,8 +97,8 @@
|
||||
"process_tip": "Salvați urma înregistrată ca profil nou sau existent",
|
||||
"rebuild": "Reconstruiți plicurile",
|
||||
"rebuild_envelope": "Reconstruiți plicul",
|
||||
"rebuild_tip": "Recalculați plicul de putere așteptat (banda min/max) pentru toate profilurile din ciclurile lor etichetate — rulați după etichetarea de noi cicluri sau corectarea celor vechi",
|
||||
"rec_start_tip": "Porniți înregistrarea urmei de putere a aparatului — porniți imediat înainte de a rula un ciclu",
|
||||
"rebuild_tip": "Recalculați plicul de putere așteptat (banda min/max) pentru toate profilurile din ciclurile lor etichetate – rulați după etichetarea de noi cicluri sau corectarea celor vechi",
|
||||
"rec_start_tip": "Porniți înregistrarea urmei de putere a aparatului – porniți imediat înainte de a rula un ciclu",
|
||||
"rec_stop": "Opriți",
|
||||
"rec_stop_tip": "Opriți înregistrarea și păstrați urma capturată pentru revizuire",
|
||||
"record": "Porniți înregistrarea",
|
||||
@@ -182,7 +182,7 @@
|
||||
},
|
||||
"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.",
|
||||
"settings_banner": "{n} conflict{s} de setări – verificați secțiunile evidențiate și remediați înainte de salvare.",
|
||||
"settings_banner_btn": "Salt la primul",
|
||||
"confidence": {
|
||||
"auto": "Trebuie să fie cel puțin egal cu Pragul de potrivire ({match})",
|
||||
@@ -451,9 +451,9 @@
|
||||
"show_expected": "Afișați suprapunerea curbei așteptate (profil potrivit, portocaliu)",
|
||||
"show_raw": "Afișați comutatorul pentru semnalul brut al prizei în graficul de putere în timp real",
|
||||
"sparkline": "Tendința recentă a duratei ciclurilor",
|
||||
"stage2": "Etapa 2 — similaritate de bază",
|
||||
"stage3": "Etapa 3 — DTW",
|
||||
"stage4": "Etapa 4 — concordanță",
|
||||
"stage2": "Etapa 2 – similaritate de bază",
|
||||
"stage3": "Etapa 3 – DTW",
|
||||
"stage4": "Etapa 4 – concordanță",
|
||||
"status": "Stare",
|
||||
"tail_trim": "Tăiere finală (s)",
|
||||
"timer_auto_pause": "Pauză automată",
|
||||
@@ -561,7 +561,12 @@
|
||||
"flags": "Semnale",
|
||||
"include_phase_map": "Includeți harta fazelor",
|
||||
"include_settings": "Includeți setările de detectare și potrivire",
|
||||
"show_contributor": "Afișați numele contribuitorilor"
|
||||
"show_contributor": "Afișați numele contribuitorilor",
|
||||
"task_pg_detail": "Simulare ciclu",
|
||||
"task_split": "Se divide ciclul",
|
||||
"task_trim": "Se decupează ciclul",
|
||||
"task_merge": "Se îmbină ciclurile",
|
||||
"task_rebuild": "Se reconstruiesc anvelopele"
|
||||
},
|
||||
"log": {
|
||||
"all_levels": "Toate nivelurile",
|
||||
@@ -645,7 +650,7 @@
|
||||
"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.",
|
||||
"artifact_header": "{n} anomalii detectate în timpul acestui ciclu",
|
||||
"artifact_pause_detail": "Puterea a scăzut aproape la zero timp de ~{n}s, apoi a revenit — probabil ușa a fost deschisă în mijlocul ciclului sau ciclul a fost întrerupt.",
|
||||
"artifact_pause_detail": "Puterea a scăzut aproape la zero timp de ~{n}s, apoi a revenit – probabil ușa a fost deschisă în mijlocul ciclului sau ciclul a fost întrerupt.",
|
||||
"artifact_spike_detail": "A depășit banda de putere obișnuită timp de ~{n}s.",
|
||||
"auto_label_intro": "Atribuiți profiluri ciclurilor neetichetate a căror încredere de potrivire depășește pragul.",
|
||||
"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.",
|
||||
@@ -654,10 +659,10 @@
|
||||
"collecting_data": "Se colectează date - mai sunt necesare {need} ciclu{plural} înainte ca reglajul fin să poată începe ({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",
|
||||
"compare_selected_cycles": "Cicluri selectate (solid) – afișați / ascundeți",
|
||||
"consider_new_profile": "Luați în considerare crearea unui profil nou.",
|
||||
"coverage_gap": "ciclurile recente nu au un profil corespunzător ({pct}% din ultimele 30).",
|
||||
"coverage_gap_similar_cycles": "{count} cicluri similare neetichetate găsite — creați un profil pentru a începe potrivirea lor.",
|
||||
"coverage_gap_similar_cycles": "{count} cicluri similare neetichetate găsite – creați un profil pentru a începe potrivirea lor.",
|
||||
"cycles_deleted": "{count} ciclu(ri) șterse",
|
||||
"enough_data": "Date suficiente pentru a învăța ({current}/{min} cicluri).",
|
||||
"export_description": "Exportați toate profilurile și ciclurile în JSON sau restaurați dintr-un export anterior.",
|
||||
@@ -686,7 +691,7 @@
|
||||
"ml_learned_intro": "Modele ajustate la această mașină.",
|
||||
"ml_loading": "se încarcă ML…",
|
||||
"ml_settings_intro": "Două comutatoare independente: unul aplică modelele în timpul unui ciclu, celălalt permite WashData să le ajusteze la mașina dvs. în timp.",
|
||||
"name_first_program": "Aveți suficiente cicluri — denumiți primul program pentru a începe potrivirea.",
|
||||
"name_first_program": "Aveți suficiente cicluri – denumiți primul program pentru a începe potrivirea.",
|
||||
"near_duplicate_cluster": "cluster de profiluri aproape duplicate detectat. Gruparea permite potrivirii să aleagă în mod fiabil între profiluri similare (de exemplu, același program la temperaturi/viteze de centrifugare diferite).",
|
||||
"no_cycles_match": "Niciun ciclu nu corespunde filtrului curent.",
|
||||
"no_cycles_profile": "Niciun ciclu pentru acest profil.",
|
||||
@@ -694,12 +699,12 @@
|
||||
"no_cycles_yet": "Niciun ciclu înregistrat încă.",
|
||||
"no_device_selected": "Niciun dispozitiv selectat.",
|
||||
"no_devices": "Niciun dispozitiv WashData configurat încă.",
|
||||
"no_envelope": "Niciun plic încă — reconstruiți după etichetarea ciclurilor.",
|
||||
"no_envelope": "Niciun plic încă – reconstruiți după etichetarea ciclurilor.",
|
||||
"no_envelope_overlay": "Niciun plic disponibil pentru suprapunere.",
|
||||
"no_fine_tuned": "Nimic ajustat încă — WashData folosește modelele sale integrate.",
|
||||
"no_fine_tuned": "Nimic ajustat încă – WashData folosește modelele sale integrate.",
|
||||
"no_logs": "Nicio înregistrare în memorie încă.",
|
||||
"no_maintenance": "Nicio întreținere înregistrată încă.",
|
||||
"no_match_yet": "Nicio tentativă de potrivire încă — aceasta se completează în timpul unui ciclu activ.",
|
||||
"no_match_yet": "Nicio tentativă de potrivire încă – aceasta se completează în timpul unui ciclu activ.",
|
||||
"no_other_users": "Niciun alt utilizator Home Assistant găsit.",
|
||||
"no_phases": "Nicio fază definită.",
|
||||
"no_phases_assigned": "Nicio fază atribuită.",
|
||||
@@ -713,7 +718,7 @@
|
||||
"notify_services_hint": "Utilizați ID-urile de serviciu {entity} (separate prin virgulă pentru mai multe). Variabile șablon: {vars}.",
|
||||
"old_actions_warning": "Configurat cu vechiul editor de acțiuni (acum eliminat). Încă se declanșează la evenimentele de ciclu, dar nu mai pot fi editate aici. Convertiți-le într-o automatizare normală sau eliminați-le.",
|
||||
"onboarding_progress": "{n} / 3 cicluri observate",
|
||||
"onboarding_watching": "Utilizați aparatul în mod normal — WashData monitorizează. După 3 cicluri, va începe potrivirea programelor.",
|
||||
"onboarding_watching": "Utilizați aparatul în mod normal – WashData monitorizează. După 3 cicluri, va începe potrivirea programelor.",
|
||||
"pending_feedback": "Feedback de detecție în așteptare",
|
||||
"performance_trend": "Tendință de performanță ({n} cicluri)",
|
||||
"pg_analysis_empty": "Încărcați un ciclu pentru a vedea analiza potrivirii.",
|
||||
@@ -748,13 +753,13 @@
|
||||
"restart_gap_footer": "Evidențiat pe grafic. Datele de putere lipsesc pentru aceste intervale; potrivirea a folosit numai citiri reale.",
|
||||
"restart_gap_header": "{n} gol la repornirea HA în timpul acestui ciclu",
|
||||
"restart_gap_item": "{dur} gol",
|
||||
"review_confirm_help": "Confirmați dacă acest ciclu a fost detectat corect. Recenziile dvs. antrenează modelul pe mașina dvs. — cu cât confirmați mai multe cicluri, cu atât obțineți o potrivire mai bună și un scor de sănătate mai bun. Un Bine/Rău rapid este suficient.",
|
||||
"review_confirm_help": "Confirmați dacă acest ciclu a fost detectat corect. Recenziile dvs. antrenează modelul pe mașina dvs. – cu cât confirmați mai multe cicluri, cu atât obțineți o potrivire mai bună și un scor de sănătate mai bun. Un Bine/Rău rapid este suficient.",
|
||||
"review_in_settings": "Revizuiți în Setări",
|
||||
"review_notes_placeholder": "Note (opțional)",
|
||||
"review_notes_tip": "Note cu text liber pentru referință proprie. Nu sunt folosite de potrivire sau antrenament.",
|
||||
"review_profile_tip": "Programul cu care acest ciclu este etichetat. Dacă programul detectat automat a fost greșit, corectați-l aici — etichetarea învață potrivirea pentru ciclurile viitoare.",
|
||||
"review_profile_tip": "Programul cu care acest ciclu este etichetat. Dacă programul detectat automat a fost greșit, corectați-l aici – etichetarea învață potrivirea pentru ciclurile viitoare.",
|
||||
"review_quality_tip": "Cât de curat este acest ciclu. Bine = un exemplu model al acestui program; Rău = detectat dar zgomotos sau atipic; Inutilizabil = detectat greșit (combinat, trunchiat sau fals). Determină scorul de sănătate și ce cicluri sunt permise pentru antrenarea modelului.",
|
||||
"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_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",
|
||||
"saving_triggers_reload": "Salvarea declanșează o reîncărcare a integrării. Entitățile HA pot apărea pe scurt ca indisponibile.",
|
||||
@@ -763,7 +768,7 @@
|
||||
"setting_changed": "Modificat de la {old} la {new} pe {date}",
|
||||
"settings_basic_note": "Se afișează setările esențiale. Comutați la Avansat pentru lista completă.",
|
||||
"shape_drift_advisory": "⚠ Deriva formei",
|
||||
"shape_drift_detail": "Tiparul de putere al acestui profil s-a schimbat în timp — posibilă uzură a aparatului sau întreținere necesară (ex. detartrare, curățarea filtrului).",
|
||||
"shape_drift_detail": "Tiparul de putere al acestui profil s-a schimbat în timp – posibilă uzură a aparatului sau întreținere necesară (ex. detartrare, curățarea filtrului).",
|
||||
"show_all_settings": "Afișați toate setările",
|
||||
"showing_suggestions": "Se afișează setarea {count} cu sugestii.",
|
||||
"split_intro": "Faceți clic pe grafic pentru a adăuga sau elimina un punct de divizare, sau detectați automat prin pauze de inactivitate. Fiecare segment rezultat poate primi propriul profil.",
|
||||
@@ -789,10 +794,10 @@
|
||||
"toast_revert_failed": "Revenire eșuată: {error}",
|
||||
"toast_reverted": "{key} a revenit la valoarea anterioară",
|
||||
"toast_save_failed": "Salvare eșuată: {error}",
|
||||
"trend_duration_longer": "Durata este în creștere ({pct}%/ciclu) — medie recentă {avg}",
|
||||
"trend_duration_shorter": "Durata este în scădere ({pct}%/ciclu) — medie recentă {avg}",
|
||||
"trend_duration_longer": "Durata este în creștere ({pct}%/ciclu) – medie recentă {avg}",
|
||||
"trend_duration_shorter": "Durata este în scădere ({pct}%/ciclu) – medie recentă {avg}",
|
||||
"trend_energy_down": "Energia este în scădere ({pct}%/ciclu)",
|
||||
"trend_energy_up": "Energia este în creștere ({pct}%/ciclu) — medie recentă {avg}",
|
||||
"trend_energy_up": "Energia este în creștere ({pct}%/ciclu) – medie recentă {avg}",
|
||||
"trim_intro": "Trageți mânerele roșii sau introduceți valori. Tot ceea ce este în afara ferestrei este eliminat.",
|
||||
"tuning_suggestions_available": "{count} sugestie de ajustare disponibilă din ciclurile observate. Acestea apar lângă câmpurile relevante.",
|
||||
"unsure_detected_prefix": "WashData nu este sigur că a detectat",
|
||||
@@ -857,7 +862,9 @@
|
||||
"share_guidelines_title": "Înainte de a partaja",
|
||||
"store_download_device_intro": "Adoptați fiecare program partajat și ciclurile sale de referință pe dispozitivul dvs. Propriile cicluri înregistrate și statisticile nu sunt afectate.",
|
||||
"store_share_device_intro": "Încărcați {brand} {model} cu ciclurile de referință pe care le selectați. Alții cu același aparat vă pot adopta programele. Intrările sunt revizuite înainte de a apărea public.",
|
||||
"share_profile_no_cycles": "Niciun ciclu de referință -- marcați un ciclu ca ⭐ în fila Cicluri pentru a include acest profil"
|
||||
"share_profile_no_cycles": "Niciun ciclu de referință -- marcați un ciclu ca ⭐ în fila Cicluri pentru a include acest profil",
|
||||
"advisory_phase_inconsistent": "'{name}' pare să amestece programe sau temperaturi diferite - ciclurile sale se încălzesc pe durate foarte diferite. Împărțirea sa în profiluri separate (de ex. pe temperatură) va îmbunătăți potrivirea și estimările de timp.",
|
||||
"advisory_phase_inconsistent_title": "⚠ Posibil programe amestecate"
|
||||
},
|
||||
"phase_desc": {
|
||||
"anti_crease": "Tumblări scurte ocazionale după finalizare pentru a reduce șifonarea.",
|
||||
@@ -940,6 +947,10 @@
|
||||
"triggers": {
|
||||
"intro": "Semnale externe opționale: un declanșator de sfârșit, un senzor de ușă, un comutator de pauză și reamintirea de descărcare.",
|
||||
"label": "Declanșatoare și Uși"
|
||||
},
|
||||
"phase_eta": {
|
||||
"label": "Timp rămas",
|
||||
"intro": "Timp rămas ținând cont de faze, pentru mașinile a căror durată de ciclu depinde de temperatură sau de centrifugare."
|
||||
}
|
||||
},
|
||||
"setting": {
|
||||
@@ -1023,6 +1034,10 @@
|
||||
"doc": "Preț fix pe kWh utilizat pentru cifrele de cost atunci când nu este stabilită mai sus nicio entitate de preț activ.",
|
||||
"label": "Preț Static Energie (pe kWh)"
|
||||
},
|
||||
"energy_sensor": {
|
||||
"doc": "Contor de energie cumulativ opțional (total_increasing în kWh/Wh, de ex. propriul contor de consum total al prizei). Când este setat, energia raportată a fiecărui ciclu este preluată din diferența acestui contor între început și sfârșit, ceea ce evită subevaluarea care apare la integrarea unui senzor de putere care raportează lent. Revine la valoarea integrată dacă citirea lipsește, dacă unitatea sa este necunoscută sau dacă delta nu este pozitiv. Lăsați necompletat pentru a continua să integrați senzorul de putere.",
|
||||
"label": "Entitate contor de energie"
|
||||
},
|
||||
"expose_debug_entities": {
|
||||
"doc": "Publicați entități suplimentare de diagnosticare HA (încrederea potrivirii, ambiguitatea, elementele interne de stare). Off menține lista de entități curată pentru utilizare normală.",
|
||||
"label": "Expuneți Entitățile de Depanare"
|
||||
@@ -1305,6 +1320,38 @@
|
||||
},
|
||||
"show_contributor": {
|
||||
"doc": "Afișați atribuirea \"de <contributor>\" pe aparatele și ciclurile de referință ale comunității."
|
||||
},
|
||||
"enable_phase_matching": {
|
||||
"label": "Timp rămas în funcție de faze",
|
||||
"doc": "Împarte fiecare ciclu în curs în faze (încălzire, spălare, centrifugare) și repartizează timpul rămas pe fiecare fază, combinat cu estimarea clasică - bazându-se pe repartiția pe faze la începutul ciclului și pe estimarea clasică spre final. Acest lucru personalizează numărătoarea inversă în funcție de cât de mult încălzește și funcționează efectiv mașina, ceea ce se observă cel mai mult în prima jumătate a unui ciclu. Dezactivat = doar estimarea clasică. Este afectată doar afișarea timpului rămas; potrivirea programelor și detectarea ciclurilor rămân neschimbate."
|
||||
},
|
||||
"keep_min_score": {
|
||||
"label": "Scor Min. de Potrivire",
|
||||
"doc": "Scorul minim de similaritate de care are nevoie un candidat pentru a rămâne în cursa de potrivire. Implicit 0.1 este deliberat permisiv - admite chiar și candidați slabi, lăsând etapele ulterioare să găsească cea mai bună potrivire. Măriți pentru a elimina mai devreme profilurile improbabile; micșorați pentru a lărgi grupul inițial de candidați."
|
||||
},
|
||||
"dtw_blend": {
|
||||
"label": "Amestec Deformare",
|
||||
"doc": "Cât din scorul de aliniere prin deformare temporală (DTW) înlocuiește scorul de bază al Etapei 2. 0 = utilizați doar scorul Etapei 2, 1 = utilizați doar scorul DTW, 0.5 (implicit) = amestec egal. Măriți pentru a vă baza mai mult pe alinierea prin deformare când programele au niveluri de putere similare dar tipare de sincronizare diferite."
|
||||
},
|
||||
"dtw_ensemble_w": {
|
||||
"label": "Mix Ansamblu Deformare",
|
||||
"doc": "În modul ansamblu DTW (implicit), ponderea pe L1 scalat față de DTW derivativ (DDTW). 1.0 = tot scalat-L1, 0 = tot DDTW, 0.7 = implicit. Varianta scalat-L1 compară nivelurile de putere; varianta derivativă reacționează la modul în care puterea se schimbă în timp. Ansamblul combină ambele."
|
||||
},
|
||||
"dtw_ddtw_scale": {
|
||||
"label": "Scară Deformare Derivativă",
|
||||
"doc": "Distanța de semi-saturație pentru scorul DTW derivativ. Scorul se înjumătățește când distanța DDTW egalează această valoare. Mai mic = mai sensibil la diferențele de formă. Implicit 30 este calibrat pentru urme tipice de putere ale aparatelor. Afectează doar modurile DTW ansamblu și ddtw."
|
||||
},
|
||||
"dtw_refine_top_n": {
|
||||
"label": "Contor Rafinare DTW",
|
||||
"doc": "Câți candidați de top ai Etapei 2 sunt rescorați de DTW. DTW este mai costisitor computațional, deci este aplicat doar la primii N candidați. Implicit 5. Măriți (la 7-9) dacă profilul corect ajunge uneori doar pe locul 4 sau 5 după Etapa 2 - DTW îl poate recupera. Micșorarea accelerează ușor potrivirea."
|
||||
},
|
||||
"duration_scale": {
|
||||
"label": "Precizie Durată",
|
||||
"doc": "Rigoarea penalizării acordului de durată a Etapei 4. Acesta este raportul logaritmic la care scorul de acord se înjumătățește. Mai mic = mai strict: o nepotrivire de durată afectează mai mult. Implicit 0.175 corespunde unei toleranțe de durată de aproximativ 18% la jumătate de pondere. Utilizați împreună cu Ponderea Duratei."
|
||||
},
|
||||
"energy_scale": {
|
||||
"label": "Precizie Energie",
|
||||
"doc": "Rigoarea penalizării acordului de energie a Etapei 4. Mai mic = mai strict: o nepotrivire de energie afectează mai mult. Implicit 0.25 este intenționat mai permisiv decât Rigoarea Duratei deoarece energia variază în funcție de sarcină. Utilizați împreună cu Ponderea Energiei."
|
||||
}
|
||||
},
|
||||
"setting_group": {
|
||||
@@ -1553,24 +1600,24 @@
|
||||
"lower": "Etichetează mai multe cicluri automat; unele pot fi identificate greșit"
|
||||
},
|
||||
"duration_tolerance": {
|
||||
"higher": "Acceptă un interval de durată mai larg — potrivire mai flexibilă",
|
||||
"lower": "Necesită durată mai apropiată — mai strict, poate respinge cicluri neobișnuite"
|
||||
"higher": "Acceptă un interval de durată mai larg – potrivire mai flexibilă",
|
||||
"lower": "Necesită durată mai apropiată – mai strict, poate respinge cicluri neobișnuite"
|
||||
},
|
||||
"end_energy_threshold": {
|
||||
"higher": "Închide doar ciclurile care au consumat energie substanțială",
|
||||
"lower": "Închide și cicluri scurte sau cu consum redus de energie"
|
||||
},
|
||||
"end_repeat_count": {
|
||||
"higher": "Necesită repetarea semnalului de final de mai multe ori — mai robust, puțin mai lent",
|
||||
"lower": "Se termină după mai puține repetări — detectare mai rapidă, risc mai mare de final fals"
|
||||
"higher": "Necesită repetarea semnalului de final de mai multe ori – mai robust, puțin mai lent",
|
||||
"lower": "Se termină după mai puține repetări – detectare mai rapidă, risc mai mare de final fals"
|
||||
},
|
||||
"learning_confidence": {
|
||||
"higher": "Învață doar din potriviri foarte sigure — mai lent dar mai fiabil",
|
||||
"higher": "Învață doar din potriviri foarte sigure – mai lent dar mai fiabil",
|
||||
"lower": "Învață din mai multe cicluri; modelul poate fi mai puțin precis"
|
||||
},
|
||||
"min_off_gap": {
|
||||
"higher": "Este nevoie de mai mult timp de inactivitate înainte de a începe un nou ciclu",
|
||||
"lower": "O pauză scurtă declanșează un nou ciclu — rulările consecutive pot fi împărțite"
|
||||
"lower": "O pauză scurtă declanșează un nou ciclu – rulările consecutive pot fi împărțite"
|
||||
},
|
||||
"min_power": {
|
||||
"higher": "Mai puțin sensibil la consumul de repaus; poate rata programe foarte silențioase",
|
||||
@@ -1581,24 +1628,24 @@
|
||||
"lower": "Oprește mai devreme un ciclu blocat"
|
||||
},
|
||||
"off_delay": {
|
||||
"higher": "Mai mult timp pentru pauzele aparatului — gestionează faze lungi de înmuiere sau uscare",
|
||||
"lower": "Detectare mai rapidă a finalului — funcționează bine pentru aparate cu pornire/oprire clară"
|
||||
"higher": "Mai mult timp pentru pauzele aparatului – gestionează faze lungi de înmuiere sau uscare",
|
||||
"lower": "Detectare mai rapidă a finalului – funcționează bine pentru aparate cu pornire/oprire clară"
|
||||
},
|
||||
"profile_match_threshold": {
|
||||
"higher": "Confirmă doar potriviri de înaltă încredere; mai multe cicluri rămân neetichetate",
|
||||
"lower": "Potrivește mai multe cicluri; unele pot fi ușor greșite"
|
||||
},
|
||||
"running_dead_zone": {
|
||||
"higher": "Ignoră scurte vârfuri de putere în repaus — mai puțin sensibil la zgomot",
|
||||
"lower": "Răspunde la impulsuri mai scurte — detectează activitate tranzitorie rapidă"
|
||||
"higher": "Ignoră scurte vârfuri de putere în repaus – mai puțin sensibil la zgomot",
|
||||
"lower": "Răspunde la impulsuri mai scurte – detectează activitate tranzitorie rapidă"
|
||||
},
|
||||
"start_threshold_w": {
|
||||
"higher": "Evită pornirile false cauzate de scurte vârfuri de putere",
|
||||
"lower": "Detectează programe de putere redusă; poate fi declanșat de zgomot"
|
||||
},
|
||||
"stop_threshold_w": {
|
||||
"higher": "Termină ciclul mai repede — se poate închide în timpul unei pauze",
|
||||
"lower": "Așteaptă mai mult să termine — mai puține finalizări premature"
|
||||
"higher": "Termină ciclul mai repede – se poate închide în timpul unei pauze",
|
||||
"lower": "Așteaptă mai mult să termine – mai puține finalizări premature"
|
||||
},
|
||||
"watchdog_interval": {
|
||||
"higher": "Faze silențioase mai lungi permise; mai puține opriri forțate false",
|
||||
@@ -1676,12 +1723,19 @@
|
||||
"start_duration_threshold": "Secunde peste prag pentru a confirma pornirea",
|
||||
"start_threshold_w": "Wați minimi pentru a fi considerat pornit",
|
||||
"stop_threshold_w": "Sub această valoare, mașina este considerată oprită",
|
||||
"dtw_bandwidth": "Câtă deformare în timp permite potrivirea formei",
|
||||
"corr_weight": "Ponderea formei curbei față de nivelul de putere în potrivire",
|
||||
"duration_weight": "Cât de mult influențează concordanța duratei potrivirea",
|
||||
"energy_weight": "Cât de mult influențează concordanța energiei potrivirea",
|
||||
"profile_match_min_duration_ratio": "Cel mai scurt ciclu (față de profil) încă permis să corespundă",
|
||||
"profile_match_max_duration_ratio": "Cel mai lung ciclu (față de profil) încă permis să corespundă"
|
||||
"dtw_bandwidth": "Etapa 3: banda de deformare Sakoe-Chiba (0 = DTW dezactivat; implicit 0.2 = 20% din lungimea ciclului)",
|
||||
"corr_weight": "Etapa 2: echilibru între forma curbei (corelație) și nivelul de putere (MAE); implicit 0.45",
|
||||
"duration_weight": "Etapa 4: cât de puternic influențează acordul de durată scorul final (implicit 0.22)",
|
||||
"energy_weight": "Etapa 4: cât de puternic influențează acordul de energie scorul final (implicit 0.22)",
|
||||
"profile_match_min_duration_ratio": "Etapa 1: lungimea minimă a ciclului ca fracție din durata profilului; implicit 0.1 (10%)",
|
||||
"profile_match_max_duration_ratio": "Etapa 1: lungimea maximă a ciclului ca fracție din durata profilului; implicit 1.5 (150%)",
|
||||
"keep_min_score": "Etapa 2: prag minim de scor pentru a rămâne în cursă; implicit 0.1 admite potriviri slabe, etapele ulterioare aleg cel mai bun",
|
||||
"dtw_blend": "Etapa 3: 0 = doar scor de bază, 1 = doar scor DTW, 0.5 = amestec egal (implicit)",
|
||||
"dtw_ensemble_w": "Etapa 3 (modul ansamblu): ponderea pe L1 scalat față de DTW derivativ; implicit 0.7 favorizează nivelul de putere",
|
||||
"dtw_ddtw_scale": "Etapa 3: distanța de semi-saturație DDTW; mai mic = mai sensibil la formă (implicit 30)",
|
||||
"dtw_refine_top_n": "Etapa 3: candidați rescorați de DTW; măriți la 7-9 dacă profilul corect se clasează pe locul 4-5 (implicit 5)",
|
||||
"duration_scale": "Etapa 4: raportul logaritmic la care acordul de durată se înjumătățește; mai mic = penalizare mai strictă (implicit 0.175)",
|
||||
"energy_scale": "Etapa 4: raportul logaritmic la care acordul de energie se înjumătățește; mai mic = penalizare mai strictă (implicit 0.25)"
|
||||
},
|
||||
"col": {
|
||||
"profile_tip": "Numele programului corespunzător. Neetichetat înseamnă că niciun profil nu a corespuns la sfârșitul ciclului.",
|
||||
@@ -1766,6 +1820,69 @@
|
||||
},
|
||||
"pg_sweep": {
|
||||
"optimize": "Optimizează: {param}"
|
||||
},
|
||||
"pg_detail": {
|
||||
"simulate": "Simulare ciclu"
|
||||
},
|
||||
"split": {
|
||||
"apply": "Se divide ciclul"
|
||||
},
|
||||
"trim": {
|
||||
"apply": "Se decupează ciclul"
|
||||
},
|
||||
"merge": {
|
||||
"apply": "Se îmbină ciclurile"
|
||||
},
|
||||
"rebuild": {
|
||||
"envelopes": "Se reconstruiesc anvelopele"
|
||||
},
|
||||
"cancelling": "Se anulează..."
|
||||
},
|
||||
"setup": {
|
||||
"hdr": {
|
||||
"card": "Configurarea dispozitivului",
|
||||
"healthy_chip": "Configurare finalizată"
|
||||
},
|
||||
"phase0": {
|
||||
"washer": "WashData detectează deja ciclurile dvs. Înregistrați primul ciclu pentru a activa numele programelor și estimările de timp.",
|
||||
"dishwasher": "WashData monitorizează. Mașinile de spălat vase au cicluri complexe – se recomandă insistent înregistrarea primului ciclu. Dacă un ciclu detectat durează prea mult, folosiți editorul de cicluri pentru a-l tăia înainte de a-l salva ca profil.",
|
||||
"generic": "WashData monitorizează. Înregistrați sau etichetați un ciclu detectat pentru a începe să creați profiluri."
|
||||
},
|
||||
"phase1a": {
|
||||
"labelled": "Început bun – primul dvs. program este salvat. Pentru date mai curate, luați în considerare înregistrarea următorului ciclu cu widgetul de înregistrare."
|
||||
},
|
||||
"phase1b": {
|
||||
"recorded": "Înregistrarea dvs. a fost salvată ca {profile_name}. Acum înregistrați sau etichetați celelalte programe obișnuite pentru a extinde acoperirea."
|
||||
},
|
||||
"phase1c": {
|
||||
"verify": "Aveți {count} programe din comunitate. Rulați un ciclu pentru a verifica dacă WashData îl recunoaște corect – potrivirea se va îmbunătăți pe măsură ce dispozitivul își construiește propriul istoric."
|
||||
},
|
||||
"phase2": {
|
||||
"cluster": "WashData a observat {count} cicluri care nu corespund niciunui program salvat – acestea se aseamănă între ele. Doriți să creați un profil nou pentru ele?",
|
||||
"unmatched": "Ultimul dvs. ciclu nu a corespuns niciunui program salvat. Este un program nou?"
|
||||
},
|
||||
"phase3": {
|
||||
"suggestions": "WashData are recomandări de setări bazate pe istoricul ciclurilor – revizuiți-le pentru a îmbunătăți acuratețea detectării.",
|
||||
"groups": "Unele profiluri ale dvs. seamănă cu același program la temperaturi diferite. Organizați-le într-un grup pentru o potrivire mai bună.",
|
||||
"phases": "Adăugați faze de program la {profile_name} pentru estimări mai precise ale timpului rămas."
|
||||
},
|
||||
"phase4": {
|
||||
"healthy": "Acest dispozitiv este complet configurat ({profile_count} profiluri)."
|
||||
},
|
||||
"cta": {
|
||||
"start_recording": "Porniți înregistrarea",
|
||||
"label_detected_cycle": "Am deja un ciclu detectat – etichetați-l în schimb",
|
||||
"browse_cycles": "Răsfoiți ciclurile pentru a eticheta altul",
|
||||
"view_profiles": "Vizualizați profilurile",
|
||||
"create_from_cluster": "Creați profil din aceste cicluri",
|
||||
"create_profile": "Creați un profil pentru acesta",
|
||||
"review_suggestions": "Revizuiți sugestiile",
|
||||
"organise_profiles": "Organizați profilurile",
|
||||
"configure_phases": "Configurați fazele",
|
||||
"skip_step": "Omiteți acest pas",
|
||||
"skip_forever": "Nu mai afișa",
|
||||
"hide_guidance": "Ascundeți ghidul",
|
||||
"show_guidance": "Afișați ghidul"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
{
|
||||
"badge": {
|
||||
"artifact_tip": "Обнаружено {n} аномалий (например, дверь открылась в середине цикла) — откройте, чтобы увидеть их на графике",
|
||||
"artifact_tip": "Обнаружено {n} аномалий (например, дверь открылась в середине цикла) – откройте, чтобы увидеть их на графике",
|
||||
"auto": "(авто-определение)",
|
||||
"built_in_tag": "встроенный",
|
||||
"declining": "↘ снижается",
|
||||
"energy_low": "Энергопотребление ниже обычного",
|
||||
"energy_spike": "Энергопотребление выше обычного",
|
||||
"fair_fit": "приемлемое качество",
|
||||
"fair_fit_tip": "Умеренная согласованность совпадений — некоторые циклы, назначенные этому профилю, имеют более низкие оценки достоверности. Пометьте больше циклов или перезапишите профиль, чтобы повысить точность.",
|
||||
"fair_fit_tip": "Умеренная согласованность совпадений – некоторые циклы, назначенные этому профилю, имеют более низкие оценки достоверности. Пометьте больше циклов или перезапишите профиль, чтобы повысить точность.",
|
||||
"feedback_requested": "Запрошен отзыв",
|
||||
"golden_cycle": "Записанный эталонный цикл",
|
||||
"improving": "↗ улучшается",
|
||||
@@ -15,7 +15,7 @@
|
||||
"needs_review": "Требуется проверка",
|
||||
"overrun": "Работал дольше обычного",
|
||||
"poor_fit": "низкое качество",
|
||||
"poor_fit_tip": "Непоследовательная история совпадений — рассмотрите возможность восстановления этого профиля",
|
||||
"poor_fit_tip": "Непоследовательная история совпадений – рассмотрите возможность восстановления этого профиля",
|
||||
"restart_gap_tip": "{n} пропуск при перезапуске HA: в графике мощности есть разрыв",
|
||||
"reviewed": "Рассмотрено",
|
||||
"steady": "→ стабильно",
|
||||
@@ -57,7 +57,7 @@
|
||||
"create_profile": "+ Создать профиль",
|
||||
"delete": "Удалить",
|
||||
"delete_group": "Удалить группу",
|
||||
"delete_group_tip": "Удалить только эту группу — профили участников останутся",
|
||||
"delete_group_tip": "Удалить только эту группу – профили участников останутся",
|
||||
"delete_profile": "Удалить профиль",
|
||||
"discard": "Отменить",
|
||||
"discard_tip": "Отменить запись без сохранения",
|
||||
@@ -87,7 +87,7 @@
|
||||
"on_cycle_finished": "По завершении цикла",
|
||||
"on_cycle_started": "При запуске цикла",
|
||||
"pause_cycle": "Пауза",
|
||||
"pause_cycle_tip": "Приостановить текущий цикл — прибор продолжит работу с того места, где остановился",
|
||||
"pause_cycle_tip": "Приостановить текущий цикл – прибор продолжит работу с того места, где остановился",
|
||||
"pg_apply_device": "Применить к устройству",
|
||||
"pg_autofill": "Автозаполнение",
|
||||
"play": "Воспроизвести",
|
||||
@@ -97,8 +97,8 @@
|
||||
"process_tip": "Сохранить запись как новый или существующий профиль",
|
||||
"rebuild": "Перестроить огибающие",
|
||||
"rebuild_envelope": "Перестроить огибающую",
|
||||
"rebuild_tip": "Пересчитать ожидаемую огибающую мощности (полоса мин./макс.) для всех профилей по помеченным циклам — запустить после пометки новых циклов или исправления старых",
|
||||
"rec_start_tip": "Начать запись потребления мощности прибора — запустить непосредственно перед началом цикла",
|
||||
"rebuild_tip": "Пересчитать ожидаемую огибающую мощности (полоса мин./макс.) для всех профилей по помеченным циклам – запустить после пометки новых циклов или исправления старых",
|
||||
"rec_start_tip": "Начать запись потребления мощности прибора – запустить непосредственно перед началом цикла",
|
||||
"rec_stop": "Стоп",
|
||||
"rec_stop_tip": "Остановить запись и сохранить захваченные данные для просмотра",
|
||||
"record": "Начать запись",
|
||||
@@ -182,7 +182,7 @@
|
||||
},
|
||||
"attn_sub": "Исправьте конфликты перед сохранением",
|
||||
"attn_title": "{n} конфликт{s} настроек",
|
||||
"settings_banner": "{n} конфликт{s} настроек — проверьте выделенные разделы и исправьте перед сохранением.",
|
||||
"settings_banner": "{n} конфликт{s} настроек – проверьте выделенные разделы и исправьте перед сохранением.",
|
||||
"settings_banner_btn": "К первому",
|
||||
"confidence": {
|
||||
"auto": "Должен быть не ниже Порога Совпадения ({match})",
|
||||
@@ -451,9 +451,9 @@
|
||||
"show_expected": "Показать ожидаемую кривую (сопоставленный профиль, оранжевый)",
|
||||
"show_raw": "Показать переключатель необработанных данных розетки на графике мощности в реальном времени",
|
||||
"sparkline": "Недавняя динамика длительности циклов",
|
||||
"stage2": "Этап 2 — базовое сходство",
|
||||
"stage3": "Этап 3 — DTW",
|
||||
"stage4": "Этап 4 — совпадение",
|
||||
"stage2": "Этап 2 – базовое сходство",
|
||||
"stage3": "Этап 3 – DTW",
|
||||
"stage4": "Этап 4 – совпадение",
|
||||
"status": "Статус",
|
||||
"tail_trim": "Обрезка конца (с)",
|
||||
"timer_auto_pause": "Авто-пауза",
|
||||
@@ -561,7 +561,12 @@
|
||||
"flags": "Метки",
|
||||
"include_phase_map": "Включить карту фаз",
|
||||
"include_settings": "Включить настройки",
|
||||
"show_contributor": "Показать автора"
|
||||
"show_contributor": "Показать автора",
|
||||
"task_pg_detail": "Смоделировать цикл",
|
||||
"task_split": "Разделение цикла",
|
||||
"task_trim": "Обрезка цикла",
|
||||
"task_merge": "Объединение циклов",
|
||||
"task_rebuild": "Пересчёт огибающих"
|
||||
},
|
||||
"log": {
|
||||
"all_levels": "Все уровни",
|
||||
@@ -645,19 +650,19 @@
|
||||
"artifact_dip_detail": "Мощность упала ниже обычного диапазона на ~{n}с.",
|
||||
"artifact_footer": "Выделено на графике выше. Это временные артефакты (например, дверь открылась в середине цикла), а не обязательно проблемы.",
|
||||
"artifact_header": "В этом цикле обнаружено {n} аномалий",
|
||||
"artifact_pause_detail": "Мощность упала почти до нуля на ~{n}с, затем возобновилась — вероятно, дверца была открыта в середине цикла или цикл был приостановлен.",
|
||||
"artifact_pause_detail": "Мощность упала почти до нуля на ~{n}с, затем возобновилась – вероятно, дверца была открыта в середине цикла или цикл был приостановлен.",
|
||||
"artifact_spike_detail": "Мощность вышла за пределы обычного диапазона на ~{n}с.",
|
||||
"auto_label_intro": "Назначить профили не помеченным циклам, чьё совпадение превышает порог.",
|
||||
"automations_intro": "WashData запускает события {start} / {end} и предоставляет объекты, поэтому уведомления и действия лучше всего строить как обычные автоматизации Home Assistant. Автоматизации, использующие это устройство, отображаются ниже.",
|
||||
"cleanup_intro": "Все помеченные циклы наложены. Отметьте выбросы и удалите для очистки профиля.",
|
||||
"clear_debug_hint": "Удалите сохраненные данные отладки, чтобы освободить место.",
|
||||
"collecting_data": "Сбор данных — ещё {need} цикл{plural} до начала точной настройки ({current}/{min}).",
|
||||
"collecting_data": "Сбор данных – ещё {need} цикл{plural} до начала точной настройки ({current}/{min}).",
|
||||
"compare_overlay_profiles": "Наложить профили (бледные)",
|
||||
"compare_profiles_tip": "Наложите конверты других профилей на диаграмму выше, чтобы увидеть, какой из них лучше всего подходит для этого цикла.",
|
||||
"compare_selected_cycles": "Выбранные циклы (чёткие) — показать / скрыть",
|
||||
"compare_selected_cycles": "Выбранные циклы (чёткие) – показать / скрыть",
|
||||
"consider_new_profile": "Рассмотрите возможность создания нового профиля.",
|
||||
"coverage_gap": "последние циклы не имеют соответствующего профиля ({pct}% из последних 30).",
|
||||
"coverage_gap_similar_cycles": "Найдено {count} похожих непомеченных циклов — создайте профиль, чтобы начать их сопоставление.",
|
||||
"coverage_gap_similar_cycles": "Найдено {count} похожих непомеченных циклов – создайте профиль, чтобы начать их сопоставление.",
|
||||
"cycles_deleted": "Удалено циклов: {count}",
|
||||
"enough_data": "Достаточно данных для обучения ({current}/{min} циклов).",
|
||||
"export_description": "Экспортируйте все профили и циклы в JSON или восстановите данные из предыдущего экспорта.",
|
||||
@@ -686,7 +691,7 @@
|
||||
"ml_learned_intro": "Модели, настроенные под эту машину.",
|
||||
"ml_loading": "загрузка ML…",
|
||||
"ml_settings_intro": "Два независимых переключателя: один применяет модели во время работы цикла, другой позволяет WashData постепенно настраивать их под вашу машину.",
|
||||
"name_first_program": "Циклов достаточно — назовите первую программу, чтобы начать сопоставление.",
|
||||
"name_first_program": "Циклов достаточно – назовите первую программу, чтобы начать сопоставление.",
|
||||
"near_duplicate_cluster": "Обнаружен почти повторяющийся кластер профилей. Группировка позволяет надежно выбирать одинаковые программы (например, одна и та же программа при разной температуре/отжиме).",
|
||||
"no_cycles_match": "Нет циклов, соответствующих текущему фильтру.",
|
||||
"no_cycles_profile": "Нет циклов для этого профиля.",
|
||||
@@ -694,12 +699,12 @@
|
||||
"no_cycles_yet": "Циклы пока не записаны.",
|
||||
"no_device_selected": "Устройство не выбрано.",
|
||||
"no_devices": "Устройства WashData ещё не настроены.",
|
||||
"no_envelope": "Огибающей пока нет — перестройте после пометки циклов.",
|
||||
"no_envelope": "Огибающей пока нет – перестройте после пометки циклов.",
|
||||
"no_envelope_overlay": "Нет доступной огибающей для наложения.",
|
||||
"no_fine_tuned": "Ещё ничего не настроено — WashData использует встроенные модели.",
|
||||
"no_fine_tuned": "Ещё ничего не настроено – WashData использует встроенные модели.",
|
||||
"no_logs": "Журналы пока не буферизованы.",
|
||||
"no_maintenance": "Обслуживание ещё не записано.",
|
||||
"no_match_yet": "Попыток совпадения пока нет — заполняется во время работы цикла.",
|
||||
"no_match_yet": "Попыток совпадения пока нет – заполняется во время работы цикла.",
|
||||
"no_other_users": "Других пользователей Home Assistant не найдено.",
|
||||
"no_phases": "Фазы не определены.",
|
||||
"no_phases_assigned": "Фазы не назначены.",
|
||||
@@ -713,7 +718,7 @@
|
||||
"notify_services_hint": "Используйте ID сервисов {entity} (через запятую для нескольких). Переменные шаблона: {vars}.",
|
||||
"old_actions_warning": "Настроен со старым редактором действий (теперь удален). Они по-прежнему срабатывают при событиях цикла, но их больше нельзя редактировать здесь. Преобразуйте их в обычную автоматику или удалите.",
|
||||
"onboarding_progress": "Наблюдалось циклов: {n} / 3",
|
||||
"onboarding_watching": "Используйте прибор как обычно — WashData наблюдает. После 3 циклов начнётся сопоставление программ.",
|
||||
"onboarding_watching": "Используйте прибор как обычно – WashData наблюдает. После 3 циклов начнётся сопоставление программ.",
|
||||
"pending_feedback": "Ожидает отзыва об обнаружении",
|
||||
"performance_trend": "Тенденция производительности ({n} циклов)",
|
||||
"pg_analysis_empty": "Загрузите цикл, чтобы увидеть анализ совпадения.",
|
||||
@@ -752,18 +757,18 @@
|
||||
"review_in_settings": "Просмотр в настройках",
|
||||
"review_notes_placeholder": "Примечания (необязательно)",
|
||||
"review_notes_tip": "Свободные текстовые заметки для справки. Не используется при сопоставлении или обучении.",
|
||||
"review_profile_tip": "Программа, под которой помечен этот цикл. Если автоматически определенная программа была неправильной, исправьте ее здесь — маркировка учит сопоставлению для будущих циклов.",
|
||||
"review_profile_tip": "Программа, под которой помечен этот цикл. Если автоматически определенная программа была неправильной, исправьте ее здесь – маркировка учит сопоставлению для будущих циклов.",
|
||||
"review_quality_tip": "Насколько чист этот цикл. Хорошо = хрестоматийный пример этой программы; Плохо = обнаружено, но шумно или нетипично; Непригодный = обнаружен неправильно (объединен, усечен или поддельен). Управляет показателем работоспособности и тем, какие циклы разрешены для обучения модели.",
|
||||
"review_recorded_tip": "Отметьте это как выбранный вручную эталонный цикл для своей программы — та же роль, что и цикл, записанный вручную. Ссылочные циклы всегда сохраняются, заполняют соответствующий шаблон и никогда не удаляются при очистке. (Это «золотой»/записанный флаг; оба — одно и то же.)",
|
||||
"review_recorded_tip": "Отметьте это как выбранный вручную эталонный цикл для своей программы – та же роль, что и цикл, записанный вручную. Ссылочные циклы всегда сохраняются, заполняют соответствующий шаблон и никогда не удаляются при очистке. (Это «золотой»/записанный флаг; оба – одно и то же.)",
|
||||
"review_tags_tip": "Необязательные флаги, описывающие, что пошло не так в этом цикле, чтобы это можно было учесть при обучении и очистке.",
|
||||
"review_to_cycles": "Открыть очередь проверки циклов",
|
||||
"saving_triggers_reload": "Сохранение вызывает перезагрузку интеграции. Объекты HA могут кратко отображаться как недоступные.",
|
||||
"search_placeholder": "Поиск настроек…",
|
||||
"see_recorder": "Смотрите виджет записи ниже",
|
||||
"setting_changed": "Изменено с {old} на {new} — {date}",
|
||||
"setting_changed": "Изменено с {old} на {new} – {date}",
|
||||
"settings_basic_note": "Показаны основные настройки. Переключитесь на «Дополнительно» для полного списка.",
|
||||
"shape_drift_advisory": "⚠ Смещение формы",
|
||||
"shape_drift_detail": "Профиль мощности этого профиля изменился со временем — возможный износ прибора или необходимость технического обслуживания (например, удаление накипи, чистка фильтра).",
|
||||
"shape_drift_detail": "Профиль мощности этого профиля изменился со временем – возможный износ прибора или необходимость технического обслуживания (например, удаление накипи, чистка фильтра).",
|
||||
"show_all_settings": "Показать все настройки",
|
||||
"showing_suggestions": "Показана настройка {count} с предложениями.",
|
||||
"split_intro": "Нажмите на график, чтобы добавить или удалить точку разбивки, или авто-определите по паузам. Каждый результирующий сегмент может получить свой профиль.",
|
||||
@@ -789,10 +794,10 @@
|
||||
"toast_revert_failed": "Откат не выполнен: {error}",
|
||||
"toast_reverted": "Возвращено: {key}",
|
||||
"toast_save_failed": "Сохранение не выполнено: {error}",
|
||||
"trend_duration_longer": "Тенденция увеличения продолжительности ({pct}%/цикл) — среднее значение за последнее время {avg}",
|
||||
"trend_duration_shorter": "Тенденция к сокращению продолжительности ({pct}%/цикл) — среднее значение за последнее время {avg}",
|
||||
"trend_duration_longer": "Тенденция увеличения продолжительности ({pct}%/цикл) – среднее значение за последнее время {avg}",
|
||||
"trend_duration_shorter": "Тенденция к сокращению продолжительности ({pct}%/цикл) – среднее значение за последнее время {avg}",
|
||||
"trend_energy_down": "Тенденция к снижению энергопотребления ({pct}%/цикл)",
|
||||
"trend_energy_up": "Тенденция роста энергопотребления ({pct}%/цикл) — последнее среднее значение {avg}",
|
||||
"trend_energy_up": "Тенденция роста энергопотребления ({pct}%/цикл) – последнее среднее значение {avg}",
|
||||
"trim_intro": "Перетащите красные маркеры или введите значения. Всё за пределами окна удаляется.",
|
||||
"tuning_suggestions_available": "{count} предложение по настройке, доступное из наблюдаемых циклов. Они появляются рядом с соответствующими полями.",
|
||||
"unsure_detected_prefix": "WashData не уверен, что обнаружил",
|
||||
@@ -857,7 +862,9 @@
|
||||
"share_guidelines_title": "Перед публикацией",
|
||||
"store_download_device_intro": "Скачать конфигурацию устройства из сообщества и применить её к новому или существующему устройству",
|
||||
"store_share_device_intro": "Поделиться программами вашего устройства (профили + эталонные циклы) с сообществом. Настройки являются необязательными.",
|
||||
"share_profile_no_cycles": "Профиль '{p}' не имеет ⭐ эталонных циклов -- он будет пропущен, если у вас нет {n}+ подтверждённых запусков"
|
||||
"share_profile_no_cycles": "Профиль '{p}' не имеет ⭐ эталонных циклов -- он будет пропущен, если у вас нет {n}+ подтверждённых запусков",
|
||||
"advisory_phase_inconsistent": "Похоже, что '{name}' смешивает разные программы или температуры - его циклы нагреваются в течение очень разного времени. Разделение на отдельные профили (напр. по температуре) улучшит сопоставление и оценки времени.",
|
||||
"advisory_phase_inconsistent_title": "⚠ Возможно, смешанные программы"
|
||||
},
|
||||
"phase_desc": {
|
||||
"anti_crease": "Периодические короткие вращения барабана после завершения для уменьшения складок.",
|
||||
@@ -940,6 +947,10 @@
|
||||
"triggers": {
|
||||
"intro": "Опциональные внешние сигналы: триггер завершения, датчик дверцы, переключатель паузы и напоминание о выгрузке.",
|
||||
"label": "Триггеры и дверцы"
|
||||
},
|
||||
"phase_eta": {
|
||||
"label": "Оставшееся время",
|
||||
"intro": "Оценка оставшегося времени с учётом фаз, для машин, длительность цикла которых зависит от температуры или отжима."
|
||||
}
|
||||
},
|
||||
"setting": {
|
||||
@@ -1004,7 +1015,7 @@
|
||||
"label": "Допуск Оценки"
|
||||
},
|
||||
"enable_ml_models": {
|
||||
"doc": "Пока цикл выполняется, позвольте моделям уточнить результаты в реальном времени: более стабильную оценку оставшегося времени и энергии/затрат, а также защиту от преждевременной остановки при обнаружении окончания (она может только откладывать завершение, никогда не заканчивать его раньше и ограничена). Использует ваши точно настроенные модели, если они доступны, в противном случае — встроенные. Выкл. = только классическая силовая логика (все еще надежная).",
|
||||
"doc": "Пока цикл выполняется, позвольте моделям уточнить результаты в реальном времени: более стабильную оценку оставшегося времени и энергии/затрат, а также защиту от преждевременной остановки при обнаружении окончания (она может только откладывать завершение, никогда не заканчивать его раньше и ограничена). Использует ваши точно настроенные модели, если они доступны, в противном случае – встроенные. Выкл. = только классическая силовая логика (все еще надежная).",
|
||||
"label": "Применять умные модели во время цикла"
|
||||
},
|
||||
"end_energy_threshold": {
|
||||
@@ -1023,6 +1034,10 @@
|
||||
"doc": "Фиксированная цена за кВтч, используемая для расчета себестоимости, если выше не указан объект реальной цены.",
|
||||
"label": "Фиксированная Цена Электроэнергии (за кВт·ч)"
|
||||
},
|
||||
"energy_sensor": {
|
||||
"doc": "Необязательный накопительный счётчик энергии (total_increasing kWh/Wh, например, собственный счётчик суммарного потребления розетки). Если задан, энергия, отображаемая для каждого цикла, берётся из разности показаний этого счётчика между началом и концом, что позволяет избежать занижения, возникающего при интегрировании медленно обновляющегося датчика мощности. Если показание отсутствует, единица измерения неизвестна или разность не положительна, используется интегрированное значение. Оставьте пустым, чтобы продолжать интегрировать датчик мощности.",
|
||||
"label": "Объект Счётчика Энергии"
|
||||
},
|
||||
"expose_debug_entities": {
|
||||
"doc": "Публикуйте дополнительные диагностические объекты высокой доступности (достоверность соответствия, неоднозначность, внутреннее состояние). Выкл. сохраняет список объектов чистым для нормального использования.",
|
||||
"label": "Открыть Отладочные Объекты"
|
||||
@@ -1164,7 +1179,7 @@
|
||||
"label": "Задержка Напоминания о Выгрузке"
|
||||
},
|
||||
"off_delay": {
|
||||
"doc": "Время ожидания после отключения питания, прежде чем объявить цикл завершенным. Если подача электроэнергии возобновится в пределах этого окна, цикл продолжится плавно — это устраняет паузы между этапами стирки. Посудомоечные машины имеют длительные фазы сушки (отключение питания на 20–60 минут), поэтому задержка выключения должна превышать это значение, чтобы вся стирка+сушка выполнялась как один цикл.",
|
||||
"doc": "Время ожидания после отключения питания, прежде чем объявить цикл завершенным. Если подача электроэнергии возобновится в пределах этого окна, цикл продолжится плавно – это устраняет паузы между этапами стирки. Посудомоечные машины имеют длительные фазы сушки (отключение питания на 20–60 минут), поэтому задержка выключения должна превышать это значение, чтобы вся стирка+сушка выполнялась как один цикл.",
|
||||
"label": "Задержка Выключения"
|
||||
},
|
||||
"pause_cuts_power": {
|
||||
@@ -1216,11 +1231,11 @@
|
||||
"label": "Длительность Застревания Насоса"
|
||||
},
|
||||
"running_dead_zone": {
|
||||
"doc": "После начала цикла провалы мощности в этом окне игнорируются. Стиральные машины наполняются холодной водой (перед нагревом ее мощность падает около 0 Вт) — без этой защиты фаза наполнения выглядит как завершение цикла. При этом НЕ происходит пропуск данных: кривая полной мощности записывается от T=0. Механизм подсказок измеряет фактическую схему запуска вашей машины и автоматически определяет ее размер.",
|
||||
"doc": "После начала цикла провалы мощности в этом окне игнорируются. Стиральные машины наполняются холодной водой (перед нагревом ее мощность падает около 0 Вт) – без этой защиты фаза наполнения выглядит как завершение цикла. При этом НЕ происходит пропуск данных: кривая полной мощности записывается от T=0. Механизм подсказок измеряет фактическую схему запуска вашей машины и автоматически определяет ее размер.",
|
||||
"label": "Мёртвая Зона Работы"
|
||||
},
|
||||
"sampling_interval": {
|
||||
"doc": "Ожидаемое время между показаниями датчика — используется для определения размера окна сглаживания и правильного запуска устранения дребезга. Каждое обновление датчика фиксируется независимо от этого значения; он только калибрует последующие вычисления. Механизм подсказок измеряет фактическую частоту вращения педалей вашего датчика на основе прошлых циклов и устанавливает ее автоматически.",
|
||||
"doc": "Ожидаемое время между показаниями датчика – используется для определения размера окна сглаживания и правильного запуска устранения дребезга. Каждое обновление датчика фиксируется независимо от этого значения; он только калибрует последующие вычисления. Механизм подсказок измеряет фактическую частоту вращения педалей вашего датчика на основе прошлых циклов и устанавливает ее автоматически.",
|
||||
"label": "Интервал Выборки"
|
||||
},
|
||||
"save_debug_traces": {
|
||||
@@ -1244,7 +1259,7 @@
|
||||
"label": "Порог Запуска"
|
||||
},
|
||||
"stop_threshold_w": {
|
||||
"doc": "Мощность должна упасть ниже этого уровня, прежде чем начнется обратный отсчет задержки выключения. Установите его ниже Start Threshold — промежуток между ними и есть полоса гистерезиса, предотвращающая мерцание. Если установлено слишком высокое значение, фазы низкой мощности (задержка полоскания, предотвращение сминания) ошибочно запускают последовательность завершения.",
|
||||
"doc": "Мощность должна упасть ниже этого уровня, прежде чем начнется обратный отсчет задержки выключения. Установите его ниже Start Threshold – промежуток между ними и есть полоса гистерезиса, предотвращающая мерцание. Если установлено слишком высокое значение, фазы низкой мощности (задержка полоскания, предотвращение сминания) ошибочно запускают последовательность завершения.",
|
||||
"label": "Порог Остановки"
|
||||
},
|
||||
"switch_entity": {
|
||||
@@ -1305,6 +1320,38 @@
|
||||
},
|
||||
"show_contributor": {
|
||||
"doc": "Показать имя автора на профилях, загруженных из магазина сообщества"
|
||||
},
|
||||
"enable_phase_matching": {
|
||||
"label": "Оставшееся время с учётом фаз",
|
||||
"doc": "Разбивает каждый активный цикл на фазы (нагрев, стирка, отжим) и распределяет оставшееся время по фазам, сочетая это с классической оценкой - опираясь на распределение по фазам в начале цикла и на классическую оценку ближе к концу. Это персонализирует отсчёт под то, сколько на самом деле нагревается и работает ваша машина, что наиболее заметно в первой половине цикла. Выключено = только классическая оценка. Влияет только на отображение оставшегося времени; сопоставление программ и обнаружение цикла остаются без изменений."
|
||||
},
|
||||
"keep_min_score": {
|
||||
"label": "Мин. оценка совпадения",
|
||||
"doc": "Минимальный балл сходства, необходимый кандидату для участия в соревновании по совпадению. Значение по умолчанию 0,1 намеренно мягкое - допускает даже слабых кандидатов и полагается на поздние этапы для нахождения наилучшего совпадения. Повысьте для более раннего отсева маловероятных профилей; понизьте для расширения начального пула кандидатов."
|
||||
},
|
||||
"dtw_blend": {
|
||||
"label": "Смешивание деформации",
|
||||
"doc": "Насколько балл выравнивания DTW заменяет основной балл Этапа 2. 0 = используй только балл Этапа 2, 1 = используй только балл DTW, 0,5 (по умолчанию) = равное смешивание. Повысьте для большей опоры на выравнивание с деформацией, когда программы имеют схожие уровни мощности, но разные временные паттерны."
|
||||
},
|
||||
"dtw_ensemble_w": {
|
||||
"label": "Микс комбинации DTW",
|
||||
"doc": "В режиме ансамбля DTW (по умолчанию), вес масштабированного L1 против производного DTW (DDTW). 1,0 = только масштабированный L1, 0 = только DDTW, 0,7 = по умолчанию. Масштабированный вариант L1 сравнивает уровни мощности; производный вариант реагирует на изменения мощности во времени. Ансамбль объединяет оба."
|
||||
},
|
||||
"dtw_ddtw_scale": {
|
||||
"label": "Масштаб производной деформации",
|
||||
"doc": "Расстояние полунасыщения для оценки производным DTW. Балл уменьшается вдвое, когда расстояние DDTW равно этому значению. Меньше = чувствительнее к различиям формы. Значение по умолчанию 30 откалибровано для типичных кривых мощности бытовых приборов. Влияет только на режимы ensemble и ddtw DTW."
|
||||
},
|
||||
"dtw_refine_top_n": {
|
||||
"label": "Количество уточнённых кандидатов",
|
||||
"doc": "Сколько ведущих кандидатов Этапа 2 DTW переоценивает. DTW дороже, поэтому применяется только к N лучшим кандидатам. По умолчанию 5. Повысьте (до 7-9), если правильный профиль иногда достигает только 4-го или 5-го места после Этапа 2 - DTW может его спасти. Снижение немного ускоряет сопоставление."
|
||||
},
|
||||
"duration_scale": {
|
||||
"label": "Резкость длительности",
|
||||
"doc": "Резкость штрафа за несоответствие длительности на Этапе 4. Это логарифмическое отношение, при котором балл соответствия уменьшается вдвое. Меньше = строже: несоответствие длительности сильнее снижает балл. Значение по умолчанию 0,175 соответствует допуску длительности около 18% при половинном весе. Используйте вместе с Весом длительности."
|
||||
},
|
||||
"energy_scale": {
|
||||
"label": "Резкость энергии",
|
||||
"doc": "Резкость штрафа за несоответствие энергии на Этапе 4. Меньше = строже: несоответствие энергии сильнее снижает балл. Значение по умолчанию 0,25 намеренно мягче, чем Резкость длительности, поскольку энергия варьируется с нагрузкой. Используйте вместе с Весом энергии."
|
||||
}
|
||||
},
|
||||
"setting_group": {
|
||||
@@ -1553,24 +1600,24 @@
|
||||
"lower": "Автоматически маркирует больше циклов; некоторые могут быть определены неверно"
|
||||
},
|
||||
"duration_tolerance": {
|
||||
"higher": "Принимает более широкий диапазон длительности — более гибкое сопоставление",
|
||||
"lower": "Требует более точного совпадения длительности — строже, но может отклонить необычные циклы"
|
||||
"higher": "Принимает более широкий диапазон длительности – более гибкое сопоставление",
|
||||
"lower": "Требует более точного совпадения длительности – строже, но может отклонить необычные циклы"
|
||||
},
|
||||
"end_energy_threshold": {
|
||||
"higher": "Закрывает только циклы, использовавшие значительное количество энергии",
|
||||
"lower": "Закрывает и короткие или маломощные циклы"
|
||||
},
|
||||
"end_repeat_count": {
|
||||
"higher": "Требует повторения сигнала завершения больше раз — надёжнее, немного медленнее",
|
||||
"lower": "Завершает после меньшего числа повторений — быстрее, выше риск ложного завершения"
|
||||
"higher": "Требует повторения сигнала завершения больше раз – надёжнее, немного медленнее",
|
||||
"lower": "Завершает после меньшего числа повторений – быстрее, выше риск ложного завершения"
|
||||
},
|
||||
"learning_confidence": {
|
||||
"higher": "Учится только на очень уверенных совпадениях — медленнее, но надёжнее",
|
||||
"higher": "Учится только на очень уверенных совпадениях – медленнее, но надёжнее",
|
||||
"lower": "Учится на большем числе циклов; модель может быть более шумной"
|
||||
},
|
||||
"min_off_gap": {
|
||||
"higher": "Перед новым циклом требуется более длительный простой",
|
||||
"lower": "Короткий простой запускает новый цикл — последовательные запуски могут разделиться"
|
||||
"lower": "Короткий простой запускает новый цикл – последовательные запуски могут разделиться"
|
||||
},
|
||||
"min_power": {
|
||||
"higher": "Менее чувствителен к фоновому потреблению; может пропустить тихие программы",
|
||||
@@ -1581,24 +1628,24 @@
|
||||
"lower": "Принудительно останавливает зависший цикл быстрее"
|
||||
},
|
||||
"off_delay": {
|
||||
"higher": "Больше времени для пауз устройства — справляется с длительным замачиванием или сушкой",
|
||||
"lower": "Более быстрое определение конца — подходит для устройств с чётким вкл./выкл."
|
||||
"higher": "Больше времени для пауз устройства – справляется с длительным замачиванием или сушкой",
|
||||
"lower": "Более быстрое определение конца – подходит для устройств с чётким вкл./выкл."
|
||||
},
|
||||
"profile_match_threshold": {
|
||||
"higher": "Подтверждает только высокоуверенные совпадения; больше циклов остаётся без метки",
|
||||
"lower": "Сопоставляет больше циклов; некоторые могут быть немного неверны"
|
||||
},
|
||||
"running_dead_zone": {
|
||||
"higher": "Игнорирует кратковременные скачки мощности в простое — менее чувствителен к шуму",
|
||||
"lower": "Реагирует на более короткие всплески мощности — улавливает быструю переходную активность"
|
||||
"higher": "Игнорирует кратковременные скачки мощности в простое – менее чувствителен к шуму",
|
||||
"lower": "Реагирует на более короткие всплески мощности – улавливает быструю переходную активность"
|
||||
},
|
||||
"start_threshold_w": {
|
||||
"higher": "Исключает ложные запуски от кратковременных скачков мощности",
|
||||
"lower": "Улавливает маломощные программы; может сработать на шум"
|
||||
},
|
||||
"stop_threshold_w": {
|
||||
"higher": "Завершает цикл быстрее — может закрыть во время паузы",
|
||||
"lower": "Дольше ждёт завершения — меньше преждевременных завершений"
|
||||
"higher": "Завершает цикл быстрее – может закрыть во время паузы",
|
||||
"lower": "Дольше ждёт завершения – меньше преждевременных завершений"
|
||||
},
|
||||
"watchdog_interval": {
|
||||
"higher": "Допускает более длительные тихие фазы; меньше ложных принудительных остановок",
|
||||
@@ -1676,12 +1723,19 @@
|
||||
"start_duration_threshold": "Секунды выше порога для подтверждения старта",
|
||||
"start_threshold_w": "Минимум ватт, чтобы считать запущенным",
|
||||
"stop_threshold_w": "Ниже этого машина считается выключенной",
|
||||
"dtw_bandwidth": "Насколько сильное растяжение по времени допускает сопоставление по форме",
|
||||
"corr_weight": "Вес формы кривой относительно уровня мощности при сопоставлении",
|
||||
"duration_weight": "Насколько совпадение по длительности влияет на сопоставление",
|
||||
"energy_weight": "Насколько совпадение по энергии влияет на сопоставление",
|
||||
"profile_match_min_duration_ratio": "Кратчайший запуск (относительно профиля), который ещё может совпасть",
|
||||
"profile_match_max_duration_ratio": "Самый длинный запуск (относительно профиля), который ещё может совпасть"
|
||||
"dtw_bandwidth": "Этап 3: полоса деформации Sakoe-Chiba (0 = DTW выключен; по умолчанию 0,2 = 20% длины цикла)",
|
||||
"corr_weight": "Этап 2: баланс между формой кривой (корреляция) и уровнем мощности (MAE); по умолчанию 0,45",
|
||||
"duration_weight": "Этап 4: насколько сильно совпадение по длительности влияет на итоговый балл (по умолчанию 0,22)",
|
||||
"energy_weight": "Этап 4: насколько сильно совпадение по энергии влияет на итоговый балл (по умолчанию 0,22)",
|
||||
"profile_match_min_duration_ratio": "Этап 1: минимальная длина цикла как доля длительности профиля; по умолчанию 0,1 (10%)",
|
||||
"profile_match_max_duration_ratio": "Этап 1: максимальная длина цикла как доля длительности профиля; по умолчанию 1,5 (150%)",
|
||||
"keep_min_score": "Этап 2: минимальный балл для участия в соревновании; по умолчанию 0,1 допускает слабые совпадения, поздние этапы выбирают лучшее",
|
||||
"dtw_blend": "Этап 3: 0 = только основной балл, 1 = только балл DTW, 0,5 = равное смешивание (по умолчанию)",
|
||||
"dtw_ensemble_w": "Этап 3 (режим ансамбля): вес масштабированного L1 против производного DTW; по умолчанию 0,7 отдаёт предпочтение уровню",
|
||||
"dtw_ddtw_scale": "Этап 3: расстояние полунасыщения DDTW; меньше = чувствительнее к форме (по умолчанию 30)",
|
||||
"dtw_refine_top_n": "Этап 3: кандидаты, переоцениваемые DTW; повысьте до 7-9, если правильный профиль занимает 4-5 место (по умолчанию 5)",
|
||||
"duration_scale": "Этап 4: логарифмическое отношение, при котором совпадение по длительности уменьшается вдвое; меньше = более строгий штраф (по умолчанию 0,175)",
|
||||
"energy_scale": "Этап 4: логарифмическое отношение, при котором совпадение по энергии уменьшается вдвое; меньше = более строгий штраф (по умолчанию 0,25)"
|
||||
},
|
||||
"col": {
|
||||
"profile_tip": "Название сопоставленной программы. «Без метки» означает, что в конце цикла не совпал ни один профиль.",
|
||||
@@ -1766,6 +1820,69 @@
|
||||
},
|
||||
"pg_sweep": {
|
||||
"optimize": "Оптимизация: {param}"
|
||||
},
|
||||
"pg_detail": {
|
||||
"simulate": "Смоделировать цикл"
|
||||
},
|
||||
"split": {
|
||||
"apply": "Разделение цикла"
|
||||
},
|
||||
"trim": {
|
||||
"apply": "Обрезка цикла"
|
||||
},
|
||||
"merge": {
|
||||
"apply": "Объединение циклов"
|
||||
},
|
||||
"rebuild": {
|
||||
"envelopes": "Пересчёт огибающих"
|
||||
},
|
||||
"cancelling": "Отмена..."
|
||||
},
|
||||
"setup": {
|
||||
"hdr": {
|
||||
"card": "Настройка устройства",
|
||||
"healthy_chip": "Настройка завершена"
|
||||
},
|
||||
"phase0": {
|
||||
"washer": "WashData уже обнаруживает ваши циклы. Запишите первый цикл, чтобы включить названия программ и оценки времени.",
|
||||
"dishwasher": "WashData наблюдает. Посудомоечные машины имеют сложные циклы – запись первого цикла настоятельно рекомендуется. Если обнаруженный цикл длится слишком долго, обрежьте его в редакторе циклов перед сохранением как профиль.",
|
||||
"generic": "WashData наблюдает. Запишите или пометьте обнаруженный цикл, чтобы начать создавать профили."
|
||||
},
|
||||
"phase1a": {
|
||||
"labelled": "Хорошее начало – ваша первая программа сохранена. Для наиболее чистых данных рассмотрите запись следующего цикла с помощью виджета записи."
|
||||
},
|
||||
"phase1b": {
|
||||
"recorded": "Ваша запись сохранена как {profile_name}. Теперь запишите или пометьте другие распространённые программы для расширения охвата."
|
||||
},
|
||||
"phase1c": {
|
||||
"verify": "У вас {count} программ от сообщества. Запустите цикл, чтобы убедиться, что WashData правильно их распознаёт – сопоставление будет улучшаться по мере того, как устройство накапливает собственную историю."
|
||||
},
|
||||
"phase2": {
|
||||
"cluster": "WashData обнаружил {count} циклов, которые не соответствуют ни одной сохранённой программе – они похожи друг на друга. Создать для них новый профиль?",
|
||||
"unmatched": "Ваш последний цикл не совпал ни с одной сохранённой программой. Это новая программа?"
|
||||
},
|
||||
"phase3": {
|
||||
"suggestions": "WashData имеет рекомендации по настройкам на основе истории ваших циклов – просмотрите их для повышения точности обнаружения.",
|
||||
"groups": "Некоторые ваши профили похожи на одну и ту же программу при разных температурах. Объедините их в группу для улучшения сопоставления.",
|
||||
"phases": "Добавьте фазы программы к {profile_name} для более точных оценок оставшегося времени."
|
||||
},
|
||||
"phase4": {
|
||||
"healthy": "Это устройство полностью настроено ({profile_count} профилей)."
|
||||
},
|
||||
"cta": {
|
||||
"start_recording": "Начать запись",
|
||||
"label_detected_cycle": "У меня уже есть обнаруженный цикл – пометить его вместо записи",
|
||||
"browse_cycles": "Просматривать циклы для пометки следующего",
|
||||
"view_profiles": "Просмотреть свои профили",
|
||||
"create_from_cluster": "Создать профиль из этих циклов",
|
||||
"create_profile": "Создать для него профиль",
|
||||
"review_suggestions": "Просмотреть предложения",
|
||||
"organise_profiles": "Упорядочить профили",
|
||||
"configure_phases": "Настроить фазы",
|
||||
"skip_step": "Пропустить этот шаг",
|
||||
"skip_forever": "Больше не показывать",
|
||||
"hide_guidance": "Скрыть подсказки",
|
||||
"show_guidance": "Показать подсказки"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
{
|
||||
"badge": {
|
||||
"artifact_tip": "Zistilo sa {n} anomálií (napr. dvere otvorené uprostred cyklu) — otvorte ich, aby ste ich videli na grafe",
|
||||
"artifact_tip": "Zistilo sa {n} anomálií (napr. dvere otvorené uprostred cyklu) – otvorte ich, aby ste ich videli na grafe",
|
||||
"auto": "(automaticky zistené)",
|
||||
"built_in_tag": "vstavaný",
|
||||
"declining": "↘ klesajúci",
|
||||
"energy_low": "Nižšia spotreba energie ako zvyčajne",
|
||||
"energy_spike": "Vyššia spotreba energie ako zvyčajne",
|
||||
"fair_fit": "prijateľná kvalita",
|
||||
"fair_fit_tip": "Stredná konzistencia zhody — niektoré cykly priradené k tomuto profilu majú nižšie skóre spoľahlivosti. Označte viac cyklov alebo znova nahrajte profil, aby ste zlepšili presnosť.",
|
||||
"fair_fit_tip": "Stredná konzistencia zhody – niektoré cykly priradené k tomuto profilu majú nižšie skóre spoľahlivosti. Označte viac cyklov alebo znova nahrajte profil, aby ste zlepšili presnosť.",
|
||||
"feedback_requested": "Vyžiadaná spätná väzba",
|
||||
"golden_cycle": "Zaznamenaný referenčný cyklus",
|
||||
"improving": "↗ zlepšujúci sa",
|
||||
@@ -15,7 +15,7 @@
|
||||
"needs_review": "Vyžaduje preskúmanie",
|
||||
"overrun": "Trvalo dlhšie ako zvyčajne",
|
||||
"poor_fit": "zlá kvalita",
|
||||
"poor_fit_tip": "Nekonzistentná história zhôd — zvážte prestavbu tohto profilu",
|
||||
"poor_fit_tip": "Nekonzistentná história zhôd – zvážte prestavbu tohto profilu",
|
||||
"restart_gap_tip": "{n} medzera reštartu HA: priebeh výkonu má dieru",
|
||||
"reviewed": "Skontrolované",
|
||||
"steady": "→ stabilný",
|
||||
@@ -57,7 +57,7 @@
|
||||
"create_profile": "+ Vytvoriť profil",
|
||||
"delete": "Odstrániť",
|
||||
"delete_group": "Odstrániť skupinu",
|
||||
"delete_group_tip": "Odstrániť iba túto skupinu — profily členov sa zachovajú",
|
||||
"delete_group_tip": "Odstrániť iba túto skupinu – profily členov sa zachovajú",
|
||||
"delete_profile": "Odstrániť profil",
|
||||
"discard": "Zahodiť",
|
||||
"discard_tip": "Zahodiť zaznamenaný priebeh bez uloženia",
|
||||
@@ -87,7 +87,7 @@
|
||||
"on_cycle_finished": "Po dokončení cyklu",
|
||||
"on_cycle_started": "Pri spustení cyklu",
|
||||
"pause_cycle": "Pozastaviť",
|
||||
"pause_cycle_tip": "Pozastaviť bežiaci cyklus — spotrebič pokračuje tam, kde prestal",
|
||||
"pause_cycle_tip": "Pozastaviť bežiaci cyklus – spotrebič pokračuje tam, kde prestal",
|
||||
"pg_apply_device": "Použiť na zariadenie",
|
||||
"pg_autofill": "Automaticky vyplniť",
|
||||
"play": "Prehrať",
|
||||
@@ -97,8 +97,8 @@
|
||||
"process_tip": "Uložiť zaznamenaný priebeh ako nový alebo existujúci profil",
|
||||
"rebuild": "Prebudovať obálky",
|
||||
"rebuild_envelope": "Prebudovať obálku",
|
||||
"rebuild_tip": "Prepočítať očakávanú výkonovú obálku (pásmo min/max) pre všetky profily z ich označených cyklov — spustiť po označení nových cyklov alebo oprave starých",
|
||||
"rec_start_tip": "Začať nahrávanie priebehu výkonu spotrebiča — spustiť tesne pred začatím cyklu",
|
||||
"rebuild_tip": "Prepočítať očakávanú výkonovú obálku (pásmo min/max) pre všetky profily z ich označených cyklov – spustiť po označení nových cyklov alebo oprave starých",
|
||||
"rec_start_tip": "Začať nahrávanie priebehu výkonu spotrebiča – spustiť tesne pred začatím cyklu",
|
||||
"rec_stop": "Zastaviť",
|
||||
"rec_stop_tip": "Zastaviť nahrávanie a podržať zachytený priebeh na kontrolu",
|
||||
"record": "Začať nahrávanie",
|
||||
@@ -231,7 +231,7 @@
|
||||
"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": "{n} konflikt{s} nastavení – skontrolujte zvýraznené sekcie a opravte pred uložením.",
|
||||
"settings_banner_btn": "Prejsť na prvý"
|
||||
},
|
||||
"hdr": {
|
||||
@@ -451,9 +451,9 @@
|
||||
"show_expected": "Zobraziť očakávanú krivku (zhodný profil, oranžový)",
|
||||
"show_raw": "Zobraziť prepínač surových dát zásuvky v živom grafe výkonu",
|
||||
"sparkline": "Nedávny trend trvania cyklov",
|
||||
"stage2": "Etapa 2 — základná podobnosť",
|
||||
"stage3": "Etapa 3 — DTW",
|
||||
"stage4": "Etapa 4 — zhoda",
|
||||
"stage2": "Etapa 2 – základná podobnosť",
|
||||
"stage3": "Etapa 3 – DTW",
|
||||
"stage4": "Etapa 4 – zhoda",
|
||||
"status": "Stav",
|
||||
"tail_trim": "Orezanie konca (s)",
|
||||
"timer_auto_pause": "Automatické pozastavenie",
|
||||
@@ -561,7 +561,12 @@
|
||||
"flags": "Príznaky",
|
||||
"include_phase_map": "Zahrnúť mapu fáz",
|
||||
"include_settings": "Zahrnúť nastavenia",
|
||||
"show_contributor": "Zobraziť prispievateľa"
|
||||
"show_contributor": "Zobraziť prispievateľa",
|
||||
"task_pg_detail": "Simulovať cyklus",
|
||||
"task_split": "Rozdeľovanie cyklu",
|
||||
"task_trim": "Orezávanie cyklu",
|
||||
"task_merge": "Zlučovanie cyklov",
|
||||
"task_rebuild": "Prepočítavanie obálok"
|
||||
},
|
||||
"log": {
|
||||
"all_levels": "Všetky úrovne",
|
||||
@@ -645,7 +650,7 @@
|
||||
"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.",
|
||||
"artifact_header": "Počet anomálií zistených počas tohto cyklu: {n}",
|
||||
"artifact_pause_detail": "Výkon poklesol takmer na nulu počas ~{n} s a potom sa obnovil — pravdepodobne boli otvorené dvere uprostred cyklu alebo bol cyklus pozastavený.",
|
||||
"artifact_pause_detail": "Výkon poklesol takmer na nulu počas ~{n} s a potom sa obnovil – pravdepodobne boli otvorené dvere uprostred cyklu alebo bol cyklus pozastavený.",
|
||||
"artifact_spike_detail": "Bol nad bežným pásmom výkonu počas ~{n} s.",
|
||||
"auto_label_intro": "Priradiť profily neoznačeným cyklom, ktorých zhoda prekračuje prah.",
|
||||
"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.",
|
||||
@@ -654,10 +659,10 @@
|
||||
"collecting_data": "Zbieranie dát: ešte {need} cyklov do spustenia doladenia ({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ť",
|
||||
"compare_selected_cycles": "Vybraté cykly (tučné) – zobraziť / skryť",
|
||||
"consider_new_profile": "Zvážte vytvorenie nového profilu.",
|
||||
"coverage_gap": "nedávne cykly nemajú žiadny zodpovedajúci profil ({pct} % z posledných 30).",
|
||||
"coverage_gap_similar_cycles": "Nájdených {count} podobných neoznačených cyklov — vytvorte profil, aby sa začali párovať.",
|
||||
"coverage_gap_similar_cycles": "Nájdených {count} podobných neoznačených cyklov – vytvorte profil, aby sa začali párovať.",
|
||||
"cycles_deleted": "Odstránených cyklov: {count}",
|
||||
"enough_data": "Dostatok dát na učenie ({current}/{min} cyklov).",
|
||||
"export_description": "Exportujte všetky profily a cykly do JSON alebo obnovte z predchádzajúceho exportu.",
|
||||
@@ -686,7 +691,7 @@
|
||||
"ml_learned_intro": "Modely doladené pre tento stroj.",
|
||||
"ml_loading": "načítava sa ML…",
|
||||
"ml_settings_intro": "Dva nezávislé prepínače: jeden používa modely počas behu cyklu, druhý umožňuje WashData časom ich doladiť na váš stroj.",
|
||||
"name_first_program": "Máte dostatok cyklov — pomenujte svoj prvý program a spustite priraďovanie.",
|
||||
"name_first_program": "Máte dostatok cyklov – pomenujte svoj prvý program a spustite priraďovanie.",
|
||||
"near_duplicate_cluster": "zistený takmer duplicitný klaster profilov. Zoskupenie umožňuje zhodu spoľahlivo vybrať medzi podobnými (napr. rovnaký program pri inej teplote/odstreďovaní).",
|
||||
"no_cycles_match": "Žiadne cykly nezodpovedajú aktuálnemu filtru.",
|
||||
"no_cycles_profile": "Pre tento profil nie sú žiadne cykly.",
|
||||
@@ -694,12 +699,12 @@
|
||||
"no_cycles_yet": "Zatiaľ neboli zaznamenané žiadne cykly.",
|
||||
"no_device_selected": "Nebolo vybrané žiadne zariadenie.",
|
||||
"no_devices": "Zatiaľ nie sú nakonfigurované žiadne zariadenia WashData.",
|
||||
"no_envelope": "Zatiaľ žiadna obálka — prebudujte po označení cyklov.",
|
||||
"no_envelope": "Zatiaľ žiadna obálka – prebudujte po označení cyklov.",
|
||||
"no_envelope_overlay": "Žiadna obálka dostupná na prekrytie.",
|
||||
"no_fine_tuned": "Zatiaľ nič nedoladené — WashData používa vstavané modely.",
|
||||
"no_fine_tuned": "Zatiaľ nič nedoladené – WashData používa vstavané modely.",
|
||||
"no_logs": "Zatiaľ nie sú uložené žiadne záznamy.",
|
||||
"no_maintenance": "Zatiaľ nebola zaznamenaná žiadna údržba.",
|
||||
"no_match_yet": "Zatiaľ žiadny pokus o zhodu — zobrazí sa počas bežiaceho cyklu.",
|
||||
"no_match_yet": "Zatiaľ žiadny pokus o zhodu – zobrazí sa počas bežiaceho cyklu.",
|
||||
"no_other_users": "Neboli nájdení žiadni iní používatelia Home Assistant.",
|
||||
"no_phases": "Nie sú definované žiadne fázy.",
|
||||
"no_phases_assigned": "Nie sú priradené žiadne fázy.",
|
||||
@@ -713,7 +718,7 @@
|
||||
"notify_services_hint": "Použite ID služieb {entity} (oddelené čiarkami pre viacero). Premenné šablóny: {vars}.",
|
||||
"old_actions_warning": "Nakonfigurované pomocou starého editora akcií (teraz odstránený). Stále sa spúšťajú pri udalostiach cyklu, ale už ich tu nemožno upravovať. Premeňte ich na normálnu automatizáciu alebo ich odstráňte.",
|
||||
"onboarding_progress": "Pozorovaných cyklov: {n} / 3",
|
||||
"onboarding_watching": "Používajte spotrebič bežne — WashData sleduje. Po 3 cykloch sa spustí priraďovanie programov.",
|
||||
"onboarding_watching": "Používajte spotrebič bežne – WashData sleduje. Po 3 cykloch sa spustí priraďovanie programov.",
|
||||
"pending_feedback": "Čaká sa na spätnú väzbu k detekcii",
|
||||
"performance_trend": "Trend výkonnosti ({n} cyklov)",
|
||||
"pg_analysis_empty": "Načítajte cyklus na zobrazenie analýzy zhody.",
|
||||
@@ -748,13 +753,13 @@
|
||||
"restart_gap_footer": "Zvýraznené v grafe. Údaje o výkone chýbajú pre tieto intervaly; párovanie použilo iba skutočné merania.",
|
||||
"restart_gap_header": "{n} medzera reštartu HA počas tohto cyklu",
|
||||
"restart_gap_item": "{dur} medzera",
|
||||
"review_confirm_help": "Potvrďte, či bol tento cyklus rozpoznaný správne. Vaše recenzie trénujú model na vašom stroji — čím viac cyklov potvrdíte, tým lepšie bude porovnávanie a hodnotenie zdravia. Stačí rýchle dobré/zlé.",
|
||||
"review_confirm_help": "Potvrďte, či bol tento cyklus rozpoznaný správne. Vaše recenzie trénujú model na vašom stroji – čím viac cyklov potvrdíte, tým lepšie bude porovnávanie a hodnotenie zdravia. Stačí rýchle dobré/zlé.",
|
||||
"review_in_settings": "Skontrolovať v nastaveniach",
|
||||
"review_notes_placeholder": "Poznámky (voliteľné)",
|
||||
"review_notes_tip": "Poznámky s voľným textom pre vašu vlastnú potrebu. Nepoužíva sa priraďovaním alebo tréningom.",
|
||||
"review_profile_tip": "Program, pod ktorým je tento cyklus označený. Ak bol automaticky zistený program nesprávny, opravte ho tu — označovanie učí párovanie pre budúce cykly.",
|
||||
"review_profile_tip": "Program, pod ktorým je tento cyklus označený. Ak bol automaticky zistený program nesprávny, opravte ho tu – označovanie učí párovanie pre budúce cykly.",
|
||||
"review_quality_tip": "Aký čistý je tento cyklus. Dobrý = učebnicový príklad tohto programu; Zlý = detekovaný, ale hlučný alebo atypický; Nepoužiteľný = nesprávne zistený (zlúčený, skrátený alebo falošný). Riadi skóre zdravia a ktoré cykly sú povolené na trénovanie modelu.",
|
||||
"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_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",
|
||||
"saving_triggers_reload": "Uloženie spustí opätovné načítanie integrácie. Entity HA sa môžu nakrátko zobraziť ako nedostupné.",
|
||||
@@ -763,7 +768,7 @@
|
||||
"setting_changed": "Zmenené z {old} na {new} dňa {date}",
|
||||
"settings_basic_note": "Zobrazujú sa základné nastavenia. Prepnite na Rozšírené pre úplný zoznam.",
|
||||
"shape_drift_advisory": "⚠ Posun tvaru",
|
||||
"shape_drift_detail": "Vzor výkonu tohto profilu sa časom zmenil — možné opotrebenie spotrebiča alebo potreba údržby (napr. odstraňovanie vodného kameňa, čistenie filtra).",
|
||||
"shape_drift_detail": "Vzor výkonu tohto profilu sa časom zmenil – možné opotrebenie spotrebiča alebo potreba údržby (napr. odstraňovanie vodného kameňa, čistenie filtra).",
|
||||
"show_all_settings": "Zobraziť všetky nastavenia",
|
||||
"showing_suggestions": "Zobrazuje sa nastavenie {count} s návrhmi.",
|
||||
"split_intro": "Kliknite na graf a pridajte alebo odstráňte bod rozdelenia, alebo automaticky zistite nečinné medzery. Každý výsledný segment môže mať vlastný profil.",
|
||||
@@ -789,10 +794,10 @@
|
||||
"toast_revert_failed": "Vrátenie zmien zlyhalo: {error}",
|
||||
"toast_reverted": "{key} vrátené späť",
|
||||
"toast_save_failed": "Uloženie zlyhalo: {error}",
|
||||
"trend_duration_longer": "Trvanie je dlhšie trendy ({pct} %/cyklus) — posledný priemer {avg}",
|
||||
"trend_duration_shorter": "Trvanie je kratšie ({pct} %/cyklus) — posledný priemer {avg}",
|
||||
"trend_duration_longer": "Trvanie je dlhšie trendy ({pct} %/cyklus) – posledný priemer {avg}",
|
||||
"trend_duration_shorter": "Trvanie je kratšie ({pct} %/cyklus) – posledný priemer {avg}",
|
||||
"trend_energy_down": "Energetický trend klesá ({pct} %/cyklus)",
|
||||
"trend_energy_up": "Energetický trend stúpa ({pct} %/cyklus) — posledný priemer {avg}",
|
||||
"trend_energy_up": "Energetický trend stúpa ({pct} %/cyklus) – posledný priemer {avg}",
|
||||
"trim_intro": "Potiahnite červené rukoväti alebo zadajte hodnoty. Všetko mimo okna sa odstráni.",
|
||||
"tuning_suggestions_available": "{count} návrh ladenia dostupný z pozorovaných cyklov. Zobrazujú sa vedľa príslušných polí.",
|
||||
"unsure_detected_prefix": "WashData si nie je istý, či zistil",
|
||||
@@ -857,7 +862,9 @@
|
||||
"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í"
|
||||
"share_profile_no_cycles": "Profil '{p}' nemá žiadne ⭐ referenčné cykly -- bude preskočený, ak nemáte {n}+ potvrdených spustení",
|
||||
"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"
|
||||
},
|
||||
"phase_desc": {
|
||||
"anti_crease": "Príležitostné krátke vírenia po dokončení na predchádzanie krčeniu oblečenia.",
|
||||
@@ -940,6 +947,10 @@
|
||||
"triggers": {
|
||||
"intro": "Voliteľné externé signály: spúšť ukončenia, senzor dverí, prepínač pauzy a pripomienka vyloženia.",
|
||||
"label": "Spúšte a dvere"
|
||||
},
|
||||
"phase_eta": {
|
||||
"label": "Zostávajúci čas",
|
||||
"intro": "Zostávajúci čas zohľadňujúci fázy, pre spotrebiče, ktorých dĺžka cyklu závisí od teploty alebo odstreďovania."
|
||||
}
|
||||
},
|
||||
"setting": {
|
||||
@@ -1023,6 +1034,10 @@
|
||||
"doc": "Pevná cena za kWh použitá pre číselné údaje o nákladoch, keď vyššie nie je nastavená žiadna aktuálna cena.",
|
||||
"label": "Statická cena energie (za kWh)"
|
||||
},
|
||||
"energy_sensor": {
|
||||
"doc": "Voliteľné kumulatívne počítadlo energie (total_increasing kWh/Wh, napr. vlastný celoživotný merač zásuvky). Keď je nastavené, energia hlásená za každý cyklus sa odvodzuje z rozdielu tohto počítadla medzi začiatkom a koncom, čo zabraňuje podhodnoteniu, ktoré vzniká integráciou pomaly hlásiaceho senzora výkonu. Vráti sa k integrovanej hodnote, ak údaj chýba, jeho jednotka je neznáma alebo rozdiel nie je kladný. Nechajte prázdne, ak chcete naďalej integrovať senzor výkonu.",
|
||||
"label": "Entita merača energie"
|
||||
},
|
||||
"expose_debug_entities": {
|
||||
"doc": "Zverejniť ďalšie diagnostické entity HA (dôvera v zhodu, nejednoznačnosť, vnútorné údaje). Vypnuté udržiava zoznam entít čistý na bežné použitie.",
|
||||
"label": "Zobraziť ladiace entity"
|
||||
@@ -1305,6 +1320,38 @@
|
||||
},
|
||||
"show_contributor": {
|
||||
"doc": "Zobraziť meno prispievateľa pri profiloch stiahnutých z obchodu komunity"
|
||||
},
|
||||
"enable_phase_matching": {
|
||||
"label": "Zostávajúci čas zohľadňujúci fázy",
|
||||
"doc": "Rozdelí každý bežiaci cyklus do fáz (ohrev, pranie, odstreďovanie) a rozpočíta zostávajúci čas na jednotlivé fázy, zmiešaný s klasickým odhadom - na začiatku cyklu sa opiera o rozpočet fáz a ku koncu o klasický odhad. Prispôsobí odpočet tomu, ako dlho sa váš spotrebič skutočne ohrieva a beží, čo je najviac badateľné v prvej polovici cyklu. Vypnuté = iba klasický odhad. Ovplyvnené je len zobrazenie zostávajúceho času; zhoda programov a detekcia cyklu sa nemenia."
|
||||
},
|
||||
"keep_min_score": {
|
||||
"label": "Min. skóre zhody",
|
||||
"doc": "Minimálne skóre podobnosti, ktoré musí mať kandidát, aby zostal v závode o zhodu. Predvolená hodnota 0,1 je zámerne benevolentná - pripúšťa aj slabých kandidátov a spolieha sa na neskoršie fázy pri výbere najlepšej zhody. Zvýšte ju pre skoršie vyradenie nepravdepodobných profilov; znížte ju pre rozšírenie počiatočnej skupiny kandidátov."
|
||||
},
|
||||
"dtw_blend": {
|
||||
"label": "Miešanie deformácie",
|
||||
"doc": "Ako veľmi skóre zarovnania DTW nahrádza základné skóre Fázy 2. 0 = použite iba skóre Fázy 2, 1 = použite iba skóre DTW, 0,5 (predvolené) = rovnaké miešanie. Zvýšte, ak chcete viac spoliehať na zarovnanie, keď majú programy podobné úrovne výkonu, ale rôzne časové vzory."
|
||||
},
|
||||
"dtw_ensemble_w": {
|
||||
"label": "Mix kombinácie DTW",
|
||||
"doc": "V kombinačnom režime DTW (predvolenom) je to váha škálovaného L1 oproti derivátneho DTW (DDTW). 1,0 = iba škálované L1, 0 = iba DDTW, 0,7 = predvolené. Škálovaná varianta L1 porovnáva úrovne výkonu; derivátna varianta reaguje na zmeny výkonu v čase. Kombinácia spája obe."
|
||||
},
|
||||
"dtw_ddtw_scale": {
|
||||
"label": "Škála derivátnej deformácie",
|
||||
"doc": "Vzdialenosť polosaturácie pre hodnotenie derivátnym DTW. Skóre sa zníži na polovicu, keď sa vzdialenosť DDTW rovná tejto hodnote. Menšia = citlivejšia na rozdiely v tvare. Predvolená hodnota 30 je kalibrovaná pre typické priebehy výkonu spotrebičov. Ovplyvňuje iba kombinačný a ddtw režim DTW."
|
||||
},
|
||||
"dtw_refine_top_n": {
|
||||
"label": "Pocet spresnenych kandidátov",
|
||||
"doc": "Koľko najlepších kandidátov z Fázy 2 je prehodnotených DTW. DTW je nákladnejší, takže sa používa iba pre N najlepších kandidátov. Predvolených 5. Zvýšte (na 7-9), ak správny profil po Fáze 2 niekedy dosiahne iba 4. alebo 5. miesto - DTW ho môže zachrániť. Zníženie mierne urýchli porovnávanie."
|
||||
},
|
||||
"duration_scale": {
|
||||
"label": "Ostrost doby trvania",
|
||||
"doc": "Ostrosť penalizácie za nezhodu dĺžky trvania vo Fáze 4. Je to logaritmický pomer, pri ktorom sa skóre zhody zníži na polovicu. Menší = prísnejší: nezhoda dĺžky trvania viac znižuje skóre. Predvolená hodnota 0,175 zodpovedá približne 18% tolerancii dĺžky trvania pri polovičnej váhe. Kombinujte s Váhou dĺžky trvania."
|
||||
},
|
||||
"energy_scale": {
|
||||
"label": "Ostrost energie",
|
||||
"doc": "Ostrosť penalizácie za nezhodu energie vo Fáze 4. Menší = prísnejší: nezhoda energie viac znižuje skóre. Predvolená hodnota 0,25 je zámerne benevolentnejšia ako Ostrosť dĺžky trvania, pretože energia sa líši podľa záťaže. Kombinujte s Váhou energie."
|
||||
}
|
||||
},
|
||||
"setting_group": {
|
||||
@@ -1424,24 +1471,24 @@
|
||||
"lower": "Viac cyklov je označených automaticky; niektoré môžu byť nesprávne určené"
|
||||
},
|
||||
"duration_tolerance": {
|
||||
"higher": "Akceptuje širší rozsah trvania — flexibilnejšie porovnávanie",
|
||||
"lower": "Vyžaduje bližšiu zhodu trvania — prísnejšie, ale môže odmietnuť nezvyčajné cykly"
|
||||
"higher": "Akceptuje širší rozsah trvania – flexibilnejšie porovnávanie",
|
||||
"lower": "Vyžaduje bližšiu zhodu trvania – prísnejšie, ale môže odmietnuť nezvyčajné cykly"
|
||||
},
|
||||
"end_energy_threshold": {
|
||||
"higher": "Uzatvára iba cykly so značnou spotrebou energie",
|
||||
"lower": "Uzatvára aj kratšie alebo menej energetické cykly"
|
||||
},
|
||||
"end_repeat_count": {
|
||||
"higher": "Vyžaduje viac opakovaní signálu konca — spoľahlivejšie, mierne pomalšie",
|
||||
"lower": "Ukončí po menej opakovaniach — rýchlejšia detekcia, väčšie riziko predčasného ukončenia"
|
||||
"higher": "Vyžaduje viac opakovaní signálu konca – spoľahlivejšie, mierne pomalšie",
|
||||
"lower": "Ukončí po menej opakovaniach – rýchlejšia detekcia, väčšie riziko predčasného ukončenia"
|
||||
},
|
||||
"learning_confidence": {
|
||||
"higher": "Učí sa iba z veľmi istých zhôd — pomalšie, ale spoľahlivejšie",
|
||||
"higher": "Učí sa iba z veľmi istých zhôd – pomalšie, ale spoľahlivejšie",
|
||||
"lower": "Učí sa z viacerých cyklov; model môže byť menej presný"
|
||||
},
|
||||
"min_off_gap": {
|
||||
"higher": "Pred začiatkom nového cyklu je potrebný dlhší pokoj",
|
||||
"lower": "Krátky pokoj spustí nový cyklus — po sebe idúce cykly sa môžu rozdeliť"
|
||||
"lower": "Krátky pokoj spustí nový cyklus – po sebe idúce cykly sa môžu rozdeliť"
|
||||
},
|
||||
"min_power": {
|
||||
"higher": "Menej citlivý na kľudový príkon; môže prehliadnuť veľmi tichý program",
|
||||
@@ -1452,24 +1499,24 @@
|
||||
"lower": "Zaseknutý cyklus je ukončený skôr"
|
||||
},
|
||||
"off_delay": {
|
||||
"higher": "Viac času na prestávky spotrebiča — vhodné pre dlhé fázy namáčania alebo sušenia",
|
||||
"lower": "Rýchlejšia detekcia konca — vhodné pre spotrebiče s čistým zapínaním/vypínaním"
|
||||
"higher": "Viac času na prestávky spotrebiča – vhodné pre dlhé fázy namáčania alebo sušenia",
|
||||
"lower": "Rýchlejšia detekcia konca – vhodné pre spotrebiče s čistým zapínaním/vypínaním"
|
||||
},
|
||||
"profile_match_threshold": {
|
||||
"higher": "Potvrdzuje iba vysoko isté zhody; viac cyklov zostane neoznačených",
|
||||
"lower": "Páruje viac cyklov; niektoré môžu byť mierne nesprávne"
|
||||
},
|
||||
"running_dead_zone": {
|
||||
"higher": "Ignoruje krátke výkonové špičky počas nečinnosti — menej citlivý na rušenie",
|
||||
"lower": "Reaguje na kratšie výkonové impulzy — zachytí rýchlu prechodnú aktivitu"
|
||||
"higher": "Ignoruje krátke výkonové špičky počas nečinnosti – menej citlivý na rušenie",
|
||||
"lower": "Reaguje na kratšie výkonové impulzy – zachytí rýchlu prechodnú aktivitu"
|
||||
},
|
||||
"start_threshold_w": {
|
||||
"higher": "Zabraňuje falošným štartom z krátkych výkonových špiček",
|
||||
"lower": "Zachytí programy s nízkym príkonom; môže reagovať na šum"
|
||||
},
|
||||
"stop_threshold_w": {
|
||||
"higher": "Ukončí cyklus rýchlejšie — môže uzatvoriť počas pauzy",
|
||||
"lower": "Čaká dlhšie na ukončenie — menej predčasných dokončení"
|
||||
"higher": "Ukončí cyklus rýchlejšie – môže uzatvoriť počas pauzy",
|
||||
"lower": "Čaká dlhšie na ukončenie – menej predčasných dokončení"
|
||||
},
|
||||
"watchdog_interval": {
|
||||
"higher": "Umožňuje dlhšie tiché fázy; menej falošných vynútených zastavení",
|
||||
@@ -1676,12 +1723,19 @@
|
||||
"start_duration_threshold": "Sekundy nad prahom na potvrdenie spustenia",
|
||||
"start_threshold_w": "Minimálny výkon vo wattoch na započítanie spustenia",
|
||||
"stop_threshold_w": "Pod touto hodnotou sa stroj počíta ako vypnutý",
|
||||
"dtw_bandwidth": "Aké veľké časové deformácie zhoda tvaru umožňuje",
|
||||
"corr_weight": "Váha tvaru krivky verzus úrovne výkonu pri priraďovaní",
|
||||
"duration_weight": "Ako veľmi zhoda dĺžky trvania ovplyvňuje priradenie",
|
||||
"energy_weight": "Ako veľmi zhoda spotreby energie ovplyvňuje priradenie",
|
||||
"profile_match_min_duration_ratio": "Najkratší beh (oproti profilu), ktorý ešte môže zodpovedať",
|
||||
"profile_match_max_duration_ratio": "Najdlhší beh (oproti profilu), ktorý ešte môže zodpovedať"
|
||||
"dtw_bandwidth": "Fáza 3: deformačné pásmo Sakoe-Chiba (0 = DTW vypnuté; predvolené 0,2 = 20 % dĺžky cyklu)",
|
||||
"corr_weight": "Fáza 2: rovnováha medzi tvarom krivky (korelácia) a úrovňou výkonu (MAE); predvolené 0,45",
|
||||
"duration_weight": "Fáza 4: ako silno zhoda dĺžky trvania ovplyvňuje výsledné skóre (predvolené 0,22)",
|
||||
"energy_weight": "Fáza 4: ako silno zhoda energie ovplyvňuje výsledné skóre (predvolené 0,22)",
|
||||
"profile_match_min_duration_ratio": "Fáza 1: minimálna dĺžka cyklu ako zlomok dĺžky trvania profilu; predvolené 0,1 (10 %)",
|
||||
"profile_match_max_duration_ratio": "Fáza 1: maximálna dĺžka cyklu ako zlomok dĺžky trvania profilu; predvolené 1,5 (150 %)",
|
||||
"keep_min_score": "Fáza 2: minimálne skóre na zostanie v závode; predvolené 0,1 pripúšťa slabé zhody, neskoršie fázy vyberú najlepšie",
|
||||
"dtw_blend": "Fáza 3: 0 = iba základné skóre, 1 = iba skóre DTW, 0,5 = rovnaké miešanie (predvolené)",
|
||||
"dtw_ensemble_w": "Fáza 3 (režim kombinácie): váha škálovaného L1 oproti derivátneho DTW; predvolené 0,7 uprednostňuje úroveň",
|
||||
"dtw_ddtw_scale": "Fáza 3: vzdialenosť polosaturácie DDTW; menšia = citlivejšia na tvar (predvolené 30)",
|
||||
"dtw_refine_top_n": "Fáza 3: kandidáti, ktorých DTW prehodnotí; zvýšte na 7-9, ak správny profil skončí na 4.-5. mieste (predvolené 5)",
|
||||
"duration_scale": "Fáza 4: logaritmický pomer, pri ktorom sa zhoda dĺžky trvania zníži na polovicu; menší = prísnejšia penalizácia (predvolené 0,175)",
|
||||
"energy_scale": "Fáza 4: logaritmický pomer, pri ktorom sa zhoda energie zníži na polovicu; menší = prísnejšia penalizácia (predvolené 0,25)"
|
||||
},
|
||||
"col": {
|
||||
"profile_tip": "Názov zhodného programu. Bez štítku znamená, že na konci cyklu sa nezhodoval žiadny profil.",
|
||||
@@ -1766,6 +1820,69 @@
|
||||
},
|
||||
"pg_sweep": {
|
||||
"optimize": "Optimalizácia: {param}"
|
||||
},
|
||||
"pg_detail": {
|
||||
"simulate": "Simulovať cyklus"
|
||||
},
|
||||
"split": {
|
||||
"apply": "Rozdeľovanie cyklu"
|
||||
},
|
||||
"trim": {
|
||||
"apply": "Orezávanie cyklu"
|
||||
},
|
||||
"merge": {
|
||||
"apply": "Zlučovanie cyklov"
|
||||
},
|
||||
"rebuild": {
|
||||
"envelopes": "Prepočítavanie obálok"
|
||||
},
|
||||
"cancelling": "Ruším..."
|
||||
},
|
||||
"setup": {
|
||||
"hdr": {
|
||||
"card": "Nastavenie zariadenia",
|
||||
"healthy_chip": "Nastavenie dokončené"
|
||||
},
|
||||
"phase0": {
|
||||
"washer": "WashData už deteguje vaše cykly. Nahrajte prvý cyklus, aby ste povolili názvy programov a odhady doby trvania.",
|
||||
"dishwasher": "WashData sleduje. Umývačky riadu majú zložité cykly – nahranie prvého cyklu je dôrazne odporúčané. Ak detegovaný cyklus trvá príliš dlho, orežte ho v editore cyklov pred uložením ako profil.",
|
||||
"generic": "WashData sleduje. Nahrajte alebo označte detegovaný cyklus a začnite vytvárať profily."
|
||||
},
|
||||
"phase1a": {
|
||||
"labelled": "Dobrý začiatok – váš prvý program je uložený. Pre najčistejšie dáta zvážte nahranie ďalšieho cyklu pomocou widgetu nahrávania."
|
||||
},
|
||||
"phase1b": {
|
||||
"recorded": "Vaša nahrávka bola uložená ako {profile_name}. Teraz nahrajte alebo označte ďalšie bežné programy, aby ste rozšírili pokrytie."
|
||||
},
|
||||
"phase1c": {
|
||||
"verify": "Máte {count} programov od komunity. Spustite cyklus, aby ste overili, že ich WashData správne rozoznáva – porovnávanie sa bude zlepšovať, ako zariadenie buduje vlastnú históriu."
|
||||
},
|
||||
"phase2": {
|
||||
"cluster": "WashData zaznamenal {count} cyklov, ktoré nezodpovedajú žiadnemu uloženému programu – navzájom si podobajú. Chcete pre ne vytvoriť nový profil?",
|
||||
"unmatched": "Váš posledný cyklus nezodpovedal žiadnemu uloženému programu. Je to nový program?"
|
||||
},
|
||||
"phase3": {
|
||||
"suggestions": "WashData má odporúčania nastavení na základe vašej histórie cyklov – skontrolujte ich pre zlepšenie presnosti detekcie.",
|
||||
"groups": "Niektoré vaše profily vyzerajú ako rovnaký program pri rôznych teplotách. Usporiadajte ich do skupiny pre lepšie porovnávanie.",
|
||||
"phases": "Pridajte fázy programu k {profile_name} pre presnejšie odhady zostávajúceho času."
|
||||
},
|
||||
"phase4": {
|
||||
"healthy": "Toto zariadenie je plne nastavené ({profile_count} profilov)."
|
||||
},
|
||||
"cta": {
|
||||
"start_recording": "Spustiť nahrávanie",
|
||||
"label_detected_cycle": "Už mám detegovaný cyklus – namiesto toho ho označte",
|
||||
"browse_cycles": "Prechádzať cykly a označiť ďalší",
|
||||
"view_profiles": "Zobraziť vaše profily",
|
||||
"create_from_cluster": "Vytvoriť profil z týchto cyklov",
|
||||
"create_profile": "Vytvoriť preňho profil",
|
||||
"review_suggestions": "Skontrolovať návrhy",
|
||||
"organise_profiles": "Usporiadať profily",
|
||||
"configure_phases": "Nakonfigurovať fázy",
|
||||
"skip_step": "Preskočiť tento krok",
|
||||
"skip_forever": "Nezobrazovať znova",
|
||||
"hide_guidance": "Skryť pokyny",
|
||||
"show_guidance": "Zobraziť pokyny"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
{
|
||||
"badge": {
|
||||
"artifact_tip": "{n} zaznanih nepravilnosti (npr. odprta vrata sredi cikla) — odprite, da jih vidite na grafu",
|
||||
"artifact_tip": "{n} zaznanih nepravilnosti (npr. odprta vrata sredi cikla) – odprite, da jih vidite na grafu",
|
||||
"auto": "(samodejno zaznano)",
|
||||
"built_in_tag": "vgrajeno",
|
||||
"declining": "↘ upada",
|
||||
"energy_low": "Nižja poraba energije kot običajno",
|
||||
"energy_spike": "Višja poraba energije kot običajno",
|
||||
"fair_fit": "sprejemljiva kakovost",
|
||||
"fair_fit_tip": "Zmerna doslednost ujemanja — nekateri cikli, dodeljeni temu profilu, imajo nižje ocene zaupanja. Označite več ciklov ali znova posnemite profil, da izboljšate natančnost.",
|
||||
"fair_fit_tip": "Zmerna doslednost ujemanja – nekateri cikli, dodeljeni temu profilu, imajo nižje ocene zaupanja. Označite več ciklov ali znova posnemite profil, da izboljšate natančnost.",
|
||||
"feedback_requested": "Zahtevane povratne informacije",
|
||||
"golden_cycle": "Posneti referenčni cikel",
|
||||
"improving": "↗ se izboljšuje",
|
||||
@@ -15,7 +15,7 @@
|
||||
"needs_review": "Potrebuje pregled",
|
||||
"overrun": "Trajalo dlje kot običajno",
|
||||
"poor_fit": "slaba kakovost",
|
||||
"poor_fit_tip": "Nedosledna zgodovina ujemanj — razmislite o ponovni izdelavi tega profila",
|
||||
"poor_fit_tip": "Nedosledna zgodovina ujemanj – razmislite o ponovni izdelavi tega profila",
|
||||
"restart_gap_tip": "{n} vrzel ponovnega zagona HA: sled moči ima luknjo",
|
||||
"reviewed": "Pregledano",
|
||||
"steady": "→ stabilno",
|
||||
@@ -57,7 +57,7 @@
|
||||
"create_profile": "+ Ustvari profil",
|
||||
"delete": "Izbriši",
|
||||
"delete_group": "Izbriši skupino",
|
||||
"delete_group_tip": "Izbriši samo to skupino — profili članov se ohranijo",
|
||||
"delete_group_tip": "Izbriši samo to skupino – profili članov se ohranijo",
|
||||
"delete_profile": "Izbriši profil",
|
||||
"discard": "Zavrzi",
|
||||
"discard_tip": "Zavrzi posneto sled brez shranjevanja",
|
||||
@@ -87,7 +87,7 @@
|
||||
"on_cycle_finished": "Ob koncu cikla",
|
||||
"on_cycle_started": "Ob začetku cikla",
|
||||
"pause_cycle": "Premor",
|
||||
"pause_cycle_tip": "Zaustavi delujoči cikel — naprava se bo nadaljevala tam, kjer je ostala",
|
||||
"pause_cycle_tip": "Zaustavi delujoči cikel – naprava se bo nadaljevala tam, kjer je ostala",
|
||||
"pg_apply_device": "Uporabi na napravi",
|
||||
"pg_autofill": "Samodejno izpolni",
|
||||
"play": "Predvajaj",
|
||||
@@ -97,8 +97,8 @@
|
||||
"process_tip": "Shrani posneto sled kot nov ali obstoječ profil",
|
||||
"rebuild": "Obnovi ovojnice",
|
||||
"rebuild_envelope": "Obnovi ovojnico",
|
||||
"rebuild_tip": "Znova izračunaj pričakovano ovojnico moči (min/maks pas) za vse profile iz njihovih označenih ciklov — zaženite po označevanju novih ciklov ali popravljanju starih",
|
||||
"rec_start_tip": "Začni snemanje sledi moči naprave — zaženite tik preden zaženete cikel",
|
||||
"rebuild_tip": "Znova izračunaj pričakovano ovojnico moči (min/maks pas) za vse profile iz njihovih označenih ciklov – zaženite po označevanju novih ciklov ali popravljanju starih",
|
||||
"rec_start_tip": "Začni snemanje sledi moči naprave – zaženite tik preden zaženete cikel",
|
||||
"rec_stop": "Ustavi",
|
||||
"rec_stop_tip": "Ustavi snemanje in obdrži posneto sled za pregled",
|
||||
"record": "Začni snemanje",
|
||||
@@ -231,7 +231,7 @@
|
||||
"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": "{n} konflikt{s} nastavitev – preverite označene razdelke in popravite pred shranjevanjem.",
|
||||
"settings_banner_btn": "Pojdi na prvega"
|
||||
},
|
||||
"hdr": {
|
||||
@@ -451,9 +451,9 @@
|
||||
"show_expected": "Prikaži pričakovano krivuljo (ujemajoči profil, oranžna)",
|
||||
"show_raw": "Prikaži stikalo za surove odčitke vtičnice v živem grafu moči",
|
||||
"sparkline": "Nedavni trend trajanja ciklov",
|
||||
"stage2": "Stopnja 2 — osnovna podobnost",
|
||||
"stage3": "Stopnja 3 — DTW",
|
||||
"stage4": "Stopnja 4 — ujemanje",
|
||||
"stage2": "Stopnja 2 – osnovna podobnost",
|
||||
"stage3": "Stopnja 3 – DTW",
|
||||
"stage4": "Stopnja 4 – ujemanje",
|
||||
"status": "Stanje",
|
||||
"tail_trim": "Obrezovanje konca (s)",
|
||||
"timer_auto_pause": "Samodejna pavza",
|
||||
@@ -561,7 +561,12 @@
|
||||
"flags": "Oznake",
|
||||
"include_phase_map": "Vključi fazno karto",
|
||||
"include_settings": "Vključi nastavitve",
|
||||
"show_contributor": "Prikaži sodelavca"
|
||||
"show_contributor": "Prikaži sodelavca",
|
||||
"task_pg_detail": "Simuliraj cikel",
|
||||
"task_split": "Deljenje cikla",
|
||||
"task_trim": "Obrezovanje cikla",
|
||||
"task_merge": "Združevanje ciklov",
|
||||
"task_rebuild": "Ponovni izračun ovojnic"
|
||||
},
|
||||
"log": {
|
||||
"all_levels": "Vse ravni",
|
||||
@@ -645,7 +650,7 @@
|
||||
"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.",
|
||||
"artifact_header": "{n} nepravilnosti, odkritih v tem ciklu",
|
||||
"artifact_pause_detail": "Moč je padla skoraj na nič za ~{n} s in se nato obnovila — verjetno so bila odprta vrata sredi cikla ali je bil cikel zaustavljen.",
|
||||
"artifact_pause_detail": "Moč je padla skoraj na nič za ~{n} s in se nato obnovila – verjetno so bila odprta vrata sredi cikla ali je bil cikel zaustavljen.",
|
||||
"artifact_spike_detail": "Presegl normalni pas moči za ~{n} s.",
|
||||
"auto_label_intro": "Dodelite profile neoznačenim ciklom, katerih ujemanje presega prag.",
|
||||
"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.",
|
||||
@@ -654,10 +659,10 @@
|
||||
"collecting_data": "Zbiranje podatkov: še {need} ciklov pred začetkom finega nastavljanja ({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",
|
||||
"compare_selected_cycles": "Izbrani cikli (polni) – prikaži / skrij",
|
||||
"consider_new_profile": "Razmislite o ustvarjanju novega profila.",
|
||||
"coverage_gap": "nedavni cikli nimajo ustreznega profila ({pct} % od zadnjih 30).",
|
||||
"coverage_gap_similar_cycles": "Najdenih {count} podobnih neoznačenih ciklov — ustvarite profil za začetek ujemanja.",
|
||||
"coverage_gap_similar_cycles": "Najdenih {count} podobnih neoznačenih ciklov – ustvarite profil za začetek ujemanja.",
|
||||
"cycles_deleted": "Izbrisanih ciklov: {count}",
|
||||
"enough_data": "Dovolj podatkov za učenje ({current}/{min} ciklov).",
|
||||
"export_description": "Izvozite vse profile in cikle v JSON ali obnovite iz prejšnjega izvoza.",
|
||||
@@ -686,7 +691,7 @@
|
||||
"ml_learned_intro": "Modeli natančno prilagojeni tej napravi.",
|
||||
"ml_loading": "nalaganje ML…",
|
||||
"ml_settings_intro": "Dve neodvisni stikali: ena uporablja modele med delovanjem cikla, druga omogoča WashData, da jih sčasoma prilagodi vaši napravi.",
|
||||
"name_first_program": "Imate dovolj ciklov — poimenujte svoj prvi program in začnite z ujemanjem.",
|
||||
"name_first_program": "Imate dovolj ciklov – poimenujte svoj prvi program in začnite z ujemanjem.",
|
||||
"near_duplicate_cluster": "zaznana skoraj podvojena gruča profilov. Združevanje omogoča ujemanje, ki zanesljivo izbira med podobnimi programi (npr. isti program pri različni temperaturi/ožemanju).",
|
||||
"no_cycles_match": "Noben cikel se ne ujema z aktualnim filtrom.",
|
||||
"no_cycles_profile": "Za ta profil ni ciklov.",
|
||||
@@ -694,12 +699,12 @@
|
||||
"no_cycles_yet": "Še ni posnetih ciklov.",
|
||||
"no_device_selected": "Ni izbrane naprave.",
|
||||
"no_devices": "Nobena naprava WashData še ni konfigurirana.",
|
||||
"no_envelope": "Ovojnice še ni — obnovite po označevanju ciklov.",
|
||||
"no_envelope": "Ovojnice še ni – obnovite po označevanju ciklov.",
|
||||
"no_envelope_overlay": "Ni ovojnice za prekrivanje.",
|
||||
"no_fine_tuned": "Še ni natančno prilagojenega — WashData uporablja vgrajene modele.",
|
||||
"no_fine_tuned": "Še ni natančno prilagojenega – WashData uporablja vgrajene modele.",
|
||||
"no_logs": "Še ni pufiranih zapisov dnevnika.",
|
||||
"no_maintenance": "Vzdrževanje še ni zabeleženo.",
|
||||
"no_match_yet": "Še ni poskusa ujemanja — zapolni se med delujočim ciklom.",
|
||||
"no_match_yet": "Še ni poskusa ujemanja – zapolni se med delujočim ciklom.",
|
||||
"no_other_users": "Ni najdenih drugih uporabnikov Home Assistant.",
|
||||
"no_phases": "Ni definiranih faz.",
|
||||
"no_phases_assigned": "Ni dodeljenih faz.",
|
||||
@@ -713,7 +718,7 @@
|
||||
"notify_services_hint": "Uporabite ID-je storitev {entity} (ločene z vejicami za več storitev). Spremenljivke predloge: {vars}.",
|
||||
"old_actions_warning": "Konfigurirano s starim urejevalnikom dejanj (zdaj odstranjen). Še vedno se sprožijo ob dogodkih cikla, vendar jih tukaj ni več mogoče urejati. Pretvorite jih v običajno avtomatizacijo ali jih odstranite.",
|
||||
"onboarding_progress": "Opazovanih ciklov: {n} / 3",
|
||||
"onboarding_watching": "Napravo uporabljajte običajno — WashData opazuje. Po 3 ciklih se bo začelo ujemanje programov.",
|
||||
"onboarding_watching": "Napravo uporabljajte običajno – WashData opazuje. Po 3 ciklih se bo začelo ujemanje programov.",
|
||||
"pending_feedback": "Čakajoče povratne informacije o zaznavi",
|
||||
"performance_trend": "Trend uspešnosti ({n} ciklov)",
|
||||
"pg_analysis_empty": "Naložite cikel za prikaz analize ujemanja.",
|
||||
@@ -748,13 +753,13 @@
|
||||
"restart_gap_footer": "Označeno na grafu. Podatki o moči manjkajo za te intervale; ujemanje je uporabilo samo dejanske meritve.",
|
||||
"restart_gap_header": "{n} vrzel ponovnega zagona HA med tem ciklom",
|
||||
"restart_gap_item": "{dur} vrzel",
|
||||
"review_confirm_help": "Preverite, ali je bil ta cikel pravilno zaznan. Vaši pregledi usposabljajo model na vašem stroju — več ciklov kot potrdite, boljše je ujemanje in točkovanje zdravja. Dovolj je hitro Dobro/Slabo.",
|
||||
"review_confirm_help": "Preverite, ali je bil ta cikel pravilno zaznan. Vaši pregledi usposabljajo model na vašem stroju – več ciklov kot potrdite, boljše je ujemanje in točkovanje zdravja. Dovolj je hitro Dobro/Slabo.",
|
||||
"review_in_settings": "Pregled v nastavitvah",
|
||||
"review_notes_placeholder": "Opombe (neobvezno)",
|
||||
"review_notes_tip": "Opombe s prostim besedilom za lastno referenco. Ne uporablja se pri ujemanju ali usposabljanju.",
|
||||
"review_profile_tip": "Program, kot je ta cikel označen. Če je bil samodejno zaznan program napačen, ga popravite tukaj — označevanje uči ujemanja za prihodnje cikle.",
|
||||
"review_profile_tip": "Program, kot je ta cikel označen. Če je bil samodejno zaznan program napačen, ga popravite tukaj – označevanje uči ujemanja za prihodnje cikle.",
|
||||
"review_quality_tip": "Kako čist je ta cikel. Dobro = učbeniški primer tega programa; Slabo = zaznano, vendar hrupno ali netipično; Neuporabno = napačno zaznano (združeno, okrnjeno ali lažno). Poganja rezultat zdravja in kateri cikli so dovoljeni za usposabljanje modela.",
|
||||
"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_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",
|
||||
"saving_triggers_reload": "Shranjevanje sproži ponovni zagon integracije. Entitete HA se lahko za kratek čas prikažejo kot nedostopne.",
|
||||
@@ -763,7 +768,7 @@
|
||||
"setting_changed": "Spremenjeno iz {old} v {new} dne {date}",
|
||||
"settings_basic_note": "Prikazane so bistvene nastavitve. Za celoten seznam preklopite na Napredno.",
|
||||
"shape_drift_advisory": "⚠ Odmik oblike",
|
||||
"shape_drift_detail": "Vzorec moči tega profila se je s časom spremenil — možna obraba naprave ali potrebno vzdrževanje (npr. razkamianje, čiščenje filtra).",
|
||||
"shape_drift_detail": "Vzorec moči tega profila se je s časom spremenil – možna obraba naprave ali potrebno vzdrževanje (npr. razkamianje, čiščenje filtra).",
|
||||
"show_all_settings": "Pokaži vse nastavitve",
|
||||
"showing_suggestions": "Prikaz nastavitve {count} s predlogi.",
|
||||
"split_intro": "Kliknite na graf, da dodate ali odstranite točko razdelitve, ali samodejno zaznajte po nedejavnih vrzelih. Vsak rezultirajoči segment lahko dobi lasten profil.",
|
||||
@@ -789,10 +794,10 @@
|
||||
"toast_revert_failed": "Razveljavitev ni uspela: {error}",
|
||||
"toast_reverted": "{key} povrnjeno",
|
||||
"toast_save_failed": "Shranjevanje ni uspelo: {error}",
|
||||
"trend_duration_longer": "Trajanje se povečuje ({pct}%/cikel) — zadnje povprečje {avg}",
|
||||
"trend_duration_shorter": "Trajanje se skrajšuje ({pct}%/cikel) — zadnje povprečje {avg}",
|
||||
"trend_duration_longer": "Trajanje se povečuje ({pct}%/cikel) – zadnje povprečje {avg}",
|
||||
"trend_duration_shorter": "Trajanje se skrajšuje ({pct}%/cikel) – zadnje povprečje {avg}",
|
||||
"trend_energy_down": "Energija pada ({pct}%/cikel)",
|
||||
"trend_energy_up": "Energija narašča ({pct}%/cikel) — zadnje povprečje {avg}",
|
||||
"trend_energy_up": "Energija narašča ({pct}%/cikel) – zadnje povprečje {avg}",
|
||||
"trim_intro": "Povlecite rdeče ročke ali vnesite vrednosti. Vse zunaj okna se odstrani.",
|
||||
"tuning_suggestions_available": "{count} predlog za nastavitev je na voljo iz opazovanih ciklov. Pojavijo se poleg ustreznih polj.",
|
||||
"unsure_detected_prefix": "WashData ni prepričan, da je zaznal",
|
||||
@@ -857,7 +862,9 @@
|
||||
"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"
|
||||
"share_profile_no_cycles": "Profil '{p}' nima ⭐ referenčnih ciklov -- preskočen bo, razen če imate {n}+ potrjenih zagonov",
|
||||
"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"
|
||||
},
|
||||
"phase_desc": {
|
||||
"anti_crease": "Občasni kratki premiki po zaključku za preprečevanje gub na oblačilih.",
|
||||
@@ -940,6 +947,10 @@
|
||||
"triggers": {
|
||||
"intro": "Izbirni zunanji signali: sprožilec za konec, senzor vrat, stikalo za premor in opomnik za raztovarjanje.",
|
||||
"label": "Sprožilci in vrata"
|
||||
},
|
||||
"phase_eta": {
|
||||
"label": "Preostali čas",
|
||||
"intro": "Preostali čas z upoštevanjem faz, za naprave, katerih dolžina cikla je odvisna od temperature ali ožemanja."
|
||||
}
|
||||
},
|
||||
"setting": {
|
||||
@@ -1023,6 +1034,10 @@
|
||||
"doc": "Fiksna cena na kWh, ki se uporablja za podatke o stroških, kadar zgoraj ni nastavljen noben subjekt v živo.",
|
||||
"label": "Statična cena energije (za kWh)"
|
||||
},
|
||||
"energy_sensor": {
|
||||
"doc": "Neobvezni kumulativni števec energije (total_increasing kWh/Wh, npr. lasten števec skupne porabe vtičnice). Ko je nastavljen, se energija, prikazana za vsak cikel, vzame iz razlike odčitkov tega števca med začetkom in koncem, kar prepreči podštevanje, do katerega pride pri integriranju počasi poročajočega senzorja moči. Vrne se na integrirano vrednost, če odčitek manjka, je njegova enota neznana ali razlika ni pozitivna. Pustite prazno, da še naprej integrirate senzor moči.",
|
||||
"label": "Entiteta merilnika energije"
|
||||
},
|
||||
"expose_debug_entities": {
|
||||
"doc": "Objavite dodatne diagnostične entitete HA (zaupanje ujemanja, dvoumnost, notranje stanje). Izključeno ohranja seznam entitet čist za običajno uporabo.",
|
||||
"label": "Izpostavi entitete za odpravljanje napak"
|
||||
@@ -1305,6 +1320,38 @@
|
||||
},
|
||||
"show_contributor": {
|
||||
"doc": "Prikaži ime sodelavca pri profilih, prenesenih iz skupnostne trgovine"
|
||||
},
|
||||
"enable_phase_matching": {
|
||||
"label": "Preostali čas z upoštevanjem faz",
|
||||
"doc": "Vsak tekoči cikel razdeli na faze (ogrevanje, pranje, ožemanje) in razporedi preostali čas po fazah, združen s klasično oceno - na začetku cikla se opira na proračun faz, proti koncu pa na klasično oceno. To prilagodi odštevanje temu, kako dolgo se vaša naprava dejansko segreva in deluje, kar je najbolj opazno v prvi polovici cikla. Izklopljeno = samo klasična ocena. Vpliva le na prikaz preostalega časa; ujemanje programov in zaznavanje cikla ostaneta nespremenjena."
|
||||
},
|
||||
"keep_min_score": {
|
||||
"label": "Min. ocena ujemanja",
|
||||
"doc": "Minimalna ocena podobnosti, ki jo mora imeti kandidat, da ostane v tekmi za ujemanje. Privzeta vrednost 0,1 je namerno dovoljna - sprejme celo šibke kandidate in se zanaša na kasnejše stopnje za iskanje najboljšega ujemanja. Zvišajte za zgodnejše izločanje malo verjetnih profilov; znižajte za razširitev začetnega nabora kandidatov."
|
||||
},
|
||||
"dtw_blend": {
|
||||
"label": "Mešanje deformacije",
|
||||
"doc": "Koliko DTW ocena poravnave nadomešča osnovno oceno Stopnje 2. 0 = uporabi samo oceno Stopnje 2, 1 = uporabi samo DTW oceno, 0,5 (privzeto) = enakomerno mešanje. Zvišajte za večje zanašanje na poravnavo, ko imajo programi podobne ravni moči, a različne časovne vzorce."
|
||||
},
|
||||
"dtw_ensemble_w": {
|
||||
"label": "Mešanica kombinacije DTW",
|
||||
"doc": "V kombiniranem načinu DTW (privzetem) je to utež skaliranega L1 v primerjavi z izvedenim DTW (DDTW). 1,0 = vse skalirano L1, 0 = vse DDTW, 0,7 = privzeto. Skalirana varianta L1 primerja ravni moči; izvedena varianta se odziva na spremembe moči skozi čas. Kombinirani način združuje oba."
|
||||
},
|
||||
"dtw_ddtw_scale": {
|
||||
"label": "Merilo izvedene deformacije",
|
||||
"doc": "Razdalja pol-nasičenja za ocenjevanje z izvedenim DTW. Ocena se prepolovi, ko je razdalja DDTW enaka tej vrednosti. Manjša = bolj občutljiva na razlike v obliki. Privzeta vrednost 30 je umerjena za tipične sledilce moči gospodinjskih aparatov. Vpliva samo na kombinirani in ddtw način DTW."
|
||||
},
|
||||
"dtw_refine_top_n": {
|
||||
"label": "Stevilo natancnejših kandidatov",
|
||||
"doc": "Koliko najboljših kandidatov Stopnje 2 DTW znova oceni. DTW je dražji, zato se uporablja samo za N najboljših kandidatov. Privzeto 5. Zvišajte (na 7-9), če pravi profil po Stopnji 2 včasih doseže samo 4. ali 5. mesto - DTW ga lahko reši. Znižanje rahlo pospeši ujemanje."
|
||||
},
|
||||
"duration_scale": {
|
||||
"label": "Ostrina trajanja",
|
||||
"doc": "Ostrina kazni za neujemanje trajanja na Stopnji 4. To je logaritmično razmerje, pri katerem se ocena ujemanja prepolovi. Manjše = strožje: neujemanje trajanja bolj znižuje oceno. Privzeta vrednost 0,175 ustreza toleranci trajanja približno 18% pri pol-uteži. Kombinirajte z Utežjo trajanja."
|
||||
},
|
||||
"energy_scale": {
|
||||
"label": "Ostrina energije",
|
||||
"doc": "Ostrina kazni za neujemanje energije na Stopnji 4. Manjše = strožje: neujemanje energije bolj znižuje oceno. Privzeta vrednost 0,25 je namerno bolj dovoljna od Ostrine trajanja, ker energija niha z obremenitvijo. Kombinirajte z Utežjo energije."
|
||||
}
|
||||
},
|
||||
"setting_group": {
|
||||
@@ -1424,24 +1471,24 @@
|
||||
"lower": "Več ciklov je samodejno označenih; nekateri so lahko napačno prepoznani"
|
||||
},
|
||||
"duration_tolerance": {
|
||||
"higher": "Sprejme širši razpon trajanja — bolj prilagodljivo ujemanje",
|
||||
"lower": "Zahteva bližje ujemanje trajanja — strožje, a lahko zavrne neobičajne cikle"
|
||||
"higher": "Sprejme širši razpon trajanja – bolj prilagodljivo ujemanje",
|
||||
"lower": "Zahteva bližje ujemanje trajanja – strožje, a lahko zavrne neobičajne cikle"
|
||||
},
|
||||
"end_energy_threshold": {
|
||||
"higher": "Zaključi samo cikle z znatno porabo energije",
|
||||
"lower": "Zaključi tudi krajše ali manj energijsko zahtevne cikle"
|
||||
},
|
||||
"end_repeat_count": {
|
||||
"higher": "Zahteva več ponovitev signala konca — bolj zanesljivo, nekoliko počasneje",
|
||||
"lower": "Konča po manj ponovitvah — hitrejše zaznavanje, večje tveganje lažnega konca"
|
||||
"higher": "Zahteva več ponovitev signala konca – bolj zanesljivo, nekoliko počasneje",
|
||||
"lower": "Konča po manj ponovitvah – hitrejše zaznavanje, večje tveganje lažnega konca"
|
||||
},
|
||||
"learning_confidence": {
|
||||
"higher": "Uči se le iz zelo zanesljivih ujemanj — počasneje, a zanesljiveje",
|
||||
"higher": "Uči se le iz zelo zanesljivih ujemanj – počasneje, a zanesljiveje",
|
||||
"lower": "Uči se iz več ciklov; model je lahko manj natančen"
|
||||
},
|
||||
"min_off_gap": {
|
||||
"higher": "Pred začetkom novega cikla je potreben daljši mir",
|
||||
"lower": "Kratek mir sproži nov cikel — zaporedni zagoni se lahko razdelijo"
|
||||
"lower": "Kratek mir sproži nov cikel – zaporedni zagoni se lahko razdelijo"
|
||||
},
|
||||
"min_power": {
|
||||
"higher": "Manj občutljiv na porabo moči v mirovanju; lahko spregleda zelo tihe programe",
|
||||
@@ -1452,24 +1499,24 @@
|
||||
"lower": "Zataknjen cikel se prisili zaključiti prej"
|
||||
},
|
||||
"off_delay": {
|
||||
"higher": "Več časa za premor naprave — primerno za dolge faze namakanja ali sušenja",
|
||||
"lower": "Hitrejše zaznavanje konca — primerno za naprave z jasnim vklopom/izklopom"
|
||||
"higher": "Več časa za premor naprave – primerno za dolge faze namakanja ali sušenja",
|
||||
"lower": "Hitrejše zaznavanje konca – primerno za naprave z jasnim vklopom/izklopom"
|
||||
},
|
||||
"profile_match_threshold": {
|
||||
"higher": "Potrdi le visoko zanesljiva ujemanja; več ciklov ostane neoznačenih",
|
||||
"lower": "Ujema več ciklov; nekateri so lahko rahlo napačni"
|
||||
},
|
||||
"running_dead_zone": {
|
||||
"higher": "Prezre kratke skoke moči med mirovanjem — manj občutljiv na šum",
|
||||
"lower": "Odziva se na krajše impulze moči — zazna hitro prehodno aktivnost"
|
||||
"higher": "Prezre kratke skoke moči med mirovanjem – manj občutljiv na šum",
|
||||
"lower": "Odziva se na krajše impulze moči – zazna hitro prehodno aktivnost"
|
||||
},
|
||||
"start_threshold_w": {
|
||||
"higher": "Preprečuje lažne zagone iz kratkih skokov moči",
|
||||
"lower": "Zazna programe z nizko močjo; lahko se odzove na šum"
|
||||
},
|
||||
"stop_threshold_w": {
|
||||
"higher": "Zaključi cikel hitreje — lahko zapre med premorom",
|
||||
"lower": "Čaka dlje na zaključek — manj prezgodnjih zaključkov"
|
||||
"higher": "Zaključi cikel hitreje – lahko zapre med premorom",
|
||||
"lower": "Čaka dlje na zaključek – manj prezgodnjih zaključkov"
|
||||
},
|
||||
"watchdog_interval": {
|
||||
"higher": "Dovoli daljše tihe faze; manj lažnih prisilnih ustavitev",
|
||||
@@ -1676,12 +1723,19 @@
|
||||
"start_duration_threshold": "Sekunde nad pragom za potrditev zagona",
|
||||
"start_threshold_w": "Najmanjša moč v vatih, da šteje kot zagnano",
|
||||
"stop_threshold_w": "Pod to vrednostjo naprava šteje kot izklopljena",
|
||||
"dtw_bandwidth": "Koliko časovnega raztegovanja dovoljuje ujemanje oblike",
|
||||
"corr_weight": "Utež oblike krivulje glede na raven moči pri ujemanju",
|
||||
"duration_weight": "Koliko skladnost trajanja vpliva na ujemanje",
|
||||
"energy_weight": "Koliko skladnost porabe energije vpliva na ujemanje",
|
||||
"profile_match_min_duration_ratio": "Najkrajše izvajanje (glede na profil), ki se še lahko ujema",
|
||||
"profile_match_max_duration_ratio": "Najdaljše izvajanje (glede na profil), ki se še lahko ujema"
|
||||
"dtw_bandwidth": "Stopnja 3: deformacijski pas Sakoe-Chiba (0 = DTW izklopljen; privzeto 0,2 = 20% dolžine cikla)",
|
||||
"corr_weight": "Stopnja 2: ravnovesje med obliko krivulje (korelacija) in ravnijo moči (MAE); privzeto 0,45",
|
||||
"duration_weight": "Stopnja 4: kako močno ujemanje trajanja vpliva na končno oceno (privzeto 0,22)",
|
||||
"energy_weight": "Stopnja 4: kako močno ujemanje energije vpliva na končno oceno (privzeto 0,22)",
|
||||
"profile_match_min_duration_ratio": "Stopnja 1: minimalna dolžina cikla kot del trajanja profila; privzeto 0,1 (10%)",
|
||||
"profile_match_max_duration_ratio": "Stopnja 1: maksimalna dolžina cikla kot del trajanja profila; privzeto 1,5 (150%)",
|
||||
"keep_min_score": "Stopnja 2: minimalna ocena za ostanok v tekmi; privzeto 0,1 sprejme šibka ujemanja, kasnejše stopnje izberejo najboljše",
|
||||
"dtw_blend": "Stopnja 3: 0 = samo osnovna ocena, 1 = samo DTW ocena, 0,5 = enakomerno mešanje (privzeto)",
|
||||
"dtw_ensemble_w": "Stopnja 3 (kombinirani način): utež skaliranega L1 v primerjavi z izvedenim DTW; privzeto 0,7 daje prednost ravni",
|
||||
"dtw_ddtw_scale": "Stopnja 3: razdalja pol-nasičenja DDTW; manjša = bolj občutljiva na obliko (privzeto 30)",
|
||||
"dtw_refine_top_n": "Stopnja 3: kandidati, ki jih DTW znova oceni; zvišajte na 7-9, če pravi profil zasede 4.-5. mesto (privzeto 5)",
|
||||
"duration_scale": "Stopnja 4: logaritmično razmerje, pri katerem se ujemanje trajanja prepolovi; manjše = strožja kazen (privzeto 0,175)",
|
||||
"energy_scale": "Stopnja 4: logaritmično razmerje, pri katerem se ujemanje energije prepolovi; manjše = strožja kazen (privzeto 0,25)"
|
||||
},
|
||||
"col": {
|
||||
"profile_tip": "Ime ujemajočega programa. Brez oznake pomeni, da se ob koncu cikla ni ujemal noben profil.",
|
||||
@@ -1766,6 +1820,69 @@
|
||||
},
|
||||
"pg_sweep": {
|
||||
"optimize": "Optimizacija: {param}"
|
||||
},
|
||||
"pg_detail": {
|
||||
"simulate": "Simuliraj cikel"
|
||||
},
|
||||
"split": {
|
||||
"apply": "Deljenje cikla"
|
||||
},
|
||||
"trim": {
|
||||
"apply": "Obrezovanje cikla"
|
||||
},
|
||||
"merge": {
|
||||
"apply": "Združevanje ciklov"
|
||||
},
|
||||
"rebuild": {
|
||||
"envelopes": "Ponovni izračun ovojnic"
|
||||
},
|
||||
"cancelling": "Prekinjam..."
|
||||
},
|
||||
"setup": {
|
||||
"hdr": {
|
||||
"card": "Nastavitev naprave",
|
||||
"healthy_chip": "Nastavitev dokončana"
|
||||
},
|
||||
"phase0": {
|
||||
"washer": "WashData že zazna vaše cikle. Posnemite prvi cikel, da omogočite imena programov in ocene časa.",
|
||||
"dishwasher": "WashData opazuje. Pomivalni stroji imajo zapletene cikle – snemanje prvega cikla je izrazito priporočeno. Če zaznani cikel teče predolgo, ga obrežite v urejevalniku ciklov, preden ga shranite kot profil.",
|
||||
"generic": "WashData opazuje. Posnemite ali označite zaznani cikel in začnite graditi profile."
|
||||
},
|
||||
"phase1a": {
|
||||
"labelled": "Dober začetek – vaš prvi program je shranjen. Za najčistejše podatke razmislite o snemanju naslednjega cikla s pripomočkom za snemanje."
|
||||
},
|
||||
"phase1b": {
|
||||
"recorded": "Vaš posnetek je bil shranjen kot {profile_name}. Zdaj posnemite ali označite ostale pogoste programe, da razširite pokritost."
|
||||
},
|
||||
"phase1c": {
|
||||
"verify": "Imate {count} programov od skupnosti. Zaženite cikel, da preverite, ali jih WashData pravilno prepozna – ujemanje se bo izboljšalo, ko naprava gradi lastno zgodovino."
|
||||
},
|
||||
"phase2": {
|
||||
"cluster": "WashData je videl {count} ciklov, ki ne ustrezajo nobenemu shranjenemu programu – med seboj so si podobni. Ali želite zanje ustvariti nov profil?",
|
||||
"unmatched": "Vaš zadnji cikel ni ustrezal nobenemu shranjenemu programu. Je to nov program?"
|
||||
},
|
||||
"phase3": {
|
||||
"suggestions": "WashData ima priporočila za nastavitve na podlagi vaše zgodovine ciklov – preglejte jih za izboljšanje natančnosti zaznavanja.",
|
||||
"groups": "Nekateri vaši profili izgledajo kot isti program pri različnih temperaturah. Organizirajte jih v skupino za boljše ujemanje.",
|
||||
"phases": "Dodajte programske faze k {profile_name} za natančnejše ocene preostalega časa."
|
||||
},
|
||||
"phase4": {
|
||||
"healthy": "Ta naprava je v celoti nastavljena ({profile_count} profilov)."
|
||||
},
|
||||
"cta": {
|
||||
"start_recording": "Začni snemanje",
|
||||
"label_detected_cycle": "Imam že zaznani cikel – namesto tega ga označi",
|
||||
"browse_cycles": "Prebrskaj cikle za označevanje naslednjega",
|
||||
"view_profiles": "Oglej si svoje profile",
|
||||
"create_from_cluster": "Ustvari profil iz teh ciklov",
|
||||
"create_profile": "Ustvari zanj profil",
|
||||
"review_suggestions": "Preglej predloge",
|
||||
"organise_profiles": "Organiziraj profile",
|
||||
"configure_phases": "Nastavi faze",
|
||||
"skip_step": "Preskoči ta korak",
|
||||
"skip_forever": "Ne prikaži znova",
|
||||
"hide_guidance": "Skrij navodila",
|
||||
"show_guidance": "Prikaži navodila"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
{
|
||||
"badge": {
|
||||
"artifact_tip": "U zbuluan {n} anomali (p.sh. dera e hapur në mes të ciklit) — hapeni për t'i parë ato në grafik",
|
||||
"artifact_tip": "U zbuluan {n} anomali (p.sh. dera e hapur në mes të ciklit) – hapeni për t'i parë ato në grafik",
|
||||
"auto": "(zbuluar automatikisht)",
|
||||
"built_in_tag": "i integruar",
|
||||
"declining": "↘ në rënie",
|
||||
"energy_low": "Energji më e ulët se zakonisht",
|
||||
"energy_spike": "Energji më e lartë se zakonisht",
|
||||
"fair_fit": "cilësi e pranueshme",
|
||||
"fair_fit_tip": "Konsistencë e moderuar e ndeshjes — disa cikle të caktuara për këtë profil kanë rezultate më të ulëta besimi. Etiketoni më shumë cikle ose riregjistroni profilin për të përmirësuar saktësinë.",
|
||||
"fair_fit_tip": "Konsistencë e moderuar e ndeshjes – disa cikle të caktuara për këtë profil kanë rezultate më të ulëta besimi. Etiketoni më shumë cikle ose riregjistroni profilin për të përmirësuar saktësinë.",
|
||||
"feedback_requested": "Kërkohet koment",
|
||||
"golden_cycle": "Cikli referues i regjistruar",
|
||||
"improving": "↗ në rritje",
|
||||
@@ -15,7 +15,7 @@
|
||||
"needs_review": "Ka nevojë për rishikim",
|
||||
"overrun": "Zgjati më shumë se zakonisht",
|
||||
"poor_fit": "cilësi e keqe",
|
||||
"poor_fit_tip": "Histori jokonsistente e ndeshjeve — merrni parasysh rindërtimin e këtij profili",
|
||||
"poor_fit_tip": "Histori jokonsistente e ndeshjeve – merrni parasysh rindërtimin e këtij profili",
|
||||
"restart_gap_tip": "{n} boshllëk rinisje të HA: gjurma e energjisë ka një vrimë",
|
||||
"reviewed": "Shqyrtuar",
|
||||
"steady": "→ i qëndrueshëm",
|
||||
@@ -87,7 +87,7 @@
|
||||
"on_cycle_finished": "Kur cikli përfundon",
|
||||
"on_cycle_started": "Kur cikli fillon",
|
||||
"pause_cycle": "Ndalo",
|
||||
"pause_cycle_tip": "Ndalo ciklin aktiv — pajisja do të vazhdojë nga aty ku kishte mbetur",
|
||||
"pause_cycle_tip": "Ndalo ciklin aktiv – pajisja do të vazhdojë nga aty ku kishte mbetur",
|
||||
"pg_apply_device": "Apliko te pajisja",
|
||||
"pg_autofill": "Mbushje automatike",
|
||||
"play": "Luaj",
|
||||
@@ -97,8 +97,8 @@
|
||||
"process_tip": "Ruaj gjurmën e regjistruar si profil të ri ose ekzistues",
|
||||
"rebuild": "Rindërto zarfet",
|
||||
"rebuild_envelope": "Rindërto zarfin",
|
||||
"rebuild_tip": "Rillogaris zarfin e pritshmë të energjisë (brezin min/maks) për të gjitha profilet nga ciklet e tyre të etiketuara — ekzekuto pas etiketimit të cikleve të reja ose korrigjimit të tjerave",
|
||||
"rec_start_tip": "Fillo regjistrimin e gjurmës së energjisë të pajisjes — fillo pak para ekzekutimit të një cikli",
|
||||
"rebuild_tip": "Rillogaris zarfin e pritshmë të energjisë (brezin min/maks) për të gjitha profilet nga ciklet e tyre të etiketuara – ekzekuto pas etiketimit të cikleve të reja ose korrigjimit të tjerave",
|
||||
"rec_start_tip": "Fillo regjistrimin e gjurmës së energjisë të pajisjes – fillo pak para ekzekutimit të një cikli",
|
||||
"rec_stop": "Ndalo",
|
||||
"rec_stop_tip": "Ndalo regjistrimin dhe mbaj gjurmën e kapur për shqyrtim",
|
||||
"record": "Fillo regjistrimin",
|
||||
@@ -231,7 +231,7 @@
|
||||
"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": "{n} konflikt{s} cilësimi – kontrolloni seksionet e theksuara dhe korrigjojini para ruajtjes.",
|
||||
"settings_banner_btn": "Shko te i pari"
|
||||
},
|
||||
"hdr": {
|
||||
@@ -451,9 +451,9 @@
|
||||
"show_expected": "Shfaq mbivendosjen e kurbës së pritshme (profili i përputhshëm, portokalli)",
|
||||
"show_raw": "Shfaq çelësin e të dhënave bruto të prizës në grafikun e fuqisë në kohë reale",
|
||||
"sparkline": "Prirja e fundit e kohëzgjatjes së cikleve",
|
||||
"stage2": "Etapa 2 — ngjashmëria bazë",
|
||||
"stage3": "Etapa 3 — DTW",
|
||||
"stage4": "Etapa 4 — përputhja",
|
||||
"stage2": "Etapa 2 – ngjashmëria bazë",
|
||||
"stage3": "Etapa 3 – DTW",
|
||||
"stage4": "Etapa 4 – përputhja",
|
||||
"status": "Statusi",
|
||||
"tail_trim": "Prerja e fundit (s)",
|
||||
"timer_auto_pause": "Auto-pauzë",
|
||||
@@ -561,7 +561,12 @@
|
||||
"flags": "Flamuj",
|
||||
"include_phase_map": "Përfshi hartën e fazave",
|
||||
"include_settings": "Përfshi cilësimet e zbulimit dhe përputhjes",
|
||||
"show_contributor": "Trego emrat e kontribuesve"
|
||||
"show_contributor": "Trego emrat e kontribuesve",
|
||||
"task_pg_detail": "Simulimi i ciklit",
|
||||
"task_split": "Ndarja e ciklit",
|
||||
"task_trim": "Prerja e ciklit",
|
||||
"task_merge": "Bashkimi i cikleve",
|
||||
"task_rebuild": "Rindërtimi i zarfave"
|
||||
},
|
||||
"log": {
|
||||
"all_levels": "Të gjitha nivelet",
|
||||
@@ -645,7 +650,7 @@
|
||||
"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.",
|
||||
"artifact_header": "{n} anomali të zbuluara gjatë këtij cikli",
|
||||
"artifact_pause_detail": "Fuqia ra pothuajse në zero për ~{n} s dhe u rikuperua — ndoshta dera u hap në mes të ciklit ose cikli u ndërpre.",
|
||||
"artifact_pause_detail": "Fuqia ra pothuajse në zero për ~{n} s dhe u rikuperua – ndoshta dera u hap në mes të ciklit ose cikli u ndërpre.",
|
||||
"artifact_spike_detail": "Shkoi mbi brezin e zakonshëm të fuqisë për ~{n} s.",
|
||||
"auto_label_intro": "Cakto profile te ciklet e paetiketuara që besueshmëria e tyre e përputhjes tejkalon pragun.",
|
||||
"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ë.",
|
||||
@@ -654,10 +659,10 @@
|
||||
"collecting_data": "Duke mbledhur të dhëna: nevojiten edhe {need} cikël{plural} para se të fillojë sintonizimi i imët ({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",
|
||||
"compare_selected_cycles": "Ciklet e zgjedhura (solide) – shfaq / fshih",
|
||||
"consider_new_profile": "Konsideroni krijimin e një profili të ri.",
|
||||
"coverage_gap": "ciklet e fundit nuk kanë asnjë profil që përputhet ({pct}% e 30 të fundit).",
|
||||
"coverage_gap_similar_cycles": "U gjetën {count} cikle të ngjashme të paetiketuara — krijo një profil për të filluar përputhjen.",
|
||||
"coverage_gap_similar_cycles": "U gjetën {count} cikle të ngjashme të paetiketuara – krijo një profil për të filluar përputhjen.",
|
||||
"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": "Eksporto të gjitha profilet dhe ciklet në JSON ose rivendos nga një eksportim i mëparshëm.",
|
||||
@@ -686,7 +691,7 @@
|
||||
"ml_learned_intro": "Modele të rregulluara mirë për këtë makinë.",
|
||||
"ml_loading": "duke ngarkuar ML…",
|
||||
"ml_settings_intro": "Dy çelësa të pavarur: njëri aplikon modelet ndërsa një cikël ekzekutohet, tjetri lejon WashData t'i rregullojë ato me kalimin e kohës.",
|
||||
"name_first_program": "Keni cikle të mjaftueshme — emërtoni programin tuaj të parë për të nisur përputhjen.",
|
||||
"name_first_program": "Keni cikle të mjaftueshme – emërtoni programin tuaj të parë për të nisur përputhjen.",
|
||||
"near_duplicate_cluster": "u zbulua grupi i profilit pothuajse dublikatë. Grupimi lejon që përputhja të zgjedhë në mënyrë të besueshme midis pamjeve të ngjashme (p.sh. i njëjti program në temperaturë/centrifugim të ndryshëm).",
|
||||
"no_cycles_match": "Asnjë cikël nuk përputhet me filtrin aktual.",
|
||||
"no_cycles_profile": "Asnjë cikël për këtë profil.",
|
||||
@@ -696,7 +701,7 @@
|
||||
"no_devices": "Asnjë pajisje WashData e konfiguruar ende.",
|
||||
"no_envelope": "Asnjë zarf ende - rindërtoni pas etiketimit të cikleve.",
|
||||
"no_envelope_overlay": "Asnjë zarf i disponueshëm për mbivendosje.",
|
||||
"no_fine_tuned": "Asgjë e rregulluar mirë ende — WashData po përdor modelet e integruara.",
|
||||
"no_fine_tuned": "Asgjë e rregulluar mirë ende – WashData po përdor modelet e integruara.",
|
||||
"no_logs": "Asnjë regjistrim i mbajtur në bufer ende.",
|
||||
"no_maintenance": "Ende nuk është regjistruar asnjë mirëmbajtje.",
|
||||
"no_match_yet": "Asnjë tentativë përputhje ende - kjo plotësohet gjatë një cikli aktiv.",
|
||||
@@ -713,7 +718,7 @@
|
||||
"notify_services_hint": "Përdorni ID-të e shërbimit {entity} (të ndara me presje për shumë). Variablat e shabllonit: {vars}.",
|
||||
"old_actions_warning": "Konfiguruar me redaktuesin e vjetër të veprimeve (tani i hequr). Ato ende ndezin në ngjarjet e ciklit, por nuk mund të modifikohen më këtu. Shndërrojini ato në një automatizim normal ose hiqni ato.",
|
||||
"onboarding_progress": "{n} / 3 cikle të vëzhguara",
|
||||
"onboarding_watching": "Përdorni pajisjen normalisht — WashData po vëzhgon. Pas 3 cikleve, do të nisë përputhja e programeve.",
|
||||
"onboarding_watching": "Përdorni pajisjen normalisht – WashData po vëzhgon. Pas 3 cikleve, do të nisë përputhja e programeve.",
|
||||
"pending_feedback": "Koment në pritje të zbulimit",
|
||||
"performance_trend": "Tendenca e performancës ({n} cikle)",
|
||||
"pg_analysis_empty": "Ngarkoni një cikël për të parë analizën e përputhjes.",
|
||||
@@ -763,7 +768,7 @@
|
||||
"setting_changed": "Ndryshuar nga {old} në {new} më {date}",
|
||||
"settings_basic_note": "Po shfaqen cilësimet thelbësore. Kaloni te Të avancuara për listën e plotë.",
|
||||
"shape_drift_advisory": "⚠ Zhvendosje forme",
|
||||
"shape_drift_detail": "Modeli i energjisë i këtij profili ka ndryshuar me kalimin e kohës — mundësi të konsumit të pajisjes ose nevojë mirëmbajtjeje (p.sh. heqja e gurëve, pastrimi i filtrit).",
|
||||
"shape_drift_detail": "Modeli i energjisë i këtij profili ka ndryshuar me kalimin e kohës – mundësi të konsumit të pajisjes ose nevojë mirëmbajtjeje (p.sh. heqja e gurëve, pastrimi i filtrit).",
|
||||
"show_all_settings": "Shfaq të gjitha cilësimet",
|
||||
"showing_suggestions": "Po shfaq cilësimin e {count} me sugjerime.",
|
||||
"split_intro": "Kliko grafikun për të shtuar ose hequr një pikë ndarjeje, ose zbulo automatikisht sipas ndërprerjeve. Çdo segment që rezulton mund të ketë profilin e tij.",
|
||||
@@ -789,7 +794,7 @@
|
||||
"toast_revert_failed": "Kthimi prapa dështoi: {error}",
|
||||
"toast_reverted": "{key} u rikthye",
|
||||
"toast_save_failed": "Ruajtja dështoi: {error}",
|
||||
"trend_duration_longer": "Kohëzgjatja në tendencë më e gjatë ({pct}%/cikël) — mesatare e fundit {avg}",
|
||||
"trend_duration_longer": "Kohëzgjatja në tendencë më e gjatë ({pct}%/cikël) – mesatare e fundit {avg}",
|
||||
"trend_duration_shorter": "Kohëzgjatja në tendencë më e shkurtër ({pct}%/cikël) - mesatare e fundit {avg}",
|
||||
"trend_energy_down": "Tendenca e energjisë në rënie ({pct}%/cikël)",
|
||||
"trend_energy_up": "Tendenca e energjisë në rritje ({pct}%/cikël) - mesatarisht kohët e fundit {avg}",
|
||||
@@ -857,7 +862,9 @@
|
||||
"share_guidelines_title": "Para se të ndani",
|
||||
"store_download_device_intro": "Adoptoni çdo program të ndarë dhe ciklet e tij të referencës në pajisjen tuaj. Ciklet dhe statistikat tuaja të regjistruara nuk preken.",
|
||||
"store_share_device_intro": "Ngarko {brand} {model} me ciklet e referencës që zgjidhni. Të tjerët me të njëjtën pajisje mund të adoptojnë programet tuaja. Hyrjet shqyrtohen para publikimit.",
|
||||
"share_profile_no_cycles": "Nuk ka cikle referimi -- shënojeni një cikël si ⭐ tek skeda Ciklet për të përfshirë këtë profil"
|
||||
"share_profile_no_cycles": "Nuk ka cikle referimi -- shënojeni një cikël si ⭐ tek skeda Ciklet për të përfshirë këtë profil",
|
||||
"advisory_phase_inconsistent": "'{name}' duket se përzien programe ose temperatura të ndryshme - ciklet e tij ngrohin për periudha shumë të ndryshme kohore. Ndarja e tij në profile të veçanta (p.sh. sipas temperaturës) do të përmirësojë përputhjen dhe vlerësimet e kohës.",
|
||||
"advisory_phase_inconsistent_title": "⚠ Ndoshta programe të përziera"
|
||||
},
|
||||
"phase_desc": {
|
||||
"anti_crease": "Rrotullime të shkurtra të herëpashershme pas përfundimit për të reduktuar rrudhat.",
|
||||
@@ -940,6 +947,10 @@
|
||||
"triggers": {
|
||||
"intro": "Sinjalet e jashtme opsionale: aktivizues përfundimi, senzori i derës, çelësi i pauzës dhe kujtues për shkarkim.",
|
||||
"label": "Aktivizues dhe dera"
|
||||
},
|
||||
"phase_eta": {
|
||||
"label": "Koha e Mbetur",
|
||||
"intro": "Kohë e mbetur e ndërgjegjshme për fazat, për makinat gjatësia e ciklit të të cilave varet nga temperatura ose centrifugimi."
|
||||
}
|
||||
},
|
||||
"setting": {
|
||||
@@ -1023,6 +1034,10 @@
|
||||
"doc": "Çmimi fiks për kWh i përdorur për shifrat e kostos kur nuk është vendosur më sipër asnjë subjekt i çmimit të drejtpërdrejtë.",
|
||||
"label": "Çmimi statik i energjisë (për kWh)"
|
||||
},
|
||||
"energy_sensor": {
|
||||
"doc": "Numërues kumulativ opsional i energjisë (total_increasing kWh/Wh, p.sh. matësi i vetë prizës për konsumin total). Kur vendoset, energjia e raportuar e çdo cikli merret nga diferenca e këtij numëruesi nga fillimi deri në fund, gjë që shmang nënllogaritjen që merrni nga integrimi i një sensori fuqie që raporton ngadalë. Kthehet te vlera e integruar nëse leximi mungon, njësia e tij është e panjohur, ose diferenca nuk është pozitive. Lëreni bosh për të vazhduar integrimin e sensorit të fuqisë.",
|
||||
"label": "Entiteti i matësit të energjisë"
|
||||
},
|
||||
"expose_debug_entities": {
|
||||
"doc": "Publikoni entitete shtesë diagnostikuese HA (besimi i ndeshjes, paqartësia, të brendshmet e gjendjes). Off e mban listën e entiteteve të pastër për përdorim normal.",
|
||||
"label": "Ekspono entitetet e korrigjimit"
|
||||
@@ -1305,6 +1320,38 @@
|
||||
},
|
||||
"show_contributor": {
|
||||
"doc": "Shfaq atribuimin \"nga <kontribuesi>\" në pajisjet dhe ciklet referuese të komunitetit."
|
||||
},
|
||||
"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."
|
||||
},
|
||||
"keep_min_score": {
|
||||
"label": "Rezultat Min. Përputhjeje",
|
||||
"doc": "Rezultati minimal i ngjashmërisë që i nevojitet një kandidati për të qëndruar në garën e përputhjes. Parazgjedhja 0.1 është me qëllim lejuese - pranon edhe kandidatë të dobët dhe u lë etapave të mëvonshme të gjejnë përputhjen më të mirë. Rriteni për të eliminuar profilet e pamundshme herët; uleni për të zgjeruar grupin fillestar të kandidatëve."
|
||||
},
|
||||
"dtw_blend": {
|
||||
"label": "Përzierje Deformimi",
|
||||
"doc": "Sa e zëvendëson rezultati i bashkimit DTW rezultatin bazë të Etapës 2. 0 = përdor vetëm rezultatin e Etapës 2, 1 = përdor vetëm rezultatin DTW, 0.5 (parazgjedhja) = përzierje e barabartë. Rriteni për t'u mbështetur më shumë në bashkimin e deformimit kur programet kanë nivele të ngjashme fuqie por modele të ndryshme kohore."
|
||||
},
|
||||
"dtw_ensemble_w": {
|
||||
"label": "Mix Ansambël DTW",
|
||||
"doc": "Në modalitetin ansambël DTW (parazgjedhja), pesë për L1-e shkallëzuar kundrejt DTW derivativ (DDTW). 1.0 = gjithë shkallëzuar-L1, 0 = gjithë DDTW, 0.7 = parazgjedhja. Varianti shkallëzuar-L1 krahason nivelet e fuqisë; varianti derivativ reagon ndaj mënyrës sesi ndryshon fuqia me kalimin e kohës. Ansambëli kombinon të dyja."
|
||||
},
|
||||
"dtw_ddtw_scale": {
|
||||
"label": "Shkalla e Deformimit Derivativ",
|
||||
"doc": "Distanca e gjysmë-ngopjes për vlerësimin e DTW derivativ. Rezultati gjysmohet kur distanca DDTW është e barabartë me këtë vlerë. Më i vogël = më i ndjeshëm ndaj ndryshimeve të formës. Parazgjedhja 30 është kalibruar për gjurmët tipike të fuqisë së pajisjeve. Ndikon vetëm mënyrat DTW ansambël dhe ddtw."
|
||||
},
|
||||
"dtw_refine_top_n": {
|
||||
"label": "Numri i Rafinimit DTW",
|
||||
"doc": "Sa kandidatë të parë të Etapës 2 ri-vlerësohen nga DTW. DTW është më e shtrenjtë llogaritëse, kështu që aplikohet vetëm tek kandidatët N më të mirë. Parazgjedhja 5. Rriteni (në 7-9) nëse profili i saktë ndonjëherë arrin vetëm në vendin e 4-të ose 5-të pas Etapës 2 - DTW mund ta shpëtojë. Ulja e saj shpejton pak përputhjen."
|
||||
},
|
||||
"duration_scale": {
|
||||
"label": "Saktësia e Kohëzgjatjes",
|
||||
"doc": "Ashpërsia e ndëshkimit të marrëveshjes së kohëzgjatjes së Etapës 4. Ky është raporti logaritmik në të cilin rezultati i marrëveshjes gjysmohet. Më i vogël = më i rreptë: një mospërputhje kohëzgjatjeje ndëshkon më shumë. Parazgjedhja 0.175 korrespondon me tolerancën e kohëzgjatjes rreth 18% në gjysmë-peshë. Çiftojeni me Peshën e Kohëzgjatjes."
|
||||
},
|
||||
"energy_scale": {
|
||||
"label": "Saktësia e Energjisë",
|
||||
"doc": "Ashpërsia e ndëshkimit të marrëveshjes së energjisë së Etapës 4. Më i vogël = më i rreptë: një mospërputhje energjie ndëshkon më shumë. Parazgjedhja 0.25 është me qëllim më lejuese se Ashpërsia e Kohëzgjatjes sepse energjia ndryshon me ngarkesën. Çiftojeni me Peshën e Energjisë."
|
||||
}
|
||||
},
|
||||
"setting_group": {
|
||||
@@ -1553,24 +1600,24 @@
|
||||
"lower": "Etiketimet automatike rriten; disa mund të identifikohen gabim"
|
||||
},
|
||||
"duration_tolerance": {
|
||||
"higher": "Pranon gamë më të gjerë kohëzgjatjeje — përputhje më fleksibël",
|
||||
"lower": "Kërkon përputhje më të ngushtë kohëzgjatjeje — më rigoroze por mund të refuzojë cikle të pazakonshme"
|
||||
"higher": "Pranon gamë më të gjerë kohëzgjatjeje – përputhje më fleksibël",
|
||||
"lower": "Kërkon përputhje më të ngushtë kohëzgjatjeje – më rigoroze por mund të refuzojë cikle të pazakonshme"
|
||||
},
|
||||
"end_energy_threshold": {
|
||||
"higher": "Mbyll vetëm ciklet që kanë konsumuar energji të konsiderueshme",
|
||||
"lower": "Mbyll edhe ciklet e shkurtra ose me konsum të ulët energjie"
|
||||
},
|
||||
"end_repeat_count": {
|
||||
"higher": "Kërkon që sinjali i fundit të përsëritet më shumë herë — më i qëndrueshëm, pak më i ngadaltë",
|
||||
"lower": "Mbyllet pas përsëritjeve më të pakta — detektim më i shpejtë, rrezik më i lartë mbylljeje false"
|
||||
"higher": "Kërkon që sinjali i fundit të përsëritet më shumë herë – më i qëndrueshëm, pak më i ngadaltë",
|
||||
"lower": "Mbyllet pas përsëritjeve më të pakta – detektim më i shpejtë, rrezik më i lartë mbylljeje false"
|
||||
},
|
||||
"learning_confidence": {
|
||||
"higher": "Mëson vetëm nga përputhjet me besueshmëri shumë të lartë — më e ngadaltë por më e besueshme",
|
||||
"higher": "Mëson vetëm nga përputhjet me besueshmëri shumë të lartë – më e ngadaltë por më e besueshme",
|
||||
"lower": "Mëson nga më shumë cikle; modeli mund të jetë më i zhurmshëm"
|
||||
},
|
||||
"min_off_gap": {
|
||||
"higher": "Nevojitet pushim më i gjatë para se të fillojë një cikël i ri",
|
||||
"lower": "Pushimi i shkurtër nis ciklin e ri — rrotullimet e njëpasnjëshme mund të ndahen"
|
||||
"lower": "Pushimi i shkurtër nis ciklin e ri – rrotullimet e njëpasnjëshme mund të ndahen"
|
||||
},
|
||||
"min_power": {
|
||||
"higher": "Më pak e ndjeshme ndaj konsumit në gjendje pritjeje; mund të humbasë programe shumë të heshtura",
|
||||
@@ -1581,24 +1628,24 @@
|
||||
"lower": "Ndërpret ciklin e bllokuar më shpejt"
|
||||
},
|
||||
"off_delay": {
|
||||
"higher": "Më shumë kohë për pauza të pajisjes — trajton faza të gjata njomjeje ose tharjeje",
|
||||
"lower": "Detektim më i shpejtë i fundit — i përshtatshëm për pajisje me ndezje/shuarje të qarta"
|
||||
"higher": "Më shumë kohë për pauza të pajisjes – trajton faza të gjata njomjeje ose tharjeje",
|
||||
"lower": "Detektim më i shpejtë i fundit – i përshtatshëm për pajisje me ndezje/shuarje të qarta"
|
||||
},
|
||||
"profile_match_threshold": {
|
||||
"higher": "Konfirmon vetëm përputhjet me besueshmëri të lartë; më shumë cikle mbeten pa etiketë",
|
||||
"lower": "Përputhet me më shumë cikle; disa mund të jenë paksa të gabuara"
|
||||
},
|
||||
"running_dead_zone": {
|
||||
"higher": "Injoron kumbëzat e shkurtra të fuqisë gjatë pushimit — më pak e ndjeshme ndaj zhurmës",
|
||||
"lower": "Reagron ndaj shpërthimeve më të shkurtra të fuqisë — kap aktivitetin kalimtar të shpejtë"
|
||||
"higher": "Injoron kumbëzat e shkurtra të fuqisë gjatë pushimit – më pak e ndjeshme ndaj zhurmës",
|
||||
"lower": "Reagron ndaj shpërthimeve më të shkurtra të fuqisë – kap aktivitetin kalimtar të shpejtë"
|
||||
},
|
||||
"start_threshold_w": {
|
||||
"higher": "Shmang startet false nga kumbëzat e shkurtra të fuqisë",
|
||||
"lower": "Kap programet me fuqi të ulët; mund të aktivizohet nga zhurma"
|
||||
},
|
||||
"stop_threshold_w": {
|
||||
"higher": "Mbyll ciklin më shpejt — mund të mbyllet gjatë një pauze",
|
||||
"lower": "Pret më gjatë para mbylljes — redukton përfundimet e parakohshme"
|
||||
"higher": "Mbyll ciklin më shpejt – mund të mbyllet gjatë një pauze",
|
||||
"lower": "Pret më gjatë para mbylljes – redukton përfundimet e parakohshme"
|
||||
},
|
||||
"watchdog_interval": {
|
||||
"higher": "Lejon faza më të gjata të heshtura; më pak ndërprerje false",
|
||||
@@ -1676,12 +1723,19 @@
|
||||
"start_duration_threshold": "Sekonda mbi prag për të konfirmuar nisjen",
|
||||
"start_threshold_w": "Watt minimalë për t'u llogaritur si nisur",
|
||||
"stop_threshold_w": "Nën këtë, makina llogaritet e fikur",
|
||||
"dtw_bandwidth": "Sa shtrembërim kohor lejon përputhja e formës",
|
||||
"corr_weight": "Pesha e formës së kurbës kundrejt nivelit të fuqisë në përputhje",
|
||||
"duration_weight": "Sa ndikon përkimi i kohëzgjatjes te përputhja",
|
||||
"energy_weight": "Sa ndikon përkimi i energjisë te përputhja",
|
||||
"profile_match_min_duration_ratio": "Cikli më i shkurtër (krahasuar me profilin) që lejohet ende të përputhet",
|
||||
"profile_match_max_duration_ratio": "Cikli më i gjatë (krahasuar me profilin) që lejohet ende të përputhet"
|
||||
"dtw_bandwidth": "Etapa 3: brez deformimi Sakoe-Chiba (0 = DTW joaktiv; parazgjedhja 0.2 = 20% e gjatësisë së ciklit)",
|
||||
"corr_weight": "Etapa 2: balancë mes formës së kurbës (korrelacion) dhe nivelit të fuqisë (MAE); parazgjedhja 0.45",
|
||||
"duration_weight": "Etapa 4: sa fortë ndikon marrëveshja e kohëzgjatjes në rezultatin final (parazgjedhja 0.22)",
|
||||
"energy_weight": "Etapa 4: sa fortë ndikon marrëveshja e energjisë në rezultatin final (parazgjedhja 0.22)",
|
||||
"profile_match_min_duration_ratio": "Etapa 1: gjatësia minimale e ciklit si pjesë e kohëzgjatjes së profilit; parazgjedhja 0.1 (10%)",
|
||||
"profile_match_max_duration_ratio": "Etapa 1: gjatësia maksimale e ciklit si pjesë e kohëzgjatjes së profilit; parazgjedhja 1.5 (150%)",
|
||||
"keep_min_score": "Etapa 2: rezultati minimal për të qëndruar në garë; parazgjedhja 0.1 pranon përputhje të dobëta, etapat e mëvonshme zgjedhin më të mirën",
|
||||
"dtw_blend": "Etapa 3: 0 = vetëm rezultati bazë, 1 = vetëm rezultati DTW, 0.5 = përzierje e barabartë (parazgjedhja)",
|
||||
"dtw_ensemble_w": "Etapa 3 (modaliteti ansambël): pesë për L1-e shkallëzuar kundrejt DTW derivativ; parazgjedhja 0.7 favorizon nivelin e fuqisë",
|
||||
"dtw_ddtw_scale": "Etapa 3: distanca e gjysmë-ngopjes DDTW; më e vogël = më e ndjeshme ndaj formës (parazgjedhja 30)",
|
||||
"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)"
|
||||
},
|
||||
"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.",
|
||||
@@ -1766,6 +1820,68 @@
|
||||
},
|
||||
"pg_sweep": {
|
||||
"optimize": "Optimizim: {param}"
|
||||
},
|
||||
"pg_detail": {
|
||||
"simulate": "Simulimi i ciklit"
|
||||
},
|
||||
"split": {
|
||||
"apply": "Ndarja e ciklit"
|
||||
},
|
||||
"trim": {
|
||||
"apply": "Prerja e ciklit"
|
||||
},
|
||||
"merge": {
|
||||
"apply": "Bashkimi i cikleve"
|
||||
},
|
||||
"rebuild": {
|
||||
"envelopes": "Rindërtimi i zarfave"
|
||||
}
|
||||
},
|
||||
"setup": {
|
||||
"hdr": {
|
||||
"card": "Konfigurimi i pajisjes",
|
||||
"healthy_chip": "Konfigurimi u kompletua"
|
||||
},
|
||||
"phase0": {
|
||||
"washer": "WashData tashmë po zbulon ciklet tuaja. Regjistroni ciklin tuaj të parë për të aktivizuar emrat e programeve dhe vlerësimet e kohës.",
|
||||
"dishwasher": "WashData po vëzhgon. Lavatriçet e enëve kanë cikle komplekse – regjistrimi i ciklit tuaj të parë rekomandohet fuqimisht. Nëse një cikël i zbuluar zgjat shumë, përdorni redaktuesin e ciklit për ta prerë para se ta ruani si profil.",
|
||||
"generic": "WashData po vëzhgon. Regjistroni ose etiketoni një cikël të zbuluar për të filluar ndërtimin e profileve."
|
||||
},
|
||||
"phase1a": {
|
||||
"labelled": "Fillim i mirë – programi juaj i parë është ruajtur. Për të dhëna sa më të pastra, merrni parasysh regjistrimin e ciklit tuaj të ardhshëm me veglën e regjistruesit."
|
||||
},
|
||||
"phase1b": {
|
||||
"recorded": "Regjistrimi juaj u ruajt si {profile_name}. Tani regjistroni ose etiketoni programet tuaja të tjera të zakonshme për të ndërtuar mbulimin."
|
||||
},
|
||||
"phase1c": {
|
||||
"verify": "Keni {count} programe nga komuniteti. Ekzekutoni një cikël për të verifikuar nëse WashData e njeh saktë – përputhja do të përmirësohet ndërsa pajisja juaj ndërton historinë e vet."
|
||||
},
|
||||
"phase2": {
|
||||
"cluster": "WashData ka parë {count} cikle që nuk përputhen me asnjë program të ruajtur – ato duken të ngjashme me njëra-tjetrën. Dëshironi të krijoni një profil të ri për to?",
|
||||
"unmatched": "Cikli juaj i fundit nuk u përputh me asnjë program të ruajtur. A është një program i ri?"
|
||||
},
|
||||
"phase3": {
|
||||
"suggestions": "WashData ka rekomandime për cilësimet bazuar në historikun tuaj të cikleve – shqyrtojini ato për të përmirësuar saktësinë e zbulimit.",
|
||||
"groups": "Disa nga profilet tuaja duken si i njëjti program në temperatura të ndryshme. Organizojini ato në një grup për përputhje më të mirë.",
|
||||
"phases": "Shtoni faza programi te {profile_name} për vlerësime më të sakta të kohës së mbetur."
|
||||
},
|
||||
"phase4": {
|
||||
"healthy": "Kjo pajisje është konfiguruar plotësisht ({profile_count} profile)."
|
||||
},
|
||||
"cta": {
|
||||
"start_recording": "Fillo regjistrimin",
|
||||
"label_detected_cycle": "Kam tashmë një cikël të zbuluar – etiketoje atë",
|
||||
"browse_cycles": "Shfleto ciklet për të etiketuar një tjetër",
|
||||
"view_profiles": "Shiko profilet tuaja",
|
||||
"create_from_cluster": "Krijo profil nga këto cikle",
|
||||
"create_profile": "Krijo një profil për të",
|
||||
"review_suggestions": "Shqyrto sugjerimet",
|
||||
"organise_profiles": "Organizo profilet",
|
||||
"configure_phases": "Konfiguro fazat",
|
||||
"skip_step": "Anashkalo këtë hap",
|
||||
"skip_forever": "Mos shfaq më",
|
||||
"hide_guidance": "Fshih udhëzuesin",
|
||||
"show_guidance": "Shfaq udhëzuesin"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
{
|
||||
"badge": {
|
||||
"artifact_tip": "Otkriveno je {n} anomalija (npr. vrata otvorena usred ciklusa) — otvorite da ih vidite na grafikonu",
|
||||
"artifact_tip": "Otkriveno je {n} anomalija (npr. vrata otvorena usred ciklusa) – otvorite da ih vidite na grafikonu",
|
||||
"auto": "(automatski otkriveno)",
|
||||
"built_in_tag": "ugrađen",
|
||||
"declining": "↘ opadajući",
|
||||
"energy_low": "Manja potrošnja energije nego obično",
|
||||
"energy_spike": "Veća potrošnja energije nego obično",
|
||||
"fair_fit": "prihvatljiva kvaliteta",
|
||||
"fair_fit_tip": "Umerena doslednost podudaranja — neki ciklusi dodeljeni ovom profilu imaju niže ocene pouzdanosti. Označite više ciklusa ili ponovo snimite profil da biste poboljšali tačnost.",
|
||||
"fair_fit_tip": "Umerena doslednost podudaranja – neki ciklusi dodeljeni ovom profilu imaju niže ocene pouzdanosti. Označite više ciklusa ili ponovo snimite profil da biste poboljšali tačnost.",
|
||||
"feedback_requested": "Zatražena povratna informacija",
|
||||
"golden_cycle": "Snimljeni referentni ciklus",
|
||||
"improving": "↗ poboljšava se",
|
||||
@@ -15,7 +15,7 @@
|
||||
"needs_review": "Potreban pregled",
|
||||
"overrun": "Trajao duže nego obično",
|
||||
"poor_fit": "loša kvaliteta",
|
||||
"poor_fit_tip": "Nedosledna istorija podudaranja — razmislite o ponovnoj izgradnji ovog profila",
|
||||
"poor_fit_tip": "Nedosledna istorija podudaranja – razmislite o ponovnoj izgradnji ovog profila",
|
||||
"restart_gap_tip": "{n} HA praznina ponovnog pokretanja: trag snage ima rupu",
|
||||
"reviewed": "Pregledano",
|
||||
"steady": "→ stabilan",
|
||||
@@ -87,7 +87,7 @@
|
||||
"on_cycle_finished": "Po završetku ciklusa",
|
||||
"on_cycle_started": "Po pokretanju ciklusa",
|
||||
"pause_cycle": "Pauziraj",
|
||||
"pause_cycle_tip": "Pauziraj aktivni ciklus — uređaj će se nastaviti od mesta gde je stao",
|
||||
"pause_cycle_tip": "Pauziraj aktivni ciklus – uređaj će se nastaviti od mesta gde je stao",
|
||||
"pg_apply_device": "Primeni na uređaj",
|
||||
"pg_autofill": "Automatsko popunjavanje",
|
||||
"play": "Reprodukuj",
|
||||
@@ -97,8 +97,8 @@
|
||||
"process_tip": "Sačuvaj snimljeni trag kao novi ili postojeći profil",
|
||||
"rebuild": "Obnovi omotače",
|
||||
"rebuild_envelope": "Obnovi omotač",
|
||||
"rebuild_tip": "Ponovo izračunaj očekivani omotač snage (min/maks opseg) za sve profile iz njihovih označenih ciklusa — pokreni nakon označavanja novih ciklusa ili ispravljanja starih",
|
||||
"rec_start_tip": "Počni snimanje traga snage uređaja — pokreni neposredno pre pokretanja ciklusa",
|
||||
"rebuild_tip": "Ponovo izračunaj očekivani omotač snage (min/maks opseg) za sve profile iz njihovih označenih ciklusa – pokreni nakon označavanja novih ciklusa ili ispravljanja starih",
|
||||
"rec_start_tip": "Počni snimanje traga snage uređaja – pokreni neposredno pre pokretanja ciklusa",
|
||||
"rec_stop": "Zaustavi",
|
||||
"rec_stop_tip": "Zaustavi snimanje i zadrži snimljeni trag radi pregleda",
|
||||
"record": "Počni snimanje",
|
||||
@@ -231,7 +231,7 @@
|
||||
"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": "{n} konflikt{s} podešavanja – proverite istaknute odeljke i ispravite pre čuvanja.",
|
||||
"settings_banner_btn": "Idi na prvi"
|
||||
},
|
||||
"hdr": {
|
||||
@@ -451,9 +451,9 @@
|
||||
"show_expected": "Prikaži preklop očekivane krive (usklađeni profil, narandžasta)",
|
||||
"show_raw": "Prikaži prekidač sirovih očitavanja utičnice u živom grafu snage",
|
||||
"sparkline": "Nedavni trend trajanja ciklusa",
|
||||
"stage2": "Etapa 2 — osnovna sličnost",
|
||||
"stage3": "Etapa 3 — DTW",
|
||||
"stage4": "Etapa 4 — slaganje",
|
||||
"stage2": "Etapa 2 – osnovna sličnost",
|
||||
"stage3": "Etapa 3 – DTW",
|
||||
"stage4": "Etapa 4 – slaganje",
|
||||
"status": "Status",
|
||||
"tail_trim": "Isecanje kraja (s)",
|
||||
"timer_auto_pause": "Automatska pauza",
|
||||
@@ -561,7 +561,12 @@
|
||||
"flags": "Oznake",
|
||||
"include_phase_map": "Uključi mapu faza",
|
||||
"include_settings": "Uključi podešavanja",
|
||||
"show_contributor": "Prikaži saradnika"
|
||||
"show_contributor": "Prikaži saradnika",
|
||||
"task_pg_detail": "Simuliraj ciklus",
|
||||
"task_split": "Deljenje ciklusa",
|
||||
"task_trim": "Obrezivanje ciklusa",
|
||||
"task_merge": "Spajanje ciklusa",
|
||||
"task_rebuild": "Ponovna izgradnja omotača"
|
||||
},
|
||||
"log": {
|
||||
"all_levels": "Svi nivoi",
|
||||
@@ -645,7 +650,7 @@
|
||||
"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.",
|
||||
"artifact_header": "{n} anomalija otkrivenih tokom ovog ciklusa",
|
||||
"artifact_pause_detail": "Snaga je pala gotovo na nulu za ~{n} s i zatim se obnovila — verovatno su se otvorila vrata usred ciklusa ili je ciklus bio pauziran.",
|
||||
"artifact_pause_detail": "Snaga je pala gotovo na nulu za ~{n} s i zatim se obnovila – verovatno su se otvorila vrata usred ciklusa ili je ciklus bio pauziran.",
|
||||
"artifact_spike_detail": "Prešao uobičajeni opseg snage za ~{n} s.",
|
||||
"auto_label_intro": "Dodeli profile neoznačenim ciklusima čija pouzdanost podudaranja prelazi prag.",
|
||||
"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.",
|
||||
@@ -654,10 +659,10 @@
|
||||
"collecting_data": "Prikupljanje podataka: još {need} ciklusa do početka finog podešavanja ({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",
|
||||
"compare_selected_cycles": "Izabrani ciklusi (neprozirni) – prikaži / sakrij",
|
||||
"consider_new_profile": "Razmislite o kreiranju novog profila.",
|
||||
"coverage_gap": "nedavni ciklusi nemaju odgovarajući profil ({pct}% od poslednjih 30).",
|
||||
"coverage_gap_similar_cycles": "{count} sličnih neoznačenih ciklusa pronađeno — napravite profil da biste počeli njihovo podudaranje.",
|
||||
"coverage_gap_similar_cycles": "{count} sličnih neoznačenih ciklusa pronađeno – napravite profil da biste počeli njihovo podudaranje.",
|
||||
"cycles_deleted": "Obrisano ciklusa: {count}",
|
||||
"enough_data": "Dovoljno podataka za učenje ({current}/{min} ciklusa).",
|
||||
"export_description": "Izvezite sve profile i cikluse u JSON ili vratite iz prethodnog izvoza.",
|
||||
@@ -686,7 +691,7 @@
|
||||
"ml_learned_intro": "Modeli fino podešeni za ovu mašinu.",
|
||||
"ml_loading": "učitavanje ML…",
|
||||
"ml_settings_intro": "Dve nezavisne sklopke: jedna primenjuje modele dok se ciklus izvodi, druga omogućava WashData da ih fino podesi za vašu mašinu tokom vremena.",
|
||||
"name_first_program": "Imate dovoljno ciklusa — imenujte svoj prvi program da biste započeli uparivanje.",
|
||||
"name_first_program": "Imate dovoljno ciklusa – imenujte svoj prvi program da biste započeli uparivanje.",
|
||||
"near_duplicate_cluster": "otkrivena je skoro duplirana grupa profila. Grupisanje omogućava pouzdano podudaranje da bira između sličnih (npr. isti program na različitoj temperaturi/centrifugiranju).",
|
||||
"no_cycles_match": "Nema ciklusa koji odgovaraju trenutnom filteru.",
|
||||
"no_cycles_profile": "Nema ciklusa za ovaj profil.",
|
||||
@@ -696,7 +701,7 @@
|
||||
"no_devices": "Nema WashData uređaja konfigurisanih još.",
|
||||
"no_envelope": "Nema omotača još - obnovi nakon označavanja ciklusa.",
|
||||
"no_envelope_overlay": "Nema dostupnog omotača za preklapanje.",
|
||||
"no_fine_tuned": "Ništa fino podešeno još — WashData koristi ugrađene modele.",
|
||||
"no_fine_tuned": "Ništa fino podešeno još – WashData koristi ugrađene modele.",
|
||||
"no_logs": "Nema dnevničkih zapisa baferovanih još.",
|
||||
"no_maintenance": "Održavanje još nije zabeleženo.",
|
||||
"no_match_yet": "Nema pokušaja podudaranja još - ovo se popunjava tokom aktivnog ciklusa.",
|
||||
@@ -713,7 +718,7 @@
|
||||
"notify_services_hint": "Koristite ID-ove servisa {entity} (odvojene zarezima za više). Promenljive šablona: {vars}.",
|
||||
"old_actions_warning": "Konfigurisano sa starim uređivačem radnji (sada uklonjeno). I dalje se aktiviraju na događaje ciklusa, ali više ne mogu da se uređuju ovde. Pretvorite ih u normalnu automatizaciju ili ih uklonite.",
|
||||
"onboarding_progress": "Posmatrano ciklusa: {n} / 3",
|
||||
"onboarding_watching": "Koristite uređaj normalno — WashData posmatra. Nakon 3 ciklusa počeće uparivanje programa.",
|
||||
"onboarding_watching": "Koristite uređaj normalno – WashData posmatra. Nakon 3 ciklusa počeće uparivanje programa.",
|
||||
"pending_feedback": "Povratna informacija detekcije na čekanju",
|
||||
"performance_trend": "Trend učinka ({n} ciklusa)",
|
||||
"pg_analysis_empty": "Učitajte ciklus da vidite analizu poklapanja.",
|
||||
@@ -763,7 +768,7 @@
|
||||
"setting_changed": "Promenjeno sa {old} na {new} dana {date}",
|
||||
"settings_basic_note": "Prikazuju se osnovna podešavanja. Prebacite na Napredno za potpunu listu.",
|
||||
"shape_drift_advisory": "⚠ Pomeraj oblika",
|
||||
"shape_drift_detail": "Obrazac snage ovog profila se promenio s vremenom — moguće habanje uređaja ili potrebno održavanje (npr. uklanjanje kamenca, čišćenje filtera).",
|
||||
"shape_drift_detail": "Obrazac snage ovog profila se promenio s vremenom – moguće habanje uređaja ili potrebno održavanje (npr. uklanjanje kamenca, čišćenje filtera).",
|
||||
"show_all_settings": "Prikaži sva podešavanja",
|
||||
"showing_suggestions": "Prikazuje se podešavanje {count} sa prijedlozima.",
|
||||
"split_intro": "Klikni na grafikon za dodavanje ili uklanjanje tačke deljenja, ili automatski otkrij po prazninama. Svaki rezultujući segment može dobiti sopstveni profil.",
|
||||
@@ -789,10 +794,10 @@
|
||||
"toast_revert_failed": "Povrat nije uspeo: {error}",
|
||||
"toast_reverted": "{key} vraćeno",
|
||||
"toast_save_failed": "Čuvanje nije uspelo: {error}",
|
||||
"trend_duration_longer": "Trajanje je u trendu duže ({pct}%/ciklus) — nedavno u proseku {avg}",
|
||||
"trend_duration_shorter": "Trajanje u trendu kraće ({pct}%/ciklus) — nedavno u proseku {avg}",
|
||||
"trend_duration_longer": "Trajanje je u trendu duže ({pct}%/ciklus) – nedavno u proseku {avg}",
|
||||
"trend_duration_shorter": "Trajanje u trendu kraće ({pct}%/ciklus) – nedavno u proseku {avg}",
|
||||
"trend_energy_down": "Energija opada ({pct}%/ciklus)",
|
||||
"trend_energy_up": "Energetski trend raste ({pct}%/ciklus) — nedavni prosek {avg}",
|
||||
"trend_energy_up": "Energetski trend raste ({pct}%/ciklus) – nedavni prosek {avg}",
|
||||
"trim_intro": "Prevuci crvene ručice ili unesi vrednosti. Sve izvan prozora se uklanja.",
|
||||
"tuning_suggestions_available": "{count} prijedlog podešavanja dostupan je iz posmatranih ciklusa. Pojavljuju se pored relevantnih polja.",
|
||||
"unsure_detected_prefix": "WashData nije siguran da je otkrio",
|
||||
@@ -857,7 +862,9 @@
|
||||
"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"
|
||||
"share_profile_no_cycles": "Profil '{p}' nema ⭐ referentnih ciklusa -- biće preskočen osim ako nemate {n}+ potvrđenih pokretanja",
|
||||
"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"
|
||||
},
|
||||
"phase_desc": {
|
||||
"anti_crease": "Povremena kratka okretanja nakon završetka radi smanjenja gužvanja.",
|
||||
@@ -940,6 +947,10 @@
|
||||
"triggers": {
|
||||
"intro": "Opcionalni spoljni signali: okidač kraja, senzor vrata, prekidač pauze i podsetnik za istovar.",
|
||||
"label": "Okidači i vrata"
|
||||
},
|
||||
"phase_eta": {
|
||||
"label": "Preostalo vreme",
|
||||
"intro": "Procena preostalog vremena zasnovana na fazama, za mašine čija dužina ciklusa zavisi od temperature ili centrifuge."
|
||||
}
|
||||
},
|
||||
"setting": {
|
||||
@@ -1023,6 +1034,10 @@
|
||||
"doc": "Fiksna cena po kVh koja se koristi za brojke troškova kada nije postavljen nijedan entitet cene uživo iznad.",
|
||||
"label": "Statična cena energije (po kWh)"
|
||||
},
|
||||
"energy_sensor": {
|
||||
"doc": "Opciono kumulativno brojilo energije (total_increasing kWh/Wh, npr. sopstveno brojilo ukupne potrošnje utičnice). Kada je postavljeno, energija prijavljena za svaki ciklus uzima se iz razlike očitavanja ovog brojila između početka i kraja, čime se izbegava potcenjivanje koje nastaje integracijom sporo izveštavajućeg senzora snage. Vraća se na integrisanu vrednost ako očitavanje nedostaje, njegova jedinica je nepoznata ili razlika nije pozitivna. Ostavite prazno da biste nastavili da integrišete senzor snage.",
|
||||
"label": "Entitet brojila energije"
|
||||
},
|
||||
"expose_debug_entities": {
|
||||
"doc": "Objavite dodatne dijagnostičke HA entitete (pouzdanost podudaranja, dvosmislenost, unutrašnje karakteristike stanja). Isključeno održava listu entiteta čistom za normalnu upotrebu.",
|
||||
"label": "Izloži entitete za otklanjanje grešaka"
|
||||
@@ -1305,6 +1320,38 @@
|
||||
},
|
||||
"show_contributor": {
|
||||
"doc": "Prikaži ime saradnika na profilima preuzetim iz prodavnice zajednice"
|
||||
},
|
||||
"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."
|
||||
},
|
||||
"keep_min_score": {
|
||||
"label": "Min. rezultat podudaranja",
|
||||
"doc": "Minimalni rezultat sličnosti koji kandidat mora imati da bi ostao u utrci podudaranja. Podrazumevana vrednost 0,1 je namerno benigna - prihvata čak i slabe kandidate i oslanja se na kasnijе faze za pronalazak najboljeg podudaranja. Povećajte za ranije odbacivanje neprobabilnih profila; smanjite za proširenje početnog skupa kandidata."
|
||||
},
|
||||
"dtw_blend": {
|
||||
"label": "Mešanje deformacije",
|
||||
"doc": "Koliko DTW rezultat poravnanja zamenjuje osnovni rezultat Faze 2. 0 = koristi samo rezultat Faze 2, 1 = koristi samo DTW rezultat, 0,5 (podrazumevano) = jednako mešanje. Povećajte za veće oslanjanje na warp poravnanje kada programi imaju slične nivoe snage ali različite obrasce tajminga."
|
||||
},
|
||||
"dtw_ensemble_w": {
|
||||
"label": "Miks kombinacije DTW",
|
||||
"doc": "U kombinovanom DTW režimu (podrazumevanom), težina skaliranog L1 naspram derivatnog DTW (DDTW). 1,0 = sve skalirano L1, 0 = sve DDTW, 0,7 = podrazumevano. Skalirana L1 varijanta upoređuje nivoe snage; derivatna varijanta reaguje na promene snage tokom vremena. Kombinovani režim spaja oba."
|
||||
},
|
||||
"dtw_ddtw_scale": {
|
||||
"label": "Razmera derivatne deformacije",
|
||||
"doc": "Rastojanje polu-zasićenja za ocenjivanje derivatnim DTW. Rezultat se prepolovi kada rastojanje DDTW bude jednako ovoj vrednosti. Manje = osetljivije na razlike u obliku. Podrazumevana vrednost 30 je kalibrisana za tipične tragove snage kućanskih uređaja. Utiče samo na kombinovani i ddtw DTW režim."
|
||||
},
|
||||
"dtw_refine_top_n": {
|
||||
"label": "Broj preciziranih kandidata",
|
||||
"doc": "Koliko prvih kandidata Faze 2 DTW ponovo ocenjuje. DTW je skuplji pa se primenjuje samo na N najboljih kandidata. Podrazumevano 5. Povećajte (na 7-9) ako ispravni profil ponekad dostigne samo 4. ili 5. mesto nakon Faze 2 - DTW ga može spasiti. Smanjenje malo ubrzava podudaranje."
|
||||
},
|
||||
"duration_scale": {
|
||||
"label": "Ostrina trajanja",
|
||||
"doc": "Oštrina kazne za nepodudaranje trajanja u Fazi 4. Ovo je odnos logaritma pri kome se rezultat slaganja prepolovi. Manje = strože: nepodudaranje trajanja više snižava rezultat. Podrazumevana vrednost 0,175 odgovara toleranciji trajanja od oko 18% pri polu-težini. Koristite zajedno s Težinom trajanja."
|
||||
},
|
||||
"energy_scale": {
|
||||
"label": "Ostrina energije",
|
||||
"doc": "Oštrina kazne za nepodudaranje energije u Fazi 4. Manje = strože: nepodudaranje energije više snižava rezultat. Podrazumevana vrednost 0,25 je namerno blaža od Oštrine trajanja jer energija varira s opterećenjem. Koristite zajedno s Težinom energije."
|
||||
}
|
||||
},
|
||||
"setting_group": {
|
||||
@@ -1424,24 +1471,24 @@
|
||||
"lower": "Više ciklusa se automatski označava; neki mogu biti pogrešno identifikovani"
|
||||
},
|
||||
"duration_tolerance": {
|
||||
"higher": "Prihvata širi opseg trajanja — fleksibilnije podudaranje",
|
||||
"lower": "Zahteva bliže podudaranje trajanja — strože, ali može odbiti neobične cikluse"
|
||||
"higher": "Prihvata širi opseg trajanja – fleksibilnije podudaranje",
|
||||
"lower": "Zahteva bliže podudaranje trajanja – strože, ali može odbiti neobične cikluse"
|
||||
},
|
||||
"end_energy_threshold": {
|
||||
"higher": "Zatvara samo cikluse sa značajnom potrošnjom energije",
|
||||
"lower": "Zatvara i kraće ili manje energetske cikluse"
|
||||
},
|
||||
"end_repeat_count": {
|
||||
"higher": "Zahteva više ponavljanja signala kraja — pouzdanije, malo sporije",
|
||||
"lower": "Završava nakon manje ponavljanja — brže otkrivanje, veći rizik lažnog završetka"
|
||||
"higher": "Zahteva više ponavljanja signala kraja – pouzdanije, malo sporije",
|
||||
"lower": "Završava nakon manje ponavljanja – brže otkrivanje, veći rizik lažnog završetka"
|
||||
},
|
||||
"learning_confidence": {
|
||||
"higher": "Uči se samo iz visoko pouzdanih podudaranja — sporije, ali pouzdanije",
|
||||
"higher": "Uči se samo iz visoko pouzdanih podudaranja – sporije, ali pouzdanije",
|
||||
"lower": "Uči se iz više ciklusa; model može biti manje precizan"
|
||||
},
|
||||
"min_off_gap": {
|
||||
"higher": "Potreban je duži odmor pre početka novog ciklusa",
|
||||
"lower": "Kratak odmor pokreće novi ciklus — uzastopni ciklusi se mogu razdeliti"
|
||||
"lower": "Kratak odmor pokreće novi ciklus – uzastopni ciklusi se mogu razdeliti"
|
||||
},
|
||||
"min_power": {
|
||||
"higher": "Manje osetljiv na potrošnju u mirovanju; može propustiti tihe programe",
|
||||
@@ -1452,24 +1499,24 @@
|
||||
"lower": "Zaglavljen ciklus se prisilno zaustavlja ranije"
|
||||
},
|
||||
"off_delay": {
|
||||
"higher": "Više vremena za pauze uređaja — prikladno za duge faze namakanja ili sušenja",
|
||||
"lower": "Brže otkrivanje kraja — dobro za uređaje s čistim uključivanjem/isključivanjem"
|
||||
"higher": "Više vremena za pauze uređaja – prikladno za duge faze namakanja ili sušenja",
|
||||
"lower": "Brže otkrivanje kraja – dobro za uređaje s čistim uključivanjem/isključivanjem"
|
||||
},
|
||||
"profile_match_threshold": {
|
||||
"higher": "Potvrđuje samo visoko pouzdana podudaranja; više ciklusa ostaje neoznačeno",
|
||||
"lower": "Podudara više ciklusa; neki mogu biti blago pogrešni"
|
||||
},
|
||||
"running_dead_zone": {
|
||||
"higher": "Zanemaruje kratke skokove snage tokom mirovanja — manje osetljiv na šum",
|
||||
"lower": "Reaguje na kraće impulse snage — otkriva brzu prolaznu aktivnost"
|
||||
"higher": "Zanemaruje kratke skokove snage tokom mirovanja – manje osetljiv na šum",
|
||||
"lower": "Reaguje na kraće impulse snage – otkriva brzu prolaznu aktivnost"
|
||||
},
|
||||
"start_threshold_w": {
|
||||
"higher": "Sprečava lažne startove od kratkih skokova snage",
|
||||
"lower": "Otkriva programe s niskom snagom; može reagovati na šum"
|
||||
},
|
||||
"stop_threshold_w": {
|
||||
"higher": "Završava ciklus brže — može zatvoriti tokom pauze",
|
||||
"lower": "Duže čeka na završetak — manje prevremenih završetaka"
|
||||
"higher": "Završava ciklus brže – može zatvoriti tokom pauze",
|
||||
"lower": "Duže čeka na završetak – manje prevremenih završetaka"
|
||||
},
|
||||
"watchdog_interval": {
|
||||
"higher": "Dozvoljava duže tihe faze; manje lažnih prisilnih zaustavljanja",
|
||||
@@ -1676,12 +1723,19 @@
|
||||
"start_duration_threshold": "Sekundi iznad praga za potvrdu pokretanja",
|
||||
"start_threshold_w": "Minimum vati da bi se računalo kao pokrenuto",
|
||||
"stop_threshold_w": "Ispod ovoga mašina se računa kao isključena",
|
||||
"dtw_bandwidth": "Koliko vremenskog izobličenja dozvoljava podudaranje oblika",
|
||||
"corr_weight": "Težina oblika krive u odnosu na nivo snage pri podudaranju",
|
||||
"duration_weight": "Koliko slaganje trajanja utiče na podudaranje",
|
||||
"energy_weight": "Koliko slaganje potrošnje energije utiče na podudaranje",
|
||||
"profile_match_min_duration_ratio": "Najkraće izvođenje (u odnosu na profil) koje još može da se podudari",
|
||||
"profile_match_max_duration_ratio": "Najduže izvođenje (u odnosu na profil) koje još može da se podudari"
|
||||
"dtw_bandwidth": "Faza 3: warp opseg Sakoe-Chiba (0 = DTW isključen; podrazumevano 0,2 = 20% dužine ciklusa)",
|
||||
"corr_weight": "Faza 2: ravnoteža između oblika krive (korelacija) i nivoa snage (MAE); podrazumevano 0,45",
|
||||
"duration_weight": "Faza 4: koliko jako slaganje trajanja utiče na konačni rezultat (podrazumevano 0,22)",
|
||||
"energy_weight": "Faza 4: koliko jako slaganje energije utiče na konačni rezultat (podrazumevano 0,22)",
|
||||
"profile_match_min_duration_ratio": "Faza 1: minimalna dužina ciklusa kao udeo trajanja profila; podrazumevano 0,1 (10%)",
|
||||
"profile_match_max_duration_ratio": "Faza 1: maksimalna dužina ciklusa kao udeo trajanja profila; podrazumevano 1,5 (150%)",
|
||||
"keep_min_score": "Faza 2: minimalni rezultat za ostanak u utrci; podrazumevano 0,1 prihvata slaba podudaranja, kasniji koraci biraju najbolje",
|
||||
"dtw_blend": "Faza 3: 0 = samo osnovni rezultat, 1 = samo DTW rezultat, 0,5 = jednako mešanje (podrazumevano)",
|
||||
"dtw_ensemble_w": "Faza 3 (kombinovani režim): težina skaliranog L1 naspram derivatnog DTW; podrazumevano 0,7 favorizuje nivo",
|
||||
"dtw_ddtw_scale": "Faza 3: rastojanje polu-zasićenja DDTW; manje = osetljivije na oblik (podrazumevano 30)",
|
||||
"dtw_refine_top_n": "Faza 3: kandidati koje DTW ponovo ocenjuje; povećajte na 7-9 ako ispravni profil zauzme 4.-5. mesto (podrazumevano 5)",
|
||||
"duration_scale": "Faza 4: odnos logaritma gde se slaganje trajanja prepolovi; manje = stroža kazna (podrazumevano 0,175)",
|
||||
"energy_scale": "Faza 4: odnos logaritma gde se slaganje energije prepolovi; manje = stroža kazna (podrazumevano 0,25)"
|
||||
},
|
||||
"col": {
|
||||
"profile_tip": "Naziv podudarnog programa. Bez oznake znači da se na kraju ciklusa nijedan profil nije podudarao.",
|
||||
@@ -1766,6 +1820,68 @@
|
||||
},
|
||||
"pg_sweep": {
|
||||
"optimize": "Optimizacija: {param}"
|
||||
},
|
||||
"pg_detail": {
|
||||
"simulate": "Simuliraj ciklus"
|
||||
},
|
||||
"split": {
|
||||
"apply": "Deljenje ciklusa"
|
||||
},
|
||||
"trim": {
|
||||
"apply": "Obrezivanje ciklusa"
|
||||
},
|
||||
"merge": {
|
||||
"apply": "Spajanje ciklusa"
|
||||
},
|
||||
"rebuild": {
|
||||
"envelopes": "Ponovna izgradnja omotača"
|
||||
}
|
||||
},
|
||||
"setup": {
|
||||
"hdr": {
|
||||
"card": "Podešavanje uređaja",
|
||||
"healthy_chip": "Podešavanje dovršeno"
|
||||
},
|
||||
"phase0": {
|
||||
"washer": "WashData već otkriva vaše cikluse. Snimite prvi ciklus kako biste omogućili nazive programa i procene vremena.",
|
||||
"dishwasher": "WashData posmatra. Mašine za pranje sudova imaju složene cikluse – snimanje prvog ciklusa je izrazito preporučeno. Ako otkriveni ciklus traje predugo, koristite uređivač ciklusa za isecanje pre čuvanja kao profila.",
|
||||
"generic": "WashData posmatra. Snimite ili označite otkriveni ciklus kako biste počeli da gradite profile."
|
||||
},
|
||||
"phase1a": {
|
||||
"labelled": "Dobar početak – vaš prvi program je sačuvan. Za najčistije podatke razmislite o snimanju sledećeg ciklusa pomoću vidžeta za snimanje."
|
||||
},
|
||||
"phase1b": {
|
||||
"recorded": "Vaša snimka sačuvana je kao {profile_name}. Sada snimite ili označite ostale uobičajene programe za izgradnju pokrivenosti."
|
||||
},
|
||||
"phase1c": {
|
||||
"verify": "Imate {count} programa od zajednice. Pokrenite ciklus kako biste proverili da li ih WashData ispravno prepoznaje – poklapanje će se poboljšavati kako vaš uređaj gradi sopstvenu istoriju."
|
||||
},
|
||||
"phase2": {
|
||||
"cluster": "WashData je video {count} ciklusa koji se ne poklapaju ni sa jednim sačuvanim programom – međusobno su slični. Da li želite da napravite novi profil za njih?",
|
||||
"unmatched": "Vaš poslednji ciklus se nije poklopio ni sa jednim sačuvanim programom. Da li je to novi program?"
|
||||
},
|
||||
"phase3": {
|
||||
"suggestions": "WashData ima preporuke podešavanja zasnovane na istoriji vaših ciklusa – pregledajte ih da biste poboljšali tačnost otkrivanja.",
|
||||
"groups": "Neki vaši profili izgledaju kao isti program na različitim temperaturama. Organizujte ih u grupu za bolje poklapanje.",
|
||||
"phases": "Dodajte faze programa u {profile_name} za tačnije procene preostalog vremena."
|
||||
},
|
||||
"phase4": {
|
||||
"healthy": "Ovaj uređaj je u potpunosti podešen ({profile_count} profila)."
|
||||
},
|
||||
"cta": {
|
||||
"start_recording": "Pokreni snimanje",
|
||||
"label_detected_cycle": "Već imam otkriven ciklus – umesto toga ga označi",
|
||||
"browse_cycles": "Pregledaj cikluse za označavanje sledećeg",
|
||||
"view_profiles": "Pogledaj svoje profile",
|
||||
"create_from_cluster": "Napravi profil od ovih ciklusa",
|
||||
"create_profile": "Napravi za njega profil",
|
||||
"review_suggestions": "Preglej predloge",
|
||||
"organise_profiles": "Organizuj profile",
|
||||
"configure_phases": "Konfiguriši faze",
|
||||
"skip_step": "Preskoči ovaj korak",
|
||||
"skip_forever": "Ne prikazuj ponovo",
|
||||
"hide_guidance": "Sakrij uputstvo",
|
||||
"show_guidance": "Prikaži uputstvo"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
{
|
||||
"badge": {
|
||||
"artifact_tip": "{n} anomalier upptäckta (t.ex. dörren öppnades mitt i cykeln) — öppna för att se dem i diagrammet",
|
||||
"artifact_tip": "{n} anomalier upptäckta (t.ex. dörren öppnades mitt i cykeln) – öppna för att se dem i diagrammet",
|
||||
"auto": "(automatiskt identifierat)",
|
||||
"built_in_tag": "inbyggd",
|
||||
"declining": "↘ sjunkande",
|
||||
"energy_low": "Lägre energi än vanligt",
|
||||
"energy_spike": "Högre energi än vanligt",
|
||||
"fair_fit": "acceptabel kvalitet",
|
||||
"fair_fit_tip": "Måttlig matchkonsistens — vissa cykler tilldelade den här profilen har lägre konfidenspoäng. Märk fler cykler eller spela in profilen igen för att förbättra noggrannheten.",
|
||||
"fair_fit_tip": "Måttlig matchkonsistens – vissa cykler tilldelade den här profilen har lägre konfidenspoäng. Märk fler cykler eller spela in profilen igen för att förbättra noggrannheten.",
|
||||
"feedback_requested": "Feedback begärd",
|
||||
"golden_cycle": "Inspelad referenscykel",
|
||||
"improving": "↗ förbättras",
|
||||
@@ -15,7 +15,7 @@
|
||||
"needs_review": "Behöver granskning",
|
||||
"overrun": "Pågick längre än vanligt",
|
||||
"poor_fit": "dålig kvalitet",
|
||||
"poor_fit_tip": "Inkonsekvent matchhistorik — överväg att bygga om den här profilen",
|
||||
"poor_fit_tip": "Inkonsekvent matchhistorik – överväg att bygga om den här profilen",
|
||||
"restart_gap_tip": "{n} HA-omstartslucka: effektspåret har ett hål",
|
||||
"reviewed": "Granskad",
|
||||
"steady": "→ stabil",
|
||||
@@ -87,7 +87,7 @@
|
||||
"on_cycle_finished": "När cykeln är klar",
|
||||
"on_cycle_started": "När cykeln startar",
|
||||
"pause_cycle": "Pausa",
|
||||
"pause_cycle_tip": "Pausa den pågående cykeln — apparaten återupptar där den slutade",
|
||||
"pause_cycle_tip": "Pausa den pågående cykeln – apparaten återupptar där den slutade",
|
||||
"pg_apply_device": "Tillämpa på enhet",
|
||||
"pg_autofill": "Autofyll",
|
||||
"play": "Spela",
|
||||
@@ -97,8 +97,8 @@
|
||||
"process_tip": "Spara det inspelade spåret som en ny eller befintlig profil",
|
||||
"rebuild": "Bygg om kuvert",
|
||||
"rebuild_envelope": "Bygg om kuvert",
|
||||
"rebuild_tip": "Beräkna om det förväntade effektkuvertet (min/max-band) för alla profiler från deras märkta cykler — kör efter märkning av nya cykler eller korrigering av gamla",
|
||||
"rec_start_tip": "Börja spela in apparatens effektspår — starta strax innan du kör en cykel",
|
||||
"rebuild_tip": "Beräkna om det förväntade effektkuvertet (min/max-band) för alla profiler från deras märkta cykler – kör efter märkning av nya cykler eller korrigering av gamla",
|
||||
"rec_start_tip": "Börja spela in apparatens effektspår – starta strax innan du kör en cykel",
|
||||
"rec_stop": "Stoppa",
|
||||
"rec_stop_tip": "Stoppa inspelningen och behåll det registrerade spåret för granskning",
|
||||
"record": "Starta inspelning",
|
||||
@@ -231,7 +231,7 @@
|
||||
"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": "{n} inställningskonflikt{s} – kontrollera de markerade avsnitten och åtgärda dem innan du sparar.",
|
||||
"settings_banner_btn": "Gå till första"
|
||||
},
|
||||
"hdr": {
|
||||
@@ -451,9 +451,9 @@
|
||||
"show_expected": "Visa förväntat kurvöverlägg (matchad profil, orange)",
|
||||
"show_raw": "Visa växlare för råa uttag-värden i live-effektdiagram",
|
||||
"sparkline": "Trend för senaste cykellängder",
|
||||
"stage2": "Steg 2 — kärnlikhet",
|
||||
"stage3": "Steg 3 — DTW",
|
||||
"stage4": "Steg 4 — överensstämmelse",
|
||||
"stage2": "Steg 2 – kärnlikhet",
|
||||
"stage3": "Steg 3 – DTW",
|
||||
"stage4": "Steg 4 – överensstämmelse",
|
||||
"status": "Status",
|
||||
"tail_trim": "Sluttrimning (s)",
|
||||
"timer_auto_pause": "Automatisk paus",
|
||||
@@ -561,7 +561,12 @@
|
||||
"flags": "Flaggor",
|
||||
"include_phase_map": "Inkludera fasekarta",
|
||||
"include_settings": "Inkludera identifierings- och matchningsinställningar",
|
||||
"show_contributor": "Visa bidragsgivarnamn"
|
||||
"show_contributor": "Visa bidragsgivarnamn",
|
||||
"task_pg_detail": "Simulera cykel",
|
||||
"task_split": "Delar upp cykel",
|
||||
"task_trim": "Beskär cykel",
|
||||
"task_merge": "Slår ihop cykler",
|
||||
"task_rebuild": "Bygger om enveloppar"
|
||||
},
|
||||
"log": {
|
||||
"all_levels": "Alla nivåer",
|
||||
@@ -645,19 +650,19 @@
|
||||
"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.",
|
||||
"artifact_header": "{n} anomalier upptäcktes under denna cykel",
|
||||
"artifact_pause_detail": "Effekten föll till nära noll i ~{n} s och återupptogs sedan — troligtvis öppnades dörren mitt i cykeln eller cykeln pausades.",
|
||||
"artifact_pause_detail": "Effekten föll till nära noll i ~{n} s och återupptogs sedan – troligtvis öppnades dörren mitt i cykeln eller cykeln pausades.",
|
||||
"artifact_spike_detail": "Drog över det normala effektbandet i ~{n} s.",
|
||||
"auto_label_intro": "Tilldela profiler till omärkta cykler vars matchningskonfidens överstiger tröskeln.",
|
||||
"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.",
|
||||
"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}).",
|
||||
"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",
|
||||
"compare_selected_cycles": "Valda cykler (solid) – visa / dölj",
|
||||
"consider_new_profile": "Överväg att skapa en ny profil.",
|
||||
"coverage_gap": "de senaste cyklerna har ingen matchande profil ({pct}% av de senaste 30).",
|
||||
"coverage_gap_similar_cycles": "{count} liknande omärkta cykler hittades — skapa en profil för att börja matcha dem.",
|
||||
"coverage_gap_similar_cycles": "{count} liknande omärkta cykler hittades – skapa en profil för att börja matcha dem.",
|
||||
"cycles_deleted": "{count} cykler borttagna",
|
||||
"enough_data": "Tillräckligt med data för att lära sig av ({current}/{min} cykler).",
|
||||
"export_description": "Exportera alla profiler och cykler till JSON, eller återställ från en tidigare export.",
|
||||
@@ -686,7 +691,7 @@
|
||||
"ml_learned_intro": "Modeller finjusterade till denna maskin.",
|
||||
"ml_loading": "laddar ML…",
|
||||
"ml_settings_intro": "Två oberoende switchar: en tillämpar modellerna medan en cykel körs, den andra låter WashData finjustera dem till din maskin över tid.",
|
||||
"name_first_program": "Du har tillräckligt med cykler — namnge ditt första program för att börja matcha.",
|
||||
"name_first_program": "Du har tillräckligt med cykler – namnge ditt första program för att börja matcha.",
|
||||
"near_duplicate_cluster": "nästan duplicerat profilkluster upptäcktes. Gruppering gör att matchning på ett tillförlitligt sätt kan välja mellan look-alikes (t.ex. samma program vid olika temperaturer/centrifugering).",
|
||||
"no_cycles_match": "Inga cykler matchar det aktuella filtret.",
|
||||
"no_cycles_profile": "Inga cykler för denna profil.",
|
||||
@@ -696,7 +701,7 @@
|
||||
"no_devices": "Inga WashData-enheter konfigurerade än.",
|
||||
"no_envelope": "Inget kuvert ännu - bygg om efter märkning av cykler.",
|
||||
"no_envelope_overlay": "Inget kuvert tillgängligt att lägga över.",
|
||||
"no_fine_tuned": "Inget finjusterat ännu — WashData använder sina inbyggda modeller.",
|
||||
"no_fine_tuned": "Inget finjusterat ännu – WashData använder sina inbyggda modeller.",
|
||||
"no_logs": "Inga loggposter buffrade än.",
|
||||
"no_maintenance": "Inget underhåll registrerat ännu.",
|
||||
"no_match_yet": "Inget matchningsförsök ännu - detta fylls i under en aktiv cykel.",
|
||||
@@ -713,7 +718,7 @@
|
||||
"notify_services_hint": "Använd {entity}-tjänst-ID:n (kommaavgränsade för flera). Mallvariabler: {vars}.",
|
||||
"old_actions_warning": "Konfigurerad med den gamla åtgärdsredigeraren (nu borttagen). De utlöses fortfarande vid cykelhändelser men kan inte längre redigeras här. Konvertera dem till en normal automatisering, eller ta bort dem.",
|
||||
"onboarding_progress": "{n} / 3 cykler observerade",
|
||||
"onboarding_watching": "Använd apparaten som vanligt — WashData observerar. Efter 3 cykler börjar programmatchningen.",
|
||||
"onboarding_watching": "Använd apparaten som vanligt – WashData observerar. Efter 3 cykler börjar programmatchningen.",
|
||||
"pending_feedback": "Väntande detektionsfeedback",
|
||||
"performance_trend": "Prestandatrend ({n} cykler)",
|
||||
"pg_analysis_empty": "Ladda en cykel för att se matchningsanalys.",
|
||||
@@ -763,7 +768,7 @@
|
||||
"setting_changed": "Ändrad från {old} till {new} den {date}",
|
||||
"settings_basic_note": "Visar väsentliga inställningar. Byt till Avancerat för hela listan.",
|
||||
"shape_drift_advisory": "⚠ Form avviker",
|
||||
"shape_drift_detail": "Effektmönstret för den här profilen har förändrats över tid — möjligt apparatslitage eller underhåll behövs (t.ex. avkalkning, filterrengöring).",
|
||||
"shape_drift_detail": "Effektmönstret för den här profilen har förändrats över tid – möjligt apparatslitage eller underhåll behövs (t.ex. avkalkning, filterrengöring).",
|
||||
"show_all_settings": "Visa alla inställningar",
|
||||
"showing_suggestions": "Visar {count} inställning med förslag.",
|
||||
"split_intro": "Klicka på diagrammet för att lägga till eller ta bort en delningspunkt, eller autoidentifiera via tomma luckor. Varje resulterande segment kan få sin egen profil.",
|
||||
@@ -789,10 +794,10 @@
|
||||
"toast_revert_failed": "Återställning misslyckades: {error}",
|
||||
"toast_reverted": "{key} återställd",
|
||||
"toast_save_failed": "Sparning misslyckades: {error}",
|
||||
"trend_duration_longer": "Varaktighet trendar längre ({pct}%/cykel) — senaste medelvärde {avg}",
|
||||
"trend_duration_shorter": "Varaktighet trendar kortare ({pct}%/cykel) — senaste medelvärde {avg}",
|
||||
"trend_duration_longer": "Varaktighet trendar längre ({pct}%/cykel) – senaste medelvärde {avg}",
|
||||
"trend_duration_shorter": "Varaktighet trendar kortare ({pct}%/cykel) – senaste medelvärde {avg}",
|
||||
"trend_energy_down": "Energin går ned ({pct}%/cykel)",
|
||||
"trend_energy_up": "Energitrend uppåt ({pct}%/cykel) — senaste snitt {avg}",
|
||||
"trend_energy_up": "Energitrend uppåt ({pct}%/cykel) – senaste snitt {avg}",
|
||||
"trim_intro": "Dra de röda handtagen eller ange värden. Allt utanför fönstret tas bort.",
|
||||
"tuning_suggestions_available": "{count} inställningsförslag tillgängligt från observerade cykler. De visas bredvid de relevanta fälten.",
|
||||
"unsure_detected_prefix": "WashData är osäker på att den identifierade",
|
||||
@@ -857,7 +862,9 @@
|
||||
"share_guidelines_title": "Innan du delar",
|
||||
"store_download_device_intro": "Ta över alla delade program och deras referenscykler till din apparat. Dina egna inspelade cykler och statistik påverkas inte.",
|
||||
"store_share_device_intro": "Ladda upp {brand} {model} med de referenscykler du väljer. Andra med samma apparat kan ta över dina program. Poster granskas innan de visas offentligt.",
|
||||
"share_profile_no_cycles": "Inga referenscykler -- markera en cykel som ⭐ på fliken Cykler för att inkludera den här profilen"
|
||||
"share_profile_no_cycles": "Inga referenscykler -- markera en cykel som ⭐ på fliken Cykler för att inkludera den här profilen",
|
||||
"advisory_phase_inconsistent": "'{name}' verkar blanda olika program eller temperaturer - dess cykler värms upp under mycket olika lång tid. Om du delar upp den i separata profiler (t.ex. per temperatur) förbättras matchningen och tidsuppskattningarna.",
|
||||
"advisory_phase_inconsistent_title": "⚠ Möjligen blandade program"
|
||||
},
|
||||
"pg_desc": {
|
||||
"abrupt_drop_watts": "Plötsligt fall som tolkas som omedelbart slut",
|
||||
@@ -869,12 +876,19 @@
|
||||
"start_duration_threshold": "Sekunder över tröskeln för att bekräfta start",
|
||||
"start_threshold_w": "Minsta antal watt för att räknas som startad",
|
||||
"stop_threshold_w": "Under detta räknas maskinen som avstängd",
|
||||
"dtw_bandwidth": "Hur mycket tidsförvrängning formmatchningen tillåter",
|
||||
"corr_weight": "Vikt på kurvform kontra effektnivå i matchningen",
|
||||
"duration_weight": "Hur mycket överensstämmelse i körtid påverkar matchningen",
|
||||
"energy_weight": "Hur mycket överensstämmelse i energiförbrukning påverkar matchningen",
|
||||
"profile_match_min_duration_ratio": "Kortaste körning (jämfört med profilen) som fortfarande får matcha",
|
||||
"profile_match_max_duration_ratio": "Längsta körning (jämfört med profilen) som fortfarande får matcha"
|
||||
"dtw_bandwidth": "Steg 3: Sakoe-Chiba-förvrängningsband (0 = DTW av; standard 0,2 = 20% av cykellängd)",
|
||||
"corr_weight": "Steg 2: balans mellan kurvform (korrelation) och effektnivå (MAE); standard 0,45",
|
||||
"duration_weight": "Steg 4: hur starkt körtidsöverensstämmelse påverkar slutpoängen (standard 0,22)",
|
||||
"energy_weight": "Steg 4: hur starkt energiöverensstämmelse påverkar slutpoängen (standard 0,22)",
|
||||
"profile_match_min_duration_ratio": "Steg 1: lägsta cykellängd som andel av profilduration; standard 0,1 (10%)",
|
||||
"profile_match_max_duration_ratio": "Steg 1: högsta cykellängd som andel av profilduration; standard 1,5 (150%)",
|
||||
"keep_min_score": "Steg 2: lägsta poäng för att vara kvar i matchen; standard 0,1 tillåter svaga kandidater, senare steg väljer bäst",
|
||||
"dtw_blend": "Steg 3: 0 = bara kärnpoäng, 1 = bara DTW-poäng, 0,5 = lika blandning (standard)",
|
||||
"dtw_ensemble_w": "Steg 3 (ensemble-läge): vikt på skalad L1 kontra derivativ DTW; standard 0,7 gynnar nivåmedvetenhet",
|
||||
"dtw_ddtw_scale": "Steg 3: DDTW-halvmättnadsavstånd; lägre = mer formkänslig (standard 30)",
|
||||
"dtw_refine_top_n": "Steg 3: kandidater som DTW ompoängsätter; öka till 7-9 om rätt profil placerar sig 4-5:a (standard 5)",
|
||||
"duration_scale": "Steg 4: log-kvot där varaktighetsöverensstämmelse halveras; lägre = striktare straff (standard 0,175)",
|
||||
"energy_scale": "Steg 4: log-kvot där energiöverensstämmelse halveras; lägre = striktare straff (standard 0,25)"
|
||||
},
|
||||
"phase_desc": {
|
||||
"anti_crease": "Enstaka korta tumlar efter färdigställandet för att förhindra skrynklor i tvätten.",
|
||||
@@ -957,6 +971,10 @@
|
||||
"triggers": {
|
||||
"intro": "Valfria externa signaler: en slututlösare, en dörrsensor, en pausknapp och en lossningspåminnelse.",
|
||||
"label": "Utlösare och dörrar"
|
||||
},
|
||||
"phase_eta": {
|
||||
"label": "Återstående tid",
|
||||
"intro": "Fasmedveten återstående tid, för maskiner vars cykellängd beror på temperatur eller centrifugering."
|
||||
}
|
||||
},
|
||||
"setting": {
|
||||
@@ -1040,6 +1058,10 @@
|
||||
"doc": "Fast pris per kWh som används för kostnadssiffror när ingen levande prisenhet anges ovan.",
|
||||
"label": "Statiskt energipris (per kWh)"
|
||||
},
|
||||
"energy_sensor": {
|
||||
"doc": "Valfri kumulativ energiräknare (total_increasing i kWh/Wh, t.ex. uttagets egen livstidsmätare). När den anges hämtas varje cykels rapporterade energi från skillnaden på denna räknare mellan start och slut, vilket undviker den underräkning du får när en långsamt rapporterande effektsensor integreras. Faller tillbaka på det integrerade värdet om avläsningen saknas, dess enhet är okänd eller skillnaden inte är positiv. Lämna tomt för att fortsätta integrera effektsensorn.",
|
||||
"label": "Energimätarentitet"
|
||||
},
|
||||
"expose_debug_entities": {
|
||||
"doc": "Publicera extra diagnostiska HA-enheter (matchningsförtroende, tvetydighet, tillståndsinterna). Av håller enhetslistan ren för normal användning.",
|
||||
"label": "Exponera felsökningsentiteter"
|
||||
@@ -1322,6 +1344,38 @@
|
||||
},
|
||||
"show_contributor": {
|
||||
"doc": "Visar tillskrivningen 'av <contributor>' på gemenskapsapparater och referenscykler."
|
||||
},
|
||||
"enable_phase_matching": {
|
||||
"label": "Fasmedveten återstående tid",
|
||||
"doc": "Dela upp varje pågående cykel i faser (uppvärmning, tvätt, centrifugering) och budgetera den återstående tiden per fas, blandat med den klassiska uppskattningen - tidigt i cykeln lutar den sig mot fasbudgeten och mot slutet mot den klassiska uppskattningen. Detta anpassar nedräkningen efter hur länge din maskin faktiskt värms upp och körs, vilket märks tydligast under den första halvan av en cykel. Av = endast den klassiska uppskattningen. Endast visningen av återstående tid påverkas; programmatchning och cykeldetektering är oförändrade."
|
||||
},
|
||||
"keep_min_score": {
|
||||
"label": "Min matchningspoäng",
|
||||
"doc": "Lägsta likhetspoäng som en kandidat behöver för att vara kvar i matchningen. Standard 0,1 är avsiktligt tillåtande – det tillåter även svaga kandidater och förlitar sig på senare steg för att hitta bästa match. Höj för att gallra bort osannolika profiler tidigare; sänk för att utöka den initiala kandidatpoolen."
|
||||
},
|
||||
"dtw_blend": {
|
||||
"label": "DTW-blandning",
|
||||
"doc": "Hur mycket DTW-justeringspoängen ersätter kärnpoängen från Steg 2. 0 = använd bara Steg 2-poängen, 1 = använd bara DTW-poängen, 0,5 (standard) = lika blandning. Höj om program har liknande effektnivåer men olika timingmönster."
|
||||
},
|
||||
"dtw_ensemble_w": {
|
||||
"label": "DTW-ensemblemix",
|
||||
"doc": "I ensemble-DTW-läge (standard) anger detta vikten på skalad L1 kontra derivativ DTW (DDTW). 1,0 = enbart skalad L1, 0 = enbart DDTW, 0,7 = standard. Den skalade varianten jämför effektnivåer; den derivativa reagerar på hur effekten förändras över tid. Ensemble blandar båda."
|
||||
},
|
||||
"dtw_ddtw_scale": {
|
||||
"label": "Derivativ DTW-skala",
|
||||
"doc": "Halvmättnadsavstånd för derivativ DTW-poängsättning. Poängen halveras när DDTW-avståndet är lika med detta värde. Lägre = mer känslig för formskillnader. Standard 30 är kalibrerad för typiska apparaters effektprofiler. Påverkar bara ensemble- och ddtw-DTW-lägen."
|
||||
},
|
||||
"dtw_refine_top_n": {
|
||||
"label": "DTW-förfinandetal",
|
||||
"doc": "Hur många toppkandidater från Steg 2 som ompoängsätts av DTW. DTW är mer beräkningskrävande så det tillämpas bara på de N bästa. Standard 5. Höj (till 7-9) om rätt profil ibland bara når 4:e eller 5:e plats efter Steg 2 – DTW kan rädda den. Lägre värde snabbar upp matchningen något."
|
||||
},
|
||||
"duration_scale": {
|
||||
"label": "Varaktighetsskärpa",
|
||||
"doc": "Skärpan i Steg 4:s straff för varaktighetsöverensstämmelse. Det är log-kvoten vid vilken överensstämmelsepoängen halveras. Lägre = striktare: en varaktighetsavvikelse straffas mer. Standard 0,175 motsvarar ungefär 18% varaktighetstolerans vid halvvikt. Para ihop med Varaktighetssvikt."
|
||||
},
|
||||
"energy_scale": {
|
||||
"label": "Energiskärpa",
|
||||
"doc": "Skärpan i Steg 4:s straff för energiöverensstämmelse. Lägre = striktare: en energiavvikelse straffas mer. Standard 0,25 är avsiktligt mer tillåtande än varaktighetsskärpan eftersom energiförbrukning varierar med last. Para ihop med Energivikt."
|
||||
}
|
||||
},
|
||||
"setting_group": {
|
||||
@@ -1766,6 +1820,69 @@
|
||||
},
|
||||
"pg_sweep": {
|
||||
"optimize": "Optimera: {param}"
|
||||
},
|
||||
"pg_detail": {
|
||||
"simulate": "Simulera cykel"
|
||||
},
|
||||
"split": {
|
||||
"apply": "Delar upp cykel"
|
||||
},
|
||||
"trim": {
|
||||
"apply": "Beskär cykel"
|
||||
},
|
||||
"merge": {
|
||||
"apply": "Slår ihop cykler"
|
||||
},
|
||||
"rebuild": {
|
||||
"envelopes": "Bygger om enveloppar"
|
||||
},
|
||||
"cancelling": "Avbryter..."
|
||||
},
|
||||
"setup": {
|
||||
"hdr": {
|
||||
"card": "Enhetsinställning",
|
||||
"healthy_chip": "Konfiguration klar"
|
||||
},
|
||||
"phase0": {
|
||||
"washer": "WashData identifierar redan dina cykler. Spela in din första cykel för att aktivera programnamn och tidsuppskattningar.",
|
||||
"dishwasher": "WashData observerar. Diskmaskiner har komplexa cykler – att spela in din första cykel rekommenderas starkt. Om en identifierad cykel körs för länge, använd cykeleditorn för att trimma den innan du sparar den som en profil.",
|
||||
"generic": "WashData observerar. Spela in eller märk en identifierad cykel för att börja bygga profiler."
|
||||
},
|
||||
"phase1a": {
|
||||
"labelled": "Bra start – ditt första program är sparat. För renast möjliga data kan du spela in din nästa cykel med inspelningswidgeten."
|
||||
},
|
||||
"phase1b": {
|
||||
"recorded": "Din inspelning sparades som {profile_name}. Spela nu in eller märk dina andra vanliga program för att bygga upp täckning."
|
||||
},
|
||||
"phase1c": {
|
||||
"verify": "Du har {count} program från gemenskapen. Kör en cykel för att verifiera att WashData identifierar den rätt – matchningen förbättras ju mer historik din enhet bygger upp."
|
||||
},
|
||||
"phase2": {
|
||||
"cluster": "WashData har sett {count} cykler som inte matchar något sparat program – de liknar varandra. Vill du skapa en ny profil för dem?",
|
||||
"unmatched": "Din senaste cykel matchade inget sparat program. Är det ett nytt program?"
|
||||
},
|
||||
"phase3": {
|
||||
"suggestions": "WashData har inställningsrekommendationer baserade på din cykelhistorik – granska dem för att förbättra detekteringens noggrannhet.",
|
||||
"groups": "Några av dina profiler ser ut som samma program vid olika temperaturer. Organisera dem i en grupp för bättre matchning.",
|
||||
"phases": "Lägg till programfaser i {profile_name} för mer exakta uppskattningar av återstående tid."
|
||||
},
|
||||
"phase4": {
|
||||
"healthy": "Den här enheten är helt konfigurerad ({profile_count} profiler)."
|
||||
},
|
||||
"cta": {
|
||||
"start_recording": "Starta inspelning",
|
||||
"label_detected_cycle": "Jag har redan en identifierad cykel – märk den istället",
|
||||
"browse_cycles": "Bläddra bland cykler för att märka en till",
|
||||
"view_profiles": "Visa dina profiler",
|
||||
"create_from_cluster": "Skapa profil från dessa cykler",
|
||||
"create_profile": "Skapa en profil för det",
|
||||
"review_suggestions": "Granska förslag",
|
||||
"organise_profiles": "Organisera profiler",
|
||||
"configure_phases": "Konfigurera faser",
|
||||
"skip_step": "Hoppa över det här steget",
|
||||
"skip_forever": "Visa inte igen",
|
||||
"hide_guidance": "Dölj vägledning",
|
||||
"show_guidance": "Visa vägledning"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
{
|
||||
"badge": {
|
||||
"artifact_tip": "{n} anormallik algılandı (ör. döngünün ortasında kapının açılması) — bunları grafikte görmek için açın",
|
||||
"artifact_tip": "{n} anormallik algılandı (ör. döngünün ortasında kapının açılması) – bunları grafikte görmek için açın",
|
||||
"auto": "(otomatik algılandı)",
|
||||
"built_in_tag": "yerleşik",
|
||||
"declining": "↘ düşüyor",
|
||||
"energy_low": "Normalden düşük enerji",
|
||||
"energy_spike": "Normalden yüksek enerji",
|
||||
"fair_fit": "kabul edilebilir kalite",
|
||||
"fair_fit_tip": "Orta düzeyde eşleşme tutarlılığı — bu profile atanan bazı döngülerin güven puanları daha düşüktür. Doğruluğu artırmak için daha fazla döngü etiketleyin veya profili yeniden kaydedin.",
|
||||
"fair_fit_tip": "Orta düzeyde eşleşme tutarlılığı – bu profile atanan bazı döngülerin güven puanları daha düşüktür. Doğruluğu artırmak için daha fazla döngü etiketleyin veya profili yeniden kaydedin.",
|
||||
"feedback_requested": "Geri bildirim istendi",
|
||||
"golden_cycle": "Kaydedilen referans döngüsü",
|
||||
"improving": "↗ iyileşiyor",
|
||||
@@ -15,7 +15,7 @@
|
||||
"needs_review": "İncelenmesi gerekiyor",
|
||||
"overrun": "Normalden daha uzun sürdü",
|
||||
"poor_fit": "düşük kalite",
|
||||
"poor_fit_tip": "Tutarsız eşleşme geçmişi — bu profili yeniden oluşturmayı düşünün",
|
||||
"poor_fit_tip": "Tutarsız eşleşme geçmişi – bu profili yeniden oluşturmayı düşünün",
|
||||
"restart_gap_tip": "{n} HA yeniden başlatma boşluğu: güç izinde bir delik var",
|
||||
"reviewed": "İncelendi",
|
||||
"steady": "→ sabit",
|
||||
@@ -87,7 +87,7 @@
|
||||
"on_cycle_finished": "Döngü bittiğinde",
|
||||
"on_cycle_started": "Döngü başladığında",
|
||||
"pause_cycle": "Duraklat",
|
||||
"pause_cycle_tip": "Çalışan döngüyü duraklatın — cihaz kaldığı yerden devam edecek",
|
||||
"pause_cycle_tip": "Çalışan döngüyü duraklatın – cihaz kaldığı yerden devam edecek",
|
||||
"pg_apply_device": "Cihaza uygula",
|
||||
"pg_autofill": "Otomatik doldur",
|
||||
"play": "Oynat",
|
||||
@@ -97,8 +97,8 @@
|
||||
"process_tip": "Kaydedilen izi yeni veya mevcut bir profil olarak kaydedin",
|
||||
"rebuild": "Zarfları Yeniden Oluştur",
|
||||
"rebuild_envelope": "Zarfı Yeniden Oluştur",
|
||||
"rebuild_tip": "Tüm profiller için etiketlenmiş döngülerinden beklenen güç zarfını (min/maks bandı) yeniden hesaplayın — yeni döngüler etiketledikten veya eskilerini düzelttikten sonra çalıştırın",
|
||||
"rec_start_tip": "Cihazın güç izini kaydetmeye başlayın — döngü çalıştırmadan hemen önce başlatın",
|
||||
"rebuild_tip": "Tüm profiller için etiketlenmiş döngülerinden beklenen güç zarfını (min/maks bandı) yeniden hesaplayın – yeni döngüler etiketledikten veya eskilerini düzelttikten sonra çalıştırın",
|
||||
"rec_start_tip": "Cihazın güç izini kaydetmeye başlayın – döngü çalıştırmadan hemen önce başlatın",
|
||||
"rec_stop": "Durdur",
|
||||
"rec_stop_tip": "Kaydı durdurun ve yakalanan izi inceleme için saklayın",
|
||||
"record": "Kayda Başla",
|
||||
@@ -182,7 +182,7 @@
|
||||
},
|
||||
"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.",
|
||||
"settings_banner": "{n} ayar çakışması{s} – 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})",
|
||||
@@ -451,9 +451,9 @@
|
||||
"show_expected": "Beklenen eğri bindirmesini göster (eşleşen profil, turuncu)",
|
||||
"show_raw": "Canlı güç grafiğinde ham soket değiştiriciyi göster",
|
||||
"sparkline": "Son döngü süresi eğilimi",
|
||||
"stage2": "Aşama 2 — çekirdek benzerlik",
|
||||
"stage3": "Aşama 3 — DTW",
|
||||
"stage4": "Aşama 4 — uyum",
|
||||
"stage2": "Aşama 2 – çekirdek benzerlik",
|
||||
"stage3": "Aşama 3 – DTW",
|
||||
"stage4": "Aşama 4 – uyum",
|
||||
"status": "Durum",
|
||||
"tail_trim": "Kuyruk Kırpma (s)",
|
||||
"timer_auto_pause": "Otomatik duraklatma",
|
||||
@@ -561,7 +561,12 @@
|
||||
"flags": "İşaretler",
|
||||
"include_phase_map": "Faz haritasını dahil et",
|
||||
"include_settings": "Algılama ve eşleştirme ayarlarını dahil et",
|
||||
"show_contributor": "Katkıda bulunanların adlarını göster"
|
||||
"show_contributor": "Katkıda bulunanların adlarını göster",
|
||||
"task_pg_detail": "Döngü simülasyonu",
|
||||
"task_split": "Döngü bölünüyor",
|
||||
"task_trim": "Döngü kırpılıyor",
|
||||
"task_merge": "Döngüler birleştiriliyor",
|
||||
"task_rebuild": "Zarflar yeniden oluşturuluyor"
|
||||
},
|
||||
"log": {
|
||||
"all_levels": "Tüm seviyeler",
|
||||
@@ -645,7 +650,7 @@
|
||||
"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.",
|
||||
"artifact_header": "Bu döngü sırasında {n} anormallik algılandı",
|
||||
"artifact_pause_detail": "Güç yaklaşık ~{n} saniye boyunca sıfıra yakın düştü, sonra devam etti — döngünün ortasında kapı açılmış veya döngü duraklatılmış olabilir.",
|
||||
"artifact_pause_detail": "Güç yaklaşık ~{n} saniye boyunca sıfıra yakın düştü, sonra devam etti – döngünün ortasında kapı açılmış veya döngü duraklatılmış olabilir.",
|
||||
"artifact_spike_detail": "Normal güç bandının üzerinde yaklaşık ~{n} saniye sürdü.",
|
||||
"auto_label_intro": "Eşleşme güveni eşiği geçen etiketsiz döngülere profil atayın.",
|
||||
"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.",
|
||||
@@ -654,10 +659,10 @@
|
||||
"collecting_data": "Veri toplanıyor: ince ayar başlamadan önce {need} döngü{plural} daha gerekiyor ({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",
|
||||
"compare_selected_cycles": "Seçili döngüler (katı) – göster / gizle",
|
||||
"consider_new_profile": "Yeni bir profil oluşturmayı düşünün.",
|
||||
"coverage_gap": "son döngülerin eşleşen profili yok (son 30 döngünün %{pct}'i).",
|
||||
"coverage_gap_similar_cycles": "{count} benzer etiketsiz döngü bulundu — bunları eşleştirmeye başlamak için bir profil oluşturun.",
|
||||
"coverage_gap_similar_cycles": "{count} benzer etiketsiz döngü bulundu – bunları eşleştirmeye başlamak için bir profil oluşturun.",
|
||||
"cycles_deleted": "{count} döngü silindi",
|
||||
"enough_data": "Öğrenmek için yeterli veri ({current}/{min} döngü).",
|
||||
"export_description": "Tüm profilleri ve döngüleri JSON'a aktarın veya önceki bir dışa aktarma işleminden geri yükleyin.",
|
||||
@@ -686,7 +691,7 @@
|
||||
"ml_learned_intro": "Bu makineye ince ayarlı modeller.",
|
||||
"ml_loading": "ML yükleniyor…",
|
||||
"ml_settings_intro": "İki bağımsız anahtar: biri döngü çalışırken modelleri uygular, diğeri WashData'nın zamanla makinenize ince ayar yapmasına izin verir.",
|
||||
"name_first_program": "Yeterli döngünüz var — eşleştirmeye başlamak için ilk programınıza ad verin.",
|
||||
"name_first_program": "Yeterli döngünüz var – eşleştirmeye başlamak için ilk programınıza ad verin.",
|
||||
"near_duplicate_cluster": "neredeyse yinelenen profil kümesi algılandı. Gruplandırma, eşleştirmenin benzerler arasında güvenilir bir şekilde seçim yapmasına olanak tanır (örneğin, farklı sıcaklıkta/döndürmede aynı program).",
|
||||
"no_cycles_match": "Mevcut filtreyle eşleşen döngü yok.",
|
||||
"no_cycles_profile": "Bu profil için döngü yok.",
|
||||
@@ -696,7 +701,7 @@
|
||||
"no_devices": "Henüz WashData cihazı yapılandırılmamış.",
|
||||
"no_envelope": "Henüz zarf yok - döngüleri etiketledikten sonra yeniden oluşturun.",
|
||||
"no_envelope_overlay": "Üst üste bindirmek için zarf mevcut değil.",
|
||||
"no_fine_tuned": "Henüz ince ayar yapılmadı — WashData yerleşik modellerini kullanıyor.",
|
||||
"no_fine_tuned": "Henüz ince ayar yapılmadı – WashData yerleşik modellerini kullanıyor.",
|
||||
"no_logs": "Henüz günlük kaydı arabelleğe alınmadı.",
|
||||
"no_maintenance": "Henüz bakım kaydı yok.",
|
||||
"no_match_yet": "Henüz eşleşme denemesi yok - bu, çalışan bir döngü sırasında doldurulur.",
|
||||
@@ -713,7 +718,7 @@
|
||||
"notify_services_hint": "{entity} hizmet kimliklerini kullanın (birden fazlası için virgülle ayrın). Şablon değişkenleri: {vars}.",
|
||||
"old_actions_warning": "Eski eylem düzenleyiciyle yapılandırılmıştır (artık kaldırılmıştır). Döngü etkinliklerinde hala tetikleniyorlar ancak artık burada düzenlenemezler. Bunları normal bir otomasyona dönüştürün veya kaldırın.",
|
||||
"onboarding_progress": "{n} / 3 döngü gözlemlendi",
|
||||
"onboarding_watching": "Cihazınızı normal şekilde kullanın — WashData izliyor. 3 döngüden sonra program eşleştirmesi başlar.",
|
||||
"onboarding_watching": "Cihazınızı normal şekilde kullanın – WashData izliyor. 3 döngüden sonra program eşleştirmesi başlar.",
|
||||
"pending_feedback": "Bekleyen algılama geri bildirimi",
|
||||
"performance_trend": "Performans trendi ({n} döngü)",
|
||||
"pg_analysis_empty": "Eşleşme analizini görmek için bir döngü yükleyin.",
|
||||
@@ -763,7 +768,7 @@
|
||||
"setting_changed": "{date} tarihinde {old} değerinden {new} değerine değiştirildi",
|
||||
"settings_basic_note": "Temel ayarlar gösteriliyor. Tam liste için Gelişmiş'e geçin.",
|
||||
"shape_drift_advisory": "⚠ Şekil kayıyor",
|
||||
"shape_drift_detail": "Bu profil için güç paterni zamanla kaymıştır — olası cihaz aşınması veya bakım gerekebilir (örn. kireç çözme, filtre temizliği).",
|
||||
"shape_drift_detail": "Bu profil için güç paterni zamanla kaymıştır – olası cihaz aşınması veya bakım gerekebilir (örn. kireç çözme, filtre temizliği).",
|
||||
"show_all_settings": "Tüm ayarları göster",
|
||||
"showing_suggestions": "Önerilerle birlikte {count} ayarı gösteriliyor.",
|
||||
"split_intro": "Bölme noktası eklemek veya kaldırmak için grafiğe tıklayın veya boşta kalma aralıklarına göre otomatik algılayın. Her elde edilen bölüm kendi profilini alabilir.",
|
||||
@@ -789,10 +794,10 @@
|
||||
"toast_revert_failed": "Geri alma başarısız: {error}",
|
||||
"toast_reverted": "{key} geri alındı",
|
||||
"toast_save_failed": "Kaydetme başarısız: {error}",
|
||||
"trend_duration_longer": "Süre trendi daha uzun (%{pct}/döngü) — son ortalama {avg}",
|
||||
"trend_duration_shorter": "Süre eğilimi daha kısa (%{pct}/döngü) — son ortalama {avg}",
|
||||
"trend_duration_longer": "Süre trendi daha uzun (%{pct}/döngü) – son ortalama {avg}",
|
||||
"trend_duration_shorter": "Süre eğilimi daha kısa (%{pct}/döngü) – son ortalama {avg}",
|
||||
"trend_energy_down": "Enerji düşüş eğiliminde (%{pct}/döngü)",
|
||||
"trend_energy_up": "Enerji yükseliş eğiliminde (%{pct}/döngü) — son ortalama {avg}",
|
||||
"trend_energy_up": "Enerji yükseliş eğiliminde (%{pct}/döngü) – son ortalama {avg}",
|
||||
"trim_intro": "Kırmızı tutamaçları sürükleyin veya değer girin. Pencerenin dışındaki her şey kaldırılır.",
|
||||
"tuning_suggestions_available": "Gözlemlenen döngülerden {count} ayarlama önerisi mevcut. İlgili alanların yanında görünürler.",
|
||||
"unsure_detected_prefix": "WashData algıladığından emin değil",
|
||||
@@ -857,7 +862,9 @@
|
||||
"share_guidelines_title": "Paylaşmadan önce",
|
||||
"store_download_device_intro": "Her paylaşılan programı ve referans döngülerini cihazınıza benimseyin. Kendi kayıtlı döngüleriniz ve istatistikleriniz etkilenmez.",
|
||||
"store_share_device_intro": "Seçtiğiniz referans döngüleriyle {brand} {model} cihazını yükleyin. Aynı cihaza sahip diğer kullanıcılar programlarınızı benimseyebilir. Girişler kamuya açılmadan önce incelenir.",
|
||||
"share_profile_no_cycles": "Referans döngüsü yok -- bu profili dahil etmek için Döngüler sekmesinde bir döngüyü ⭐ olarak işaretleyin"
|
||||
"share_profile_no_cycles": "Referans döngüsü yok -- bu profili dahil etmek için Döngüler sekmesinde bir döngüyü ⭐ olarak işaretleyin",
|
||||
"advisory_phase_inconsistent": "'{name}' farklı programları veya sıcaklıkları karıştırıyor gibi görünüyor - çevrimleri çok farklı sürelerde ısıtma yapıyor. Bunu ayrı profillere bölmek (örneğin her sıcaklık için) eşleştirmeyi ve süre tahminlerini iyileştirir.",
|
||||
"advisory_phase_inconsistent_title": "⚠ Karışık olabilecek programlar"
|
||||
},
|
||||
"pg_desc": {
|
||||
"abrupt_drop_watts": "Ani düşüş anında bitiş sayılır",
|
||||
@@ -869,12 +876,19 @@
|
||||
"start_duration_threshold": "Başlangıcı onaylamak için eşik üstünde saniye",
|
||||
"start_threshold_w": "Başladı sayılması için minimum watt",
|
||||
"stop_threshold_w": "Bunun altında makine kapalı sayılır",
|
||||
"dtw_bandwidth": "Şekil eşleştirmesinin ne kadar zaman bükmeye izin verdiği",
|
||||
"corr_weight": "Eşleştirmede eğri şekline karşı güç düzeyinin ağırlığı",
|
||||
"duration_weight": "Süre uyumunun eşleştirmeyi ne kadar etkilediği",
|
||||
"energy_weight": "Enerji uyumunun eşleştirmeyi ne kadar etkilediği",
|
||||
"profile_match_min_duration_ratio": "Eşleşmeye hâlâ izin verilen en kısa çevrim (profile göre)",
|
||||
"profile_match_max_duration_ratio": "Eşleşmeye hâlâ izin verilen en uzun çevrim (profile göre)"
|
||||
"dtw_bandwidth": "Aşama 3: Sakoe-Chiba büküm bandı (0 = DTW kapalı; varsayılan 0.2 = döngü uzunluğunun %20'si)",
|
||||
"corr_weight": "Aşama 2: eğri şekli (korelasyon) ile güç düzeyi (MAE) arasındaki denge; varsayılan 0.45",
|
||||
"duration_weight": "Aşama 4: çalışma süresi uyumunun nihai puanı ne kadar etkilediği (varsayılan 0.22)",
|
||||
"energy_weight": "Aşama 4: enerji uyumunun nihai puanı ne kadar etkilediği (varsayılan 0.22)",
|
||||
"profile_match_min_duration_ratio": "Aşama 1: profil süresinin bir kesri olarak minimum döngü uzunluğu; varsayılan 0.1 (%10)",
|
||||
"profile_match_max_duration_ratio": "Aşama 1: profil süresinin bir kesri olarak maksimum döngü uzunluğu; varsayılan 1.5 (%150)",
|
||||
"keep_min_score": "Aşama 2: yarışta kalmak için taban puan; varsayılan 0.1 zayıf eşleşmelere izin verir, sonraki aşamalar en iyisini seçer",
|
||||
"dtw_blend": "Aşama 3: 0 = yalnızca çekirdek puan, 1 = yalnızca DTW puanı, 0.5 = eşit karışım (varsayılan)",
|
||||
"dtw_ensemble_w": "Aşama 3 (topluluk modu): ölçeklendirilmiş-L1 ile türev DTW arasındaki ağırlık; varsayılan 0.7 düzey farkındalığını tercih eder",
|
||||
"dtw_ddtw_scale": "Aşama 3: DDTW yarı doygunluk mesafesi; küçük = şekle daha duyarlı (varsayılan 30)",
|
||||
"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)"
|
||||
},
|
||||
"phase_desc": {
|
||||
"anti_crease": "Kırışıklıkları azaltmak için tamamlandıktan sonra ara sıra kısa yuvarlanmalar.",
|
||||
@@ -957,6 +971,10 @@
|
||||
"triggers": {
|
||||
"intro": "İsteğe bağlı harici sinyaller: bitiş tetikleyicisi, kapı sensörü, duraklatma anahtarı ve boşaltma hatırlatıcısı.",
|
||||
"label": "Tetikleyiciler & Kapılar"
|
||||
},
|
||||
"phase_eta": {
|
||||
"label": "Kalan Süre",
|
||||
"intro": "Çevrim uzunluğu sıcaklığa veya sıkmaya bağlı olan makineler için aşama farkındalıklı kalan süre."
|
||||
}
|
||||
},
|
||||
"setting": {
|
||||
@@ -1040,6 +1058,10 @@
|
||||
"doc": "Yukarıda hiçbir canlı fiyat varlığı belirlenmediğinde maliyet rakamları için kullanılan kWh başına sabit fiyat.",
|
||||
"label": "Sabit Enerji Fiyatı (kWh başına)"
|
||||
},
|
||||
"energy_sensor": {
|
||||
"doc": "İsteğe bağlı kümülatif enerji sayacı (total_increasing kWh/Wh, örn. prizin kendi ömür boyu sayacı). Ayarlandığında, her döngünün raporlanan enerjisi bu sayacın baştan sona olan farkından alınır; bu da yavaş raporlayan bir güç sensörünün integralini almaktan kaynaklanan eksik sayımı önler. Okuma eksikse, birimi bilinmiyorsa veya fark pozitif değilse integral alınmış değere geri döner. Güç sensörünün integralini almaya devam etmek için boş bırakın.",
|
||||
"label": "Enerji Sayacı Varlığı"
|
||||
},
|
||||
"expose_debug_entities": {
|
||||
"doc": "Ekstra teşhis HA varlıkları yayınlayın (eşleşme güveni, belirsizlik, dahili durum bilgileri). Kapalı, varlık listesini normal kullanım için temiz tutar.",
|
||||
"label": "Hata Ayıklama Varlıklarını Göster"
|
||||
@@ -1322,6 +1344,38 @@
|
||||
},
|
||||
"show_contributor": {
|
||||
"doc": "Topluluk cihazlarında ve referans döngülerinde \"- <katkıda bulunan>\" özelliğini göster."
|
||||
},
|
||||
"enable_phase_matching": {
|
||||
"label": "Aşama farkındalıklı kalan süre",
|
||||
"doc": "Çalışan her çevrimi aşamalara (ısıtma, yıkama, sıkma) böler ve kalan süreyi aşama başına ayırarak klasik tahminle harmanlar - çevrimin başında aşama bütçesine, sona yaklaşırken klasik tahmine ağırlık verir. Bu, geri sayımı makinenizin gerçekte ne kadar ısıttığına ve çalıştığına göre kişiselleştirir; en çok çevrimin ilk yarısında fark edilir. Kapalı = yalnızca klasik tahmin. Yalnızca kalan süre göstergesi etkilenir; program eşleştirme ve çevrim algılama değişmez."
|
||||
},
|
||||
"keep_min_score": {
|
||||
"label": "Min. Eşleşme Puanı",
|
||||
"doc": "Bir adayın eşleşme yarışında kalabilmesi için gereken minimum benzerlik puanı. Varsayılan 0.1 kasıtlı olarak gevşektir - zayıf adayları bile kabul eder ve en iyi eşleşmeyi sonraki aşamalara bırakır. Olası olmayan profilleri daha erken elemek için artırın; başlangıç aday havuzunu genişletmek için azaltın."
|
||||
},
|
||||
"dtw_blend": {
|
||||
"label": "Büküm Karışımı",
|
||||
"doc": "Zaman bükme (DTW) hizalama puanının Aşama 2 çekirdek puanını ne ölçüde değiştirdiği. 0 = yalnızca Aşama 2 puanı, 1 = yalnızca DTW puanı, 0.5 (varsayılan) = eşit karışım. Programların güç düzeyleri benzer ancak zamanlama kalıpları farklıysa büküm hizalamasına daha fazla güvenmek için artırın."
|
||||
},
|
||||
"dtw_ensemble_w": {
|
||||
"label": "Büküm Topluluk Karışımı",
|
||||
"doc": "Topluluk DTW modunda (varsayılan), ölçeklendirilmiş L1 ile türev DTW (DDTW) arasındaki ağırlık. 1.0 = tamamen ölçeklendirilmiş-L1, 0 = tamamen DDTW, 0.7 = varsayılan. Ölçeklendirilmiş-L1 değişkeni güç düzeylerini karşılaştırır; türev değişkeni gücün zaman içinde nasıl değiştiğine tepki verir. Topluluk her ikisini de birleştirir."
|
||||
},
|
||||
"dtw_ddtw_scale": {
|
||||
"label": "Türev Büküm Ölçeği",
|
||||
"doc": "Türev DTW puanlaması için yarı doygunluk mesafesi. DDTW mesafesi bu değere eşit olduğunda puan yarıya düşer. Küçük = şekil farklılıklarına daha duyarlı. Varsayılan 30, tipik ev aletleri güç izleri için kalibre edilmiştir. Yalnızca topluluk ve ddtw DTW modlarını etkiler."
|
||||
},
|
||||
"dtw_refine_top_n": {
|
||||
"label": "Büküm Yeniden Skor Sayısı",
|
||||
"doc": "Kaç üst Aşama 2 adayı DTW tarafından yeniden puanlandırılır. DTW daha pahalıdır, bu nedenle yalnızca en iyi N adaya uygulanır. Varsayılan 5. Doğru profil bazen Aşama 2'den sonra yalnızca 4. veya 5. sıraya geliyorsa artırın (7-9'a) - DTW onu kurtarabilir. Azaltmak eşleşmeyi biraz hızlandırır."
|
||||
},
|
||||
"duration_scale": {
|
||||
"label": "Süre Keskinliği",
|
||||
"doc": "Aşama 4 süre uyumu cezasının keskinliği. Bu, uyum puanının yarıya düştüğü logaritmik orandır. Küçük = daha sert: bir süre uyumsuzluğu daha fazla zarara yol açar. Varsayılan 0.175, yarı ağırlıkta yaklaşık %18 süre toleransına karşılık gelir. Süre Ağırlığı ile birlikte kullanın."
|
||||
},
|
||||
"energy_scale": {
|
||||
"label": "Enerji Keskinliği",
|
||||
"doc": "Aşama 4 enerji uyumu cezasının keskinliği. Küçük = daha sert: bir enerji uyumsuzluğu daha fazla zarara yol açar. Varsayılan 0.25, enerji yükle değiştiğinden Süre Keskinliğinden kasıtlı olarak daha gevşektir. Enerji Ağırlığı ile birlikte kullanın."
|
||||
}
|
||||
},
|
||||
"setting_group": {
|
||||
@@ -1570,24 +1624,24 @@
|
||||
"lower": "Daha fazla döngüyü otomatik etiketler; bazıları yanlış tanımlanabilir"
|
||||
},
|
||||
"duration_tolerance": {
|
||||
"higher": "Daha geniş süre aralığı kabul eder — daha esnek eşleştirme",
|
||||
"lower": "Daha yakın süre eşleşmesi gerektirir — daha katı ama alışılmadık döngüleri reddedebilir"
|
||||
"higher": "Daha geniş süre aralığı kabul eder – daha esnek eşleştirme",
|
||||
"lower": "Daha yakın süre eşleşmesi gerektirir – daha katı ama alışılmadık döngüleri reddedebilir"
|
||||
},
|
||||
"end_energy_threshold": {
|
||||
"higher": "Yalnızca önemli enerji kullanan döngüleri kapatır",
|
||||
"lower": "Daha kısa veya düşük enerjili döngüleri de kapatır"
|
||||
},
|
||||
"end_repeat_count": {
|
||||
"higher": "Bitiş sinyalinin daha fazla tekrarlanmasını gerektirir — daha güvenilir, biraz daha yavaş",
|
||||
"lower": "Daha az tekrardan sonra biter — daha hızlı algılama, daha yüksek yanlış bitiş riski"
|
||||
"higher": "Bitiş sinyalinin daha fazla tekrarlanmasını gerektirir – daha güvenilir, biraz daha yavaş",
|
||||
"lower": "Daha az tekrardan sonra biter – daha hızlı algılama, daha yüksek yanlış bitiş riski"
|
||||
},
|
||||
"learning_confidence": {
|
||||
"higher": "Yalnızca çok güvenli eşleşmelerden öğrenir — daha yavaş ama daha güvenilir",
|
||||
"higher": "Yalnızca çok güvenli eşleşmelerden öğrenir – daha yavaş ama daha güvenilir",
|
||||
"lower": "Daha fazla döngüden öğrenir; model daha gürültülü olabilir"
|
||||
},
|
||||
"min_off_gap": {
|
||||
"higher": "Yeni döngü başlamadan önce daha uzun boşta kalma süresi gerekir",
|
||||
"lower": "Kısa boşta kalma yeni döngü başlatır — arka arkaya çalışmalar bölünebilir"
|
||||
"lower": "Kısa boşta kalma yeni döngü başlatır – arka arkaya çalışmalar bölünebilir"
|
||||
},
|
||||
"min_power": {
|
||||
"higher": "Boşta güç çekimine daha az duyarlı; çok sessiz programları kaçırabilir",
|
||||
@@ -1598,24 +1652,24 @@
|
||||
"lower": "Takılı döngüyü daha erken zorunlu durdurur"
|
||||
},
|
||||
"off_delay": {
|
||||
"higher": "Cihaz duraklamaları için daha fazla süre — uzun ıslatma veya kurutma aşamalarını yönetir",
|
||||
"lower": "Daha hızlı bitiş algılama — net açık/kapalı cihazlar için iyi çalışır"
|
||||
"higher": "Cihaz duraklamaları için daha fazla süre – uzun ıslatma veya kurutma aşamalarını yönetir",
|
||||
"lower": "Daha hızlı bitiş algılama – net açık/kapalı cihazlar için iyi çalışır"
|
||||
},
|
||||
"profile_match_threshold": {
|
||||
"higher": "Yalnızca yüksek güvenli eşleşmeleri onaylar; daha fazla döngü etiketsiz kalır",
|
||||
"lower": "Daha fazla döngüyle eşleşir; bazıları hafif hatalı olabilir"
|
||||
},
|
||||
"running_dead_zone": {
|
||||
"higher": "Boşta kısa güç artışlarını yoksayar — gürültüye daha az duyarlı",
|
||||
"lower": "Daha kısa güç patlamalarına yanıt verir — hızlı geçici etkinliği yakalar"
|
||||
"higher": "Boşta kısa güç artışlarını yoksayar – gürültüye daha az duyarlı",
|
||||
"lower": "Daha kısa güç patlamalarına yanıt verir – hızlı geçici etkinliği yakalar"
|
||||
},
|
||||
"start_threshold_w": {
|
||||
"higher": "Kısa güç artışlarından kaynaklanan yanlış başlatmaları önler",
|
||||
"lower": "Düşük güçlü programları yakalar; gürültüde tetiklenebilir"
|
||||
},
|
||||
"stop_threshold_w": {
|
||||
"higher": "Döngüyü daha hızlı bitirir — duraklamada kapanabilir",
|
||||
"lower": "Bitişi daha uzun bekler — daha az erken tamamlanma"
|
||||
"higher": "Döngüyü daha hızlı bitirir – duraklamada kapanabilir",
|
||||
"lower": "Bitişi daha uzun bekler – daha az erken tamamlanma"
|
||||
},
|
||||
"watchdog_interval": {
|
||||
"higher": "Daha uzun sessiz aşamalara izin verilir; daha az yanlış zorunlu durdurma",
|
||||
@@ -1766,6 +1820,69 @@
|
||||
},
|
||||
"pg_sweep": {
|
||||
"optimize": "Optimizasyon: {param}"
|
||||
},
|
||||
"pg_detail": {
|
||||
"simulate": "Döngü simülasyonu"
|
||||
},
|
||||
"split": {
|
||||
"apply": "Döngü bölünüyor"
|
||||
},
|
||||
"trim": {
|
||||
"apply": "Döngü kırpılıyor"
|
||||
},
|
||||
"merge": {
|
||||
"apply": "Döngüler birleştiriliyor"
|
||||
},
|
||||
"rebuild": {
|
||||
"envelopes": "Zarflar yeniden oluşturuluyor"
|
||||
},
|
||||
"cancelling": "İptal ediliyor..."
|
||||
},
|
||||
"setup": {
|
||||
"hdr": {
|
||||
"card": "Cihaz Kurulumu",
|
||||
"healthy_chip": "Kurulum tamamlandı"
|
||||
},
|
||||
"phase0": {
|
||||
"washer": "WashData döngülerinizi zaten algılıyor. Program adlarını ve süre tahminlerini etkinleştirmek için ilk döngünüzü kaydedin.",
|
||||
"dishwasher": "WashData izliyor. Bulaşık makinelerinin döngüleri karmaşıktır – ilk döngünüzü kaydetmeniz kesinlikle önerilir. Algılanan bir döngü çok uzun sürerse, profil olarak kaydetmeden önce döngü düzenleyicisini kullanarak kırpın.",
|
||||
"generic": "WashData izliyor. Profil oluşturmaya başlamak için algılanan bir döngüyü kaydedin veya etiketleyin."
|
||||
},
|
||||
"phase1a": {
|
||||
"labelled": "İyi bir başlangıç – ilk programınız kaydedildi. En temiz veri için bir sonraki döngünüzü kaydedici widget'ı ile kaydetmeyi düşünün."
|
||||
},
|
||||
"phase1b": {
|
||||
"recorded": "Kaydınız {profile_name} olarak kaydedildi. Kapsama alanı oluşturmak için diğer yaygın programlarınızı kaydedin veya etiketleyin."
|
||||
},
|
||||
"phase1c": {
|
||||
"verify": "Topluluktan {count} programınız var. WashData'nın doğru tanıyıp tanımadığını doğrulamak için bir döngü çalıştırın – cihazınız kendi geçmişini oluşturdukça eşleştirme iyileşecektir."
|
||||
},
|
||||
"phase2": {
|
||||
"cluster": "WashData, kayıtlı hiçbir programla eşleşmeyen {count} döngü gördü – bunlar birbirlerine benziyor. Bunlar için yeni bir profil oluşturmak ister misiniz?",
|
||||
"unmatched": "Son döngünüz kayıtlı hiçbir programla eşleşmedi. Yeni bir program mı?"
|
||||
},
|
||||
"phase3": {
|
||||
"suggestions": "WashData, döngü geçmişinize göre ayar önerileri sunuyor – algılama doğruluğunu artırmak için bunları inceleyin.",
|
||||
"groups": "Bazı profilleriniz farklı sıcaklıklardaki aynı programa benziyor. Daha iyi eşleştirme için bunları bir grupta düzenleyin.",
|
||||
"phases": "Daha doğru kalan süre tahminleri için {profile_name} profiline program aşamaları ekleyin."
|
||||
},
|
||||
"phase4": {
|
||||
"healthy": "Bu cihaz tamamen kuruldu ({profile_count} profil)."
|
||||
},
|
||||
"cta": {
|
||||
"start_recording": "Kaydı Başlat",
|
||||
"label_detected_cycle": "Zaten algılanmış bir döngüm var – bunun yerine etiketle",
|
||||
"browse_cycles": "Başka birini etiketlemek için döngülere göz at",
|
||||
"view_profiles": "Profillerinizi görüntüleyin",
|
||||
"create_from_cluster": "Bu döngülerden profil oluştur",
|
||||
"create_profile": "Bunun için bir profil oluştur",
|
||||
"review_suggestions": "Önerileri incele",
|
||||
"organise_profiles": "Profilleri düzenle",
|
||||
"configure_phases": "Aşamaları yapılandır",
|
||||
"skip_step": "Bu adımı atla",
|
||||
"skip_forever": "Bir daha gösterme",
|
||||
"hide_guidance": "Rehberi gizle",
|
||||
"show_guidance": "Rehberi göster"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
{
|
||||
"badge": {
|
||||
"artifact_tip": "Виявлено {n} аномалій (наприклад, двері відкриті посеред циклу) — відкрийте, щоб побачити їх на графіку",
|
||||
"artifact_tip": "Виявлено {n} аномалій (наприклад, двері відкриті посеред циклу) – відкрийте, щоб побачити їх на графіку",
|
||||
"auto": "(виявлено автоматично)",
|
||||
"built_in_tag": "вбудований",
|
||||
"declining": "↘ знижується",
|
||||
"energy_low": "Енергії менше, ніж зазвичай",
|
||||
"energy_spike": "Енергії більше, ніж зазвичай",
|
||||
"fair_fit": "прийнятна якість",
|
||||
"fair_fit_tip": "Помірна постійність збігів — деякі цикли, призначені цьому профілю, мають нижчі оцінки надійності. Позначте більше циклів або перезапишіть профіль, щоб підвищити точність.",
|
||||
"fair_fit_tip": "Помірна постійність збігів – деякі цикли, призначені цьому профілю, мають нижчі оцінки надійності. Позначте більше циклів або перезапишіть профіль, щоб підвищити точність.",
|
||||
"feedback_requested": "Запит на відгук",
|
||||
"golden_cycle": "Записаний контрольний цикл",
|
||||
"improving": "↗ покращується",
|
||||
@@ -15,7 +15,7 @@
|
||||
"needs_review": "Потребує перегляду",
|
||||
"overrun": "Тривав довше, ніж зазвичай",
|
||||
"poor_fit": "погана якість",
|
||||
"poor_fit_tip": "Непослідовна історія збігів — розгляньте можливість відновлення цього профілю",
|
||||
"poor_fit_tip": "Непослідовна історія збігів – розгляньте можливість відновлення цього профілю",
|
||||
"restart_gap_tip": "{n} пропуск при перезапуску HA: у графіку потужності є розрив",
|
||||
"reviewed": "Переглянуто",
|
||||
"steady": "→ стабільно",
|
||||
@@ -57,7 +57,7 @@
|
||||
"create_profile": "+ Створити профіль",
|
||||
"delete": "Видалити",
|
||||
"delete_group": "Видалити групу",
|
||||
"delete_group_tip": "Видалити лише цю групу — профілі учасників збережуться",
|
||||
"delete_group_tip": "Видалити лише цю групу – профілі учасників збережуться",
|
||||
"delete_profile": "Видалити профіль",
|
||||
"discard": "Відхилити",
|
||||
"discard_tip": "Відхилити запис без збереження",
|
||||
@@ -87,7 +87,7 @@
|
||||
"on_cycle_finished": "Коли цикл завершено",
|
||||
"on_cycle_started": "Коли цикл розпочато",
|
||||
"pause_cycle": "Пауза",
|
||||
"pause_cycle_tip": "Призупинити поточний цикл — прилад продовжить роботу з того місця, де зупинився",
|
||||
"pause_cycle_tip": "Призупинити поточний цикл – прилад продовжить роботу з того місця, де зупинився",
|
||||
"pg_apply_device": "Застосувати до пристрою",
|
||||
"pg_autofill": "Автозаповнення",
|
||||
"play": "Відтворити",
|
||||
@@ -97,8 +97,8 @@
|
||||
"process_tip": "Зберегти запис як новий або наявний профіль",
|
||||
"rebuild": "Відновити конверти",
|
||||
"rebuild_envelope": "Відновити конверт",
|
||||
"rebuild_tip": "Перерахувати очікуваний конверт потужності (смуга мін./макс.) для всіх профілів з позначених циклів — запускати після позначення нових або виправлення старих циклів",
|
||||
"rec_start_tip": "Розпочати запис потужності приладу — запустіть безпосередньо перед початком циклу",
|
||||
"rebuild_tip": "Перерахувати очікуваний конверт потужності (смуга мін./макс.) для всіх профілів з позначених циклів – запускати після позначення нових або виправлення старих циклів",
|
||||
"rec_start_tip": "Розпочати запис потужності приладу – запустіть безпосередньо перед початком циклу",
|
||||
"rec_stop": "Зупинити",
|
||||
"rec_stop_tip": "Зупинити запис і зберегти захоплені дані для перегляду",
|
||||
"record": "Почати запис",
|
||||
@@ -182,7 +182,7 @@
|
||||
},
|
||||
"attn_sub": "Виправте конфлікти перед збереженням",
|
||||
"attn_title": "{n} конфлікт{s} налаштувань",
|
||||
"settings_banner": "{n} конфлікт{s} налаштувань — перевірте виділені розділи й виправте перед збереженням.",
|
||||
"settings_banner": "{n} конфлікт{s} налаштувань – перевірте виділені розділи й виправте перед збереженням.",
|
||||
"settings_banner_btn": "До першого",
|
||||
"confidence": {
|
||||
"auto": "Має бути не нижчим за Поріг Зіставлення ({match})",
|
||||
@@ -451,9 +451,9 @@
|
||||
"show_expected": "Показати накладення очікуваної кривої (відповідний профіль, помаранчевий)",
|
||||
"show_raw": "Показати перемикач необроблених даних розетки на графіку потужності в реальному часі",
|
||||
"sparkline": "Тренд тривалості останніх циклів",
|
||||
"stage2": "Етап 2 — основна подібність",
|
||||
"stage3": "Етап 3 — DTW",
|
||||
"stage4": "Етап 4 — відповідність",
|
||||
"stage2": "Етап 2 – основна подібність",
|
||||
"stage3": "Етап 3 – DTW",
|
||||
"stage4": "Етап 4 – відповідність",
|
||||
"status": "Стан",
|
||||
"tail_trim": "Обрізання кінця (с)",
|
||||
"timer_auto_pause": "Автопауза",
|
||||
@@ -561,7 +561,12 @@
|
||||
"flags": "Мітки",
|
||||
"include_phase_map": "Включити карту фаз",
|
||||
"include_settings": "Включити налаштування",
|
||||
"show_contributor": "Показати автора"
|
||||
"show_contributor": "Показати автора",
|
||||
"task_pg_detail": "Змоделювати цикл",
|
||||
"task_split": "Розділення циклу",
|
||||
"task_trim": "Обрізання циклу",
|
||||
"task_merge": "Об'єднання циклів",
|
||||
"task_rebuild": "Перерахунок обвідних"
|
||||
},
|
||||
"log": {
|
||||
"all_levels": "Усі рівні",
|
||||
@@ -645,19 +650,19 @@
|
||||
"artifact_dip_detail": "Опустився нижче звичайної смуги потужності приблизно на ~{n} с.",
|
||||
"artifact_footer": "Виділено на графіку вище. Це тимчасові артефакти (наприклад, двері відчинені посередині циклу), не обов'язково проблеми.",
|
||||
"artifact_header": "Протягом цього циклу виявлено {n} аномалій",
|
||||
"artifact_pause_detail": "Потужність впала майже до нуля приблизно на ~{n} с, а потім відновилася — імовірно, двері відчинили під час циклу або цикл призупинили.",
|
||||
"artifact_pause_detail": "Потужність впала майже до нуля приблизно на ~{n} с, а потім відновилася – імовірно, двері відчинили під час циклу або цикл призупинили.",
|
||||
"artifact_spike_detail": "Вийшов за верхню межу звичайної смуги потужності приблизно на ~{n} с.",
|
||||
"auto_label_intro": "Призначте профілі непозначеним циклам, чия впевненість збігу перевищує поріг.",
|
||||
"automations_intro": "WashData запускає події {start} / {end} та надає об'єкти, тому сповіщення й дії найкраще будувати як звичайні автоматизації Home Assistant. Автоматизації, що використовують цей пристрій, відображаються нижче.",
|
||||
"cleanup_intro": "Усі позначені цикли накладено. Позначте аномалії і видаліть їх для очищення профілю.",
|
||||
"clear_debug_hint": "Видаліть збережені дані налагодження, щоб звільнити місце.",
|
||||
"collecting_data": "Збір даних — потрібно ще {need} цикл{plural} до початку точного налаштування ({current}/{min}).",
|
||||
"collecting_data": "Збір даних – потрібно ще {need} цикл{plural} до початку точного налаштування ({current}/{min}).",
|
||||
"compare_overlay_profiles": "Накласти профілі (блідо)",
|
||||
"compare_profiles_tip": "Накладіть інші конверти профілів на таблицю вище, щоб побачити, який з них найкраще підходить для цього циклу.",
|
||||
"compare_selected_cycles": "Вибрані цикли (суцільно) — показати / приховати",
|
||||
"compare_selected_cycles": "Вибрані цикли (суцільно) – показати / приховати",
|
||||
"consider_new_profile": "Розгляньте можливість створення нового профілю.",
|
||||
"coverage_gap": "останні цикли не мають відповідного профілю ({pct}% з останніх 30).",
|
||||
"coverage_gap_similar_cycles": "Знайдено {count} схожих непозначених циклів — створіть профіль, щоб почати їх зіставлення.",
|
||||
"coverage_gap_similar_cycles": "Знайдено {count} схожих непозначених циклів – створіть профіль, щоб почати їх зіставлення.",
|
||||
"cycles_deleted": "Видалено циклів: {count}",
|
||||
"enough_data": "Достатньо даних для навчання ({current}/{min} циклів).",
|
||||
"export_description": "Експортуйте всі профілі та цикли в JSON або відновіть попередній експорт.",
|
||||
@@ -686,7 +691,7 @@
|
||||
"ml_learned_intro": "Моделі, налаштовані під цей пристрій.",
|
||||
"ml_loading": "завантаження ML…",
|
||||
"ml_settings_intro": "Два незалежних перемикачі: один застосовує моделі під час циклу, інший дозволяє WashData з часом налаштовуватися під ваш пристрій.",
|
||||
"name_first_program": "У вас достатньо циклів — назвіть першу програму, щоб почати зіставлення.",
|
||||
"name_first_program": "У вас достатньо циклів – назвіть першу програму, щоб почати зіставлення.",
|
||||
"near_duplicate_cluster": "виявлено майже повторюваний кластер профілів. Групування дає змогу надійно вибирати між подібними програмами (наприклад, однакова програма з різною температурою/віджиманням).",
|
||||
"no_cycles_match": "Жоден цикл не відповідає поточному фільтру.",
|
||||
"no_cycles_profile": "Немає циклів для цього профілю.",
|
||||
@@ -694,12 +699,12 @@
|
||||
"no_cycles_yet": "Жодного циклу ще не записано.",
|
||||
"no_device_selected": "Пристрій не вибрано.",
|
||||
"no_devices": "Жодного пристрою WashData ще не налаштовано.",
|
||||
"no_envelope": "Конверта ще немає — відновіть після позначення циклів.",
|
||||
"no_envelope": "Конверта ще немає – відновіть після позначення циклів.",
|
||||
"no_envelope_overlay": "Немає доступного конверта для накладання.",
|
||||
"no_fine_tuned": "Ще нічого не налаштовано — WashData використовує вбудовані моделі.",
|
||||
"no_fine_tuned": "Ще нічого не налаштовано – WashData використовує вбудовані моделі.",
|
||||
"no_logs": "Жодних записів журналу ще не буферизовано.",
|
||||
"no_maintenance": "Обслуговування ще не записано.",
|
||||
"no_match_yet": "Ще немає спроби збігу — це заповнюється під час запущеного циклу.",
|
||||
"no_match_yet": "Ще немає спроби збігу – це заповнюється під час запущеного циклу.",
|
||||
"no_other_users": "Інших користувачів Home Assistant не знайдено.",
|
||||
"no_phases": "Фаз не визначено.",
|
||||
"no_phases_assigned": "Фаз не призначено.",
|
||||
@@ -713,7 +718,7 @@
|
||||
"notify_services_hint": "Використовуйте ID сервісів {entity} (через кому для кількох). Змінні шаблону: {vars}.",
|
||||
"old_actions_warning": "Налаштовано за допомогою старого редактора дій (тепер вилучено). Вони все ще запускаються на події циклу, але їх більше не можна редагувати тут. Перетворіть їх на звичайну автоматизацію або видаліть.",
|
||||
"onboarding_progress": "{n} / 3 циклів спостережено",
|
||||
"onboarding_watching": "Користуйтеся приладом як завжди — WashData спостерігає. Після 3 циклів почнеться зіставлення програм.",
|
||||
"onboarding_watching": "Користуйтеся приладом як завжди – WashData спостерігає. Після 3 циклів почнеться зіставлення програм.",
|
||||
"pending_feedback": "Очікує відгук про виявлення",
|
||||
"performance_trend": "Тенденція продуктивності ({n} циклів)",
|
||||
"pg_analysis_empty": "Завантажте цикл, щоб побачити аналіз збігу.",
|
||||
@@ -748,13 +753,13 @@
|
||||
"restart_gap_footer": "Виділено на графіку. Дані потужності відсутні для цих інтервалів; зіставлення використовувало лише реальні показання.",
|
||||
"restart_gap_header": "{n} пропуск при перезапуску HA під час цього циклу",
|
||||
"restart_gap_item": "{dur} пропуск",
|
||||
"review_confirm_help": "Перевірте, чи правильно було виявлено цей цикл. Ваші відгуки навчають модель на вашому пристрої — що більше циклів ви підтвердите, то кращим буде відповідність та оцінка стану. Достатньо швидкого Добре/Погано.",
|
||||
"review_confirm_help": "Перевірте, чи правильно було виявлено цей цикл. Ваші відгуки навчають модель на вашому пристрої – що більше циклів ви підтвердите, то кращим буде відповідність та оцінка стану. Достатньо швидкого Добре/Погано.",
|
||||
"review_in_settings": "Переглянути в налаштуваннях",
|
||||
"review_notes_placeholder": "Примітки (необов'язково)",
|
||||
"review_notes_tip": "Довільні текстові нотатки для власної довідки. Не використовується під час підбору чи навчання.",
|
||||
"review_profile_tip": "Програма, якою позначено цей цикл. Якщо автоматично визначена програма була неправильною, виправте це тут — маркування навчає відповідності для майбутніх циклів.",
|
||||
"review_profile_tip": "Програма, якою позначено цей цикл. Якщо автоматично визначена програма була неправильною, виправте це тут – маркування навчає відповідності для майбутніх циклів.",
|
||||
"review_quality_tip": "Наскільки чистий цей цикл. Добре = хрестоматійний приклад цієї програми; Погано = виявлено, але шумно або нетипово; Непридатний = неправильно виявлений (об'єднаний, усічений або фальшивий). Керує оцінкою стану та циклами, дозволеними для навчання моделі.",
|
||||
"review_recorded_tip": "Позначте це як підібраний вручну еталонний цикл для своєї програми — така ж роль, як цикл, записаний вручну. Довідкові цикли завжди зберігаються, заповнюють відповідний шаблон і ніколи не відкидаються під час очищення. (Це «золотий»/записаний прапор; обидва — одне й те саме.)",
|
||||
"review_recorded_tip": "Позначте це як підібраний вручну еталонний цикл для своєї програми – така ж роль, як цикл, записаний вручну. Довідкові цикли завжди зберігаються, заповнюють відповідний шаблон і ніколи не відкидаються під час очищення. (Це «золотий»/записаний прапор; обидва – одне й те саме.)",
|
||||
"review_tags_tip": "Необов'язкові прапорці, що описують, що пішло не так у цьому циклі, щоб навчання та очищення могли це врахувати.",
|
||||
"review_to_cycles": "Відкрити чергу огляду циклів",
|
||||
"saving_triggers_reload": "Збереження запускає перезавантаження інтеграції. Об'єкти HA можуть короткочасно відображатися як недоступні.",
|
||||
@@ -763,7 +768,7 @@
|
||||
"setting_changed": "Змінено з {old} на {new} {date}",
|
||||
"settings_basic_note": "Показано основні налаштування. Перейдіть до Розширених, щоб побачити весь список.",
|
||||
"shape_drift_advisory": "⚠ Форма змінюється",
|
||||
"shape_drift_detail": "Профіль потужності для цього профілю змінився з часом — можливе зношення приладу або потрібне обслуговування (наприклад, видалення накипу, очищення фільтра).",
|
||||
"shape_drift_detail": "Профіль потужності для цього профілю змінився з часом – можливе зношення приладу або потрібне обслуговування (наприклад, видалення накипу, очищення фільтра).",
|
||||
"show_all_settings": "Показати всі налаштування",
|
||||
"showing_suggestions": "Показано {count} налаштувань із пропозиціями.",
|
||||
"split_intro": "Натисніть на графік, щоб додати або видалити точку поділу, або автовизначення за паузами. Кожен отриманий сегмент може отримати власний профіль.",
|
||||
@@ -789,10 +794,10 @@
|
||||
"toast_revert_failed": "Відкат не виконано: {error}",
|
||||
"toast_reverted": "Повернено: {key}",
|
||||
"toast_save_failed": "Збереження не виконано: {error}",
|
||||
"trend_duration_longer": "Тривалість збільшується ({pct}%/цикл) — останній середній показник {avg}",
|
||||
"trend_duration_shorter": "Тривалість скорочується ({pct}%/цикл) — останній середній показник {avg}",
|
||||
"trend_duration_longer": "Тривалість збільшується ({pct}%/цикл) – останній середній показник {avg}",
|
||||
"trend_duration_shorter": "Тривалість скорочується ({pct}%/цикл) – останній середній показник {avg}",
|
||||
"trend_energy_down": "Енергія зменшується ({pct}%/цикл)",
|
||||
"trend_energy_up": "Енергія зростає ({pct}%/цикл) — останній середній показник {avg}",
|
||||
"trend_energy_up": "Енергія зростає ({pct}%/цикл) – останній середній показник {avg}",
|
||||
"trim_intro": "Перетягніть червоні маркери або введіть значення. Все за межами вікна видаляється.",
|
||||
"tuning_suggestions_available": "Доступна {count} пропозиція налаштування на основі спостережених циклів. Вони з'являються поряд із відповідними полями.",
|
||||
"unsure_detected_prefix": "WashData не впевнений, що виявив",
|
||||
@@ -857,7 +862,9 @@
|
||||
"share_guidelines_title": "Перед публікацією",
|
||||
"store_download_device_intro": "Завантажити конфігурацію пристрою зі спільноти та застосувати її до нового або наявного пристрою",
|
||||
"store_share_device_intro": "Поділитися програмами вашого пристрою (профілі + еталонні цикли) зі спільнотою. Налаштування необов'язкові.",
|
||||
"share_profile_no_cycles": "Профіль '{p}' не має ⭐ еталонних циклів -- його буде пропущено, якщо у вас немає {n}+ підтверджених запусків"
|
||||
"share_profile_no_cycles": "Профіль '{p}' не має ⭐ еталонних циклів -- його буде пропущено, якщо у вас немає {n}+ підтверджених запусків",
|
||||
"advisory_phase_inconsistent": "Схоже, що '{name}' поєднує різні програми або температури - його цикли нагріваються протягом дуже різного часу. Розділення на окремі профілі (напр. за температурою) покращить зіставлення та оцінки часу.",
|
||||
"advisory_phase_inconsistent_title": "⚠ Можливо, змішані програми"
|
||||
},
|
||||
"phase_desc": {
|
||||
"anti_crease": "Час від часу короткі оберти після завершення для зменшення зморшок.",
|
||||
@@ -940,6 +947,10 @@
|
||||
"triggers": {
|
||||
"intro": "Додаткові зовнішні сигнали: тригер завершення, датчик дверей, перемикач паузи та нагадування про вивантаження.",
|
||||
"label": "Тригери & Двері"
|
||||
},
|
||||
"phase_eta": {
|
||||
"label": "Залишок часу",
|
||||
"intro": "Оцінка залишку часу з урахуванням фаз, для машин, тривалість циклу яких залежить від температури або віджиму."
|
||||
}
|
||||
},
|
||||
"setting": {
|
||||
@@ -1023,6 +1034,10 @@
|
||||
"doc": "Фіксована ціна за кВт-год, яка використовується для показників витрат, якщо вище не встановлено реальну ціну.",
|
||||
"label": "Фіксована ціна на енергію (за kWh)"
|
||||
},
|
||||
"energy_sensor": {
|
||||
"doc": "Необов’язковий накопичувальний лічильник енергії (total_increasing kWh/Wh, наприклад, власний лічильник загального споживання розетки). Якщо задано, енергія, що відображається для кожного циклу, береться з різниці показань цього лічильника між початком і кінцем, що дозволяє уникнути заниження, яке виникає при інтегруванні датчика потужності, що повільно оновлюється. Якщо показання відсутнє, його одиниця невідома або різниця не додатна, використовується інтегроване значення. Залиште порожнім, щоб продовжувати інтегрувати датчик потужності.",
|
||||
"label": "Сутність лічильника енергії"
|
||||
},
|
||||
"expose_debug_entities": {
|
||||
"doc": "Опублікуйте додаткові діагностичні об’єкти високої доступності (достовірність відповідності, неоднозначність, внутрішні стани). Якщо вимкнено, список об’єктів залишається чистим для звичайного використання.",
|
||||
"label": "Показати відлагоджувальні сутності"
|
||||
@@ -1305,6 +1320,38 @@
|
||||
},
|
||||
"show_contributor": {
|
||||
"doc": "Показати ім'я автора на профілях, завантажених з магазину спільноти"
|
||||
},
|
||||
"enable_phase_matching": {
|
||||
"label": "Залишок часу з урахуванням фаз",
|
||||
"doc": "Розбиває кожен активний цикл на фази (нагрівання, прання, віджим) і розподіляє залишок часу за фазами, поєднуючи це з класичною оцінкою - спираючись на розподіл за фазами на початку циклу та на класичну оцінку ближче до кінця. Це персоналізує відлік під те, скільки насправді нагрівається та працює ваша машина, що найпомітніше в першій половині циклу. Вимкнено = лише класична оцінка. Впливає лише на відображення залишку часу; зіставлення програм і виявлення циклу залишаються незмінними."
|
||||
},
|
||||
"keep_min_score": {
|
||||
"label": "Мін. оцінка збігу",
|
||||
"doc": "Мінімальна оцінка подібності, необхідна кандидату для участі у змаганні зі збігів. Значення за замовчуванням 0,1 є навмисно м'яким - допускає навіть слабких кандидатів і покладається на пізніші етапи для знаходження найкращого збігу. Збільшіть для ранішого відхилення малоймовірних профілів; зменшіть для розширення початкового пулу кандидатів."
|
||||
},
|
||||
"dtw_blend": {
|
||||
"label": "Змішування деформації",
|
||||
"doc": "Наскільки оцінка вирівнювання DTW замінює базову оцінку Етапу 2. 0 = використовуй лише оцінку Етапу 2, 1 = використовуй лише оцінку DTW, 0,5 (за замовчуванням) = рівне змішування. Збільшіть для більшого покладання на вирівнювання деформацією, коли програми мають схожі рівні потужності, але різні часові шаблони."
|
||||
},
|
||||
"dtw_ensemble_w": {
|
||||
"label": "Мікс комбінації DTW",
|
||||
"doc": "В режимі ансамблю DTW (за замовчуванням), вага масштабованого L1 проти похідного DTW (DDTW). 1,0 = лише масштабований L1, 0 = лише DDTW, 0,7 = за замовчуванням. Масштабований варіант L1 порівнює рівні потужності; похідний варіант реагує на зміни потужності в часі. Ансамбль поєднує обидва."
|
||||
},
|
||||
"dtw_ddtw_scale": {
|
||||
"label": "Масштаб похідної деформації",
|
||||
"doc": "Відстань напівнасичення для оцінювання похідним DTW. Оцінка зменшується вдвічі, коли відстань DDTW рівна цьому значенню. Менша = більш чутлива до відмінностей форми. Значення за замовчуванням 30 відкалібровано для типових слідів потужності побутових приладів. Впливає лише на режими ensemble та ddtw DTW."
|
||||
},
|
||||
"dtw_refine_top_n": {
|
||||
"label": "Кількість уточнених кандидатів",
|
||||
"doc": "Скільки провідних кандидатів Етапу 2 DTW переоцінює. DTW є дорожчим, тому застосовується лише до N найкращих кандидатів. За замовчуванням 5. Збільшіть (до 7-9), якщо правильний профіль іноді досягає лише 4-го або 5-го місця після Етапу 2 - DTW може його врятувати. Зменшення трохи прискорює зіставлення."
|
||||
},
|
||||
"duration_scale": {
|
||||
"label": "Гострота тривалості",
|
||||
"doc": "Гострота штрафу за невідповідність тривалості на Етапі 4. Це лог-відношення, при якому оцінка збігу зменшується вдвічі. Менше = суворіше: невідповідність тривалості більше знижує оцінку. Значення за замовчуванням 0,175 відповідає допуску тривалості близько 18% при половинній вазі. Використовуйте разом із Вагою тривалості."
|
||||
},
|
||||
"energy_scale": {
|
||||
"label": "Гострота енергії",
|
||||
"doc": "Гострота штрафу за невідповідність енергії на Етапі 4. Менше = суворіше: невідповідність енергії більше знижує оцінку. Значення за замовчуванням 0,25 є навмисно більш м'яким, ніж Гострота тривалості, оскільки енергія варіюється з навантаженням. Використовуйте разом із Вагою енергії."
|
||||
}
|
||||
},
|
||||
"setting_group": {
|
||||
@@ -1553,24 +1600,24 @@
|
||||
"lower": "Автоматично позначає більше циклів; деякі можуть бути визначені неправильно"
|
||||
},
|
||||
"duration_tolerance": {
|
||||
"higher": "Приймає ширший діапазон тривалості — гнучкіше зіставлення",
|
||||
"lower": "Потребує точнішого збігу тривалості — суворіше, але може відхилити незвичні цикли"
|
||||
"higher": "Приймає ширший діапазон тривалості – гнучкіше зіставлення",
|
||||
"lower": "Потребує точнішого збігу тривалості – суворіше, але може відхилити незвичні цикли"
|
||||
},
|
||||
"end_energy_threshold": {
|
||||
"higher": "Закриває лише цикли зі значним споживанням енергії",
|
||||
"lower": "Закриває також коротші або маломощні цикли"
|
||||
},
|
||||
"end_repeat_count": {
|
||||
"higher": "Потребує більшої кількості повторень сигналу завершення — надійніше, дещо повільніше",
|
||||
"lower": "Завершує після меншої кількості повторень — швидше, більший ризик хибного завершення"
|
||||
"higher": "Потребує більшої кількості повторень сигналу завершення – надійніше, дещо повільніше",
|
||||
"lower": "Завершує після меншої кількості повторень – швидше, більший ризик хибного завершення"
|
||||
},
|
||||
"learning_confidence": {
|
||||
"higher": "Навчається лише на дуже впевнених збігах — повільніше, але надійніше",
|
||||
"higher": "Навчається лише на дуже впевнених збігах – повільніше, але надійніше",
|
||||
"lower": "Навчається на більшій кількості циклів; модель може бути більш зашумленою"
|
||||
},
|
||||
"min_off_gap": {
|
||||
"higher": "Перед новим циклом потрібен тривалий простій",
|
||||
"lower": "Короткий простій запускає новий цикл — послідовні запуски можуть розділитися"
|
||||
"lower": "Короткий простій запускає новий цикл – послідовні запуски можуть розділитися"
|
||||
},
|
||||
"min_power": {
|
||||
"higher": "Менш чутливий до фонового споживання; може пропустити тихі програми",
|
||||
@@ -1581,24 +1628,24 @@
|
||||
"lower": "Швидше примусово зупиняє зависший цикл"
|
||||
},
|
||||
"off_delay": {
|
||||
"higher": "Більше часу для пауз пристрою — обробляє тривале замочування або сушку",
|
||||
"lower": "Швидше визначення завершення — добре для пристроїв із чітким вкл./викл."
|
||||
"higher": "Більше часу для пауз пристрою – обробляє тривале замочування або сушку",
|
||||
"lower": "Швидше визначення завершення – добре для пристроїв із чітким вкл./викл."
|
||||
},
|
||||
"profile_match_threshold": {
|
||||
"higher": "Підтверджує лише збіги з високою впевненістю; більше циклів залишаються без мітки",
|
||||
"lower": "Зіставляє більше циклів; деякі можуть бути дещо неправильними"
|
||||
},
|
||||
"running_dead_zone": {
|
||||
"higher": "Ігнорує короткочасні стрибки потужності в режимі простою — менш чутливий до шуму",
|
||||
"lower": "Реагує на коротші сплески потужності — вловлює швидку перехідну активність"
|
||||
"higher": "Ігнорує короткочасні стрибки потужності в режимі простою – менш чутливий до шуму",
|
||||
"lower": "Реагує на коротші сплески потужності – вловлює швидку перехідну активність"
|
||||
},
|
||||
"start_threshold_w": {
|
||||
"higher": "Запобігає хибним запускам від короткочасних стрибків потужності",
|
||||
"lower": "Вловлює маломощні програми; може спрацювати на шум"
|
||||
},
|
||||
"stop_threshold_w": {
|
||||
"higher": "Завершує цикл швидше — може закрити під час паузи",
|
||||
"lower": "Довше очікує завершення — менше передчасних завершень"
|
||||
"higher": "Завершує цикл швидше – може закрити під час паузи",
|
||||
"lower": "Довше очікує завершення – менше передчасних завершень"
|
||||
},
|
||||
"watchdog_interval": {
|
||||
"higher": "Дозволяє триваліші тихі фази; менше хибних примусових зупинок",
|
||||
@@ -1676,12 +1723,19 @@
|
||||
"start_duration_threshold": "Секунди вище порогу для підтвердження старту",
|
||||
"start_threshold_w": "Мінімум ват, щоб вважати запущеним",
|
||||
"stop_threshold_w": "Нижче цього машина вважається вимкненою",
|
||||
"dtw_bandwidth": "Наскільки сильне розтягнення в часі дозволяє зіставлення за формою",
|
||||
"corr_weight": "Вага форми кривої відносно рівня потужності при зіставленні",
|
||||
"duration_weight": "Наскільки збіг за тривалістю впливає на зіставлення",
|
||||
"energy_weight": "Наскільки збіг за енергією впливає на зіставлення",
|
||||
"profile_match_min_duration_ratio": "Найкоротший запуск (щодо профілю), який ще може збігтися",
|
||||
"profile_match_max_duration_ratio": "Найдовший запуск (щодо профілю), який ще може збігтися"
|
||||
"dtw_bandwidth": "Етап 3: смуга деформації Sakoe-Chiba (0 = DTW вимкнено; за замовчуванням 0,2 = 20% довжини циклу)",
|
||||
"corr_weight": "Етап 2: баланс між формою кривої (кореляція) та рівнем потужності (MAE); за замовчуванням 0,45",
|
||||
"duration_weight": "Етап 4: наскільки сильно збіг за тривалістю впливає на кінцеву оцінку (за замовчуванням 0,22)",
|
||||
"energy_weight": "Етап 4: наскільки сильно збіг за енергією впливає на кінцеву оцінку (за замовчуванням 0,22)",
|
||||
"profile_match_min_duration_ratio": "Етап 1: мінімальна довжина циклу як частка тривалості профілю; за замовчуванням 0,1 (10%)",
|
||||
"profile_match_max_duration_ratio": "Етап 1: максимальна довжина циклу як частка тривалості профілю; за замовчуванням 1,5 (150%)",
|
||||
"keep_min_score": "Етап 2: мінімальна оцінка для участі у змаганні; за замовчуванням 0,1 допускає слабкі збіги, пізніші етапи обирають найкращий",
|
||||
"dtw_blend": "Етап 3: 0 = лише базова оцінка, 1 = лише оцінка DTW, 0,5 = рівне змішування (за замовчуванням)",
|
||||
"dtw_ensemble_w": "Етап 3 (режим ансамблю): вага масштабованого L1 проти похідного DTW; за замовчуванням 0,7 надає перевагу рівню",
|
||||
"dtw_ddtw_scale": "Етап 3: відстань напівнасичення DDTW; менша = більш чутлива до форми (за замовчуванням 30)",
|
||||
"dtw_refine_top_n": "Етап 3: кандидати, які DTW переоцінює; збільшіть до 7-9, якщо правильний профіль займає 4-5 місце (за замовчуванням 5)",
|
||||
"duration_scale": "Етап 4: лог-відношення, при якому збіг за тривалістю зменшується вдвічі; менше = суворіший штраф (за замовчуванням 0,175)",
|
||||
"energy_scale": "Етап 4: лог-відношення, при якому збіг за енергією зменшується вдвічі; менше = суворіший штраф (за замовчуванням 0,25)"
|
||||
},
|
||||
"col": {
|
||||
"profile_tip": "Назва зіставленої програми. «Без мітки» означає, що наприкінці циклу не збігся жоден профіль.",
|
||||
@@ -1766,6 +1820,69 @@
|
||||
},
|
||||
"pg_sweep": {
|
||||
"optimize": "Оптимізація: {param}"
|
||||
},
|
||||
"pg_detail": {
|
||||
"simulate": "Змоделювати цикл"
|
||||
},
|
||||
"split": {
|
||||
"apply": "Розділення циклу"
|
||||
},
|
||||
"trim": {
|
||||
"apply": "Обрізання циклу"
|
||||
},
|
||||
"merge": {
|
||||
"apply": "Об'єднання циклів"
|
||||
},
|
||||
"rebuild": {
|
||||
"envelopes": "Перерахунок обвідних"
|
||||
},
|
||||
"cancelling": "Скасування..."
|
||||
},
|
||||
"setup": {
|
||||
"hdr": {
|
||||
"card": "Налаштування пристрою",
|
||||
"healthy_chip": "Налаштування завершено"
|
||||
},
|
||||
"phase0": {
|
||||
"washer": "WashData вже виявляє ваші цикли. Запишіть перший цикл, щоб увімкнути назви програм і оцінки часу.",
|
||||
"dishwasher": "WashData спостерігає. Посудомийні машини мають складні цикли – запис першого циклу наполегливо рекомендується. Якщо виявлений цикл триває занадто довго, обріжте його в редакторі циклів перед збереженням як профіль.",
|
||||
"generic": "WashData спостерігає. Запишіть або позначте виявлений цикл, щоб почати створювати профілі."
|
||||
},
|
||||
"phase1a": {
|
||||
"labelled": "Гарний початок – ваша перша програма збережена. Для найчистіших даних розгляньте запис наступного циклу за допомогою віджета запису."
|
||||
},
|
||||
"phase1b": {
|
||||
"recorded": "Ваш запис збережено як {profile_name}. Тепер запишіть або позначте інші поширені програми для розширення охоплення."
|
||||
},
|
||||
"phase1c": {
|
||||
"verify": "У вас є {count} програм від спільноти. Запустіть цикл, щоб переконатися, що WashData правильно їх розпізнає – зіставлення покращуватиметься в міру того, як пристрій накопичує власну історію."
|
||||
},
|
||||
"phase2": {
|
||||
"cluster": "WashData виявив {count} циклів, які не відповідають жодній збереженій програмі – вони схожі один на одного. Хочете створити для них новий профіль?",
|
||||
"unmatched": "Ваш останній цикл не збігся з жодною збереженою програмою. Це нова програма?"
|
||||
},
|
||||
"phase3": {
|
||||
"suggestions": "WashData має рекомендації щодо налаштувань на основі вашої історії циклів – перегляньте їх для підвищення точності виявлення.",
|
||||
"groups": "Деякі ваші профілі схожі на одну й ту саму програму при різних температурах. Об'єднайте їх у групу для покращення зіставлення.",
|
||||
"phases": "Додайте фази програми до {profile_name} для точніших оцінок часу, що залишився."
|
||||
},
|
||||
"phase4": {
|
||||
"healthy": "Цей пристрій повністю налаштовано ({profile_count} профілів)."
|
||||
},
|
||||
"cta": {
|
||||
"start_recording": "Почати запис",
|
||||
"label_detected_cycle": "У мене вже є виявлений цикл – натомість позначити його",
|
||||
"browse_cycles": "Переглянути цикли для позначення наступного",
|
||||
"view_profiles": "Переглянути свої профілі",
|
||||
"create_from_cluster": "Створити профіль з цих циклів",
|
||||
"create_profile": "Створити для нього профіль",
|
||||
"review_suggestions": "Переглянути пропозиції",
|
||||
"organise_profiles": "Упорядкувати профілі",
|
||||
"configure_phases": "Налаштувати фази",
|
||||
"skip_step": "Пропустити цей крок",
|
||||
"skip_forever": "Більше не показувати",
|
||||
"hide_guidance": "Приховати підказки",
|
||||
"show_guidance": "Показати підказки"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
{
|
||||
"badge": {
|
||||
"artifact_tip": "检测到 {n} 个异常(例如,门在周期中打开)— 打开以在图表上查看",
|
||||
"artifact_tip": "检测到 {n} 个异常(例如,门在周期中打开)– 打开以在图表上查看",
|
||||
"auto": "(自动检测)",
|
||||
"built_in_tag": "内置",
|
||||
"declining": "↘ 下降中",
|
||||
"energy_low": "能耗低于正常水平",
|
||||
"energy_spike": "能耗高于正常水平",
|
||||
"fair_fit": "质量尚可",
|
||||
"fair_fit_tip": "匹配一致性适中 — 分配给此配置文件的部分周期置信度较低。标记更多周期或重新录制配置文件以提高准确性。",
|
||||
"fair_fit_tip": "匹配一致性适中 – 分配给此配置文件的部分周期置信度较低。标记更多周期或重新录制配置文件以提高准确性。",
|
||||
"feedback_requested": "已请求反馈",
|
||||
"golden_cycle": "记录参考周期",
|
||||
"improving": "↗ 提升中",
|
||||
@@ -15,7 +15,7 @@
|
||||
"needs_review": "需要审查",
|
||||
"overrun": "运行时间超出正常",
|
||||
"poor_fit": "质量差",
|
||||
"poor_fit_tip": "匹配历史不一致 — 考虑重建此配置文件",
|
||||
"poor_fit_tip": "匹配历史不一致 – 考虑重建此配置文件",
|
||||
"restart_gap_tip": "{n} HA 重启间隙 - 电源跟踪有漏洞",
|
||||
"reviewed": "已审核",
|
||||
"steady": "→ 稳定",
|
||||
@@ -57,7 +57,7 @@
|
||||
"create_profile": "+ 创建配置文件",
|
||||
"delete": "删除",
|
||||
"delete_group": "删除组",
|
||||
"delete_group_tip": "仅删除此组 — 保留成员配置文件",
|
||||
"delete_group_tip": "仅删除此组 – 保留成员配置文件",
|
||||
"delete_profile": "删除配置文件",
|
||||
"discard": "丢弃",
|
||||
"discard_tip": "丢弃录制的电力记录,不保存",
|
||||
@@ -87,7 +87,7 @@
|
||||
"on_cycle_finished": "周期完成时",
|
||||
"on_cycle_started": "周期开始时",
|
||||
"pause_cycle": "暂停",
|
||||
"pause_cycle_tip": "暂停正在运行的周期 — 设备将从中断处恢复",
|
||||
"pause_cycle_tip": "暂停正在运行的周期 – 设备将从中断处恢复",
|
||||
"pg_apply_device": "应用到设备",
|
||||
"pg_autofill": "自动填充",
|
||||
"play": "播放",
|
||||
@@ -97,8 +97,8 @@
|
||||
"process_tip": "将录制的电力记录保存为新的或现有的配置文件",
|
||||
"rebuild": "重建包络",
|
||||
"rebuild_envelope": "重建包络",
|
||||
"rebuild_tip": "从已标记周期重新计算所有配置文件的预期功率包络(最小/最大范围)— 在标记新周期或修正旧周期后运行",
|
||||
"rec_start_tip": "开始录制设备的电力轨迹 — 在运行周期之前立即开始",
|
||||
"rebuild_tip": "从已标记周期重新计算所有配置文件的预期功率包络(最小/最大范围)– 在标记新周期或修正旧周期后运行",
|
||||
"rec_start_tip": "开始录制设备的电力轨迹 – 在运行周期之前立即开始",
|
||||
"rec_stop": "停止",
|
||||
"rec_stop_tip": "停止录制并保留已捕获的电力记录以供审核",
|
||||
"record": "开始录制",
|
||||
@@ -231,7 +231,7 @@
|
||||
"interval": "应至少为采样间隔 ({si} 秒) 的 2 倍",
|
||||
"sampling": "采样间隔应最多为看门狗间隔 ({wi} 秒) 的一半"
|
||||
},
|
||||
"settings_banner": "{n} 个设置冲突{s} — 请检查高亮显示的部分,并在保存前修复。",
|
||||
"settings_banner": "{n} 个设置冲突{s} – 请检查高亮显示的部分,并在保存前修复。",
|
||||
"settings_banner_btn": "前往第一处"
|
||||
},
|
||||
"hdr": {
|
||||
@@ -451,9 +451,9 @@
|
||||
"show_expected": "显示预期曲线叠加(匹配配置文件,橙色)",
|
||||
"show_raw": "在实时功率图中显示原始插座切换开关",
|
||||
"sparkline": "近期周期时长趋势",
|
||||
"stage2": "阶段 2 — 核心相似度",
|
||||
"stage3": "阶段 3 — DTW",
|
||||
"stage4": "阶段 4 — 一致度",
|
||||
"stage2": "阶段 2 – 核心相似度",
|
||||
"stage3": "阶段 3 – DTW",
|
||||
"stage4": "阶段 4 – 一致度",
|
||||
"status": "状态",
|
||||
"tail_trim": "尾部裁剪(秒)",
|
||||
"timer_auto_pause": "自动暂停",
|
||||
@@ -561,7 +561,12 @@
|
||||
"flags": "标志",
|
||||
"include_phase_map": "包含阶段图",
|
||||
"include_settings": "包含检测与匹配设置",
|
||||
"show_contributor": "显示贡献者名称"
|
||||
"show_contributor": "显示贡献者名称",
|
||||
"task_pg_detail": "模拟周期",
|
||||
"task_split": "正在拆分周期",
|
||||
"task_trim": "正在裁剪周期",
|
||||
"task_merge": "正在合并周期",
|
||||
"task_rebuild": "正在重建包络"
|
||||
},
|
||||
"log": {
|
||||
"all_levels": "所有级别",
|
||||
@@ -645,7 +650,7 @@
|
||||
"artifact_dip_detail": "跌破通常功率范围约 {n} 秒。",
|
||||
"artifact_footer": "在上图中高亮显示。这些是瞬态异常(例如门在周期中打开),不一定是问题。",
|
||||
"artifact_header": "此周期中检测到 {n} 个异常",
|
||||
"artifact_pause_detail": "功率降至接近零约 {n} 秒后恢复 — 可能是周期中途开门或周期被暂停。",
|
||||
"artifact_pause_detail": "功率降至接近零约 {n} 秒后恢复 – 可能是周期中途开门或周期被暂停。",
|
||||
"artifact_spike_detail": "超出通常功率范围约 {n} 秒。",
|
||||
"auto_label_intro": "为置信度达到阈值的未标记周期分配配置文件。",
|
||||
"automations_intro": "WashData 触发 {start} / {end} 事件并公开实体,因此通知和操作最好构建为常规 Home Assistant 自动化。使用此设备的自动化显示在下方。",
|
||||
@@ -654,10 +659,10 @@
|
||||
"collecting_data": "正在收集数据,还需要 {need} 个周期{plural}才能开始微调({current}/{min})。",
|
||||
"compare_overlay_profiles": "叠加配置文件(浅色)",
|
||||
"compare_profiles_tip": "将其他配置文件包络叠加在上方图表上,看哪个最适合此周期。",
|
||||
"compare_selected_cycles": "选中的周期(实线)— 显示/隐藏",
|
||||
"compare_selected_cycles": "选中的周期(实线)– 显示/隐藏",
|
||||
"consider_new_profile": "考虑创建新配置文件。",
|
||||
"coverage_gap": "近期周期没有匹配的配置文件(最近 30 次的 {pct}%)。",
|
||||
"coverage_gap_similar_cycles": "发现 {count} 个相似未标记周期 — 创建配置文件以开始匹配它们。",
|
||||
"coverage_gap_similar_cycles": "发现 {count} 个相似未标记周期 – 创建配置文件以开始匹配它们。",
|
||||
"cycles_deleted": "已删除 {count} 个周期",
|
||||
"enough_data": "有足够数据可供学习({current}/{min} 个循环)。",
|
||||
"export_description": "将所有配置文件和周期导出为 JSON,或从之前的导出中恢复。",
|
||||
@@ -686,7 +691,7 @@
|
||||
"ml_learned_intro": "针对此机器微调的模型。",
|
||||
"ml_loading": "加载 ML 中…",
|
||||
"ml_settings_intro": "两个独立开关:一个在周期运行时应用模型,另一个让 WashData 随时间针对您的机器进行微调。",
|
||||
"name_first_program": "您已有足够的周期 — 为您的第一个程序命名即可开始匹配。",
|
||||
"name_first_program": "您已有足够的周期 – 为您的第一个程序命名即可开始匹配。",
|
||||
"near_duplicate_cluster": "检测到近似重复的配置文件群。分组可让匹配在相似项目间可靠地选择(例如同一程序在不同温度/转速下)。",
|
||||
"no_cycles_match": "没有与当前筛选条件匹配的周期。",
|
||||
"no_cycles_profile": "此配置文件没有周期。",
|
||||
@@ -694,12 +699,12 @@
|
||||
"no_cycles_yet": "尚未记录任何周期。",
|
||||
"no_device_selected": "未选择设备。",
|
||||
"no_devices": "尚未配置 WashData 设备。",
|
||||
"no_envelope": "还没有包络 — 标记周期后重建。",
|
||||
"no_envelope": "还没有包络 – 标记周期后重建。",
|
||||
"no_envelope_overlay": "没有可叠加的包络。",
|
||||
"no_fine_tuned": "尚未微调 — WashData 正在使用内置模型。",
|
||||
"no_fine_tuned": "尚未微调 – WashData 正在使用内置模型。",
|
||||
"no_logs": "尚未缓冲任何日志记录。",
|
||||
"no_maintenance": "尚未记录任何维护。",
|
||||
"no_match_yet": "尚未尝试匹配 — 此项在运行周期时填充。",
|
||||
"no_match_yet": "尚未尝试匹配 – 此项在运行周期时填充。",
|
||||
"no_other_users": "未找到其他 Home Assistant 用户。",
|
||||
"no_phases": "未定义阶段。",
|
||||
"no_phases_assigned": "未分配阶段。",
|
||||
@@ -713,7 +718,7 @@
|
||||
"notify_services_hint": "使用 {entity} 服务 ID(多个请用英文逗号分隔)。模板变量:{vars}。",
|
||||
"old_actions_warning": "使用旧版操作编辑器配置(现已移除)。它们仍会在周期事件上触发,但无法在此处编辑。将它们转换为普通自动化,或移除它们。",
|
||||
"onboarding_progress": "已观察 {n} / 3 个周期",
|
||||
"onboarding_watching": "照常使用您的设备 — WashData 正在观察。3 个周期后将开始程序匹配。",
|
||||
"onboarding_watching": "照常使用您的设备 – WashData 正在观察。3 个周期后将开始程序匹配。",
|
||||
"pending_feedback": "待处理的检测反馈",
|
||||
"performance_trend": "性能趋势({n} 个周期)",
|
||||
"pg_analysis_empty": "加载一个周期以查看匹配分析。",
|
||||
@@ -745,16 +750,16 @@
|
||||
"recent_logs": "最近的 ha_washdata 记录",
|
||||
"recording_in_progress": "录制进行中",
|
||||
"reminders_intro": "在上次保养后经过这么多个周期时在面板中显示提醒。留空或填 0 可关闭提醒。",
|
||||
"restart_gap_footer": "在图表上突出显示。这些间隔的功率数据缺失——仅使用真实读数进行匹配。",
|
||||
"restart_gap_footer": "在图表上突出显示。这些间隔的功率数据缺失––仅使用真实读数进行匹配。",
|
||||
"restart_gap_header": "{n} 此周期内的 HA 重新启动间隔",
|
||||
"restart_gap_item": "{dur}间隙",
|
||||
"review_confirm_help": "确认此周期是否被正确检测。您的审查可在您的机器上训练模型 — 确认的周期越多,匹配和健康评分越好。快速的好/差就足够了。",
|
||||
"review_confirm_help": "确认此周期是否被正确检测。您的审查可在您的机器上训练模型 – 确认的周期越多,匹配和健康评分越好。快速的好/差就足够了。",
|
||||
"review_in_settings": "在设置中审查",
|
||||
"review_notes_placeholder": "注释(可选)",
|
||||
"review_notes_tip": "供个人参考的自由文本注释。不用于匹配或训练。",
|
||||
"review_profile_tip": "此周期标记的程序。如果自动检测的程序有误,请在此处修正 — 标记可帮助未来周期的匹配学习。",
|
||||
"review_profile_tip": "此周期标记的程序。如果自动检测的程序有误,请在此处修正 – 标记可帮助未来周期的匹配学习。",
|
||||
"review_quality_tip": "此周期的质量。好 = 该程序的标准示例;差 = 已检测但有噪声或不典型;不可用 = 误检测(合并、截断或虚假)。影响健康评分及允许训练模型的周期。",
|
||||
"review_recorded_tip": "将此标记为其程序的精选参考周期 — 与手动录制周期的作用相同。参考周期始终保留,为匹配模板提供种子,且不会被清理删除。(这是“黄金”/录制标志;两者是同一件事。)",
|
||||
"review_recorded_tip": "将此标记为其程序的精选参考周期 – 与手动录制周期的作用相同。参考周期始终保留,为匹配模板提供种子,且不会被清理删除。(这是“黄金”/录制标志;两者是同一件事。)",
|
||||
"review_tags_tip": "描述此周期出现问题的可选标志,以便训练和清理可以考虑这些问题。",
|
||||
"review_to_cycles": "打开周期审查队列",
|
||||
"saving_triggers_reload": "保存会触发集成重载。HA 实体可能短暂显示为不可用。",
|
||||
@@ -763,7 +768,7 @@
|
||||
"setting_changed": "于 {date} 从 {old} 更改为 {new}",
|
||||
"settings_basic_note": "正在显示基本设置。切换到高级可查看完整列表。",
|
||||
"shape_drift_advisory": "⚠ 形状偏移",
|
||||
"shape_drift_detail": "此配置文件的功率模式随时间发生了变化 — 可能是设备磨损或需要维护(例如除垢、清洁滤网)。",
|
||||
"shape_drift_detail": "此配置文件的功率模式随时间发生了变化 – 可能是设备磨损或需要维护(例如除垢、清洁滤网)。",
|
||||
"show_all_settings": "显示所有设置",
|
||||
"showing_suggestions": "显示 {count} 个有建议的设置。",
|
||||
"split_intro": "点击图表添加或删除分割点,或通过空闲间隔自动检测。每个结果片段可获得自己的配置文件。",
|
||||
@@ -789,10 +794,10 @@
|
||||
"toast_revert_failed": "还原失败:{error}",
|
||||
"toast_reverted": "已还原 {key}",
|
||||
"toast_save_failed": "保存失败:{error}",
|
||||
"trend_duration_longer": "时长趋势增长({pct}%/周期)— 近期平均 {avg}",
|
||||
"trend_duration_shorter": "时长趋势缩短({pct}%/周期)— 近期平均 {avg}",
|
||||
"trend_duration_longer": "时长趋势增长({pct}%/周期)– 近期平均 {avg}",
|
||||
"trend_duration_shorter": "时长趋势缩短({pct}%/周期)– 近期平均 {avg}",
|
||||
"trend_energy_down": "能耗趋势下降({pct}%/周期)",
|
||||
"trend_energy_up": "能耗趋势上升({pct}%/周期)— 近期平均 {avg}",
|
||||
"trend_energy_up": "能耗趋势上升({pct}%/周期)– 近期平均 {avg}",
|
||||
"trim_intro": "拖动红色控制柄,或输入值。窗口外的所有内容将被移除。",
|
||||
"tuning_suggestions_available": "来自观察周期的 {count} 个调整建议可用。它们显示在相关字段旁边。",
|
||||
"unsure_detected_prefix": "WashData 不确定是否检测到",
|
||||
@@ -857,7 +862,9 @@
|
||||
"share_guidelines_title": "分享前须知",
|
||||
"store_download_device_intro": "将所有共享程序及其参考周期采用到您的设备。您自己录制的周期和统计数据不受影响。",
|
||||
"store_share_device_intro": "上传 {brand} {model} 及您选择的参考周期。拥有相同设备的其他用户可以采用您的程序。条目在公开前经过审核。",
|
||||
"share_profile_no_cycles": "无参考周期 -- 请在\"周期\"选项卡中将周期标记为 ⭐ 以包含此配置文件"
|
||||
"share_profile_no_cycles": "无参考周期 -- 请在\"周期\"选项卡中将周期标记为 ⭐ 以包含此配置文件",
|
||||
"advisory_phase_inconsistent": "'{name}' 似乎混合了不同的程序或温度,各周期的加热时长差异很大。将其拆分为独立的配置文件(例如按温度区分)可以改善匹配和时间估算。",
|
||||
"advisory_phase_inconsistent_title": "⚠ 可能混合了不同程序"
|
||||
},
|
||||
"pg_desc": {
|
||||
"abrupt_drop_watts": "骤降视为立即结束",
|
||||
@@ -869,12 +876,19 @@
|
||||
"start_duration_threshold": "确认启动所需的超阈值秒数",
|
||||
"start_threshold_w": "计为启动的最小瓦数",
|
||||
"stop_threshold_w": "低于此值机器计为关闭",
|
||||
"dtw_bandwidth": "形状匹配允许的时间扭曲程度",
|
||||
"corr_weight": "匹配中曲线形状与功率水平的权重",
|
||||
"duration_weight": "运行时长的吻合程度对匹配的影响大小",
|
||||
"energy_weight": "能耗吻合程度对匹配的影响大小",
|
||||
"profile_match_min_duration_ratio": "仍可用于匹配的最短运行时长(相对于程序档案)",
|
||||
"profile_match_max_duration_ratio": "仍可用于匹配的最长运行时长(相对于程序档案)"
|
||||
"dtw_bandwidth": "Stage 3: Sakoe-Chiba 规整带宽 (0 = DTW 关闭; 默认 0.2 = 周期长度的 20%)",
|
||||
"corr_weight": "Stage 2: 曲线形状(相关性)与功率水平(MAE)之间的平衡; 默认 0.45",
|
||||
"duration_weight": "Stage 4: 运行时长一致性对最终得分的影响程度(默认 0.22)",
|
||||
"energy_weight": "Stage 4: 能耗一致性对最终得分的影响程度(默认 0.22)",
|
||||
"profile_match_min_duration_ratio": "Stage 1: 最短允许运行时长占档案时长的比例; 默认 0.1 (10%)",
|
||||
"profile_match_max_duration_ratio": "Stage 1: 最长允许运行时长占档案时长的比例; 默认 1.5 (150%)",
|
||||
"keep_min_score": "Stage 2: 保留在竞争中的最低得分; 默认 0.1 接受弱候选,后续阶段选出最佳",
|
||||
"dtw_blend": "Stage 3: 0 = 仅核心得分,1 = 仅 DTW 得分,0.5 = 等权混合(默认)",
|
||||
"dtw_ensemble_w": "Stage 3 (集成模式): 缩放 L1 对导数 DTW 的权重; 默认 0.7 偏重水平感知",
|
||||
"dtw_ddtw_scale": "Stage 3: DDTW 半饱和距离; 越小对形状越敏感(默认 30)",
|
||||
"dtw_refine_top_n": "Stage 3: DTW 重新评分的候选数量; 若正确档案排在第 4-5 位则调高至 7-9(默认 5)",
|
||||
"duration_scale": "Stage 4: 时长一致性得分减半时的对数比率; 越小惩罚越严格(默认 0.175)",
|
||||
"energy_scale": "Stage 4: 能耗一致性得分减半时的对数比率; 越小惩罚越严格(默认 0.25)"
|
||||
},
|
||||
"phase_desc": {
|
||||
"anti_crease": "完成后偶尔进行短暂的翻滚以减少皱纹。",
|
||||
@@ -957,6 +971,10 @@
|
||||
"triggers": {
|
||||
"intro": "可选的外部信号:结束触发器、门传感器、暂停开关和卸载提醒。",
|
||||
"label": "触发器与门"
|
||||
},
|
||||
"phase_eta": {
|
||||
"label": "剩余时间",
|
||||
"intro": "阶段感知的剩余时间,适用于周期长度取决于温度或脱水的机器。"
|
||||
}
|
||||
},
|
||||
"setting": {
|
||||
@@ -1040,6 +1058,10 @@
|
||||
"doc": "当上面未设置实时价格实体时,每千瓦时的固定价格用于成本数据。",
|
||||
"label": "固定电价(每 kWh)"
|
||||
},
|
||||
"energy_sensor": {
|
||||
"doc": "可选的累积电能计数器(total_increasing 的 kWh/Wh,例如插座自带的累计电能表)。设置后,每个周期报告的能耗将取自该计数器从开始到结束的差值(delta),从而避免因积分上报缓慢的功率传感器而导致的少计。若读数缺失、单位未知或差值不为正,则回退到积分值。留空则继续对功率传感器进行积分。",
|
||||
"label": "电能表实体"
|
||||
},
|
||||
"expose_debug_entities": {
|
||||
"doc": "发布额外的诊断 HA 实体(匹配置信度、模糊性、状态内部)。关闭可保持实体列表干净以供正常使用。",
|
||||
"label": "暴露调试实体"
|
||||
@@ -1073,7 +1095,7 @@
|
||||
"label": "最小功率"
|
||||
},
|
||||
"ml_training_enabled": {
|
||||
"doc": "定期隔夜研究您审查的循环,并针对该特定机器微调模型。只有当改变在持续的周期中真正取得更好的成绩时,才会保留改变,因此这只能有所帮助或保持不变——永远不会倒退。",
|
||||
"doc": "定期隔夜研究您审查的循环,并针对该特定机器微调模型。只有当改变在持续的周期中真正取得更好的成绩时,才会保留改变,因此这只能有所帮助或保持不变––永远不会倒退。",
|
||||
"label": "从此机器学习"
|
||||
},
|
||||
"ml_training_hour": {
|
||||
@@ -1322,6 +1344,38 @@
|
||||
},
|
||||
"show_contributor": {
|
||||
"doc": "在社区家电和参考周期上显示\"by <contributor>\"的贡献者署名。"
|
||||
},
|
||||
"enable_phase_matching": {
|
||||
"label": "阶段感知的剩余时间",
|
||||
"doc": "将每个运行中的周期分解为多个阶段(加热、洗涤、脱水),按阶段分配剩余时间,并与经典估算相融合:周期早期更依赖阶段分配,接近结束时更依赖经典估算。这会根据您的机器实际加热和运行的时长来个性化倒计时,在周期的前半段效果最明显。关闭 = 仅使用经典估算。仅影响剩余时间显示;程序匹配和周期检测保持不变。"
|
||||
},
|
||||
"keep_min_score": {
|
||||
"label": "最低匹配得分",
|
||||
"doc": "候选档案留在匹配竞争中所需的最低相似度得分。默认 0.1 有意设置得较宽松,允许弱候选也进入,由后续阶段找出最佳匹配。提高此值可更早淘汰不合适的档案;降低此值可扩大初始候选池。"
|
||||
},
|
||||
"dtw_blend": {
|
||||
"label": "规整混合",
|
||||
"doc": "时间规整(DTW)对齐得分替换 Stage 2 核心得分的程度。0 = 仅使用 Stage 2 得分,1 = 仅使用 DTW 得分,0.5(默认)= 等权混合。当程序功率水平相近但时序模式不同时,可提高此值以更多依赖规整对齐。"
|
||||
},
|
||||
"dtw_ensemble_w": {
|
||||
"label": "规整集成混合",
|
||||
"doc": "在集成 DTW 模式(默认)下,缩放 L1 与导数 DTW(DDTW)的权重分配。1.0 = 全部缩放-L1,0 = 全部 DDTW,0.7 = 默认。缩放-L1 变体比较功率水平;导数变体对功率如何随时间变化做出响应。集成模式将二者结合。"
|
||||
},
|
||||
"dtw_ddtw_scale": {
|
||||
"label": "导数规整尺度",
|
||||
"doc": "导数 DTW 评分的半饱和距离。当 DDTW 距离等于此值时,得分减半。越小对形状差异越敏感。默认 30 针对典型家电功率曲线进行了校准。仅影响集成和 ddtw DTW 模式。"
|
||||
},
|
||||
"dtw_refine_top_n": {
|
||||
"label": "规整精化数量",
|
||||
"doc": "DTW 重新评分的 Stage 2 顶部候选数量。由于 DTW 计算代价较高,仅对前 N 个候选应用。默认 5。若正确档案有时在 Stage 2 后只排到第 4 或第 5 位,可调高此值(至 7-9),DTW 能将其拉回。降低此值可略微加速匹配。"
|
||||
},
|
||||
"duration_scale": {
|
||||
"label": "时长锐度",
|
||||
"doc": "Stage 4 时长一致性惩罚的锐度。这是一致性得分减半时的对数比率。越小越严格:时长不匹配的惩罚越大。默认 0.175 对应半权重下约 18% 的时长容差。请与时长权重配合使用。"
|
||||
},
|
||||
"energy_scale": {
|
||||
"label": "能耗锐度",
|
||||
"doc": "Stage 4 能耗一致性惩罚的锐度。越小越严格:能耗不匹配的惩罚越大。默认 0.25 有意比时长锐度更宽松,因为能耗会随负荷变化。请与能耗权重配合使用。"
|
||||
}
|
||||
},
|
||||
"setting_group": {
|
||||
@@ -1570,24 +1624,24 @@
|
||||
"lower": "自动标记更多循环,部分可能被误识别"
|
||||
},
|
||||
"duration_tolerance": {
|
||||
"higher": "接受更宽的时长范围——匹配更灵活",
|
||||
"lower": "要求时长更接近——更严格,但可能拒绝非常规循环"
|
||||
"higher": "接受更宽的时长范围––匹配更灵活",
|
||||
"lower": "要求时长更接近––更严格,但可能拒绝非常规循环"
|
||||
},
|
||||
"end_energy_threshold": {
|
||||
"higher": "仅关闭消耗大量能量的循环",
|
||||
"lower": "也关闭较短或低能耗的循环"
|
||||
},
|
||||
"end_repeat_count": {
|
||||
"higher": "结束信号需重复更多次——更稳健,但略慢",
|
||||
"lower": "更少重复后结束——检测更快,但误结束风险更高"
|
||||
"higher": "结束信号需重复更多次––更稳健,但略慢",
|
||||
"lower": "更少重复后结束––检测更快,但误结束风险更高"
|
||||
},
|
||||
"learning_confidence": {
|
||||
"higher": "仅从高置信度匹配中学习——较慢但更可靠",
|
||||
"higher": "仅从高置信度匹配中学习––较慢但更可靠",
|
||||
"lower": "从更多循环中学习,模型可能更嘈杂"
|
||||
},
|
||||
"min_off_gap": {
|
||||
"higher": "新循环开始前需要更长的空闲时间",
|
||||
"lower": "短暂空闲即触发新循环——连续运行可能被拆分"
|
||||
"lower": "短暂空闲即触发新循环––连续运行可能被拆分"
|
||||
},
|
||||
"min_power": {
|
||||
"higher": "对待机功耗不那么敏感,可能遗漏非常安静的程序",
|
||||
@@ -1598,24 +1652,24 @@
|
||||
"lower": "更快地强制终止卡住的循环"
|
||||
},
|
||||
"off_delay": {
|
||||
"higher": "为设备暂停留出更多时间——适合长时间浸泡或烘干阶段",
|
||||
"lower": "更快检测结束——适合干净的开关设备"
|
||||
"higher": "为设备暂停留出更多时间––适合长时间浸泡或烘干阶段",
|
||||
"lower": "更快检测结束––适合干净的开关设备"
|
||||
},
|
||||
"profile_match_threshold": {
|
||||
"higher": "仅提交高置信度匹配,更多循环保持未标记",
|
||||
"lower": "匹配更多循环,部分可能略有偏差"
|
||||
},
|
||||
"running_dead_zone": {
|
||||
"higher": "忽略待机时的短暂功率尖峰——对噪声不那么敏感",
|
||||
"lower": "响应更短的功率突发——捕捉快速瞬态活动"
|
||||
"higher": "忽略待机时的短暂功率尖峰––对噪声不那么敏感",
|
||||
"lower": "响应更短的功率突发––捕捉快速瞬态活动"
|
||||
},
|
||||
"start_threshold_w": {
|
||||
"higher": "避免因短暂功率尖峰引起的误启动",
|
||||
"lower": "捕捉低功率程序,可能对噪声触发"
|
||||
},
|
||||
"stop_threshold_w": {
|
||||
"higher": "更快结束循环——可能在暂停时关闭",
|
||||
"lower": "等待更长时间结束——减少提前完成"
|
||||
"higher": "更快结束循环––可能在暂停时关闭",
|
||||
"lower": "等待更长时间结束––减少提前完成"
|
||||
},
|
||||
"watchdog_interval": {
|
||||
"higher": "允许更长的静默阶段,减少误强制停止",
|
||||
@@ -1766,6 +1820,69 @@
|
||||
},
|
||||
"pg_sweep": {
|
||||
"optimize": "优化:{param}"
|
||||
},
|
||||
"pg_detail": {
|
||||
"simulate": "模拟周期"
|
||||
},
|
||||
"split": {
|
||||
"apply": "正在拆分周期"
|
||||
},
|
||||
"trim": {
|
||||
"apply": "正在裁剪周期"
|
||||
},
|
||||
"merge": {
|
||||
"apply": "正在合并周期"
|
||||
},
|
||||
"rebuild": {
|
||||
"envelopes": "正在重建包络"
|
||||
},
|
||||
"cancelling": "正在取消..."
|
||||
},
|
||||
"setup": {
|
||||
"hdr": {
|
||||
"card": "设备设置",
|
||||
"healthy_chip": "设置完成"
|
||||
},
|
||||
"phase0": {
|
||||
"washer": "WashData 已在检测您的周期。录制第一个周期以启用程序名称和时间估算。",
|
||||
"dishwasher": "WashData 正在监视。洗碗机的周期较为复杂 – 强烈建议录制第一个周期。如果检测到的周期运行过长,请使用周期编辑器在保存为配置文件前进行裁剪。",
|
||||
"generic": "WashData 正在监视。录制或标记检测到的周期,开始构建配置文件。"
|
||||
},
|
||||
"phase1a": {
|
||||
"labelled": "良好的开始 – 您的第一个程序已保存。为获得最准确的数据,建议使用录制小部件录制下一个周期。"
|
||||
},
|
||||
"phase1b": {
|
||||
"recorded": "您的录制已保存为 {profile_name}。现在录制或标记您的其他常用程序以建立覆盖范围。"
|
||||
},
|
||||
"phase1c": {
|
||||
"verify": "您有来自社区的 {count} 个程序。运行一个周期以验证 WashData 是否正确识别 – 随着设备积累自己的历史记录,匹配将不断改善。"
|
||||
},
|
||||
"phase2": {
|
||||
"cluster": "WashData 发现了 {count} 个与任何已保存程序不匹配的周期 – 它们彼此相似。想为这些周期创建新配置文件吗?",
|
||||
"unmatched": "您的上一个周期与任何已保存的程序不匹配。是新程序吗?"
|
||||
},
|
||||
"phase3": {
|
||||
"suggestions": "WashData 根据您的周期历史记录提供了设置建议 – 请查看以提高检测精度。",
|
||||
"groups": "您的部分配置文件看起来像在不同温度下运行的同一程序。将它们整理成组以获得更好的匹配效果。",
|
||||
"phases": "为 {profile_name} 添加程序阶段,以获得更准确的剩余时间估算。"
|
||||
},
|
||||
"phase4": {
|
||||
"healthy": "此设备已完全设置好({profile_count} 个配置文件)。"
|
||||
},
|
||||
"cta": {
|
||||
"start_recording": "开始录制",
|
||||
"label_detected_cycle": "我已有检测到的周期 – 直接标记",
|
||||
"browse_cycles": "浏览周期以标记其他",
|
||||
"view_profiles": "查看您的配置文件",
|
||||
"create_from_cluster": "从这些周期创建配置文件",
|
||||
"create_profile": "为此创建配置文件",
|
||||
"review_suggestions": "查看建议",
|
||||
"organise_profiles": "整理配置文件",
|
||||
"configure_phases": "配置阶段",
|
||||
"skip_step": "跳过此步骤",
|
||||
"skip_forever": "不再显示",
|
||||
"hide_guidance": "隐藏指南",
|
||||
"show_guidance": "显示指南"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,9 +40,12 @@ from .const import (
|
||||
CONF_COMPLETION_MIN_SECONDS,
|
||||
CONF_DEVICE_TYPE,
|
||||
CONF_DOOR_SENSOR_ENTITY,
|
||||
CONF_ANTI_WRINKLE_EXIT_POWER,
|
||||
CONF_ANTI_WRINKLE_MAX_POWER,
|
||||
CONF_DURATION_TOLERANCE,
|
||||
CONF_END_ENERGY_THRESHOLD,
|
||||
CONF_END_REPEAT_COUNT,
|
||||
CONF_ENERGY_SENSOR,
|
||||
CONF_EXTERNAL_END_TRIGGER,
|
||||
CONF_LEARNING_CONFIDENCE,
|
||||
CONF_LINKED_DEVICE,
|
||||
@@ -57,7 +60,9 @@ from .const import (
|
||||
CONF_PROFILE_MATCH_MIN_DURATION_RATIO,
|
||||
CONF_PROFILE_MATCH_THRESHOLD,
|
||||
CONF_PROFILE_MIN_WARMUP_CYCLES,
|
||||
CONF_PROFILE_UNMATCH_THRESHOLD,
|
||||
CONF_PUMP_STUCK_DURATION,
|
||||
CONF_POWER_OFF_THRESHOLD_W,
|
||||
CONF_RUNNING_DEAD_ZONE,
|
||||
CONF_SAMPLING_INTERVAL,
|
||||
CONF_SMOOTHING_WINDOW,
|
||||
@@ -82,6 +87,7 @@ from .const import (
|
||||
from . import playground
|
||||
from . import task_registry
|
||||
from .cycle_detector import CycleDetectorConfig
|
||||
from .setup_advisor import compute_setup_phase
|
||||
from .ws_schema import WS_OPEN_RESPONSES, WS_RESPONSE_TYPES
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
@@ -175,6 +181,12 @@ _SUGGESTION_KEYS: tuple[str, ...] = (
|
||||
CONF_LEARNING_CONFIDENCE,
|
||||
CONF_PROFILE_MATCH_THRESHOLD,
|
||||
CONF_END_REPEAT_COUNT,
|
||||
# Device-class-specific suggestions from reconcile_suggestions
|
||||
CONF_PROFILE_UNMATCH_THRESHOLD,
|
||||
CONF_POWER_OFF_THRESHOLD_W,
|
||||
CONF_ANTI_WRINKLE_EXIT_POWER,
|
||||
CONF_ANTI_WRINKLE_MAX_POWER,
|
||||
CONF_PUMP_STUCK_DURATION,
|
||||
)
|
||||
|
||||
# Suggestion keys coerced to int when applied (mirrors the OptionsFlow).
|
||||
@@ -188,6 +200,7 @@ _SUGGESTION_INT_KEYS: frozenset[str] = frozenset({
|
||||
CONF_SMOOTHING_WINDOW,
|
||||
CONF_COMPLETION_MIN_SECONDS,
|
||||
CONF_END_REPEAT_COUNT,
|
||||
CONF_PUMP_STUCK_DURATION,
|
||||
})
|
||||
|
||||
|
||||
@@ -288,8 +301,15 @@ async def _recorder_power(hass: HomeAssistant, entity_id: str, start_dt: Any) ->
|
||||
|
||||
|
||||
def _cycle_kwh(c: dict[str, Any]) -> float | None:
|
||||
"""Cycle energy in kWh. Cycles store energy as ``energy_wh``; convert."""
|
||||
wh = c.get("energy_wh")
|
||||
"""Cycle energy in kWh for display.
|
||||
|
||||
Prefers the external meter's reading (``energy_meter_wh``, issue #316) when a
|
||||
cycle recorded one, otherwise the integrated ``energy_wh``. Cycles store energy
|
||||
in Wh; convert to kWh.
|
||||
"""
|
||||
wh = c.get("energy_meter_wh")
|
||||
if wh is None:
|
||||
wh = c.get("energy_wh")
|
||||
if wh is not None:
|
||||
try:
|
||||
return round(float(wh) / 1000.0, 4)
|
||||
@@ -449,7 +469,6 @@ _ADMIN_COMMANDS = frozenset({
|
||||
# with get_, so it is whitelisted here to gate at the 'read' level.
|
||||
_READ_WRITE_COMMANDS = frozenset({
|
||||
"set_program",
|
||||
"run_playground_simulation",
|
||||
"run_playground_cycle_detail",
|
||||
"run_playground_history",
|
||||
"run_playground_sweep",
|
||||
@@ -461,6 +480,7 @@ _READ_WRITE_COMMANDS = frozenset({
|
||||
"get_task_result",
|
||||
"start_playground_history",
|
||||
"start_playground_sweep",
|
||||
"start_playground_cycle_detail",
|
||||
# Community store: read-only browse is read-level (writes below default to 'edit').
|
||||
"store_status",
|
||||
"store_search_devices",
|
||||
@@ -1030,6 +1050,7 @@ def async_register_commands(hass: HomeAssistant) -> None:
|
||||
ws_get_devices, ws_get_device_cycles,
|
||||
# Settings
|
||||
ws_get_options, ws_set_options, ws_get_settings_changelog,
|
||||
ws_get_setup_status,
|
||||
# Profiles
|
||||
ws_get_profiles, ws_create_profile, ws_rename_profile, ws_delete_profile,
|
||||
ws_rebuild_envelopes, ws_get_profile_phases, ws_set_profile_phases,
|
||||
@@ -1076,8 +1097,8 @@ def async_register_commands(hass: HomeAssistant) -> None:
|
||||
ws_revert_ml_models,
|
||||
# Cycle controls (pause / resume / force-stop)
|
||||
ws_pause_cycle, ws_resume_cycle, ws_terminate_cycle,
|
||||
# Playground (F3): headless what-if replay + DTW visualizer
|
||||
ws_run_playground_simulation, ws_get_dtw_debug,
|
||||
# Playground (F3): DTW visualizer
|
||||
ws_get_dtw_debug,
|
||||
# Playground redesign: faithful single-cycle sim + history table + sweep
|
||||
ws_run_playground_cycle_detail, ws_run_playground_history,
|
||||
ws_run_playground_sweep,
|
||||
@@ -1085,6 +1106,7 @@ def async_register_commands(hass: HomeAssistant) -> None:
|
||||
ws_list_tasks, ws_subscribe_tasks, ws_cancel_task, ws_get_task_result,
|
||||
# Playground batch/sweep as detached registry-tracked tasks
|
||||
ws_start_playground_history, ws_start_playground_sweep,
|
||||
ws_start_playground_cycle_detail,
|
||||
# Community store (online features): status/connect/disconnect/browse/import/upload
|
||||
ws_store_status, ws_store_connect, ws_store_disconnect,
|
||||
ws_store_search_devices, ws_store_get_profiles, ws_store_get_cycles,
|
||||
@@ -1319,6 +1341,7 @@ async def ws_set_options(
|
||||
CONF_DOOR_SENSOR_ENTITY,
|
||||
CONF_LINKED_DEVICE,
|
||||
CONF_SWITCH_ENTITY,
|
||||
CONF_ENERGY_SENSOR,
|
||||
):
|
||||
if key in new_options and not new_options[key]:
|
||||
new_options[key] = None
|
||||
@@ -1413,6 +1436,79 @@ async def ws_get_settings_changelog(
|
||||
_send_result(connection, msg["id"], "get_settings_changelog", {"changelog": changelog})
|
||||
|
||||
|
||||
@websocket_api.websocket_command(
|
||||
{
|
||||
vol.Required("type"): "ha_washdata/get_setup_status",
|
||||
vol.Required("entry_id"): str,
|
||||
}
|
||||
)
|
||||
@websocket_api.async_response
|
||||
async def ws_get_setup_status(
|
||||
hass: HomeAssistant,
|
||||
connection: websocket_api.ActiveConnection,
|
||||
msg: dict[str, Any],
|
||||
) -> None:
|
||||
"""Return the current setup phase for the adoption guidance card."""
|
||||
manager = _get_manager(hass, msg["entry_id"])
|
||||
if not manager:
|
||||
connection.send_error(msg["id"], "not_found", "Device not found")
|
||||
return
|
||||
|
||||
# Gather user's skipped steps from user prefs
|
||||
skipped_steps: dict[str, str | None] = {}
|
||||
user = getattr(connection, "user", None)
|
||||
if user:
|
||||
holder = hass.data.get(_PANEL_DATA_KEY)
|
||||
if holder:
|
||||
prefs = holder["data"].get("prefs", {}).get(user.id, {})
|
||||
for k, v in prefs.items():
|
||||
if k.startswith("setup_skip_"):
|
||||
skipped_steps[k] = v
|
||||
|
||||
# Gather store data (executor-safe reads)
|
||||
store = manager.profile_store
|
||||
profile_names = list(store._data.get("profiles", {}).keys())
|
||||
past_cycles = store._data.get("past_cycles", [])
|
||||
ref_names: set[str] = set()
|
||||
for rc in store._data.get("reference_cycles", []):
|
||||
if rc.get("profile_name"):
|
||||
ref_names.add(rc["profile_name"])
|
||||
|
||||
coverage_gap = await hass.async_add_executor_job(store.suggest_coverage_gaps)
|
||||
# suggestions: read from the store (cheap dict lookup; heavy computation happens
|
||||
# in the SuggestionEngine background task, not here).
|
||||
suggestions = list((store.get_suggestions() or {}).values())
|
||||
pg_data = store._data.get("profile_groups", {})
|
||||
pending_groups = (pg_data.get("suggestions") or []) if isinstance(pg_data, dict) else []
|
||||
|
||||
device_type = manager.device_type
|
||||
|
||||
result = compute_setup_phase(
|
||||
device_type=device_type,
|
||||
profile_names=profile_names,
|
||||
past_cycles=past_cycles,
|
||||
ref_profile_names=ref_names,
|
||||
coverage_gap=coverage_gap,
|
||||
suggestions=suggestions,
|
||||
profile_groups=pending_groups,
|
||||
skipped_steps=skipped_steps,
|
||||
now=dt_util.now(),
|
||||
)
|
||||
|
||||
_send_result(connection, msg["id"], "get_setup_status", {
|
||||
"phase": result.phase,
|
||||
"message_key": result.message_key,
|
||||
"message_params": result.message_params,
|
||||
"cta_label_key": result.cta_label_key,
|
||||
"cta_action": result.cta_action,
|
||||
"secondary_label_key": result.secondary_label_key,
|
||||
"secondary_action": result.secondary_action,
|
||||
"skippable": result.skippable,
|
||||
"dismissible": result.dismissible,
|
||||
"step_key": result.step_key,
|
||||
})
|
||||
|
||||
|
||||
# ─── Profiles ─────────────────────────────────────────────────────────────────
|
||||
|
||||
@websocket_api.websocket_command(
|
||||
@@ -1721,24 +1817,67 @@ async def ws_delete_profile_group(
|
||||
@websocket_api.websocket_command(
|
||||
{vol.Required("type"): "ha_washdata/rebuild_envelopes", vol.Required("entry_id"): str}
|
||||
)
|
||||
@websocket_api.async_response
|
||||
async def ws_rebuild_envelopes(
|
||||
@callback
|
||||
def ws_rebuild_envelopes(
|
||||
hass: HomeAssistant,
|
||||
connection: websocket_api.ActiveConnection,
|
||||
msg: dict[str, Any],
|
||||
) -> None:
|
||||
"""Rebuild power-profile envelopes for all profiles."""
|
||||
"""Rebuild power-profile envelopes for all profiles.
|
||||
|
||||
Runs as a detached, registry-tracked task that rebuilds one profile per step
|
||||
(each DTW pass already offloads to the executor): rebuilding every profile
|
||||
serially inside the WS request stalled low-power hosts for the whole run
|
||||
(issue #311). Progress/result come via the task registry."""
|
||||
entry_id: str = msg["entry_id"]
|
||||
manager = _get_manager(hass, entry_id)
|
||||
if manager is None:
|
||||
if _get_manager(hass, entry_id) is None:
|
||||
_err_not_found(connection, msg["id"], entry_id)
|
||||
return
|
||||
reg = task_registry.get_registry(hass)
|
||||
task = reg.create(
|
||||
entry_id, "rebuild", "Rebuilding envelopes",
|
||||
label_key="task.rebuild.envelopes", label_params={},
|
||||
)
|
||||
hass.async_create_task(_rebuild_envelopes_task(hass, task, entry_id))
|
||||
_send_result(connection, msg["id"], "rebuild_envelopes", {"task_id": task.id})
|
||||
|
||||
|
||||
async def _rebuild_envelopes_task(hass: HomeAssistant, task: Any, entry_id: str) -> None:
|
||||
"""Detached runner: rebuild every profile's envelope one at a time, reporting
|
||||
progress and honouring cancel, so the loop breathes between profiles."""
|
||||
reg = task_registry.get_registry(hass)
|
||||
manager = _get_manager(hass, entry_id)
|
||||
if manager is None:
|
||||
reg.finish(task, state=task_registry.STATE_ERROR, error="device unavailable")
|
||||
return
|
||||
store = manager.profile_store
|
||||
lock = _entry_write_lock(hass, entry_id)
|
||||
await lock.acquire()
|
||||
try:
|
||||
await manager.profile_store.async_rebuild_all_envelopes()
|
||||
_send_result(connection, msg["id"], "rebuild_envelopes", {"success": True})
|
||||
names = list(store.get_profiles().keys())
|
||||
reg.update(task, total=len(names), done=0)
|
||||
rebuilt = 0
|
||||
for i, name in enumerate(names):
|
||||
if task.cancel_requested:
|
||||
break
|
||||
try:
|
||||
if await store.async_rebuild_envelope(name):
|
||||
rebuilt += 1
|
||||
except Exception as exc: # pylint: disable=broad-exception-caught
|
||||
_LOGGER.debug("Envelope rebuild failed for %s/%s: %s", entry_id, name, exc)
|
||||
reg.update(task, done=i + 1)
|
||||
if _get_manager(hass, entry_id) is manager:
|
||||
manager.notify_update()
|
||||
reg.finish(
|
||||
task,
|
||||
state=task_registry.STATE_CANCELLED if task.cancel_requested else task_registry.STATE_DONE,
|
||||
result={"success": True, "rebuilt": rebuilt},
|
||||
)
|
||||
except Exception as exc: # pylint: disable=broad-exception-caught
|
||||
connection.send_error(msg["id"], "unknown_error", str(exc))
|
||||
_LOGGER.warning("Rebuild-envelopes task failed for %s: %s", entry_id, exc)
|
||||
reg.finish(task, state=task_registry.STATE_ERROR, error=str(exc))
|
||||
finally:
|
||||
lock.release()
|
||||
|
||||
|
||||
@websocket_api.websocket_command(
|
||||
@@ -2814,6 +2953,21 @@ def ws_get_constants(
|
||||
]
|
||||
from .const import STORE_WEB_ORIGIN
|
||||
from . import store_account
|
||||
from .const import ( # pylint: disable=import-outside-toplevel
|
||||
DEFAULT_PROFILE_MATCH_MIN_DURATION_RATIO,
|
||||
DEFAULT_PROFILE_MATCH_MAX_DURATION_RATIO,
|
||||
DEFAULT_DTW_BANDWIDTH,
|
||||
MATCH_CORR_WEIGHT,
|
||||
MATCH_KEEP_MIN_SCORE,
|
||||
MATCH_DTW_BLEND,
|
||||
MATCH_DTW_ENSEMBLE_W,
|
||||
MATCH_DDTW_DIST_SCALE,
|
||||
MATCH_DTW_REFINE_TOP_N,
|
||||
MATCH_DURATION_WEIGHT,
|
||||
MATCH_ENERGY_WEIGHT,
|
||||
MATCH_DURATION_SCALE,
|
||||
MATCH_ENERGY_SCALE,
|
||||
)
|
||||
_send_result(connection, msg["id"], "get_constants", {
|
||||
"device_types": device_types,
|
||||
"state_colors": dict(STATE_COLORS),
|
||||
@@ -2821,6 +2975,24 @@ def ws_get_constants(
|
||||
"ml_suggestions_enabled": ENABLE_ML_SUGGESTIONS,
|
||||
"ml_training_available": ENABLE_ML_TRAINING,
|
||||
"PROFILE_MIN_WARMUP_CYCLES": CONF_PROFILE_MIN_WARMUP_CYCLES,
|
||||
# Canonical matcher defaults for the Playground's matcher-param fields, so
|
||||
# the panel's _PG_MATCH_DEFAULTS table cannot silently drift from const.py.
|
||||
# The panel keeps that table only as an offline fallback.
|
||||
"pg_match_defaults": {
|
||||
"profile_match_min_duration_ratio": DEFAULT_PROFILE_MATCH_MIN_DURATION_RATIO,
|
||||
"profile_match_max_duration_ratio": DEFAULT_PROFILE_MATCH_MAX_DURATION_RATIO,
|
||||
"corr_weight": MATCH_CORR_WEIGHT,
|
||||
"keep_min_score": MATCH_KEEP_MIN_SCORE,
|
||||
"dtw_bandwidth": DEFAULT_DTW_BANDWIDTH,
|
||||
"dtw_blend": MATCH_DTW_BLEND,
|
||||
"dtw_ensemble_w": MATCH_DTW_ENSEMBLE_W,
|
||||
"dtw_ddtw_scale": MATCH_DDTW_DIST_SCALE,
|
||||
"dtw_refine_top_n": MATCH_DTW_REFINE_TOP_N,
|
||||
"duration_weight": MATCH_DURATION_WEIGHT,
|
||||
"energy_weight": MATCH_ENERGY_WEIGHT,
|
||||
"duration_scale": MATCH_DURATION_SCALE,
|
||||
"energy_scale": MATCH_ENERGY_SCALE,
|
||||
},
|
||||
# Community store: the panel opens <origin>/connect.html for the GitHub
|
||||
# handoff and validates postMessage against new URL(origin).origin.
|
||||
"store_online_available": True,
|
||||
@@ -3082,32 +3254,61 @@ async def ws_get_cycle_power_data(
|
||||
vol.Required("end_s"): vol.Coerce(float),
|
||||
}
|
||||
)
|
||||
@websocket_api.async_response
|
||||
async def ws_trim_cycle(
|
||||
@callback
|
||||
def ws_trim_cycle(
|
||||
hass: HomeAssistant,
|
||||
connection: websocket_api.ActiveConnection,
|
||||
msg: dict[str, Any],
|
||||
) -> None:
|
||||
"""Trim a cycle's power data to the [start_s, end_s] offset window."""
|
||||
"""Trim a cycle's power data to the [start_s, end_s] offset window.
|
||||
|
||||
Runs as a detached, registry-tracked task (returns a task_id immediately): the
|
||||
trim recomputes the signature and rebuilds the profile envelope, which stalls
|
||||
low-power hosts if held on the event loop for the whole WS request (issue #311).
|
||||
Progress/result come via subscribe_tasks/get_task_result."""
|
||||
entry_id: str = msg["entry_id"]
|
||||
manager = _get_manager(hass, entry_id)
|
||||
if manager is None:
|
||||
if _get_manager(hass, entry_id) is None:
|
||||
_err_not_found(connection, msg["id"], entry_id)
|
||||
return
|
||||
reg = task_registry.get_registry(hass)
|
||||
task = reg.create(
|
||||
entry_id, "trim", "Trimming cycle", label_key="task.trim.apply", label_params={},
|
||||
)
|
||||
hass.async_create_task(_trim_task(
|
||||
hass, task, entry_id, msg["cycle_id"], float(msg["start_s"]), float(msg["end_s"]),
|
||||
))
|
||||
_send_result(connection, msg["id"], "trim_cycle", {"task_id": task.id})
|
||||
|
||||
|
||||
async def _trim_task(
|
||||
hass: HomeAssistant, task: Any, entry_id: str,
|
||||
cycle_id: str, start_s: float, end_s: float,
|
||||
) -> None:
|
||||
"""Detached runner for a cycle trim (recompute + single-profile envelope
|
||||
rebuild). Serialized under the per-entry write lock like reprocess."""
|
||||
reg = task_registry.get_registry(hass)
|
||||
manager = _get_manager(hass, entry_id)
|
||||
if manager is None:
|
||||
reg.finish(task, state=task_registry.STATE_ERROR, error="device unavailable")
|
||||
return
|
||||
store = manager.profile_store
|
||||
lock = _entry_write_lock(hass, entry_id)
|
||||
await lock.acquire()
|
||||
try:
|
||||
ok = await manager.profile_store.trim_cycle_power_data(
|
||||
msg["cycle_id"], float(msg["start_s"]), float(msg["end_s"])
|
||||
)
|
||||
if ok:
|
||||
reg.update(task, total=1, done=0)
|
||||
ok = await store.trim_cycle_power_data(cycle_id, start_s, end_s)
|
||||
reg.update(task, done=1)
|
||||
if not ok:
|
||||
reg.finish(task, state=task_registry.STATE_ERROR, error="trim_failed")
|
||||
return
|
||||
if _get_manager(hass, entry_id) is manager:
|
||||
manager.notify_update()
|
||||
_send_result(connection, msg["id"], "trim_cycle", {"success": True})
|
||||
else:
|
||||
connection.send_error(
|
||||
msg["id"], "trim_failed", "Trim produced no data or cycle not found"
|
||||
)
|
||||
reg.finish(task, state=task_registry.STATE_DONE, result={"success": True})
|
||||
except Exception as exc: # pylint: disable=broad-exception-caught
|
||||
connection.send_error(msg["id"], "unknown_error", str(exc))
|
||||
_LOGGER.warning("Trim task failed for %s: %s", entry_id, exc)
|
||||
reg.finish(task, state=task_registry.STATE_ERROR, error=str(exc))
|
||||
finally:
|
||||
lock.release()
|
||||
|
||||
|
||||
@websocket_api.websocket_command(
|
||||
@@ -3173,13 +3374,19 @@ async def ws_analyze_split(
|
||||
vol.Optional("segment_profiles"): list,
|
||||
}
|
||||
)
|
||||
@websocket_api.async_response
|
||||
async def ws_apply_split(
|
||||
@callback
|
||||
def ws_apply_split(
|
||||
hass: HomeAssistant,
|
||||
connection: websocket_api.ActiveConnection,
|
||||
msg: dict[str, Any],
|
||||
) -> None:
|
||||
"""Split a cycle at the given offsets, optionally labeling each segment."""
|
||||
"""Split a cycle at the given offsets, optionally labeling each segment.
|
||||
|
||||
Cheap validation (cycle exists, at least two segments) runs synchronously so a
|
||||
bad request fails fast; the heavy apply (per-segment extraction + affected
|
||||
envelope rebuilds + save) then runs as a detached, registry-tracked task so it
|
||||
never holds the event loop for the whole request on low-power hosts (issue
|
||||
#311). Progress/result come via subscribe_tasks/get_task_result."""
|
||||
entry_id: str = msg["entry_id"]
|
||||
manager = _get_manager(hass, entry_id)
|
||||
if manager is None:
|
||||
@@ -3188,40 +3395,69 @@ async def ws_apply_split(
|
||||
|
||||
store = manager.profile_store
|
||||
cycle_id: str = msg["cycle_id"]
|
||||
try:
|
||||
cycle = next(
|
||||
(c for c in store.get_past_cycles() if c.get("id") == cycle_id), None
|
||||
cycle = next(
|
||||
(c for c in store.get_past_cycles() if c.get("id") == cycle_id), None
|
||||
)
|
||||
if not cycle:
|
||||
connection.send_error(msg["id"], "not_found", f"Cycle {cycle_id!r} not found")
|
||||
return
|
||||
|
||||
offsets = [float(o) for o in msg["split_offsets"]]
|
||||
seg_bounds = store.build_split_segments_from_offsets(cycle, offsets)
|
||||
if len(seg_bounds) < 2:
|
||||
connection.send_error(
|
||||
msg["id"],
|
||||
"split_failed",
|
||||
"Split points did not produce at least two segments",
|
||||
)
|
||||
if not cycle:
|
||||
connection.send_error(msg["id"], "not_found", f"Cycle {cycle_id!r} not found")
|
||||
return
|
||||
return
|
||||
|
||||
offsets = [float(o) for o in msg["split_offsets"]]
|
||||
seg_bounds = store.build_split_segments_from_offsets(cycle, offsets)
|
||||
if len(seg_bounds) < 2:
|
||||
connection.send_error(
|
||||
msg["id"],
|
||||
"split_failed",
|
||||
"Split points did not produce at least two segments",
|
||||
)
|
||||
return
|
||||
profiles = msg.get("segment_profiles") or []
|
||||
segments: list[dict[str, Any]] = []
|
||||
for i, (seg_start, seg_end) in enumerate(seg_bounds):
|
||||
prof = profiles[i] if i < len(profiles) else None
|
||||
if prof in ("", "none", "__none__"):
|
||||
prof = None
|
||||
segments.append(
|
||||
{"start": float(seg_start), "end": float(seg_end), "profile": prof}
|
||||
)
|
||||
|
||||
profiles = msg.get("segment_profiles") or []
|
||||
segments: list[dict[str, Any]] = []
|
||||
for i, (seg_start, seg_end) in enumerate(seg_bounds):
|
||||
prof = profiles[i] if i < len(profiles) else None
|
||||
if prof in ("", "none", "__none__"):
|
||||
prof = None
|
||||
segments.append(
|
||||
{"start": float(seg_start), "end": float(seg_end), "profile": prof}
|
||||
)
|
||||
reg = task_registry.get_registry(hass)
|
||||
task = reg.create(
|
||||
entry_id, "split", "Splitting cycle", label_key="task.split.apply", label_params={},
|
||||
)
|
||||
hass.async_create_task(_apply_split_task(hass, task, entry_id, cycle_id, segments))
|
||||
_send_result(connection, msg["id"], "apply_split", {"task_id": task.id})
|
||||
|
||||
|
||||
async def _apply_split_task(
|
||||
hass: HomeAssistant, task: Any, entry_id: str,
|
||||
cycle_id: str, segments: list[dict[str, Any]],
|
||||
) -> None:
|
||||
"""Detached runner for a cycle split. Rebuilds only the affected profiles'
|
||||
envelopes (done inside apply_split_interactive). Serialized under the per-entry
|
||||
write lock like reprocess."""
|
||||
reg = task_registry.get_registry(hass)
|
||||
manager = _get_manager(hass, entry_id)
|
||||
if manager is None:
|
||||
reg.finish(task, state=task_registry.STATE_ERROR, error="device unavailable")
|
||||
return
|
||||
store = manager.profile_store
|
||||
lock = _entry_write_lock(hass, entry_id)
|
||||
await lock.acquire()
|
||||
try:
|
||||
reg.update(task, total=1, done=0)
|
||||
new_ids = await store.apply_split_interactive(cycle_id, segments)
|
||||
await store.async_rebuild_all_envelopes()
|
||||
manager.notify_update()
|
||||
_send_result(connection, msg["id"], "apply_split", {"success": True, "new_ids": new_ids})
|
||||
reg.update(task, done=1)
|
||||
if _get_manager(hass, entry_id) is manager:
|
||||
manager.notify_update()
|
||||
reg.finish(
|
||||
task, state=task_registry.STATE_DONE,
|
||||
result={"success": True, "new_ids": new_ids},
|
||||
)
|
||||
except Exception as exc: # pylint: disable=broad-exception-caught
|
||||
connection.send_error(msg["id"], "unknown_error", str(exc))
|
||||
_LOGGER.warning("Apply-split task failed for %s: %s", entry_id, exc)
|
||||
reg.finish(task, state=task_registry.STATE_ERROR, error=str(exc))
|
||||
|
||||
|
||||
@websocket_api.websocket_command(
|
||||
@@ -3233,20 +3469,24 @@ async def ws_apply_split(
|
||||
vol.Optional("new_profile_name"): vol.Any(str, None),
|
||||
}
|
||||
)
|
||||
@websocket_api.async_response
|
||||
async def ws_apply_merge(
|
||||
@callback
|
||||
def ws_apply_merge(
|
||||
hass: HomeAssistant,
|
||||
connection: websocket_api.ActiveConnection,
|
||||
msg: dict[str, Any],
|
||||
) -> None:
|
||||
"""Merge two or more cycles into one, optionally labeling the result."""
|
||||
"""Merge two or more cycles into one, optionally labeling the result.
|
||||
|
||||
Cheap validation runs synchronously; the merge (gap-fill + signature recompute
|
||||
+ affected-profile envelope rebuilds + save) then runs as a detached,
|
||||
registry-tracked task so it never holds the event loop for the whole request
|
||||
on low-power hosts (issue #311). Progress/result via the task registry."""
|
||||
entry_id: str = msg["entry_id"]
|
||||
manager = _get_manager(hass, entry_id)
|
||||
if manager is None:
|
||||
_err_not_found(connection, msg["id"], entry_id)
|
||||
return
|
||||
|
||||
store = manager.profile_store
|
||||
ids: list[str] = msg["cycle_ids"]
|
||||
if len(ids) < 2:
|
||||
connection.send_error(
|
||||
@@ -3255,29 +3495,69 @@ async def ws_apply_merge(
|
||||
return
|
||||
|
||||
target = msg.get("target_profile")
|
||||
try:
|
||||
if target == "__create_new__":
|
||||
name = (msg.get("new_profile_name") or "").strip()
|
||||
if not name:
|
||||
connection.send_error(
|
||||
msg["id"], "invalid_format", "New profile name required"
|
||||
)
|
||||
return
|
||||
await store.create_profile_standalone(name)
|
||||
target = name
|
||||
elif target in ("", "none", "__none__"):
|
||||
target = None
|
||||
|
||||
new_id = await store.apply_merge_interactive(ids, target)
|
||||
if not new_id:
|
||||
connection.send_error(msg["id"], "merge_failed", "Cycles could not be merged")
|
||||
new_name: str | None = None
|
||||
if target == "__create_new__":
|
||||
new_name = (msg.get("new_profile_name") or "").strip()
|
||||
if not new_name:
|
||||
connection.send_error(msg["id"], "invalid_format", "New profile name required")
|
||||
return
|
||||
elif target in ("", "none", "__none__"):
|
||||
target = None
|
||||
|
||||
await store.async_rebuild_all_envelopes()
|
||||
manager.notify_update()
|
||||
_send_result(connection, msg["id"], "apply_merge", {"success": True, "new_id": new_id})
|
||||
reg = task_registry.get_registry(hass)
|
||||
task = reg.create(
|
||||
entry_id, "merge", "Merging cycles", label_key="task.merge.apply", label_params={},
|
||||
)
|
||||
hass.async_create_task(_apply_merge_task(hass, task, entry_id, ids, target, new_name))
|
||||
_send_result(connection, msg["id"], "apply_merge", {"task_id": task.id})
|
||||
|
||||
|
||||
async def _apply_merge_task(
|
||||
hass: HomeAssistant, task: Any, entry_id: str,
|
||||
ids: list[str], target: str | None, new_name: str | None,
|
||||
) -> None:
|
||||
"""Detached runner for a cycle merge. Rebuilds only the affected profiles'
|
||||
envelopes (done inside apply_merge_interactive). Serialized under the per-entry
|
||||
write lock like reprocess."""
|
||||
reg = task_registry.get_registry(hass)
|
||||
manager = _get_manager(hass, entry_id)
|
||||
if manager is None:
|
||||
reg.finish(task, state=task_registry.STATE_ERROR, error="device unavailable")
|
||||
return
|
||||
store = manager.profile_store
|
||||
lock = _entry_write_lock(hass, entry_id)
|
||||
await lock.acquire()
|
||||
try:
|
||||
reg.update(task, total=1, done=0)
|
||||
created_new = False
|
||||
if new_name:
|
||||
# Raises ValueError if the name already exists, so reaching the next
|
||||
# line guarantees we created a brand-new (empty) profile that must be
|
||||
# rolled back if the merge below fails.
|
||||
await store.create_profile_standalone(new_name)
|
||||
created_new = True
|
||||
target = new_name
|
||||
new_id = await store.apply_merge_interactive(ids, target)
|
||||
reg.update(task, done=1)
|
||||
if not new_id:
|
||||
if created_new and new_name:
|
||||
# Merge rejected the cycle set (stale/invalid id, unparseable start
|
||||
# time, ...). Delete the empty profile we just created so a failed
|
||||
# merge doesn't orphan a cycle-less profile in the store.
|
||||
await store.delete_profile(new_name, unlabel_cycles=False)
|
||||
reg.finish(task, state=task_registry.STATE_ERROR, error="merge_failed")
|
||||
return
|
||||
if _get_manager(hass, entry_id) is manager:
|
||||
manager.notify_update()
|
||||
reg.finish(
|
||||
task, state=task_registry.STATE_DONE,
|
||||
result={"success": True, "new_id": new_id},
|
||||
)
|
||||
except Exception as exc: # pylint: disable=broad-exception-caught
|
||||
connection.send_error(msg["id"], "unknown_error", str(exc))
|
||||
_LOGGER.warning("Apply-merge task failed for %s: %s", entry_id, exc)
|
||||
reg.finish(task, state=task_registry.STATE_ERROR, error=str(exc))
|
||||
finally:
|
||||
lock.release()
|
||||
|
||||
|
||||
# ─── Profile envelope / member cycles ──────────────────────────────────────────
|
||||
@@ -3492,6 +3772,13 @@ async def ws_set_user_prefs(
|
||||
cur.pop("lang_override", None) # empty clears -> system default
|
||||
elif isinstance(lang, str) and _PREF_LANG_TAG_RE.match(lang):
|
||||
cur["lang_override"] = lang
|
||||
# Allow setup guidance skip keys: setup_skip_<step_key> -> "never" | ISO timestamp
|
||||
for k, v in p.items():
|
||||
if isinstance(k, str) and k.startswith("setup_skip_"):
|
||||
if v is None:
|
||||
cur.pop(k, None)
|
||||
elif v == "never" or (isinstance(v, str) and len(v) <= 40):
|
||||
cur[k] = v
|
||||
prefs[user.id] = cur
|
||||
await _save_panel_data(hass)
|
||||
_send_result(connection, msg["id"], "set_user_prefs", {"success": True})
|
||||
@@ -4567,56 +4854,6 @@ def _playground_base_config(manager: Any, entry: Any) -> CycleDetectorConfig:
|
||||
)
|
||||
|
||||
|
||||
@websocket_api.websocket_command(
|
||||
{
|
||||
vol.Required("type"): "ha_washdata/run_playground_simulation",
|
||||
vol.Required("entry_id"): str,
|
||||
vol.Optional("cycle_ids", default=list): [str],
|
||||
vol.Optional("settings_override", default=dict): dict,
|
||||
vol.Optional("concurrency", default=1): vol.Coerce(int),
|
||||
}
|
||||
)
|
||||
@websocket_api.async_response
|
||||
async def ws_run_playground_simulation(
|
||||
hass: HomeAssistant,
|
||||
connection: websocket_api.ActiveConnection,
|
||||
msg: dict[str, Any],
|
||||
) -> None:
|
||||
"""Replay stored cycles through a headless detector with overridden settings.
|
||||
|
||||
Returns ``{results: [...], summary: {...}}`` - a per-cycle event log +
|
||||
outcome plus aggregate counts. Nothing is persisted; this is a pure what-if.
|
||||
"""
|
||||
entry_id: str = msg["entry_id"]
|
||||
manager = _get_manager(hass, entry_id)
|
||||
if manager is None:
|
||||
_err_not_found(connection, msg["id"], entry_id)
|
||||
return
|
||||
|
||||
store = getattr(manager, "profile_store", None)
|
||||
if store is None:
|
||||
connection.send_error(msg["id"], "unavailable", "Profile store unavailable")
|
||||
return
|
||||
|
||||
try:
|
||||
base_config = _playground_base_config(manager, _get_entry(hass, entry_id))
|
||||
cycle_ids = list(msg.get("cycle_ids") or [])
|
||||
settings_override = dict(msg.get("settings_override") or {})
|
||||
concurrency = int(msg.get("concurrency", 1))
|
||||
payload = await hass.async_add_executor_job(
|
||||
playground.run_playground_batch,
|
||||
store,
|
||||
cycle_ids,
|
||||
base_config,
|
||||
settings_override,
|
||||
concurrency,
|
||||
)
|
||||
_send_result(connection, msg["id"], "run_playground_simulation", payload)
|
||||
except Exception as exc: # pylint: disable=broad-exception-caught
|
||||
_LOGGER.debug("Playground simulation failed for %s: %s", entry_id, exc)
|
||||
connection.send_error(msg["id"], "unknown_error", str(exc))
|
||||
|
||||
|
||||
def _playground_context(hass: HomeAssistant, entry_id: str):
|
||||
"""Return (manager, store, base_config, options, price) for a Playground call,
|
||||
or None (after sending the appropriate error) when unavailable."""
|
||||
@@ -5108,3 +5345,88 @@ def ws_start_playground_sweep(
|
||||
msg["objective"], param_y, list(values_y) if values_y else None,
|
||||
))
|
||||
_send_result(connection, msg["id"], "start_playground_sweep", {"task_id": task.id})
|
||||
|
||||
|
||||
# Readings replayed per executor job for the single-cycle detail sim. The event
|
||||
# loop breathes between chunks; a ~233min/5s dishwasher cycle (~2800 readings)
|
||||
# becomes ~11 short jobs instead of one multi-minute GIL-holding call (issue #311).
|
||||
_PG_DETAIL_CHUNK = 250
|
||||
|
||||
|
||||
async def _pg_detail_task(
|
||||
hass: HomeAssistant, task: Any, entry_id: str,
|
||||
cycle_id: str, override: dict[str, Any] | None,
|
||||
) -> None:
|
||||
reg = task_registry.get_registry(hass)
|
||||
ctx = _playground_context(hass, entry_id)
|
||||
if ctx is None:
|
||||
reg.finish(task, state=task_registry.STATE_ERROR, error="device unavailable")
|
||||
return
|
||||
_manager, store, base_config, options, price = ctx
|
||||
try:
|
||||
sim = await hass.async_add_executor_job(
|
||||
playground.build_cycle_detail_sim_by_id,
|
||||
store, cycle_id, base_config, override, options, price,
|
||||
)
|
||||
if isinstance(sim, dict): # {"error": ...} marker (not_found / build failure)
|
||||
if sim.get("error") == "not_found":
|
||||
reg.finish(task, state=task_registry.STATE_ERROR, error="not_found")
|
||||
else:
|
||||
reg.finish(task, state=task_registry.STATE_ERROR, error=str(sim.get("error")))
|
||||
return
|
||||
if not sim.ready:
|
||||
reg.finish(task, state=task_registry.STATE_DONE, result=sim.empty_payload())
|
||||
return
|
||||
total = sim.n_readings
|
||||
reg.update(task, total=total)
|
||||
for i in range(0, total, _PG_DETAIL_CHUNK):
|
||||
if task.cancel_requested:
|
||||
break
|
||||
await hass.async_add_executor_job(sim.step, i, i + _PG_DETAIL_CHUNK)
|
||||
reg.update(task, done=min(total, i + _PG_DETAIL_CHUNK))
|
||||
if not task.cancel_requested:
|
||||
await hass.async_add_executor_job(sim.run_tail)
|
||||
payload = await hass.async_add_executor_job(sim.finalize)
|
||||
payload["partial"] = task.cancel_requested
|
||||
reg.finish(
|
||||
task,
|
||||
state=task_registry.STATE_CANCELLED if task.cancel_requested else task_registry.STATE_DONE,
|
||||
result=payload,
|
||||
)
|
||||
except Exception as exc: # pylint: disable=broad-exception-caught
|
||||
_LOGGER.debug("Playground detail task failed for %s: %s", entry_id, exc)
|
||||
reg.finish(task, state=task_registry.STATE_ERROR, error=str(exc))
|
||||
|
||||
|
||||
@websocket_api.websocket_command(
|
||||
{
|
||||
vol.Required("type"): "ha_washdata/start_playground_cycle_detail",
|
||||
vol.Required("entry_id"): str,
|
||||
vol.Required("cycle_id"): str,
|
||||
vol.Optional("settings_override", default=dict): dict,
|
||||
}
|
||||
)
|
||||
@callback
|
||||
def ws_start_playground_cycle_detail(
|
||||
hass: HomeAssistant,
|
||||
connection: websocket_api.ActiveConnection,
|
||||
msg: dict[str, Any],
|
||||
) -> None:
|
||||
"""Kick off a detached, registry-tracked single-cycle "Simulate" replay;
|
||||
returns the task id immediately. The heavy per-5s replay runs chunk-by-chunk
|
||||
in the executor so a long cycle no longer stalls Home Assistant (issue #311).
|
||||
Progress/result come via subscribe_tasks/get_task_result."""
|
||||
entry_id = msg["entry_id"]
|
||||
if _playground_context(hass, entry_id) is None:
|
||||
_err_not_found(connection, msg["id"], entry_id)
|
||||
return
|
||||
reg = task_registry.get_registry(hass)
|
||||
task = reg.create(
|
||||
entry_id, "pg_detail", "Simulate cycle",
|
||||
label_key="task.pg_detail.simulate", label_params={},
|
||||
)
|
||||
override = dict(msg.get("settings_override") or {})
|
||||
hass.async_create_task(
|
||||
_pg_detail_task(hass, task, entry_id, msg["cycle_id"], override)
|
||||
)
|
||||
_send_result(connection, msg["id"], "start_playground_cycle_detail", {"task_id": task.id})
|
||||
|
||||
@@ -258,16 +258,6 @@ class AnalyzeSplitResponse(TypedDict):
|
||||
full_duration_s: float
|
||||
|
||||
|
||||
class ApplySplitResponse(TypedDict):
|
||||
success: bool
|
||||
new_ids: list[str]
|
||||
|
||||
|
||||
class ApplyMergeResponse(TypedDict):
|
||||
success: bool
|
||||
new_id: str
|
||||
|
||||
|
||||
# ─── Profile envelope / member cycles ──────────────────────────────────────────
|
||||
|
||||
class ProfileEnvelope(TypedDict):
|
||||
@@ -363,24 +353,6 @@ class GetMlTrainingStatusResponse(TypedDict):
|
||||
|
||||
# ─── Playground (F3) ───────────────────────────────────────────────────────────
|
||||
|
||||
class PlaygroundSummary(TypedDict):
|
||||
cycles: int
|
||||
requested: int
|
||||
concurrency: int
|
||||
detected: int
|
||||
missed: int
|
||||
false_end: int
|
||||
match_correct: int
|
||||
match_wrong: int
|
||||
unmatched: int
|
||||
skipped_ids: list[str]
|
||||
|
||||
|
||||
class RunPlaygroundSimulationResponse(TypedDict):
|
||||
results: list[dict[str, Any]]
|
||||
summary: PlaygroundSummary
|
||||
|
||||
|
||||
class RunPlaygroundCycleDetailResponse(TypedDict, total=False):
|
||||
cycle_id: Any
|
||||
label: str | None
|
||||
@@ -602,12 +574,27 @@ class GetShareableCyclesResponse(TypedDict, total=False):
|
||||
phase_programs: list
|
||||
|
||||
|
||||
class GetSetupStatusResponse(TypedDict, total=False):
|
||||
"""Current adoption phase for the setup guidance card."""
|
||||
phase: str
|
||||
message_key: str
|
||||
message_params: dict
|
||||
cta_label_key: str
|
||||
cta_action: str
|
||||
secondary_label_key: str | None
|
||||
secondary_action: str | None
|
||||
skippable: bool
|
||||
dismissible: bool
|
||||
step_key: str | None
|
||||
|
||||
|
||||
WS_RESPONSE_TYPES: dict[str, type] = {
|
||||
"get_devices": GetDevicesResponse,
|
||||
"get_device_cycles": GetDeviceCyclesResponse,
|
||||
"get_options": GetOptionsResponse,
|
||||
"set_options": SuccessResponse,
|
||||
"get_settings_changelog": GetSettingsChangelogResponse,
|
||||
"get_setup_status": GetSetupStatusResponse,
|
||||
"get_profiles": GetProfilesResponse,
|
||||
"create_profile": CreateProfileResponse,
|
||||
"rename_profile": SuccessResponse,
|
||||
@@ -616,7 +603,7 @@ WS_RESPONSE_TYPES: dict[str, type] = {
|
||||
"save_profile_group": SuccessResponse,
|
||||
"rename_profile_group": SuccessResponse,
|
||||
"delete_profile_group": SuccessResponse,
|
||||
"rebuild_envelopes": SuccessResponse,
|
||||
"rebuild_envelopes": StartTaskResponse,
|
||||
"get_profile_phases": GetProfilePhasesResponse,
|
||||
"set_profile_phases": SuccessResponse,
|
||||
"get_maintenance_log": GetMaintenanceLogResponse,
|
||||
@@ -649,10 +636,10 @@ WS_RESPONSE_TYPES: dict[str, type] = {
|
||||
"clear_suggestions": SuccessResponse,
|
||||
"run_suggestion_analysis": RunSuggestionAnalysisResponse,
|
||||
"get_cycle_power_data": GetCyclePowerDataResponse,
|
||||
"trim_cycle": SuccessResponse,
|
||||
"trim_cycle": StartTaskResponse,
|
||||
"analyze_split": AnalyzeSplitResponse,
|
||||
"apply_split": ApplySplitResponse,
|
||||
"apply_merge": ApplyMergeResponse,
|
||||
"apply_split": StartTaskResponse,
|
||||
"apply_merge": StartTaskResponse,
|
||||
"get_profile_envelope": GetProfileEnvelopeResponse,
|
||||
"get_profile_cycles": GetProfileCyclesResponse,
|
||||
"get_panel_config": GetPanelConfigResponse,
|
||||
@@ -671,7 +658,6 @@ WS_RESPONSE_TYPES: dict[str, type] = {
|
||||
"pause_cycle": OkResponse,
|
||||
"resume_cycle": OkResponse,
|
||||
"terminate_cycle": OkResponse,
|
||||
"run_playground_simulation": RunPlaygroundSimulationResponse,
|
||||
"run_playground_cycle_detail": RunPlaygroundCycleDetailResponse,
|
||||
"run_playground_history": RunPlaygroundHistoryResponse,
|
||||
"run_playground_sweep": RunPlaygroundSweepResponse,
|
||||
@@ -682,6 +668,7 @@ WS_RESPONSE_TYPES: dict[str, type] = {
|
||||
"get_task_result": TaskSnapshot,
|
||||
"start_playground_history": StartTaskResponse,
|
||||
"start_playground_sweep": StartTaskResponse,
|
||||
"start_playground_cycle_detail": StartTaskResponse,
|
||||
"store_status": StoreStatusResponse,
|
||||
"store_connect": StoreSimpleResponse,
|
||||
"store_disconnect": StoreSimpleResponse,
|
||||
@@ -751,6 +738,7 @@ WS_COMMANDS: dict[str, dict] = {
|
||||
"get_options": {"params": [_entry()]},
|
||||
"set_options": {"params": [_entry(), _p("options", "dict")]},
|
||||
"get_settings_changelog": {"params": [_entry()]},
|
||||
"get_setup_status": {"params": [_entry()]},
|
||||
"get_profiles": {"params": [_entry()]},
|
||||
"create_profile": {"params": [
|
||||
_entry(),
|
||||
@@ -911,12 +899,6 @@ WS_COMMANDS: dict[str, dict] = {
|
||||
"pause_cycle": {"params": [_entry()]},
|
||||
"resume_cycle": {"params": [_entry()]},
|
||||
"terminate_cycle": {"params": [_entry()]},
|
||||
"run_playground_simulation": {"params": [
|
||||
_entry(),
|
||||
_p("cycle_ids", "list[str]", False),
|
||||
_p("settings_override", "dict", False),
|
||||
_p("concurrency", "int", False),
|
||||
]},
|
||||
"run_playground_cycle_detail": {"params": [
|
||||
_entry(),
|
||||
_p("cycle_id", "str"),
|
||||
@@ -960,6 +942,11 @@ WS_COMMANDS: dict[str, dict] = {
|
||||
_p("param_y", "str|null", False),
|
||||
_p("values_y", "list[float]", False),
|
||||
]},
|
||||
"start_playground_cycle_detail": {"params": [
|
||||
_entry(),
|
||||
_p("cycle_id", "str"),
|
||||
_p("settings_override", "dict", False),
|
||||
]},
|
||||
# Community store (online features)
|
||||
"store_status": {"params": [_entry()]},
|
||||
"store_connect": {"params": [
|
||||
|
||||
@@ -147,8 +147,8 @@ const _SETTINGS_SECTIONS = [
|
||||
{ sub: 'Duration Gates', fields: [
|
||||
{ key: 'profile_match_min_duration_ratio', label: 'Min Duration Ratio', type: 'number', step: 0.01, min: 0, max: 1, def: 0.1,
|
||||
doc: 'Minimum cycle length relative to the profile. 0.9 means a cycle must be at least 90% of the profile duration to match.' },
|
||||
{ key: 'profile_match_max_duration_ratio', label: 'Max Duration Ratio', type: 'number', step: 0.01, min: 0, def: 1.3,
|
||||
doc: 'Maximum cycle length relative to the profile. 1.3 means a cycle must be under 130% of the profile duration to match.' },
|
||||
{ key: 'profile_match_max_duration_ratio', label: 'Max Duration Ratio', type: 'number', step: 0.01, min: 0, def: 1.5,
|
||||
doc: 'Maximum cycle length relative to the profile. 1.5 means a cycle must be under 150% of the profile duration to match.' },
|
||||
{ key: 'profile_duration_tolerance', label: 'Profile Duration Tolerance', type: 'number', step: 0.01, min: 0, max: 1, def: 0.25,
|
||||
doc: 'The +/- band around a profile average duration used during matching. 0.25 means a 60 min profile matches 45-75 min cycles.' },
|
||||
{ key: 'duration_tolerance', label: 'Estimate Tolerance', type: 'number', step: 0.01, min: 0, max: 1, def: 0.1,
|
||||
@@ -161,6 +161,10 @@ const _SETTINGS_SECTIONS = [
|
||||
doc: 'If the match score falls between this and Auto-Label Confidence, WashData flags the finished cycle for review in the Cycles queue so you can verify the identified program. Below this score the match is too uncertain to surface. Must be kept below Auto-Label Confidence.' },
|
||||
] },
|
||||
] },
|
||||
{ id: 'phase_eta', label: 'Time Remaining', intro: 'Phase-aware time-remaining, for machines whose cycle length depends on temperature or spin.', onlyDeviceTypes: ['washing_machine', 'washer_dryer'], fields: [
|
||||
{ key: 'enable_phase_matching', label: 'Phase-aware time remaining', type: 'checkbox', def: false,
|
||||
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.' },
|
||||
] },
|
||||
{ id: 'timing', label: 'Timing & Watchdog', intro: 'Background cadence, the offline watchdog and housekeeping.', groups: [
|
||||
{ sub: 'Watchdog', fields: [
|
||||
{ key: 'watchdog_interval', label: 'Watchdog Interval', unit: 's', type: 'number', min: 1, def: 30,
|
||||
@@ -271,6 +275,8 @@ const _SETTINGS_SECTIONS = [
|
||||
doc: 'Android notification channel name for the finish message. Blank reuses the start/live channel.' },
|
||||
] },
|
||||
{ sub: 'Energy', fields: [
|
||||
{ key: 'energy_sensor', label: 'Energy Meter Entity', type: 'entity', domain: 'sensor', optional: true,
|
||||
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.' },
|
||||
{ key: 'energy_price_entity', label: 'Energy Price Entity', type: 'entity', domain: 'sensor', basic: true,
|
||||
doc: 'Sensor with the current electricity price per kWh (e.g. a dynamic tariff). Takes precedence over the static price below. Each cycle freezes the price in effect when it finished.' },
|
||||
{ key: 'energy_price_static', label: 'Static Energy Price (per kWh)', type: 'number', step: 0.001, min: 0, basic: true,
|
||||
@@ -316,6 +322,24 @@ for (const sec of _SETTINGS_SECTIONS) {
|
||||
for (const grp of groups) for (const f of (grp.fields || [])) _FIELD_BY_KEY[f.key] = f;
|
||||
}
|
||||
|
||||
// Default values for playground-only matcher params (code constants, not stored
|
||||
// options, so _FIELD_BY_KEY has no entry for them).
|
||||
const _PG_MATCH_DEFAULTS = {
|
||||
profile_match_min_duration_ratio: 0.1,
|
||||
profile_match_max_duration_ratio: 1.5,
|
||||
corr_weight: 0.45,
|
||||
keep_min_score: 0.1,
|
||||
dtw_bandwidth: 0.2,
|
||||
dtw_blend: 0.5,
|
||||
dtw_ensemble_w: 0.7,
|
||||
dtw_ddtw_scale: 30,
|
||||
dtw_refine_top_n: 5,
|
||||
duration_weight: 0.22,
|
||||
energy_weight: 0.22,
|
||||
duration_scale: 0.175,
|
||||
energy_scale: 0.25,
|
||||
};
|
||||
|
||||
// ─── Setting conflict rules ───────────────────────────────────────────────────
|
||||
// Each rule describes a cross-parameter invariant. `check(vals)` returns true
|
||||
// when the invariant is violated. `fieldErrors(vals)` maps each affected key to
|
||||
@@ -608,22 +632,37 @@ th.wd-tc-flags { color: var(--secondary-text-color); font-weight: 500; }
|
||||
}
|
||||
.wd-field textarea { min-height: 64px; resize: vertical; }
|
||||
.wd-field input[type=checkbox] { width: auto; margin-right: 8px; }
|
||||
.wd-field .wd-check-row { display: flex; align-items: center; cursor: pointer; text-transform: none; letter-spacing: normal; font-weight: 500; color: var(--primary-text-color); }
|
||||
/* Switch-style boolean settings (replaces the old plain checkbox). Scoped under
|
||||
.wd-field-switch so the switch label wins over the generic ".wd-field label"
|
||||
(display:block, higher specificity) rule and stays a centered flex row. */
|
||||
.wd-field-switch label { margin: 0; }
|
||||
.wd-field-switch .wd-switch-row { display: flex; align-items: center; gap: 10px; min-height: 22px; }
|
||||
.wd-field-switch .wd-switch-lbl { display: flex; align-items: center; gap: 10px; cursor: pointer; min-width: 0; margin: 0; }
|
||||
/* Switch label: a flex row [toggle][text], vertically centred. The .wd-field
|
||||
.wd-switch-lbl selector is needed to beat .wd-field label (display:block +
|
||||
.82em + uppercase, specificity 0,1,1) which otherwise leaks in and both breaks
|
||||
the vertical centring (align-items is a no-op on a block) and shrinks the label.
|
||||
The bare .wd-switch-lbl covers inline use outside a .wd-field (e.g. adopt). */
|
||||
.wd-switch-lbl,
|
||||
.wd-field .wd-switch-lbl {
|
||||
display: inline-flex; align-items: center; gap: 10px; cursor: pointer;
|
||||
min-width: 0; margin: 0; font-size: 1rem; font-weight: 400;
|
||||
letter-spacing: normal; text-transform: none;
|
||||
}
|
||||
/* Match the switch label to every other setting name (see .wd-field label). */
|
||||
.wd-switch-text { font-size: .82em; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--secondary-text-color); }
|
||||
#wd-settings-form .wd-switch-text, #wd-ml-form .wd-switch-text { color: var(--primary-text-color); }
|
||||
/* Normal-case, readable label for switches outside the Settings form (store /
|
||||
panel prefs / access control), whose labels are descriptive sentences. */
|
||||
.wd-switch-text--plain { font-size: .9em; font-weight: 600; line-height: 1.3; letter-spacing: normal; text-transform: none; color: var(--primary-text-color); }
|
||||
.wd-switch { position: relative; display: inline-flex; flex: 0 0 auto; width: 40px; height: 22px; }
|
||||
.wd-switch input { position: absolute; opacity: 0; width: 0; height: 0; margin: 0; }
|
||||
.wd-switch-slider { position: absolute; inset: 0; border-radius: 22px; background: var(--switch-unchecked-track-color, rgba(120,120,120,.5)); transition: background .2s; }
|
||||
.wd-switch-slider::before { content: ""; position: absolute; height: 16px; width: 16px; left: 3px; top: 3px; border-radius: 50%; background: var(--switch-unchecked-button-color, #fafafa); box-shadow: 0 1px 2px rgba(0,0,0,.3); transition: transform .2s; }
|
||||
.wd-switch input:checked + .wd-switch-slider { background: var(--switch-checked-track-color, var(--primary-color, #03a9f4)); }
|
||||
.wd-switch input:checked + .wd-switch-slider::before { transform: translateX(18px); background: var(--switch-checked-button-color, #fff); }
|
||||
/* Force a light thumb: some themes set --switch-checked-button-color to the accent,
|
||||
which made the knob vanish into the (also-accent) track. A white thumb reads on
|
||||
any track colour. */
|
||||
.wd-switch input:checked + .wd-switch-slider::before { transform: translateX(18px); background: #fff; }
|
||||
.wd-switch input:focus-visible + .wd-switch-slider { outline: 2px solid var(--primary-color, #03a9f4); outline-offset: 2px; }
|
||||
/* A11y: a shared keyboard focus ring for all interactive controls (many HA themes
|
||||
suppress the UA default outline). */
|
||||
@@ -779,9 +818,16 @@ button.wd-profile-card { display: block; }
|
||||
.wd-prof-wrap { position: relative; }
|
||||
.wd-profile-name { font-weight: 600; font-size: 1em; margin-bottom: 6px; }
|
||||
.wd-profile-meta { font-size: .8em; color: var(--secondary-text-color); }
|
||||
/* Profile-card header: name on the left, mini power-signature sparkline on the
|
||||
right, both on one line and vertically aligned regardless of badge count. */
|
||||
.wd-profile-head { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }
|
||||
.wd-profile-head .wd-profile-name { margin: 0; flex: 1 1 auto; min-width: 0; }
|
||||
/* Status-pill row: wraps cleanly on its own line below the name, and every pill
|
||||
(health / trend / warm-up / imported) shares one uniform compact pill shape. */
|
||||
.wd-profile-badges { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-bottom: 8px; }
|
||||
.wd-profile-badges .wd-badge { margin: 0; padding: 2px 9px; border-radius: 999px; font-size: .72em; font-weight: 600; gap: 4px; }
|
||||
/* D2: mini duration sparkline on profile cards */
|
||||
.wd-profile-name { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
|
||||
.wd-prof-spark { margin-left: auto; width: 64px; height: 20px; display: block; flex-shrink: 0; }
|
||||
.wd-prof-spark { width: 64px; height: 20px; display: block; flex-shrink: 0; }
|
||||
/* Community Store */
|
||||
.wd-store-crumbs { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin-bottom: 14px; font-size: .85em; }
|
||||
.wd-crumb { background: none; border: none; color: var(--primary-color); cursor: pointer; padding: 2px 4px; font: inherit; }
|
||||
@@ -929,6 +975,15 @@ button.wd-profile-card { display: block; }
|
||||
.wd-onboard .wd-card-title { margin-top: 0; }
|
||||
.wd-onboard-skip { font-size: .8em; color: var(--secondary-text-color); text-decoration: underline; cursor: pointer; }
|
||||
.wd-onboard-skip:hover { color: var(--primary-color); }
|
||||
/* Setup card (replaces getting-started card, phases 0-3) and phase-4 chip */
|
||||
.wd-setup-card { margin-top: 12px; padding: 16px; border-radius: 10px; border: 1px solid var(--primary-color, #03a9f4); background: color-mix(in srgb, var(--primary-color, #03a9f4) 8%, var(--card-background-color, var(--ha-card-background))); }
|
||||
.wd-setup-card .wd-card-title { margin-top: 0; }
|
||||
.wd-setup-chip { display: inline-flex; align-items: center; gap: 6px; padding: 5px 12px; border-radius: 20px; font-size: .82em; font-weight: 600; cursor: pointer; border: 1px solid var(--divider-color); background: var(--secondary-background-color); margin-top: 12px; }
|
||||
.wd-setup-chip--healthy { border-color: var(--success-color, #4caf50); background: color-mix(in srgb, var(--success-color, #4caf50) 10%, var(--card-background-color, transparent)); }
|
||||
.wd-setup-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
|
||||
.wd-setup-dot--green { background: var(--success-color, #4caf50); }
|
||||
.wd-link { background: none; border: none; padding: 0; color: var(--primary-color); cursor: pointer; font: inherit; text-decoration: underline; display: inline; }
|
||||
.wd-link:hover { opacity: .8; }
|
||||
/* Logs page */
|
||||
.wd-logbar { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-bottom: 12px; }
|
||||
.wd-logs { font-family: monospace; font-size: .76em; background: var(--secondary-background-color); border-radius: var(--wd-radius-md); padding: 10px; height: 56vh; min-height: 140px; overflow: auto; resize: vertical; }
|
||||
@@ -1073,6 +1128,9 @@ button.wd-profile-card { display: block; }
|
||||
.wd-task-pill-eta { opacity: .75; }
|
||||
.wd-task-pill-x { border: none; background: rgba(0,0,0,.18); color: inherit; width: 16px; height: 16px; border-radius: 50%; cursor: pointer; font-size: .9em; line-height: 1; display: inline-flex; align-items: center; justify-content: center; padding: 0; }
|
||||
.wd-task-pill-x:hover { background: rgba(0,0,0,.32); }
|
||||
.wd-task-pill--cancelling { background: rgba(255,160,0,.28); }
|
||||
.wd-task-pill-cancelling { opacity: .9; font-style: italic; }
|
||||
.wd-task-pill-x--cancelling { opacity: .4; cursor: default; pointer-events: none; }
|
||||
.wd-task-spin { width: 10px; height: 10px; border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%; animation: wd-spin-kf .8s linear infinite; opacity: .9; }
|
||||
@keyframes wd-spin-kf { to { transform: rotate(360deg); } }
|
||||
.wd-pg-batchrow { display: flex; align-items: center; gap: 10px; margin: 6px 0 8px; }
|
||||
@@ -1168,6 +1226,35 @@ function _safeHttpUrl(u) {
|
||||
const s = String(u == null ? '' : u).trim();
|
||||
return /^https?:\/\//i.test(s) ? s : '';
|
||||
}
|
||||
// Apply an alpha channel to any CSS color and return a valid rgba() string.
|
||||
// The base color may come from a theme's `--primary-color` (issues #314/#315),
|
||||
// which `getPropertyValue` returns as the raw declared token: `#03a9f4` for hex
|
||||
// themes but `rgb(238, 147, 0)` for many custom themes / HA's accent picker.
|
||||
// The old `col + '55'` alpha-suffix concatenation produced `rgb(238, 147, 0)55`,
|
||||
// an invalid color that made canvas `addColorStop`/`fillStyle` throw and froze
|
||||
// the panel. This parses hex (#rgb/#rgba/#rrggbb/#rrggbbaa) and rgb()/rgba(),
|
||||
// and never throws -- an unrecognised color falls back to itself so the draw
|
||||
// still succeeds (worst case: no transparency) rather than aborting the render.
|
||||
function _withAlpha(col, alpha) {
|
||||
const s = String(col == null ? '' : col).trim();
|
||||
let m = s.match(/^#([0-9a-fA-F]{3,8})$/);
|
||||
if (m) {
|
||||
let h = m[1];
|
||||
if (h.length === 3 || h.length === 4) h = h.split('').map(c => c + c).join('');
|
||||
if (h.length === 6 || h.length === 8) {
|
||||
const r = parseInt(h.slice(0, 2), 16);
|
||||
const g = parseInt(h.slice(2, 4), 16);
|
||||
const b = parseInt(h.slice(4, 6), 16);
|
||||
return `rgba(${r}, ${g}, ${b}, ${alpha})`;
|
||||
}
|
||||
}
|
||||
m = s.match(/^rgba?\(([^)]+)\)$/i);
|
||||
if (m) {
|
||||
const parts = m[1].split(',').map(p => p.trim());
|
||||
if (parts.length >= 3) return `rgba(${parts[0]}, ${parts[1]}, ${parts[2]}, ${alpha})`;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
function _num(v, def) { const n = parseFloat(v); return isNaN(n) ? def : n; }
|
||||
// Visible, keyboard-focusable descendants of `root` (for modal focus trapping).
|
||||
function _focusableEls(root) {
|
||||
@@ -1436,6 +1523,20 @@ function _tip(text, diagram) {
|
||||
return `<span class="wd-tip">i<span class="wd-tip-pop">${dg}<span class="wd-tip-txt">${_esc(text)}</span></span></span>`;
|
||||
}
|
||||
|
||||
// Settings-style toggle switch, reused everywhere instead of raw checkboxes.
|
||||
// `inner` is the <input> attributes (id / data-* / checked / disabled), `label`
|
||||
// is plain-case text, `tip` is an optional _tip(...) string placed inline at the
|
||||
// end of the row. Inline variant (no .wd-field wrapper) fits inside flex rows.
|
||||
function _switchInline(inner, label, tip = '') {
|
||||
return `<label class="wd-switch-lbl"><span class="wd-switch"><input type="checkbox" ${inner}>`
|
||||
+ `<span class="wd-switch-slider"></span></span>`
|
||||
+ `<span class="wd-switch-text wd-switch-text--plain">${_esc(label)}</span></label>${tip || ''}`;
|
||||
}
|
||||
function _switchRow(inner, label, tip = '', hint = '') {
|
||||
return `<div class="wd-field wd-field-switch"><div class="wd-switch-row">${_switchInline(inner, label, tip)}</div>`
|
||||
+ `${hint ? `<div class="wd-field-hint">${_esc(hint)}</div>` : ''}</div>`;
|
||||
}
|
||||
|
||||
// Small conceptual diagrams illustrating each parameter (from SETTINGS_VISUALIZED).
|
||||
function _diagram(id) {
|
||||
const wrap = inner => `<svg class="wd-dg" viewBox="0 0 200 90" preserveAspectRatio="xMidYMid meet">${inner}</svg>`;
|
||||
@@ -1601,7 +1702,7 @@ class HaWashdataPanel extends HTMLElement {
|
||||
this._hassUpdateThrottle = null;
|
||||
this._evtUnsubs = [];
|
||||
// Data
|
||||
this._constants = { stateColors: {}, deviceTypes: [], mlLabEnabled: false, mlSuggestionsEnabled: false, mlTrainingAvailable: false, storeOnlineAvailable: false, storeOnlineEnabled: false, storeWebOrigin: '', storePrefs: {} };
|
||||
this._constants = { stateColors: {}, deviceTypes: [], mlLabEnabled: false, mlSuggestionsEnabled: false, mlTrainingAvailable: false, storeOnlineAvailable: false, storeOnlineEnabled: false, storeWebOrigin: '', storePrefs: {}, pgMatchDefaults: {} };
|
||||
this._constantsLoaded = false;
|
||||
this._devices = [];
|
||||
this._cycles = [];
|
||||
@@ -1627,6 +1728,7 @@ class HaWashdataPanel extends HTMLElement {
|
||||
this._mlSettings = {}; // conf key -> {classic_value, ml_value, ml_reason, ...}
|
||||
this._mlSettingsLoading = false;
|
||||
this._mlTrainingStatus = null; // {enabled, running, last_trained, cycle_count, min_cycles, ...}
|
||||
this._setupStatus = null; // result of ws_get_setup_status
|
||||
// UI state
|
||||
this._selIdx = 0;
|
||||
this._tab = 'status';
|
||||
@@ -1648,6 +1750,7 @@ class HaWashdataPanel extends HTMLElement {
|
||||
this._pendingSettings = {}; // unsaved edits accumulated across section switches
|
||||
this._busy = new Set(); // in-flight long operations (drives spinners)
|
||||
this._tasks = {}; // id -> background-task snapshot (registry, reconnect-safe)
|
||||
this._cancellingTasks = new Set(); // task ids for which cancel was requested but not yet confirmed
|
||||
this._taskCallbacks = {}; // id -> fn(taskSnapshot) run once when a tracked task settles
|
||||
this._tasksSubscribed = false; // subscribe_tasks succeeded (else poll fallback)
|
||||
this._pgHistoryTaskId = null; // active Test-on-history task id
|
||||
@@ -1846,6 +1949,7 @@ class HaWashdataPanel extends HTMLElement {
|
||||
const prev = this._tasks[t.id];
|
||||
if (prev && (prev.updated_at || 0) > (t.updated_at || 0)) return;
|
||||
this._tasks[t.id] = t;
|
||||
if (t.state !== 'running') this._cancellingTasks.delete(t.id);
|
||||
this._updateTaskPills();
|
||||
this._pgAdoptTask(t);
|
||||
this._onTrackedTaskProgress(t);
|
||||
@@ -1949,7 +2053,11 @@ class HaWashdataPanel extends HTMLElement {
|
||||
tid = r && r.task_id;
|
||||
if (!tid) throw new Error('no task id');
|
||||
const kind = String(msg.type || '').endsWith('reprocess_history') ? 'reprocess'
|
||||
: String(msg.type || '').endsWith('trigger_ml_training') ? 'ml_training' : 'task';
|
||||
: String(msg.type || '').endsWith('trigger_ml_training') ? 'ml_training'
|
||||
: String(msg.type || '').endsWith('apply_split') ? 'split'
|
||||
: String(msg.type || '').endsWith('trim_cycle') ? 'trim'
|
||||
: String(msg.type || '').endsWith('apply_merge') ? 'merge'
|
||||
: String(msg.type || '').endsWith('rebuild_envelopes') ? 'rebuild' : 'task';
|
||||
this._addProvisionalTask(tid, kind, msg.entry_id, 0);
|
||||
} catch (e) {
|
||||
this._busy.delete(busyKey);
|
||||
@@ -2036,6 +2144,11 @@ class HaWashdataPanel extends HTMLElement {
|
||||
const m = {
|
||||
pg_history: this._t('lbl.task_pg_history', {}, 'Test on history'),
|
||||
pg_sweep: this._t('lbl.task_pg_sweep', {}, 'Optimize'),
|
||||
pg_detail: this._t('lbl.task_pg_detail', {}, 'Simulate cycle'),
|
||||
split: this._t('lbl.task_split', {}, 'Splitting cycle'),
|
||||
trim: this._t('lbl.task_trim', {}, 'Trimming cycle'),
|
||||
merge: this._t('lbl.task_merge', {}, 'Merging cycles'),
|
||||
rebuild: this._t('lbl.task_rebuild', {}, 'Rebuilding envelopes'),
|
||||
reprocess: this._t('lbl.task_reprocess', {}, 'Reprocessing'),
|
||||
ml_training: this._t('lbl.task_ml_training', {}, 'Learning'),
|
||||
};
|
||||
@@ -2065,17 +2178,23 @@ class HaWashdataPanel extends HTMLElement {
|
||||
const running = Object.values(this._tasks || {}).filter(t => t.state === 'running');
|
||||
if (!running.length) return '';
|
||||
return running.map(t => {
|
||||
const cancelling = this._cancellingTasks.has(t.id);
|
||||
const dev = this._deviceName(t.entry_id);
|
||||
const action = t.label_key ? this._t(t.label_key, t.label_params || {}, t.label || this._taskActionLabel(t.kind)) : this._taskActionLabel(t.kind);
|
||||
const label = (dev ? dev + ' · ' : '') + action;
|
||||
const pct = t.progress != null ? Math.round(t.progress * 100) + '%' : '';
|
||||
const eta = (t.eta_s != null && t.eta_s > 0) ? this._fmtEta(t.eta_s) : '';
|
||||
return `<span class="wd-task-pill" title="${_esc(label + (pct ? ' ' + pct : ''))}">`
|
||||
const cancellingLabel = this._t('task.cancelling', {}, 'Cancelling…');
|
||||
const pillClass = 'wd-task-pill' + (cancelling ? ' wd-task-pill--cancelling' : '');
|
||||
const titleSuffix = cancelling ? (' · ' + cancellingLabel) : (pct ? ' ' + pct : '');
|
||||
return `<span class="${pillClass}" title="${_esc(label + titleSuffix)}">`
|
||||
+ `<span class="wd-task-spin"></span>`
|
||||
+ `<span class="wd-task-pill-lbl">${_esc(label)}</span>`
|
||||
+ (pct ? `<span class="wd-task-pill-pct">${pct}</span>` : '')
|
||||
+ (eta ? `<span class="wd-task-pill-eta">${_esc(eta)}</span>` : '')
|
||||
+ `<button class="wd-task-pill-x" data-action="task-cancel" data-task-id="${_esc(t.id)}" title="${_esc(this._t('btn.cancel', {}, 'Cancel'))}">✕</button>`
|
||||
+ (cancelling
|
||||
? `<span class="wd-task-pill-cancelling">${_esc(cancellingLabel)}</span>`
|
||||
: (pct ? `<span class="wd-task-pill-pct">${pct}</span>` : '')
|
||||
+ (eta ? `<span class="wd-task-pill-eta">${_esc(eta)}</span>` : ''))
|
||||
+ `<button class="wd-task-pill-x${cancelling ? ' wd-task-pill-x--cancelling' : ''}" data-action="task-cancel" data-task-id="${_esc(t.id)}" ${cancelling ? 'disabled ' : ''}title="${_esc(this._t('btn.cancel', {}, 'Cancel'))}">✕</button>`
|
||||
+ `</span>`;
|
||||
}).join('');
|
||||
}
|
||||
@@ -2215,7 +2334,7 @@ class HaWashdataPanel extends HTMLElement {
|
||||
if (!this._constantsLoaded) {
|
||||
try {
|
||||
const c = await this._ws({ type: `${_DOMAIN}/get_constants` });
|
||||
this._constants = { stateColors: c.state_colors || {}, deviceTypes: c.device_types || [], mlLabEnabled: !!(c.ml_lab_enabled), mlSuggestionsEnabled: !!(c.ml_suggestions_enabled), mlTrainingAvailable: !!(c.ml_training_available), storeOnlineAvailable: !!(c.store_online_available), storeOnlineEnabled: !!(c.store_online_enabled), storeWebOrigin: c.store_web_origin || '', storePrefs: c.store_prefs || {} };
|
||||
this._constants = { stateColors: c.state_colors || {}, deviceTypes: c.device_types || [], mlLabEnabled: !!(c.ml_lab_enabled), mlSuggestionsEnabled: !!(c.ml_suggestions_enabled), mlTrainingAvailable: !!(c.ml_training_available), storeOnlineAvailable: !!(c.store_online_available), storeOnlineEnabled: !!(c.store_online_enabled), storeWebOrigin: c.store_web_origin || '', storePrefs: c.store_prefs || {}, pgMatchDefaults: c.pg_match_defaults || {}, PROFILE_MIN_WARMUP_CYCLES: c.PROFILE_MIN_WARMUP_CYCLES };
|
||||
} catch (_) { /* fall back to humanized labels */ }
|
||||
try {
|
||||
this._panelCfg = await this._ws({ type: `${_DOMAIN}/get_panel_config` });
|
||||
@@ -2247,7 +2366,11 @@ class HaWashdataPanel extends HTMLElement {
|
||||
// Keep the Manual Recording widget's live duration / sample count fresh
|
||||
// while a recording is running (the backend reports them live; without
|
||||
// this poll the widget stays frozen at its start-of-recording snapshot).
|
||||
if (this._canEdit() && this._recState && this._recState.state === 'recording') {
|
||||
// Gate on the authoritative dev.recording flag rather than the polled
|
||||
// _recState, which is null on first load and would otherwise never be
|
||||
// populated -- leaving the widget showing "Start Recording" during an
|
||||
// active recording (#313).
|
||||
if (this._canEdit() && dev.recording) {
|
||||
try { this._recState = await this._ws({ type: `${_DOMAIN}/get_recording_state`, entry_id: dev.entry_id }); } catch (_) { /* keep previous */ }
|
||||
}
|
||||
}
|
||||
@@ -2791,6 +2914,13 @@ class HaWashdataPanel extends HTMLElement {
|
||||
try { this._matchDebug = await this._ws({ type: `${_DOMAIN}/get_match_debug`, entry_id: eid }); } catch (_) { /* keep */ }
|
||||
}
|
||||
if (this._canEdit()) { try { this._recState = await this._ws({ type: `${_DOMAIN}/get_recording_state`, entry_id: eid }); } catch (_) {} }
|
||||
// Fetch setup guidance phase (always, not just when profileCount === 0)
|
||||
try {
|
||||
this._setupStatus = await this._ws({
|
||||
type: `${_DOMAIN}/get_setup_status`,
|
||||
entry_id: eid,
|
||||
});
|
||||
} catch (_) { this._setupStatus = null; }
|
||||
} else if (this._tab === 'history') {
|
||||
await this._fetchCycles(eid);
|
||||
if (!this._profiles.length) await this._fetchProfiles(eid);
|
||||
@@ -3453,17 +3583,20 @@ class HaWashdataPanel extends HTMLElement {
|
||||
${this._statusEnv ? `<label class="wd-leg-i"><input type="checkbox" data-statustoggle="show_expected" ${showExpected ? 'checked' : ''}><span class="wd-leg-sw" style="background:#ff9800"></span> ${this._t('lbl.expected', {}, 'Expected')}</label>` : ''}
|
||||
${this._pref('show_raw', false) ? `<label class="wd-leg-i"><input type="checkbox" data-statustoggle="show_raw_active" ${showRawLeg ? 'checked' : ''}><span class="wd-leg-sw" style="background:#9e9e9e"></span> ${this._t('lbl.raw_socket', {}, 'Raw socket')}</label>` : ''}
|
||||
</div>`;
|
||||
// F1 first-run wizard: on a fresh device (no profiles yet, onboarding not
|
||||
// skipped) replace the empty chart placeholder with a getting-started card
|
||||
// until enough cycles are observed. A live cycle (hasCurve) always wins so
|
||||
// the user sees their appliance being watched in real time.
|
||||
// Setup card: phase-aware guidance replacing the old getting-started card.
|
||||
// A live cycle (hasCurve) always wins so the user sees their appliance.
|
||||
const cycleCount = this._cyclesTotal || 0;
|
||||
const profileCount = (this._profiles || []).length;
|
||||
const showGettingStarted = !this._pref('onboarding_dismissed', false) && profileCount === 0 && !hasCurve;
|
||||
const setupDismissed = this._pref('setup_card_dismissed', false);
|
||||
const setupStatus = this._setupStatus;
|
||||
// Phase 3 and 4 collapse to a chip when dismissed; earlier phases always show
|
||||
// the full guidance card regardless of the dismissed pref.
|
||||
const showSetupCard = setupStatus && !hasCurve;
|
||||
const setupCardHtml = showSetupCard ? this._htmlSetupCard(setupStatus, setupDismissed) : '';
|
||||
const curveHtml = hasCurve
|
||||
? `<div class="wd-canvas-wrap" style="margin-top:14px"><canvas id="wd-status-canvas" role="img" aria-label="${_esc(this._t('lbl.aria_power_chart', {}, 'Power consumption chart'))}" style="height:160px"></canvas></div>${legend}`
|
||||
: (showGettingStarted
|
||||
? this._htmlGettingStarted(cycleCount)
|
||||
: (showSetupCard
|
||||
? setupCardHtml
|
||||
: `<p class="wd-info" style="margin-top:12px">${this._t('msg.live_chart_loading', {}, 'Live power chart appears as readings arrive.')}</p>`);
|
||||
|
||||
const showDebug = this._pref('show_debug', false);
|
||||
@@ -3514,7 +3647,7 @@ class HaWashdataPanel extends HTMLElement {
|
||||
</div>
|
||||
<div class="wd-badge ${isRunning ? 'wd-running' : ''}" style="color:${color};background:color-mix(in srgb, ${color} 13%, transparent);">
|
||||
<span class="wd-dot"></span>${_esc(label)}
|
||||
${dev.sub_state ? `<span style="opacity:.7;font-size:.85em">(${_esc(dev.sub_state)})</span>` : ''}
|
||||
${!rec && dev.sub_state && dev.sub_state.toLowerCase() !== state ? `<span style="opacity:.7;font-size:.85em">(${_esc(dev.sub_state)})</span>` : ''}
|
||||
</div>
|
||||
${programCtl}
|
||||
<div class="wd-stats">
|
||||
@@ -3524,7 +3657,7 @@ class HaWashdataPanel extends HTMLElement {
|
||||
</div>
|
||||
${progressHtml}
|
||||
${this._htmlPhaseTimeline(dev, prog, isRunning)}
|
||||
${showGettingStarted ? '' : `<div class="wd-card-title" style="margin-top:18px">${this._t('hdr.live_power', {}, 'Live Power')}</div>`}
|
||||
${showSetupCard ? '' : `<div class="wd-card-title" style="margin-top:18px">${this._t('hdr.live_power', {}, 'Live Power')}</div>`}
|
||||
${curveHtml}
|
||||
</div>
|
||||
${this._canEdit() ? this._htmlRecordingWidget() : ''}
|
||||
@@ -3533,35 +3666,131 @@ class HaWashdataPanel extends HTMLElement {
|
||||
`;
|
||||
}
|
||||
|
||||
// F1: first-run guided card shown in the Status power-chart area of a fresh
|
||||
// device. Below 3 observed cycles it explains the "just run it" learning phase
|
||||
// with a 0..3 progress meter; at 3+ it nudges toward creating the first
|
||||
// profile (reusing the existing create-profile entry point). A "Skip setup"
|
||||
// link dismisses it permanently via the onboarding_dismissed user pref.
|
||||
_htmlGettingStarted(cycleCount) {
|
||||
const n = Math.max(0, Math.min(3, cycleCount || 0));
|
||||
const heading = `<div class="wd-card-title" style="margin:12px 0 4px">${this._t('hdr.getting_started', {}, 'Getting started')}</div>`;
|
||||
const skip = `<div style="margin-top:14px"><span role="button" tabindex="0" data-action="skip-onboarding" class="wd-onboard-skip">${this._t('btn.skip_setup', {}, 'Skip setup')}</span></div>`;
|
||||
if (cycleCount >= 3) {
|
||||
// Enough cycles observed — point the user at naming their first program.
|
||||
const createBtn = this._canEdit()
|
||||
? `<div style="margin-top:12px"><button class="wd-btn wd-btn-primary" data-action="create-profile">${this._t('btn.new_profile', {}, '+ New Profile')}</button></div>`
|
||||
: '';
|
||||
return `<div class="wd-onboard">
|
||||
${heading}
|
||||
<p class="wd-info" style="margin:0">${this._t('msg.name_first_program', {}, 'You have enough cycles — name your first program to start matching.')}</p>
|
||||
${createBtn}
|
||||
${skip}
|
||||
</div>`;
|
||||
// Setup Card — phase-aware guidance for device onboarding. Replaces the old
|
||||
// getting-started card for backends that support get_setup_status (Task 4).
|
||||
// Phase 4 renders as a compact chip (device fully set up); phases 0–3 render
|
||||
// the full guidance card with a primary CTA, optional secondary action, skip
|
||||
// links, and a permanent-hide link when dismissible.
|
||||
_htmlSetupCard(status, dismissed = false) {
|
||||
if (!status) return '';
|
||||
const { phase, message_key, message_params, cta_label_key, cta_action,
|
||||
secondary_label_key, secondary_action, skippable, dismissible,
|
||||
step_key } = status;
|
||||
|
||||
// Phase 4: always a collapsed chip (setup complete — no full card).
|
||||
if (phase === 'phase4') {
|
||||
return `
|
||||
<div class="wd-setup-chip wd-setup-chip--healthy" data-action="expand-setup" role="button" tabindex="0"
|
||||
title="${_esc(this._t('setup.cta.show_guidance', {}, 'Show guidance'))}">
|
||||
<span class="wd-setup-dot wd-setup-dot--green"></span>
|
||||
<span>${this._t('setup.hdr.healthy_chip', {}, 'Setup complete')}</span>
|
||||
</div>`;
|
||||
}
|
||||
const pct = (n / 3) * 100;
|
||||
return `<div class="wd-onboard">
|
||||
${heading}
|
||||
<p class="wd-info" style="margin:0 0 12px">${this._t('msg.onboarding_watching', {}, 'Run your appliance normally — WashData is watching. After 3 cycles, program matching will begin.')}</p>
|
||||
<div class="wd-prog-bg"><div class="wd-prog-fill" style="width:${pct.toFixed(0)}%"></div></div>
|
||||
<div class="wd-prog-row"><span>${this._t('msg.onboarding_progress', {n}, `${n} / 3 cycles observed`)}</span></div>
|
||||
${skip}
|
||||
</div>`;
|
||||
|
||||
// Phase 3 dismissed: compact chip so the user can restore guidance without
|
||||
// the full card. Click clears setup_card_dismissed and re-renders the full card.
|
||||
if (phase === 'phase3' && dismissed) {
|
||||
return `
|
||||
<div class="wd-setup-chip" data-action="expand-setup" role="button" tabindex="0"
|
||||
title="${_esc(this._t('setup.cta.show_guidance', {}, 'Show guidance'))}">
|
||||
<span class="wd-setup-dot" style="background:var(--warning-color,#ff9800)"></span>
|
||||
<span>${this._t('setup.hdr.card', {}, 'Device Setup')}</span>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
const msg = this._t(message_key, message_params || {}, '');
|
||||
const ctaLabel = this._t(cta_label_key, {}, 'Continue');
|
||||
const secLabel = secondary_label_key
|
||||
? this._t(secondary_label_key, {}, '')
|
||||
: null;
|
||||
|
||||
const skipHtml = skippable ? `
|
||||
<span style="display:flex;gap:12px;margin-top:6px">
|
||||
<a class="wd-link" data-action="setup-skip" data-step="${_esc(step_key || '')}" data-snooze="14d"
|
||||
style="font-size:.85em">${this._t('setup.cta.skip_step', {}, 'Skip this step')}</a>
|
||||
<a class="wd-link" data-action="setup-skip" data-step="${_esc(step_key || '')}" data-snooze="never"
|
||||
style="font-size:.85em;opacity:.7">${this._t('setup.cta.skip_forever', {}, "Don't show again")}</a>
|
||||
</span>` : '';
|
||||
|
||||
const hideHtml = dismissible ? `
|
||||
<a class="wd-link" data-action="hide-setup-card" style="font-size:.8em;opacity:.6;margin-top:4px">
|
||||
${this._t('setup.cta.hide_guidance', {}, 'Hide guidance')}
|
||||
</a>` : '';
|
||||
|
||||
return `
|
||||
<div class="wd-setup-card" data-phase="${_esc(phase)}">
|
||||
<div class="wd-card-title">${this._t('setup.hdr.card', {}, 'Device Setup')}</div>
|
||||
<p style="margin:6px 0 12px">${_esc(msg)}</p>
|
||||
<div style="display:flex;flex-wrap:wrap;gap:8px;align-items:center">
|
||||
<button class="wd-btn wd-btn-primary" data-action="setup-cta"
|
||||
data-cta-action="${_esc(cta_action || '')}"
|
||||
data-cta-params="${_esc(JSON.stringify(message_params || {}))}">
|
||||
${_esc(ctaLabel)}
|
||||
</button>
|
||||
${secLabel ? `<a class="wd-link" data-action="setup-cta"
|
||||
data-cta-action="${_esc(secondary_action || '')}"
|
||||
data-cta-params="${_esc(JSON.stringify(message_params || {}))}">
|
||||
${_esc(secLabel)}
|
||||
</a>` : ''}
|
||||
</div>
|
||||
${skipHtml}
|
||||
${hideHtml}
|
||||
</div>`;
|
||||
}
|
||||
|
||||
// Dispatch a setup card CTA action to the appropriate panel destination.
|
||||
_dispatchSetupCta(ctaAction, params) {
|
||||
if (!ctaAction) return;
|
||||
if (ctaAction === 'open_recorder') {
|
||||
// Scroll to recorder widget on the Status tab
|
||||
this.shadowRoot.querySelector('.wd-rec-dot')?.closest('.wd-card')?.scrollIntoView({ behavior: 'smooth' });
|
||||
return;
|
||||
}
|
||||
if (ctaAction === 'open_cycles' || ctaAction === 'open_cycles_unlabeled') {
|
||||
this._tab = 'history';
|
||||
if (ctaAction === 'open_cycles_unlabeled') {
|
||||
this._cycleFilter = { ...(this._cycleFilter || {}), status: 'unlabeled' };
|
||||
}
|
||||
this._fetchTabData();
|
||||
return;
|
||||
}
|
||||
if (ctaAction === 'open_profiles' || ctaAction === 'open_profiles_groups') {
|
||||
this._tab = 'profiles';
|
||||
this._fetchTabData();
|
||||
return;
|
||||
}
|
||||
if (ctaAction === 'open_suggestions') {
|
||||
this._tab = 'settings';
|
||||
this._settingsSugOnly = true;
|
||||
this._fetchTabData();
|
||||
return;
|
||||
}
|
||||
if (ctaAction === 'create_profile_from_cluster') {
|
||||
// No modal shortcut yet — open the profiles tab where the user can create
|
||||
// a profile; a future task may pre-populate from cluster cycle IDs.
|
||||
this._tab = 'profiles';
|
||||
this._fetchTabData();
|
||||
return;
|
||||
}
|
||||
if (ctaAction && ctaAction.startsWith('open_cycle:')) {
|
||||
// No direct cycle modal shortcut yet — open the history tab.
|
||||
this._tab = 'history';
|
||||
this._fetchTabData();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Reload the setup guidance phase from the backend and re-render.
|
||||
async _reloadSetupStatus() {
|
||||
const dev = this._devices[this._selIdx];
|
||||
if (!dev) return;
|
||||
try {
|
||||
this._setupStatus = await this._ws({
|
||||
type: `${_DOMAIN}/get_setup_status`,
|
||||
entry_id: dev.entry_id,
|
||||
});
|
||||
} catch (_) { this._setupStatus = null; }
|
||||
this._render();
|
||||
}
|
||||
|
||||
// D1: compact horizontal phase timeline for the matched profile, drawn below
|
||||
@@ -3597,11 +3826,18 @@ class HaWashdataPanel extends HTMLElement {
|
||||
|
||||
_htmlRecordingWidget() {
|
||||
const rs = this._recState;
|
||||
const state = rs ? rs.state : 'idle';
|
||||
// dev.recording (from get_devices) is the authoritative recording flag.
|
||||
// _recState is a separately-polled detail source that is null on first load
|
||||
// and only refreshed while already recording, so trusting it alone showed
|
||||
// "Start Recording" during an active recording (#313). Derive the state from
|
||||
// the authoritative flag and use _recState only for the live duration/samples.
|
||||
const dev = this._devices[this._selIdx];
|
||||
const recording = !!(dev && dev.recording);
|
||||
const state = recording ? 'recording' : (rs ? rs.state : 'idle');
|
||||
const dotCls = state === 'recording' ? 'wd-rec-active' : state === 'stopped' ? 'wd-rec-ready' : 'wd-rec-idle';
|
||||
const stateLabel = state === 'recording' ? this._t('status.recording', {}, 'Recording…') : state === 'stopped' ? this._t('status.ready', {}, 'Ready to process') : this._t('status.idle', {}, 'Idle');
|
||||
let detail = '';
|
||||
if (state === 'recording') detail = `${_fmtDuration(rs.duration_s)} · ${rs.sample_count || 0} samples`;
|
||||
if (state === 'recording') detail = rs ? `${_fmtDuration(rs.duration_s)} · ${rs.sample_count || 0} samples` : '';
|
||||
else if (state === 'stopped') detail = `${rs.sample_count || 0} samples · ${_fmtDuration(rs.duration_s)}`;
|
||||
const buttons = state === 'recording'
|
||||
? `<button class="wd-btn wd-btn-danger wd-btn-sm" data-action="rec-stop" title="${_esc(this._t('btn.rec_stop_tip', {}, 'Stop recording and hold the captured trace for review'))}">${this._t('btn.rec_stop', {}, 'Stop')}</button>`
|
||||
@@ -3872,10 +4108,10 @@ class HaWashdataPanel extends HTMLElement {
|
||||
// match immediately), shown with an "Imported" badge instead of "Still learning".
|
||||
const isWarmup = cycleCount < warmupThreshold && !p.is_imported;
|
||||
const warmupBadge = isWarmup
|
||||
? `<span class="wd-badge" title="${_esc(this._t('msg.warmup_detail', {needed: warmupThreshold}, `This profile needs ${warmupThreshold} labelled cycles before auto-matching begins. Every confirmed cycle helps it learn.`))}" style="background:var(--info-color,#2196f3);color:#fff;padding:2px 6px;border-radius:4px;font-size:.75em">${this._t('msg.warmup_badge', {done: cycleCount, needed: warmupThreshold}, `Still learning (${cycleCount}/${warmupThreshold} cycles)`)}</span>`
|
||||
? `<span class="wd-badge" title="${_esc(this._t('msg.warmup_detail', {needed: warmupThreshold}, `This profile needs ${warmupThreshold} labelled cycles before auto-matching begins. Every confirmed cycle helps it learn.`))}" style="background:var(--info-color,#2196f3);color:#fff">${this._t('msg.warmup_badge', {done: cycleCount, needed: warmupThreshold}, `Still learning (${cycleCount}/${warmupThreshold} cycles)`)}</span>`
|
||||
: '';
|
||||
const importedBadge = p.is_imported
|
||||
? `<span class="wd-badge" title="${_esc(this._t('badge.imported_tip', {}, 'Imported from the community store. Used for matching only, not counted in stats.'))}" style="background:var(--info-color,#2196f3);color:#fff;padding:2px 6px;border-radius:4px;font-size:.75em">📥 ${this._t('status.imported', {}, 'Imported')}</span>`
|
||||
? `<span class="wd-badge" title="${_esc(this._t('badge.imported_tip', {}, 'Imported from the community store. Used for matching only, not counted in stats.'))}" style="background:var(--info-color,#2196f3);color:#fff">📥 ${this._t('status.imported', {}, 'Imported')}</span>`
|
||||
: '';
|
||||
const badges = [healthBadge, trendBadge, warmupBadge, importedBadge].filter(Boolean).join(' ');
|
||||
// Mini power-signature curve: the profile's real average power shape (from its
|
||||
@@ -3887,7 +4123,11 @@ class HaWashdataPanel extends HTMLElement {
|
||||
return `
|
||||
<div class="wd-prof-wrap">
|
||||
<button class="wd-profile-card" type="button" data-action="open-profile" data-pname="${_esc(p.name)}">
|
||||
<div class="wd-profile-name">${_esc(p.name)}${badges ? ' ' + badges : ''}${spark}</div>
|
||||
<div class="wd-profile-head">
|
||||
<span class="wd-profile-name">${_esc(p.name)}</span>
|
||||
${spark}
|
||||
</div>
|
||||
${badges ? `<div class="wd-profile-badges">${badges}</div>` : ''}
|
||||
<div class="wd-profile-meta">${p.cycle_count || 0} cycles · ${dur}${energy}${total}${cost}</div>
|
||||
</button>
|
||||
</div>`;
|
||||
@@ -3932,42 +4172,6 @@ class HaWashdataPanel extends HTMLElement {
|
||||
const groupedNames = new Set();
|
||||
pg.groups.forEach(g => (g.members || []).forEach(m => groupedNames.add(m)));
|
||||
|
||||
// Suggestion banner: near-duplicate clusters the user can confirm as groups.
|
||||
const sugBanner = (canEdit && (pg.suggestions || []).length) ? `
|
||||
<div class="wd-sug-banner">
|
||||
<span>🔗 <b>${pg.suggestions.length}</b> ${this._t('msg.near_duplicate_cluster', {}, 'near-duplicate profile cluster' + (pg.suggestions.length > 1 ? 's' : '') + ' detected. Grouping lets matching reliably pick between look-alikes (e.g. same program at different temperature/spin).')}</span>
|
||||
${pg.suggestions.map((s, i) => `<button class="wd-btn wd-btn-sm wd-btn-primary" data-action="pg-suggest" data-idx="${i}">${this._t('btn.group_suggest', {n: s.members.length, members: _esc(s.members.join(', ').slice(0, 48))}, `Group ${s.members.length}: ${_esc(s.members.join(', ').slice(0, 48))}`)}</button>`).join('')}
|
||||
</div>` : '';
|
||||
|
||||
// Coverage gap banner: unmatched cycles that might represent unknown programs.
|
||||
const cg = this._coverageGaps || {};
|
||||
const cgBanner = (canEdit && cg.suggest_create) ? (() => {
|
||||
const clusters = (cg.duration_clusters || []).slice(0, 3);
|
||||
const clusterHints = clusters.map(cl => `~${cl.duration_bucket_min}–${cl.duration_bucket_min + 15} min (${cl.count}×)`).join(', ');
|
||||
const profileSuggestions = (cg.profile_suggestions || []).slice(0, 2);
|
||||
const suggestionHtml = profileSuggestions.length > 0
|
||||
? profileSuggestions.map(ps => `
|
||||
<div style="margin-top:6px;display:flex;align-items:center;gap:8px">
|
||||
<span style="font-size:.9em">${this._t('msg.coverage_gap_similar_cycles', {count: ps.count}, `${ps.count} similar unlabelled cycles found — create a profile to start matching them.`)}</span>
|
||||
<button class="wd-btn wd-btn-sm wd-btn-primary wd-create-cluster" data-cycle-ids="${_esc(JSON.stringify(ps.cycle_ids))}" data-name="${_esc(ps.suggested_name)}">${this._t('btn.create_from_cluster', {count: ps.count}, `Create profile from ${ps.count} cycles`)}</button>
|
||||
</div>`).join('')
|
||||
: '';
|
||||
return `<div class="wd-sug-banner" style="border-color:var(--info-color,#2196f3);background:rgba(33,150,243,.07)">
|
||||
<span>📂 <b>${cg.unmatched_count}</b> ${this._t('msg.coverage_gap', {pct: Math.round(cg.unmatched_rate * 100)}, `recent cycles have no matching profile (${Math.round(cg.unmatched_rate * 100)}% of last 30).`)}${clusterHints ? ` ${this._t('lbl.duration', {}, 'Duration')}: ${clusterHints}.` : ''} ${this._t('msg.consider_new_profile', {}, 'Consider creating a new profile.')}</span>
|
||||
${canEdit ? `<button class="wd-btn wd-btn-sm wd-btn-primary" data-action="create-profile">${this._t('btn.create_profile', {}, '+ Create profile')}</button>` : ''}
|
||||
${suggestionHtml}
|
||||
</div>`;
|
||||
})() : '';
|
||||
|
||||
// Recommendations: actionable maintenance advisories derived from the
|
||||
// per-profile health/trend signals (drift, poor fit). Informational only.
|
||||
const advisories = this._profileAdvisories || [];
|
||||
const advBanner = advisories.length ? `
|
||||
<div class="wd-sug-banner" style="border-color:var(--warning-color,#ff9800);background:rgba(255,152,0,.06);flex-direction:column;align-items:stretch;gap:6px">
|
||||
<span style="font-weight:600">💡 ${this._t('hdr.recommendations', {n: advisories.length}, `Recommendations (${advisories.length})`)}</span>
|
||||
${advisories.slice(0, 5).map(a => `<div style="font-size:.9em">${a.severity === 'warning' ? '⚠' : 'ℹ️'} ${_esc(a.message_key ? this._t(a.message_key, a.message_params || {}, a.message || '') : (a.message || ''))}</div>`).join('')}
|
||||
</div>` : '';
|
||||
|
||||
// Group sections (with cohesion badge + low-cohesion warning).
|
||||
const groupSections = pg.groups.map(g => {
|
||||
const memCards = (g.members || []).map(m => byName[m] ? this._profileCardHtml(byName[m]) : '').join('');
|
||||
@@ -4014,9 +4218,6 @@ class HaWashdataPanel extends HTMLElement {
|
||||
<button class="wd-btn wd-btn-secondary" data-action="rebuild-envelopes" ${rebuildBusy ? 'disabled' : ''} title="${_esc(this._t('btn.rebuild_tip', {}, 'Recompute the expected power envelope (min/max band) for all profiles from their labelled cycles — run after labelling new cycles or correcting old ones'))}">${rebuildBusy ? ('<span class="wd-spin"></span> ' + this._t('status.rebuilding', {}, 'Rebuilding…')) : this._t('btn.rebuild', {}, 'Rebuild Envelopes')}</button>
|
||||
</div>` : ''}
|
||||
</div>
|
||||
${sugBanner}
|
||||
${cgBanner}
|
||||
${advBanner}
|
||||
${groupSections}
|
||||
${this._profiles.length === 0
|
||||
? `<div class="wd-empty"><div class="wd-icon">📊</div>${this._t('msg.no_profiles_yet', {}, 'No profiles yet. Create one from a labelled cycle.')}</div>`
|
||||
@@ -4991,20 +5192,38 @@ class HaWashdataPanel extends HTMLElement {
|
||||
['end_repeat_count', 'End Repeat Count', '', 'Low readings in a row before ending', 'advanced'],
|
||||
['abrupt_drop_watts', 'Abrupt Drop Threshold', 'W', 'Sudden drop treated as immediate end', 'advanced'],
|
||||
['interrupted_min_seconds', 'Interrupted Min', 's', 'Short cycles flagged as interrupted', 'advanced'],
|
||||
['profile_match_min_duration_ratio', 'Min Duration Ratio', '', 'Shortest run (vs the profile) still allowed to match', 'matching'],
|
||||
['profile_match_max_duration_ratio', 'Max Duration Ratio', '', 'Longest run (vs the profile) still allowed to match', 'matching'],
|
||||
['profile_match_min_duration_ratio', 'Min Duration Ratio', '', 'Stage 1: shortest run (vs the profile) still allowed to match', 'matching'],
|
||||
['profile_match_max_duration_ratio', 'Max Duration Ratio', '', 'Stage 1: longest run (vs the profile) still allowed to match', 'matching'],
|
||||
['corr_weight', 'Correlation Weight', '', 'Stage 2: balance between curve shape (correlation) and power level (MAE); default 0.45', 'matching'],
|
||||
['keep_min_score', 'Keep Min Score', '', 'Stage 2: floor score to stay in the race; default 0.1 admits weak matches, later stages pick the best', 'matching'],
|
||||
['dtw_bandwidth', 'DTW Bandwidth', '', 'Stage 3: Sakoe-Chiba warp band (0 = DTW off; default 0.2 = 20% of cycle length)', 'matching'],
|
||||
['dtw_blend', 'DTW Blend', '', 'Stage 3: 0 = core score only, 1 = DTW score only, 0.5 = equal blend (default)', 'matching'],
|
||||
['dtw_ensemble_w', 'DTW Ensemble Weight','', 'Stage 3 (ensemble mode): weight on scaled-L1 vs derivative DTW; default 0.7 favours level-aware', 'matching'],
|
||||
['dtw_ddtw_scale', 'DDTW Scale', '', 'Stage 3: DDTW half-saturation distance; smaller = more shape-sensitive (default 30)', 'matching'],
|
||||
['dtw_refine_top_n', 'DTW Refine Top-N', '', 'Stage 3: candidates DTW re-scores; raise to 7-9 if correct profile ranks 4th-5th (default 5)', 'matching'],
|
||||
['duration_weight', 'Duration Weight', '', 'Stage 4: how strongly run-length agreement affects the final score (default 0.22)', 'matching'],
|
||||
['energy_weight', 'Energy Weight', '', 'Stage 4: how strongly energy agreement affects the final score (default 0.22)', 'matching'],
|
||||
['duration_scale', 'Duration Scale', '', 'Stage 4: log-ratio where duration agreement halves; smaller = stricter penalty (default 0.175)', 'matching'],
|
||||
['energy_scale', 'Energy Scale', '', 'Stage 4: log-ratio where energy agreement halves; smaller = stricter penalty (default 0.25)', 'matching'],
|
||||
];
|
||||
}
|
||||
|
||||
// Resolve a pre-fill value for an override field: staged override → live option
|
||||
// → field default → ''.
|
||||
// → field default (settings schema) → matcher constant default → ''.
|
||||
_pgFieldVal(key, store) {
|
||||
const s = store || {};
|
||||
if (s[key] !== undefined) return s[key];
|
||||
const o = this._opts || {};
|
||||
if (o[key] !== undefined && o[key] !== null) return o[key];
|
||||
const f = _FIELD_BY_KEY[key] || {};
|
||||
return f.def !== undefined ? f.def : '';
|
||||
if (f.def !== undefined) return f.def;
|
||||
// Prefer backend-provided matcher defaults (const.py, via get_constants) so the
|
||||
// Playground can't drift from the real defaults; the hardcoded _PG_MATCH_DEFAULTS
|
||||
// table below is only an offline fallback for when the payload hasn't loaded.
|
||||
const be = (this._constants && this._constants.pgMatchDefaults) || {};
|
||||
if (be[key] !== undefined) return be[key];
|
||||
if (_PG_MATCH_DEFAULTS[key] !== undefined) return _PG_MATCH_DEFAULTS[key];
|
||||
return '';
|
||||
}
|
||||
|
||||
_htmlPlayground() {
|
||||
@@ -5668,10 +5887,33 @@ class HaWashdataPanel extends HTMLElement {
|
||||
const override = { ...this._pgParamOverrides };
|
||||
if (this._pgThreshStart != null) override.start_threshold_w = this._pgThreshStart;
|
||||
if (this._pgThreshStop != null) override.stop_threshold_w = this._pgThreshStop;
|
||||
// Run the heavy per-5s replay as a detached, chunked background task so a long
|
||||
// cycle no longer stalls Home Assistant (issue #311). We still await its
|
||||
// completion here (the caller drives the busy spinner + redraw), but the
|
||||
// backend yields the event loop between chunks. A header pill shows progress.
|
||||
try {
|
||||
const d = await this._ws({ type: `${_DOMAIN}/run_playground_cycle_detail`, entry_id: entryId, cycle_id: cid, settings_override: override });
|
||||
const r = await this._ws({ type: `${_DOMAIN}/start_playground_cycle_detail`, entry_id: entryId, cycle_id: cid, settings_override: override });
|
||||
const tid = r && r.task_id;
|
||||
if (!tid) throw new Error('no task id');
|
||||
this._addProvisionalTask(tid, 'pg_detail', entryId, 0);
|
||||
const result = await new Promise((resolve) => {
|
||||
this._taskCallbacks[tid] = async (t) => {
|
||||
if (t.state === 'done' || t.state === 'cancelled') {
|
||||
try {
|
||||
const rr = await this._ws({ type: `${_DOMAIN}/get_task_result`, task_id: t.id });
|
||||
resolve(rr && rr.result);
|
||||
} catch (_) { resolve(null); }
|
||||
} else {
|
||||
resolve(null); // error / lost
|
||||
}
|
||||
};
|
||||
// Race guard: task may have finished before the callback was registered.
|
||||
const known = this._tasks[tid];
|
||||
if (known && known.state !== 'running') this._settleTaskCallback(known);
|
||||
else if (!this._tasksSubscribed) this._pollTaskGeneric(tid);
|
||||
});
|
||||
if (!this._isActiveEntry(entryId)) return; // device switched mid-flight - drop stale result
|
||||
this._pgDetail = (d && !d.error) ? d : null;
|
||||
this._pgDetail = (result && !result.error) ? result : null;
|
||||
this._pgNeedsRestart = false;
|
||||
} catch (e) {
|
||||
if (this._pgIsUnknownCmd(e)) this._pgNeedsRestart = true;
|
||||
@@ -5863,7 +6105,7 @@ class HaWashdataPanel extends HTMLElement {
|
||||
pts.forEach(p => ctx.lineTo(toX(p.t), toY(p.w)));
|
||||
ctx.lineTo(toX(pts[pts.length-1].t), toY(0));
|
||||
ctx.closePath();
|
||||
ctx.fillStyle = primary + '1a'; ctx.fill();
|
||||
ctx.fillStyle = _withAlpha(primary, 0.10); ctx.fill();
|
||||
|
||||
// Cycle power trace line
|
||||
ctx.beginPath(); ctx.strokeStyle = primary; ctx.lineWidth = 2*dpr;
|
||||
@@ -6412,10 +6654,10 @@ class HaWashdataPanel extends HTMLElement {
|
||||
<div class="wd-field"><label>${this._t('lbl.panel_language', {}, 'Panel language')}</label><select id="wd-pref-lang">${langOpts}</select></div>
|
||||
</div>
|
||||
<div class="wd-subhead">${this._t('hdr.status_graph', {}, 'Status Graph')}</div>
|
||||
<div class="wd-field"><label class="wd-check-row"><input type="checkbox" id="wd-pref-expected" ${(cur.show_expected !== false) ? 'checked' : ''}> ${this._t('lbl.show_expected', {}, 'Show expected curve overlay (matched profile, orange)')}</label></div>
|
||||
<div class="wd-field"><label class="wd-check-row"><input type="checkbox" id="wd-pref-raw" ${cur.show_raw ? 'checked' : ''}> ${this._t('lbl.show_raw', {}, 'Show raw socket toggle in live power graph')}</label></div>
|
||||
${_switchRow(`id="wd-pref-expected" ${(cur.show_expected !== false) ? 'checked' : ''}`, this._t('lbl.show_expected', {}, 'Show expected curve overlay (matched profile, orange)'))}
|
||||
${_switchRow(`id="wd-pref-raw" ${cur.show_raw ? 'checked' : ''}`, this._t('lbl.show_raw', {}, 'Show raw socket toggle in live power graph'))}
|
||||
<div class="wd-subhead">${this._t('hdr.diagnostics_pref', {}, 'Diagnostics')}</div>
|
||||
<div class="wd-field"><label class="wd-check-row"><input type="checkbox" id="wd-pref-debug" ${cur.show_debug ? 'checked' : ''}> ${this._t('lbl.show_debug', {}, 'Show live match debug card on the Status page (confidence, ambiguity, top candidates)')}</label></div>
|
||||
${_switchRow(`id="wd-pref-debug" ${cur.show_debug ? 'checked' : ''}`, this._t('lbl.show_debug', {}, 'Show live match debug card on the Status page (confidence, ambiguity, top candidates)'))}
|
||||
<div class="wd-card-actions"><button class="wd-btn wd-btn-primary" data-action="save-prefs">${this._t('btn.save_preferences', {}, 'Save Preferences')}</button></div>
|
||||
</div>`;
|
||||
}
|
||||
@@ -6432,13 +6674,13 @@ class HaWashdataPanel extends HTMLElement {
|
||||
const dtOpts = tabOpts.map(([v, l]) => `<option value="${v}" ${(p.default_tab || 'status') === v ? 'selected' : ''}>${_esc(l)}</option>`).join('');
|
||||
const hidden = p.hidden_tabs || [];
|
||||
const hideChecks = tabOpts.filter(([v]) => v !== 'status')
|
||||
.map(([v, l]) => `<label class="wd-check-row" style="margin-right:14px;display:inline-flex"><input type="checkbox" data-hidetab="${v}" ${hidden.includes(v) ? 'checked' : ''}> ${_esc(l)}</label>`).join('');
|
||||
.map(([v, l]) => _switchInline(`data-hidetab="${v}" ${hidden.includes(v) ? 'checked' : ''}`, l)).join('');
|
||||
return `<div class="wd-card">
|
||||
<div class="wd-card-title">${this._t('hdr.panel_settings', {}, 'Panel Settings (all users)')}</div>
|
||||
<div class="wd-form-grid">
|
||||
<div class="wd-field"><label>${this._t('lbl.panel_default_tab', {}, 'Default tab')}</label><select id="wd-ps-deftab">${dtOpts}</select></div>
|
||||
</div>
|
||||
<div class="wd-field"><label>${this._t('lbl.hide_tabs', {}, 'Hide tabs for non-admins')}</label><div style="display:flex;flex-wrap:wrap;gap:4px">${hideChecks}</div></div>
|
||||
<div class="wd-field"><label>${this._t('lbl.hide_tabs', {}, 'Hide tabs for non-admins')}</label><div style="display:flex;flex-wrap:wrap;gap:10px 22px;margin-top:6px">${hideChecks}</div></div>
|
||||
<div class="wd-card-actions"><button class="wd-btn wd-btn-primary" data-action="save-panel">${this._t('btn.save_panel_settings', {}, 'Save Panel Settings')}</button></div>
|
||||
</div>`;
|
||||
}
|
||||
@@ -6461,8 +6703,7 @@ class HaWashdataPanel extends HTMLElement {
|
||||
const adminNote = users.filter(u => u.is_admin).map(u => `<span class="wd-pill">${_esc(u.name)} - full (admin)</span>`).join(' ');
|
||||
return `<div class="wd-card">
|
||||
<div class="wd-card-title">${this._t('hdr.access_control', {}, 'Access Control')}</div>
|
||||
<div class="wd-field"><label class="wd-check-row"><input type="checkbox" id="wd-rbac-enabled" ${rbac.enabled ? 'checked' : ''}> ${this._t('lbl.enable_access_control', {}, 'Enable per-user access control')}</label>
|
||||
<div class="wd-field-hint">${this._t('msg.rbac_hint', {}, 'When off, every Home Assistant user has full access (the default). Administrators always have full access and can manage everyone.')}</div></div>
|
||||
${_switchRow(`id="wd-rbac-enabled" ${rbac.enabled ? 'checked' : ''}`, this._t('lbl.enable_access_control', {}, 'Enable per-user access control'), '', this._t('msg.rbac_hint', {}, 'When off, every Home Assistant user has full access (the default). Administrators always have full access and can manage everyone.'))}
|
||||
<div class="wd-field"><label>${this._t('lbl.default_access_level', {}, 'Default level for users not listed below')}</label>${this._levelSelect('id="wd-rbac-default"', rbac.default_level || 'none', false)}</div>
|
||||
${adminNote ? `<div class="wd-field"><label>${this._t('lbl.administrators', {}, 'Administrators')}</label><div>${adminNote}</div></div>` : ''}
|
||||
<div class="wd-card-actions"><button class="wd-btn wd-btn-primary" data-action="save-rbac">${this._t('btn.save_access_control', {}, 'Save Access Control')}</button></div>
|
||||
@@ -6556,7 +6797,7 @@ class HaWashdataPanel extends HTMLElement {
|
||||
const dlBusy = this._busy.has('store-download-device');
|
||||
const dlHeader = (this._canEdit() && dev && items.length) ? `<div class="wd-card" style="margin-bottom:10px;display:flex;align-items:center;gap:12px;flex-wrap:wrap">
|
||||
<span class="wd-info" style="flex:1;min-width:180px">${this._t('msg.store_download_device_intro', {}, 'Adopt every shared program and its reference cycles onto your device. Your own recorded cycles and stats are not affected.')}</span>
|
||||
<label class="wd-check-row" style="font-size:.85em">${this._t('lbl.adopt_settings', {}, 'Also adopt settings')} ${_tip(this._t('msg.adopt_settings_hint', {}, 'Overwrite this device\'s detection & matching thresholds with the shared ones. Your notifications, entities and energy price are never changed.'))}<input type="checkbox" data-action="store-toggle-dl-settings" ${this._dlSettings ? 'checked' : ''} ${dlBusy ? 'disabled' : ''}></label>
|
||||
${_switchInline(`data-action="store-toggle-dl-settings" ${this._dlSettings ? 'checked' : ''} ${dlBusy ? 'disabled' : ''}`, this._t('lbl.adopt_settings', {}, 'Also adopt settings'), _tip(this._t('msg.adopt_settings_hint', {}, 'Overwrite this device\'s detection & matching thresholds with the shared ones. Your notifications, entities and energy price are never changed.')))}
|
||||
<button class="wd-btn wd-btn-primary wd-btn-sm" data-action="store-download-device" data-device-id="${_esc(dev.id)}" ${dlBusy ? 'disabled' : ''}>${dlBusy ? '<span class="wd-spin"></span> ' : '⬇ '}${this._t('btn.download_device', {}, 'Download this setup')}</button>
|
||||
</div>` : '';
|
||||
return dlHeader + list;
|
||||
@@ -6652,7 +6893,7 @@ class HaWashdataPanel extends HTMLElement {
|
||||
return `<div class="wd-card">
|
||||
<div class="wd-card-title">${this._t('hdr.online_account', {}, 'Community Store & online features')}</div>
|
||||
<p class="wd-info" style="margin-bottom:12px">${this._t('msg.online_intro_global', {}, 'Browse and share reference recordings with other WashData users, and confirm appliance entries. One connection applies to your whole WashData integration; appliance brand and model are set per device under Basic. All online features are opt-in and off by default.')}</p>
|
||||
<div class="wd-field"><label class="wd-check-row"><input type="checkbox" data-action="store-toggle-online" ${on ? 'checked' : ''} ${busy ? 'disabled' : ''}> ${this._t('lbl.enable_online', {}, 'Enable online features')}</label></div>
|
||||
${_switchRow(`data-action="store-toggle-online" ${on ? 'checked' : ''} ${busy ? 'disabled' : ''}`, this._t('lbl.enable_online', {}, 'Enable online features'))}
|
||||
${on ? this._htmlStorePrefs(busy) : ''}
|
||||
${on ? connBlock : ''}
|
||||
</div>`;
|
||||
@@ -6664,7 +6905,7 @@ class HaWashdataPanel extends HTMLElement {
|
||||
const prefs = (this._constants && this._constants.storePrefs) || {};
|
||||
return _STORE_PREFS.map(p => {
|
||||
const checked = prefs[p.key] !== false; // defaults on; get_constants sends the full set
|
||||
return `<div class="wd-field"><label class="wd-check-row"><input type="checkbox" data-action="store-toggle-pref" data-pref="${_esc(p.key)}" ${checked ? 'checked' : ''} ${busy ? 'disabled' : ''}> ${this._t(p.labelKey, {}, p.labelFb)}</label> ${_tip(this._t(p.docKey, {}, p.docFb))}</div>`;
|
||||
return _switchRow(`data-action="store-toggle-pref" data-pref="${_esc(p.key)}" ${checked ? 'checked' : ''} ${busy ? 'disabled' : ''}`, this._t(p.labelKey, {}, p.labelFb), _tip(this._t(p.docKey, {}, p.docFb)));
|
||||
}).join('');
|
||||
}
|
||||
|
||||
@@ -6848,7 +7089,7 @@ class HaWashdataPanel extends HTMLElement {
|
||||
ctx.beginPath();
|
||||
opts.band.max.forEach((p, i) => i ? ctx.lineTo(X(p[0]), Y(p[1])) : ctx.moveTo(X(p[0]), Y(p[1])));
|
||||
for (let i = opts.band.min.length - 1; i >= 0; i--) ctx.lineTo(X(opts.band.min[i][0]), Y(opts.band.min[i][1]));
|
||||
ctx.closePath(); ctx.fillStyle = opts.band.fill || (primary + '22'); ctx.fill();
|
||||
ctx.closePath(); ctx.fillStyle = opts.band.fill || _withAlpha(primary, 0.13); ctx.fill();
|
||||
}
|
||||
series.forEach(s => {
|
||||
const pts = s.points || []; if (!pts.length) return;
|
||||
@@ -6856,7 +7097,7 @@ class HaWashdataPanel extends HTMLElement {
|
||||
if (s.fill) {
|
||||
ctx.beginPath(); pts.forEach((p, i) => i ? ctx.lineTo(X(p[0]), Y(p[1])) : ctx.moveTo(X(p[0]), Y(p[1])));
|
||||
ctx.lineTo(X(pts[pts.length - 1][0]), Y(0)); ctx.lineTo(X(pts[0][0]), Y(0)); ctx.closePath();
|
||||
const g = ctx.createLinearGradient(0, padT, 0, ch - padB); g.addColorStop(0, col + '55'); g.addColorStop(1, col + '08'); ctx.fillStyle = g; ctx.fill();
|
||||
const g = ctx.createLinearGradient(0, padT, 0, ch - padB); g.addColorStop(0, _withAlpha(col, 0.33)); g.addColorStop(1, _withAlpha(col, 0.03)); ctx.fillStyle = g; ctx.fill();
|
||||
}
|
||||
ctx.beginPath(); pts.forEach((p, i) => i ? ctx.lineTo(X(p[0]), Y(p[1])) : ctx.moveTo(X(p[0]), Y(p[1])));
|
||||
ctx.strokeStyle = col; ctx.lineWidth = (s.width || 1.5) * dpr; ctx.lineJoin = 'round';
|
||||
@@ -7622,6 +7863,14 @@ class HaWashdataPanel extends HTMLElement {
|
||||
<span style="font-size:.82em;opacity:.75;display:block;margin-top:4px">${this._t('msg.shape_drift_detail', {}, 'The power pattern for this profile has shifted over time — possible appliance wear or maintenance needed (e.g. descaling, filter cleaning).')}</span>
|
||||
</div>`;
|
||||
})() : ''}
|
||||
${(() => {
|
||||
const adv = (this._profileAdvisories || []).find(a => a && a.profile === m.name && a.code === 'phase_inconsistent');
|
||||
if (!adv) return '';
|
||||
return `<div style="margin-top:8px;padding:8px 10px;background:color-mix(in srgb, var(--warning-color,#ff9800) 9%, transparent);border-radius:6px;border-left:3px solid var(--warning-color,#ff9800)">
|
||||
<span style="font-weight:600;color:var(--warning-color,#ff9800)">${this._t('msg.advisory_phase_inconsistent_title', {}, '⚠ Possibly mixed programs')}</span>
|
||||
<span style="font-size:.82em;opacity:.85;display:block;margin-top:4px">${_esc(this._t(adv.message_key, adv.message_params, adv.message))}</span>
|
||||
</div>`;
|
||||
})()}
|
||||
${env.avg && env.avg.length ? `<div class="wd-canvas-wrap"><canvas id="wd-env-canvas" role="img" aria-label="${_esc(this._t('lbl.aria_envelope_chart', {}, 'Profile power envelope chart'))}"></canvas></div>` : `<p class="wd-info">${this._t('msg.no_envelope', {}, 'No envelope yet - rebuild after labelling cycles.')}</p>`}`;
|
||||
} else if (m.tab === 'phases') {
|
||||
const cat = m.catalog || [];
|
||||
@@ -7852,7 +8101,7 @@ class HaWashdataPanel extends HTMLElement {
|
||||
if (!m || !m.env || !(m.env.avg || []).length) return;
|
||||
const env = m.env;
|
||||
const full = env.target_duration || env.avg[env.avg.length - 1][0];
|
||||
const bands = (m.phases || []).map((ph, i) => ({ x0: ph.start, x1: ph.end, fill: _PALETTE[i % _PALETTE.length] + '33' }));
|
||||
const bands = (m.phases || []).map((ph, i) => ({ x0: ph.start, x1: ph.end, fill: _withAlpha(_PALETTE[i % _PALETTE.length], 0.20) }));
|
||||
const vlines = [];
|
||||
(m.phases || []).forEach((ph, i) => {
|
||||
const col = _PALETTE[i % _PALETTE.length];
|
||||
@@ -9204,9 +9453,41 @@ class HaWashdataPanel extends HTMLElement {
|
||||
} else if (a === 'create-profile') {
|
||||
this._modal = { type: 'create-profile' }; this._render();
|
||||
|
||||
} else if (a === 'skip-onboarding') {
|
||||
// F1: dismiss the first-run wizard permanently for this user.
|
||||
this._setPref('onboarding_dismissed', true);
|
||||
} else if (a === 'setup-cta') {
|
||||
// Setup card primary / secondary CTA — navigate to the relevant panel section.
|
||||
const ctaAction = btn.dataset.ctaAction || '';
|
||||
let params = {};
|
||||
try { params = JSON.parse(btn.dataset.ctaParams || '{}'); } catch (_) {}
|
||||
this._dispatchSetupCta(ctaAction, params);
|
||||
|
||||
} else if (a === 'setup-skip') {
|
||||
// Setup card step skip (snooze 14 days or never).
|
||||
const stepKey = btn.dataset.step;
|
||||
const snooze = btn.dataset.snooze; // "never" or "14d"
|
||||
if (stepKey) {
|
||||
let val;
|
||||
if (snooze === 'never') {
|
||||
val = 'never';
|
||||
} else {
|
||||
const until = new Date();
|
||||
until.setDate(until.getDate() + 14);
|
||||
val = until.toISOString();
|
||||
}
|
||||
this._setPref(stepKey, val);
|
||||
this._reloadSetupStatus(); // async fire-and-forget; calls _render() when done
|
||||
}
|
||||
|
||||
} else if (a === 'hide-setup-card') {
|
||||
// Setup card permanent hide (only offered when dismissible, i.e. phase 3/4).
|
||||
// Keep _setupStatus so _htmlSetupCard can collapse to the phase-3 chip
|
||||
// immediately (nulling it here would hide the card entirely instead — the
|
||||
// sibling setup-skip / expand-setup handlers also leave the status intact).
|
||||
this._setPref('setup_card_dismissed', true);
|
||||
this._render();
|
||||
|
||||
} else if (a === 'expand-setup') {
|
||||
// Phase 3/4 chip tapped — restore full guidance card by clearing the pref.
|
||||
this._setPref('setup_card_dismissed', false);
|
||||
this._render();
|
||||
|
||||
} else if (a === 'set-settings-level') {
|
||||
@@ -9237,10 +9518,13 @@ class HaWashdataPanel extends HTMLElement {
|
||||
});
|
||||
|
||||
} else if (a === 'rebuild-envelopes') {
|
||||
this._busyRun('rebuild-envelopes', async () => {
|
||||
try { await this._ws({ type: `${_DOMAIN}/rebuild_envelopes`, entry_id: eid }); this._showToast(this._t('toast.envelopes_rebuilt', {}, 'Envelopes rebuilt')); await this._fetchProfiles(eid); }
|
||||
catch (e) { this._showToast(this._t('toast.rebuild_failed', {error: e.message || e}, 'Rebuild failed: ' + (e.message || e)), 'error'); }
|
||||
});
|
||||
// Backgrounded task (issue #311): rebuilding every profile serially can
|
||||
// stall a low-power host, so run it via the registry with a header pill.
|
||||
this._kickAndTrack(
|
||||
{ type: `${_DOMAIN}/rebuild_envelopes`, entry_id: eid },
|
||||
'rebuild-envelopes',
|
||||
async () => { this._showToast(this._t('toast.envelopes_rebuilt', {}, 'Envelopes rebuilt')); await this._fetchProfiles(eid); },
|
||||
);
|
||||
|
||||
} else if (a === 'rec-start') {
|
||||
this._ws({ type: `${_DOMAIN}/start_recording`, entry_id: eid }).then(() => { this._showToast(this._t('toast.recording_started', {}, 'Recording started')); return this._fetchRecState(eid); }).then(() => this._render()).catch(e => this._showToast(this._t('toast.start_failed', {error: e.message || e}, 'Start failed: ' + (e.message || e)), 'error'));
|
||||
@@ -9382,7 +9666,16 @@ class HaWashdataPanel extends HTMLElement {
|
||||
if (tid) this._ws({ type: `${_DOMAIN}/cancel_task`, task_id: tid }).catch(() => {});
|
||||
} else if (a === 'task-cancel') {
|
||||
const tid = btn.dataset.taskId;
|
||||
if (tid) this._ws({ type: `${_DOMAIN}/cancel_task`, task_id: tid }).catch(() => {});
|
||||
if (tid) {
|
||||
this._cancellingTasks.add(tid);
|
||||
this._updateTaskPills();
|
||||
this._ws({ type: `${_DOMAIN}/cancel_task`, task_id: tid }).catch(() => {
|
||||
// Cancel request itself failed (dropped socket, etc.) — re-enable the
|
||||
// ✕ so the user can retry instead of leaving the pill stuck "Cancelling…".
|
||||
this._cancellingTasks.delete(tid);
|
||||
this._updateTaskPills();
|
||||
});
|
||||
}
|
||||
} else if (a === 'pg-load-run') {
|
||||
const tid = btn.dataset.taskId;
|
||||
if (!tid) return;
|
||||
@@ -9817,19 +10110,34 @@ class HaWashdataPanel extends HTMLElement {
|
||||
return;
|
||||
}
|
||||
if (action === 'cyc-apply-trim') {
|
||||
// Backgrounded task (issue #311): recompute + envelope rebuild can stall a
|
||||
// low-power host, so run it via the registry with a header pill.
|
||||
const cid = m.cycleId, s = m.trim.start, e2 = m.trim.end;
|
||||
await this._busyRun('cyc-trim-apply', async () => {
|
||||
try { await this._ws({ type: `${_DOMAIN}/trim_cycle`, entry_id: eid, cycle_id: cid, start_s: s, end_s: e2 }); this._showToast(this._t('toast.cycle_trimmed', {}, 'Cycle trimmed')); await this._closeCycleDetail(eid); await this._fetchCycles(eid); }
|
||||
catch (e) { this._showToast(this._t('toast.trim_failed', {error: e.message || e}, 'Trim failed: ' + (e.message || e)), 'error'); }
|
||||
});
|
||||
this._kickAndTrack(
|
||||
{ type: `${_DOMAIN}/trim_cycle`, entry_id: eid, cycle_id: cid, start_s: s, end_s: e2 },
|
||||
'cyc-trim-apply',
|
||||
async () => {
|
||||
this._showToast(this._t('toast.cycle_trimmed', {}, 'Cycle trimmed'));
|
||||
await this._closeCycleDetail(eid);
|
||||
await this._fetchCycles(eid);
|
||||
},
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (action === 'cyc-apply-split') {
|
||||
// Backgrounded task (issue #311): per-segment extraction + affected
|
||||
// envelope rebuilds can stall a low-power host, so run it via the registry.
|
||||
const cid = m.cycleId, offs = m.split.offsets.slice(), profs = m.split.profiles.slice();
|
||||
await this._busyRun('cyc-split-apply', async () => {
|
||||
try { const r = await this._ws({ type: `${_DOMAIN}/apply_split`, entry_id: eid, cycle_id: cid, split_offsets: offs, segment_profiles: profs }); this._showToast(this._t('toast.split_complete', {count: (r.new_ids || []).length}, `Split into ${(r.new_ids || []).length} cycles`)); await this._closeCycleDetail(eid); await this._fetchCycles(eid); await this._fetchProfiles(eid); }
|
||||
catch (e) { this._showToast(this._t('toast.split_failed', {error: e.message || e}, 'Split failed: ' + (e.message || e)), 'error'); }
|
||||
});
|
||||
this._kickAndTrack(
|
||||
{ type: `${_DOMAIN}/apply_split`, entry_id: eid, cycle_id: cid, split_offsets: offs, segment_profiles: profs },
|
||||
'cyc-split-apply',
|
||||
async (result) => {
|
||||
this._showToast(this._t('toast.split_complete', {count: (result.new_ids || []).length}, `Split into ${(result.new_ids || []).length} cycles`));
|
||||
await this._closeCycleDetail(eid);
|
||||
await this._fetchCycles(eid);
|
||||
await this._fetchProfiles(eid);
|
||||
},
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -9887,10 +10195,19 @@ class HaWashdataPanel extends HTMLElement {
|
||||
return;
|
||||
}
|
||||
if (action === 'pp-rebuild') {
|
||||
await this._busyRun('pp-rebuild', async () => {
|
||||
try { await this._ws({ type: `${_DOMAIN}/rebuild_envelopes`, entry_id: eid }); const r = await this._ws({ type: `${_DOMAIN}/get_profile_envelope`, entry_id: eid, profile_name: m.name }); if (this._modal) this._modal.env = r.envelope; this._showToast(this._t('toast.envelope_rebuilt', {}, 'Envelope rebuilt')); }
|
||||
catch (e) { this._showToast(this._t('msg.toast_rebuild_failed', {error: e.message || e}, 'Rebuild failed: ' + (e.message || e)), 'error'); }
|
||||
});
|
||||
// Backgrounded task (issue #311): rebuild runs via the registry; the
|
||||
// profile's fresh envelope is fetched only once the task has settled.
|
||||
this._kickAndTrack(
|
||||
{ type: `${_DOMAIN}/rebuild_envelopes`, entry_id: eid },
|
||||
'pp-rebuild',
|
||||
async () => {
|
||||
try {
|
||||
const r = await this._ws({ type: `${_DOMAIN}/get_profile_envelope`, entry_id: eid, profile_name: m.name });
|
||||
if (this._modal) this._modal.env = r.envelope;
|
||||
} catch (_) { /* modal may have closed */ }
|
||||
this._showToast(this._t('toast.envelope_rebuilt', {}, 'Envelope rebuilt'));
|
||||
},
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (action === 'pp-delete') {
|
||||
@@ -9980,14 +10297,17 @@ class HaWashdataPanel extends HTMLElement {
|
||||
const newName = sr.getElementById('wd-merge-newname')?.value?.trim() || null;
|
||||
const ids = m.ids || [];
|
||||
this._modal = null; this._render();
|
||||
await this._busyRun('cyc-merge', async () => {
|
||||
try {
|
||||
await this._ws({ type: `${_DOMAIN}/apply_merge`, entry_id: eid, cycle_ids: ids, target_profile: target || null, new_profile_name: newName });
|
||||
// Backgrounded task (issue #311): gap-fill + affected envelope rebuilds can
|
||||
// stall a low-power host, so run it via the registry with a header pill.
|
||||
this._kickAndTrack(
|
||||
{ type: `${_DOMAIN}/apply_merge`, entry_id: eid, cycle_ids: ids, target_profile: target || null, new_profile_name: newName },
|
||||
'cyc-merge',
|
||||
async () => {
|
||||
this._showToast(this._t('toast.cycles_merged', {}, 'Cycles merged'));
|
||||
this._cycleSel.clear(); this._selectMode = false;
|
||||
await this._fetchCycles(eid); await this._fetchProfiles(eid);
|
||||
} catch (e) { this._showToast(this._t('toast.merge_failed', {error: e.message || e}, 'Merge failed: ' + (e.message || e)), 'error'); }
|
||||
});
|
||||
},
|
||||
);
|
||||
} else if (action === 'bulk-relabel-ok' && eid) {
|
||||
// D6: apply the chosen label to every selected cycle via label_cycle.
|
||||
const profileName = sr.getElementById('wd-relabel-profile')?.value || '';
|
||||
|
||||
+31
-41
@@ -19,16 +19,6 @@ export interface AnalyzeSplitResponse {
|
||||
full_duration_s: number;
|
||||
}
|
||||
|
||||
export interface ApplyMergeResponse {
|
||||
success: boolean;
|
||||
new_id: string;
|
||||
}
|
||||
|
||||
export interface ApplySplitResponse {
|
||||
success: boolean;
|
||||
new_ids: string[];
|
||||
}
|
||||
|
||||
export interface ApplySuggestionsResponse {
|
||||
success: boolean;
|
||||
applied: string[];
|
||||
@@ -263,6 +253,19 @@ export interface GetSettingsChangelogResponse {
|
||||
changelog: Record<string, unknown>[];
|
||||
}
|
||||
|
||||
export interface GetSetupStatusResponse {
|
||||
phase?: string;
|
||||
message_key?: string;
|
||||
message_params?: Record<string, unknown>;
|
||||
cta_label_key?: string;
|
||||
cta_action?: string;
|
||||
secondary_label_key?: string | null;
|
||||
secondary_action?: string | null;
|
||||
skippable?: boolean;
|
||||
dismissible?: boolean;
|
||||
step_key?: string | null;
|
||||
}
|
||||
|
||||
export interface GetShareableCyclesResponse {
|
||||
items?: unknown[];
|
||||
phase_programs?: unknown[];
|
||||
@@ -280,19 +283,6 @@ export interface OkResponse {
|
||||
ok: boolean;
|
||||
}
|
||||
|
||||
export interface PlaygroundSummary {
|
||||
cycles: number;
|
||||
requested: number;
|
||||
concurrency: number;
|
||||
detected: number;
|
||||
missed: number;
|
||||
false_end: number;
|
||||
match_correct: number;
|
||||
match_wrong: number;
|
||||
unmatched: number;
|
||||
skipped_ids: string[];
|
||||
}
|
||||
|
||||
export interface ProfileEnvelope {
|
||||
avg: number[][];
|
||||
min: number[][];
|
||||
@@ -330,11 +320,6 @@ export interface RunPlaygroundHistoryResponse {
|
||||
diff?: Record<string, string[]>;
|
||||
}
|
||||
|
||||
export interface RunPlaygroundSimulationResponse {
|
||||
results: Record<string, unknown>[];
|
||||
summary: PlaygroundSummary;
|
||||
}
|
||||
|
||||
export interface RunPlaygroundSweepResponse {
|
||||
param?: string;
|
||||
objective?: string;
|
||||
@@ -500,6 +485,10 @@ export interface GetSettingsChangelogRequest {
|
||||
entry_id: string;
|
||||
}
|
||||
|
||||
export interface GetSetupStatusRequest {
|
||||
entry_id: string;
|
||||
}
|
||||
|
||||
export interface GetProfilesRequest {
|
||||
entry_id: string;
|
||||
}
|
||||
@@ -817,13 +806,6 @@ export interface TerminateCycleRequest {
|
||||
entry_id: string;
|
||||
}
|
||||
|
||||
export interface RunPlaygroundSimulationRequest {
|
||||
entry_id: string;
|
||||
cycle_ids?: string[];
|
||||
settings_override?: Record<string, unknown>;
|
||||
concurrency?: number;
|
||||
}
|
||||
|
||||
export interface RunPlaygroundCycleDetailRequest {
|
||||
entry_id: string;
|
||||
cycle_id: string;
|
||||
@@ -885,6 +867,12 @@ export interface StartPlaygroundSweepRequest {
|
||||
values_y?: number[];
|
||||
}
|
||||
|
||||
export interface StartPlaygroundCycleDetailRequest {
|
||||
entry_id: string;
|
||||
cycle_id: string;
|
||||
settings_override?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
export interface StoreStatusRequest {
|
||||
entry_id: string;
|
||||
}
|
||||
@@ -996,6 +984,7 @@ export interface WashDataWsRequests {
|
||||
"ha_washdata/get_options": GetOptionsRequest;
|
||||
"ha_washdata/set_options": SetOptionsRequest;
|
||||
"ha_washdata/get_settings_changelog": GetSettingsChangelogRequest;
|
||||
"ha_washdata/get_setup_status": GetSetupStatusRequest;
|
||||
"ha_washdata/get_profiles": GetProfilesRequest;
|
||||
"ha_washdata/create_profile": CreateProfileRequest;
|
||||
"ha_washdata/rename_profile": RenameProfileRequest;
|
||||
@@ -1059,7 +1048,6 @@ export interface WashDataWsRequests {
|
||||
"ha_washdata/pause_cycle": PauseCycleRequest;
|
||||
"ha_washdata/resume_cycle": ResumeCycleRequest;
|
||||
"ha_washdata/terminate_cycle": TerminateCycleRequest;
|
||||
"ha_washdata/run_playground_simulation": RunPlaygroundSimulationRequest;
|
||||
"ha_washdata/run_playground_cycle_detail": RunPlaygroundCycleDetailRequest;
|
||||
"ha_washdata/run_playground_history": RunPlaygroundHistoryRequest;
|
||||
"ha_washdata/run_playground_sweep": RunPlaygroundSweepRequest;
|
||||
@@ -1070,6 +1058,7 @@ export interface WashDataWsRequests {
|
||||
"ha_washdata/get_task_result": GetTaskResultRequest;
|
||||
"ha_washdata/start_playground_history": StartPlaygroundHistoryRequest;
|
||||
"ha_washdata/start_playground_sweep": StartPlaygroundSweepRequest;
|
||||
"ha_washdata/start_playground_cycle_detail": StartPlaygroundCycleDetailRequest;
|
||||
"ha_washdata/store_status": StoreStatusRequest;
|
||||
"ha_washdata/store_connect": StoreConnectRequest;
|
||||
"ha_washdata/store_disconnect": StoreDisconnectRequest;
|
||||
@@ -1096,6 +1085,7 @@ export interface WashDataWsResponses {
|
||||
"ha_washdata/get_options": GetOptionsResponse;
|
||||
"ha_washdata/set_options": SuccessResponse;
|
||||
"ha_washdata/get_settings_changelog": GetSettingsChangelogResponse;
|
||||
"ha_washdata/get_setup_status": GetSetupStatusResponse;
|
||||
"ha_washdata/get_profiles": GetProfilesResponse;
|
||||
"ha_washdata/create_profile": CreateProfileResponse;
|
||||
"ha_washdata/rename_profile": SuccessResponse;
|
||||
@@ -1104,7 +1094,7 @@ export interface WashDataWsResponses {
|
||||
"ha_washdata/save_profile_group": SuccessResponse;
|
||||
"ha_washdata/rename_profile_group": SuccessResponse;
|
||||
"ha_washdata/delete_profile_group": SuccessResponse;
|
||||
"ha_washdata/rebuild_envelopes": SuccessResponse;
|
||||
"ha_washdata/rebuild_envelopes": StartTaskResponse;
|
||||
"ha_washdata/get_profile_phases": GetProfilePhasesResponse;
|
||||
"ha_washdata/set_profile_phases": SuccessResponse;
|
||||
"ha_washdata/get_maintenance_log": GetMaintenanceLogResponse;
|
||||
@@ -1137,10 +1127,10 @@ export interface WashDataWsResponses {
|
||||
"ha_washdata/clear_suggestions": SuccessResponse;
|
||||
"ha_washdata/run_suggestion_analysis": RunSuggestionAnalysisResponse;
|
||||
"ha_washdata/get_cycle_power_data": GetCyclePowerDataResponse;
|
||||
"ha_washdata/trim_cycle": SuccessResponse;
|
||||
"ha_washdata/trim_cycle": StartTaskResponse;
|
||||
"ha_washdata/analyze_split": AnalyzeSplitResponse;
|
||||
"ha_washdata/apply_split": ApplySplitResponse;
|
||||
"ha_washdata/apply_merge": ApplyMergeResponse;
|
||||
"ha_washdata/apply_split": StartTaskResponse;
|
||||
"ha_washdata/apply_merge": StartTaskResponse;
|
||||
"ha_washdata/get_profile_envelope": GetProfileEnvelopeResponse;
|
||||
"ha_washdata/get_profile_cycles": GetProfileCyclesResponse;
|
||||
"ha_washdata/get_panel_config": GetPanelConfigResponse;
|
||||
@@ -1159,7 +1149,6 @@ export interface WashDataWsResponses {
|
||||
"ha_washdata/pause_cycle": OkResponse;
|
||||
"ha_washdata/resume_cycle": OkResponse;
|
||||
"ha_washdata/terminate_cycle": OkResponse;
|
||||
"ha_washdata/run_playground_simulation": RunPlaygroundSimulationResponse;
|
||||
"ha_washdata/run_playground_cycle_detail": RunPlaygroundCycleDetailResponse;
|
||||
"ha_washdata/run_playground_history": RunPlaygroundHistoryResponse;
|
||||
"ha_washdata/run_playground_sweep": RunPlaygroundSweepResponse;
|
||||
@@ -1170,6 +1159,7 @@ export interface WashDataWsResponses {
|
||||
"ha_washdata/get_task_result": TaskSnapshot;
|
||||
"ha_washdata/start_playground_history": StartTaskResponse;
|
||||
"ha_washdata/start_playground_sweep": StartTaskResponse;
|
||||
"ha_washdata/start_playground_cycle_detail": StartTaskResponse;
|
||||
"ha_washdata/store_status": StoreStatusResponse;
|
||||
"ha_washdata/store_connect": StoreSimpleResponse;
|
||||
"ha_washdata/store_disconnect": StoreSimpleResponse;
|
||||
|
||||
Reference in New Issue
Block a user