diff --git a/custom_components/heating_mpc/config_flow.py b/custom_components/heating_mpc/config_flow.py index 629476d..a07589d 100644 --- a/custom_components/heating_mpc/config_flow.py +++ b/custom_components/heating_mpc/config_flow.py @@ -302,14 +302,23 @@ class ZoneSubentryFlow(config_entries.ConfigSubentryFlow): return await self._zone_form("reconfigure", user_input, existing, existing[ZONE_KEY]) async def async_step_sensor_weights(self, user_input: dict[str, Any] | None = None): + """One weight per sensor; fields are numbered so they have translated labels.""" sensors = self._draft[ZONE_SENSORS] if user_input is not None: - self._draft[ZONE_SENSOR_WEIGHTS] = {s: float(user_input[f"weight__{s}"]) for s in sensors} + self._draft[ZONE_SENSOR_WEIGHTS] = { + s: float(user_input[f"sensor_weight_{i}"]) for i, s in enumerate(sensors, 1)} return self._finish() weights = self._draft.get(ZONE_SENSOR_WEIGHTS) or {} - return self.async_show_form(step_id="sensor_weights", data_schema=vol.Schema({ - vol.Required(f"weight__{s}", default=weights.get(s, 1.0)): _number(*SENSOR_WEIGHT_RANGE, 0.1) - for s in sensors})) + names = [] + for i, sensor in enumerate(sensors, 1): + state = self.hass.states.get(sensor) + names.append(f"{i}. {state.name if state else sensor} ({sensor})") + return self.async_show_form( + step_id="sensor_weights", + data_schema=vol.Schema({ + vol.Required(f"sensor_weight_{i}", default=weights.get(s, 1.0)): _number(*SENSOR_WEIGHT_RANGE, 0.1) + for i, s in enumerate(sensors, 1)}), + description_placeholders={"sensors": "\n".join(names)}) def _finish(self): data = {key: self._draft[key] for key in ( diff --git a/custom_components/heating_mpc/strings.json b/custom_components/heating_mpc/strings.json index 6cd2d17..8e608ab 100644 --- a/custom_components/heating_mpc/strings.json +++ b/custom_components/heating_mpc/strings.json @@ -143,7 +143,7 @@ "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.", + "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. If you choose two or more sensors, the next step asks for each sensor's weight.", "data": { "name": "Name", "sensors": "Temperature sensors", @@ -159,11 +159,19 @@ }, "sensor_weights": { "title": "Sensor weights", - "description": "How much each sensor counts in the zone temperature (0.1–10)." + "description": "How much each sensor counts in the zone temperature (0.1–10). Equal weights give the plain average.\n\n{sensors}", + "data": { + "sensor_weight_1": "Sensor 1 weight", + "sensor_weight_2": "Sensor 2 weight", + "sensor_weight_3": "Sensor 3 weight", + "sensor_weight_4": "Sensor 4 weight", + "sensor_weight_5": "Sensor 5 weight", + "sensor_weight_6": "Sensor 6 weight" + } }, "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.", + "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. If you choose two or more sensors, the next step asks for each sensor's weight.", "data": { "name": "Name", "sensors": "Temperature sensors", diff --git a/custom_components/heating_mpc/translations/en.json b/custom_components/heating_mpc/translations/en.json index 6cd2d17..8e608ab 100644 --- a/custom_components/heating_mpc/translations/en.json +++ b/custom_components/heating_mpc/translations/en.json @@ -143,7 +143,7 @@ "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.", + "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. If you choose two or more sensors, the next step asks for each sensor's weight.", "data": { "name": "Name", "sensors": "Temperature sensors", @@ -159,11 +159,19 @@ }, "sensor_weights": { "title": "Sensor weights", - "description": "How much each sensor counts in the zone temperature (0.1–10)." + "description": "How much each sensor counts in the zone temperature (0.1–10). Equal weights give the plain average.\n\n{sensors}", + "data": { + "sensor_weight_1": "Sensor 1 weight", + "sensor_weight_2": "Sensor 2 weight", + "sensor_weight_3": "Sensor 3 weight", + "sensor_weight_4": "Sensor 4 weight", + "sensor_weight_5": "Sensor 5 weight", + "sensor_weight_6": "Sensor 6 weight" + } }, "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.", + "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. If you choose two or more sensors, the next step asks for each sensor's weight.", "data": { "name": "Name", "sensors": "Temperature sensors", diff --git a/custom_components/heating_mpc/translations/ro.json b/custom_components/heating_mpc/translations/ro.json index 84662ad..cbe2118 100644 --- a/custom_components/heating_mpc/translations/ro.json +++ b/custom_components/heating_mpc/translations/ro.json @@ -143,7 +143,7 @@ "step": { "user": { "title": "Zonă termică", - "description": "O cameră sau o zonă a apartamentului. Ponderile senzorilor combină mai mulți senzori din aceeași cameră; ponderea de confort spune cât de importantă este zona pentru MPC. Niciuna nu modifică proprietățile termice învățate ale zonei.", + "description": "O cameră sau o zonă a apartamentului. Ponderile senzorilor combină mai mulți senzori din aceeași cameră; ponderea de confort spune cât de importantă este zona pentru MPC. Niciuna nu modifică proprietățile termice învățate ale zonei. Dacă alegi doi sau mai mulți senzori, pasul următor cere ponderea fiecărui senzor.", "data": { "name": "Nume", "sensors": "Senzori de temperatură", @@ -159,11 +159,19 @@ }, "sensor_weights": { "title": "Ponderile senzorilor", - "description": "Cât contează fiecare senzor în temperatura zonei (0,1–10)." + "description": "Cât contează fiecare senzor în temperatura zonei (0,1–10). Ponderi egale dau media simplă.\n\n{sensors}", + "data": { + "sensor_weight_1": "Ponderea senzorului 1", + "sensor_weight_2": "Ponderea senzorului 2", + "sensor_weight_3": "Ponderea senzorului 3", + "sensor_weight_4": "Ponderea senzorului 4", + "sensor_weight_5": "Ponderea senzorului 5", + "sensor_weight_6": "Ponderea senzorului 6" + } }, "reconfigure": { "title": "Zonă termică", - "description": "O cameră sau o zonă a apartamentului. Ponderile senzorilor combină mai mulți senzori din aceeași cameră; ponderea de confort spune cât de importantă este zona pentru MPC. Niciuna nu modifică proprietățile termice învățate ale zonei.", + "description": "O cameră sau o zonă a apartamentului. Ponderile senzorilor combină mai mulți senzori din aceeași cameră; ponderea de confort spune cât de importantă este zona pentru MPC. Niciuna nu modifică proprietățile termice învățate ale zonei. Dacă alegi doi sau mai mulți senzori, pasul următor cere ponderea fiecărui senzor.", "data": { "name": "Nume", "sensors": "Senzori de temperatură", diff --git a/tests/ha/test_config_flow.py b/tests/ha/test_config_flow.py index aada193..6caf6ee 100644 --- a/tests/ha/test_config_flow.py +++ b/tests/ha/test_config_flow.py @@ -132,8 +132,11 @@ async def test_zone_subentry_add_edit_and_validation(hass, entry, inputs): "name": " Living ", "sensors": ["sensor.living_a", "sensor.living_b"], "comfort_weight": 2, "target_offset": 0.5, "neighbors": ["sensor.room"]}) assert result["step_id"] == "sensor_weights" - result = await flows.async_configure(result["flow_id"], { - "weight__sensor.living_a": 3, "weight__sensor.living_b": 1}) + # Numbered, translated fields; the description says which sensor is which. + assert [str(key) for key in result["data_schema"].schema] == ["sensor_weight_1", "sensor_weight_2"] + assert result["description_placeholders"]["sensors"].splitlines() == [ + "1. living a (sensor.living_a)", "2. living b (sensor.living_b)"] # HA name fallback + result = await flows.async_configure(result["flow_id"], {"sensor_weight_1": 3, "sensor_weight_2": 1}) assert result["type"] is FlowResultType.CREATE_ENTRY await hass.async_block_till_done() living = next(sub for sub in zones_of(entry).values() if sub.title == "Living") @@ -149,6 +152,13 @@ async def test_zone_subentry_add_edit_and_validation(hass, entry, inputs): result = await flows.async_configure(result["flow_id"], { "name": "Living", "sensors": ["sensor.living_a"], "comfort_weight": 1, "target_offset": 0}) assert result["type"] is FlowResultType.ABORT and result["reason"] == "reconfigure_successful" + # Editing a multi-sensor zone shows the saved sensor weights. + result = await flows.async_init((entry.entry_id, "zone"), context={ + "source": SOURCE_RECONFIGURE, "subentry_id": living.subentry_id}) + result = await flows.async_configure(result["flow_id"], { + "name": "Living", "sensors": ["sensor.living_a", "sensor.living_b"], "comfort_weight": 1, "target_offset": 0}) + assert result["data_schema"]({})["sensor_weight_1"] == 1.0 + flows.async_abort(result["flow_id"]) await hass.async_block_till_done() assert entry.subentries[living.subentry_id].data["key"] == key assert hass.data[DOMAIN][entry.entry_id].zones[key].sensors == ("sensor.living_a",)