291 files
This commit is contained in:
@@ -1904,6 +1904,9 @@ class AutoTpiManager:
|
||||
|
||||
async def _detect_failures(self, current_temp_in: float):
|
||||
"""Detect system failures."""
|
||||
if not self.learning_active:
|
||||
return
|
||||
|
||||
OFFSET_FAILURE = 1.0
|
||||
MIN_LEARN_FOR_DETECTION = 25
|
||||
|
||||
@@ -3119,6 +3122,7 @@ class AutoTpiManager:
|
||||
)
|
||||
# Update status to indicate learning has resumed
|
||||
self.state.last_learning_status = "learning_resumed"
|
||||
self.state.consecutive_failures = 0
|
||||
|
||||
# Always enable learning when activating
|
||||
self.state.autolearn_enabled = True
|
||||
|
||||
@@ -899,9 +899,16 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
|
||||
# transform _attr_preset_modes into _vtherm_preset_modes
|
||||
self._vtherm_preset_modes = [VThermPreset(mode) for mode in self._attr_preset_modes]
|
||||
|
||||
# Re-applicate the last preset if any to take change into account
|
||||
if self._state_manager.current_state.preset and self._state_manager.current_state.preset != VThermPreset.NONE:
|
||||
await self.async_set_preset_mode_internal(self._state_manager.current_state.preset)
|
||||
# Re-apply the requested visible preset, if it is still configured.
|
||||
# The current preset can be a temporary hidden override (safety/power)
|
||||
# and must never become the requested user preset during initialization.
|
||||
requested_preset = self._state_manager.requested_state.preset
|
||||
if (
|
||||
requested_preset != VThermPreset.NONE
|
||||
and requested_preset in self._vtherm_preset_modes
|
||||
and requested_preset not in HIDDEN_PRESETS
|
||||
):
|
||||
await self.async_set_preset_mode_internal(requested_preset)
|
||||
|
||||
##
|
||||
## Properties overriden from ClimateEntity (or not)
|
||||
@@ -2291,9 +2298,9 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
|
||||
|
||||
async def service_set_safety(
|
||||
self,
|
||||
delay_min: int,
|
||||
min_on_percent: float,
|
||||
default_on_percent: float,
|
||||
delay_min: int | None = None,
|
||||
min_on_percent: float | None = None,
|
||||
default_on_percent: float | None = None,
|
||||
):
|
||||
"""Called by a service call:
|
||||
service: versatile_thermostat.set_safety
|
||||
@@ -2307,13 +2314,17 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
|
||||
if self.lock_manager.check_is_locked("service_set_safety"):
|
||||
return
|
||||
write_event_log(
|
||||
_LOGGER, self, f"Calling SERVICE_SET_SAFETY, delay_min: {delay_min}, " f"min_on_percent: {min_on_percent * 100} %, default_on_percent: {default_on_percent * 100} %"
|
||||
_LOGGER,
|
||||
self,
|
||||
f"Calling SERVICE_SET_SAFETY, delay_min: {delay_min}, "
|
||||
f"min_on_percent: {min_on_percent * 100 if min_on_percent is not None else 'unchanged'} %, "
|
||||
f"default_on_percent: {default_on_percent * 100 if default_on_percent is not None else 'unchanged'} %",
|
||||
)
|
||||
if delay_min:
|
||||
if delay_min is not None:
|
||||
self._safety_manager.set_safety_delay_min(delay_min)
|
||||
if min_on_percent:
|
||||
if min_on_percent is not None:
|
||||
self._safety_manager.set_safety_min_on_percent(min_on_percent)
|
||||
if default_on_percent:
|
||||
if default_on_percent is not None:
|
||||
self._safety_manager.set_safety_default_on_percent(default_on_percent)
|
||||
|
||||
await self.async_control_heating()
|
||||
|
||||
@@ -418,24 +418,27 @@ class FeatureCentralBoilerManager(BaseFeatureManager):
|
||||
if self._is_configured and not force:
|
||||
return self._all_boiler_entities
|
||||
|
||||
required_entities = {
|
||||
"number activation threshold": self._nb_active_device_threshold_number_entity,
|
||||
"power activation threshold": self._total_power_active_threshold_number_entity,
|
||||
"number of active devices": self._nb_active_device_number_entity,
|
||||
"total active power": self._total_power_active_entity,
|
||||
}
|
||||
self._all_boiler_entities = []
|
||||
if self._nb_active_device_threshold_number_entity:
|
||||
self._all_boiler_entities.append(self._nb_active_device_threshold_number_entity.entity_id)
|
||||
if self._total_power_active_threshold_number_entity:
|
||||
self._all_boiler_entities.append(self._total_power_active_threshold_number_entity.entity_id)
|
||||
if self._nb_active_device_number_entity:
|
||||
self._all_boiler_entities.append(self._nb_active_device_number_entity.entity_id)
|
||||
if self._total_power_active_entity:
|
||||
self._all_boiler_entities.append(self._total_power_active_entity.entity_id)
|
||||
for entity in required_entities.values():
|
||||
if entity:
|
||||
self._all_boiler_entities.append(entity.entity_id)
|
||||
|
||||
old_ready = self._is_ready
|
||||
self._is_ready = self.is_configured and len(self._all_boiler_entities) == 4 and self._central_boiler_entity is not None
|
||||
if not self._is_ready and self.is_configured:
|
||||
missing_entities = [name for name, entity in required_entities.items() if entity is None]
|
||||
_LOGGER.warning(
|
||||
"%s - central boiler manager is not fully configured. Found only %d/4 entities and central boiler entity=%s. Central boiler control will not work properly. This could a temporary message at startup.",
|
||||
"%s - central boiler manager is not fully configured. Found only %d/4 entities and central boiler entity=%s. Missing entities: %s. Central boiler control will not work properly. This could a temporary message at startup.",
|
||||
self,
|
||||
len(self._all_boiler_entities),
|
||||
self._central_boiler_entity,
|
||||
", ".join(missing_entities) or "none",
|
||||
)
|
||||
return []
|
||||
if not self._is_ready and not self.is_configured:
|
||||
|
||||
@@ -22,6 +22,6 @@
|
||||
"vtherm_api>=0.5.0"
|
||||
],
|
||||
"ssdp": [],
|
||||
"version": "10.5.0",
|
||||
"version": "10.5.1",
|
||||
"zeroconf": []
|
||||
}
|
||||
|
||||
@@ -151,10 +151,11 @@ async def async_setup_entry(
|
||||
class EnergySensor(VersatileThermostatBaseEntity, SensorEntity):
|
||||
"""Representation of a Energy sensor which exposes the energy"""
|
||||
|
||||
_attr_translation_key = "energy"
|
||||
|
||||
def __init__(self, hass: HomeAssistant, unique_id, name, entry_infos) -> None:
|
||||
"""Initialize the energy sensor"""
|
||||
super().__init__(hass, unique_id, entry_infos.get(CONF_NAME))
|
||||
self._attr_name = "Energy"
|
||||
self._attr_unique_id = f"{self._device_name}_energy"
|
||||
|
||||
@callback
|
||||
@@ -210,10 +211,11 @@ class EnergySensor(VersatileThermostatBaseEntity, SensorEntity):
|
||||
class MeanPowerSensor(VersatileThermostatBaseEntity, SensorEntity):
|
||||
"""Representation of a power sensor which exposes the mean power in a cycle"""
|
||||
|
||||
_attr_translation_key = "mean_power_cycle"
|
||||
|
||||
def __init__(self, hass: HomeAssistant, unique_id, name, entry_infos) -> None:
|
||||
"""Initialize the energy sensor"""
|
||||
super().__init__(hass, unique_id, entry_infos.get(CONF_NAME))
|
||||
self._attr_name = "Mean power cycle"
|
||||
self._attr_unique_id = f"{self._device_name}_mean_power_cycle"
|
||||
|
||||
@callback
|
||||
@@ -272,10 +274,11 @@ class MeanPowerSensor(VersatileThermostatBaseEntity, SensorEntity):
|
||||
class OnPercentSensor(VersatileThermostatBaseEntity, SensorEntity):
|
||||
"""Representation of a on percent sensor which exposes the on_percent in a cycle"""
|
||||
|
||||
_attr_translation_key = "power_percent"
|
||||
|
||||
def __init__(self, hass: HomeAssistant, unique_id, name, entry_infos) -> None:
|
||||
"""Initialize the energy sensor"""
|
||||
super().__init__(hass, unique_id, entry_infos.get(CONF_NAME))
|
||||
self._attr_name = "Power percent"
|
||||
self._attr_unique_id = f"{self._device_name}_power_percent"
|
||||
|
||||
@callback
|
||||
@@ -330,10 +333,11 @@ class OnPercentSensor(VersatileThermostatBaseEntity, SensorEntity):
|
||||
class AutoTpiSensor(VersatileThermostatBaseEntity, SensorEntity):
|
||||
"""Representation of the Auto TPI Learning state"""
|
||||
|
||||
_attr_translation_key = "auto_tpi_learning"
|
||||
|
||||
def __init__(self, hass: HomeAssistant, unique_id, name, entry_infos) -> None:
|
||||
"""Initialize the Auto TPI sensor"""
|
||||
super().__init__(hass, unique_id, entry_infos.get(CONF_NAME))
|
||||
self._attr_name = "Auto TPI Learning State"
|
||||
self._attr_unique_id = f"{self._device_name}_auto_tpi_learning"
|
||||
self._attr_icon = "mdi:brain"
|
||||
|
||||
@@ -358,11 +362,11 @@ class AutoTpiSensor(VersatileThermostatBaseEntity, SensorEntity):
|
||||
# Determine state
|
||||
if manager.learning_active:
|
||||
if manager.is_in_bootstrap:
|
||||
self._attr_native_value = "Bootstrap"
|
||||
self._attr_native_value = "bootstrap"
|
||||
else:
|
||||
self._attr_native_value = "Active"
|
||||
self._attr_native_value = "active"
|
||||
else:
|
||||
self._attr_native_value = "Off" # Or "Completed" / "Idle" depending on context, but "Off" implies not learning.
|
||||
self._attr_native_value = "off" # Or "Completed" / "Idle" depending on context, but "Off" implies not learning.
|
||||
|
||||
# Update attributes
|
||||
# Update attributes
|
||||
@@ -405,10 +409,11 @@ class AutoTpiSensor(VersatileThermostatBaseEntity, SensorEntity):
|
||||
class ValveOpenPercentSensor(VersatileThermostatBaseEntity, SensorEntity):
|
||||
"""Representation of a on percent sensor which exposes the on_percent in a cycle"""
|
||||
|
||||
_attr_translation_key = "valve_open_percent"
|
||||
|
||||
def __init__(self, hass: HomeAssistant, unique_id, name, entry_infos) -> None:
|
||||
"""Initialize the energy sensor"""
|
||||
super().__init__(hass, unique_id, entry_infos.get(CONF_NAME))
|
||||
self._attr_name = "Valve open percent"
|
||||
self._attr_unique_id = f"{self._device_name}_valve_open_percent"
|
||||
|
||||
@callback
|
||||
@@ -451,10 +456,11 @@ class ValveOpenPercentSensor(VersatileThermostatBaseEntity, SensorEntity):
|
||||
class OnTimeSensor(VersatileThermostatBaseEntity, SensorEntity):
|
||||
"""Representation of a on time sensor which exposes the on_time_sec in a cycle"""
|
||||
|
||||
_attr_translation_key = "on_time"
|
||||
|
||||
def __init__(self, hass: HomeAssistant, unique_id, name, entry_infos) -> None:
|
||||
"""Initialize the energy sensor"""
|
||||
super().__init__(hass, unique_id, entry_infos.get(CONF_NAME))
|
||||
self._attr_name = "On time"
|
||||
self._attr_unique_id = f"{self._device_name}_on_time"
|
||||
|
||||
@callback
|
||||
@@ -500,10 +506,11 @@ class OnTimeSensor(VersatileThermostatBaseEntity, SensorEntity):
|
||||
class OffTimeSensor(VersatileThermostatBaseEntity, SensorEntity):
|
||||
"""Representation of a on time sensor which exposes the off_time_sec in a cycle"""
|
||||
|
||||
_attr_translation_key = "off_time"
|
||||
|
||||
def __init__(self, hass: HomeAssistant, unique_id, name, entry_infos) -> None:
|
||||
"""Initialize the energy sensor"""
|
||||
super().__init__(hass, unique_id, entry_infos.get(CONF_NAME))
|
||||
self._attr_name = "Off time"
|
||||
self._attr_unique_id = f"{self._device_name}_off_time"
|
||||
|
||||
@callback
|
||||
@@ -548,10 +555,11 @@ class OffTimeSensor(VersatileThermostatBaseEntity, SensorEntity):
|
||||
class LastTemperatureSensor(VersatileThermostatBaseEntity, SensorEntity):
|
||||
"""Representation of a last temperature datetime sensor"""
|
||||
|
||||
_attr_translation_key = "last_temperature_date"
|
||||
|
||||
def __init__(self, hass: HomeAssistant, unique_id, name, entry_infos) -> None:
|
||||
"""Initialize the last temperature datetime sensor"""
|
||||
super().__init__(hass, unique_id, entry_infos.get(CONF_NAME))
|
||||
self._attr_name = "Last temperature date"
|
||||
self._attr_entity_registry_enabled_default = False
|
||||
self._attr_unique_id = f"{self._device_name}_last_temp_datetime"
|
||||
|
||||
@@ -578,10 +586,11 @@ class LastTemperatureSensor(VersatileThermostatBaseEntity, SensorEntity):
|
||||
class LastExtTemperatureSensor(VersatileThermostatBaseEntity, SensorEntity):
|
||||
"""Representation of a last external temperature datetime sensor"""
|
||||
|
||||
_attr_translation_key = "last_external_temperature_date"
|
||||
|
||||
def __init__(self, hass: HomeAssistant, unique_id, name, entry_infos) -> None:
|
||||
"""Initialize the last temperature datetime sensor"""
|
||||
super().__init__(hass, unique_id, entry_infos.get(CONF_NAME))
|
||||
self._attr_name = "Last external temperature date"
|
||||
self._attr_entity_registry_enabled_default = False
|
||||
self._attr_unique_id = f"{self._device_name}_last_ext_temp_datetime"
|
||||
|
||||
@@ -608,10 +617,11 @@ class LastExtTemperatureSensor(VersatileThermostatBaseEntity, SensorEntity):
|
||||
class TemperatureSlopeSensor(VersatileThermostatBaseEntity, SensorEntity):
|
||||
"""Representation of a sensor which exposes the temperature slope curve"""
|
||||
|
||||
_attr_translation_key = "temperature_slope"
|
||||
|
||||
def __init__(self, hass: HomeAssistant, unique_id, name, entry_infos) -> None:
|
||||
"""Initialize the slope sensor"""
|
||||
super().__init__(hass, unique_id, entry_infos.get(CONF_NAME))
|
||||
self._attr_name = "Temperature slope"
|
||||
self._attr_unique_id = f"{self._device_name}_temperature_slope"
|
||||
|
||||
@callback
|
||||
@@ -665,10 +675,11 @@ class TemperatureSlopeSensor(VersatileThermostatBaseEntity, SensorEntity):
|
||||
class RegulatedTemperatureSensor(VersatileThermostatBaseEntity, SensorEntity):
|
||||
"""Representation of a Energy sensor which exposes the energy"""
|
||||
|
||||
_attr_translation_key = "regulated_temperature"
|
||||
|
||||
def __init__(self, hass: HomeAssistant, unique_id, name, entry_infos) -> None:
|
||||
"""Initialize the regulated temperature sensor"""
|
||||
super().__init__(hass, unique_id, entry_infos.get(CONF_NAME))
|
||||
self._attr_name = "Regulated temperature"
|
||||
self._attr_unique_id = f"{self._device_name}_regulated_temperature"
|
||||
|
||||
@callback
|
||||
@@ -716,10 +727,11 @@ class RegulatedTemperatureSensor(VersatileThermostatBaseEntity, SensorEntity):
|
||||
class EMATemperatureSensor(VersatileThermostatBaseEntity, SensorEntity):
|
||||
"""Representation of a Exponential Moving Average temp"""
|
||||
|
||||
_attr_translation_key = "ema_temperature"
|
||||
|
||||
def __init__(self, hass: HomeAssistant, unique_id, name, entry_infos) -> None:
|
||||
"""Initialize the regulated temperature sensor"""
|
||||
super().__init__(hass, unique_id, entry_infos.get(CONF_NAME))
|
||||
self._attr_name = "EMA temperature"
|
||||
self._attr_unique_id = f"{self._device_name}_ema_temperature"
|
||||
|
||||
@callback
|
||||
@@ -768,6 +780,10 @@ class NbActiveDeviceForBoilerSensor(SensorEntity):
|
||||
"""Representation of the number of VTherm
|
||||
which are active and configured to activate the boiler"""
|
||||
|
||||
|
||||
_attr_has_entity_name = True
|
||||
_attr_translation_key = "nb_device_active_boiler"
|
||||
|
||||
# TODO remove all listener mecanisms
|
||||
_entity_component_unrecorded_attributes = SensorEntity._entity_component_unrecorded_attributes.union( # pylint: disable=protected-access
|
||||
frozenset({"active_device_ids"})
|
||||
@@ -778,7 +794,6 @@ class NbActiveDeviceForBoilerSensor(SensorEntity):
|
||||
self._hass = hass
|
||||
self._config_id = unique_id
|
||||
self._device_name = entry_infos.get(CONF_NAME)
|
||||
self._attr_name = "Nb device active for boiler"
|
||||
self._attr_unique_id = "nb_device_active_boiler"
|
||||
self._attr_value = self._attr_native_value = None # default value
|
||||
self._entities = []
|
||||
@@ -951,10 +966,11 @@ class TotalPowerActiveDeviceForBoilerSensor(NbActiveDeviceForBoilerSensor):
|
||||
"""Representation of the total power of VTherm
|
||||
which are active and configured to activate the boiler"""
|
||||
|
||||
_attr_translation_key = "total_power_active_boiler"
|
||||
|
||||
def __init__(self, hass: HomeAssistant, unique_id, name, entry_infos) -> None:
|
||||
"""Initialize the energy sensor"""
|
||||
super().__init__(hass, unique_id, name, entry_infos)
|
||||
self._attr_name = "Total power active for boiler"
|
||||
self._attr_unique_id = "total_power_active_boiler"
|
||||
self._attr_value = self._attr_native_value = None # default value
|
||||
self._cancel_listener_power: callable | None = None
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -151,7 +151,7 @@ class ThermostatOverClimateValve(ThermostatProp[UnderlyingClimate], ThermostatOv
|
||||
for under in self._underlyings_valve_regulation:
|
||||
_LOGGER.debug("%s - starting underlying valve regulation %s", self, under)
|
||||
try:
|
||||
under.startup()
|
||||
await under.async_startup()
|
||||
_LOGGER.debug("%s - underlying valve regulation %s started successfully", self, under)
|
||||
except Exception as ex: # pylint: disable=broad-except
|
||||
_LOGGER.error("%s - Error starting underlying valve regulation %s: %s", self, under, ex)
|
||||
@@ -190,6 +190,7 @@ class ThermostatOverClimateValve(ThermostatProp[UnderlyingClimate], ThermostatOv
|
||||
"last_sent_opening_value": under.last_sent_opening_value,
|
||||
"min_opening_degree": under._min_opening_degree, # pylint: disable=protected-access
|
||||
"max_opening_degree": under._max_opening_degree, # pylint: disable=protected-access
|
||||
**under.bootstrap_diagnostics,
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
@@ -358,6 +358,7 @@
|
||||
"heater_heating_time": "Doba ohřevu (min)",
|
||||
"heater_cooling_time": "Doba chlazení (min)",
|
||||
"auto_tpi_heating_rate": "Rychlost ohřevu ({unit}/h)",
|
||||
"auto_tpi_cooling_rate": "Rychlost chlazení ({unit}/h)",
|
||||
"auto_tpi_aggressiveness": "Agresivita",
|
||||
"auto_tpi_enable_advanced_settings": "Povolit pokročilé parametry",
|
||||
"auto_tpi_continuous_kext": "Průběžné učení Kext"
|
||||
@@ -367,6 +368,7 @@
|
||||
"heater_heating_time": "Čas k dosažení plného výkonu (minuty)",
|
||||
"heater_cooling_time": "Čas na ochlazení po zastavení (minuty)\n\n| Typ | Doba ohřevu | Doba chlazení |\n| :--- | :--- | :--- |\n| Elektrický radiátor | 5 min | 7mn |\n| Vodní radiátor | 15 minut | 20 min |\n| Podlahové vytápění | 30 min | 45 min |",
|
||||
"auto_tpi_heating_rate": "Kapacita nárůstu teploty radiátoru ({unit} za hodinu). Ponechejte na 0 pro automatické učení (bootstrap).",
|
||||
"auto_tpi_cooling_rate": "Kapacita poklesu teploty radiátoru ({unit} za hodinu). Ponechejte na 0 pro automatické učení (bootstrap).",
|
||||
"auto_tpi_aggressiveness": "Redukční faktor pro naučené koeficienty (50-100%). Nižší hodnoty vedou ke konzervativnějším koeficientům a snižují riziko přestřelení.",
|
||||
"auto_tpi_enable_advanced_settings": "Zaškrtněte pro přístup k jemnému doladění parametrů (Alpha, Decay, Weight).",
|
||||
"auto_tpi_continuous_kext": "Zaškrtnutím povolíte průběžné učení externího koeficientu (Kext) mimo relace AutoTPI."
|
||||
@@ -768,6 +770,7 @@
|
||||
"data": {
|
||||
"auto_tpi_learning_type": "Typ učení",
|
||||
"auto_tpi_heating_rate": "Rychlost ohřevu ({unit}/h)",
|
||||
"auto_tpi_cooling_rate": "Rychlost chlazení ({unit}/h)",
|
||||
"heater_heating_time": "Doba ohřevu (min)",
|
||||
"heater_cooling_time": "Doba chlazení (min)",
|
||||
"auto_tpi_aggressiveness": "Agresivita",
|
||||
@@ -777,6 +780,7 @@
|
||||
"data_description": {
|
||||
"auto_tpi_learning_type": "Zvolte 'Discovery' pro počáteční spuštění (vážený průměr, váha 1) nebo 'Fine Tuning' pro průběžné úpravy (EWMA, Alpha 0,08).",
|
||||
"auto_tpi_heating_rate": "Kapacita nárůstu teploty radiátoru ({unit} za hodinu). Ponechejte na 0 pro automatické učení (bootstrap).",
|
||||
"auto_tpi_cooling_rate": "Kapacita poklesu teploty radiátoru ({unit} za hodinu). Ponechejte na 0 pro automatické učení (bootstrap).",
|
||||
"heater_heating_time": "Čas k dosažení plného výkonu (minuty)",
|
||||
"heater_cooling_time": "Čas na ochlazení po zastavení (minuty)\n\n| Typ | Doba ohřevu | Doba chlazení |\n| :--- | :--- | :--- |\n| Elektrický radiátor | 5 min | 7mn |\n| Vodní radiátor | 15 minut | 20 min |\n| Podlahové vytápění | 30 min | 45 min |",
|
||||
"auto_tpi_aggressiveness": "Redukční faktor pro naučené koeficienty (50-100%). Nižší hodnoty vedou ke konzervativnějším koeficientům a snižují riziko přestřelení.",
|
||||
|
||||
@@ -312,6 +312,7 @@
|
||||
"heater_heating_time": "Aufheizzeit (min)",
|
||||
"heater_cooling_time": "Auskühlzeit (min)",
|
||||
"auto_tpi_heating_rate": "Aufheizgeschwindigkeit ({unit}/h)",
|
||||
"auto_tpi_cooling_rate": "Abkühlrate ({unit}/h)",
|
||||
"auto_tpi_aggressiveness": "Aggressivität",
|
||||
"auto_tpi_enable_advanced_settings": "Erweiterte Einstellungen aktivieren",
|
||||
"auto_tpi_continuous_kext": "Kontinuierliches Kext-lernen"
|
||||
@@ -321,6 +322,7 @@
|
||||
"heater_heating_time": "Zeit bis zum Erreichen der vollen Leistung (Minuten)",
|
||||
"heater_cooling_time": "Abkühlzeit nach dem Ausschalten (Minuten)\n\n| Typ | Aufheizzeit | Abkühlzeit |\n| :--- | :--- | :--- |\n| Elektroheizkörper | 5 Min. | 7 Min. |\n| Wasserheizkörper | 15 Min. | 20 Min. |\n| Fußbodenheizung | 30 Min. | 45 Min. |",
|
||||
"auto_tpi_heating_rate": "Temperaturanstiegskapazität des Heizkörpers ({unit} pro Stunde). Kann über den Aktionsdienst 'Kapazität kalibrieren' geschätzt werden.",
|
||||
"auto_tpi_cooling_rate": "Abkühlleistung des Heizkörpers ({unit} pro Stunde). Für automatisches Lernen (Bootstrap) auf 0 belassen.",
|
||||
"auto_tpi_aggressiveness": "Skalierungsfaktor für die gelernten Koeffizienten (50-100 %). Niedrigere Werte führen zu konservativeren Koeffizienten und verringern das Risiko einer Überschreitung des Sollwerts.",
|
||||
"auto_tpi_enable_advanced_settings": "Option anwählen, um die Feinabstimmung der Parameter (Alpha, Abklingen, Gewicht) vorzunehmen.",
|
||||
"auto_tpi_continuous_kext": "Kontrollkästchen aktivieren, um das kontinuierliche Lernen des externen Koeffizienten (Kext) außerhalb von AutoTPI-Sitzungen zu ermöglichen."
|
||||
@@ -746,6 +748,7 @@
|
||||
"data": {
|
||||
"auto_tpi_learning_type": "Art des Lernens",
|
||||
"auto_tpi_heating_rate": "Aufheizrate ({unit}/h)",
|
||||
"auto_tpi_cooling_rate": "Abkühlrate ({unit}/h)",
|
||||
"heater_heating_time": "Aufheizzeit (min)",
|
||||
"heater_cooling_time": "Abkühlzeit (min)",
|
||||
"auto_tpi_aggressiveness": "Aggressivität",
|
||||
@@ -755,6 +758,7 @@
|
||||
"data_description": {
|
||||
"auto_tpi_learning_type": "Wähle 'Erkundung' für den ersten Start (gewichteter Durchschnitt, Gewicht 1) oder 'Feinabstimmung' für kontinuierliche Anpassungen (EWMA, Alpha 0,08).",
|
||||
"auto_tpi_heating_rate": "Temperaturanstiegskapazität des Heizkörpers ({unit} pro Stunde). Kann über den Aktionsdienst 'Kapazität kalibrieren' geschätzt werden.",
|
||||
"auto_tpi_cooling_rate": "Abkühlleistung des Heizkörpers ({unit} pro Stunde). Für automatisches Lernen (Bootstrap) auf 0 belassen.",
|
||||
"heater_heating_time": "Zeit bis zum Erreichen der vollen Leistung (Minuten)",
|
||||
"heater_cooling_time": "Abkühlzeit nach dem Ausschalten (Minuten)\n\n| Typ | Aufheizzeit | Abkühlzeit |\n| :--- | :--- | :--- |\n| Elektroheizkörper | 5 Min. | 7 Min. |\n| Wasserheizkörper | 15 Min. | 20 Min. |\n| Fußbodenheizung | 30 Min. | 45 Min. |",
|
||||
"auto_tpi_aggressiveness": "Skalierungsfaktor für die gelernten Koeffizienten (50–100 %). Niedrigere Werte führen zu konservativeren Koeffizienten und verringern das Risiko einer Überschreitung des Sollwerts.",
|
||||
@@ -948,6 +952,56 @@
|
||||
"name": "Zentralheizungskessel"
|
||||
}
|
||||
},
|
||||
"sensor": {
|
||||
"energy": {
|
||||
"name": "Energie"
|
||||
},
|
||||
"mean_power_cycle": {
|
||||
"name": "Mittlere Zyklusleistung"
|
||||
},
|
||||
"power_percent": {
|
||||
"name": "Leistungsanteil"
|
||||
},
|
||||
"auto_tpi_learning": {
|
||||
"name": "Auto-TPI-Lernstatus",
|
||||
"state": {
|
||||
"disabled": "Deaktiviert",
|
||||
"bootstrap": "Initialisierung",
|
||||
"active": "Aktiv",
|
||||
"off": "Aus"
|
||||
}
|
||||
},
|
||||
"valve_open_percent": {
|
||||
"name": "Ventilöffnungsgrad"
|
||||
},
|
||||
"on_time": {
|
||||
"name": "Einschaltzeit"
|
||||
},
|
||||
"off_time": {
|
||||
"name": "Ausschaltzeit"
|
||||
},
|
||||
"last_temperature_date": {
|
||||
"name": "Zeitpunkt der letzten Temperaturmessung"
|
||||
},
|
||||
"last_external_temperature_date": {
|
||||
"name": "Zeitpunkt der letzten Außentemperaturmessung"
|
||||
},
|
||||
"temperature_slope": {
|
||||
"name": "Temperaturänderungsrate"
|
||||
},
|
||||
"regulated_temperature": {
|
||||
"name": "Geregelte Temperatur"
|
||||
},
|
||||
"ema_temperature": {
|
||||
"name": "EMA-Temperatur"
|
||||
},
|
||||
"nb_device_active_boiler": {
|
||||
"name": "Anzahl aktiver Geräte für Heizkessel"
|
||||
},
|
||||
"total_power_active_boiler": {
|
||||
"name": "Gesamte aktive Leistung für Heizkessel"
|
||||
}
|
||||
},
|
||||
"number": {
|
||||
"frost_temp": {
|
||||
"name": "Frostschutz"
|
||||
|
||||
@@ -248,6 +248,14 @@
|
||||
"max_closing_degree": "Μέγιστη τιμή του βαθμού κλεισίματος. Η βαλβίδα δεν θα κλείσει ποτέ περισσότερο από αυτήν την τιμή. Ορίστε το στο 100 για πλήρες κλείσιμο της βαλβίδας"
|
||||
}
|
||||
},
|
||||
"auto_tpi_configuration": {
|
||||
"data": {
|
||||
"auto_tpi_cooling_rate": "Ρυθμός ψύξης ({unit}/h)"
|
||||
},
|
||||
"data_description": {
|
||||
"auto_tpi_cooling_rate": "Ικανότητα ψύξης του καλοριφέρ ({unit} ανά ώρα). Αφήστε την τιμή στο 0 για αυτόματη εκμάθηση (bootstrap)."
|
||||
}
|
||||
},
|
||||
"heating_failure_detection": {
|
||||
"title": "Heating failure detection",
|
||||
"description": "Configure the heating failure detection feature. This detects anomalies when heating is expected but temperature doesn't increase, or when heating is off but temperature keeps rising.",
|
||||
@@ -525,6 +533,14 @@
|
||||
"max_closing_degree": "Μέγιστη τιμή του βαθμού κλεισίματος. Η βαλβίδα δεν θα κλείσει ποτέ περισσότερο από αυτήν την τιμή. Ορίστε το στο 100 για πλήρες κλείσιμο της βαλβίδας"
|
||||
}
|
||||
},
|
||||
"auto_tpi_configuration": {
|
||||
"data": {
|
||||
"auto_tpi_cooling_rate": "Ρυθμός ψύξης ({unit}/h)"
|
||||
},
|
||||
"data_description": {
|
||||
"auto_tpi_cooling_rate": "Ικανότητα ψύξης του καλοριφέρ ({unit} ανά ώρα). Αφήστε την τιμή στο 0 για αυτόματη εκμάθηση (bootstrap)."
|
||||
}
|
||||
},
|
||||
"heating_failure_detection": {
|
||||
"title": "Heating failure detection",
|
||||
"description": "Configure the heating failure detection feature. This detects anomalies when heating is expected but temperature doesn't increase, or when heating is off but temperature keeps rising.",
|
||||
@@ -628,4 +644,4 @@
|
||||
"description": "Θέτει ένα VTherm σε εποχική αναστολή. Εμφανίζεται ως απενεργοποιημένο και, για over_climate με άμεσο έλεγχο βαλβίδας και over_valve, στέλνει ακατέργαστο αίτημα ανοίγματος βαλβίδας 100%. Το φυσικό άνοιγμα εξακολουθεί να υπόκειται στον ρυθμισμένο έλεγχο βαλβίδας και στα όρια της οντότητας number."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -312,6 +312,7 @@
|
||||
"heater_heating_time": "Heating time (min)",
|
||||
"heater_cooling_time": "Cooling time (min)",
|
||||
"auto_tpi_heating_rate": "Heating Rate ({unit}/h)",
|
||||
"auto_tpi_cooling_rate": "Cooling Rate ({unit}/h)",
|
||||
"auto_tpi_aggressiveness": "Aggressiveness",
|
||||
"auto_tpi_enable_advanced_settings": "Enable Advanced Parameters",
|
||||
"auto_tpi_continuous_kext": "Continuous Kext Learning"
|
||||
@@ -321,6 +322,7 @@
|
||||
"heater_heating_time": "Time to reach full power (minutes)",
|
||||
"heater_cooling_time": "Time to cool down after stop (minutes)\n\n| Type | Heating time | Cooling time |\n| :--- | :--- | :--- |\n| Electric radiator | 5mn | 7mn |\n| Water radiator | 15mn | 20mn |\n| Underfloor heating | 30mn | 45mn |",
|
||||
"auto_tpi_heating_rate": "Radiator temperature rise capacity ({unit} per hour). Leave at 0 for automatic learning (bootstrap).",
|
||||
"auto_tpi_cooling_rate": "Radiator temperature cooling capacity ({unit} per hour). Leave at 0 for automatic learning (bootstrap).",
|
||||
"auto_tpi_aggressiveness": "Reduction factor for learned coefficients (50-100%). Lower values result in more conservative coefficients and reduce overshoot risk.",
|
||||
"auto_tpi_enable_advanced_settings": "Check to access parameter fine-tuning (Alpha, Decay, Weight).",
|
||||
"auto_tpi_continuous_kext": "Check to enable continuous learning of the external coefficient (Kext) outside of AutoTPI sessions."
|
||||
@@ -746,6 +748,7 @@
|
||||
"data": {
|
||||
"auto_tpi_learning_type": "Learning Type",
|
||||
"auto_tpi_heating_rate": "Heating Rate ({unit}/h)",
|
||||
"auto_tpi_cooling_rate": "Cooling Rate ({unit}/h)",
|
||||
"heater_heating_time": "Heating time (min)",
|
||||
"heater_cooling_time": "Cooling time (min)",
|
||||
"auto_tpi_aggressiveness": "Aggressiveness",
|
||||
@@ -755,6 +758,7 @@
|
||||
"data_description": {
|
||||
"auto_tpi_learning_type": "Choose 'Discovery' for initial startup (Weighted Average, weight 1) or 'Fine Tuning' for continuous adjustments (EWMA, Alpha 0.08).",
|
||||
"auto_tpi_heating_rate": "Radiator temperature rise capacity ({unit} per hour). Leave at 0 for automatic learning (bootstrap).",
|
||||
"auto_tpi_cooling_rate": "Radiator temperature cooling capacity ({unit} per hour). Leave at 0 for automatic learning (bootstrap).",
|
||||
"heater_heating_time": "Time to reach full power (minutes)",
|
||||
"heater_cooling_time": "Time to cool down after stop (minutes)\n\n| Type | Heating time | Cooling time |\n| :--- | :--- | :--- |\n| Electric radiator | 5mn | 7mn |\n| Water radiator | 15mn | 20mn |\n| Underfloor heating | 30mn | 45mn |",
|
||||
"auto_tpi_aggressiveness": "Reduction factor for learned coefficients (50-100%). Lower values result in more conservative coefficients and reduce overshoot risk.",
|
||||
@@ -948,6 +952,56 @@
|
||||
"name": "Central boiler"
|
||||
}
|
||||
},
|
||||
"sensor": {
|
||||
"energy": {
|
||||
"name": "Energy"
|
||||
},
|
||||
"mean_power_cycle": {
|
||||
"name": "Mean power cycle"
|
||||
},
|
||||
"power_percent": {
|
||||
"name": "Power percent"
|
||||
},
|
||||
"auto_tpi_learning": {
|
||||
"name": "Auto TPI Learning State",
|
||||
"state": {
|
||||
"disabled": "Disabled",
|
||||
"bootstrap": "Bootstrap",
|
||||
"active": "Active",
|
||||
"off": "Off"
|
||||
}
|
||||
},
|
||||
"valve_open_percent": {
|
||||
"name": "Valve open percent"
|
||||
},
|
||||
"on_time": {
|
||||
"name": "On time"
|
||||
},
|
||||
"off_time": {
|
||||
"name": "Off time"
|
||||
},
|
||||
"last_temperature_date": {
|
||||
"name": "Last temperature date"
|
||||
},
|
||||
"last_external_temperature_date": {
|
||||
"name": "Last external temperature date"
|
||||
},
|
||||
"temperature_slope": {
|
||||
"name": "Temperature slope"
|
||||
},
|
||||
"regulated_temperature": {
|
||||
"name": "Regulated temperature"
|
||||
},
|
||||
"ema_temperature": {
|
||||
"name": "EMA temperature"
|
||||
},
|
||||
"nb_device_active_boiler": {
|
||||
"name": "Number of active devices for boiler"
|
||||
},
|
||||
"total_power_active_boiler": {
|
||||
"name": "Total active power for boiler"
|
||||
}
|
||||
},
|
||||
"number": {
|
||||
"frost_temp": {
|
||||
"name": "Frost"
|
||||
|
||||
@@ -313,6 +313,7 @@
|
||||
"heater_heating_time": "Temps de chauffe (min)",
|
||||
"heater_cooling_time": "Temps de refroidissement (min)",
|
||||
"auto_tpi_heating_rate": "Taux de chauffe ({unit}/h)",
|
||||
"auto_tpi_cooling_rate": "Taux de refroidissement ({unit}/h)",
|
||||
"auto_tpi_aggressiveness": "Agressivité",
|
||||
"auto_tpi_enable_advanced_settings": "Activer les paramètres avancés",
|
||||
"auto_tpi_continuous_kext": "Apprentissage continu de Kext"
|
||||
@@ -322,6 +323,7 @@
|
||||
"heater_heating_time": "Temps pour atteindre la pleine puissance (minutes)",
|
||||
"heater_cooling_time": "Temps pour refroidir après arrêt (minutes)\n\n| Type | Temps de chauffe | Temps de refroidissement |\n| :--- | :--- | :--- |\n| Radiateur électrique | 5mn | 7mn |\n| Radiateur à eau | 15mn | 20mn |\n| Chauffage par le sol | 30mn | 45mn |",
|
||||
"auto_tpi_heating_rate": "Capacité de montée en température du radiateur ({unit} par heure). Laisser à 0 pour l'apprentissage automatique (bootstrap).",
|
||||
"auto_tpi_cooling_rate": "Capacité de descente en température du radiateur ({unit} par heure). Laisser à 0 pour l'apprentissage automatique (bootstrap).",
|
||||
"auto_tpi_aggressiveness": "Facteur de réduction des coefficients appris (50-100%). Des valeurs plus basses donnent des coefficients plus conservateurs et réduisent le risque de dépassement de consigne.",
|
||||
"auto_tpi_enable_advanced_settings": "Cochez pour accéder au réglage fin des paramètres (Alpha, Décroissance, Poids).",
|
||||
"auto_tpi_continuous_kext": "Cochez pour activer l'ajustement continu du coefficient extérieur (Kext) hors session AutoTPI."
|
||||
@@ -724,6 +726,7 @@
|
||||
"data": {
|
||||
"auto_tpi_learning_type": "Type d'apprentissage",
|
||||
"auto_tpi_heating_rate": "Taux de chauffe ({unit}/h)",
|
||||
"auto_tpi_cooling_rate": "Taux de refroidissement ({unit}/h)",
|
||||
"heater_heating_time": "Temps de chauffe (min)",
|
||||
"heater_cooling_time": "Temps de refroidissement (min)",
|
||||
"auto_tpi_aggressiveness": "Agressivité",
|
||||
@@ -733,6 +736,7 @@
|
||||
"data_description": {
|
||||
"auto_tpi_learning_type": "Choisissez 'Découverte' pour le démarrage initial (Moyenne pondérée, poids 1) ou 'Ajustement fin' pour des ajustements continus (EWMA, Alpha 0.08).",
|
||||
"auto_tpi_heating_rate": "Capacité de montée en température du radiateur ({unit} par heure). Laisser à 0 pour l'apprentissage automatique (bootstrap).",
|
||||
"auto_tpi_cooling_rate": "Capacité de descente en température du radiateur ({unit} par heure). Laisser à 0 pour l'apprentissage automatique (bootstrap).",
|
||||
"heater_heating_time": "Temps pour atteindre la pleine puissance (minutes)",
|
||||
"heater_cooling_time": "Temps pour refroidir après arrêt (minutes)\n\n| Type | Temps de chauffe | Temps de refroidissement |\n| :--- | :--- | :--- |\n| Radiateur électrique | 5mn | 7mn |\n| Radiateur à eau | 15mn | 20mn |\n| Chauffage par le sol | 30mn | 45mn |",
|
||||
"auto_tpi_aggressiveness": "Facteur de réduction des coefficients appris (50-100%). Des valeurs plus basses donnent des coefficients plus conservateurs et réduisent le risque de dépassement de consigne.",
|
||||
|
||||
@@ -312,6 +312,7 @@
|
||||
"heater_heating_time": "Tempo riscaldamento (min)",
|
||||
"heater_cooling_time": "Tempo raffrescamento (min)",
|
||||
"auto_tpi_heating_rate": "Velocità di riscaldamento ({unit}/h)",
|
||||
"auto_tpi_cooling_rate": "Velocità di raffreddamento ({unit}/h)",
|
||||
"auto_tpi_aggressiveness": "Aggressività",
|
||||
"auto_tpi_enable_advanced_settings": "Abilita paramnetri avanzati",
|
||||
"auto_tpi_continuous_kext": "Apprendimento continuo di Kext"
|
||||
@@ -321,6 +322,7 @@
|
||||
"heater_heating_time": "Tempo necessario per raggiungere la piena potenza (minuti)",
|
||||
"heater_cooling_time": "Tempo di raffreddamento dopo l'arresto (minuti)\n\n| Tipo | Tempo di riscaldamento | Tempo di raffreddamento |\n| :--- | :--- | :--- |\n| Radiatore elettrico | 5 min | 7 min |\n| Radiatore ad acqua | 15 min | 20 min |\n| Riscaldamento a pavimento | 30 min | 45 min |",
|
||||
"auto_tpi_heating_rate": "Capacità di aumento della temperatura del radiatore ({unit} all'ora). Lasciare a 0 per l'apprendimento automatico (bootstrap).",
|
||||
"auto_tpi_cooling_rate": "Capacità di raffreddamento del radiatore ({unit} all'ora). Lasciare a 0 per l'apprendimento automatico (bootstrap).",
|
||||
"auto_tpi_aggressiveness": "Fattore di riduzione per i coefficienti appresi (50-100%). Valori inferiori determinano coefficienti più conservativi e riducono il rischio di sovra-riscaldamento.",
|
||||
"auto_tpi_enable_advanced_settings": "Controlla per accedere alla regolazione fine dei parametri (Alpha, Decadimento, Peso).",
|
||||
"auto_tpi_continuous_kext": "Selezionare per attivare la regolazione continua del coefficiente esterno (Kext) al di fuori della sessione AutoTPI."
|
||||
@@ -710,6 +712,7 @@
|
||||
"data": {
|
||||
"auto_tpi_learning_type": "Tipo di apprendimento",
|
||||
"auto_tpi_heating_rate": "Velocità di riscaldamento ({unit}/h)",
|
||||
"auto_tpi_cooling_rate": "Velocità di raffreddamento ({unit}/h)",
|
||||
"heater_heating_time": "Tempo di riscaldamento (min)",
|
||||
"heater_cooling_time": "Tempo di raffrescamento (min)",
|
||||
"auto_tpi_aggressiveness": "Aggressività",
|
||||
@@ -719,6 +722,7 @@
|
||||
"data_description": {
|
||||
"auto_tpi_learning_type": "Scegliere “Discovery” per l'avvio iniziale (media ponderata, peso 1) o “Fine Tuning” per le regolazioni continue (EWMA, Alpha 0,08).",
|
||||
"auto_tpi_heating_rate": "Capacità di aumento della temperatura del radiatore ({unit} all'ora). Lasciare a 0 per l'apprendimento automatico (bootstrap).",
|
||||
"auto_tpi_cooling_rate": "Capacità di raffreddamento del radiatore ({unit} all'ora). Lasciare a 0 per l'apprendimento automatico (bootstrap).",
|
||||
"heater_heating_time": "Tempo necessario per raggiungere la piena potenza (minuti)",
|
||||
"heater_cooling_time": "Tempo di raffreddamento dopo l'arresto (minuti)\n\n| Tipo | Tempo di riscaldamento | Tempo di raffreddamento |\n| :--- | :--- | :--- |\n| Radiatore elettrico | 5 min | 7 min |\n| Radiatore ad acqua | 15 min | 20 min |\n| Riscaldamento a pavimento | 30 min | 45 min |",
|
||||
"auto_tpi_aggressiveness": "Fattore di riduzione per i coefficienti appresi (50-100%). Valori inferiori determinano coefficienti più conservativi e riducono il rischio di sovrariscaldamento.",
|
||||
@@ -1087,4 +1091,4 @@
|
||||
"message": "L'apprendimento automatico TPI per {name} è stato interrotto a causa di 3 errori consecutivi. Motivo: {reason}. Controllare la configurazione."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -325,6 +325,14 @@
|
||||
"humidity_sensor_entity_id": "Pozostaw puste, aby automatycznie użyć wykrytego czujnika."
|
||||
}
|
||||
},
|
||||
"auto_tpi_configuration": {
|
||||
"data": {
|
||||
"auto_tpi_cooling_rate": "Szybkość chłodzenia ({unit}/h)"
|
||||
},
|
||||
"data_description": {
|
||||
"auto_tpi_cooling_rate": "Zdolność chłodzenia grzejnika ({unit} na godzinę). Pozostaw 0 dla automatycznego uczenia (bootstrap)."
|
||||
}
|
||||
},
|
||||
"heating_failure_detection": {
|
||||
"title": "Wykrywanie awarii ogrzewania",
|
||||
"description": "Konfiguracja funkcji wykrywania awarii ogrzewania. Wykrywa anomalie, gdy ogrzewanie jest oczekiwane, ale temperatura nie wzrasta, lub gdy ogrzewanie jest wyłączone, ale temperatura nadal rośnie.",
|
||||
@@ -693,8 +701,8 @@
|
||||
"heater_heating_time": "Czas nagrzewania się grzejnika (w min.)",
|
||||
"heater_cooling_time": "Czas wychładzania się grzejnika (w min.)",
|
||||
"auto_tpi_max_coef_int": "Maksymalna wartość współczynnika wewnętrznego",
|
||||
"auto_tpi_heating_rate": "Szybkość nagrzewania (°C/h)",
|
||||
"auto_tpi_cooling_rate": "Szybkość wystudzania (°C/h)"
|
||||
"auto_tpi_heating_rate": "Szybkość nagrzewania ({unit}/h)",
|
||||
"auto_tpi_cooling_rate": "Szybkość wystudzania ({unit}/h)"
|
||||
},
|
||||
"data_description": {
|
||||
"auto_tpi_enable_update_config": "Automatycznie aktualizuj konfigurację o wyuczone współczynniki",
|
||||
@@ -703,7 +711,8 @@
|
||||
"auto_tpi_continuous_learning": "Po zakończeniu procesu nauki system będzie obliczał i aplikował w tle nowe wartości współczynników (zalecana metoda EMA).",
|
||||
"heater_heating_time": "Czas osiągnięcia pełnej mocy (w min.)",
|
||||
"heater_cooling_time": "Czas wychłodzenia po zatrzymaniu (w min.)",
|
||||
"auto_tpi_max_coef_int": "Maksymalna dopuszczalna wartość współczynnika wewnętrznego"
|
||||
"auto_tpi_max_coef_int": "Maksymalna dopuszczalna wartość współczynnika wewnętrznego",
|
||||
"auto_tpi_cooling_rate": "Zdolność chłodzenia grzejnika ({unit} na godzinę). Pozostaw 0 dla automatycznego uczenia (bootstrap)."
|
||||
}
|
||||
},
|
||||
"auto_tpi_avg_settings": {
|
||||
@@ -729,7 +738,7 @@
|
||||
}
|
||||
},
|
||||
"heating_failure_detection": {
|
||||
"title": "Wykrywanie awarii ogrzewania",
|
||||
"title": "Wykrywanie awarii ogrzewania - {name}",
|
||||
"description": "Konfiguracja funkcji wykrywania awarii ogrzewania. Wykrywa anomalie, gdy ogrzewanie jest oczekiwane, ale temperatura nie wzrasta, lub gdy ogrzewanie jest wyłączone, ale temperatura nadal rośnie.",
|
||||
"data": {
|
||||
"use_heating_failure_detection_feature": "Włącz wykrywanie awarii ogrzewania",
|
||||
@@ -737,7 +746,7 @@
|
||||
"heating_failure_threshold": "Próg awarii ogrzewania",
|
||||
"cooling_failure_threshold": "Próg awarii chłodzenia",
|
||||
"heating_failure_detection_delay": "Opóźnienie wykrywania (minuty)",
|
||||
"temperature_change_tolerance": "Tolerancja zmiany temperatury (°C)",
|
||||
"temperature_change_tolerance": "Tolerancja zmiany temperatury ({unit})",
|
||||
"failure_detection_enable_template": "Szablon włączenia wykrywania"
|
||||
},
|
||||
"data_description": {
|
||||
|
||||
@@ -307,6 +307,14 @@
|
||||
"sync_entity_ids": "The list of the entities used to synchronize the internal temperature of the underlying devices. There should be one per underlying device. Should be a calibration entity if checkbox is selected or a temperature entity otherwise. Both are `number` entities."
|
||||
}
|
||||
},
|
||||
"auto_tpi_configuration": {
|
||||
"data": {
|
||||
"auto_tpi_cooling_rate": "Скорость охлаждения ({unit}/ч)"
|
||||
},
|
||||
"data_description": {
|
||||
"auto_tpi_cooling_rate": "Способность радиатора к охлаждению ({unit} в час). Оставьте 0 для автоматического обучения (bootstrap)."
|
||||
}
|
||||
},
|
||||
"heating_failure_detection": {
|
||||
"title": "Обнаружение сбоев отопления",
|
||||
"description": "Настройка функции обнаружения сбоев отопления. Обнаруживает аномалии, когда ожидается нагрев, но температура не повышается, или когда отопление выключено, но температура продолжает расти.",
|
||||
@@ -654,6 +662,14 @@
|
||||
"sync_entity_ids": "The list of the entities used to synchronize the internal temperature of the underlying devices. There should be one per underlying device. Should be a calibration entity if checkbox is selected or a temperature entity otherwise. Both are `number` entities."
|
||||
}
|
||||
},
|
||||
"auto_tpi_configuration": {
|
||||
"data": {
|
||||
"auto_tpi_cooling_rate": "Скорость охлаждения ({unit}/ч)"
|
||||
},
|
||||
"data_description": {
|
||||
"auto_tpi_cooling_rate": "Способность радиатора к охлаждению ({unit} в час). Оставьте 0 для автоматического обучения (bootstrap)."
|
||||
}
|
||||
},
|
||||
"heating_failure_detection": {
|
||||
"title": "Обнаружение сбоев отопления",
|
||||
"description": "Настройка функции обнаружения сбоев отопления. Обнаруживает аномалии, когда ожидается нагрев, но температура не повышается, или когда отопление выключено, но температура продолжает расти.",
|
||||
@@ -832,4 +848,4 @@
|
||||
"description": "Переводит VTherm в сезонный режим сна. Он отображается как выключенный и для over_climate с прямым управлением клапаном и over_valve отправляет необработанный запрос на открытие клапана на 100 %. Физическое открытие по-прежнему ограничивается настроенным управлением клапаном и пределами сущности number."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -300,6 +300,14 @@
|
||||
"max_closing_degree": "Maximálna hodnota stupňa zatvorenia. Ventil sa nikdy nezatvorí viac ako táto hodnota. Nastavte na 100 pre úplné zatvorenie ventilu"
|
||||
}
|
||||
},
|
||||
"auto_tpi_configuration": {
|
||||
"data": {
|
||||
"auto_tpi_cooling_rate": "Rýchlosť chladenia ({unit}/h)"
|
||||
},
|
||||
"data_description": {
|
||||
"auto_tpi_cooling_rate": "Schopnosť chladiča ochladzovať ({unit} za hodinu). Pre automatické učenie (bootstrap) ponechajte hodnotu 0."
|
||||
}
|
||||
},
|
||||
"heating_failure_detection": {
|
||||
"title": "Detekcia porúch vykurovania",
|
||||
"description": "Konfigurácia funkcie detekcie porúch vykurovania. Detekuje anomálie, keď sa očakáva vykurovanie, ale teplota nestúpa, alebo keď je vykurovanie vypnuté, ale teplota stále stúpa.",
|
||||
@@ -637,6 +645,14 @@
|
||||
"max_closing_degree": "Maximálna hodnota stupňa zatvorenia. Ventil sa nikdy nezatvorí viac ako táto hodnota. Nastavte na 100 pre úplné zatvorenie ventilu"
|
||||
}
|
||||
},
|
||||
"auto_tpi_configuration": {
|
||||
"data": {
|
||||
"auto_tpi_cooling_rate": "Rýchlosť chladenia ({unit}/h)"
|
||||
},
|
||||
"data_description": {
|
||||
"auto_tpi_cooling_rate": "Schopnosť chladiča ochladzovať ({unit} za hodinu). Pre automatické učenie (bootstrap) ponechajte hodnotu 0."
|
||||
}
|
||||
},
|
||||
"heating_failure_detection": {
|
||||
"title": "Detekcia porúch vykurovania",
|
||||
"description": "Konfigurácia funkcie detekcie porúch vykurovania. Detekuje anomálie, keď sa očakáva vykurovanie, ale teplota nestúpa, alebo keď je vykurovanie vypnuté, ale teplota stále stúpa.",
|
||||
@@ -804,4 +820,4 @@
|
||||
"description": "Prepne VTherm do sezónneho režimu spánku. Zobrazuje sa ako vypnutý a pre over_climate s priamym riadením ventilu a over_valve odošle hrubú požiadavku na otvorenie ventilu na 100 %. Fyzické otvorenie naďalej podlieha nastavenému riadeniu ventilu a limitom entity number."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -311,6 +311,7 @@
|
||||
"heater_heating_time": "加热时间(分钟)",
|
||||
"heater_cooling_time": "冷却时间(分钟)",
|
||||
"auto_tpi_heating_rate": "升温速率({unit}/h)",
|
||||
"auto_tpi_cooling_rate": "冷却速率 ({unit}/小时)",
|
||||
"auto_tpi_aggressiveness": "激进程度",
|
||||
"auto_tpi_enable_advanced_settings": "启用高级参数",
|
||||
"auto_tpi_continuous_kext": "持续学习 Kext"
|
||||
@@ -320,6 +321,7 @@
|
||||
"heater_heating_time": "达到满功率的时间(分钟)",
|
||||
"heater_cooling_time": "停止后的冷却时间(分钟)\n\n| 类型 | 加热时间 | 冷却时间 |\n| :--- | :--- | :--- |\n| 电暖器 | 5mn | 7mn |\n| 水暖散热器 | 15mn | 20mn |\n| 地暖 | 30mn | 45mn |",
|
||||
"auto_tpi_heating_rate": "散热器升温能力({unit}每小时)。保留为 0 以进行自动学习(引导程序)。",
|
||||
"auto_tpi_cooling_rate": "散热器降温能力(每小时 {unit})。保留为 0 以进行自动学习(bootstrap)。",
|
||||
"auto_tpi_aggressiveness": "学习系数的缩减因子 (50-100%)。较低的值会产生更保守的系数并降低超调风险。",
|
||||
"auto_tpi_enable_advanced_settings": "勾选后可访问参数微调(Alpha、衰减、权重)。",
|
||||
"auto_tpi_continuous_kext": "选中以启用 AutoTPI 会话之外的外部系数 (Kext) 的持续学习。"
|
||||
@@ -722,6 +724,7 @@
|
||||
"data": {
|
||||
"auto_tpi_learning_type": "学习类型",
|
||||
"auto_tpi_heating_rate": "升温速率({unit}/h)",
|
||||
"auto_tpi_cooling_rate": "冷却速率 ({unit}/小时)",
|
||||
"heater_heating_time": "加热时间(分钟)",
|
||||
"heater_cooling_time": "冷却时间(分钟)",
|
||||
"auto_tpi_aggressiveness": "激进程度",
|
||||
@@ -731,6 +734,7 @@
|
||||
"data_description": {
|
||||
"auto_tpi_learning_type": "选择“发现”用于初始启动(加权平均,权重 1),或选择“微调”用于持续调整(EWMA,Alpha 0.08)。",
|
||||
"auto_tpi_heating_rate": "散热器升温能力({unit}每小时)。保留为 0 以进行自动学习(引导程序)。",
|
||||
"auto_tpi_cooling_rate": "散热器降温能力(每小时 {unit})。保留为 0 以进行自动学习(bootstrap)。",
|
||||
"heater_heating_time": "达到满功率的时间(分钟)",
|
||||
"heater_cooling_time": "停止后的冷却时间(分钟)\n\n| 类型 | 加热时间 | 冷却时间 |\n| :--- | :--- | :--- |\n| 电暖器 | 5mn | 7mn |\n| 水暖散热器 | 15mn | 20mn |\n| 地暖 | 30mn | 45mn |",
|
||||
"auto_tpi_aggressiveness": "学习系数的缩减因子 (50-100%)。较低的值会产生更保守的系数并降低超调风险。",
|
||||
@@ -1087,4 +1091,4 @@
|
||||
"message": "由于连续 3 次失败,{name} 的自动 TPI 学习已停止。原因:{reason}。请检查您的配置。"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
# pylint: disable=unused-argument, line-too-long, too-many-lines, broad-exception-caught
|
||||
|
||||
"""Underlying entities classes"""
|
||||
import math
|
||||
import re
|
||||
from typing import Any, Dict, List, Optional, Tuple, TypeVar
|
||||
from collections.abc import Callable
|
||||
@@ -1456,6 +1457,8 @@ class UnderlyingValveRegulation(UnderlyingValve):
|
||||
self._min_opening_degree: int = min_opening_degree
|
||||
self._max_closing_degree: int = max_closing_degree
|
||||
self._opening_threshold: int = opening_threshold
|
||||
self._seed_attempted_targets: set[str] = set()
|
||||
self._seed_diagnostics: dict[str, str] = {}
|
||||
|
||||
if self._min_opening_degree >= self._max_opening_degree:
|
||||
self._min_opening_degree = self._opening_threshold
|
||||
@@ -1542,6 +1545,122 @@ class UnderlyingValveRegulation(UnderlyingValve):
|
||||
entities.append(self._closing_degree_entity_id)
|
||||
self._state_manager.add_underlying_entities(entities)
|
||||
|
||||
async def async_startup(self) -> None:
|
||||
"""Install normal listeners then run the bounded one-shot seed."""
|
||||
self.startup()
|
||||
await self._seed_unknown_degrees_once()
|
||||
|
||||
@staticmethod
|
||||
def _is_finite_number(value: Any) -> bool:
|
||||
"""Return whether a value is a finite numeric value, excluding bool."""
|
||||
return isinstance(value, (int, float)) and not isinstance(value, bool) and math.isfinite(value)
|
||||
|
||||
def _target_state_kind(self, entity_id: str) -> str:
|
||||
"""Classify a configured degree state for the one-shot seed."""
|
||||
state = self._state_manager.get_state(entity_id)
|
||||
if state is None:
|
||||
return "state_absent"
|
||||
if state.state == STATE_UNKNOWN:
|
||||
return "unknown"
|
||||
if state.state == STATE_UNAVAILABLE:
|
||||
return "state_unavailable"
|
||||
value = get_safe_float_value(state.state)
|
||||
return "numeric" if value is not None and math.isfinite(value) else "invalid_target_state"
|
||||
|
||||
def _seed_pair_if_valid(self, targets: list[str]) -> tuple[int, int] | None:
|
||||
"""Return the safe d=0 pair only when all pair preconditions hold."""
|
||||
configured_bounds = (
|
||||
self._min_opening_degree,
|
||||
self._max_opening_degree,
|
||||
self._max_closing_degree,
|
||||
self._opening_threshold,
|
||||
)
|
||||
if not all(self._is_finite_number(value) for value in configured_bounds):
|
||||
return None
|
||||
if not (0 <= self._min_opening_degree < self._max_opening_degree <= 100 and 0 <= self._max_closing_degree <= 100 and 0 <= self._opening_threshold <= 100):
|
||||
return None
|
||||
|
||||
opening_degree, closing_degree = OpeningClosingDegreeCalculation.calculate_opening_closing_degree(
|
||||
brut_valve_open_percent=0,
|
||||
min_opening_degree=self._min_opening_degree,
|
||||
max_closing_degree=self._max_closing_degree,
|
||||
max_opening_degree=self._max_opening_degree,
|
||||
opening_threshold=self._opening_threshold,
|
||||
)
|
||||
if not all(isinstance(value, int) and not isinstance(value, bool) for value in (opening_degree, closing_degree)):
|
||||
return None
|
||||
|
||||
values = {
|
||||
self._opening_degree_entity_id: opening_degree,
|
||||
self._closing_degree_entity_id: closing_degree,
|
||||
}
|
||||
for entity_id in targets:
|
||||
state = self._state_manager.get_state(entity_id)
|
||||
if state is None:
|
||||
return None
|
||||
minimum = state.attributes.get("min")
|
||||
maximum = state.attributes.get("max")
|
||||
if not self._is_finite_number(minimum) or not self._is_finite_number(maximum):
|
||||
return None
|
||||
minimum_value = float(minimum)
|
||||
maximum_value = float(maximum)
|
||||
if minimum_value > maximum_value:
|
||||
return None
|
||||
if not minimum_value <= values[entity_id] <= maximum_value:
|
||||
return None
|
||||
|
||||
return opening_degree, closing_degree
|
||||
|
||||
async def _seed_unknown_degrees_once(self) -> None:
|
||||
"""Seed exact unknown degree targets once without affecting readiness."""
|
||||
targets = self.valve_entity_ids
|
||||
state_kinds = {entity_id: self._target_state_kind(entity_id) for entity_id in targets}
|
||||
invalid_targets = {entity_id: kind for entity_id, kind in state_kinds.items() if kind not in ("numeric", "unknown")}
|
||||
if invalid_targets:
|
||||
self._seed_diagnostics.update(invalid_targets)
|
||||
_LOGGER.warning("%s - Valve-regulation seed skipped: %s", self, invalid_targets)
|
||||
return
|
||||
|
||||
unknown_targets = [entity_id for entity_id, kind in state_kinds.items() if kind == "unknown"]
|
||||
if not unknown_targets:
|
||||
for entity_id in targets:
|
||||
self._seed_diagnostics[entity_id] = "already_numeric"
|
||||
return
|
||||
|
||||
pair = self._seed_pair_if_valid(targets)
|
||||
if pair is None:
|
||||
for entity_id in targets:
|
||||
self._seed_diagnostics[entity_id] = "invalid_bounds"
|
||||
_LOGGER.warning("%s - Valve-regulation seed skipped: invalid_bounds", self)
|
||||
return
|
||||
|
||||
values = dict(zip((self._opening_degree_entity_id, self._closing_degree_entity_id), pair))
|
||||
for entity_id in unknown_targets:
|
||||
if entity_id in self._seed_attempted_targets:
|
||||
continue
|
||||
self._seed_attempted_targets.add(entity_id)
|
||||
try:
|
||||
await self.send_value_to_number(entity_id, values[entity_id])
|
||||
except Exception: # pragma: no cover - helper errors are integration-dependent
|
||||
self._seed_diagnostics[entity_id] = "service_error"
|
||||
_LOGGER.warning("%s - Valve-regulation seed service_error for %s", self, entity_id)
|
||||
else:
|
||||
self._seed_diagnostics[entity_id] = "seed_attempted"
|
||||
_LOGGER.info("%s - Valve-regulation seed_attempted for %s with value %s", self, entity_id, values[entity_id])
|
||||
|
||||
@property
|
||||
def bootstrap_diagnostics(self) -> dict[str, Any]:
|
||||
"""Return seed diagnostics without inferring target readiness."""
|
||||
return {
|
||||
"seed_targets": dict(self._seed_diagnostics),
|
||||
"seed_attempted_targets": sorted(self._seed_attempted_targets),
|
||||
}
|
||||
|
||||
@overrides
|
||||
def remove_entity(self):
|
||||
"""Remove the listener without issuing a compensating command."""
|
||||
super().remove_entity()
|
||||
|
||||
@overrides
|
||||
def _get_controlled_percent(self, raw_percent: int) -> int:
|
||||
"""Keep the raw TPI percentage until ``send_percent_open``.
|
||||
|
||||
Reference in New Issue
Block a user