From 80fb07eae193f251d5c0a082b4b88f398bcee1e4 Mon Sep 17 00:00:00 2001 From: LiShuzhen Date: Tue, 17 Dec 2024 16:31:08 +0800 Subject: [PATCH 01/23] fix: air-conditioner switch on --- custom_components/xiaomi_home/climate.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/custom_components/xiaomi_home/climate.py b/custom_components/xiaomi_home/climate.py index 860afac..baedf61 100644 --- a/custom_components/xiaomi_home/climate.py +++ b/custom_components/xiaomi_home/climate.py @@ -254,6 +254,7 @@ class AirConditioner(MIoTServiceEntity, ClimateEntity): async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None: """Set new target hvac mode.""" + # set air-conditioner off if hvac_mode == HVACMode.OFF and self._prop_on: if not await self.set_property_async( prop=self._prop_on, value=False): @@ -261,6 +262,11 @@ class AirConditioner(MIoTServiceEntity, ClimateEntity): f'set climate prop.on failed, {hvac_mode}, ' f'{self.entity_id}') return + # set air-conditioner on + if hvac_mode != HVACMode.OFF and not self.get_prop_value( + prop=self._prop_on): + await self.async_turn_on() + # set mode mode_value = self.get_map_value( map_=self._hvac_mode_map, description=hvac_mode) if ( From 5b6f94a54a89dabaf1493cfc2516310f3f1d282e Mon Sep 17 00:00:00 2001 From: LiShuzhen Date: Tue, 17 Dec 2024 17:33:28 +0800 Subject: [PATCH 02/23] fix: set prop --- custom_components/xiaomi_home/climate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/xiaomi_home/climate.py b/custom_components/xiaomi_home/climate.py index baedf61..0b1ffd7 100644 --- a/custom_components/xiaomi_home/climate.py +++ b/custom_components/xiaomi_home/climate.py @@ -265,7 +265,7 @@ class AirConditioner(MIoTServiceEntity, ClimateEntity): # set air-conditioner on if hvac_mode != HVACMode.OFF and not self.get_prop_value( prop=self._prop_on): - await self.async_turn_on() + await self.set_property_async(prop=self._prop_on, value=True) # set mode mode_value = self.get_map_value( map_=self._hvac_mode_map, description=hvac_mode) From 18283ed179bf3b99c04eedf3f1dcd6e38b6facad Mon Sep 17 00:00:00 2001 From: LiShuzhen Date: Tue, 17 Dec 2024 17:50:08 +0800 Subject: [PATCH 03/23] perf: remove permanent true statement --- custom_components/xiaomi_home/climate.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/custom_components/xiaomi_home/climate.py b/custom_components/xiaomi_home/climate.py index 0b1ffd7..a1d2ad4 100644 --- a/custom_components/xiaomi_home/climate.py +++ b/custom_components/xiaomi_home/climate.py @@ -255,7 +255,7 @@ class AirConditioner(MIoTServiceEntity, ClimateEntity): async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None: """Set new target hvac mode.""" # set air-conditioner off - if hvac_mode == HVACMode.OFF and self._prop_on: + if hvac_mode == HVACMode.OFF: if not await self.set_property_async( prop=self._prop_on, value=False): raise RuntimeError( @@ -263,7 +263,7 @@ class AirConditioner(MIoTServiceEntity, ClimateEntity): f'{self.entity_id}') return # set air-conditioner on - if hvac_mode != HVACMode.OFF and not self.get_prop_value( + elif not self.get_prop_value( prop=self._prop_on): await self.set_property_async(prop=self._prop_on, value=True) # set mode @@ -372,7 +372,7 @@ class AirConditioner(MIoTServiceEntity, ClimateEntity): @ property def hvac_mode(self) -> Optional[HVACMode]: """Return the hvac mode. e.g., heat, cool mode.""" - if self._prop_on and self.get_prop_value(prop=self._prop_on) is False: + if not self.get_prop_value(prop=self._prop_on): return HVACMode.OFF return self.get_map_description( map_=self._hvac_mode_map, From ac5901bf1f50da189dbfa36d2b5ad9735f8ba020 Mon Sep 17 00:00:00 2001 From: LiShuzhen Date: Tue, 17 Dec 2024 17:57:02 +0800 Subject: [PATCH 04/23] fix: bool value false --- custom_components/xiaomi_home/climate.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/custom_components/xiaomi_home/climate.py b/custom_components/xiaomi_home/climate.py index a1d2ad4..cc12373 100644 --- a/custom_components/xiaomi_home/climate.py +++ b/custom_components/xiaomi_home/climate.py @@ -263,8 +263,7 @@ class AirConditioner(MIoTServiceEntity, ClimateEntity): f'{self.entity_id}') return # set air-conditioner on - elif not self.get_prop_value( - prop=self._prop_on): + elif self.get_prop_value(prop=self._prop_on) is False: await self.set_property_async(prop=self._prop_on, value=True) # set mode mode_value = self.get_map_value( @@ -372,7 +371,7 @@ class AirConditioner(MIoTServiceEntity, ClimateEntity): @ property def hvac_mode(self) -> Optional[HVACMode]: """Return the hvac mode. e.g., heat, cool mode.""" - if not self.get_prop_value(prop=self._prop_on): + if self.get_prop_value(prop=self._prop_on) is False: return HVACMode.OFF return self.get_map_description( map_=self._hvac_mode_map, From 8a1e464cdd748c44c0712ae99292c251345748a2 Mon Sep 17 00:00:00 2001 From: topsworld Date: Tue, 17 Dec 2024 17:41:00 +0800 Subject: [PATCH 05/23] fix: invalid cover status --- custom_components/xiaomi_home/cover.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/custom_components/xiaomi_home/cover.py b/custom_components/xiaomi_home/cover.py index 0e6da09..d8236c7 100644 --- a/custom_components/xiaomi_home/cover.py +++ b/custom_components/xiaomi_home/cover.py @@ -97,9 +97,9 @@ class Cover(MIoTServiceEntity, CoverEntity): _prop_motor_value_close: Optional[int] _prop_motor_value_pause: Optional[int] _prop_status: Optional[MIoTSpecProperty] - _prop_status_opening: Optional[bool] - _prop_status_closing: Optional[bool] - _prop_status_stop: Optional[bool] + _prop_status_opening: Optional[int] + _prop_status_closing: Optional[int] + _prop_status_stop: Optional[int] _prop_current_position: Optional[MIoTSpecProperty] _prop_target_position: Optional[MIoTSpecProperty] _prop_position_value_min: Optional[int] @@ -120,6 +120,9 @@ class Cover(MIoTServiceEntity, CoverEntity): self._prop_motor_value_close = None self._prop_motor_value_pause = None self._prop_status = None + self._prop_status_opening = None + self._prop_status_closing = None + self._prop_status_stop = None self._prop_current_position = None self._prop_target_position = None self._prop_position_value_min = None @@ -159,11 +162,11 @@ class Cover(MIoTServiceEntity, CoverEntity): 'status value_list is None, %s', self.entity_id) continue for item in prop.value_list: - if item['name'].lower() in ['opening']: + if item['name'].lower() in ['opening', 'open']: self._prop_status_opening = item['value'] - elif item['name'].lower() in ['closing']: + elif item['name'].lower() in ['closing', 'close']: self._prop_status_closing = item['value'] - elif item['name'].lower() in ['stop']: + elif item['name'].lower() in ['stop', 'pause']: self._prop_status_stop = item['value'] self._prop_status = prop elif prop.name == 'current-position': From bf435374d22130b254e74f5b9bf0d6a0339d5b97 Mon Sep 17 00:00:00 2001 From: topsworld Date: Tue, 17 Dec 2024 20:50:01 +0800 Subject: [PATCH 06/23] fix: water heater entity add STATE_OFF --- custom_components/xiaomi_home/water_heater.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/custom_components/xiaomi_home/water_heater.py b/custom_components/xiaomi_home/water_heater.py index 1828316..bcf158d 100644 --- a/custom_components/xiaomi_home/water_heater.py +++ b/custom_components/xiaomi_home/water_heater.py @@ -53,6 +53,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.components.water_heater import ( + STATE_OFF, ATTR_TEMPERATURE, WaterHeaterEntity, WaterHeaterEntityFeature @@ -116,6 +117,7 @@ class WaterHeater(MIoTServiceEntity, WaterHeaterEntity): if isinstance(prop.value_range, dict): self._attr_min_temp = prop.value_range['min'] self._attr_max_temp = prop.value_range['max'] + self._attr_precision = prop.value_range['step'] if ( self._attr_temperature_unit is None and prop.external_unit @@ -149,6 +151,7 @@ class WaterHeater(MIoTServiceEntity, WaterHeaterEntity): self._attr_supported_features |= ( WaterHeaterEntityFeature.OPERATION_MODE) self._prop_mode = prop + self._attr_operation_list.append(STATE_OFF) async def async_turn_on(self) -> None: """Turn the water heater on.""" @@ -167,6 +170,12 @@ class WaterHeater(MIoTServiceEntity, WaterHeaterEntity): """Set the operation mode of the water heater. Must be in the operation_list. """ + if operation_mode == STATE_OFF: + await self.set_property_async(prop=self._prop_on, value=False) + return + if self.get_prop_value(prop=self._prop_on) is False: + await self.set_property_async( + prop=self._prop_on, value=True, update=False) await self.set_property_async( prop=self._prop_mode, value=self.__get_mode_value(description=operation_mode)) @@ -188,6 +197,8 @@ class WaterHeater(MIoTServiceEntity, WaterHeaterEntity): @property def current_operation(self) -> Optional[str]: """Return the current mode.""" + if self.get_prop_value(prop=self._prop_on) is False: + return STATE_OFF return self.__get_mode_description( key=self.get_prop_value(prop=self._prop_mode)) From 1fd5e8e57d5e54e1de3f7b70e2c07135fedc4943 Mon Sep 17 00:00:00 2001 From: topsworld Date: Tue, 17 Dec 2024 21:01:56 +0800 Subject: [PATCH 07/23] fix: set the temperature limit --- custom_components/xiaomi_home/water_heater.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/custom_components/xiaomi_home/water_heater.py b/custom_components/xiaomi_home/water_heater.py index bcf158d..a6217ae 100644 --- a/custom_components/xiaomi_home/water_heater.py +++ b/custom_components/xiaomi_home/water_heater.py @@ -115,9 +115,6 @@ class WaterHeater(MIoTServiceEntity, WaterHeaterEntity): # temperature if prop.name == 'temperature': if isinstance(prop.value_range, dict): - self._attr_min_temp = prop.value_range['min'] - self._attr_max_temp = prop.value_range['max'] - self._attr_precision = prop.value_range['step'] if ( self._attr_temperature_unit is None and prop.external_unit @@ -130,6 +127,9 @@ class WaterHeater(MIoTServiceEntity, WaterHeaterEntity): self.entity_id) # target-temperature if prop.name == 'target-temperature': + self._attr_min_temp = prop.value_range['min'] + self._attr_max_temp = prop.value_range['max'] + self._attr_precision = prop.value_range['step'] if self._attr_temperature_unit is None and prop.external_unit: self._attr_temperature_unit = prop.external_unit self._attr_supported_features |= ( From 189060dd864e83b476f03edd8e2fb217f9ab6012 Mon Sep 17 00:00:00 2001 From: topsworld Date: Tue, 17 Dec 2024 21:30:55 +0800 Subject: [PATCH 08/23] fix: add STATE_ON to devices that not define mode --- custom_components/xiaomi_home/water_heater.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/custom_components/xiaomi_home/water_heater.py b/custom_components/xiaomi_home/water_heater.py index a6217ae..ee6a91d 100644 --- a/custom_components/xiaomi_home/water_heater.py +++ b/custom_components/xiaomi_home/water_heater.py @@ -53,6 +53,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.components.water_heater import ( + STATE_ON, STATE_OFF, ATTR_TEMPERATURE, WaterHeaterEntity, @@ -151,6 +152,8 @@ class WaterHeater(MIoTServiceEntity, WaterHeaterEntity): self._attr_supported_features |= ( WaterHeaterEntityFeature.OPERATION_MODE) self._prop_mode = prop + if not self._attr_operation_list: + self._attr_operation_list = [STATE_ON] self._attr_operation_list.append(STATE_OFF) async def async_turn_on(self) -> None: @@ -173,6 +176,9 @@ class WaterHeater(MIoTServiceEntity, WaterHeaterEntity): if operation_mode == STATE_OFF: await self.set_property_async(prop=self._prop_on, value=False) return + if operation_mode == STATE_ON: + await self.set_property_async(prop=self._prop_on, value=True) + return if self.get_prop_value(prop=self._prop_on) is False: await self.set_property_async( prop=self._prop_on, value=True, update=False) @@ -199,6 +205,8 @@ class WaterHeater(MIoTServiceEntity, WaterHeaterEntity): """Return the current mode.""" if self.get_prop_value(prop=self._prop_on) is False: return STATE_OFF + if not self._prop_mode and self.get_prop_value(prop=self._prop_on): + return STATE_ON return self.__get_mode_description( key=self.get_prop_value(prop=self._prop_mode)) From 99e654f0c7285ab959980a1c36a272192afe2604 Mon Sep 17 00:00:00 2001 From: topsworld Date: Wed, 18 Dec 2024 10:34:07 +0800 Subject: [PATCH 09/23] style: remove invalid space --- custom_components/xiaomi_home/climate.py | 14 +++++++------- custom_components/xiaomi_home/config_flow.py | 4 ++-- custom_components/xiaomi_home/light.py | 4 ++-- custom_components/xiaomi_home/miot/miot_client.py | 2 +- custom_components/xiaomi_home/miot/miot_lan.py | 4 ++-- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/custom_components/xiaomi_home/climate.py b/custom_components/xiaomi_home/climate.py index cc12373..909fee4 100644 --- a/custom_components/xiaomi_home/climate.py +++ b/custom_components/xiaomi_home/climate.py @@ -344,31 +344,31 @@ class AirConditioner(MIoTServiceEntity, ClimateEntity): f'set climate prop.fan_mode failed, {fan_mode}, ' f'{self.entity_id}') - @ property + @property def target_temperature(self) -> Optional[float]: """Return the target temperature.""" return self.get_prop_value( prop=self._prop_target_temp) if self._prop_target_temp else None - @ property + @property def target_humidity(self) -> Optional[int]: """Return the target humidity.""" return self.get_prop_value( prop=self._prop_target_humi) if self._prop_target_humi else None - @ property + @property def current_temperature(self) -> Optional[float]: """Return the current temperature.""" return self.get_prop_value( prop=self._prop_env_temp) if self._prop_env_temp else None - @ property + @property def current_humidity(self) -> Optional[int]: """Return the current humidity.""" return self.get_prop_value( prop=self._prop_env_humi) if self._prop_env_humi else None - @ property + @property def hvac_mode(self) -> Optional[HVACMode]: """Return the hvac mode. e.g., heat, cool mode.""" if self.get_prop_value(prop=self._prop_on) is False: @@ -377,7 +377,7 @@ class AirConditioner(MIoTServiceEntity, ClimateEntity): map_=self._hvac_mode_map, key=self.get_prop_value(prop=self._prop_mode)) - @ property + @property def fan_mode(self) -> Optional[str]: """Return the fan mode. @@ -387,7 +387,7 @@ class AirConditioner(MIoTServiceEntity, ClimateEntity): map_=self._fan_mode_map, key=self.get_prop_value(prop=self._prop_fan_level)) - @ property + @property def swing_mode(self) -> Optional[str]: """Return the swing mode. diff --git a/custom_components/xiaomi_home/config_flow.py b/custom_components/xiaomi_home/config_flow.py index ccc91f9..c1e4e67 100644 --- a/custom_components/xiaomi_home/config_flow.py +++ b/custom_components/xiaomi_home/config_flow.py @@ -564,8 +564,8 @@ class XiaomiMihomeConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): last_step=False, ) - @ staticmethod - @ callback + @staticmethod + @callback def async_get_options_flow( config_entry: config_entries.ConfigEntry, ) -> config_entries.OptionsFlow: diff --git a/custom_components/xiaomi_home/light.py b/custom_components/xiaomi_home/light.py index 610882e..49229f5 100644 --- a/custom_components/xiaomi_home/light.py +++ b/custom_components/xiaomi_home/light.py @@ -236,7 +236,7 @@ class Light(MIoTServiceEntity, LightEntity): """Return the color temperature.""" return self.get_prop_value(prop=self._prop_color_temp) - @ property + @property def rgb_color(self) -> Optional[tuple[int, int, int]]: """Return the rgb color value.""" rgb = self.get_prop_value(prop=self._prop_color) @@ -247,7 +247,7 @@ class Light(MIoTServiceEntity, LightEntity): b = rgb & 0xFF return r, g, b - @ property + @property def effect(self) -> Optional[str]: """Return the current mode.""" return self.__get_mode_description( diff --git a/custom_components/xiaomi_home/miot/miot_client.py b/custom_components/xiaomi_home/miot/miot_client.py index 771de41..31c87f0 100644 --- a/custom_components/xiaomi_home/miot/miot_client.py +++ b/custom_components/xiaomi_home/miot/miot_client.py @@ -1760,7 +1760,7 @@ class MIoTClient: delay_sec, self.__show_devices_changed_notify) -@ staticmethod +@staticmethod async def get_miot_instance_async( hass: HomeAssistant, entry_id: str, entry_data: Optional[dict] = None, persistent_notify: Optional[Callable[[str, str, str], None]] = None diff --git a/custom_components/xiaomi_home/miot/miot_lan.py b/custom_components/xiaomi_home/miot/miot_lan.py index 4635572..525be2f 100644 --- a/custom_components/xiaomi_home/miot/miot_lan.py +++ b/custom_components/xiaomi_home/miot/miot_lan.py @@ -564,11 +564,11 @@ class MIoTLan: 0, lambda: self._main_loop.create_task( self.init_async())) - @ property + @property def virtual_did(self) -> str: return self._virtual_did - @ property + @property def mev(self) -> MIoTEventLoop: return self._mev From b5f9e931b70cf4013eebc1aa83923d7ef92d7cdd Mon Sep 17 00:00:00 2001 From: topsworld Date: Wed, 18 Dec 2024 10:35:59 +0800 Subject: [PATCH 10/23] feat: support xiaomi heater devices --- custom_components/xiaomi_home/climate.py | 112 +++++++++++++++++- .../xiaomi_home/miot/specs/specv2entity.py | 27 ++++- 2 files changed, 135 insertions(+), 4 deletions(-) diff --git a/custom_components/xiaomi_home/climate.py b/custom_components/xiaomi_home/climate.py index 909fee4..ccda2b6 100644 --- a/custom_components/xiaomi_home/climate.py +++ b/custom_components/xiaomi_home/climate.py @@ -82,9 +82,12 @@ async def async_setup_entry( new_entities = [] for miot_device in device_list: - for data in miot_device.entity_list.get('climate', []): + for data in miot_device.entity_list.get('air-conditioner', []): new_entities.append( AirConditioner(miot_device=miot_device, entity_data=data)) + for data in miot_device.entity_list.get('heater', []): + new_entities.append( + Heater(miot_device=miot_device, entity_data=data)) if new_entities: async_add_entities(new_entities) @@ -115,7 +118,7 @@ class AirConditioner(MIoTServiceEntity, ClimateEntity): def __init__( self, miot_device: MIoTDevice, entity_data: MIoTEntityData ) -> None: - """Initialize the Climate.""" + """Initialize the Air conditioner.""" super().__init__(miot_device=miot_device, entity_data=entity_data) self._attr_icon = 'mdi:air-conditioner' self._attr_supported_features = ClimateEntityFeature(0) @@ -473,3 +476,108 @@ class AirConditioner(MIoTServiceEntity, ClimateEntity): self._value_ac_state.update(v_ac_state) _LOGGER.debug( 'ac_state update, %s', self._value_ac_state) + + +class Heater(MIoTServiceEntity, ClimateEntity): + """Heater entities for Xiaomi Home.""" + # service: heater + _prop_on: Optional[MIoTSpecProperty] + _prop_mode: Optional[MIoTSpecProperty] + _prop_target_temp: Optional[MIoTSpecProperty] + # service: environment + _prop_env_temp: Optional[MIoTSpecProperty] + _prop_env_humi: Optional[MIoTSpecProperty] + + def __init__( + self, miot_device: MIoTDevice, entity_data: MIoTEntityData + ) -> None: + """Initialize the Heater.""" + super().__init__(miot_device=miot_device, entity_data=entity_data) + self._attr_icon = 'mdi:air-conditioner' + self._attr_supported_features = ClimateEntityFeature(0) + + self._prop_on = None + self._prop_mode = None + self._prop_target_temp = None + self._prop_env_temp = None + self._prop_env_humi = None + + # properties + for prop in entity_data.props: + if prop.name == 'on': + self._attr_supported_features |= ( + ClimateEntityFeature.TURN_ON) + self._attr_supported_features |= ( + ClimateEntityFeature.TURN_OFF) + self._prop_on = prop + elif prop.name == 'target-temperature': + if not isinstance(prop.value_range, dict): + _LOGGER.error( + 'invalid target-temperature value_range format, %s', + self.entity_id) + continue + self._attr_min_temp = prop.value_range['min'] + self._attr_max_temp = prop.value_range['max'] + self._attr_target_temperature_step = prop.value_range['step'] + self._attr_temperature_unit = prop.external_unit + self._attr_supported_features |= ( + ClimateEntityFeature.TARGET_TEMPERATURE) + self._prop_target_temp = prop + elif prop.name == 'temperature': + self._prop_env_temp = prop + elif prop.name == 'relative-humidity': + self._prop_env_humi = prop + + # hvac modes + self._attr_hvac_modes = [HVACMode.HEAT, HVACMode.OFF] + + async def async_turn_on(self) -> None: + """Turn the entity on.""" + await self.set_property_async(prop=self._prop_on, value=True) + + async def async_turn_off(self) -> None: + """Turn the entity off.""" + await self.set_property_async(prop=self._prop_on, value=False) + + async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None: + """Set new target hvac mode.""" + await self.set_property_async( + prop=self._prop_on, value=False + if hvac_mode == HVACMode.OFF else True) + + async def async_set_temperature(self, **kwargs): + """Set new target temperature.""" + if ATTR_TEMPERATURE in kwargs: + temp = kwargs[ATTR_TEMPERATURE] + if temp > self.max_temp: + temp = self.max_temp + elif temp < self.min_temp: + temp = self.min_temp + + await self.set_property_async( + prop=self._prop_target_temp, value=temp) + + @property + def target_temperature(self) -> Optional[float]: + """Return the target temperature.""" + return self.get_prop_value( + prop=self._prop_target_temp) if self._prop_target_temp else None + + @property + def current_temperature(self) -> Optional[float]: + """Return the current temperature.""" + return self.get_prop_value( + prop=self._prop_env_temp) if self._prop_env_temp else None + + @property + def current_humidity(self) -> Optional[int]: + """Return the current humidity.""" + return self.get_prop_value( + prop=self._prop_env_humi) if self._prop_env_humi else None + + @property + def hvac_mode(self) -> Optional[HVACMode]: + """Return the hvac mode.""" + return ( + HVACMode.HEAT if self.get_prop_value(prop=self._prop_on) + else HVACMode.OFF) diff --git a/custom_components/xiaomi_home/miot/specs/specv2entity.py b/custom_components/xiaomi_home/miot/specs/specv2entity.py index 5c64083..084cb1a 100644 --- a/custom_components/xiaomi_home/miot/specs/specv2entity.py +++ b/custom_components/xiaomi_home/miot/specs/specv2entity.py @@ -208,9 +208,32 @@ SPEC_DEVICE_TRANS_MAP: dict[str, dict | str] = { } } }, - 'entity': 'climate' + 'entity': 'air-conditioner' }, - 'air-condition-outlet': 'air-conditioner' + 'air-condition-outlet': 'air-conditioner', + 'heater': { + 'required': { + 'heater': { + 'required': { + 'properties': { + 'on': {'read', 'write'} + } + }, + 'optional': { + 'properties': {'target-temperature'} + }, + } + }, + 'optional': { + 'environment': { + 'required': {}, + 'optional': { + 'properties': {'temperature', 'relative-humidity'} + } + }, + }, + 'entity': 'heater' + } } """SPEC_SERVICE_TRANS_MAP From 7a50778d2b8c5e3c0aad417ef2ddff25fc32cce9 Mon Sep 17 00:00:00 2001 From: Hudson Brendon Date: Wed, 18 Dec 2024 00:24:46 -0300 Subject: [PATCH 11/23] Create pt.json --- .../xiaomi_home/translations/pt.json | 144 ++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 custom_components/xiaomi_home/translations/pt.json diff --git a/custom_components/xiaomi_home/translations/pt.json b/custom_components/xiaomi_home/translations/pt.json new file mode 100644 index 0000000..ca72df4 --- /dev/null +++ b/custom_components/xiaomi_home/translations/pt.json @@ -0,0 +1,144 @@ +{ + "config": { + "flow_title": "Integração Xiaomi Home", + "step": { + "eula": { + "title": "Aviso de Risco", + "description": "1. As informações da sua conta Xiaomi e dos seus dispositivos serão armazenadas no sistema do Home Assistant. **A Xiaomi não pode garantir a segurança do mecanismo de armazenamento do Home Assistant**. É da sua responsabilidade impedir que a sua informação seja roubada.\r\n2. Esta integração é mantida pela comunidade open-source. Podem ocorrer problemas de estabilidade ou outros. Ao encontrar problemas ou falhas nesta integração, **deverá procurar ajuda junto da comunidade open-source, em vez de contactar o apoio ao cliente da Xiaomi**.\r\n3. Necessitará de algumas competências técnicas para manter o seu ambiente de operação local. Esta integração não é intuitiva para utilizadores iniciantes.\r\n4. Leia o ficheiro README antes de começar.\n\n5. Para garantir uma utilização estável da integração e prevenir uso indevido, **esta integração só pode ser utilizada no Home Assistant. Para mais detalhes, consulte a LICENSE**.", + "data": { + "eula": "Estou ciente dos riscos acima e disposto(a) a assumi-los voluntariamente ao utilizar a integração." + } + }, + "auth_config": { + "title": "Configuração Básica", + "description": "### Região de Login\r\nSelecione a região da sua conta Xiaomi. Pode encontrá-la na aplicação Xiaomi Home > Perfil (menu inferior) > Configurações adicionais > Sobre o Xiaomi Home.\r\n### Idioma\r\nSelecione o idioma para os nomes de dispositivos e entidades. Algumas frases sem tradução serão apresentadas em inglês.\r\n### URL de Redirecionamento OAuth2\r\nO endereço de redirecionamento para a autenticação OAuth2 é **[http://homeassistant.local:8123](http://homeassistant.local:8123)**. O Home Assistant deve estar na mesma rede local que o terminal atual (por exemplo, o computador pessoal) e esse terminal deve conseguir aceder à página inicial do Home Assistant através deste endereço. Caso contrário, a autenticação de login pode falhar.\r\n### Notas\r\n- Para utilizadores com centenas (ou mais) de dispositivos Mi Home, a adição inicial da integração demorará algum tempo. Seja paciente.\r\n- Se o Home Assistant estiver a ser executado num ambiente Docker, assegure-se de que o modo de rede do Docker está configurado como host; caso contrário, a funcionalidade de controlo local pode não funcionar corretamente.\r\n- A funcionalidade de controlo local da integração tem algumas dependências. Leia cuidadosamente o README.", + "data": { + "cloud_server": "Região de Login", + "integration_language": "Idioma", + "oauth_redirect_url": "URL de Redirecionamento OAuth2" + } + }, + "oauth_error": { + "title": "Erro de Login", + "description": "Clique em SEGUINTE para tentar novamente." + }, + "devices_filter": { + "title": "Selecione a Casa e os Dispositivos", + "description": "## Instruções de Utilização\r\n### Modo de Controlo\r\n- Automático: Quando existir um gateway central Xiaomi disponível na rede local, o Home Assistant dará prioridade ao envio de comandos de controlo através do gateway central, permitindo um controlo local. Caso não exista um gateway central na rede local, tentará enviar comandos através da funcionalidade de controlo LAN. Apenas se estas condições não forem cumpridas, os comandos serão enviados pela nuvem.\r\n- Nuvem: Todos os comandos de controlo são enviados através da nuvem.\r\n### Importar dispositivos da casa\r\nA integração adicionará dispositivos das casas selecionadas.\n### Modo de sincronização do nome da divisão\r\nAo importar dispositivos da aplicação Xiaomi Home para o Home Assistant, a nomeação da área onde o dispositivo é adicionado segue as regras abaixo. Note que o processo de sincronização dos dispositivos não altera as definições de casa ou divisão na aplicação Xiaomi Home.\r\n- Não sincronizar: O dispositivo não será atribuído a qualquer área.\r\n- Outras opções: O dispositivo será adicionado a uma área cujo nome corresponde ao da casa e/ou divisão definida na aplicação Xiaomi Home.\r\n### Modo de depuração de ação\r\nPara as ações definidas no MIoT-Spec-V2 do dispositivo, será criada uma entidade do tipo texto juntamente com uma entidade de notificação, nas quais poderá enviar comandos de controlo ao dispositivo para fins de depuração.\r\n### Ocultar entidades não padrão\r\nOculta as entidades geradas a partir de instâncias não padrão do MIoT-Spec-V2, cujos nomes começam por \"*\".\r\n\r\n \r\n### Olá {nick_name}, selecione o modo de controlo da integração e a casa na qual deseja importar os dispositivos.", + "data": { + "ctrl_mode": "Modo de Controlo", + "home_infos": "Importar dispositivos da casa", + "area_name_rule": "Modo de sincronização do nome da divisão", + "action_debug": "Modo de depuração de ação", + "hide_non_standard_entities": "Ocultar entidades não padrão" + } + } + }, + "progress": { + "oauth": "### {link_left}Clique aqui para iniciar sessão{link_right}\r\n(Será automaticamente redirecionado após um login bem-sucedido)" + }, + "error": { + "eula_not_agree": "Por favor, leia o aviso de risco.", + "get_token_error": "Não foi possível obter a informação de autorização de login (token OAuth).", + "get_homeinfo_error": "Não foi possível obter a informação da casa.", + "mdns_discovery_error": "Exceção no serviço de descoberta de dispositivos locais.", + "get_cert_error": "Não foi possível obter o certificado do gateway central.", + "no_family_selected": "Nenhuma casa selecionada.", + "no_devices": "A casa selecionada não possui quaisquer dispositivos. Por favor, selecione uma casa que contenha dispositivos e continue.", + "no_central_device": "O [Modo Gateway Central] requer um gateway central Xiaomi disponível na rede local onde o Home Assistant está. Verifique se a casa selecionada cumpre este requisito." + }, + "abort": { + "network_connect_error": "A configuração falhou. A ligação de rede é anormal. Verifique a configuração de rede do equipamento.", + "already_configured": "A configuração para este utilizador já foi concluída. Vá à página de integrações e clique em CONFIGURAR para efetuar alterações.", + "invalid_auth_info": "A informação de autenticação expirou. Vá à página de integrações e clique em CONFIGURAR para reautenticar.", + "config_flow_error": "Erro na configuração da integração: {error}." + } + }, + "options": { + "step": { + "auth_config": { + "title": "Configuração de Autenticação", + "description": "A informação de autenticação local expirou. Por favor, reinicie o processo de autenticação.\r\n### Região de Login Atual: {cloud_server}\r\n### URL de Redirecionamento OAuth2\r\nO endereço de redirecionamento para a autenticação OAuth2 é **[http://homeassistant.local:8123](http://homeassistant.local:8123)**. O Home Assistant deve estar na mesma rede local que o terminal atual (por exemplo, o computador) e esse terminal deve conseguir aceder à página inicial do Home Assistant através deste endereço. Caso contrário, a autenticação poderá falhar.", + "data": { + "oauth_redirect_url": "URL de Redirecionamento OAuth2" + } + }, + "oauth_error": { + "title": "Ocorreu um erro durante o login.", + "description": "Clique em SEGUINTE para tentar novamente." + }, + "config_options": { + "title": "Opções de Configuração", + "description": "### Olá, {nick_name}\r\n\r\nID Xiaomi: {uid}\r\nRegião de Login Atual: {cloud_server}\r\n\r\nSelecione as opções que pretende configurar e depois clique em SEGUINTE.", + "data": { + "integration_language": "Idioma da Integração", + "update_user_info": "Atualizar informação do utilizador", + "update_devices": "Atualizar lista de dispositivos", + "action_debug": "Modo de depuração de ação", + "hide_non_standard_entities": "Ocultar entidades não padrão", + "update_trans_rules": "Atualizar regras de conversão de entidades", + "update_lan_ctrl_config": "Atualizar configuração de controlo LAN" + } + }, + "update_user_info": { + "title": "Atualizar Alcunha do Utilizador", + "description": "Olá {nick_name}, pode modificar a sua alcunha personalizada abaixo.", + "data": { + "nick_name": "Alcunha" + } + }, + "devices_filter": { + "title": "Selecionar novamente a Casa e os Dispositivos", + "description": "## Instruções de Utilização\r\n### Modo de Controlo\r\n- Automático: Quando houver um gateway central Xiaomi disponível na rede local, o Home Assistant priorizará o envio de comandos através dele para obter controlo local. Se não existir um gateway central, tentará enviar comandos através da função de controlo LAN da Xiaomi. Apenas se estas condições não forem satisfeitas, os comandos serão enviados pela nuvem.\r\n- Nuvem: Todos os comandos de controlo são enviados através da nuvem.\r\n### Importar dispositivos da casa\r\nA integração adicionará dispositivos das casas selecionadas.\r\n \r\n### Olá {nick_name}, selecione o modo de controlo da integração e a casa da qual pretende importar dispositivos.", + "data": { + "ctrl_mode": "Modo de Controlo", + "home_infos": "Importar dispositivos da casa" + } + }, + "update_trans_rules": { + "title": "Atualizar Regras de Transformação de Entidades", + "description": "## Instruções de Utilização\r\n- Atualiza a informação das entidades dos dispositivos na instância atual da integração, incluindo configuração multilingue MIoT-Spec-V2, tradução de booleanos e filtragem de modelos.\r\n- **Aviso**: Esta é uma configuração global e atualizará a cache local, afetando todas as instâncias da integração.\r\n- Esta operação levará algum tempo, seja paciente. Selecione \"Confirmar a atualização\" e clique em \"SEGUINTE\" para iniciar a atualização de **{urn_count}** regras, caso contrário, ignore esta etapa.\r\n", + "data": { + "confirm": "Confirmar a atualização" + } + }, + "update_lan_ctrl_config": { + "title": "Atualizar Configuração de Controlo LAN", + "description": "## Instruções de Utilização\r\nAtualize as configurações para a funcionalidade de controlo LAN da Xiaomi. Quando a nuvem e o gateway central não puderem controlar os dispositivos, a integração tentará controlá-los através da LAN. Se não selecionar nenhuma interface de rede, o controlo LAN não terá efeito.\r\n- Apenas dispositivos compatíveis com MIoT-Spec-V2 ligados via IP na LAN são suportados. Alguns dispositivos produzidos antes de 2020 podem não suportar controlo LAN ou subscrição LAN.\r\n- Selecione a(s) placa(s) de rede que estejam na mesma rede que os dispositivos a controlar. Pode selecionar várias placas. Se o Home Assistant tiver duas ou mais ligações à rede local devido à seleção de várias placas, é recomendado selecionar a que tiver melhor ligação, caso contrário poderá afetar negativamente o desempenho dos dispositivos.\r\n- Se houver dispositivos terminais (colunas Xiaomi com ecrã, telemóveis, etc.) na LAN que suportem controlo local, a ativação da subscrição LAN pode causar anomalias em automações e dispositivos locais.\r\n- **Aviso**: Esta é uma configuração global, afetando todas as instâncias da integração. Utilize com cautela.\r\n{notice_net_dup}", + "data": { + "net_interfaces": "Selecione a(s) interface(s) de rede a utilizar", + "enable_subscribe": "Ativar subscrição LAN" + } + }, + "config_confirm": { + "title": "Confirmar Configuração", + "description": "Olá **{nick_name}**, confirme a informação da configuração mais recente e depois clique em SUBMETER.\r\nA integração será recarregada com a configuração atualizada.\r\n\r\nIdioma da Integração:\t{lang_new}\r\nAlcunha:\t{nick_name_new}\r\nModo de depuração de ação:\t{action_debug}\r\nOcultar entidades não padrão:\t{hide_non_standard_entities}\r\nAlterações aos Dispositivos:\tAdicionar **{devices_add}** dispositivos, Remover **{devices_remove}** dispositivos\r\nAlteração das Regras de Transformação:\tExistem **{trans_rules_count}** regras no total, com **{trans_rules_count_success}** regras atualizadas", + "data": { + "confirm": "Confirmar a alteração" + } + } + }, + "progress": { + "oauth": "### {link_left}Por favor, clique aqui para voltar a iniciar sessão{link_right}" + }, + "error": { + "not_auth": "Não autenticado. Por favor, clique no link de autenticação para confirmar a sua identidade.", + "get_token_error": "Não foi possível obter a informação de autorização de login (token OAuth).", + "get_homeinfo_error": "Não foi possível obter a informação da casa.", + "get_cert_error": "Não foi possível obter o certificado do gateway central.", + "no_devices": "A casa selecionada não possui quaisquer dispositivos. Por favor, selecione uma casa com dispositivos e continue.", + "no_family_selected": "Nenhuma casa selecionada.", + "no_central_device": "O [Modo Gateway Central] requer um gateway central Xiaomi disponível na rede local onde o Home Assistant está. Verifique se a casa selecionada cumpre este requisito.", + "mdns_discovery_error": "Exceção no serviço de descoberta de dispositivos locais.", + "update_config_error": "Não foi possível atualizar a informação de configuração.", + "not_confirm": "As alterações não foram confirmadas. Por favor, confirme a alteração antes de submeter." + }, + "abort": { + "network_connect_error": "A configuração falhou. A ligação de rede é anormal. Verifique a configuração da rede do equipamento.", + "options_flow_error": "Erro na reconfiguração da integração: {error}", + "re_add": "Por favor, volte a adicionar a integração. Mensagem de erro: {error}", + "storage_error": "Exceção no módulo de armazenamento da integração. Tente novamente ou volte a adicionar a integração: {error}", + "inconsistent_account": "A informação da conta é inconsistente. Por favor, inicie sessão com a conta correta." + } + } +} From 83dbceac6de545be57fc35f76d7f5c44f28ee7c8 Mon Sep 17 00:00:00 2001 From: Hudson Brendon Date: Wed, 18 Dec 2024 00:16:15 -0300 Subject: [PATCH 12/23] Create pt-BR.json --- .../xiaomi_home/translations/pt-BR.json | 144 ++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 custom_components/xiaomi_home/translations/pt-BR.json diff --git a/custom_components/xiaomi_home/translations/pt-BR.json b/custom_components/xiaomi_home/translations/pt-BR.json new file mode 100644 index 0000000..4ae8c2e --- /dev/null +++ b/custom_components/xiaomi_home/translations/pt-BR.json @@ -0,0 +1,144 @@ +{ + "config": { + "flow_title": "Integração Xiaomi Home", + "step": { + "eula": { + "title": "Aviso de risco", + "description": "1. Suas informações de usuário Xiaomi e informações dos dispositivos serão armazenadas no sistema Home Assistant. **A Xiaomi não pode garantir a segurança do mecanismo de armazenamento do Home Assistant**. Você é responsável por evitar que suas informações sejam roubadas.\r\n2. Esta integração é mantida pela comunidade open-source. Podem haver problemas de estabilidade ou outros problemas. Ao encontrar falhas ou erros nesta integração, **você deve buscar ajuda da comunidade open-source em vez de contatar o suporte da Xiaomi**.\r\n3. Você precisará de certa habilidade técnica para manter seu ambiente operacional local. Esta integração não é amigável para iniciantes.\r\n4. Por favor, leia o arquivo README antes de começar.\n\n5. Para garantir o uso estável da integração e evitar abusos da interface, **esta integração só é permitida para uso no Home Assistant. Para mais detalhes, consulte a LICENSE**.", + "data": { + "eula": "Estou ciente dos riscos acima e disposto(a) a assumi-los voluntariamente ao utilizar a integração." + } + }, + "auth_config": { + "title": "Configuração básica", + "description": "### Região de Login\r\nSelecione a região da sua conta Xiaomi. Você pode encontrá-la no aplicativo Xiaomi Home > Perfil (localizado no menu inferior) > Configurações adicionais > Sobre o Xiaomi Home.\r\n### Idioma\r\nSelecione o idioma dos nomes dos dispositivos e entidades. Algumas frases sem tradução serão exibidas em inglês.\r\n### URL de Redirecionamento OAuth2\r\nO endereço de redirecionamento da autenticação OAuth2 é **[http://homeassistant.local:8123](http://homeassistant.local:8123)**. O Home Assistant precisa estar na mesma rede local que o terminal atual (por exemplo, o computador pessoal) e o terminal precisa acessar a página inicial do Home Assistant através desse endereço. Caso contrário, a autenticação de login pode falhar.\r\n### Observações\r\n- Para usuários com centenas ou mais dispositivos Mi Home, a adição inicial da integração levará algum tempo. Seja paciente.\r\n- Se o Home Assistant estiver sendo executado em um ambiente Docker, certifique-se de que o modo de rede do Docker esteja definido como host, caso contrário a funcionalidade de controle local pode não funcionar corretamente.\r\n- A funcionalidade de controle local da integração tem algumas dependências. Por favor, leia o README atentamente.", + "data": { + "cloud_server": "Região de Login", + "integration_language": "Idioma", + "oauth_redirect_url": "URL de Redirecionamento OAuth2" + } + }, + "oauth_error": { + "title": "Erro de Login", + "description": "Clique em AVANÇAR para tentar novamente." + }, + "devices_filter": { + "title": "Selecione a Casa e os Dispositivos", + "description": "## Instruções de Uso\r\n### Modo de controle\r\n- Auto: Quando houver um gateway central Xiaomi disponível na rede local, o Home Assistant priorizará o envio de comandos de controle do dispositivo através do gateway central, obtendo assim controle local. Se não houver gateway central na rede local, ele tentará enviar comandos através da função de controle LAN da Xiaomi. Somente quando as condições de controle local acima não forem atendidas, os comandos serão enviados pela nuvem.\r\n- Nuvem: Todos os comandos de controle são enviados através da nuvem.\r\n### Importar dispositivos da casa\r\nA integração adicionará dispositivos das casas selecionadas.\n### Modo de sincronização do nome do cômodo\r\nAo importar dispositivos do aplicativo Xiaomi Home para o Home Assistant, a convenção de nomeação da área onde o dispositivo é adicionado é a seguinte. Observe que o processo de sincronização do dispositivo não altera as configurações de casa ou cômodo no aplicativo Xiaomi Home.\r\n- Não sincronizar: O dispositivo não será adicionado a nenhuma área.\r\n- Outras opções: O dispositivo será adicionado a uma área nomeada de acordo com o nome da casa e/ou do cômodo que já existem no aplicativo Xiaomi Home.\r\n### Modo de depuração para ação\r\nPara as ações definidas no MIoT-Spec-V2 do dispositivo, será criada uma entidade de texto juntamente com uma entidade de notificação, nas quais você poderá enviar comandos de controle ao dispositivo para fins de depuração.\r\n### Ocultar entidades criadas não padrão\r\nOculta as entidades geradas a partir de instâncias não padrão do MIoT-Spec-V2, cujos nomes começam com \"*\".\r\n\r\n \r\n### Olá {nick_name}, selecione o modo de controle da integração e a casa onde estão os dispositivos que você deseja importar.", + "data": { + "ctrl_mode": "Modo de controle", + "home_infos": "Importar dispositivos da casa", + "area_name_rule": "Modo de sincronização do nome do cômodo", + "action_debug": "Modo de depuração para ação", + "hide_non_standard_entities": "Ocultar entidades não padrão criadas" + } + } + }, + "progress": { + "oauth": "### {link_left}Clique aqui para fazer login{link_right}\r\n(Você será redirecionado automaticamente para a próxima página após um login bem-sucedido)" + }, + "error": { + "eula_not_agree": "Por favor, leia o aviso de risco.", + "get_token_error": "Falha ao obter as informações de autorização de login (token OAuth).", + "get_homeinfo_error": "Falha ao obter as informações da casa.", + "mdns_discovery_error": "Exceção no serviço de descoberta de dispositivos locais.", + "get_cert_error": "Falha ao obter o certificado do gateway central.", + "no_family_selected": "Nenhuma casa selecionada.", + "no_devices": "A casa selecionada não possui nenhum dispositivo. Por favor, escolha uma casa que contenha dispositivos e continue.", + "no_central_device": "[Modo Gateway Central] requer um gateway central Xiaomi disponível na rede local onde o Home Assistant está. Verifique se a casa selecionada atende a esse requisito." + }, + "abort": { + "network_connect_error": "Configuração falhou. A conexão de rede está anormal. Verifique a configuração de rede do equipamento.", + "already_configured": "A configuração para este usuário já foi concluída. Vá para a página de integrações e clique no botão CONFIGURAR para modificações.", + "invalid_auth_info": "As informações de autenticação expiraram. Vá para a página de integrações e clique em CONFIGURAR para reautenticar.", + "config_flow_error": "Erro na configuração da integração: {error}." + } + }, + "options": { + "step": { + "auth_config": { + "title": "Configuração de Autenticação", + "description": "As informações de autenticação local expiraram. Por favor, reinicie o processo de autenticação.\r\n### Região de Login Atual: {cloud_server}\r\n### URL de Redirecionamento OAuth2\r\nO endereço de redirecionamento da autenticação OAuth2 é **[http://homeassistant.local:8123](http://homeassistant.local:8123)**. O Home Assistant precisa estar na mesma rede local que o terminal atual (por exemplo, o computador pessoal) e o terminal precisa acessar a página inicial do Home Assistant através desse endereço. Caso contrário, a autenticação de login pode falhar.", + "data": { + "oauth_redirect_url": "URL de Redirecionamento OAuth2" + } + }, + "oauth_error": { + "title": "Ocorreu um erro durante o login.", + "description": "Clique em AVANÇAR para tentar novamente." + }, + "config_options": { + "title": "Opções de Configuração", + "description": "### Olá, {nick_name}\r\n\r\nID Xiaomi: {uid}\r\nRegião de Login Atual: {cloud_server}\r\n\r\nSelecione as opções que você deseja configurar e clique em AVANÇAR.", + "data": { + "integration_language": "Idioma da Integração", + "update_user_info": "Atualizar informações do usuário", + "update_devices": "Atualizar lista de dispositivos", + "action_debug": "Modo de depuração para ação", + "hide_non_standard_entities": "Ocultar entidades não padrão criadas", + "update_trans_rules": "Atualizar regras de conversão de entidades", + "update_lan_ctrl_config": "Atualizar configuração de controle LAN" + } + }, + "update_user_info": { + "title": "Atualizar Apelido do Usuário", + "description": "Olá {nick_name}, você pode modificar seu apelido personalizado abaixo.", + "data": { + "nick_name": "Apelido" + } + }, + "devices_filter": { + "title": "Selecionar novamente Casa e Dispositivos", + "description": "## Instruções de Uso\r\n### Modo de controle\r\n- Auto: Quando houver um gateway central Xiaomi disponível na rede local, o Home Assistant priorizará o envio de comandos através dele para obter controle local. Caso não haja, tentará enviar comandos através da função de controle LAN da Xiaomi. Somente se as condições anteriores não forem atendidas, o controle será feito pela nuvem.\r\n- Nuvem: Todos os comandos de controle são enviados pela nuvem.\r\n### Importar dispositivos da casa\r\nA integração adicionará dispositivos das casas selecionadas.\r\n \r\n### Olá {nick_name}, selecione o modo de controle da integração e a casa de onde deseja importar dispositivos.", + "data": { + "ctrl_mode": "Modo de controle", + "home_infos": "Importar dispositivos da casa" + } + }, + "update_trans_rules": { + "title": "Atualizar Regras de Transformação de Entidades", + "description": "## Instruções de Uso\r\n- Atualiza as informações das entidades dos dispositivos na instância atual da integração, incluindo configuração multilíngue MIoT-Spec-V2, tradução de booleanos e filtragem de modelos.\r\n- **Aviso**: Esta é uma configuração global e atualizará o cache local. Ela afetará todas as instâncias da integração.\r\n- Esta operação levará algum tempo, seja paciente. Marque \"Confirmar atualização\" e clique em \"Avançar\" para iniciar a atualização de **{urn_count}** regras, caso contrário, pule.\r\n", + "data": { + "confirm": "Confirmar a atualização" + } + }, + "update_lan_ctrl_config": { + "title": "Atualizar configuração de controle LAN", + "description": "## Instruções de Uso\r\nAtualize as configurações para a função de controle LAN da Xiaomi. Quando a nuvem e o gateway central não puderem controlar os dispositivos, a integração tentará controlá-los através da LAN. Se nenhuma placa de rede for selecionada, o controle LAN não terá efeito.\r\n- Somente dispositivos compatíveis com MIoT-Spec-V2 conectados via IP na LAN são suportados. Alguns dispositivos produzidos antes de 2020 podem não suportar controle LAN ou assinatura LAN.\r\n- Selecione a(s) placa(s) de rede que estão na mesma rede que os dispositivos a serem controlados. É possível selecionar várias placas. Se o Home Assistant tiver duas ou mais conexões com a rede local devido a múltiplas placas, recomenda-se selecionar a que tiver melhor conexão de rede. Caso contrário, isso pode afetar o desempenho.\r\n- Se houver dispositivos terminais (alto-falantes Xiaomi com tela, celular, etc.) na LAN que suportem controle local, habilitar a assinatura LAN pode causar comportamentos anormais em automações e dispositivos locais.\r\n- **Aviso**: Esta é uma configuração global. Afetará todas as instâncias da integração. Use com cautela.\r\n{notice_net_dup}", + "data": { + "net_interfaces": "Selecione a placa de rede a ser usada", + "enable_subscribe": "Habilitar assinatura LAN" + } + }, + "config_confirm": { + "title": "Confirmar Configuração", + "description": "Olá **{nick_name}**, confirme as informações da configuração mais recente e depois clique em ENVIAR.\r\nA integração será recarregada com a configuração atualizada.\r\n\r\nIdioma da Integração:\t{lang_new}\r\nApelido:\t{nick_name_new}\r\nModo de depuração para ação:\t{action_debug}\r\nOcultar entidades não padrão criadas:\t{hide_non_standard_entities}\r\nAlterações de Dispositivos:\tAdicionar **{devices_add}** dispositivos, Remover **{devices_remove}** dispositivos\r\nAlteração nas Regras de Transformação:\tUm total de **{trans_rules_count}** regras, e **{trans_rules_count_success}** regras atualizadas", + "data": { + "confirm": "Confirmar a mudança" + } + } + }, + "progress": { + "oauth": "### {link_left}Por favor, clique aqui para relogar{link_right}" + }, + "error": { + "not_auth": "Não autenticado. Por favor, clique no link de autenticação para autenticar sua identidade.", + "get_token_error": "Falha ao obter as informações de autorização de login (token OAuth).", + "get_homeinfo_error": "Falha ao obter as informações da casa.", + "get_cert_error": "Falha ao obter o certificado do gateway central.", + "no_devices": "A casa selecionada não possui nenhum dispositivo. Por favor, escolha uma casa com dispositivos e continue.", + "no_family_selected": "Nenhuma casa selecionada.", + "no_central_device": "[Modo Gateway Central] requer um gateway central Xiaomi disponível na rede local onde o Home Assistant está. Verifique se a casa selecionada atende a esse requisito.", + "mdns_discovery_error": "Exceção no serviço de descoberta de dispositivos locais.", + "update_config_error": "Falha ao atualizar as informações de configuração.", + "not_confirm": "As alterações não foram confirmadas. Por favor, confirme a mudança antes de enviar." + }, + "abort": { + "network_connect_error": "Configuração falhou. A conexão de rede está anormal. Verifique a configuração da rede do equipamento.", + "options_flow_error": "Erro na reconfiguração da integração: {error}", + "re_add": "Por favor, adicione novamente a integração. Mensagem de erro: {error}", + "storage_error": "Exceção no módulo de armazenamento da integração. Tente novamente ou readicione a integração: {error}", + "inconsistent_account": "As informações da conta são inconsistentes. Por favor, faça login com a conta correta." + } + } +} From 6bb4bf32d76f0f97a1a8ea4d97a1b3809393742a Mon Sep 17 00:00:00 2001 From: KNOOP Date: Tue, 17 Dec 2024 16:20:02 +0800 Subject: [PATCH 13/23] fix: handle UnitOfConductivity import Move unit imports inside function and add fallback for older versions. Resolves #123 --- .../xiaomi_home/miot/miot_device.py | 51 +++++++++++-------- 1 file changed, 31 insertions(+), 20 deletions(-) diff --git a/custom_components/xiaomi_home/miot/miot_device.py b/custom_components/xiaomi_home/miot/miot_device.py index 56637d6..3531ebf 100644 --- a/custom_components/xiaomi_home/miot/miot_device.py +++ b/custom_components/xiaomi_home/miot/miot_device.py @@ -59,20 +59,6 @@ from homeassistant.const import ( LIGHT_LUX, PERCENTAGE, SIGNAL_STRENGTH_DECIBELS, - UnitOfEnergy, - UnitOfElectricCurrent, - UnitOfElectricPotential, - UnitOfInformation, - UnitOfLength, - UnitOfMass, - UnitOfSpeed, - UnitOfTime, - UnitOfTemperature, - UnitOfPressure, - UnitOfPower, - UnitOfVolume, - UnitOfVolumeFlowRate, - UnitOfConductivity ) from homeassistant.helpers.entity import DeviceInfo from homeassistant.components.switch import SwitchDeviceClass @@ -505,7 +491,8 @@ class MIoTDevice: prop_access.add('read') if prop.writable: prop_access.add('write') - if prop_access != (SPEC_PROP_TRANS_MAP['entities'][platform]['access']): + if prop_access != (SPEC_PROP_TRANS_MAP[ + 'entities'][platform]['access']): return None if prop.format_ not in SPEC_PROP_TRANS_MAP[ 'entities'][platform]['format']: @@ -584,7 +571,24 @@ class MIoTDevice: self.append_action(action=action) def unit_convert(self, spec_unit: str) -> Optional[str]: - return { + """Convert MIoT unit to Home Assistant unit.""" + from homeassistant.const import ( + UnitOfEnergy, + UnitOfElectricCurrent, + UnitOfElectricPotential, + UnitOfInformation, + UnitOfLength, + UnitOfMass, + UnitOfSpeed, + UnitOfTime, + UnitOfTemperature, + UnitOfPressure, + UnitOfPower, + UnitOfVolume, + UnitOfVolumeFlowRate, + ) + + unit_map = { 'percentage': PERCENTAGE, 'weeks': UnitOfTime.WEEKS, 'days': UnitOfTime.DAYS, @@ -616,11 +620,18 @@ class MIoTDevice: 'm': UnitOfLength.METERS, 'km': UnitOfLength.KILOMETERS, 'm3/h': UnitOfVolumeFlowRate.CUBIC_METERS_PER_HOUR, - 'μS/cm': UnitOfConductivity.MICROSIEMENS_PER_CM, 'gram': UnitOfMass.GRAMS, 'dB': SIGNAL_STRENGTH_DECIBELS, 'kB': UnitOfInformation.KILOBYTES, - }.get(spec_unit, None) + } + + try: + from homeassistant.const import UnitOfConductivity + unit_map['μS/cm'] = UnitOfConductivity.MICROSIEMENS_PER_CM + except ImportError: + unit_map['μS/cm'] = 'μS/cm' + + return unit_map.get(spec_unit, None) def icon_convert(self, spec_unit: str) -> Optional[str]: if spec_unit in ['percentage']: @@ -1170,8 +1181,8 @@ class MIoTEventEntity(Entity): handler=self.__on_device_state_changed) # Sub value changed self.miot_device.sub_event( - handler=self.__on_event_occurred, siid=self.service.iid, - eiid=self.spec.iid) + handler=self.__on_event_occurred, + siid=self.service.iid, eiid=self.spec.iid) async def async_will_remove_from_hass(self) -> None: self.miot_device.unsub_device_state( From c744919032ca7ae81311ebae91b1d920db7752c6 Mon Sep 17 00:00:00 2001 From: KNOOP Date: Tue, 17 Dec 2024 18:21:03 +0800 Subject: [PATCH 14/23] fix: handle UnitOfConductivity import #54 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move unit imports inside function 和 add fallback for older versions. Resolves --- .../xiaomi_home/miot/miot_device.py | 32 +++++++++---------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/custom_components/xiaomi_home/miot/miot_device.py b/custom_components/xiaomi_home/miot/miot_device.py index 3531ebf..8de4c1c 100644 --- a/custom_components/xiaomi_home/miot/miot_device.py +++ b/custom_components/xiaomi_home/miot/miot_device.py @@ -54,11 +54,24 @@ from homeassistant.helpers.entity import Entity from homeassistant.const import ( CONCENTRATION_MICROGRAMS_PER_CUBIC_METER, CONCENTRATION_MILLIGRAMS_PER_CUBIC_METER, - CONCENTRATION_PARTS_PER_MILLION, CONCENTRATION_PARTS_PER_BILLION, + CONCENTRATION_PARTS_PER_MILLION, LIGHT_LUX, PERCENTAGE, SIGNAL_STRENGTH_DECIBELS, + UnitOfEnergy, + UnitOfElectricCurrent, + UnitOfElectricPotential, + UnitOfInformation, + UnitOfLength, + UnitOfMass, + UnitOfSpeed, + UnitOfTime, + UnitOfTemperature, + UnitOfPressure, + UnitOfPower, + UnitOfVolume, + UnitOfVolumeFlowRate, ) from homeassistant.helpers.entity import DeviceInfo from homeassistant.components.switch import SwitchDeviceClass @@ -572,22 +585,6 @@ class MIoTDevice: def unit_convert(self, spec_unit: str) -> Optional[str]: """Convert MIoT unit to Home Assistant unit.""" - from homeassistant.const import ( - UnitOfEnergy, - UnitOfElectricCurrent, - UnitOfElectricPotential, - UnitOfInformation, - UnitOfLength, - UnitOfMass, - UnitOfSpeed, - UnitOfTime, - UnitOfTemperature, - UnitOfPressure, - UnitOfPower, - UnitOfVolume, - UnitOfVolumeFlowRate, - ) - unit_map = { 'percentage': PERCENTAGE, 'weeks': UnitOfTime.WEEKS, @@ -625,6 +622,7 @@ class MIoTDevice: 'kB': UnitOfInformation.KILOBYTES, } + # Handle UnitOfConductivity separately since it might not be available in all HA versions try: from homeassistant.const import UnitOfConductivity unit_map['μS/cm'] = UnitOfConductivity.MICROSIEMENS_PER_CM From b498a708acf860f0a3be0f0794318aa055d8027a Mon Sep 17 00:00:00 2001 From: Guoliang Li Date: Wed, 18 Dec 2024 15:44:04 +0800 Subject: [PATCH 15/23] style: ignore pylint warning --- custom_components/xiaomi_home/miot/miot_device.py | 1 + 1 file changed, 1 insertion(+) diff --git a/custom_components/xiaomi_home/miot/miot_device.py b/custom_components/xiaomi_home/miot/miot_device.py index 8de4c1c..8fdc597 100644 --- a/custom_components/xiaomi_home/miot/miot_device.py +++ b/custom_components/xiaomi_home/miot/miot_device.py @@ -624,6 +624,7 @@ class MIoTDevice: # Handle UnitOfConductivity separately since it might not be available in all HA versions try: + # pylint: disable=import-outside-toplevel from homeassistant.const import UnitOfConductivity unit_map['μS/cm'] = UnitOfConductivity.MICROSIEMENS_PER_CM except ImportError: From e70acd8421a5105e7cf12b2ead6bfb8269a0ff9c Mon Sep 17 00:00:00 2001 From: Guoliang Li Date: Wed, 18 Dec 2024 15:48:51 +0800 Subject: [PATCH 16/23] style: update comments to meet coding standards --- custom_components/xiaomi_home/miot/miot_device.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/custom_components/xiaomi_home/miot/miot_device.py b/custom_components/xiaomi_home/miot/miot_device.py index 8fdc597..3cda670 100644 --- a/custom_components/xiaomi_home/miot/miot_device.py +++ b/custom_components/xiaomi_home/miot/miot_device.py @@ -622,7 +622,8 @@ class MIoTDevice: 'kB': UnitOfInformation.KILOBYTES, } - # Handle UnitOfConductivity separately since it might not be available in all HA versions + # Handle UnitOfConductivity separately since + # it might not be available in all HA versions try: # pylint: disable=import-outside-toplevel from homeassistant.const import UnitOfConductivity From ce4f23b1bd0a695d8b212d494e4313fe6744f2bf Mon Sep 17 00:00:00 2001 From: Guoliang Li Date: Wed, 18 Dec 2024 15:54:37 +0800 Subject: [PATCH 17/23] style: fix the trailing space problem reported by pylint --- custom_components/xiaomi_home/miot/miot_device.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/xiaomi_home/miot/miot_device.py b/custom_components/xiaomi_home/miot/miot_device.py index 3cda670..fa48345 100644 --- a/custom_components/xiaomi_home/miot/miot_device.py +++ b/custom_components/xiaomi_home/miot/miot_device.py @@ -622,7 +622,7 @@ class MIoTDevice: 'kB': UnitOfInformation.KILOBYTES, } - # Handle UnitOfConductivity separately since + # Handle UnitOfConductivity separately since # it might not be available in all HA versions try: # pylint: disable=import-outside-toplevel From 6e2de896c39731844a9cc04847ff949a62cb70d0 Mon Sep 17 00:00:00 2001 From: topsworld Date: Wed, 18 Dec 2024 17:42:40 +0800 Subject: [PATCH 18/23] feat: update xiaomi heater ctrl logic --- custom_components/xiaomi_home/climate.py | 36 +++++++++++++++++++ .../xiaomi_home/miot/specs/specv2entity.py | 2 +- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/custom_components/xiaomi_home/climate.py b/custom_components/xiaomi_home/climate.py index ccda2b6..106abb9 100644 --- a/custom_components/xiaomi_home/climate.py +++ b/custom_components/xiaomi_home/climate.py @@ -484,10 +484,13 @@ class Heater(MIoTServiceEntity, ClimateEntity): _prop_on: Optional[MIoTSpecProperty] _prop_mode: Optional[MIoTSpecProperty] _prop_target_temp: Optional[MIoTSpecProperty] + _prop_heat_level: Optional[MIoTSpecProperty] # service: environment _prop_env_temp: Optional[MIoTSpecProperty] _prop_env_humi: Optional[MIoTSpecProperty] + _heat_level_map: Optional[dict[int, str]] + def __init__( self, miot_device: MIoTDevice, entity_data: MIoTEntityData ) -> None: @@ -495,12 +498,15 @@ class Heater(MIoTServiceEntity, ClimateEntity): super().__init__(miot_device=miot_device, entity_data=entity_data) self._attr_icon = 'mdi:air-conditioner' self._attr_supported_features = ClimateEntityFeature(0) + self._attr_preset_modes = [] self._prop_on = None self._prop_mode = None self._prop_target_temp = None + self._prop_heat_level = None self._prop_env_temp = None self._prop_env_humi = None + self._heat_level_map = None # properties for prop in entity_data.props: @@ -523,6 +529,21 @@ class Heater(MIoTServiceEntity, ClimateEntity): self._attr_supported_features |= ( ClimateEntityFeature.TARGET_TEMPERATURE) self._prop_target_temp = prop + elif prop.name == 'heat-level': + if ( + not isinstance(prop.value_list, list) + or not prop.value_list + ): + _LOGGER.error( + 'invalid heat-level value_list, %s', self.entity_id) + continue + self._heat_level_map = { + item['value']: item['description'] + for item in prop.value_list} + self._attr_preset_modes = list(self._heat_level_map.values()) + self._attr_supported_features |= ( + ClimateEntityFeature.PRESET_MODE) + self._prop_heat_level = prop elif prop.name == 'temperature': self._prop_env_temp = prop elif prop.name == 'relative-humidity': @@ -557,6 +578,13 @@ class Heater(MIoTServiceEntity, ClimateEntity): await self.set_property_async( prop=self._prop_target_temp, value=temp) + async def async_set_preset_mode(self, preset_mode: str) -> None: + """Set the preset mode.""" + await self.set_property_async( + self._prop_heat_level, + value=self.get_map_value( + map_=self._heat_level_map, description=preset_mode)) + @property def target_temperature(self) -> Optional[float]: """Return the target temperature.""" @@ -581,3 +609,11 @@ class Heater(MIoTServiceEntity, ClimateEntity): return ( HVACMode.HEAT if self.get_prop_value(prop=self._prop_on) else HVACMode.OFF) + + @property + def preset_mode(self) -> Optional[str]: + return ( + self.get_map_description( + map_=self._heat_level_map, + key=self.get_prop_value(prop=self._prop_heat_level)) + if self._prop_heat_level else None) diff --git a/custom_components/xiaomi_home/miot/specs/specv2entity.py b/custom_components/xiaomi_home/miot/specs/specv2entity.py index 084cb1a..4a57867 100644 --- a/custom_components/xiaomi_home/miot/specs/specv2entity.py +++ b/custom_components/xiaomi_home/miot/specs/specv2entity.py @@ -220,7 +220,7 @@ SPEC_DEVICE_TRANS_MAP: dict[str, dict | str] = { } }, 'optional': { - 'properties': {'target-temperature'} + 'properties': {'target-temperature', 'heat-level'} }, } }, From fec5d10f42c200c20dd427bafa49aa5a46c54f55 Mon Sep 17 00:00:00 2001 From: fanjinyu Date: Wed, 18 Dec 2024 19:32:00 +0800 Subject: [PATCH 19/23] add pt and pt-BR language support in i18n --- .../xiaomi_home/miot/i18n/pt-BR.json | 95 +++++++++++++++++++ .../xiaomi_home/miot/i18n/pt.json | 95 +++++++++++++++++++ 2 files changed, 190 insertions(+) create mode 100644 custom_components/xiaomi_home/miot/i18n/pt-BR.json create mode 100644 custom_components/xiaomi_home/miot/i18n/pt.json diff --git a/custom_components/xiaomi_home/miot/i18n/pt-BR.json b/custom_components/xiaomi_home/miot/i18n/pt-BR.json new file mode 100644 index 0000000..8df352b --- /dev/null +++ b/custom_components/xiaomi_home/miot/i18n/pt-BR.json @@ -0,0 +1,95 @@ +{ + "config": { + "other": { + "devices": "dispositivos", + "found_central_gateway": "encontrado o gateway central local" + }, + "control_mode": { + "auto": "automático", + "cloud": "nuvem" + }, + "room_name_rule": { + "none": "não sincronizado", + "home_room": "Nome da casa e nome do quarto (Xiaomi Home Quarto)", + "room": "Nome do quarto (Quarto)", + "home": "Nome da casa (Xiaomi Home)" + }, + "option_status": { + "enable": "habilitado", + "disable": "desabilitado" + }, + "lan_ctrl_config": { + "notice_net_dup": "\r\n**[Aviso]** Detectado múltiplas interfaces de rede que podem estar conectando à mesma rede, por favor, selecione a correta.", + "net_unavailable": "Interface indisponível" + } + }, + "miot": { + "client": { + "invalid_oauth_info": "Informações de autenticação inválidas, a conexão com a nuvem estará indisponível. Vá para a página de integração do Xiaomi Home e clique em 'Opções' para reautenticar.", + "invalid_device_cache": "Informações de dispositivo no cache inválidas. Vá para a página de integração do Xiaomi Home e clique em 'Opções -> Atualizar lista de dispositivos' para atualizar as informações locais.", + "invalid_cert_info": "Certificado de usuário inválido. A conexão local do gateway central estará indisponível. Vá para a página de integração do Xiaomi Home e clique em 'Opções' para reautenticar.", + "device_cloud_error": "Erro ao obter informações do dispositivo da nuvem. Verifique a conexão da rede local.", + "xiaomi_home_error_title": "Erro de Integração do Xiaomi Home", + "xiaomi_home_error": "Erro detectado em **{nick_name}({uid}, {cloud_server})**. Vá para a página de opções para reconfigurar.\n\n**Erro**: \n{message}", + "device_list_changed_title": "Mudança na lista de dispositivos do Xiaomi Home", + "device_list_changed": "Detectado que as informações do dispositivo **{nick_name}({uid}, {cloud_server})** mudaram. Vá para a página de integração e clique em 'Opções -> Atualizar lista de dispositivos' para atualizar as informações locais.\n\nStatus atual da rede: {network_status}\n{message}\n", + "device_list_add": "\n**{count} dispositivos novos**: \n{message}", + "device_list_del": "\n**{count} dispositivos não disponíveis**: \n{message}", + "device_list_offline": "\n**{count} dispositivos offline**: \n{message}", + "network_status_online": "online", + "network_status_offline": "offline", + "device_exec_error": "Erro na execução" + } + }, + "error": { + "common": { + "-10000": "Erro desconhecido", + "-10001": "Serviço indisponível", + "-10002": "Parâmetro inválido", + "-10003": "Recursos insuficientes", + "-10004": "Erro interno", + "-10005": "Permissões insuficientes", + "-10006": "Execução expirada", + "-10007": "Dispositivo offline ou inexistente", + "-10020": "OAuth2 não autorizado", + "-10030": "Token inválido (HTTP)", + "-10040": "Formato de mensagem inválido", + "-10050": "Certificado inválido", + "-704000000": "Erro desconhecido", + "-704010000": "Não autorizado (o dispositivo pode ter sido excluído)", + "-704014006": "Descrição do dispositivo não encontrada", + "-704030013": "Propriedade não pode ser lida", + "-704030023": "Propriedade não pode ser escrita", + "-704030033": "Propriedade não pode ser assinada", + "-704040002": "Serviço inexistente", + "-704040003": "Propriedade inexistente", + "-704040004": "Evento inexistente", + "-704040005": "Ação inexistente", + "-704040999": "Funcionalidade não lançada", + "-704042001": "Dispositivo inexistente", + "-704042011": "Dispositivo offline", + "-704053036": "Tempo de operação do dispositivo expirado", + "-704053100": "Dispositivo não pode executar esta operação no estado atual", + "-704083036": "Tempo de operação do dispositivo expirado", + "-704090001": "Dispositivo inexistente", + "-704220008": "ID inválido", + "-704220025": "Número de parâmetros de ação incompatível", + "-704220035": "Parâmetro de ação incorreto", + "-704220043": "Valor da propriedade incorreto", + "-704222034": "Valor de retorno de ação incorreto", + "-705004000": "Erro desconhecido", + "-705004501": "Erro desconhecido", + "-705201013": "Propriedade não pode ser lida", + "-705201015": "Erro na execução da ação", + "-705201023": "Propriedade não pode ser escrita", + "-705201033": "Propriedade não pode ser assinada", + "-706012000": "Erro desconhecido", + "-706012013": "Propriedade não pode ser lida", + "-706012015": "Erro na execução da ação", + "-706012023": "Propriedade não pode ser escrita", + "-706012033": "Propriedade não pode ser assinada", + "-706012043": "Valor da propriedade incorreto", + "-706014006": "Descrição do dispositivo não encontrada" + } + } +} \ No newline at end of file diff --git a/custom_components/xiaomi_home/miot/i18n/pt.json b/custom_components/xiaomi_home/miot/i18n/pt.json new file mode 100644 index 0000000..dd30774 --- /dev/null +++ b/custom_components/xiaomi_home/miot/i18n/pt.json @@ -0,0 +1,95 @@ +{ + "config": { + "other": { + "devices": "dispositivos", + "found_central_gateway": ", encontrou a central de gateway local" + }, + "control_mode": { + "auto": "Automático", + "cloud": "Nuvem" + }, + "room_name_rule": { + "none": "Não sincronizar", + "home_room": "Nome da casa e Nome do quarto (Xiaomi Home Quarto)", + "room": "Nome do quarto (Quarto)", + "home": "Nome da casa (Xiaomi Home)" + }, + "option_status": { + "enable": "Habilitar", + "disable": "Desabilitar" + }, + "lan_ctrl_config": { + "notice_net_dup": "\r\n**[Aviso]** Detectado que várias interfaces podem estar conectadas à mesma rede, escolha com cuidado.", + "net_unavailable": "Interface indisponível" + } + }, + "miot": { + "client": { + "invalid_oauth_info": "Informações de autenticação inválidas, a conexão na nuvem ficará indisponível. Por favor, acesse a página de integração do Xiaomi Home e clique em 'Opções' para autenticar novamente.", + "invalid_device_cache": "Erro no cache de informações do dispositivo. Por favor, acesse a página de integração do Xiaomi Home e clique em 'Opções -> Atualizar lista de dispositivos' para atualizar as informações locais.", + "invalid_cert_info": "Certificado de usuário inválido, a conexão com a central local ficará indisponível. Por favor, acesse a página de integração do Xiaomi Home e clique em 'Opções' para autenticar novamente.", + "device_cloud_error": "Erro ao obter informações do dispositivo na nuvem. Verifique a conexão de rede local.", + "xiaomi_home_error_title": "Erro de integração do Xiaomi Home", + "xiaomi_home_error": "Detectado erro em **{nick_name}({uid}, {cloud_server})**. Por favor, acesse a página de opções para reconfigurar.\n\n**Informação do erro**: \n{message}", + "device_list_changed_title": "Mudança na lista de dispositivos do Xiaomi Home", + "device_list_changed": "Detectada alteração nas informações do dispositivo de **{nick_name}({uid}, {cloud_server})**. Por favor, acesse a página de opções de integração e clique em 'Opções -> Atualizar lista de dispositivos' para atualizar as informações locais.\n\nStatus atual da rede: {network_status}\n{message}\n", + "device_list_add": "\n**{count} novos dispositivos**: \n{message}", + "device_list_del": "\n**{count} dispositivos indisponíveis**: \n{message}", + "device_list_offline": "\n**{count} dispositivos offline**: \n{message}", + "network_status_online": "Online", + "network_status_offline": "Offline", + "device_exec_error": "Erro de execução" + } + }, + "error": { + "common": { + "-10000": "Erro desconhecido", + "-10001": "Serviço indisponível", + "-10002": "Parâmetro inválido", + "-10003": "Recursos insuficientes", + "-10004": "Erro interno", + "-10005": "Permissão negada", + "-10006": "Tempo limite de execução", + "-10007": "Dispositivo offline ou inexistente", + "-10020": "Não autorizado (OAuth2)", + "-10030": "Token inválido (HTTP)", + "-10040": "Formato de mensagem inválido", + "-10050": "Certificado inválido", + "-704000000": "Erro desconhecido", + "-704010000": "Não autorizado (o dispositivo pode ter sido removido)", + "-704014006": "Descrição do dispositivo não encontrada", + "-704030013": "Propriedade não legível", + "-704030023": "Propriedade não gravável", + "-704030033": "Propriedade não subscritível", + "-704040002": "Serviço inexistente", + "-704040003": "Propriedade inexistente", + "-704040004": "Evento inexistente", + "-704040005": "Ação inexistente", + "-704040999": "Funcionalidade não disponível", + "-704042001": "Dispositivo inexistente", + "-704042011": "Dispositivo offline", + "-704053036": "Tempo limite de operação do dispositivo", + "-704053100": "O dispositivo não pode executar esta operação no estado atual", + "-704083036": "Tempo limite de operação do dispositivo", + "-704090001": "Dispositivo inexistente", + "-704220008": "ID inválido", + "-704220025": "Número de parâmetros da ação não corresponde", + "-704220035": "Erro nos parâmetros da ação", + "-704220043": "Valor de propriedade inválido", + "-704222034": "Erro no valor de retorno da ação", + "-705004000": "Erro desconhecido", + "-705004501": "Erro desconhecido", + "-705201013": "Propriedade não legível", + "-705201015": "Erro na execução da ação", + "-705201023": "Propriedade não gravável", + "-705201033": "Propriedade não subscritível", + "-706012000": "Erro desconhecido", + "-706012013": "Propriedade não legível", + "-706012015": "Erro na execução da ação", + "-706012023": "Propriedade não gravável", + "-706012033": "Propriedade não subscritível", + "-706012043": "Valor de propriedade inválido", + "-706014006": "Descrição do dispositivo não encontrada" + } + } +} \ No newline at end of file From 2c37fb63ca94909602e9c7634f626f0a5f2452c6 Mon Sep 17 00:00:00 2001 From: topsworld Date: Wed, 18 Dec 2024 20:39:48 +0800 Subject: [PATCH 20/23] doc: update change log and version --- custom_components/xiaomi_home/manifest.json | 2 +- doc/CHANGELOG.md | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/custom_components/xiaomi_home/manifest.json b/custom_components/xiaomi_home/manifest.json index 67ff027..406fe9d 100644 --- a/custom_components/xiaomi_home/manifest.json +++ b/custom_components/xiaomi_home/manifest.json @@ -25,7 +25,7 @@ "cryptography", "psutil" ], - "version": "v0.1.0", + "version": "v0.1.2", "zeroconf": [ "_miot-central._tcp.local." ] diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 4fc27b4..a05915e 100644 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,5 +1,23 @@ # CHANGELOG +## 0.1.2 +### Added +- Support Xiaomi Heater devices. https://github.com/XiaoMi/ha_xiaomi_home/issues/124 https://github.com/XiaoMi/ha_xiaomi_home/issues/117 +- Language supports pt, pt-BR. +### Changed +- Adjust the minimum version of HASS core to 2024.4.4 and above versions. +### Fixed + +## 0.1.1 +### Added +### Changed +### Fixed +- fix humidifier trans rule. https://github.com/XiaoMi/ha_xiaomi_home/issues/59 +- fix get homeinfo error. https://github.com/XiaoMi/ha_xiaomi_home/issues/22 +- fix air-conditioner switch on. https://github.com/XiaoMi/ha_xiaomi_home/issues/37 https://github.com/XiaoMi/ha_xiaomi_home/issues/16 +- fix invalid cover status. https://github.com/XiaoMi/ha_xiaomi_home/issues/11 https://github.com/XiaoMi/ha_xiaomi_home/issues/85 +- water heater entity add STATE_OFF. https://github.com/XiaoMi/ha_xiaomi_home/issues/105 https://github.com/XiaoMi/ha_xiaomi_home/issues/17 + ## 0.1.0 ### Added - first version From fce67ba2da8058c5364a2bfcfe579f1ca5e1773a Mon Sep 17 00:00:00 2001 From: topsworld Date: Wed, 18 Dec 2024 20:45:07 +0800 Subject: [PATCH 21/23] doc: move CONTRIBUTING.md, CHANGELOG.md to root path --- doc/CHANGELOG.md => CHANGELOG.md | 6 +++--- doc/CONTRIBUTING.md => CONTRIBUTING.md | 2 +- README.md | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) rename doc/CHANGELOG.md => CHANGELOG.md (96%) rename doc/CONTRIBUTING.md => CONTRIBUTING.md (98%) diff --git a/doc/CHANGELOG.md b/CHANGELOG.md similarity index 96% rename from doc/CHANGELOG.md rename to CHANGELOG.md index a05915e..ed98f74 100644 --- a/doc/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # CHANGELOG -## 0.1.2 +## v0.1.2 ### Added - Support Xiaomi Heater devices. https://github.com/XiaoMi/ha_xiaomi_home/issues/124 https://github.com/XiaoMi/ha_xiaomi_home/issues/117 - Language supports pt, pt-BR. @@ -8,7 +8,7 @@ - Adjust the minimum version of HASS core to 2024.4.4 and above versions. ### Fixed -## 0.1.1 +## v0.1.1 ### Added ### Changed ### Fixed @@ -18,7 +18,7 @@ - fix invalid cover status. https://github.com/XiaoMi/ha_xiaomi_home/issues/11 https://github.com/XiaoMi/ha_xiaomi_home/issues/85 - water heater entity add STATE_OFF. https://github.com/XiaoMi/ha_xiaomi_home/issues/105 https://github.com/XiaoMi/ha_xiaomi_home/issues/17 -## 0.1.0 +## v0.1.0 ### Added - first version ### Changed diff --git a/doc/CONTRIBUTING.md b/CONTRIBUTING.md similarity index 98% rename from doc/CONTRIBUTING.md rename to CONTRIBUTING.md index ff13ba1..dfcdb65 100644 --- a/doc/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,6 @@ # Contribution Guidelines -[English](./CONTRIBUTING.md) | [简体中文](./CONTRIBUTING_zh.md) +[English](./CONTRIBUTING.md) | [简体中文](./doc/CONTRIBUTING_zh.md) Thank you for considering contributing to our project! We appreciate your efforts to make our project better. diff --git a/README.md b/README.md index 6f97f2a..c140586 100644 --- a/README.md +++ b/README.md @@ -376,8 +376,8 @@ Example: ## Documents - [License](./LICENSE.md) -- Contribution Guidelines: [English](./doc/CONTRIBUTING.md) | [简体中文](./doc/CONTRIBUTING_zh.md) -- [ChangeLog](./doc/CHANGELOG.md) +- Contribution Guidelines: [English](./CONTRIBUTING.md) | [简体中文](./doc/CONTRIBUTING_zh.md) +- [ChangeLog](./CHANGELOG.md) - Development Documents: https://developers.home-assistant.io/docs/creating_component_index ## Directory Structure From 7618f6b366857a81d63d48a1f1e2074458e32834 Mon Sep 17 00:00:00 2001 From: topsworld Date: Wed, 18 Dec 2024 20:46:32 +0800 Subject: [PATCH 22/23] doc: update change log --- CHANGELOG.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ed98f74..a14aec7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,14 +12,14 @@ ### Added ### Changed ### Fixed -- fix humidifier trans rule. https://github.com/XiaoMi/ha_xiaomi_home/issues/59 -- fix get homeinfo error. https://github.com/XiaoMi/ha_xiaomi_home/issues/22 -- fix air-conditioner switch on. https://github.com/XiaoMi/ha_xiaomi_home/issues/37 https://github.com/XiaoMi/ha_xiaomi_home/issues/16 -- fix invalid cover status. https://github.com/XiaoMi/ha_xiaomi_home/issues/11 https://github.com/XiaoMi/ha_xiaomi_home/issues/85 -- water heater entity add STATE_OFF. https://github.com/XiaoMi/ha_xiaomi_home/issues/105 https://github.com/XiaoMi/ha_xiaomi_home/issues/17 +- Fix humidifier trans rule. https://github.com/XiaoMi/ha_xiaomi_home/issues/59 +- Fix get homeinfo error. https://github.com/XiaoMi/ha_xiaomi_home/issues/22 +- Fix air-conditioner switch on. https://github.com/XiaoMi/ha_xiaomi_home/issues/37 https://github.com/XiaoMi/ha_xiaomi_home/issues/16 +- Fix invalid cover status. https://github.com/XiaoMi/ha_xiaomi_home/issues/11 https://github.com/XiaoMi/ha_xiaomi_home/issues/85 +- Water heater entity add STATE_OFF. https://github.com/XiaoMi/ha_xiaomi_home/issues/105 https://github.com/XiaoMi/ha_xiaomi_home/issues/17 ## v0.1.0 ### Added -- first version +- First version ### Changed ### Fixed From 1e0ddc1f0cbab5c849068a1c3bc30e4d82351613 Mon Sep 17 00:00:00 2001 From: topsworld Date: Wed, 18 Dec 2024 21:20:51 +0800 Subject: [PATCH 23/23] feat: const.INTEGRATION_LANGUAGES add pt, pt-BR --- custom_components/xiaomi_home/miot/const.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/custom_components/xiaomi_home/miot/const.py b/custom_components/xiaomi_home/miot/const.py index 7aec73d..7518ca2 100644 --- a/custom_components/xiaomi_home/miot/const.py +++ b/custom_components/xiaomi_home/miot/const.py @@ -110,11 +110,13 @@ INTEGRATION_LANGUAGES = { 'zh-Hans': '简体中文', 'zh-Hant': '繁體中文', 'en': 'English', - 'es': 'Español', - 'ru': 'Русский', - 'fr': 'Français', 'de': 'Deutsch', - 'ja': '日本語' + 'es': 'Español', + 'fr': 'Français', + 'ja': '日本語', + 'pt': 'Português', + 'pt-BR': 'Português (Brasil)', + 'ru': 'Русский', } DEFAULT_CTRL_MODE: str = 'auto'