{ "title": "Heating MPC", "config": { "step": { "user": { "title": "Heating MPC — room inputs", "description": "Choose thermostat, read-only relay and room sensors. This integration NEVER commands the heater.", "data": { "climate_entity": "Existing Generic Thermostat", "heater_entity": "Physical heating switch (read-only)", "room_entities": "Individual room temperature sensors", "room_max_age_minutes": "Maximum room sensor report age (minutes)", "weather_max_age_minutes": "Maximum weather sensor report age (minutes)", "room_stale_use_last_value": "Keep using the last value of a room sensor that stopped reporting" }, "data_description": { "room_stale_use_last_value": "Off: a room sensor older than its report-age limit is left out and the other rooms are re-weighted. On: its last value is still used, for up to 24 hours without a report; for sensors that report only when the value changes. Unavailable or invalid room sensors are always left out. Nothing pauses unless no room is usable." } }, "weather": { "title": "Primary weather sources", "description": "Choose as many sensors per metric as needed and arrange them in priority order. If the preferred source is unavailable, the next one is used automatically. Outdoor temperature is mandatory; wind and cloud coverage are diagnostic-only in this version.", "data": { "outside_temperature_sources": "Outdoor temperature sources (ordered: preferred first)", "outside_wind_sources": "Wind speed sources (optional)", "outside_clouds_sources": "Cloud coverage sources (optional)", "outside_wind_direction_sources": "Wind direction sources (optional; degrees the wind comes from)", "outside_wind_gust_sources": "Wind gust sources (optional)" } }, "weather_extra": { "title": "Additional weather sources", "description": "Additional weather inputs are optional and used only for comparison/diagnostics in v0.2; they do not yet change MPC predictions.", "data": { "outside_humidity_sources": "Outdoor humidity sources (optional)", "outside_feelslike_sources": "Feels-like temperature sources (optional)", "outside_pressure_sources": "Atmospheric pressure sources (optional)", "outside_visibility_sources": "Visibility sources (optional)", "outside_rain_sources": "Rain sources (optional)", "outside_snow_sources": "Snow sources (optional)" } }, "weights": { "title": "Room priorities", "description": "Each selected sensor becomes its own zone with this comfort weight. Later, group the sensors of one room into one zone with Add zone or by editing a zone." } }, "error": { "invalid_rooms": "Select 1–12 distinct room sensors.", "invalid_weather": "Select at least one outdoor temperature sensor, distinct from room sensors." }, "abort": { "already_configured": "Heating MPC is already configured." } }, "options": { "step": { "init": { "title": "Heating MPC options", "description": "Change room sensors and controller settings. This integration remains shadow-only.", "data": { "climate_entity": "Existing Generic Thermostat", "heater_entity": "Physical heating switch (read-only)", "horizon_minutes": "Prediction horizon (minutes)", "minimum_on_minutes": "Minimum ON time (minutes)", "minimum_off_minutes": "Minimum OFF time (minutes)", "switching_cost": "Switching cost", "heating_cost": "Heating runtime cost", "comfort_band": "Comfort tolerance (°C)", "room_max_age_minutes": "Maximum room sensor report age (minutes)", "weather_max_age_minutes": "Maximum weather sensor report age (minutes)", "room_stale_use_last_value": "Keep using the last value of a room sensor that stopped reporting", "internal_heat_half_life_minutes": "Extra electrical heat: forecast half-life (minutes)", "window_open_minutes": "Open window: assumed remaining open time (minutes)", "recovery_minutes": "Recovery after closing a window (minutes)", "ventilation_wind": "Ventilation: use wind speed and direction", "ventilation_gust": "Ventilation: use wind gusts", "ventilation_cross": "Ventilation: cross-ventilation between zones" }, "data_description": { "room_stale_use_last_value": "Off: a room sensor older than its report-age limit is left out and the other rooms are re-weighted. On: its last value is still used, for up to 24 hours without a report; for sensors that report only when the value changes. Unavailable or invalid room sensors are always left out. Nothing pauses unless no room is usable.", "internal_heat_half_life_minutes": "Forecasts assume heat above the baseline fades with this half-life, for example when a gaming session ends. 0 assumes it stops now.", "window_open_minutes": "Forecasts assume an open window closes after this many more minutes, then the room recovers.", "recovery_minutes": "Time constant of the air warming back towards the walls' temperature.", "ventilation_wind": "Needs wind sources; direction also needs wind direction sources.", "ventilation_gust": "Adds a term for gusts above the mean wind. Keep it only if Forecast Error improves.", "ventilation_cross": "Adds a term for windows open in several zones at once. Needs windows in two or more zones." } }, "weather": { "title": "Weather source priority", "description": "Choose as many sensors per metric as needed and arrange them in priority order. If the preferred source is unavailable, the next one is used automatically. Outdoor temperature is mandatory; wind and cloud coverage are diagnostic-only in this version.", "data": { "outside_temperature_sources": "Outdoor temperature sources (ordered: preferred first)", "outside_wind_sources": "Wind speed sources (optional)", "outside_clouds_sources": "Cloud coverage sources (optional)", "outside_wind_direction_sources": "Wind direction sources (optional; degrees the wind comes from)", "outside_wind_gust_sources": "Wind gust sources (optional)" } }, "weather_extra": { "title": "Additional weather sensors", "description": "Additional weather inputs are optional and used only for comparison/diagnostics in v0.2; they do not yet change MPC predictions.", "data": { "outside_humidity_sources": "Outdoor humidity sources (optional)", "outside_feelslike_sources": "Feels-like temperature sources (optional)", "outside_pressure_sources": "Atmospheric pressure sources (optional)", "outside_visibility_sources": "Visibility sources (optional)", "outside_rain_sources": "Rain sources (optional)", "outside_snow_sources": "Snow sources (optional)" } } }, "error": { "invalid_weather": "Select at least one outdoor temperature sensor, distinct from room sensors." } }, "entity": { "sensor": { "last_sample": { "state": { "waiting_for_inputs": "Waiting for inputs", "first_sample": "First sample", "sensors_changed": "Zone sensors changed", "learned": "Learned", "ventilation": "Window open or recovering", "partly_rejected": "Partly rejected (outlier)", "interval_out_of_range": "Irregular interval", "relay_changed": "Relay switched", "outside_source_changed": "Outdoor source changed", "lag_uncertain": "Waiting for radiators to settle" } } } }, "config_subentries": { "zone": { "entry_type": "Zone", "initiate_flow": { "user": "Add zone", "reconfigure": "Edit zone" }, "step": { "user": { "title": "Thermal zone", "description": "A room or area of the apartment. Sensor weights combine several sensors in one room; the comfort weight says how much the zone matters to the MPC. Neither changes the zone's learned thermal properties.", "data": { "name": "Name", "sensors": "Temperature sensors", "comfort_weight": "Comfort weight", "target_offset": "Target offset (°C)", "neighbors": "Adjacent zones (heat exchange)" }, "data_description": { "comfort_weight": "Relative importance for the MPC (0.1–10).", "target_offset": "Added to the thermostat's target temperature for this zone.", "neighbors": "Zones this one exchanges heat with, for example through a wall or an open door. The coefficient is learned only when the data supports it." } }, "sensor_weights": { "title": "Sensor weights", "description": "How much each sensor counts in the zone temperature (0.1–10)." }, "reconfigure": { "title": "Thermal zone", "description": "A room or area of the apartment. Sensor weights combine several sensors in one room; the comfort weight says how much the zone matters to the MPC. Neither changes the zone's learned thermal properties.", "data": { "name": "Name", "sensors": "Temperature sensors", "comfort_weight": "Comfort weight", "target_offset": "Target offset (°C)", "neighbors": "Adjacent zones (heat exchange)" }, "data_description": { "comfort_weight": "Relative importance for the MPC (0.1–10).", "target_offset": "Added to the thermostat's target temperature for this zone.", "neighbors": "Zones this one exchanges heat with, for example through a wall or an open door. The coefficient is learned only when the data supports it." } } }, "error": { "zone_name_required": "Enter a name.", "zone_sensors": "Choose 1–6 different sensors.", "sensor_in_other_zone": "A chosen sensor already belongs to another zone.", "sensor_is_weather_source": "A chosen sensor is used as an outdoor temperature source.", "too_many_zones": "At most 12 zones are supported." }, "abort": { "reconfigure_successful": "The zone was updated." } }, "heat_source": { "entry_type": "Heat source", "initiate_flow": { "user": "Add heat source", "reconfigure": "Edit heat source" }, "step": { "user": { "title": "Electrical heat source", "description": "Equipment whose electrical power ends up as heat in a zone, such as a UPS with computers. Only the variation above a persistent baseline is modeled: the constant part is already part of the zone's learned behavior. Use active power (W or kW), not VA or load %.", "data": { "name": "Name", "sensor": "Active power sensor", "zone": "Zone", "heat_fraction": "Share of power that becomes heat in the zone", "baseline_mode": "Baseline", "baseline_w": "Manual baseline (W)", "included_in": "Already included in the measurement of", "response_minutes": "Thermal response time (minutes)", "enabled": "Enabled" }, "data_description": { "heat_fraction": "1.0 when the equipment is in this zone. Lower it if part of the heat goes elsewhere, for example out of a vent.", "baseline_mode": "Automatic uses the low end of the last 24 hours (the persistent load).", "included_in": "Choose the UPS or meter whose reading already contains this device, so its power is not counted twice.", "response_minutes": "How quickly the zone feels a change in power: room air, furniture and equipment take time to warm." } }, "reconfigure": { "title": "Electrical heat source", "description": "Equipment whose electrical power ends up as heat in a zone, such as a UPS with computers. Only the variation above a persistent baseline is modeled: the constant part is already part of the zone's learned behavior. Use active power (W or kW), not VA or load %.", "data": { "name": "Name", "sensor": "Active power sensor", "zone": "Zone", "heat_fraction": "Share of power that becomes heat in the zone", "baseline_mode": "Baseline", "baseline_w": "Manual baseline (W)", "included_in": "Already included in the measurement of", "response_minutes": "Thermal response time (minutes)", "enabled": "Enabled" }, "data_description": { "heat_fraction": "1.0 when the equipment is in this zone. Lower it if part of the heat goes elsewhere, for example out of a vent.", "baseline_mode": "Automatic uses the low end of the last 24 hours (the persistent load).", "included_in": "Choose the UPS or meter whose reading already contains this device, so its power is not counted twice.", "response_minutes": "How quickly the zone feels a change in power: room air, furniture and equipment take time to warm." } } }, "error": { "source_name_required": "Enter a name.", "sensor_in_other_source": "This power sensor is already used by another heat source.", "invalid_parent_source": "The parent must be an existing source that is not itself included in another.", "source_has_children": "Other sources are included in this one, so it cannot be included in another.", "baseline_required": "Enter the manual baseline in W.", "too_many_sources": "At most 16 heat sources are supported." }, "abort": { "reconfigure_successful": "The heat source was updated.", "no_zones": "Add a zone first." } }, "window": { "entry_type": "Window", "initiate_flow": { "user": "Add window", "reconfigure": "Edit window" }, "step": { "user": { "title": "Window", "description": "A window contact sensor. Open-window periods are kept out of the zone's normal heat-loss learning and modeled as ventilation instead. Unknown or unavailable states count as unknown, never as closed.", "data": { "name": "Name", "sensor": "Contact sensor", "zone": "Zone", "inverted": "Sensor reports on when closed", "azimuth": "Facing direction (°)", "opening_factor": "Opening factor", "enabled": "Enabled" }, "data_description": { "inverted": "Turn on for sensors whose polarity is the reverse of a standard window sensor.", "azimuth": "Direction the outside of the window faces, clockwise from north (0 = N, 90 = E, 180 = S, 270 = W). Used with the wind direction.", "opening_factor": "Relative ventilation when open: 1.0 for a normal window, lower for tilted, higher for a large or double window." } }, "reconfigure": { "title": "Window", "description": "A window contact sensor. Open-window periods are kept out of the zone's normal heat-loss learning and modeled as ventilation instead. Unknown or unavailable states count as unknown, never as closed.", "data": { "name": "Name", "sensor": "Contact sensor", "zone": "Zone", "inverted": "Sensor reports on when closed", "azimuth": "Facing direction (°)", "opening_factor": "Opening factor", "enabled": "Enabled" }, "data_description": { "inverted": "Turn on for sensors whose polarity is the reverse of a standard window sensor.", "azimuth": "Direction the outside of the window faces, clockwise from north (0 = N, 90 = E, 180 = S, 270 = W). Used with the wind direction.", "opening_factor": "Relative ventilation when open: 1.0 for a normal window, lower for tilted, higher for a large or double window." } } }, "error": { "window_name_required": "Enter a name.", "sensor_in_other_window": "This sensor is already used by another window.", "too_many_windows": "At most 24 windows are supported." }, "abort": { "reconfigure_successful": "The window was updated.", "no_zones": "Add a zone first." } } }, "selector": { "baseline_mode": { "options": { "auto": "Automatic (24-hour low)", "manual": "Manual value" } } } }