Skip to content

Commit d58f63a

Browse files
committed
check this translation format
1 parent 24269e3 commit d58f63a

File tree

6 files changed

+259
-259
lines changed

6 files changed

+259
-259
lines changed

custom_components/bwt_perla/sensor.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
from .const import DOMAIN
2121
from .coordinator import BwtCoordinator
2222
from .sensors.base import *
23+
from .sensors.error import *
2324

2425
_GLASS = "mdi:cup-water"
2526
_COUNTER = "mdi:counter"

custom_components/bwt_perla/sensors/base.py

Lines changed: 0 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,7 @@
1919
from homeassistant.core import callback
2020
from homeassistant.helpers.device_registry import DeviceInfo
2121
from homeassistant.helpers.update_coordinator import CoordinatorEntity
22-
from homeassistant.helpers import translation
2322

24-
from ..util import truncate_value
2523

2624
from ..const import DOMAIN
2725
from ..coordinator import BwtCoordinator
@@ -30,8 +28,6 @@
3028

3129
_FAUCET = "mdi:faucet"
3230
_WATER = "mdi:water"
33-
_WARNING = "mdi:alert-circle"
34-
_ERROR = "mdi:alert-decagram"
3531
_WATER_CHECK = "mdi:water-check"
3632
_HOLIDAY = "mdi:location-exit"
3733
_UNKNOWN = "mdi:help-circle"
@@ -55,40 +51,6 @@ def __init__(
5551
self._attr_unique_id = entry_id + "_" + key
5652

5753

58-
class TranslatableErrorMixin:
59-
"""Mixin for entities that need to translate error codes.
60-
61-
This mixin provides translation functionality for entities that display
62-
multiple error/warning codes. It loads translations when the entity is
63-
added to Home Assistant and provides a method to translate individual codes.
64-
65-
Attributes:
66-
_translations: Dictionary of translations loaded from language files.
67-
Initialized as None and populated in async_added_to_hass.
68-
"""
69-
70-
_translations = None
71-
72-
async def async_added_to_hass(self) -> None:
73-
"""When entity is added to hass, load translations."""
74-
await super().async_added_to_hass()
75-
# Load translations for the current language
76-
self._translations = await translation.async_get_translations(
77-
self.hass,
78-
self.hass.config.language,
79-
"entity_component",
80-
{DOMAIN},
81-
)
82-
83-
def _translate_code(self, code_name: str) -> str:
84-
"""Translate an error/warning code to the user's language."""
85-
if self._translations is None:
86-
return code_name
87-
88-
key = f"component.{DOMAIN}.entity_component._.state.error.{code_name.lower()}"
89-
return self._translations.get(key, code_name)
90-
91-
9254
class TotalOutputSensor(BwtEntity, SensorEntity):
9355
"""Total water [liter] that passed through the output."""
9456

@@ -132,89 +94,6 @@ def _handle_coordinator_update(self) -> None:
13294
self.async_write_ha_state()
13395

13496

135-
class ErrorSensor(TranslatableErrorMixin, BwtEntity, SensorEntity):
136-
"""Errors reported by the device."""
137-
138-
_attr_icon = _ERROR
139-
140-
def __init__(self, coordinator, device_info, entry_id) -> None:
141-
"""Initialize the sensor with the common coordinator."""
142-
super().__init__(coordinator, device_info, entry_id, "errors")
143-
self._update_values(self._get_errors())
144-
145-
def _get_errors(self):
146-
"""Get the current list of fatal errors."""
147-
return [x for x in self.coordinator.data.errors() if x.is_fatal()]
148-
149-
async def async_added_to_hass(self) -> None:
150-
"""When entity is added to hass, load translations."""
151-
await super().async_added_to_hass()
152-
# Update values with translations now that they're loaded
153-
self._update_values(self._get_errors())
154-
self.async_write_ha_state()
155-
156-
def _update_values(self, errors) -> None:
157-
"""Update error values with translations."""
158-
raw_values = [x.name for x in errors]
159-
# Store raw values as extra attributes for automation
160-
self._attr_extra_state_attributes = {"error_codes": raw_values}
161-
162-
# Translate error names for display
163-
if errors:
164-
translated = [self._translate_code(x.name) for x in errors]
165-
# Join translated parts and ensure it does not exceed 255 chars
166-
joined = ", ".join(translated)
167-
self._attr_native_value = truncate_value(joined, 255)
168-
else:
169-
self._attr_native_value = ""
170-
171-
@callback
172-
def _handle_coordinator_update(self) -> None:
173-
"""Handle updated data from the coordinator."""
174-
self._update_values(self._get_errors())
175-
self.async_write_ha_state()
176-
177-
178-
class WarningSensor(TranslatableErrorMixin, BwtEntity, SensorEntity):
179-
"""Warnings reported by the device."""
180-
181-
_attr_icon = _WARNING
182-
183-
def __init__(self, coordinator, device_info, entry_id) -> None:
184-
"""Initialize the sensor with the common coordinator."""
185-
super().__init__(coordinator, device_info, entry_id, "warnings")
186-
self._update_values(self._get_warnings())
187-
188-
def _get_warnings(self):
189-
"""Get the current list of non-fatal warnings."""
190-
return [x for x in self.coordinator.data.errors() if not x.is_fatal()]
191-
192-
async def async_added_to_hass(self) -> None:
193-
"""When entity is added to hass, load translations."""
194-
await super().async_added_to_hass()
195-
# Update values with translations now that they're loaded
196-
self._update_values(self._get_warnings())
197-
self.async_write_ha_state()
198-
199-
def _update_values(self, warnings) -> None:
200-
"""Update warning values with translations."""
201-
raw_values = [x.name for x in warnings]
202-
# Store raw values as extra attributes for automation
203-
self._attr_extra_state_attributes = {"warning_codes": raw_values}
204-
205-
# Translate warning names for display
206-
translated = [self._translate_code(x.name) for x in warnings]
207-
# Join translated parts and ensure it does not exceed 255 chars
208-
joined = ", ".join(translated)
209-
self._attr_native_value = truncate_value(joined, 255)
210-
211-
@callback
212-
def _handle_coordinator_update(self) -> None:
213-
"""Handle updated data from the coordinator."""
214-
self._update_values(self._get_warnings())
215-
self.async_write_ha_state()
216-
217-
21897
class SimpleSensor(BwtEntity, SensorEntity):
21998
"""Simplest sensor with least configuration options."""
22099

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
from .base import BwtEntity
2+
from homeassistant.components.sensor import (
3+
SensorEntity,
4+
)
5+
from ..const import DOMAIN
6+
from ..util import truncate_value
7+
8+
from homeassistant.core import callback
9+
from homeassistant.helpers import translation
10+
11+
from bwt_api.error import BwtError
12+
13+
_WARNING = "mdi:alert-circle"
14+
_ERROR = "mdi:alert-decagram"
15+
16+
class TranslatableErrorMixin:
17+
"""Mixin for entities that need to translate error codes.
18+
19+
This mixin provides translation functionality for entities that display
20+
multiple error/warning codes. It loads translations when the entity is
21+
added to Home Assistant and provides a method to translate individual codes.
22+
23+
Attributes:
24+
_translations: Dictionary of translations loaded from language files.
25+
Initialized as None and populated in async_added_to_hass.
26+
"""
27+
28+
_translations = None
29+
30+
async def async_added_to_hass(self) -> None:
31+
"""When entity is added to hass, load translations."""
32+
await super().async_added_to_hass()
33+
# Load translations for the current language
34+
self._translations = await translation.async_get_translations(
35+
self.hass,
36+
self.hass.config.language,
37+
"entity_component",
38+
{DOMAIN},
39+
)
40+
41+
def _translate_code(self, code_name: str) -> str:
42+
"""Translate an error/warning code to the user's language."""
43+
if self._translations is None:
44+
return code_name
45+
46+
key = f"component.{DOMAIN}.entity_component._.state.error_{code_name.lower()}"
47+
return self._translations.get(key, code_name)
48+
49+
class ErrorSensor(TranslatableErrorMixin, BwtEntity, SensorEntity):
50+
"""Errors reported by the device."""
51+
52+
_attr_icon = _ERROR
53+
54+
def __init__(self, coordinator, device_info, entry_id) -> None:
55+
"""Initialize the sensor with the common coordinator."""
56+
super().__init__(coordinator, device_info, entry_id, "errors")
57+
self._update_values(self._get_errors())
58+
59+
def _get_errors(self):
60+
"""Get the current list of fatal errors."""
61+
return [x for x in self.coordinator.data.errors() if x.is_fatal()]
62+
63+
async def async_added_to_hass(self) -> None:
64+
"""When entity is added to hass, load translations."""
65+
await super().async_added_to_hass()
66+
# Update values with translations now that they're loaded
67+
self._update_values(self._get_errors())
68+
self.async_write_ha_state()
69+
70+
def _update_values(self, errors) -> None:
71+
"""Update error values with translations."""
72+
raw_values = [x.name for x in errors]
73+
# Store raw values as extra attributes for automation
74+
self._attr_extra_state_attributes = {"error_codes": raw_values}
75+
76+
# Translate error names for display
77+
translated = [self._translate_code(x.name) for x in errors]
78+
# Join translated parts and ensure it does not exceed 255 chars
79+
joined = ", ".join(translated)
80+
self._attr_native_value = truncate_value(joined, 255)
81+
82+
@callback
83+
def _handle_coordinator_update(self) -> None:
84+
"""Handle updated data from the coordinator."""
85+
self._update_values(self._get_errors())
86+
self.async_write_ha_state()
87+
88+
89+
class WarningSensor(TranslatableErrorMixin, BwtEntity, SensorEntity):
90+
"""Warnings reported by the device."""
91+
92+
_attr_icon = _WARNING
93+
94+
def __init__(self, coordinator, device_info, entry_id) -> None:
95+
"""Initialize the sensor with the common coordinator."""
96+
super().__init__(coordinator, device_info, entry_id, "warnings")
97+
self._update_values(self._get_warnings())
98+
99+
def _get_warnings(self):
100+
"""Get the current list of non-fatal warnings."""
101+
return [x for x in self.coordinator.data.errors() if not x.is_fatal()]
102+
103+
async def async_added_to_hass(self) -> None:
104+
"""When entity is added to hass, load translations."""
105+
await super().async_added_to_hass()
106+
# Update values with translations now that they're loaded
107+
self._update_values(self._get_warnings())
108+
self.async_write_ha_state()
109+
110+
def _update_values(self, warnings) -> None:
111+
"""Update warning values with translations."""
112+
raw_values = [x.name for x in warnings]
113+
# Store raw values as extra attributes for automation
114+
self._attr_extra_state_attributes = {"warning_codes": raw_values}
115+
116+
# Translate warning names for display
117+
translated = [self._translate_code(x.name) for x in warnings]
118+
# Join translated parts and ensure it does not exceed 255 chars
119+
joined = ", ".join(translated)
120+
self._attr_native_value = truncate_value(joined, 255)
121+
122+
@callback
123+
def _handle_coordinator_update(self) -> None:
124+
"""Handle updated data from the coordinator."""
125+
self._update_values(self._get_warnings())
126+
self.async_write_ha_state()

custom_components/bwt_perla/strings.json

Lines changed: 44 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -105,52 +105,50 @@
105105
"entity_component": {
106106
"_": {
107107
"state": {
108-
"error": {
109-
"unknown": "Unknown error",
110-
"offline_motor_1": "Motor 1 offline",
111-
"offline_motor_2": "Motor 2 offline",
112-
"offline_motor_blend": "Blend motor offline",
113-
"regenerativ_20": "Regeneration salt level < 20%",
114-
"overcurrent_motor_1": "Overcurrent motor 1",
115-
"overcurrent_motor_2": "Overcurrent motor 2",
116-
"overcurrent_motor_3": "Overcurrent motor 3",
117-
"overcurrent_valve": "Overcurrent valve",
118-
"stop_volume": "Stop volume",
119-
"stop_sensor": "Stop sensor",
120-
"constant_flow": "Constant flow",
121-
"low_pressure": "Low pressure",
122-
"piston_position": "Piston position",
123-
"electronic": "Electronic",
124-
"insufficient_regenerativ": "Insufficient regeneration salt",
125-
"stop_wireless_sensor": "Stop wireless sensor",
126-
"regenerativ_0": "Regeneration salt empty",
127-
"maintenance_customer": "Routine maintenance due",
128-
"inspection_customer": "Customer inspection required",
129-
"maintenance_service": "Technician maintenance due",
130-
"minerals_low": "Minerals low",
131-
"minerals_0": "Minerals empty",
132-
"overcurrent_valve_1": "Overcurrent valve 1",
133-
"overcurrent_valve_2": "Overcurrent valve 2",
134-
"overcurrent_dosing": "Overcurrent dosing",
135-
"overcurrent_valve_ball": "Overcurrent ball valve",
136-
"meter_not_counting": "Water meter not counting",
137-
"regeneration_drain": "Regeneration drain issue",
138-
"init_pcb_0": "PCB initialization 0",
139-
"init_pcb_1": "PCB initialization 1",
140-
"position_motor_1": "Motor 1 position",
141-
"position_motor_2": "Motor 2 position",
142-
"conductivity_high": "Conductivity too high",
143-
"conductivity_limit_1": "Conductivity limit 1 exceeded",
144-
"conductivity_limit_2": "Conductivity limit 2 exceeded",
145-
"conductivity_limit_water": "Water conductivity limit exceeded",
146-
"no_function": "No function",
147-
"temperature_disconnected": "Temperature sensor disconnected",
148-
"temperature_high": "Temperature too high",
149-
"offline_valve_ball": "Ball valve offline",
150-
"external_filter_change": "External filter change required",
151-
"brine_unsaturated": "Brine unsaturated",
152-
"dosing_fault": "Dosing fault"
153-
}
108+
"error_unknown": "Unknown error",
109+
"error_offline_motor_1": "Motor 1 offline",
110+
"error_offline_motor_2": "Motor 2 offline",
111+
"error_offline_motor_blend": "Blend motor offline",
112+
"error_regenerativ_20": "Regeneration salt level < 20%",
113+
"error_overcurrent_motor_1": "Overcurrent motor 1",
114+
"error_overcurrent_motor_2": "Overcurrent motor 2",
115+
"error_overcurrent_motor_3": "Overcurrent motor 3",
116+
"error_overcurrent_valve": "Overcurrent valve",
117+
"error_stop_volume": "Stop volume",
118+
"error_stop_sensor": "Stop sensor",
119+
"error_constant_flow": "Constant flow",
120+
"error_low_pressure": "Low pressure",
121+
"error_piston_position": "Piston position",
122+
"error_electronic": "Electronic",
123+
"error_insufficient_regenerativ": "Insufficient regeneration salt",
124+
"error_stop_wireless_sensor": "Stop wireless sensor",
125+
"error_regenerativ_0": "Regeneration salt empty",
126+
"error_maintenance_customer": "Routine maintenance due",
127+
"error_inspection_customer": "Customer inspection required",
128+
"error_maintenance_service": "Technician maintenance due",
129+
"error_minerals_low": "Minerals low",
130+
"error_minerals_0": "Minerals empty",
131+
"error_overcurrent_valve_1": "Overcurrent valve 1",
132+
"error_overcurrent_valve_2": "Overcurrent valve 2",
133+
"error_overcurrent_dosing": "Overcurrent dosing",
134+
"error_overcurrent_valve_ball": "Overcurrent ball valve",
135+
"error_meter_not_counting": "Water meter not counting",
136+
"error_regeneration_drain": "Regeneration drain issue",
137+
"error_init_pcb_0": "PCB initialization 0",
138+
"error_init_pcb_1": "PCB initialization 1",
139+
"error_position_motor_1": "Motor 1 position",
140+
"error_position_motor_2": "Motor 2 position",
141+
"error_conductivity_high": "Conductivity too high",
142+
"error_conductivity_limit_1": "Conductivity limit 1 exceeded",
143+
"error_conductivity_limit_2": "Conductivity limit 2 exceeded",
144+
"error_conductivity_limit_water": "Water conductivity limit exceeded",
145+
"error_no_function": "No function",
146+
"error_temperature_disconnected": "Temperature sensor disconnected",
147+
"error_temperature_high": "Temperature too high",
148+
"error_offline_valve_ball": "Ball valve offline",
149+
"error_external_filter_change": "External filter change required",
150+
"error_brine_unsaturated": "Brine unsaturated",
151+
"error_dosing_fault": "Dosing fault"
154152
}
155153
}
156154
}

0 commit comments

Comments
 (0)