mirror of
https://github.com/XiaoMi/ha_xiaomi_home.git
synced 2025-07-06 19:59:05 +08:00
Compare commits
66 Commits
Author | SHA1 | Date | |
---|---|---|---|
b6147de1b8 | |||
621ca8002b | |||
40a75bef28 | |||
196e19d10a | |||
310029d8ed | |||
365f4e57d8 | |||
6d978872e7 | |||
29b7489ac7 | |||
78461cbd8a | |||
7654e5e518 | |||
0f5da18108 | |||
ea9aa082b7 | |||
9af59e28bd | |||
c1867e2baf | |||
afef709839 | |||
02ddf8df56 | |||
f87e746188 | |||
67785f747a | |||
bd3a98b976 | |||
6ce3206b30 | |||
aacb794e1f | |||
a879ae2cdf | |||
640ac25d9c | |||
5f5b3feea5 | |||
571483b302 | |||
b955c199fc | |||
f10885fbfd | |||
bba8ba7f7b | |||
1f20416e97 | |||
2d6387c30a | |||
b93d8631b8 | |||
dabf277942 | |||
c4a981a15d | |||
3c464a0b0c | |||
b4be1e0aa9 | |||
8364a544f2 | |||
d980b1bfb4 | |||
2fb030c52d | |||
54e26378be | |||
6fae26a378 | |||
d437963628 | |||
be627afe54 | |||
fa382939a0 | |||
caec202c71 | |||
1e0ddc1f0c | |||
01f6bbf2c7 | |||
e0cd8486eb | |||
7618f6b366 | |||
fce67ba2da | |||
2c37fb63ca | |||
fec5d10f42 | |||
10aa78f490 | |||
6e2de896c3 | |||
ce4f23b1bd | |||
e70acd8421 | |||
b498a708ac | |||
c744919032 | |||
6bb4bf32d7 | |||
83dbceac6d | |||
7a50778d2b | |||
b5f9e931b7 | |||
99e654f0c7 | |||
b7fc534a34 | |||
da58d4c0a5 | |||
dbf943386e | |||
bff5b3bf44 |
42
.github/ISSUE_TEMPLATE/bug_report.yaml
vendored
42
.github/ISSUE_TEMPLATE/bug_report.yaml
vendored
@ -1,11 +1,9 @@
|
||||
name: Bug report / 报告问题
|
||||
name: Bug Report / 报告问题
|
||||
description: Create a report to help us improve. / 报告问题以帮助我们改进
|
||||
title: "[Bug]: "
|
||||
labels: ["bug"]
|
||||
body:
|
||||
- type: input
|
||||
attributes:
|
||||
label: Describe the bug / 描述问题
|
||||
label: Describe the Bug / 描述问题
|
||||
description: |
|
||||
> A clear and concise description of what the bug is.
|
||||
> 清晰且简明地描述问题。
|
||||
@ -14,7 +12,7 @@ body:
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: To Reproduce / 复现步骤
|
||||
label: How to Reproduce / 复现步骤
|
||||
description: |
|
||||
> If applicable, add screenshots to help explain your problem. You can attach images by clicking this area to highlight it and then dragging files in. Steps to reproduce the behavior:
|
||||
> 如有需要,可添加截图以帮助解释问题。点击此区域以高亮显示并拖动截图文件以上传。请详细描述复现步骤:
|
||||
@ -28,23 +26,47 @@ body:
|
||||
|
||||
- type: input
|
||||
attributes:
|
||||
label: Expected behavior / 预期结果
|
||||
label: Expected Behavior / 预期结果
|
||||
description: |
|
||||
> A clear and concise description of what you expected to happen.
|
||||
> 描述预期结果。
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
attributes:
|
||||
label: Reproduce Time / 问题复现的时间点
|
||||
description: |
|
||||
> Year-month-day, 24-hour time.
|
||||
> 年-月-日,24小时制。
|
||||
placeholder: "2025-01-01 17:00:00"
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Home Assistant Logs / 系统日志
|
||||
description: |
|
||||
> Please [set the log level](https://github.com/XiaoMi/ha_xiaomi_home/blob/main/CONTRIBUTING.md#reporting-bugs) to `debug` and try to reproduce the problem.
|
||||
> [Settings > System > Logs > DOWNLOAD FULL LOG](https://my.home-assistant.io/redirect/logs) > Filter `xiaomi_home`
|
||||
> If you are concerned about privacy, you can send the log to ha_xiaomi_home@xiaomi.com . The mail body should include the link to this issue.
|
||||
> 请将[日志级别设置](https://github.com/XiaoMi/ha_xiaomi_home/blob/main/doc/CONTRIBUTING_zh.md#%E6%88%91%E5%8F%AF%E4%BB%A5%E5%A6%82%E4%BD%95%E8%B4%A1%E7%8C%AE)为 `debug` 并尝试复现问题。
|
||||
> [设置 > 系统 > 日志 > 下载完整日志](https://my.home-assistant.io/redirect/logs) > 筛选 `xiaomi_home`
|
||||
> 如果您担心隐私问题,可将日志发送至 ha_xiaomi_home@xiaomi.com ,邮件正文附上此问题的链接。
|
||||
|
||||
- type: input
|
||||
attributes:
|
||||
label: Home Assistant Core version / Home Assistant Core 版本
|
||||
label: Log Timezone / 日志时区
|
||||
description: |
|
||||
> The [timezone](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) of the timestamp in the log.
|
||||
> 日志所用时间戳的[时区](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones)。
|
||||
placeholder: "Asia/Shanghai"
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
attributes:
|
||||
label: Home Assistant Core Version / Home Assistant Core 版本
|
||||
description: |
|
||||
> [Settings > About](https://my.home-assistant.io/redirect/info)
|
||||
> [设置 > 关于 Home Assistant](https://my.home-assistant.io/redirect/info)
|
||||
@ -54,7 +76,7 @@ body:
|
||||
|
||||
- type: input
|
||||
attributes:
|
||||
label: Home Assistant Operation System version / Home Assistant Operation System 版本
|
||||
label: Home Assistant Operation System Version / Home Assistant Operation System 版本
|
||||
description: |
|
||||
> [Settings > About](https://my.home-assistant.io/redirect/info)
|
||||
> [设置 > 关于 Home Assistant](https://my.home-assistant.io/redirect/info)
|
||||
@ -64,7 +86,7 @@ body:
|
||||
|
||||
- type: input
|
||||
attributes:
|
||||
label: Xiaomi Home integration version / 米家集成版本
|
||||
label: Xiaomi Home Integration Version / 米家集成版本
|
||||
description: |
|
||||
> [Settings > Devices & services > Configured > `Xiaomi Home`](https://my.home-assistant.io/redirect/integration/?domain=xiaomi_home)
|
||||
> [设置 > 设备与服务 > 已配置 > `Xiaomi Home`](https://my.home-assistant.io/redirect/integration/?domain=xiaomi_home)
|
||||
@ -74,4 +96,4 @@ body:
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Additional context / 其他说明
|
||||
label: Additional Context / 其他说明
|
||||
|
64
CHANGELOG.md
Normal file
64
CHANGELOG.md
Normal file
@ -0,0 +1,64 @@
|
||||
# CHANGELOG
|
||||
|
||||
## v0.1.4
|
||||
### Added
|
||||
- Refactor miot network, add network detection logic, improve devices filter logic. [458](https://github.com/XiaoMi/ha_xiaomi_home/pull/458) [#191](https://github.com/XiaoMi/ha_xiaomi_home/pull/191)
|
||||
### Changed
|
||||
- Remove tev dependency for lan control & fixs. [#333](https://github.com/XiaoMi/ha_xiaomi_home/pull/333)
|
||||
- Use yaml to parse action params. [#447](https://github.com/XiaoMi/ha_xiaomi_home/pull/447)
|
||||
- Update issue template. [#445](https://github.com/XiaoMi/ha_xiaomi_home/pull/445)
|
||||
- Remove duplicate dependency(aiohttp) [#390](https://github.com/XiaoMi/ha_xiaomi_home/pull/390)
|
||||
### Fixed
|
||||
|
||||
## v0.1.4b1
|
||||
### Added
|
||||
- Support devices filter, and device changed notify logical refinement. [#332](https://github.com/XiaoMi/ha_xiaomi_home/pull/332)
|
||||
### Changed
|
||||
- Readme amend HACS installation. [#404](https://github.com/XiaoMi/ha_xiaomi_home/pull/404)
|
||||
### Fixed
|
||||
- Fix unit_convert AttributeError, Change to catch all Exception. [#396](https://github.com/XiaoMi/ha_xiaomi_home/pull/396)
|
||||
- Ignore undefined piid and keep processing following arguments. [#377](https://github.com/XiaoMi/ha_xiaomi_home/pull/377)
|
||||
- Fix some type error, wrong use of any and Any. [#338](https://github.com/XiaoMi/ha_xiaomi_home/pull/338)
|
||||
- Fix lumi.switch.acn040 identify service translation of zh-Hans [#412](https://github.com/XiaoMi/ha_xiaomi_home/pull/412)
|
||||
|
||||
## v0.1.4b0
|
||||
### Added
|
||||
### Changed
|
||||
### Fixed
|
||||
- Fix miot cloud token refresh logic. [#307](https://github.com/XiaoMi/ha_xiaomi_home/pull/307)
|
||||
- Fix lan ctrl filter logic. [#303](https://github.com/XiaoMi/ha_xiaomi_home/pull/303)
|
||||
|
||||
## v0.1.3
|
||||
### Added
|
||||
### Changed
|
||||
- Remove default bug label. [#276](https://github.com/XiaoMi/ha_xiaomi_home/pull/276)
|
||||
- Improve multi-language translation actions. [#256](https://github.com/XiaoMi/ha_xiaomi_home/pull/256)
|
||||
- Use aiohttp instead of waiting for blocking calls. [#227](https://github.com/XiaoMi/ha_xiaomi_home/pull/227)
|
||||
- Language supports dt. [#237](https://github.com/XiaoMi/ha_xiaomi_home/pull/237)
|
||||
### Fixed
|
||||
- Fix local control error. [#271](https://github.com/XiaoMi/ha_xiaomi_home/pull/271)
|
||||
- Fix README_zh and miot_storage. [#270](https://github.com/XiaoMi/ha_xiaomi_home/pull/270)
|
||||
|
||||
## 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.
|
||||
### Changed
|
||||
- Adjust the minimum version of HASS core to 2024.4.4 and above versions.
|
||||
### Fixed
|
||||
|
||||
## v0.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
|
||||
|
||||
## v0.1.0
|
||||
### Added
|
||||
- First version
|
||||
### Changed
|
||||
### Fixed
|
@ -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.
|
||||
|
12
README.md
12
README.md
@ -8,7 +8,7 @@ Xiaomi Home Integration is an integrated component of Home Assistant supported b
|
||||
|
||||
> Home Assistant version requirement:
|
||||
>
|
||||
> - Core $\geq$ 2024.11.0
|
||||
> - Core $\geq$ 2024.4.4
|
||||
> - Operating System $\geq$ 13.0
|
||||
|
||||
### Method 1: Git clone from GitHub
|
||||
@ -32,7 +32,7 @@ git checkout v1.0.0
|
||||
|
||||
### Method 2: [HACS](https://hacs.xyz/)
|
||||
|
||||
HACS > Overflow Menu > Custom repositories > Repository: https://github.com/XiaoMi/ha_xiaomi_home.git & Category: Integration > ADD
|
||||
HACS > Overflow Menu > Custom repositories > Repository: https://github.com/XiaoMi/ha_xiaomi_home.git & Category or Type: Integration > ADD > Xiaomi Home in New or Available for download section of HACS > DOWNLOAD
|
||||
|
||||
> Xiaomi Home has not been added to the HACS store as a default yet. It's coming soon.
|
||||
|
||||
@ -76,6 +76,8 @@ Method: [Settings > Devices & services > Configured > Xiaomi Home](https://my.ho
|
||||
|
||||
Xiaomi Home Integration and the affiliated cloud interface is provided by Xiaomi officially. You need to use your Xiaomi account to login to get your device list. Xiaomi Home Integration implements OAuth 2.0 login process, which does not keep your account password in the Home Assistant application. However, due to the limitation of the Home Assistant platform, the user information (including device information, certificates, tokens, etc.) of your Xiaomi account will be saved in the Home Assistant configuration file in clear text after successful login. You need to ensure that your Home Assistant configuration file is properly stored. The exposure of your configuration file may result in others logging in with your identity.
|
||||
|
||||
> If you suspect that your OAuth 2.0 token has been leaked, you can revoke the login authorization of your Xiaomi account by the following steps: Xiaomi Home APP -> Profile -> Click your username and get into Xiaomi Account management page -> Basic info: Apps -> Xiaomi Home (Home Assistant Integration) -> Remove
|
||||
|
||||
## FAQ
|
||||
|
||||
- Does Xiaomi Home Integration support all Xiaomi Home devices?
|
||||
@ -323,7 +325,7 @@ Device information service (urn:miot-spec-v2:service:device-information:00007801
|
||||
|
||||
## Multiple Language Support
|
||||
|
||||
There are 8 languages available for selection in the config flow language option of Xiaomi Home, including Simplified Chinese, Traditional Chinese, English, Spanish, Russian, French, German, and Japanese. The config flow page in Simplified Chinese and English has been manually reviewed by the developer. Other languages are translated by machine translation. If you want to modify the words and sentences in the config flow page, you need to modify the json file of the certain language in `custom_components/xiaomi_home/translations/` directory.
|
||||
There are 8 languages available for selection in the config flow language option of Xiaomi Home, including Simplified Chinese, Traditional Chinese, English, Spanish, Russian, French, German, and Japanese. The config flow page in Simplified Chinese and English has been manually reviewed by the developer. Other languages are translated by machine translation. If you want to modify the words and sentences in the config flow page, you need to modify the json file of the certain language in `custom_components/xiaomi_home/translations/` and `custom_components/xiaomi_home/miot/i18n/` directory.
|
||||
|
||||
When displaying Home Assistant entity name, Xiaomi Home downloads the multiple language file configured by the device vendor from MIoT Cloud, which contains translations for MIoT-Spec-V2 instances of the device. `multi_lang.json` is a locally maintained multiple language dictionary, which has a higher priority than the multiple language file obtained from the cloud and can be used to supplement or modify the multiple language translation of devices.
|
||||
|
||||
@ -376,8 +378,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
|
||||
|
@ -47,7 +47,7 @@ Climate entities for Xiaomi Home.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
import logging
|
||||
from typing import Optional
|
||||
from typing import Any, Optional
|
||||
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
@ -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)
|
||||
@ -344,31 +347,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 +380,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 +390,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.
|
||||
|
||||
@ -412,7 +415,7 @@ class AirConditioner(MIoTServiceEntity, ClimateEntity):
|
||||
return SWING_OFF
|
||||
return None
|
||||
|
||||
def __ac_state_changed(self, prop: MIoTSpecProperty, value: any) -> None:
|
||||
def __ac_state_changed(self, prop: MIoTSpecProperty, value: Any) -> None:
|
||||
del prop
|
||||
if not isinstance(value, str):
|
||||
_LOGGER.error(
|
||||
@ -473,3 +476,144 @@ 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]
|
||||
_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:
|
||||
"""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._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:
|
||||
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 == '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':
|
||||
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)
|
||||
|
||||
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."""
|
||||
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)
|
||||
|
||||
@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)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -46,6 +46,7 @@ off Xiaomi or its affiliates' products.
|
||||
Event entities for Xiaomi Home.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
from typing import Any
|
||||
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
@ -84,6 +85,6 @@ class Event(MIoTEventEntity, EventEntity):
|
||||
# Set device_class
|
||||
self._attr_device_class = spec.device_class
|
||||
|
||||
def on_event_occurred(self, name: str, arguments: list[dict[int, any]]):
|
||||
def on_event_occurred(self, name: str, arguments: list[dict[int, Any]]):
|
||||
"""An event is occurred."""
|
||||
self._trigger_event(event_type=name, event_attributes=arguments)
|
||||
|
@ -93,7 +93,7 @@ class Fan(MIoTServiceEntity, FanEntity):
|
||||
_speed_min: Optional[int]
|
||||
_speed_max: Optional[int]
|
||||
_speed_step: Optional[int]
|
||||
_mode_list: Optional[dict[any, any]]
|
||||
_mode_list: Optional[dict[Any, Any]]
|
||||
|
||||
def __init__(
|
||||
self, miot_device: MIoTDevice, entity_data: MIoTEntityData
|
||||
|
@ -47,7 +47,7 @@ Humidifier entities for Xiaomi Home.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
import logging
|
||||
from typing import Optional
|
||||
from typing import Any, Optional
|
||||
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
@ -97,7 +97,7 @@ class Humidifier(MIoTServiceEntity, HumidifierEntity):
|
||||
_prop_target_humidity: Optional[MIoTSpecProperty]
|
||||
_prop_humidity: Optional[MIoTSpecProperty]
|
||||
|
||||
_mode_list: dict[any, any]
|
||||
_mode_list: dict[Any, Any]
|
||||
|
||||
def __init__(
|
||||
self, miot_device: MIoTDevice, entity_data: MIoTEntityData
|
||||
|
@ -47,7 +47,7 @@ Light entities for Xiaomi Home.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
import logging
|
||||
from typing import Optional
|
||||
from typing import Any, Optional
|
||||
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
@ -102,7 +102,7 @@ class Light(MIoTServiceEntity, LightEntity):
|
||||
_prop_mode: Optional[MIoTSpecProperty]
|
||||
|
||||
_brightness_scale: Optional[tuple[int, int]]
|
||||
_mode_list: Optional[dict[any, any]]
|
||||
_mode_list: Optional[dict[Any, Any]]
|
||||
|
||||
def __init__(
|
||||
self, miot_device: MIoTDevice, entity_data: MIoTEntityData
|
||||
@ -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(
|
||||
|
@ -20,12 +20,12 @@
|
||||
],
|
||||
"requirements": [
|
||||
"construct>=2.10.56",
|
||||
"paho-mqtt<=2.0.0",
|
||||
"paho-mqtt<2.0.0",
|
||||
"numpy",
|
||||
"cryptography",
|
||||
"psutil"
|
||||
],
|
||||
"version": "v0.1.0",
|
||||
"version": "v0.1.4",
|
||||
"zeroconf": [
|
||||
"_miot-central._tcp.local."
|
||||
]
|
||||
|
@ -46,10 +46,19 @@ off Xiaomi or its affiliates' products.
|
||||
Common utilities.
|
||||
"""
|
||||
import json
|
||||
from os import path
|
||||
import random
|
||||
from typing import Optional
|
||||
from typing import Any, Optional
|
||||
import hashlib
|
||||
from paho.mqtt.client import MQTTMatcher
|
||||
from paho.mqtt.matcher import MQTTMatcher
|
||||
import yaml
|
||||
|
||||
MIOT_ROOT_PATH: str = path.dirname(path.abspath(__file__))
|
||||
|
||||
|
||||
def gen_absolute_path(relative_path: str) -> str:
|
||||
"""Generate an absolute path."""
|
||||
return path.join(MIOT_ROOT_PATH, relative_path)
|
||||
|
||||
|
||||
def calc_group_id(uid: str, home_id: str) -> str:
|
||||
@ -64,25 +73,34 @@ def load_json_file(json_file: str) -> dict:
|
||||
return json.load(f)
|
||||
|
||||
|
||||
def load_yaml_file(yaml_file: str) -> dict:
|
||||
"""Load a YAML file."""
|
||||
with open(yaml_file, 'r', encoding='utf-8') as f:
|
||||
return yaml.load(f, Loader=yaml.FullLoader)
|
||||
|
||||
|
||||
def randomize_int(value: int, ratio: float) -> int:
|
||||
"""Randomize an integer value."""
|
||||
return int(value * (1 - ratio + random.random()*2*ratio))
|
||||
|
||||
def randomize_float(value: float, ratio: float) -> float:
|
||||
"""Randomize a float value."""
|
||||
return value * (1 - ratio + random.random()*2*ratio)
|
||||
|
||||
class MIoTMatcher(MQTTMatcher):
|
||||
"""MIoT Pub/Sub topic matcher."""
|
||||
|
||||
def iter_all_nodes(self) -> any:
|
||||
def iter_all_nodes(self) -> Any:
|
||||
"""Return an iterator on all nodes with their paths and contents."""
|
||||
def rec(node, path):
|
||||
def rec(node, path_):
|
||||
# pylint: disable=protected-access
|
||||
if node._content:
|
||||
yield ('/'.join(path), node._content)
|
||||
yield ('/'.join(path_), node._content)
|
||||
for part, child in node._children.items():
|
||||
yield from rec(child, path + [part])
|
||||
yield from rec(child, path_ + [part])
|
||||
return rec(self._root, [])
|
||||
|
||||
def get(self, topic: str) -> Optional[any]:
|
||||
def get(self, topic: str) -> Optional[Any]:
|
||||
try:
|
||||
return self[topic]
|
||||
except KeyError:
|
||||
|
@ -67,24 +67,16 @@ SPEC_STD_LIB_EFFECTIVE_TIME = 3600*24*14
|
||||
MANUFACTURER_EFFECTIVE_TIME = 3600*24*14
|
||||
|
||||
SUPPORTED_PLATFORMS: list = [
|
||||
# 'alarm_control_panel',
|
||||
'binary_sensor',
|
||||
'button',
|
||||
'climate',
|
||||
# 'camera',
|
||||
# 'conversation',
|
||||
'cover',
|
||||
# 'device_tracker',
|
||||
'event',
|
||||
'fan',
|
||||
'humidifier',
|
||||
'light',
|
||||
# 'lock',
|
||||
# 'media_player',
|
||||
'notify',
|
||||
'number',
|
||||
# 'remote',
|
||||
# 'scene',
|
||||
'select',
|
||||
'sensor',
|
||||
'switch',
|
||||
@ -107,14 +99,17 @@ SUPPORT_CENTRAL_GATEWAY_CTRL: list = ['cn']
|
||||
|
||||
DEFAULT_INTEGRATION_LANGUAGE: str = 'en'
|
||||
INTEGRATION_LANGUAGES = {
|
||||
'zh-Hans': '简体中文',
|
||||
'zh-Hant': '繁體中文',
|
||||
'de': 'Deutsch',
|
||||
'en': 'English',
|
||||
'es': 'Español',
|
||||
'ru': 'Русский',
|
||||
'fr': 'Français',
|
||||
'de': 'Deutsch',
|
||||
'ja': '日本語'
|
||||
'ja': '日本語',
|
||||
'nl': 'Nederlands',
|
||||
'pt': 'Português',
|
||||
'pt-BR': 'Português (Brasil)',
|
||||
'ru': 'Русский',
|
||||
'zh-Hans': '简体中文',
|
||||
'zh-Hant': '繁體中文'
|
||||
}
|
||||
|
||||
DEFAULT_CTRL_MODE: str = 'auto'
|
||||
|
@ -2,12 +2,48 @@
|
||||
"config": {
|
||||
"other": {
|
||||
"devices": "Geräte",
|
||||
"found_central_gateway": ", lokales zentrales Gateway gefunden"
|
||||
"found_central_gateway": ", lokales zentrales Gateway gefunden",
|
||||
"without_room": "Kein Raum zugewiesen",
|
||||
"no_display": "nicht anzeigen"
|
||||
},
|
||||
"control_mode": {
|
||||
"auto": "automatisch",
|
||||
"cloud": "Cloud"
|
||||
},
|
||||
"statistics_logic": {
|
||||
"or": "ODER-Logik",
|
||||
"and": "UND-Logik"
|
||||
},
|
||||
"filter_mode": {
|
||||
"exclude": "ausschließen",
|
||||
"include": "einschließen"
|
||||
},
|
||||
"connect_type": {
|
||||
"0": "WiFi",
|
||||
"1": "yunyi-Gerät",
|
||||
"2": "Cloud-Gerät",
|
||||
"3": "ZigBee",
|
||||
"4": "webSocket",
|
||||
"5": "virtuelles Gerät",
|
||||
"6": "BLE",
|
||||
"7": "lokaler AP",
|
||||
"8": "WiFi+BLE",
|
||||
"9": "andere",
|
||||
"10": "Funktions-Plug-in",
|
||||
"11": "Zellnetz",
|
||||
"12": "Kabel",
|
||||
"13": "NB-IoT",
|
||||
"14": "Drittanbieter-Cloud-Zugriff",
|
||||
"15": "Infrarot-Fernbedienungsgerät",
|
||||
"16": "BLE-Mesh",
|
||||
"17": "virtuelle Gerätegruppe",
|
||||
"18": "Gateway-Untergerät",
|
||||
"19": "Sicherheitsstufe Gateway-Untergerät",
|
||||
"22": "PLC",
|
||||
"23": "nur Kabel",
|
||||
"24": "Matter",
|
||||
"25": "WiFi+Zellnetz"
|
||||
},
|
||||
"room_name_rule": {
|
||||
"none": "nicht synchronisieren",
|
||||
"home_room": "Hausname und Raumname (Xiaomi Home Schlafzimmer)",
|
||||
@ -18,6 +54,11 @@
|
||||
"enable": "aktivieren",
|
||||
"disable": "deaktivieren"
|
||||
},
|
||||
"device_state": {
|
||||
"add": "hinzufügen",
|
||||
"del": "nicht verfügbar",
|
||||
"offline": "offline"
|
||||
},
|
||||
"lan_ctrl_config": {
|
||||
"notice_net_dup": "\r\n**[Hinweis]** Es wurden mehrere Netzwerkkarten erkannt, die möglicherweise mit demselben Netzwerk verbunden sind. Bitte achten Sie auf die Auswahl.",
|
||||
"net_unavailable": "Schnittstelle nicht verfügbar"
|
||||
|
@ -2,12 +2,48 @@
|
||||
"config": {
|
||||
"other": {
|
||||
"devices": "Devices",
|
||||
"found_central_gateway": ", Found Local Central Hub Gateway"
|
||||
"found_central_gateway": ", Found Local Central Hub Gateway",
|
||||
"without_room": "No room assigned",
|
||||
"no_display": "Do not display"
|
||||
},
|
||||
"control_mode": {
|
||||
"auto": "Auto",
|
||||
"cloud": "Cloud"
|
||||
},
|
||||
"statistics_logic": {
|
||||
"or": "OR logic",
|
||||
"and": "AND logic"
|
||||
},
|
||||
"filter_mode": {
|
||||
"exclude": "Exclude",
|
||||
"include": "Include"
|
||||
},
|
||||
"connect_type": {
|
||||
"0": "WiFi",
|
||||
"1": "yunyi device",
|
||||
"2": "Cloud device",
|
||||
"3": "ZigBee",
|
||||
"4": "webSocket",
|
||||
"5": "Virtual device",
|
||||
"6": "BLE",
|
||||
"7": "Local AP",
|
||||
"8": "WiFi+BLE",
|
||||
"9": "Other",
|
||||
"10": "Function plug-in",
|
||||
"11": "Cellular network",
|
||||
"12": "Cable",
|
||||
"13": "NB-IoT",
|
||||
"14": "Third-party cloud access",
|
||||
"15": "Infrared remote control device",
|
||||
"16": "BLE-Mesh",
|
||||
"17": "Virtual device group",
|
||||
"18": "Gateway sub-device",
|
||||
"19": "Security level gateway sub-device",
|
||||
"22": "PLC",
|
||||
"23": "Cable only",
|
||||
"24": "Matter",
|
||||
"25": "WiFi+Cellular network"
|
||||
},
|
||||
"room_name_rule": {
|
||||
"none": "Do not synchronize",
|
||||
"home_room": "Home Name and Room Name (Xiaomi Home Bedroom)",
|
||||
@ -18,6 +54,11 @@
|
||||
"enable": "Enable",
|
||||
"disable": "Disable"
|
||||
},
|
||||
"device_state": {
|
||||
"add": "Add",
|
||||
"del": "Unavailable",
|
||||
"offline": "Offline"
|
||||
},
|
||||
"lan_ctrl_config": {
|
||||
"notice_net_dup": "\r\n**[Notice]** Multiple network cards detected that may be connected to the same network. Please pay attention to the selection.",
|
||||
"net_unavailable": "Interface unavailable"
|
||||
|
@ -2,12 +2,48 @@
|
||||
"config": {
|
||||
"other": {
|
||||
"devices": "dispositivos",
|
||||
"found_central_gateway": ", se encontró la puerta de enlace central local"
|
||||
"found_central_gateway": ", se encontró la puerta de enlace central local",
|
||||
"without_room": "Sin habitación asignada",
|
||||
"no_display": "no mostrar"
|
||||
},
|
||||
"control_mode": {
|
||||
"auto": "automático",
|
||||
"cloud": "nube"
|
||||
},
|
||||
"statistics_logic": {
|
||||
"or": "lógica OR",
|
||||
"and": "lógica AND"
|
||||
},
|
||||
"filter_mode": {
|
||||
"exclude": "excluir",
|
||||
"include": "incluir"
|
||||
},
|
||||
"connect_type": {
|
||||
"0": "WiFi",
|
||||
"1": "dispositivo yunyi",
|
||||
"2": "dispositivo de nube",
|
||||
"3": "ZigBee",
|
||||
"4": "webSocket",
|
||||
"5": "dispositivo virtual",
|
||||
"6": "BLE",
|
||||
"7": "AP local",
|
||||
"8": "WiFi+BLE",
|
||||
"9": "otro",
|
||||
"10": "complemento de función",
|
||||
"11": "red celular",
|
||||
"12": "cable",
|
||||
"13": "NB-IoT",
|
||||
"14": "acceso a la nube de terceros",
|
||||
"15": "dispositivo de control remoto infrarrojo",
|
||||
"16": "BLE-Mesh",
|
||||
"17": "grupo de dispositivos virtuales",
|
||||
"18": "subdispositivo de puerta de enlace",
|
||||
"19": "subdispositivo de puerta de enlace de nivel de seguridad",
|
||||
"22": "PLC",
|
||||
"23": "solo cable",
|
||||
"24": "Matter",
|
||||
"25": "WiFi+red celular"
|
||||
},
|
||||
"room_name_rule": {
|
||||
"none": "no sincronizar",
|
||||
"home_room": "nombre de la casa y nombre de la habitación (Xiaomi Home Dormitorio)",
|
||||
@ -18,6 +54,11 @@
|
||||
"enable": "habilitar",
|
||||
"disable": "deshabilitar"
|
||||
},
|
||||
"device_state": {
|
||||
"add": "agregar",
|
||||
"del": "no disponible",
|
||||
"offline": "fuera de línea"
|
||||
},
|
||||
"lan_ctrl_config": {
|
||||
"notice_net_dup": "\r\n**[Aviso]** Se detectaron varias tarjetas de red que pueden estar conectadas a la misma red. Por favor, preste atención a la selección.",
|
||||
"net_unavailable": "Interfaz no disponible"
|
||||
|
@ -2,12 +2,48 @@
|
||||
"config": {
|
||||
"other": {
|
||||
"devices": "appareils",
|
||||
"found_central_gateway": ", passerelle centrale locale trouvée"
|
||||
"found_central_gateway": ", passerelle centrale locale trouvée",
|
||||
"without_room": "Aucune pièce attribuée",
|
||||
"no_display": "ne pas afficher"
|
||||
},
|
||||
"control_mode": {
|
||||
"auto": "automatique",
|
||||
"cloud": "cloud"
|
||||
},
|
||||
"statistics_logic": {
|
||||
"or": "ou logique",
|
||||
"and": "et logique"
|
||||
},
|
||||
"filter_mode": {
|
||||
"exclude": "exclure",
|
||||
"include": "inclure"
|
||||
},
|
||||
"connect_type": {
|
||||
"0": "WiFi",
|
||||
"1": "appareil yunyi",
|
||||
"2": "appareil cloud",
|
||||
"3": "ZigBee",
|
||||
"4": "webSocket",
|
||||
"5": "appareil virtuel",
|
||||
"6": "BLE",
|
||||
"7": "AP local",
|
||||
"8": "WiFi+BLE",
|
||||
"9": "autre",
|
||||
"10": "plug-in de fonction",
|
||||
"11": "réseau cellulaire",
|
||||
"12": "câble",
|
||||
"13": "NB-IoT",
|
||||
"14": "accès cloud tiers",
|
||||
"15": "appareil de télécommande infrarouge",
|
||||
"16": "BLE-Mesh",
|
||||
"17": "groupe d'appareils virtuels",
|
||||
"18": "sous-appareil de passerelle",
|
||||
"19": "niveau de sécurité sous-appareil de passerelle",
|
||||
"22": "PLC",
|
||||
"23": "câble uniquement",
|
||||
"24": "Matter",
|
||||
"25": "WiFi+réseau cellulaire"
|
||||
},
|
||||
"room_name_rule": {
|
||||
"none": "ne pas synchroniser",
|
||||
"home_room": "nom de la maison et nom de la pièce (Xiaomi Home Chambre)",
|
||||
@ -18,6 +54,11 @@
|
||||
"enable": "activer",
|
||||
"disable": "désactiver"
|
||||
},
|
||||
"device_state": {
|
||||
"add": "Ajouter",
|
||||
"del": "Supprimer",
|
||||
"offline": "hors ligne"
|
||||
},
|
||||
"lan_ctrl_config": {
|
||||
"notice_net_dup": "\r\n**[Remarque]** Plusieurs cartes réseau détectées qui peuvent être connectées au même réseau. Veuillez faire attention à la sélection.",
|
||||
"net_unavailable": "Interface non disponible"
|
||||
|
@ -2,12 +2,48 @@
|
||||
"config": {
|
||||
"other": {
|
||||
"devices": "デバイス",
|
||||
"found_central_gateway": "、ローカル中央ゲートウェイが見つかりました"
|
||||
"found_central_gateway": "、ローカル中央ゲートウェイが見つかりました",
|
||||
"without_room": "部屋が割り当てられていません",
|
||||
"no_display": "表示しない"
|
||||
},
|
||||
"control_mode": {
|
||||
"auto": "自動",
|
||||
"cloud": "クラウド"
|
||||
},
|
||||
"statistics_logic": {
|
||||
"or": "ORロジック",
|
||||
"and": "ANDロジック"
|
||||
},
|
||||
"filter_mode": {
|
||||
"exclude": "除外",
|
||||
"include": "含む"
|
||||
},
|
||||
"connect_type": {
|
||||
"0": "WiFi",
|
||||
"1": "yunyiデバイス",
|
||||
"2": "クラウドデバイス",
|
||||
"3": "ZigBee",
|
||||
"4": "webSocket",
|
||||
"5": "仮想デバイス",
|
||||
"6": "BLE",
|
||||
"7": "ローカルAP",
|
||||
"8": "WiFi+BLE",
|
||||
"9": "その他",
|
||||
"10": "機能プラグイン",
|
||||
"11": "セルラーネットワーク",
|
||||
"12": "ケーブル",
|
||||
"13": "NB-IoT",
|
||||
"14": "サードパーティクラウドアクセス",
|
||||
"15": "赤外線リモコンデバイス",
|
||||
"16": "BLE-Mesh",
|
||||
"17": "仮想デバイスグループ",
|
||||
"18": "ゲートウェイサブデバイス",
|
||||
"19": "セキュリティレベルゲートウェイサブデバイス",
|
||||
"22": "PLC",
|
||||
"23": "ケーブルのみ",
|
||||
"24": "Matter",
|
||||
"25": "WiFi+セルラーネットワーク"
|
||||
},
|
||||
"room_name_rule": {
|
||||
"none": "同期しない",
|
||||
"home_room": "家の名前と部屋の名前 (Xiaomi Home 寝室)",
|
||||
@ -18,6 +54,11 @@
|
||||
"enable": "有効",
|
||||
"disable": "無効"
|
||||
},
|
||||
"device_state": {
|
||||
"add": "追加",
|
||||
"del": "利用不可",
|
||||
"offline": "オフライン"
|
||||
},
|
||||
"lan_ctrl_config": {
|
||||
"notice_net_dup": "\r\n**[注意]** 複数のネットワークカードが同じネットワークに接続されている可能性があります。選択に注意してください。",
|
||||
"net_unavailable": "インターフェースが利用できません"
|
||||
|
136
custom_components/xiaomi_home/miot/i18n/nl.json
Normal file
136
custom_components/xiaomi_home/miot/i18n/nl.json
Normal file
@ -0,0 +1,136 @@
|
||||
{
|
||||
"config": {
|
||||
"other": {
|
||||
"devices": "Apparaten",
|
||||
"found_central_gateway": ", Lokale centrale hub-gateway gevonden",
|
||||
"without_room": "Niet toegewezen kamer",
|
||||
"no_display": "Niet weergeven"
|
||||
},
|
||||
"control_mode": {
|
||||
"auto": "Automatisch",
|
||||
"cloud": "Cloud"
|
||||
},
|
||||
"statistics_logic": {
|
||||
"or": "OF-logica",
|
||||
"and": "EN-logica"
|
||||
},
|
||||
"filter_mode": {
|
||||
"exclude": "Uitsluiten",
|
||||
"include": "Inclusief"
|
||||
},
|
||||
"connect_type": {
|
||||
"0": "WiFi",
|
||||
"1": "yunyi-apparaat",
|
||||
"2": "Cloudapparaat",
|
||||
"3": "ZigBee",
|
||||
"4": "webSocket",
|
||||
"5": "Virtueel apparaat",
|
||||
"6": "BLE",
|
||||
"7": "Lokaal AP",
|
||||
"8": "WiFi+BLE",
|
||||
"9": "Andere",
|
||||
"10": "Functieplug-in",
|
||||
"11": "Cellulair netwerk",
|
||||
"12": "Kabel",
|
||||
"13": "NB-IoT",
|
||||
"14": "Toegang van derden tot de cloud",
|
||||
"15": "Infrarood afstandsbedieningsapparaat",
|
||||
"16": "BLE-Mesh",
|
||||
"17": "Virtuele apparaatgroep",
|
||||
"18": "Gateway sub-apparaat",
|
||||
"19": "Beveiligingsniveau gateway sub-apparaat",
|
||||
"22": "PLC",
|
||||
"23": "Alleen kabel",
|
||||
"24": "Matter",
|
||||
"25": "WiFi+Cellulair netwerk"
|
||||
},
|
||||
"room_name_rule": {
|
||||
"none": "Niet synchroniseren",
|
||||
"home_room": "Huisnaam en Kamernaam (Xiaomi Home Slaapkamer)",
|
||||
"room": "Kamernaam (Slaapkamer)",
|
||||
"home": "Huisnaam (Xiaomi Home)"
|
||||
},
|
||||
"option_status": {
|
||||
"enable": "Inschakelen",
|
||||
"disable": "Uitschakelen"
|
||||
},
|
||||
"device_state": {
|
||||
"add": "Toevoegen",
|
||||
"del": "Niet beschikbaar",
|
||||
"offline": "Offline"
|
||||
},
|
||||
"lan_ctrl_config": {
|
||||
"notice_net_dup": "\r\n**[Let op]** Meerdere netwerkkaarten gedetecteerd die mogelijk zijn verbonden met hetzelfde netwerk. Let op bij de selectie.",
|
||||
"net_unavailable": "Interface niet beschikbaar"
|
||||
}
|
||||
},
|
||||
"miot": {
|
||||
"client": {
|
||||
"invalid_oauth_info": "Authenticatie-informatie is ongeldig, cloudverbinding zal niet beschikbaar zijn. Ga naar de Xiaomi Home-integratiepagina en klik op 'Opties' om opnieuw te verifiëren.",
|
||||
"invalid_device_cache": "Cache van apparaatgegevens is abnormaal. Ga naar de Xiaomi Home-integratiepagina, klik op 'Opties->Apparaatlijst bijwerken' en werk de lokale cache bij.",
|
||||
"invalid_cert_info": "Ongeldig gebruikerscertificaat, lokale centrale verbinding zal niet beschikbaar zijn. Ga naar de Xiaomi Home-integratiepagina en klik op 'Opties' om opnieuw te verifiëren.",
|
||||
"device_cloud_error": "Er is een uitzondering opgetreden bij het ophalen van apparaatgegevens uit de cloud. Controleer de lokale netwerkverbinding.",
|
||||
"xiaomi_home_error_title": "Xiaomi Home-integratiefout",
|
||||
"xiaomi_home_error": "Gedetecteerd **{nick_name}({uid}, {cloud_server})** fout, ga naar de optiespagina om opnieuw te configureren.\n\n**Foutmelding**: \n{message}",
|
||||
"device_list_changed_title": "Wijzigingen in Xiaomi Home-apparaatlijst",
|
||||
"device_list_changed": "Gedetecteerd **{nick_name}({uid}, {cloud_server})** apparaatgegevens zijn gewijzigd. Ga naar de integratie-optiespagina, klik op `Opties->Apparaatlijst bijwerken` en werk lokale apparaatgegevens bij.\n\nHuidige netwerkstatus: {network_status}\n{message}\n",
|
||||
"device_list_add": "\n**{count} nieuwe apparaten:** \n{message}",
|
||||
"device_list_del": "\n**{count} apparaten niet beschikbaar:** \n{message}",
|
||||
"device_list_offline": "\n**{count} apparaten offline:** \n{message}",
|
||||
"network_status_online": "Online",
|
||||
"network_status_offline": "Offline",
|
||||
"device_exec_error": "Uitvoeringsfout"
|
||||
}
|
||||
},
|
||||
"error": {
|
||||
"common": {
|
||||
"-10000": "Onbekende fout",
|
||||
"-10001": "Service niet beschikbaar",
|
||||
"-10002": "Ongeldige parameter",
|
||||
"-10003": "Onvoldoende middelen",
|
||||
"-10004": "Interne fout",
|
||||
"-10005": "Onvoldoende machtigingen",
|
||||
"-10006": "Uitvoeringstijd verstreken",
|
||||
"-10007": "Apparaat offline of bestaat niet",
|
||||
"-10020": "Niet geautoriseerd (OAuth2)",
|
||||
"-10030": "Ongeldig token (HTTP)",
|
||||
"-10040": "Ongeldig berichtformaat",
|
||||
"-10050": "Ongeldig certificaat",
|
||||
"-704000000": "Onbekende fout",
|
||||
"-704010000": "Niet geautoriseerd (apparaat kan zijn verwijderd)",
|
||||
"-704014006": "Apparaatbeschrijving niet gevonden",
|
||||
"-704030013": "Eigenschap niet leesbaar",
|
||||
"-704030023": "Eigenschap niet schrijfbaar",
|
||||
"-704030033": "Eigenschap niet abonneerbaar",
|
||||
"-704040002": "Service bestaat niet",
|
||||
"-704040003": "Eigenschap bestaat niet",
|
||||
"-704040004": "Gebeurtenis bestaat niet",
|
||||
"-704040005": "Actie bestaat niet",
|
||||
"-704040999": "Functie niet online",
|
||||
"-704042001": "Apparaat bestaat niet",
|
||||
"-704042011": "Apparaat offline",
|
||||
"-704053036": "Apparaatbedieningstijd verstreken",
|
||||
"-704053100": "Apparaat kan deze handeling niet uitvoeren in de huidige staat",
|
||||
"-704083036": "Apparaatbedieningstijd verstreken",
|
||||
"-704090001": "Apparaat bestaat niet",
|
||||
"-704220008": "Ongeldige ID",
|
||||
"-704220025": "Aantal actieparameters komt niet overeen",
|
||||
"-704220035": "Fout in actieparameter",
|
||||
"-704220043": "Fout in eigenschapswaarde",
|
||||
"-704222034": "Fout in retourwaarde actie",
|
||||
"-705004000": "Onbekende fout",
|
||||
"-705004501": "Onbekende fout",
|
||||
"-705201013": "Eigenschap niet leesbaar",
|
||||
"-705201015": "Fout bij uitvoeren van actie",
|
||||
"-705201023": "Eigenschap niet schrijfbaar",
|
||||
"-705201033": "Eigenschap niet abonneerbaar",
|
||||
"-706012000": "Onbekende fout",
|
||||
"-706012013": "Eigenschap niet leesbaar",
|
||||
"-706012015": "Fout bij uitvoeren van actie",
|
||||
"-706012023": "Eigenschap niet schrijfbaar",
|
||||
"-706012033": "Eigenschap niet abonneerbaar",
|
||||
"-706012043": "Fout in eigenschapswaarde",
|
||||
"-706014006": "Apparaatbeschrijving niet gevonden"
|
||||
}
|
||||
}
|
||||
}
|
136
custom_components/xiaomi_home/miot/i18n/pt-BR.json
Normal file
136
custom_components/xiaomi_home/miot/i18n/pt-BR.json
Normal file
@ -0,0 +1,136 @@
|
||||
{
|
||||
"config": {
|
||||
"other": {
|
||||
"devices": "dispositivos",
|
||||
"found_central_gateway": "encontrado o gateway central local",
|
||||
"without_room": "sem quarto atribuído",
|
||||
"no_display": "não exibir"
|
||||
},
|
||||
"control_mode": {
|
||||
"auto": "automático",
|
||||
"cloud": "nuvem"
|
||||
},
|
||||
"statistics_logic": {
|
||||
"or": "lógica OU",
|
||||
"and": "lógica E"
|
||||
},
|
||||
"filter_mode": {
|
||||
"exclude": "excluir",
|
||||
"include": "incluir"
|
||||
},
|
||||
"connect_type": {
|
||||
"0": "WiFi",
|
||||
"1": "dispositivo yunyi",
|
||||
"2": "dispositivo de nuvem",
|
||||
"3": "ZigBee",
|
||||
"4": "webSocket",
|
||||
"5": "dispositivo virtual",
|
||||
"6": "BLE",
|
||||
"7": "AP local",
|
||||
"8": "WiFi+BLE",
|
||||
"9": "outro",
|
||||
"10": "plug-in de função",
|
||||
"11": "rede celular",
|
||||
"12": "cabo",
|
||||
"13": "NB-IoT",
|
||||
"14": "acesso à nuvem de terceiros",
|
||||
"15": "dispositivo de controle remoto infravermelho",
|
||||
"16": "BLE-Mesh",
|
||||
"17": "grupo de dispositivos virtuais",
|
||||
"18": "subdispositivo de gateway",
|
||||
"19": "subdispositivo de gateway de nível de segurança",
|
||||
"22": "PLC",
|
||||
"23": "somente cabo",
|
||||
"24": "Matter",
|
||||
"25": "WiFi+rede celular"
|
||||
},
|
||||
"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"
|
||||
},
|
||||
"device_state": {
|
||||
"add": "adicionar",
|
||||
"del": "indisponível",
|
||||
"offline": "offline"
|
||||
},
|
||||
"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"
|
||||
}
|
||||
}
|
||||
}
|
136
custom_components/xiaomi_home/miot/i18n/pt.json
Normal file
136
custom_components/xiaomi_home/miot/i18n/pt.json
Normal file
@ -0,0 +1,136 @@
|
||||
{
|
||||
"config": {
|
||||
"other": {
|
||||
"devices": "dispositivos",
|
||||
"found_central_gateway": ", encontrou a central de gateway local",
|
||||
"without_room": "Sem quarto atribuído",
|
||||
"no_display": "Não exibir"
|
||||
},
|
||||
"control_mode": {
|
||||
"auto": "Automático",
|
||||
"cloud": "Nuvem"
|
||||
},
|
||||
"statistics_logic": {
|
||||
"or": "Ou lógica",
|
||||
"and": "E lógica"
|
||||
},
|
||||
"filter_mode": {
|
||||
"exclude": "Excluir",
|
||||
"include": "Incluir"
|
||||
},
|
||||
"connect_type": {
|
||||
"0": "WiFi",
|
||||
"1": "dispositivo yunyi",
|
||||
"2": "dispositivo de nuvem",
|
||||
"3": "ZigBee",
|
||||
"4": "webSocket",
|
||||
"5": "dispositivo virtual",
|
||||
"6": "BLE",
|
||||
"7": "AP local",
|
||||
"8": "WiFi+BLE",
|
||||
"9": "outro",
|
||||
"10": "plug-in de função",
|
||||
"11": "rede celular",
|
||||
"12": "cabo",
|
||||
"13": "NB-IoT",
|
||||
"14": "acesso à nuvem de terceiros",
|
||||
"15": "dispositivo de controle remoto infravermelho",
|
||||
"16": "BLE-Mesh",
|
||||
"17": "grupo de dispositivos virtuais",
|
||||
"18": "subdispositivo de gateway",
|
||||
"19": "subdispositivo de gateway de nível de segurança",
|
||||
"22": "PLC",
|
||||
"23": "somente cabo",
|
||||
"24": "Matter",
|
||||
"25": "WiFi+rede celular"
|
||||
},
|
||||
"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"
|
||||
},
|
||||
"device_state": {
|
||||
"add": "Adicionar",
|
||||
"del": "Indisponível",
|
||||
"offline": "Offline"
|
||||
},
|
||||
"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"
|
||||
}
|
||||
}
|
||||
}
|
@ -2,12 +2,48 @@
|
||||
"config": {
|
||||
"other": {
|
||||
"devices": "устройства",
|
||||
"found_central_gateway": ", найден локальный центральный шлюз"
|
||||
"found_central_gateway": ", найден локальный центральный шлюз",
|
||||
"without_room": "без комнаты",
|
||||
"no_display": "не отображать"
|
||||
},
|
||||
"control_mode": {
|
||||
"auto": "автоматический",
|
||||
"cloud": "облако"
|
||||
},
|
||||
"statistics_logic": {
|
||||
"or": "логика ИЛИ",
|
||||
"and": "логика И"
|
||||
},
|
||||
"filter_mode": {
|
||||
"exclude": "исключить",
|
||||
"include": "включить"
|
||||
},
|
||||
"connect_type": {
|
||||
"0": "WiFi",
|
||||
"1": "yunyi устройство",
|
||||
"2": "Облачное устройство",
|
||||
"3": "ZigBee",
|
||||
"4": "webSocket",
|
||||
"5": "Виртуальное устройство",
|
||||
"6": "BLE",
|
||||
"7": "Локальный AP",
|
||||
"8": "WiFi+BLE",
|
||||
"9": "Другое",
|
||||
"10": "Плагин функции",
|
||||
"11": "Сотовая сеть",
|
||||
"12": "Кабель",
|
||||
"13": "NB-IoT",
|
||||
"14": "Доступ к стороннему облаку",
|
||||
"15": "Устройство с ИК-пультом дистанционного управления",
|
||||
"16": "BLE-Mesh",
|
||||
"17": "Группа виртуальных устройств",
|
||||
"18": "Подустройство шлюза",
|
||||
"19": "Подустройство шлюза уровня безопасности",
|
||||
"22": "PLC",
|
||||
"23": "Только кабель",
|
||||
"24": "Matter",
|
||||
"25": "WiFi+Сотовая сеть"
|
||||
},
|
||||
"room_name_rule": {
|
||||
"none": "не синхронизировать",
|
||||
"home_room": "название дома и название комнаты (Xiaomi Home Спальня)",
|
||||
@ -18,6 +54,11 @@
|
||||
"enable": "Включить",
|
||||
"disable": "Отключить"
|
||||
},
|
||||
"device_state": {
|
||||
"add": "Добавить",
|
||||
"del": "Недоступно",
|
||||
"offline": "Не в сети"
|
||||
},
|
||||
"lan_ctrl_config": {
|
||||
"notice_net_dup": "\r\n**[Уведомление]** Обнаружено несколько сетевых карт, которые могут быть подключены к одной и той же сети. Пожалуйста, обратите внимание на выбор.",
|
||||
"net_unavailable": "Интерфейс недоступен"
|
||||
|
@ -2,7 +2,9 @@
|
||||
"config": {
|
||||
"other": {
|
||||
"devices": "个设备",
|
||||
"found_central_gateway": ",发现本地中枢网关"
|
||||
"found_central_gateway": ",发现本地中枢网关",
|
||||
"without_room": "未分配房间",
|
||||
"no_display": "不显示"
|
||||
},
|
||||
"control_mode": {
|
||||
"auto": "自动",
|
||||
@ -14,10 +16,49 @@
|
||||
"room": "房间名 (卧室)",
|
||||
"home": "家庭名 (米家)"
|
||||
},
|
||||
"statistics_logic": {
|
||||
"or": "或逻辑",
|
||||
"and": "与逻辑"
|
||||
},
|
||||
"filter_mode": {
|
||||
"exclude": "排除",
|
||||
"include": "包含"
|
||||
},
|
||||
"connect_type": {
|
||||
"0": "WiFi",
|
||||
"1": "yunyi设备",
|
||||
"2": "云接入设备",
|
||||
"3": "ZigBee",
|
||||
"4": "webSocket",
|
||||
"5": "虚拟设备",
|
||||
"6": "BLE",
|
||||
"7": "本地AP",
|
||||
"8": "WiFi+BLE",
|
||||
"9": "其他",
|
||||
"10": "功能插件",
|
||||
"11": "蜂窝网",
|
||||
"12": "网线",
|
||||
"13": "NB-IoT",
|
||||
"14": "第三方云接入",
|
||||
"15": "红外遥控器子设备",
|
||||
"16": "BLE-Mesh",
|
||||
"17": "虚拟设备组",
|
||||
"18": "代理网关子设备",
|
||||
"19": "安全级代理网关子设备",
|
||||
"22": "PLC",
|
||||
"23": "仅网线",
|
||||
"24": "Matter",
|
||||
"25": "WiFi+蜂窝网"
|
||||
},
|
||||
"option_status": {
|
||||
"enable": "启用",
|
||||
"disable": "禁用"
|
||||
},
|
||||
"device_state": {
|
||||
"add": "新增",
|
||||
"del": "不可用",
|
||||
"offline": "离线"
|
||||
},
|
||||
"lan_ctrl_config": {
|
||||
"notice_net_dup": "\r\n**[提示]** 检测到多个网卡可能连接同一个网络,请注意选择。",
|
||||
"net_unavailable": "接口不可用"
|
||||
|
@ -2,12 +2,48 @@
|
||||
"config": {
|
||||
"other": {
|
||||
"devices": "個設備",
|
||||
"found_central_gateway": ",發現本地中樞網關"
|
||||
"found_central_gateway": ",發現本地中樞網關",
|
||||
"without_room": "未分配房間",
|
||||
"no_display": "不顯示"
|
||||
},
|
||||
"control_mode": {
|
||||
"auto": "自動",
|
||||
"cloud": "雲端"
|
||||
},
|
||||
"statistics_logic": {
|
||||
"or": "或邏輯",
|
||||
"and": "與邏輯"
|
||||
},
|
||||
"filter_mode": {
|
||||
"exclude": "排除",
|
||||
"include": "包含"
|
||||
},
|
||||
"connect_type": {
|
||||
"0": "WiFi",
|
||||
"1": "yunyi設備",
|
||||
"2": "雲接入設備",
|
||||
"3": "ZigBee",
|
||||
"4": "webSocket",
|
||||
"5": "虛擬設備",
|
||||
"6": "BLE",
|
||||
"7": "本地AP",
|
||||
"8": "WiFi+BLE",
|
||||
"9": "其他",
|
||||
"10": "功能插件",
|
||||
"11": "蜂窩網",
|
||||
"12": "網線",
|
||||
"13": "NB-IoT",
|
||||
"14": "第三方雲接入",
|
||||
"15": "紅外遙控器子設備",
|
||||
"16": "BLE-Mesh",
|
||||
"17": "虛擬設備組",
|
||||
"18": "代理網關子設備",
|
||||
"19": "安全級代理網關子設備",
|
||||
"22": "PLC",
|
||||
"23": "僅網線",
|
||||
"24": "Matter",
|
||||
"25": "WiFi+蜂窩網"
|
||||
},
|
||||
"room_name_rule": {
|
||||
"none": "不同步",
|
||||
"home_room": "家庭名 和 房間名 (米家 臥室)",
|
||||
@ -18,6 +54,11 @@
|
||||
"enable": "啟用",
|
||||
"disable": "禁用"
|
||||
},
|
||||
"device_state": {
|
||||
"add": "新增",
|
||||
"del": "不可用",
|
||||
"offline": "離線"
|
||||
},
|
||||
"lan_ctrl_config": {
|
||||
"notice_net_dup": "\r\n**[提示]** 檢測到多個網卡可能連接同一個網絡,請注意選擇。",
|
||||
"net_unavailable": "接口不可用"
|
||||
@ -43,20 +84,18 @@
|
||||
},
|
||||
"error": {
|
||||
"common": {
|
||||
"-1": "未知錯誤",
|
||||
"-10000": "未知錯誤",
|
||||
"-10001": "服務不可用",
|
||||
"-10002": "無效參數",
|
||||
"-10002": "參數無效",
|
||||
"-10003": "資源不足",
|
||||
"-10004": "內部錯誤",
|
||||
"-10005": "權限不足",
|
||||
"-10006": "執行超時",
|
||||
"-10007": "設備離線或者不存在",
|
||||
"-10020": "無效的消息格式"
|
||||
},
|
||||
"gw": {},
|
||||
"lan": {},
|
||||
"cloud": {
|
||||
"-10020": "未授權(OAuth2)",
|
||||
"-10030": "無效的token(HTTP)",
|
||||
"-10040": "無效的消息格式",
|
||||
"-10050": "無效的證書",
|
||||
"-704000000": "未知錯誤",
|
||||
"-704010000": "未授權(設備可能被刪除)",
|
||||
"-704014006": "沒找到設備描述",
|
||||
|
1320
custom_components/xiaomi_home/miot/lan/profile_models.yaml
Normal file
1320
custom_components/xiaomi_home/miot/lan/profile_models.yaml
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,52 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""MIoT client instance."""
|
||||
"""
|
||||
Copyright (C) 2024 Xiaomi Corporation.
|
||||
|
||||
The ownership and intellectual property rights of Xiaomi Home Assistant
|
||||
Integration and related Xiaomi cloud service API interface provided under this
|
||||
license, including source code and object code (collectively, "Licensed Work"),
|
||||
are owned by Xiaomi. Subject to the terms and conditions of this License, Xiaomi
|
||||
hereby grants you a personal, limited, non-exclusive, non-transferable,
|
||||
non-sublicensable, and royalty-free license to reproduce, use, modify, and
|
||||
distribute the Licensed Work only for your use of Home Assistant for
|
||||
non-commercial purposes. For the avoidance of doubt, Xiaomi does not authorize
|
||||
you to use the Licensed Work for any other purpose, including but not limited
|
||||
to use Licensed Work to develop applications (APP), Web services, and other
|
||||
forms of software.
|
||||
|
||||
You may reproduce and distribute copies of the Licensed Work, with or without
|
||||
modifications, whether in source or object form, provided that you must give
|
||||
any other recipients of the Licensed Work a copy of this License and retain all
|
||||
copyright and disclaimers.
|
||||
|
||||
Xiaomi provides the Licensed Work on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied, including, without
|
||||
limitation, any warranties, undertakes, or conditions of TITLE, NO ERROR OR
|
||||
OMISSION, CONTINUITY, RELIABILITY, NON-INFRINGEMENT, MERCHANTABILITY, or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. In any event, you are solely responsible
|
||||
for any direct, indirect, special, incidental, or consequential damages or
|
||||
losses arising from the use or inability to use the Licensed Work.
|
||||
|
||||
Xiaomi reserves all rights not expressly granted to you in this License.
|
||||
Except for the rights expressly granted by Xiaomi under this License, Xiaomi
|
||||
does not authorize you in any form to use the trademarks, copyrights, or other
|
||||
forms of intellectual property rights of Xiaomi and its affiliates, including,
|
||||
without limitation, without obtaining other written permission from Xiaomi, you
|
||||
shall not use "Xiaomi", "Mijia" and other words related to Xiaomi or words that
|
||||
may make the public associate with Xiaomi in any form to publicize or promote
|
||||
the software or hardware devices that use the Licensed Work.
|
||||
|
||||
Xiaomi has the right to immediately terminate all your authorization under this
|
||||
License in the event:
|
||||
1. You assert patent invalidation, litigation, or other claims against patents
|
||||
or other intellectual property rights of Xiaomi or its affiliates; or,
|
||||
2. You make, have made, manufacture, sell, or offer to sell products that knock
|
||||
off Xiaomi or its affiliates' products.
|
||||
|
||||
MIoT client instance.
|
||||
"""
|
||||
from copy import deepcopy
|
||||
from typing import Callable, Optional, final
|
||||
from typing import Any, Callable, Optional, final
|
||||
import asyncio
|
||||
import json
|
||||
import logging
|
||||
@ -36,9 +81,9 @@ _LOGGER = logging.getLogger(__name__)
|
||||
@dataclass
|
||||
class MIoTClientSub:
|
||||
"""MIoT client subscription."""
|
||||
topic: str = None
|
||||
handler: Callable[[dict, any], None] = None
|
||||
handler_ctx: any = None
|
||||
topic: Optional[str]
|
||||
handler: Callable[[dict, Any], None]
|
||||
handler_ctx: Any = None
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f'{self.topic}, {id(self.handler)}, {id(self.handler_ctx)}'
|
||||
@ -119,9 +164,11 @@ class MIoTClient:
|
||||
_refresh_props_retry_count: int
|
||||
|
||||
# Persistence notify handler, params: notify_id, title, message
|
||||
_persistence_notify: Callable[[str, str, str], None]
|
||||
_persistence_notify: Callable[[str, Optional[str], Optional[str]], None]
|
||||
# Device list changed notify
|
||||
_show_devices_changed_notify_timer: Optional[asyncio.TimerHandle]
|
||||
# Display devices changed notify
|
||||
_display_devs_notify: list[str]
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
@ -186,6 +233,9 @@ class MIoTClient:
|
||||
self._persistence_notify = None
|
||||
self._show_devices_changed_notify_timer = None
|
||||
|
||||
self._display_devs_notify = entry_data.get(
|
||||
'display_devices_changed_notify', ['add', 'del', 'offline'])
|
||||
|
||||
async def init_async(self) -> None:
|
||||
# Load user config and check
|
||||
self._user_config = await self._storage.load_user_config_async(
|
||||
@ -194,14 +244,14 @@ class MIoTClient:
|
||||
# Integration need to be add again
|
||||
raise MIoTClientError('load_user_config_async error')
|
||||
_LOGGER.debug('user config, %s', json.dumps(self._user_config))
|
||||
# Load cache device list
|
||||
await self.__load_cache_device_async()
|
||||
# MIoT i18n client
|
||||
self._i18n = MIoTI18n(
|
||||
lang=self._entry_data.get(
|
||||
'integration_language', DEFAULT_INTEGRATION_LANGUAGE),
|
||||
loop=self._main_loop)
|
||||
await self._i18n.init_async()
|
||||
# Load cache device list
|
||||
await self.__load_cache_device_async()
|
||||
# MIoT oauth client instance
|
||||
self._oauth = MIoTOauthClient(
|
||||
client_id=OAUTH2_CLIENT_ID,
|
||||
@ -345,6 +395,8 @@ class MIoTClient:
|
||||
if self._show_devices_changed_notify_timer:
|
||||
self._show_devices_changed_notify_timer.cancel()
|
||||
self._show_devices_changed_notify_timer = None
|
||||
await self._oauth.deinit_async()
|
||||
await self._http.deinit_async()
|
||||
# Remove notify
|
||||
self._persistence_notify(
|
||||
self.__gen_notify_key('dev_list_changed'), None, None)
|
||||
@ -412,6 +464,21 @@ class MIoTClient:
|
||||
return self._entry_data.get(
|
||||
'hide_non_standard_entities', False)
|
||||
|
||||
@property
|
||||
def display_devices_changed_notify(self) -> list[str]:
|
||||
return self._display_devs_notify
|
||||
|
||||
@display_devices_changed_notify.setter
|
||||
def display_devices_changed_notify(self, value: list[str]) -> None:
|
||||
if set(value) == set(self._display_devs_notify):
|
||||
return
|
||||
self._display_devs_notify = value
|
||||
if value:
|
||||
self.__request_show_devices_changed_notify()
|
||||
else:
|
||||
self._persistence_notify(
|
||||
self.__gen_notify_key('dev_list_changed'), None, None)
|
||||
|
||||
@property
|
||||
def device_list(self) -> dict:
|
||||
return self._device_list_cache
|
||||
@ -526,7 +593,7 @@ class MIoTClient:
|
||||
return False
|
||||
|
||||
async def set_prop_async(
|
||||
self, did: str, siid: int, piid: int, value: any
|
||||
self, did: str, siid: int, piid: int, value: Any
|
||||
) -> bool:
|
||||
if did not in self._device_list_cache:
|
||||
raise MIoTClientError(f'did not exist, {did}')
|
||||
@ -612,7 +679,7 @@ class MIoTClient:
|
||||
0.2, lambda: self._main_loop.create_task(
|
||||
self.__refresh_props_handler()))
|
||||
|
||||
async def get_prop_async(self, did: str, siid: int, piid: int) -> any:
|
||||
async def get_prop_async(self, did: str, siid: int, piid: int) -> Any:
|
||||
if did not in self._device_list_cache:
|
||||
raise MIoTClientError(f'did not exist, {did}')
|
||||
|
||||
@ -717,8 +784,8 @@ class MIoTClient:
|
||||
return None
|
||||
|
||||
def sub_prop(
|
||||
self, did: str, handler: Callable[[dict, any], None],
|
||||
siid: int = None, piid: int = None, handler_ctx: any = None
|
||||
self, did: str, handler: Callable[[dict, Any], None],
|
||||
siid: int = None, piid: int = None, handler_ctx: Any = None
|
||||
) -> bool:
|
||||
if did not in self._device_list_cache:
|
||||
raise MIoTClientError(f'did not exist, {did}')
|
||||
@ -741,8 +808,8 @@ class MIoTClient:
|
||||
return True
|
||||
|
||||
def sub_event(
|
||||
self, did: str, handler: Callable[[dict, any], None],
|
||||
siid: int = None, eiid: int = None, handler_ctx: any = None
|
||||
self, did: str, handler: Callable[[dict, Any], None],
|
||||
siid: int = None, eiid: int = None, handler_ctx: Any = None
|
||||
) -> bool:
|
||||
if did not in self._device_list_cache:
|
||||
raise MIoTClientError(f'did not exist, {did}')
|
||||
@ -764,8 +831,8 @@ class MIoTClient:
|
||||
return True
|
||||
|
||||
def sub_device_state(
|
||||
self, did: str, handler: Callable[[str, MIoTDeviceState, any], None],
|
||||
handler_ctx: any = None
|
||||
self, did: str, handler: Callable[[str, MIoTDeviceState, Any], None],
|
||||
handler_ctx: Any = None
|
||||
) -> bool:
|
||||
"""Call callback handler in main loop"""
|
||||
if did not in self._device_list_cache:
|
||||
@ -1022,12 +1089,13 @@ class MIoTClient:
|
||||
handler=self.__on_lan_device_state_changed)
|
||||
for did, info in (
|
||||
await self._miot_lan.get_dev_list_async()).items():
|
||||
self.__on_lan_device_state_changed(
|
||||
await self.__on_lan_device_state_changed(
|
||||
did=did, state=info, ctx=None)
|
||||
_LOGGER.info('lan device list, %s', self._device_list_lan)
|
||||
self._miot_lan.update_devices(devices={
|
||||
did: {
|
||||
'token': info['token'],
|
||||
'model': info['model'],
|
||||
'connect_type': info['connect_type']}
|
||||
for did, info in self._device_list_cache.items()
|
||||
if 'token' in info and 'connect_type' in info
|
||||
@ -1059,7 +1127,7 @@ class MIoTClient:
|
||||
|
||||
@final
|
||||
def __on_cloud_device_state_changed(
|
||||
self, did: str, state: MIoTDeviceState, ctx: any
|
||||
self, did: str, state: MIoTDeviceState, ctx: Any
|
||||
) -> None:
|
||||
_LOGGER.info('cloud device state changed, %s, %s', did, state)
|
||||
cloud_device = self._device_list_cloud.get(did, None)
|
||||
@ -1109,7 +1177,7 @@ class MIoTClient:
|
||||
|
||||
@final
|
||||
async def __on_lan_device_state_changed(
|
||||
self, did: str, state: dict, ctx: any
|
||||
self, did: str, state: dict, ctx: Any
|
||||
) -> None:
|
||||
_LOGGER.info('lan device state changed, %s, %s', did, state)
|
||||
lan_state_new: bool = state.get('online', False)
|
||||
@ -1145,7 +1213,7 @@ class MIoTClient:
|
||||
self.__request_show_devices_changed_notify()
|
||||
|
||||
@final
|
||||
def __on_prop_msg(self, params: dict, ctx: any) -> None:
|
||||
def __on_prop_msg(self, params: dict, ctx: Any) -> None:
|
||||
"""params MUST contain did, siid, piid, value"""
|
||||
# BLE device has no online/offline msg
|
||||
try:
|
||||
@ -1157,7 +1225,7 @@ class MIoTClient:
|
||||
_LOGGER.error('on prop msg error, %s, %s', params, err)
|
||||
|
||||
@final
|
||||
def __on_event_msg(self, params: dict, ctx: any) -> None:
|
||||
def __on_event_msg(self, params: dict, ctx: Any) -> None:
|
||||
try:
|
||||
subs: list[MIoTClientSub] = list(self._sub_tree.iter_match(
|
||||
f'{params["did"]}/e/{params["siid"]}/{params["eiid"]}'))
|
||||
@ -1291,6 +1359,7 @@ class MIoTClient:
|
||||
self._miot_lan.update_devices(devices={
|
||||
did: {
|
||||
'token': info['token'],
|
||||
'model': info['model'],
|
||||
'connect_type': info['connect_type']}
|
||||
for did, info in self._device_list_cache.items()
|
||||
if 'token' in info and 'connect_type' in info
|
||||
@ -1489,7 +1558,7 @@ class MIoTClient:
|
||||
None)
|
||||
self.__on_prop_msg(params=result, ctx=None)
|
||||
if request_list:
|
||||
_LOGGER.error(
|
||||
_LOGGER.info(
|
||||
'refresh props failed, cloud, %s',
|
||||
list(request_list.keys()))
|
||||
request_list = None
|
||||
@ -1545,7 +1614,7 @@ class MIoTClient:
|
||||
succeed_once = True
|
||||
if succeed_once:
|
||||
return True
|
||||
_LOGGER.error(
|
||||
_LOGGER.info(
|
||||
'refresh props failed, gw, %s', list(request_list.keys()))
|
||||
# Add failed request back to the list
|
||||
self._refresh_props_list.update(request_list)
|
||||
@ -1588,7 +1657,7 @@ class MIoTClient:
|
||||
succeed_once = True
|
||||
if succeed_once:
|
||||
return True
|
||||
_LOGGER.error(
|
||||
_LOGGER.info(
|
||||
'refresh props failed, lan, %s', list(request_list.keys()))
|
||||
# Add failed request back to the list
|
||||
self._refresh_props_list.update(request_list)
|
||||
@ -1620,10 +1689,10 @@ class MIoTClient:
|
||||
if self._refresh_props_timer:
|
||||
self._refresh_props_timer.cancel()
|
||||
self._refresh_props_timer = None
|
||||
_LOGGER.error('refresh props failed, retry count exceed')
|
||||
_LOGGER.info('refresh props failed, retry count exceed')
|
||||
return
|
||||
self._refresh_props_retry_count += 1
|
||||
_LOGGER.error(
|
||||
_LOGGER.info(
|
||||
'refresh props failed, retry, %s', self._refresh_props_retry_count)
|
||||
self._refresh_props_timer = self._main_loop.call_later(
|
||||
3, lambda: self._main_loop.create_task(
|
||||
@ -1667,15 +1736,16 @@ class MIoTClient:
|
||||
count_offline: int = 0
|
||||
|
||||
# New devices
|
||||
for did, info in {
|
||||
**self._device_list_gateway, **self._device_list_cloud
|
||||
}.items():
|
||||
if did in self._device_list_cache:
|
||||
continue
|
||||
count_add += 1
|
||||
message_add += (
|
||||
f'- {info.get("name", "unknown")} ({did}, '
|
||||
f'{info.get("model", "unknown")})\n')
|
||||
if 'add' in self._display_devs_notify:
|
||||
for did, info in {
|
||||
**self._device_list_gateway, **self._device_list_cloud
|
||||
}.items():
|
||||
if did in self._device_list_cache:
|
||||
continue
|
||||
count_add += 1
|
||||
message_add += (
|
||||
f'- {info.get("name", "unknown")} ({did}, '
|
||||
f'{info.get("model", "unknown")})\n')
|
||||
# Get unavailable and offline devices
|
||||
home_name_del: Optional[str] = None
|
||||
home_name_offline: Optional[str] = None
|
||||
@ -1685,7 +1755,7 @@ class MIoTClient:
|
||||
if online:
|
||||
# Skip online device
|
||||
continue
|
||||
if online is None:
|
||||
if 'del' in self._display_devs_notify and online is None:
|
||||
# Device not exist
|
||||
if home_name_del != home_name_new:
|
||||
message_del += f'\n[{home_name_new}]\n'
|
||||
@ -1694,7 +1764,8 @@ class MIoTClient:
|
||||
message_del += (
|
||||
f'- {info.get("name", "unknown")} ({did}, '
|
||||
f'{info.get("room_name", "unknown")})\n')
|
||||
else:
|
||||
continue
|
||||
if 'offline' in self._display_devs_notify:
|
||||
# Device offline
|
||||
if home_name_offline != home_name_new:
|
||||
message_offline += f'\n[{home_name_new}]\n'
|
||||
@ -1705,19 +1776,19 @@ class MIoTClient:
|
||||
f'{info.get("room_name", "unknown")})\n')
|
||||
|
||||
message = ''
|
||||
if count_add:
|
||||
if 'add' in self._display_devs_notify and count_add:
|
||||
message += self._i18n.translate(
|
||||
key='miot.client.device_list_add',
|
||||
replace={
|
||||
'count': count_add,
|
||||
'message': message_add})
|
||||
if count_del:
|
||||
if 'del' in self._display_devs_notify and count_del:
|
||||
message += self._i18n.translate(
|
||||
key='miot.client.device_list_del',
|
||||
replace={
|
||||
'count': count_del,
|
||||
'message': message_del})
|
||||
if count_offline:
|
||||
if 'offline' in self._display_devs_notify and count_offline:
|
||||
message += self._i18n.translate(
|
||||
key='miot.client.device_list_offline',
|
||||
replace={
|
||||
@ -1752,6 +1823,8 @@ class MIoTClient:
|
||||
def __request_show_devices_changed_notify(
|
||||
self, delay_sec: float = 6
|
||||
) -> None:
|
||||
if not self._display_devs_notify:
|
||||
return
|
||||
if not self._mips_cloud and not self._mips_local and not self._miot_lan:
|
||||
return
|
||||
if self._show_devices_changed_notify_timer:
|
||||
@ -1760,7 +1833,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
|
||||
@ -1778,15 +1851,6 @@ async def get_miot_instance_async(
|
||||
loop: asyncio.AbstractEventLoop = asyncio.get_running_loop()
|
||||
if loop is None:
|
||||
raise MIoTClientError('loop is None')
|
||||
# MIoT network
|
||||
network: Optional[MIoTNetwork] = hass.data[DOMAIN].get(
|
||||
'miot_network', None)
|
||||
if not network:
|
||||
network = MIoTNetwork(loop=loop)
|
||||
hass.data[DOMAIN]['miot_network'] = network
|
||||
await network.init_async(
|
||||
refresh_interval=NETWORK_REFRESH_INTERVAL)
|
||||
_LOGGER.info('create miot_network instance')
|
||||
# MIoT storage
|
||||
storage: Optional[MIoTStorage] = hass.data[DOMAIN].get(
|
||||
'miot_storage', None)
|
||||
@ -1795,12 +1859,29 @@ async def get_miot_instance_async(
|
||||
root_path=entry_data['storage_path'], loop=loop)
|
||||
hass.data[DOMAIN]['miot_storage'] = storage
|
||||
_LOGGER.info('create miot_storage instance')
|
||||
global_config: dict = await storage.load_user_config_async(
|
||||
uid='global_config', cloud_server='all',
|
||||
keys=['network_detect_addr', 'net_interfaces', 'enable_subscribe'])
|
||||
# MIoT network
|
||||
network_detect_addr: dict = global_config.get(
|
||||
'network_detect_addr', {})
|
||||
network: Optional[MIoTNetwork] = hass.data[DOMAIN].get(
|
||||
'miot_network', None)
|
||||
if not network:
|
||||
network = MIoTNetwork(
|
||||
ip_addr_list=network_detect_addr.get('ip', []),
|
||||
url_addr_list=network_detect_addr.get('url', []),
|
||||
refresh_interval=NETWORK_REFRESH_INTERVAL,
|
||||
loop=loop)
|
||||
hass.data[DOMAIN]['miot_network'] = network
|
||||
await network.init_async()
|
||||
_LOGGER.info('create miot_network instance')
|
||||
# MIoT service
|
||||
mips_service: Optional[MipsService] = hass.data[DOMAIN].get(
|
||||
'mips_service', None)
|
||||
if not mips_service:
|
||||
aiozc = await zeroconf.async_get_async_instance(hass)
|
||||
mips_service: MipsService = MipsService(aiozc=aiozc, loop=loop)
|
||||
mips_service = MipsService(aiozc=aiozc, loop=loop)
|
||||
hass.data[DOMAIN]['mips_service'] = mips_service
|
||||
await mips_service.init_async()
|
||||
_LOGGER.info('create mips_service instance')
|
||||
@ -1808,15 +1889,11 @@ async def get_miot_instance_async(
|
||||
miot_lan: Optional[MIoTLan] = hass.data[DOMAIN].get(
|
||||
'miot_lan', None)
|
||||
if not miot_lan:
|
||||
lan_config = (await storage.load_user_config_async(
|
||||
uid='global_config',
|
||||
cloud_server='all',
|
||||
keys=['net_interfaces', 'enable_subscribe'])) or {}
|
||||
miot_lan = MIoTLan(
|
||||
net_ifs=lan_config.get('net_interfaces', []),
|
||||
net_ifs=global_config.get('net_interfaces', []),
|
||||
network=network,
|
||||
mips_service=mips_service,
|
||||
enable_subscribe=lan_config.get('enable_subscribe', False),
|
||||
enable_subscribe=global_config.get('enable_subscribe', False),
|
||||
loop=loop)
|
||||
hass.data[DOMAIN]['miot_lan'] = miot_lan
|
||||
_LOGGER.info('create miot_lan instance')
|
||||
|
@ -51,10 +51,9 @@ import json
|
||||
import logging
|
||||
import re
|
||||
import time
|
||||
from functools import partial
|
||||
from typing import Optional
|
||||
from typing import Any, Optional
|
||||
from urllib.parse import urlencode
|
||||
import requests
|
||||
import aiohttp
|
||||
|
||||
# pylint: disable=relative-beyond-top-level
|
||||
from .common import calc_group_id
|
||||
@ -71,8 +70,9 @@ TOKEN_EXPIRES_TS_RATIO = 0.7
|
||||
|
||||
class MIoTOauthClient:
|
||||
"""oauth agent url, default: product env."""
|
||||
_main_loop: asyncio.AbstractEventLoop = None
|
||||
_oauth_host: str = None
|
||||
_main_loop: asyncio.AbstractEventLoop
|
||||
_session: aiohttp.ClientSession
|
||||
_oauth_host: str
|
||||
_client_id: int
|
||||
_redirect_url: str
|
||||
|
||||
@ -94,9 +94,11 @@ class MIoTOauthClient:
|
||||
self._oauth_host = DEFAULT_OAUTH2_API_HOST
|
||||
else:
|
||||
self._oauth_host = f'{cloud_server}.{DEFAULT_OAUTH2_API_HOST}'
|
||||
self._session = aiohttp.ClientSession(loop=self._main_loop)
|
||||
|
||||
async def __call_async(self, func):
|
||||
return await self._main_loop.run_in_executor(executor=None, func=func)
|
||||
async def deinit_async(self) -> None:
|
||||
if self._session and not self._session.closed:
|
||||
await self._session.close()
|
||||
|
||||
def set_redirect_url(self, redirect_url: str) -> None:
|
||||
if not isinstance(redirect_url, str) or redirect_url.strip() == '':
|
||||
@ -140,21 +142,22 @@ class MIoTOauthClient:
|
||||
|
||||
return f'{OAUTH2_AUTH_URL}?{encoded_params}'
|
||||
|
||||
def _get_token(self, data) -> dict:
|
||||
http_res = requests.get(
|
||||
async def __get_token_async(self, data) -> dict:
|
||||
http_res = await self._session.get(
|
||||
url=f'https://{self._oauth_host}/app/v2/ha/oauth/get_token',
|
||||
params={'data': json.dumps(data)},
|
||||
headers={'content-type': 'application/x-www-form-urlencoded'},
|
||||
timeout=MIHOME_HTTP_API_TIMEOUT
|
||||
)
|
||||
if http_res.status_code == 401:
|
||||
if http_res.status == 401:
|
||||
raise MIoTOauthError(
|
||||
'unauthorized(401)', MIoTErrorCode.CODE_OAUTH_UNAUTHORIZED)
|
||||
if http_res.status_code != 200:
|
||||
if http_res.status != 200:
|
||||
raise MIoTOauthError(
|
||||
f'invalid http status code, {http_res.status_code}')
|
||||
f'invalid http status code, {http_res.status}')
|
||||
|
||||
res_obj = http_res.json()
|
||||
res_str = await http_res.text()
|
||||
res_obj = json.loads(res_str)
|
||||
if (
|
||||
not res_obj
|
||||
or res_obj.get('code', None) != 0
|
||||
@ -172,7 +175,7 @@ class MIoTOauthClient:
|
||||
(res_obj['result'].get('expires_in', 0)*TOKEN_EXPIRES_TS_RATIO))
|
||||
}
|
||||
|
||||
def get_access_token(self, code: str) -> dict:
|
||||
async def get_access_token_async(self, code: str) -> dict:
|
||||
"""get access token by authorization code
|
||||
|
||||
Args:
|
||||
@ -184,16 +187,13 @@ class MIoTOauthClient:
|
||||
if not isinstance(code, str):
|
||||
raise MIoTOauthError('invalid code')
|
||||
|
||||
return self._get_token(data={
|
||||
return await self.__get_token_async(data={
|
||||
'client_id': self._client_id,
|
||||
'redirect_uri': self._redirect_url,
|
||||
'code': code,
|
||||
})
|
||||
|
||||
async def get_access_token_async(self, code: str) -> dict:
|
||||
return await self.__call_async(partial(self.get_access_token, code))
|
||||
|
||||
def refresh_access_token(self, refresh_token: str) -> dict:
|
||||
async def refresh_access_token_async(self, refresh_token: str) -> dict:
|
||||
"""get access token by refresh token.
|
||||
|
||||
Args:
|
||||
@ -205,16 +205,12 @@ class MIoTOauthClient:
|
||||
if not isinstance(refresh_token, str):
|
||||
raise MIoTOauthError('invalid refresh_token')
|
||||
|
||||
return self._get_token(data={
|
||||
return await self.__get_token_async(data={
|
||||
'client_id': self._client_id,
|
||||
'redirect_uri': self._redirect_url,
|
||||
'refresh_token': refresh_token,
|
||||
})
|
||||
|
||||
async def refresh_access_token_async(self, refresh_token: str) -> dict:
|
||||
return await self.__call_async(
|
||||
partial(self.refresh_access_token, refresh_token))
|
||||
|
||||
|
||||
class MIoTHttpClient:
|
||||
"""MIoT http client."""
|
||||
@ -222,25 +218,26 @@ class MIoTHttpClient:
|
||||
GET_PROP_AGGREGATE_INTERVAL: float = 0.2
|
||||
GET_PROP_MAX_REQ_COUNT = 150
|
||||
_main_loop: asyncio.AbstractEventLoop
|
||||
_session: aiohttp.ClientSession
|
||||
_host: str
|
||||
_base_url: str
|
||||
_client_id: str
|
||||
_access_token: str
|
||||
|
||||
_get_prop_timer: asyncio.TimerHandle
|
||||
_get_prop_list: dict[str, dict[str, asyncio.Future | str | bool]]
|
||||
_get_prop_timer: Optional[asyncio.TimerHandle]
|
||||
_get_prop_list: dict[str, dict]
|
||||
|
||||
def __init__(
|
||||
self, cloud_server: str, client_id: str, access_token: str,
|
||||
loop: Optional[asyncio.AbstractEventLoop] = None
|
||||
) -> None:
|
||||
self._main_loop = loop or asyncio.get_running_loop()
|
||||
self._host = None
|
||||
self._base_url = None
|
||||
self._client_id = None
|
||||
self._access_token = None
|
||||
self._host = DEFAULT_OAUTH2_API_HOST
|
||||
self._base_url = ''
|
||||
self._client_id = ''
|
||||
self._access_token = ''
|
||||
|
||||
self._get_prop_timer: asyncio.TimerHandle = None
|
||||
self._get_prop_timer = None
|
||||
self._get_prop_list = {}
|
||||
|
||||
if (
|
||||
@ -254,10 +251,19 @@ class MIoTHttpClient:
|
||||
cloud_server=cloud_server, client_id=client_id,
|
||||
access_token=access_token)
|
||||
|
||||
async def __call_async(self, func) -> any:
|
||||
if self._main_loop is None:
|
||||
raise MIoTHttpError('miot http, un-support async methods')
|
||||
return await self._main_loop.run_in_executor(executor=None, func=func)
|
||||
self._session = aiohttp.ClientSession(loop=self._main_loop)
|
||||
|
||||
async def deinit_async(self) -> None:
|
||||
if self._get_prop_timer:
|
||||
self._get_prop_timer.cancel()
|
||||
self._get_prop_timer = None
|
||||
for item in self._get_prop_list.values():
|
||||
fut: Optional[asyncio.Future] = item.get('fut', None)
|
||||
if fut:
|
||||
fut.cancel()
|
||||
self._get_prop_list.clear()
|
||||
if self._session and not self._session.closed:
|
||||
await self._session.close()
|
||||
|
||||
def update_http_header(
|
||||
self, cloud_server: Optional[str] = None,
|
||||
@ -265,9 +271,7 @@ class MIoTHttpClient:
|
||||
access_token: Optional[str] = None
|
||||
) -> None:
|
||||
if isinstance(cloud_server, str):
|
||||
if cloud_server == 'cn':
|
||||
self._host = DEFAULT_OAUTH2_API_HOST
|
||||
else:
|
||||
if cloud_server != 'cn':
|
||||
self._host = f'{cloud_server}.{DEFAULT_OAUTH2_API_HOST}'
|
||||
self._base_url = f'https://{self._host}'
|
||||
if isinstance(client_id, str):
|
||||
@ -276,36 +280,35 @@ class MIoTHttpClient:
|
||||
self._access_token = access_token
|
||||
|
||||
@property
|
||||
def __api_session(self) -> requests.Session:
|
||||
session = requests.Session()
|
||||
session.headers.update({
|
||||
def __api_request_headers(self) -> dict:
|
||||
return {
|
||||
'Host': self._host,
|
||||
'X-Client-BizId': 'haapi',
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': f'Bearer{self._access_token}',
|
||||
'X-Client-AppId': self._client_id,
|
||||
})
|
||||
return session
|
||||
}
|
||||
|
||||
def mihome_api_get(
|
||||
# pylint: disable=unused-private-member
|
||||
async def __mihome_api_get_async(
|
||||
self, url_path: str, params: dict,
|
||||
timeout: int = MIHOME_HTTP_API_TIMEOUT
|
||||
) -> dict:
|
||||
http_res = None
|
||||
with self.__api_session as session:
|
||||
http_res = session.get(
|
||||
url=f'{self._base_url}{url_path}',
|
||||
params=params,
|
||||
timeout=timeout)
|
||||
if http_res.status_code == 401:
|
||||
http_res = await self._session.get(
|
||||
url=f'{self._base_url}{url_path}',
|
||||
params=params,
|
||||
headers=self.__api_request_headers,
|
||||
timeout=timeout)
|
||||
if http_res.status == 401:
|
||||
raise MIoTHttpError(
|
||||
'mihome api get failed, unauthorized(401)',
|
||||
MIoTErrorCode.CODE_HTTP_INVALID_ACCESS_TOKEN)
|
||||
if http_res.status_code != 200:
|
||||
if http_res.status != 200:
|
||||
raise MIoTHttpError(
|
||||
f'mihome api get failed, {http_res.status_code}, '
|
||||
f'mihome api get failed, {http_res.status}, '
|
||||
f'{url_path}, {params}')
|
||||
res_obj: dict = http_res.json()
|
||||
res_str = await http_res.text()
|
||||
res_obj: dict = json.loads(res_str)
|
||||
if res_obj.get('code', None) != 0:
|
||||
raise MIoTHttpError(
|
||||
f'invalid response code, {res_obj.get("code",None)}, '
|
||||
@ -315,28 +318,25 @@ class MIoTHttpClient:
|
||||
self._base_url, url_path, params, res_obj)
|
||||
return res_obj
|
||||
|
||||
def mihome_api_post(
|
||||
async def __mihome_api_post_async(
|
||||
self, url_path: str, data: dict,
|
||||
timeout: int = MIHOME_HTTP_API_TIMEOUT
|
||||
) -> dict:
|
||||
encoded_data = None
|
||||
if data:
|
||||
encoded_data = json.dumps(data).encode('utf-8')
|
||||
http_res = None
|
||||
with self.__api_session as session:
|
||||
http_res = session.post(
|
||||
url=f'{self._base_url}{url_path}',
|
||||
data=encoded_data,
|
||||
timeout=timeout)
|
||||
if http_res.status_code == 401:
|
||||
http_res = await self._session.post(
|
||||
url=f'{self._base_url}{url_path}',
|
||||
json=data,
|
||||
headers=self.__api_request_headers,
|
||||
timeout=timeout)
|
||||
if http_res.status == 401:
|
||||
raise MIoTHttpError(
|
||||
'mihome api get failed, unauthorized(401)',
|
||||
MIoTErrorCode.CODE_HTTP_INVALID_ACCESS_TOKEN)
|
||||
if http_res.status_code != 200:
|
||||
if http_res.status != 200:
|
||||
raise MIoTHttpError(
|
||||
f'mihome api post failed, {http_res.status_code}, '
|
||||
f'mihome api post failed, {http_res.status}, '
|
||||
f'{url_path}, {data}')
|
||||
res_obj: dict = http_res.json()
|
||||
res_str = await http_res.text()
|
||||
res_obj: dict = json.loads(res_str)
|
||||
if res_obj.get('code', None) != 0:
|
||||
raise MIoTHttpError(
|
||||
f'invalid response code, {res_obj.get("code",None)}, '
|
||||
@ -346,16 +346,17 @@ class MIoTHttpClient:
|
||||
self._base_url, url_path, data, res_obj)
|
||||
return res_obj
|
||||
|
||||
def get_user_info(self) -> dict:
|
||||
http_res = requests.get(
|
||||
async def get_user_info_async(self) -> dict:
|
||||
http_res = await self._session.get(
|
||||
url='https://open.account.xiaomi.com/user/profile',
|
||||
params={'clientId': self._client_id,
|
||||
'token': self._access_token},
|
||||
params={
|
||||
'clientId': self._client_id, 'token': self._access_token},
|
||||
headers={'content-type': 'application/x-www-form-urlencoded'},
|
||||
timeout=MIHOME_HTTP_API_TIMEOUT
|
||||
)
|
||||
|
||||
res_obj = http_res.json()
|
||||
res_str = await http_res.text()
|
||||
res_obj = json.loads(res_str)
|
||||
if (
|
||||
not res_obj
|
||||
or res_obj.get('code', None) != 0
|
||||
@ -366,14 +367,11 @@ class MIoTHttpClient:
|
||||
|
||||
return res_obj['data']
|
||||
|
||||
async def get_user_info_async(self) -> dict:
|
||||
return await self.__call_async(partial(self.get_user_info))
|
||||
|
||||
def get_central_cert(self, csr: str) -> Optional[str]:
|
||||
async def get_central_cert_async(self, csr: str) -> Optional[str]:
|
||||
if not isinstance(csr, str):
|
||||
raise MIoTHttpError('invalid params')
|
||||
|
||||
res_obj: dict = self.mihome_api_post(
|
||||
res_obj: dict = await self.__mihome_api_post_async(
|
||||
url_path='/app/v2/ha/oauth/get_central_crt',
|
||||
data={
|
||||
'csr': str(base64.b64encode(csr.encode('utf-8')), 'utf-8')
|
||||
@ -387,11 +385,10 @@ class MIoTHttpClient:
|
||||
|
||||
return cert
|
||||
|
||||
async def get_central_cert_async(self, csr: str) -> Optional[str]:
|
||||
return await self.__call_async(partial(self.get_central_cert, csr))
|
||||
|
||||
def __get_dev_room_page(self, max_id: str = None) -> dict:
|
||||
res_obj = self.mihome_api_post(
|
||||
async def __get_dev_room_page_async(
|
||||
self, max_id: Optional[str] = None
|
||||
) -> dict:
|
||||
res_obj = await self.__mihome_api_post_async(
|
||||
url_path='/app/v2/homeroom/get_dev_room_page',
|
||||
data={
|
||||
'start_id': max_id,
|
||||
@ -419,7 +416,7 @@ class MIoTHttpClient:
|
||||
res_obj['result'].get('has_more', False)
|
||||
and isinstance(res_obj['result'].get('max_id', None), str)
|
||||
):
|
||||
next_list = self.__get_dev_room_page(
|
||||
next_list = await self.__get_dev_room_page_async(
|
||||
max_id=res_obj['result']['max_id'])
|
||||
for home_id, info in next_list.items():
|
||||
home_list.setdefault(home_id, {'dids': [], 'room_info': {}})
|
||||
@ -432,8 +429,8 @@ class MIoTHttpClient:
|
||||
|
||||
return home_list
|
||||
|
||||
def get_homeinfos(self) -> dict:
|
||||
res_obj = self.mihome_api_post(
|
||||
async def get_homeinfos_async(self) -> dict:
|
||||
res_obj = await self.__mihome_api_post_async(
|
||||
url_path='/app/v2/homeroom/gethome',
|
||||
data={
|
||||
'limit': 150,
|
||||
@ -446,7 +443,7 @@ class MIoTHttpClient:
|
||||
if 'result' not in res_obj:
|
||||
raise MIoTHttpError('invalid response result')
|
||||
|
||||
uid: str = None
|
||||
uid: Optional[str] = None
|
||||
home_infos: dict = {}
|
||||
for device_source in ['homelist', 'share_home_list']:
|
||||
home_infos.setdefault(device_source, {})
|
||||
@ -485,7 +482,7 @@ class MIoTHttpClient:
|
||||
res_obj['result'].get('has_more', False)
|
||||
and isinstance(res_obj['result'].get('max_id', None), str)
|
||||
):
|
||||
more_list = self.__get_dev_room_page(
|
||||
more_list = await self.__get_dev_room_page_async(
|
||||
max_id=res_obj['result']['max_id'])
|
||||
for home_id, info in more_list.items():
|
||||
if home_id not in home_infos['homelist']:
|
||||
@ -507,17 +504,11 @@ class MIoTHttpClient:
|
||||
'share_home_list': home_infos.get('share_home_list', [])
|
||||
}
|
||||
|
||||
async def get_homeinfos_async(self) -> dict:
|
||||
return await self.__call_async(self.get_homeinfos)
|
||||
|
||||
def get_uid(self) -> str:
|
||||
return self.get_homeinfos().get('uid', None)
|
||||
|
||||
async def get_uid_async(self) -> str:
|
||||
return (await self.get_homeinfos_async()).get('uid', None)
|
||||
|
||||
def __get_device_list_page(
|
||||
self, dids: list[str], start_did: str = None
|
||||
async def __get_device_list_page_async(
|
||||
self, dids: list[str], start_did: Optional[str] = None
|
||||
) -> dict[str, dict]:
|
||||
req_data: dict = {
|
||||
'limit': 200,
|
||||
@ -527,7 +518,7 @@ class MIoTHttpClient:
|
||||
if start_did:
|
||||
req_data['start_did'] = start_did
|
||||
device_infos: dict = {}
|
||||
res_obj = self.mihome_api_post(
|
||||
res_obj = await self.__mihome_api_post_async(
|
||||
url_path='/app/v2/home/device_list_page',
|
||||
data=req_data
|
||||
)
|
||||
@ -578,17 +569,16 @@ class MIoTHttpClient:
|
||||
|
||||
next_start_did = res_obj.get('next_start_did', None)
|
||||
if res_obj.get('has_more', False) and next_start_did:
|
||||
device_infos.update(self.__get_device_list_page(
|
||||
device_infos.update(await self.__get_device_list_page_async(
|
||||
dids=dids, start_did=next_start_did))
|
||||
|
||||
return device_infos
|
||||
|
||||
async def get_devices_with_dids_async(
|
||||
self, dids: list[str]
|
||||
) -> dict[str, dict]:
|
||||
) -> Optional[dict[str, dict]]:
|
||||
results: list[dict[str, dict]] = await asyncio.gather(
|
||||
*[self.__call_async(
|
||||
partial(self.__get_device_list_page, dids[index:index+150]))
|
||||
*[self.__get_device_list_page_async(dids=dids[index:index+150])
|
||||
for index in range(0, len(dids), 150)])
|
||||
devices = {}
|
||||
for result in results:
|
||||
@ -598,10 +588,10 @@ class MIoTHttpClient:
|
||||
return devices
|
||||
|
||||
async def get_devices_async(
|
||||
self, home_ids: list[str] = None
|
||||
self, home_ids: Optional[list[str]] = None
|
||||
) -> dict[str, dict]:
|
||||
homeinfos = await self.get_homeinfos_async()
|
||||
homes: dict[str, dict[str, any]] = {}
|
||||
homes: dict[str, dict[str, Any]] = {}
|
||||
devices: dict[str, dict] = {}
|
||||
for device_type in ['home_list', 'share_home_list']:
|
||||
homes.setdefault(device_type, {})
|
||||
@ -638,8 +628,9 @@ class MIoTHttpClient:
|
||||
'group_id': group_id
|
||||
} for did in room_info.get('dids', [])})
|
||||
dids = sorted(list(devices.keys()))
|
||||
results: dict[str, dict] = await self.get_devices_with_dids_async(
|
||||
dids=dids)
|
||||
results = await self.get_devices_with_dids_async(dids=dids)
|
||||
if results is None:
|
||||
raise MIoTHttpError('get devices failed')
|
||||
for did in dids:
|
||||
if did not in results:
|
||||
devices.pop(did, None)
|
||||
@ -665,12 +656,12 @@ class MIoTHttpClient:
|
||||
'devices': devices
|
||||
}
|
||||
|
||||
def get_props(self, params: list) -> list:
|
||||
async def get_props_async(self, params: list) -> list:
|
||||
"""
|
||||
params = [{"did": "xxxx", "siid": 2, "piid": 1},
|
||||
{"did": "xxxxxx", "siid": 2, "piid": 2}]
|
||||
"""
|
||||
res_obj = self.mihome_api_post(
|
||||
res_obj = await self.__mihome_api_post_async(
|
||||
url_path='/app/v2/miotspec/prop/get',
|
||||
data={
|
||||
'datasource': 1,
|
||||
@ -681,11 +672,8 @@ class MIoTHttpClient:
|
||||
raise MIoTHttpError('invalid response result')
|
||||
return res_obj['result']
|
||||
|
||||
async def get_props_async(self, params: list) -> list:
|
||||
return await self.__call_async(partial(self.get_props, params))
|
||||
|
||||
def get_prop(self, did: str, siid: int, piid: int) -> any:
|
||||
results = self.get_props(
|
||||
async def __get_prop_async(self, did: str, siid: int, piid: int) -> Any:
|
||||
results = await self.get_props_async(
|
||||
params=[{'did': did, 'siid': siid, 'piid': piid}])
|
||||
if not results:
|
||||
return None
|
||||
@ -711,7 +699,7 @@ class MIoTHttpClient:
|
||||
if not props_buffer:
|
||||
_LOGGER.error('get prop error, empty request list')
|
||||
return False
|
||||
results = await self.__call_async(partial(self.get_props, props_buffer))
|
||||
results = await self.get_props_async(props_buffer)
|
||||
|
||||
for result in results:
|
||||
if not all(
|
||||
@ -720,7 +708,7 @@ class MIoTHttpClient:
|
||||
key = f'{result["did"]}.{result["siid"]}.{result["piid"]}'
|
||||
prop_obj = self._get_prop_list.pop(key, None)
|
||||
if prop_obj is None:
|
||||
_LOGGER.error('get prop error, key not exists, %s', result)
|
||||
_LOGGER.info('get prop error, key not exists, %s', result)
|
||||
continue
|
||||
prop_obj['fut'].set_result(result['value'])
|
||||
props_req.remove(key)
|
||||
@ -731,7 +719,7 @@ class MIoTHttpClient:
|
||||
continue
|
||||
prop_obj['fut'].set_result(None)
|
||||
if props_req:
|
||||
_LOGGER.error(
|
||||
_LOGGER.info(
|
||||
'get prop from cloud failed, %s, %s', len(key), props_req)
|
||||
|
||||
if self._get_prop_list:
|
||||
@ -745,10 +733,9 @@ class MIoTHttpClient:
|
||||
|
||||
async def get_prop_async(
|
||||
self, did: str, siid: int, piid: int, immediately: bool = False
|
||||
) -> any:
|
||||
) -> Any:
|
||||
if immediately:
|
||||
return await self.__call_async(
|
||||
partial(self.get_prop, did, siid, piid))
|
||||
return await self.__get_prop_async(did, siid, piid)
|
||||
key: str = f'{did}.{siid}.{piid}'
|
||||
prop_obj = self._get_prop_list.get(key, None)
|
||||
if prop_obj:
|
||||
@ -766,11 +753,11 @@ class MIoTHttpClient:
|
||||
|
||||
return await fut
|
||||
|
||||
def set_prop(self, params: list) -> list:
|
||||
async def set_prop_async(self, params: list) -> list:
|
||||
"""
|
||||
params = [{"did": "xxxx", "siid": 2, "piid": 1, "value": False}]
|
||||
"""
|
||||
res_obj = self.mihome_api_post(
|
||||
res_obj = await self.__mihome_api_post_async(
|
||||
url_path='/app/v2/miotspec/prop/set',
|
||||
data={
|
||||
'params': params
|
||||
@ -782,20 +769,14 @@ class MIoTHttpClient:
|
||||
|
||||
return res_obj['result']
|
||||
|
||||
async def set_prop_async(self, params: list) -> list:
|
||||
"""
|
||||
params = [{"did": "xxxx", "siid": 2, "piid": 1, "value": False}]
|
||||
"""
|
||||
return await self.__call_async(partial(self.set_prop, params))
|
||||
|
||||
def action(
|
||||
async def action_async(
|
||||
self, did: str, siid: int, aiid: int, in_list: list[dict]
|
||||
) -> dict:
|
||||
"""
|
||||
params = {"did": "xxxx", "siid": 2, "aiid": 1, "in": []}
|
||||
"""
|
||||
# NOTICE: Non-standard action param
|
||||
res_obj = self.mihome_api_post(
|
||||
res_obj = await self.__mihome_api_post_async(
|
||||
url_path='/app/v2/miotspec/action',
|
||||
data={
|
||||
'params': {
|
||||
@ -810,9 +791,3 @@ class MIoTHttpClient:
|
||||
raise MIoTHttpError('invalid response result')
|
||||
|
||||
return res_obj['result']
|
||||
|
||||
async def action_async(
|
||||
self, did: str, siid: int, aiid: int, in_list: list[dict]
|
||||
) -> dict:
|
||||
return await self.__call_async(
|
||||
partial(self.action, did, siid, aiid, in_list))
|
||||
|
@ -47,15 +47,15 @@ MIoT device instance.
|
||||
"""
|
||||
import asyncio
|
||||
from abc import abstractmethod
|
||||
from typing import Callable, Optional
|
||||
from typing import Any, Callable, Optional
|
||||
import logging
|
||||
|
||||
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,
|
||||
@ -72,7 +72,6 @@ from homeassistant.const import (
|
||||
UnitOfPower,
|
||||
UnitOfVolume,
|
||||
UnitOfVolumeFlowRate,
|
||||
UnitOfConductivity
|
||||
)
|
||||
from homeassistant.helpers.entity import DeviceInfo
|
||||
from homeassistant.components.switch import SwitchDeviceClass
|
||||
@ -104,7 +103,7 @@ _LOGGER = logging.getLogger(__name__)
|
||||
class MIoTEntityData:
|
||||
"""MIoT Entity Data."""
|
||||
platform: str
|
||||
device_class: any
|
||||
device_class: Any
|
||||
spec: MIoTSpecInstance | MIoTSpecService
|
||||
|
||||
props: set[MIoTSpecProperty]
|
||||
@ -244,8 +243,8 @@ class MIoTDevice:
|
||||
return True
|
||||
|
||||
def sub_property(
|
||||
self, handler: Callable[[dict, any], None], siid: int = None,
|
||||
piid: int = None, handler_ctx: any = None
|
||||
self, handler: Callable[[dict, Any], None], siid: int = None,
|
||||
piid: int = None, handler_ctx: Any = None
|
||||
) -> bool:
|
||||
return self.miot_client.sub_prop(
|
||||
did=self._did, handler=handler, siid=siid, piid=piid,
|
||||
@ -255,8 +254,8 @@ class MIoTDevice:
|
||||
return self.miot_client.unsub_prop(did=self._did, siid=siid, piid=piid)
|
||||
|
||||
def sub_event(
|
||||
self, handler: Callable[[dict, any], None], siid: int = None,
|
||||
eiid: int = None, handler_ctx: any = None
|
||||
self, handler: Callable[[dict, Any], None], siid: int = None,
|
||||
eiid: int = None, handler_ctx: Any = None
|
||||
) -> bool:
|
||||
return self.miot_client.sub_event(
|
||||
did=self._did, handler=handler, siid=siid, eiid=eiid,
|
||||
@ -505,7 +504,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 +584,8 @@ class MIoTDevice:
|
||||
self.append_action(action=action)
|
||||
|
||||
def unit_convert(self, spec_unit: str) -> Optional[str]:
|
||||
return {
|
||||
"""Convert MIoT unit to Home Assistant unit."""
|
||||
unit_map = {
|
||||
'percentage': PERCENTAGE,
|
||||
'weeks': UnitOfTime.WEEKS,
|
||||
'days': UnitOfTime.DAYS,
|
||||
@ -616,11 +617,21 @@ 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)
|
||||
}
|
||||
|
||||
# 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 Exception: # pylint: disable=broad-except
|
||||
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']:
|
||||
@ -677,7 +688,7 @@ class MIoTDevice:
|
||||
return None
|
||||
|
||||
def __on_device_state_changed(
|
||||
self, did: str, state: MIoTDeviceState, ctx: any
|
||||
self, did: str, state: MIoTDeviceState, ctx: Any
|
||||
) -> None:
|
||||
self._online = state
|
||||
for key, handler in self._device_state_sub_list.items():
|
||||
@ -693,11 +704,11 @@ class MIoTServiceEntity(Entity):
|
||||
entity_data: MIoTEntityData
|
||||
|
||||
_main_loop: asyncio.AbstractEventLoop
|
||||
_prop_value_map: dict[MIoTSpecProperty, any]
|
||||
_prop_value_map: dict[MIoTSpecProperty, Any]
|
||||
|
||||
_event_occurred_handler: Callable[[MIoTSpecEvent, dict], None]
|
||||
_prop_changed_subs: dict[
|
||||
MIoTSpecProperty, Callable[[MIoTSpecProperty, any], None]]
|
||||
MIoTSpecProperty, Callable[[MIoTSpecProperty, Any], None]]
|
||||
|
||||
_pending_write_ha_state_timer: Optional[asyncio.TimerHandle]
|
||||
|
||||
@ -748,7 +759,7 @@ class MIoTServiceEntity(Entity):
|
||||
|
||||
def sub_prop_changed(
|
||||
self, prop: MIoTSpecProperty,
|
||||
handler: Callable[[MIoTSpecProperty, any], None]
|
||||
handler: Callable[[MIoTSpecProperty, Any], None]
|
||||
) -> None:
|
||||
if not prop or not handler:
|
||||
_LOGGER.error(
|
||||
@ -805,13 +816,13 @@ class MIoTServiceEntity(Entity):
|
||||
self.miot_device.unsub_event(
|
||||
siid=event.service.iid, eiid=event.iid)
|
||||
|
||||
def get_map_description(self, map_: dict[int, any], key: int) -> any:
|
||||
def get_map_description(self, map_: dict[int, Any], key: int) -> Any:
|
||||
if map_ is None:
|
||||
return None
|
||||
return map_.get(key, None)
|
||||
|
||||
def get_map_value(
|
||||
self, map_: dict[int, any], description: any
|
||||
self, map_: dict[int, Any], description: Any
|
||||
) -> Optional[int]:
|
||||
if map_ is None:
|
||||
return None
|
||||
@ -820,7 +831,7 @@ class MIoTServiceEntity(Entity):
|
||||
return key
|
||||
return None
|
||||
|
||||
def get_prop_value(self, prop: MIoTSpecProperty) -> any:
|
||||
def get_prop_value(self, prop: MIoTSpecProperty) -> Any:
|
||||
if not prop:
|
||||
_LOGGER.error(
|
||||
'get_prop_value error, property is None, %s, %s',
|
||||
@ -828,7 +839,7 @@ class MIoTServiceEntity(Entity):
|
||||
return None
|
||||
return self._prop_value_map.get(prop, None)
|
||||
|
||||
def set_prop_value(self, prop: MIoTSpecProperty, value: any) -> None:
|
||||
def set_prop_value(self, prop: MIoTSpecProperty, value: Any) -> None:
|
||||
if not prop:
|
||||
_LOGGER.error(
|
||||
'set_prop_value error, property is None, %s, %s',
|
||||
@ -837,7 +848,7 @@ class MIoTServiceEntity(Entity):
|
||||
self._prop_value_map[prop] = value
|
||||
|
||||
async def set_property_async(
|
||||
self, prop: MIoTSpecProperty, value: any, update: bool = True
|
||||
self, prop: MIoTSpecProperty, value: Any, update: bool = True
|
||||
) -> bool:
|
||||
value = prop.value_format(value)
|
||||
if not prop:
|
||||
@ -864,7 +875,7 @@ class MIoTServiceEntity(Entity):
|
||||
self.async_write_ha_state()
|
||||
return True
|
||||
|
||||
async def get_property_async(self, prop: MIoTSpecProperty) -> any:
|
||||
async def get_property_async(self, prop: MIoTSpecProperty) -> Any:
|
||||
if not prop:
|
||||
_LOGGER.error(
|
||||
'get property failed, property is None, %s, %s',
|
||||
@ -903,7 +914,7 @@ class MIoTServiceEntity(Entity):
|
||||
f'{e}, {self.entity_id}, {self.name}, {action.name}') from e
|
||||
return True
|
||||
|
||||
def __on_properties_changed(self, params: dict, ctx: any) -> None:
|
||||
def __on_properties_changed(self, params: dict, ctx: Any) -> None:
|
||||
_LOGGER.debug('properties changed, %s', params)
|
||||
for prop in self.entity_data.props:
|
||||
if (
|
||||
@ -911,7 +922,7 @@ class MIoTServiceEntity(Entity):
|
||||
or prop.service.iid != params['siid']
|
||||
):
|
||||
continue
|
||||
value: any = prop.value_format(params['value'])
|
||||
value: Any = prop.value_format(params['value'])
|
||||
self._prop_value_map[prop] = value
|
||||
if prop in self._prop_changed_subs:
|
||||
self._prop_changed_subs[prop](prop, value)
|
||||
@ -919,7 +930,7 @@ class MIoTServiceEntity(Entity):
|
||||
if not self._pending_write_ha_state_timer:
|
||||
self.async_write_ha_state()
|
||||
|
||||
def __on_event_occurred(self, params: dict, ctx: any) -> None:
|
||||
def __on_event_occurred(self, params: dict, ctx: Any) -> None:
|
||||
_LOGGER.debug('event occurred, %s', params)
|
||||
if self._event_occurred_handler is None:
|
||||
return
|
||||
@ -977,9 +988,9 @@ class MIoTPropertyEntity(Entity):
|
||||
_main_loop: asyncio.AbstractEventLoop
|
||||
# {'min':int, 'max':int, 'step': int}
|
||||
_value_range: dict[str, int]
|
||||
# {any: any}
|
||||
_value_list: dict[any, any]
|
||||
_value: any
|
||||
# {Any: Any}
|
||||
_value_list: dict[Any, Any]
|
||||
_value: Any
|
||||
|
||||
_pending_write_ha_state_timer: Optional[asyncio.TimerHandle]
|
||||
|
||||
@ -1043,12 +1054,12 @@ class MIoTPropertyEntity(Entity):
|
||||
self.miot_device.unsub_property(
|
||||
siid=self.service.iid, piid=self.spec.iid)
|
||||
|
||||
def get_vlist_description(self, value: any) -> str:
|
||||
def get_vlist_description(self, value: Any) -> str:
|
||||
if not self._value_list:
|
||||
return None
|
||||
return self._value_list.get(value, None)
|
||||
|
||||
def get_vlist_value(self, description: str) -> any:
|
||||
def get_vlist_value(self, description: str) -> Any:
|
||||
if not self._value_list:
|
||||
return None
|
||||
for key, value in self._value_list.items():
|
||||
@ -1056,7 +1067,7 @@ class MIoTPropertyEntity(Entity):
|
||||
return key
|
||||
return None
|
||||
|
||||
async def set_property_async(self, value: any) -> bool:
|
||||
async def set_property_async(self, value: Any) -> bool:
|
||||
if not self.spec.writable:
|
||||
raise RuntimeError(
|
||||
f'set property failed, not writable, '
|
||||
@ -1073,7 +1084,7 @@ class MIoTPropertyEntity(Entity):
|
||||
self.async_write_ha_state()
|
||||
return True
|
||||
|
||||
async def get_property_async(self) -> any:
|
||||
async def get_property_async(self) -> Any:
|
||||
if not self.spec.readable:
|
||||
_LOGGER.error(
|
||||
'get property failed, not readable, %s, %s',
|
||||
@ -1084,7 +1095,7 @@ class MIoTPropertyEntity(Entity):
|
||||
did=self.miot_device.did, siid=self.spec.service.iid,
|
||||
piid=self.spec.iid))
|
||||
|
||||
def __on_value_changed(self, params: dict, ctx: any) -> None:
|
||||
def __on_value_changed(self, params: dict, ctx: Any) -> None:
|
||||
_LOGGER.debug('property changed, %s', params)
|
||||
self._value = self.spec.value_format(params['value'])
|
||||
if not self._pending_write_ha_state_timer:
|
||||
@ -1124,7 +1135,7 @@ class MIoTEventEntity(Entity):
|
||||
service: MIoTSpecService
|
||||
|
||||
_main_loop: asyncio.AbstractEventLoop
|
||||
_value: any
|
||||
_value: Any
|
||||
_attr_event_types: list[str]
|
||||
_arguments_map: dict[int, str]
|
||||
|
||||
@ -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(
|
||||
@ -1181,14 +1192,14 @@ class MIoTEventEntity(Entity):
|
||||
|
||||
@abstractmethod
|
||||
def on_event_occurred(
|
||||
self, name: str, arguments: list[dict[int, any]]
|
||||
self, name: str, arguments: list[dict[int, Any]]
|
||||
): ...
|
||||
|
||||
def __on_event_occurred(self, params: dict, ctx: any) -> None:
|
||||
def __on_event_occurred(self, params: dict, ctx: Any) -> None:
|
||||
_LOGGER.debug('event occurred, %s', params)
|
||||
trans_arg = {}
|
||||
try:
|
||||
for item in params['arguments']:
|
||||
for item in params['arguments']:
|
||||
try:
|
||||
if 'value' not in item:
|
||||
continue
|
||||
if 'piid' in item:
|
||||
@ -1204,10 +1215,10 @@ class MIoTEventEntity(Entity):
|
||||
for index, prop in enumerate(self.spec.argument)
|
||||
}
|
||||
break
|
||||
except KeyError as error:
|
||||
_LOGGER.error(
|
||||
'on event msg, invalid args, %s, %s, %s',
|
||||
self.entity_id, params, error)
|
||||
except KeyError as error:
|
||||
_LOGGER.debug(
|
||||
'on event msg, invalid args, %s, %s, %s',
|
||||
self.entity_id, params, error)
|
||||
self.on_event_occurred(
|
||||
name=self.spec.description_trans, arguments=trans_arg)
|
||||
self.async_write_ha_state()
|
||||
|
@ -46,6 +46,7 @@ off Xiaomi or its affiliates' products.
|
||||
MIoT error code and exception.
|
||||
"""
|
||||
from enum import Enum
|
||||
from typing import Any
|
||||
|
||||
|
||||
class MIoTErrorCode(Enum):
|
||||
@ -73,15 +74,16 @@ class MIoTErrorCode(Enum):
|
||||
# Config flow error code, -10100
|
||||
# Options flow error code , -10110
|
||||
# MIoT lan error code, -10120
|
||||
CODE_LAN_UNAVAILABLE = -10120
|
||||
|
||||
|
||||
class MIoTError(Exception):
|
||||
"""MIoT error."""
|
||||
code: MIoTErrorCode
|
||||
message: any
|
||||
message: Any
|
||||
|
||||
def __init__(
|
||||
self, message: any, code: MIoTErrorCode = MIoTErrorCode.CODE_UNKNOWN
|
||||
self, message: Any, code: MIoTErrorCode = MIoTErrorCode.CODE_UNKNOWN
|
||||
) -> None:
|
||||
self.message = message
|
||||
self.code = code
|
||||
@ -140,3 +142,7 @@ class MIoTConfigError(MIoTError):
|
||||
|
||||
class MIoTOptionsError(MIoTError):
|
||||
...
|
||||
|
||||
|
||||
class MIoTLanError(MIoTError):
|
||||
...
|
||||
|
@ -49,7 +49,7 @@ import selectors
|
||||
import heapq
|
||||
import time
|
||||
import traceback
|
||||
from typing import Callable, TypeVar
|
||||
from typing import Any, Callable, TypeVar
|
||||
import logging
|
||||
import threading
|
||||
|
||||
@ -64,17 +64,17 @@ TimeoutHandle = TypeVar('TimeoutHandle')
|
||||
class MIoTFdHandler:
|
||||
"""File descriptor handler."""
|
||||
fd: int
|
||||
read_handler: Callable[[any], None]
|
||||
read_handler_ctx: any
|
||||
write_handler: Callable[[any], None]
|
||||
write_handler_ctx: any
|
||||
read_handler: Callable[[Any], None]
|
||||
read_handler_ctx: Any
|
||||
write_handler: Callable[[Any], None]
|
||||
write_handler_ctx: Any
|
||||
|
||||
def __init__(
|
||||
self, fd: int,
|
||||
read_handler: Callable[[any], None] = None,
|
||||
read_handler_ctx: any = None,
|
||||
write_handler: Callable[[any], None] = None,
|
||||
write_handler_ctx: any = None
|
||||
read_handler: Callable[[Any], None] = None,
|
||||
read_handler_ctx: Any = None,
|
||||
write_handler: Callable[[Any], None] = None,
|
||||
write_handler_ctx: Any = None
|
||||
) -> None:
|
||||
self.fd = fd
|
||||
self.read_handler = read_handler
|
||||
@ -87,13 +87,13 @@ class MIoTTimeout:
|
||||
"""Timeout handler."""
|
||||
key: TimeoutHandle
|
||||
target: int
|
||||
handler: Callable[[any], None]
|
||||
handler_ctx: any
|
||||
handler: Callable[[Any], None]
|
||||
handler_ctx: Any
|
||||
|
||||
def __init__(
|
||||
self, key: str = None, target: int = None,
|
||||
handler: Callable[[any], None] = None,
|
||||
handler_ctx: any = None
|
||||
handler: Callable[[Any], None] = None,
|
||||
handler_ctx: Any = None
|
||||
) -> None:
|
||||
self.key = key
|
||||
self.target = target
|
||||
@ -185,8 +185,8 @@ class MIoTEventLoop:
|
||||
self._timer_handlers = {}
|
||||
|
||||
def set_timeout(
|
||||
self, timeout_ms: int, handler: Callable[[any], None],
|
||||
handler_ctx: any = None
|
||||
self, timeout_ms: int, handler: Callable[[Any], None],
|
||||
handler_ctx: Any = None
|
||||
) -> TimeoutHandle:
|
||||
"""Set a timer."""
|
||||
if timeout_ms is None or handler is None:
|
||||
@ -211,7 +211,7 @@ class MIoTEventLoop:
|
||||
heapq.heapify(self._timer_heap)
|
||||
|
||||
def set_read_handler(
|
||||
self, fd: int, handler: Callable[[any], None], handler_ctx: any = None
|
||||
self, fd: int, handler: Callable[[Any], None], handler_ctx: Any = None
|
||||
) -> bool:
|
||||
"""Set a read handler for a file descriptor.
|
||||
|
||||
@ -222,7 +222,7 @@ class MIoTEventLoop:
|
||||
fd, is_read=True, handler=handler, handler_ctx=handler_ctx)
|
||||
|
||||
def set_write_handler(
|
||||
self, fd: int, handler: Callable[[any], None], handler_ctx: any = None
|
||||
self, fd: int, handler: Callable[[Any], None], handler_ctx: Any = None
|
||||
) -> bool:
|
||||
"""Set a write handler for a file descriptor.
|
||||
|
||||
@ -233,8 +233,8 @@ class MIoTEventLoop:
|
||||
fd, is_read=False, handler=handler, handler_ctx=handler_ctx)
|
||||
|
||||
def __set_handler(
|
||||
self, fd, is_read: bool, handler: Callable[[any], None],
|
||||
handler_ctx: any = None
|
||||
self, fd, is_read: bool, handler: Callable[[Any], None],
|
||||
handler_ctx: Any = None
|
||||
) -> bool:
|
||||
"""Set a handler."""
|
||||
if fd is None:
|
||||
|
@ -71,7 +71,7 @@ class MIoTI18n:
|
||||
) -> None:
|
||||
self._main_loop = loop or asyncio.get_event_loop()
|
||||
self._lang = lang
|
||||
self._data = None
|
||||
self._data = {}
|
||||
|
||||
async def init_async(self) -> None:
|
||||
if self._data:
|
||||
@ -94,7 +94,7 @@ class MIoTI18n:
|
||||
self._data = data
|
||||
|
||||
async def deinit_async(self) -> None:
|
||||
self._data = None
|
||||
self._data = {}
|
||||
|
||||
def translate(
|
||||
self, key: str, replace: Optional[dict[str, str]] = None
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -50,7 +50,7 @@ import base64
|
||||
import binascii
|
||||
import copy
|
||||
from enum import Enum
|
||||
from typing import Callable, Optional
|
||||
from typing import Callable, Coroutine, Optional
|
||||
import logging
|
||||
|
||||
from zeroconf import (
|
||||
@ -98,8 +98,8 @@ class MipsServiceData:
|
||||
def __init__(self, service_info: AsyncServiceInfo) -> None:
|
||||
if service_info is None:
|
||||
raise MipsServiceError('invalid params')
|
||||
properties = service_info.decoded_properties
|
||||
if properties is None:
|
||||
properties: dict = service_info.decoded_properties
|
||||
if not properties:
|
||||
raise MipsServiceError('invalid service properties')
|
||||
self.profile = properties.get('profile', None)
|
||||
if self.profile is None:
|
||||
@ -111,9 +111,11 @@ class MipsServiceData:
|
||||
if not self.addresses:
|
||||
raise MipsServiceError('invalid addresses')
|
||||
self.addresses.sort()
|
||||
if not service_info.port:
|
||||
raise MipsServiceError('invalid port')
|
||||
self.port = service_info.port
|
||||
self.type = service_info.type
|
||||
self.server = service_info.server
|
||||
self.server = service_info.server or ''
|
||||
# Parse profile
|
||||
self.did = str(int.from_bytes(self.profile_bin[1:9]))
|
||||
self.group_id = binascii.hexlify(
|
||||
@ -150,8 +152,8 @@ class MipsService:
|
||||
_aio_browser: AsyncServiceBrowser
|
||||
_services: dict[str, dict]
|
||||
# key = (key, group_id)
|
||||
_sub_list: dict[(str, str), Callable[[
|
||||
str, MipsServiceState, dict], asyncio.Future]]
|
||||
_sub_list: dict[tuple[str, str], Callable[[
|
||||
str, MipsServiceState, dict], Coroutine]]
|
||||
|
||||
def __init__(
|
||||
self, aiozc: AsyncZeroconf,
|
||||
@ -159,7 +161,6 @@ class MipsService:
|
||||
) -> None:
|
||||
self._aiozc = aiozc
|
||||
self._main_loop = loop or asyncio.get_running_loop()
|
||||
self._aio_browser = None
|
||||
|
||||
self._services = {}
|
||||
self._sub_list = {}
|
||||
@ -207,7 +208,7 @@ class MipsService:
|
||||
|
||||
def sub_service_change(
|
||||
self, key: str, group_id: str,
|
||||
handler: Callable[[str, MipsServiceState, dict], asyncio.Future]
|
||||
handler: Callable[[str, MipsServiceState, dict], Coroutine]
|
||||
) -> None:
|
||||
if key is None or group_id is None or handler is None:
|
||||
raise MipsServiceError('invalid params')
|
||||
@ -232,7 +233,7 @@ class MipsService:
|
||||
for item in list(self._services.values()):
|
||||
if item['name'] != name:
|
||||
continue
|
||||
service_data = self._services.pop(item['group_id'], None)
|
||||
service_data = self._services.pop(item['group_id'], {})
|
||||
self.__call_service_change(
|
||||
state=MipsServiceState.REMOVED, data=service_data)
|
||||
return
|
||||
@ -275,10 +276,10 @@ class MipsService:
|
||||
_LOGGER.error('invalid mips service, %s, %s', error, info)
|
||||
|
||||
def __call_service_change(
|
||||
self, state: MipsServiceState, data: dict = None
|
||||
self, state: MipsServiceState, data: dict
|
||||
) -> None:
|
||||
_LOGGER.info('call service change, %s, %s', state, data)
|
||||
for keys in list(self._sub_list.keys()):
|
||||
if keys[1] in [data['group_id'], '*']:
|
||||
if keys[1] in [data.get('group_id', None), '*']:
|
||||
self._main_loop.create_task(
|
||||
self._sub_list[keys](data['group_id'], state, data))
|
||||
|
@ -58,7 +58,7 @@ import threading
|
||||
from abc import ABC, abstractmethod
|
||||
from dataclasses import dataclass
|
||||
from enum import Enum, auto
|
||||
from typing import Callable, Optional, final
|
||||
from typing import Any, Callable, Optional, final
|
||||
|
||||
from paho.mqtt.client import (
|
||||
MQTT_ERR_SUCCESS,
|
||||
@ -173,9 +173,9 @@ class MipsCmdType(Enum):
|
||||
class MipsCmd:
|
||||
"""MIoT Pub/Sub command."""
|
||||
type_: MipsCmdType
|
||||
data: any
|
||||
data: Any
|
||||
|
||||
def __init__(self, type_: MipsCmdType, data: any) -> None:
|
||||
def __init__(self, type_: MipsCmdType, data: Any) -> None:
|
||||
self.type_ = type_
|
||||
self.data = data
|
||||
|
||||
@ -184,8 +184,8 @@ class MipsCmd:
|
||||
class MipsRequest:
|
||||
"""MIoT Pub/Sub request."""
|
||||
mid: int = None
|
||||
on_reply: Callable[[str, any], None] = None
|
||||
on_reply_ctx: any = None
|
||||
on_reply: Callable[[str, Any], None] = None
|
||||
on_reply_ctx: Any = None
|
||||
timer: TimeoutHandle = None
|
||||
|
||||
|
||||
@ -194,8 +194,8 @@ class MipsRequestData:
|
||||
"""MIoT Pub/Sub request data."""
|
||||
topic: str = None
|
||||
payload: str = None
|
||||
on_reply: Callable[[str, any], None] = None
|
||||
on_reply_ctx: any = None
|
||||
on_reply: Callable[[str, Any], None] = None
|
||||
on_reply_ctx: Any = None
|
||||
timeout_ms: int = None
|
||||
|
||||
|
||||
@ -223,8 +223,8 @@ class MipsApi:
|
||||
param2: payload
|
||||
param3: handler_ctx
|
||||
"""
|
||||
handler: Callable[[MipsIncomingApiCall, str, any], None] = None
|
||||
handler_ctx: any = None
|
||||
handler: Callable[[MipsIncomingApiCall, str, Any], None] = None
|
||||
handler_ctx: Any = None
|
||||
|
||||
|
||||
class MipsRegApi(MipsApi):
|
||||
@ -247,8 +247,8 @@ class MipsBroadcast:
|
||||
param 2: msg payload
|
||||
param 3: handle_ctx
|
||||
"""
|
||||
handler: Callable[[str, str, any], None] = None
|
||||
handler_ctx: any = None
|
||||
handler: Callable[[str, str, Any], None] = None
|
||||
handler_ctx: Any = None
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f'{self.topic}, {id(self.handler)}, {id(self.handler_ctx)}'
|
||||
@ -265,7 +265,6 @@ class MipsState:
|
||||
"""
|
||||
str: key
|
||||
bool: mips connect state
|
||||
any: ctx
|
||||
"""
|
||||
handler: Callable[[str, bool], asyncio.Future] = None
|
||||
|
||||
@ -288,10 +287,10 @@ class MipsDeviceState:
|
||||
"""handler
|
||||
str: did
|
||||
MIoTDeviceState: online/offline/disable
|
||||
any: ctx
|
||||
Any: ctx
|
||||
"""
|
||||
handler: Callable[[str, MIoTDeviceState, any], None] = None
|
||||
handler_ctx: any = None
|
||||
handler: Callable[[str, MIoTDeviceState, Any], None] = None
|
||||
handler_ctx: Any = None
|
||||
|
||||
|
||||
class MipsRegDeviceState(MipsDeviceState):
|
||||
@ -512,8 +511,8 @@ class MipsClient(ABC):
|
||||
|
||||
@final
|
||||
def mev_set_timeout(
|
||||
self, timeout_ms: int, handler: Callable[[any], None],
|
||||
handler_ctx: any = None
|
||||
self, timeout_ms: int, handler: Callable[[Any], None],
|
||||
handler_ctx: Any = None
|
||||
) -> Optional[TimeoutHandle]:
|
||||
"""set timeout.
|
||||
NOTICE: Internal function, only mips threads are allowed to call
|
||||
@ -534,7 +533,7 @@ class MipsClient(ABC):
|
||||
|
||||
@final
|
||||
def mev_set_read_handler(
|
||||
self, fd: int, handler: Callable[[any], None], handler_ctx: any
|
||||
self, fd: int, handler: Callable[[Any], None], handler_ctx: Any
|
||||
) -> bool:
|
||||
"""set read handler.
|
||||
NOTICE: Internal function, only mips threads are allowed to call
|
||||
@ -546,7 +545,7 @@ class MipsClient(ABC):
|
||||
|
||||
@final
|
||||
def mev_set_write_handler(
|
||||
self, fd: int, handler: Callable[[any], None], handler_ctx: any
|
||||
self, fd: int, handler: Callable[[Any], None], handler_ctx: Any
|
||||
) -> bool:
|
||||
"""set write handler.
|
||||
NOTICE: Internal function, only mips threads are allowed to call
|
||||
@ -604,8 +603,8 @@ class MipsClient(ABC):
|
||||
|
||||
@abstractmethod
|
||||
def sub_prop(
|
||||
self, did: str, handler: Callable[[dict, any], None],
|
||||
siid: int = None, piid: int = None, handler_ctx: any = None
|
||||
self, did: str, handler: Callable[[dict, Any], None],
|
||||
siid: int = None, piid: int = None, handler_ctx: Any = None
|
||||
) -> bool: ...
|
||||
|
||||
@abstractmethod
|
||||
@ -615,8 +614,8 @@ class MipsClient(ABC):
|
||||
|
||||
@abstractmethod
|
||||
def sub_event(
|
||||
self, did: str, handler: Callable[[dict, any], None],
|
||||
siid: int = None, eiid: int = None, handler_ctx: any = None
|
||||
self, did: str, handler: Callable[[dict, Any], None],
|
||||
siid: int = None, eiid: int = None, handler_ctx: Any = None
|
||||
) -> bool: ...
|
||||
|
||||
@abstractmethod
|
||||
@ -632,11 +631,11 @@ class MipsClient(ABC):
|
||||
@abstractmethod
|
||||
async def get_prop_async(
|
||||
self, did: str, siid: int, piid: int, timeout_ms: int = 10000
|
||||
) -> any: ...
|
||||
) -> Any: ...
|
||||
|
||||
@abstractmethod
|
||||
async def set_prop_async(
|
||||
self, did: str, siid: int, piid: int, value: any,
|
||||
self, did: str, siid: int, piid: int, value: Any,
|
||||
timeout_ms: int = 10000
|
||||
) -> bool: ...
|
||||
|
||||
@ -709,7 +708,7 @@ class MipsClient(ABC):
|
||||
return False
|
||||
|
||||
@final
|
||||
def _mips_send_cmd(self, type_: MipsCmdType, data: any) -> bool:
|
||||
def _mips_send_cmd(self, type_: MipsCmdType, data: Any) -> bool:
|
||||
if self._mips_queue is None or self._cmd_event_fd is None:
|
||||
raise MIoTMipsError('send mips cmd disable')
|
||||
# Put data to queue
|
||||
@ -723,7 +722,7 @@ class MipsClient(ABC):
|
||||
if threading.current_thread() is not self._mips_thread:
|
||||
raise MIoTMipsError('illegal call')
|
||||
|
||||
def __mips_cmd_read_handler(self, ctx: any) -> None:
|
||||
def __mips_cmd_read_handler(self, ctx: Any) -> None:
|
||||
fd_value = os.eventfd_read(self._cmd_event_fd)
|
||||
if fd_value == 0:
|
||||
return
|
||||
@ -763,20 +762,20 @@ class MipsClient(ABC):
|
||||
if self._on_mips_cmd:
|
||||
self._on_mips_cmd(mips_cmd=mips_cmd)
|
||||
|
||||
def __mqtt_read_handler(self, ctx: any) -> None:
|
||||
def __mqtt_read_handler(self, ctx: Any) -> None:
|
||||
self.__mqtt_loop_handler(ctx=ctx)
|
||||
|
||||
def __mqtt_write_handler(self, ctx: any) -> None:
|
||||
def __mqtt_write_handler(self, ctx: Any) -> None:
|
||||
self.mev_set_write_handler(self._mqtt_fd, None, None)
|
||||
self.__mqtt_loop_handler(ctx=ctx)
|
||||
|
||||
def __mqtt_timer_handler(self, ctx: any) -> None:
|
||||
def __mqtt_timer_handler(self, ctx: Any) -> None:
|
||||
self.__mqtt_loop_handler(ctx=ctx)
|
||||
if self._mqtt:
|
||||
self._mqtt_timer = self.mev_set_timeout(
|
||||
self.MQTT_INTERVAL_MS, self.__mqtt_timer_handler, None)
|
||||
|
||||
def __mqtt_loop_handler(self, ctx: any) -> None:
|
||||
def __mqtt_loop_handler(self, ctx: Any) -> None:
|
||||
try:
|
||||
if self._mqtt:
|
||||
self._mqtt.loop_read()
|
||||
@ -896,7 +895,7 @@ class MipsClient(ABC):
|
||||
self._mips_reconnect_timer = self.mev_set_timeout(
|
||||
interval, self.__mips_connect, None)
|
||||
|
||||
def __mips_sub_internal_pending_handler(self, ctx: any) -> None:
|
||||
def __mips_sub_internal_pending_handler(self, ctx: Any) -> None:
|
||||
subbed_count = 1
|
||||
for topic in list(self._mips_sub_pending_map.keys()):
|
||||
if subbed_count > self.MIPS_SUB_PATCH:
|
||||
@ -923,7 +922,7 @@ class MipsClient(ABC):
|
||||
else:
|
||||
self._mips_sub_pending_timer = None
|
||||
|
||||
def __mips_connect(self, ctx: any = None) -> None:
|
||||
def __mips_connect(self, ctx: Any = None) -> None:
|
||||
result = MQTT_ERR_UNKNOWN
|
||||
if self._mips_reconnect_timer:
|
||||
self.mev_clear_timeout(self._mips_reconnect_timer)
|
||||
@ -1034,8 +1033,8 @@ class MipsCloudClient(MipsClient):
|
||||
|
||||
@final
|
||||
def sub_prop(
|
||||
self, did: str, handler: Callable[[dict, any], None],
|
||||
siid: int = None, piid: int = None, handler_ctx: any = None
|
||||
self, did: str, handler: Callable[[dict, Any], None],
|
||||
siid: int = None, piid: int = None, handler_ctx: Any = None
|
||||
) -> bool:
|
||||
if not isinstance(did, str) or handler is None:
|
||||
raise MIoTMipsError('invalid params')
|
||||
@ -1044,7 +1043,7 @@ class MipsCloudClient(MipsClient):
|
||||
f'device/{did}/up/properties_changed/'
|
||||
f'{"#" if siid is None or piid is None else f"{siid}/{piid}"}')
|
||||
|
||||
def on_prop_msg(topic: str, payload: str, ctx: any) -> bool:
|
||||
def on_prop_msg(topic: str, payload: str, ctx: Any) -> bool:
|
||||
try:
|
||||
msg: dict = json.loads(payload)
|
||||
except json.JSONDecodeError:
|
||||
@ -1077,8 +1076,8 @@ class MipsCloudClient(MipsClient):
|
||||
|
||||
@final
|
||||
def sub_event(
|
||||
self, did: str, handler: Callable[[dict, any], None],
|
||||
siid: int = None, eiid: int = None, handler_ctx: any = None
|
||||
self, did: str, handler: Callable[[dict, Any], None],
|
||||
siid: int = None, eiid: int = None, handler_ctx: Any = None
|
||||
) -> bool:
|
||||
if not isinstance(did, str) or handler is None:
|
||||
raise MIoTMipsError('invalid params')
|
||||
@ -1087,7 +1086,7 @@ class MipsCloudClient(MipsClient):
|
||||
f'device/{did}/up/event_occured/'
|
||||
f'{"#" if siid is None or eiid is None else f"{siid}/{eiid}"}')
|
||||
|
||||
def on_event_msg(topic: str, payload: str, ctx: any) -> bool:
|
||||
def on_event_msg(topic: str, payload: str, ctx: Any) -> bool:
|
||||
try:
|
||||
msg: dict = json.loads(payload)
|
||||
except json.JSONDecodeError:
|
||||
@ -1122,15 +1121,15 @@ class MipsCloudClient(MipsClient):
|
||||
|
||||
@final
|
||||
def sub_device_state(
|
||||
self, did: str, handler: Callable[[str, MIoTDeviceState, any], None],
|
||||
handler_ctx: any = None
|
||||
self, did: str, handler: Callable[[str, MIoTDeviceState, Any], None],
|
||||
handler_ctx: Any = None
|
||||
) -> bool:
|
||||
"""subscribe online state."""
|
||||
if not isinstance(did, str) or handler is None:
|
||||
raise MIoTMipsError('invalid params')
|
||||
topic: str = f'device/{did}/state/#'
|
||||
|
||||
def on_state_msg(topic: str, payload: str, ctx: any) -> None:
|
||||
def on_state_msg(topic: str, payload: str, ctx: Any) -> None:
|
||||
msg: dict = json.loads(payload)
|
||||
# {"device_id":"xxxx","device_name":"米家智能插座3 ","event":"online",
|
||||
# "model": "cuco.plug.v3","timestamp":1709001070828,"uid":xxxx}
|
||||
@ -1163,11 +1162,11 @@ class MipsCloudClient(MipsClient):
|
||||
|
||||
async def get_prop_async(
|
||||
self, did: str, siid: int, piid: int, timeout_ms: int = 10000
|
||||
) -> any:
|
||||
) -> Any:
|
||||
raise NotImplementedError('please call in http client')
|
||||
|
||||
async def set_prop_async(
|
||||
self, did: str, siid: int, piid: int, value: any,
|
||||
self, did: str, siid: int, piid: int, value: Any,
|
||||
timeout_ms: int = 10000
|
||||
) -> bool:
|
||||
raise NotImplementedError('please call in http client')
|
||||
@ -1199,8 +1198,8 @@ class MipsCloudClient(MipsClient):
|
||||
self._mips_unsub_internal(topic=unreg_bc.topic)
|
||||
|
||||
def __reg_broadcast(
|
||||
self, topic: str, handler: Callable[[str, str, any], None],
|
||||
handler_ctx: any = None
|
||||
self, topic: str, handler: Callable[[str, str, Any], None],
|
||||
handler_ctx: Any = None
|
||||
) -> bool:
|
||||
return self._mips_send_cmd(
|
||||
type_=MipsCmdType.REG_BROADCAST,
|
||||
@ -1259,7 +1258,7 @@ class MipsLocalClient(MipsClient):
|
||||
_device_state_sub_map: dict[str, MipsDeviceState]
|
||||
_get_prop_queue: dict[str, list]
|
||||
_get_prop_timer: asyncio.TimerHandle
|
||||
_on_dev_list_changed: Callable[[any, list[str]], asyncio.Future]
|
||||
_on_dev_list_changed: Callable[[Any, list[str]], asyncio.Future]
|
||||
|
||||
def __init__(
|
||||
self, did: str, host: str, group_id: str,
|
||||
@ -1347,14 +1346,14 @@ class MipsLocalClient(MipsClient):
|
||||
|
||||
@final
|
||||
def sub_prop(
|
||||
self, did: str, handler: Callable[[dict, any], None],
|
||||
siid: int = None, piid: int = None, handler_ctx: any = None
|
||||
self, did: str, handler: Callable[[dict, Any], None],
|
||||
siid: int = None, piid: int = None, handler_ctx: Any = None
|
||||
) -> bool:
|
||||
topic: str = (
|
||||
f'appMsg/notify/iot/{did}/property/'
|
||||
f'{"#" if siid is None or piid is None else f"{siid}.{piid}"}')
|
||||
|
||||
def on_prop_msg(topic: str, payload: str, ctx: any):
|
||||
def on_prop_msg(topic: str, payload: str, ctx: Any):
|
||||
msg: dict = json.loads(payload)
|
||||
if (
|
||||
msg is None
|
||||
@ -1380,14 +1379,14 @@ class MipsLocalClient(MipsClient):
|
||||
|
||||
@final
|
||||
def sub_event(
|
||||
self, did: str, handler: Callable[[dict, any], None],
|
||||
siid: int = None, eiid: int = None, handler_ctx: any = None
|
||||
self, did: str, handler: Callable[[dict, Any], None],
|
||||
siid: int = None, eiid: int = None, handler_ctx: Any = None
|
||||
) -> bool:
|
||||
topic: str = (
|
||||
f'appMsg/notify/iot/{did}/event/'
|
||||
f'{"#" if siid is None or eiid is None else f"{siid}.{eiid}"}')
|
||||
|
||||
def on_event_msg(topic: str, payload: str, ctx: any):
|
||||
def on_event_msg(topic: str, payload: str, ctx: Any):
|
||||
msg: dict = json.loads(payload)
|
||||
if (
|
||||
msg is None
|
||||
@ -1414,7 +1413,7 @@ class MipsLocalClient(MipsClient):
|
||||
@final
|
||||
async def get_prop_safe_async(
|
||||
self, did: str, siid: int, piid: int, timeout_ms: int = 10000
|
||||
) -> any:
|
||||
) -> Any:
|
||||
self._get_prop_queue.setdefault(did, [])
|
||||
fut: asyncio.Future = self.main_loop.create_future()
|
||||
self._get_prop_queue[did].append({
|
||||
@ -1434,7 +1433,7 @@ class MipsLocalClient(MipsClient):
|
||||
@final
|
||||
async def get_prop_async(
|
||||
self, did: str, siid: int, piid: int, timeout_ms: int = 10000
|
||||
) -> any:
|
||||
) -> Any:
|
||||
result_obj = await self.__request_async(
|
||||
topic='proxy/get',
|
||||
payload=json.dumps({
|
||||
@ -1449,7 +1448,7 @@ class MipsLocalClient(MipsClient):
|
||||
|
||||
@final
|
||||
async def set_prop_async(
|
||||
self, did: str, siid: int, piid: int, value: any,
|
||||
self, did: str, siid: int, piid: int, value: Any,
|
||||
timeout_ms: int = 10000
|
||||
) -> dict:
|
||||
payload_obj: dict = {
|
||||
@ -1580,13 +1579,13 @@ class MipsLocalClient(MipsClient):
|
||||
|
||||
@final
|
||||
@property
|
||||
def on_dev_list_changed(self) -> Callable[[any, list[str]], asyncio.Future]:
|
||||
def on_dev_list_changed(self) -> Callable[[Any, list[str]], asyncio.Future]:
|
||||
return self._on_dev_list_changed
|
||||
|
||||
@final
|
||||
@on_dev_list_changed.setter
|
||||
def on_dev_list_changed(
|
||||
self, func: Callable[[any, list[str]], asyncio.Future]
|
||||
self, func: Callable[[Any, list[str]], asyncio.Future]
|
||||
) -> None:
|
||||
"""run in main loop."""
|
||||
self._on_dev_list_changed = func
|
||||
@ -1731,8 +1730,8 @@ class MipsLocalClient(MipsClient):
|
||||
|
||||
def __request(
|
||||
self, topic: str, payload: str,
|
||||
on_reply: Callable[[str, any], None],
|
||||
on_reply_ctx: any = None, timeout_ms: int = 10000
|
||||
on_reply: Callable[[str, Any], None],
|
||||
on_reply_ctx: Any = None, timeout_ms: int = 10000
|
||||
) -> bool:
|
||||
if topic is None or payload is None or on_reply is None:
|
||||
raise MIoTMipsError('invalid params')
|
||||
@ -1745,8 +1744,8 @@ class MipsLocalClient(MipsClient):
|
||||
return self._mips_send_cmd(type_=MipsCmdType.CALL_API, data=req_data)
|
||||
|
||||
def __reg_broadcast(
|
||||
self, topic: str, handler: Callable[[str, str, any], None],
|
||||
handler_ctx: any
|
||||
self, topic: str, handler: Callable[[str, str, Any], None],
|
||||
handler_ctx: Any
|
||||
) -> bool:
|
||||
return self._mips_send_cmd(
|
||||
type_=MipsCmdType.REG_BROADCAST,
|
||||
@ -1764,7 +1763,7 @@ class MipsLocalClient(MipsClient):
|
||||
) -> dict:
|
||||
fut_handler: asyncio.Future = self.main_loop.create_future()
|
||||
|
||||
def on_msg_reply(payload: str, ctx: any):
|
||||
def on_msg_reply(payload: str, ctx: Any):
|
||||
fut: asyncio.Future = ctx
|
||||
if fut:
|
||||
self.main_loop.call_soon_threadsafe(fut.set_result, payload)
|
||||
|
@ -52,7 +52,8 @@ import socket
|
||||
from dataclasses import dataclass
|
||||
from enum import Enum, auto
|
||||
import subprocess
|
||||
from typing import Callable, Optional
|
||||
from typing import Callable, Coroutine, Optional
|
||||
import aiohttp
|
||||
import psutil
|
||||
import ipaddress
|
||||
|
||||
@ -77,38 +78,54 @@ class NetworkInfo:
|
||||
|
||||
class MIoTNetwork:
|
||||
"""MIoT network utilities."""
|
||||
PING_ADDRESS_LIST = [
|
||||
_IP_ADDRESS_LIST: list[str] = [
|
||||
'1.2.4.8', # CNNIC sDNS
|
||||
'8.8.8.8', # Google Public DNS
|
||||
'233.5.5.5', # AliDNS
|
||||
'1.1.1.1', # Cloudflare DNS
|
||||
'114.114.114.114', # 114 DNS
|
||||
'208.67.222.222', # OpenDNS
|
||||
'9.9.9.9', # Quad9 DNS
|
||||
'9.9.9.9' # Quad9
|
||||
]
|
||||
_URL_ADDRESS_LIST: list[str] = [
|
||||
'https://www.bing.com',
|
||||
'https://www.google.com',
|
||||
'https://www.baidu.com'
|
||||
]
|
||||
_REFRESH_INTERVAL = 30
|
||||
_DETECT_TIMEOUT = 6
|
||||
|
||||
_main_loop: asyncio.AbstractEventLoop
|
||||
|
||||
_ip_addr_map: dict[str, float]
|
||||
_url_addr_list: dict[str, float]
|
||||
_http_session: aiohttp.ClientSession
|
||||
|
||||
_refresh_interval: int
|
||||
_refresh_task: asyncio.Task
|
||||
_refresh_timer: asyncio.TimerHandle
|
||||
_refresh_task: Optional[asyncio.Task]
|
||||
_refresh_timer: Optional[asyncio.TimerHandle]
|
||||
|
||||
_network_status: bool
|
||||
_network_info: dict[str, NetworkInfo]
|
||||
|
||||
_sub_list_network_status: dict[str, Callable[[bool], asyncio.Future]]
|
||||
_sub_list_network_status: dict[str, Callable[[bool], Coroutine]]
|
||||
_sub_list_network_info: dict[str, Callable[[
|
||||
InterfaceStatus, NetworkInfo], asyncio.Future]]
|
||||
|
||||
_ping_address_priority: int
|
||||
|
||||
InterfaceStatus, NetworkInfo], Coroutine]]
|
||||
_done_event: asyncio.Event
|
||||
|
||||
def __init__(
|
||||
self, loop: Optional[asyncio.AbstractEventLoop] = None
|
||||
self,
|
||||
ip_addr_list: Optional[list[str]] = None,
|
||||
url_addr_list: Optional[list[str]] = None,
|
||||
refresh_interval: Optional[int] = None,
|
||||
loop: Optional[asyncio.AbstractEventLoop] = None
|
||||
) -> None:
|
||||
self._main_loop = loop or asyncio.get_running_loop()
|
||||
self._ip_addr_map = {
|
||||
ip: self._DETECT_TIMEOUT for ip in
|
||||
ip_addr_list or self._IP_ADDRESS_LIST}
|
||||
self._http_addr_map = {
|
||||
url: self._DETECT_TIMEOUT for url in
|
||||
url_addr_list or self._URL_ADDRESS_LIST}
|
||||
self._http_session = aiohttp.ClientSession()
|
||||
self._refresh_interval = refresh_interval or self._REFRESH_INTERVAL
|
||||
|
||||
self._refresh_interval = None
|
||||
self._refresh_task = None
|
||||
self._refresh_timer = None
|
||||
|
||||
@ -118,10 +135,28 @@ class MIoTNetwork:
|
||||
self._sub_list_network_status = {}
|
||||
self._sub_list_network_info = {}
|
||||
|
||||
self._ping_address_priority = 0
|
||||
|
||||
self._done_event = asyncio.Event()
|
||||
|
||||
async def init_async(self) -> bool:
|
||||
self.__refresh_timer_handler()
|
||||
# MUST get network info before starting
|
||||
return await self._done_event.wait()
|
||||
|
||||
async def deinit_async(self) -> None:
|
||||
if self._refresh_task:
|
||||
self._refresh_task.cancel()
|
||||
self._refresh_task = None
|
||||
if self._refresh_timer:
|
||||
self._refresh_timer.cancel()
|
||||
self._refresh_timer = None
|
||||
await self._http_session.close()
|
||||
|
||||
self._network_status = False
|
||||
self._network_info.clear()
|
||||
self._sub_list_network_status.clear()
|
||||
self._sub_list_network_info.clear()
|
||||
self._done_event.clear()
|
||||
|
||||
@property
|
||||
def network_status(self) -> bool:
|
||||
return self._network_status
|
||||
@ -130,23 +165,28 @@ class MIoTNetwork:
|
||||
def network_info(self) -> dict[str, NetworkInfo]:
|
||||
return self._network_info
|
||||
|
||||
async def deinit_async(self) -> None:
|
||||
if self._refresh_task:
|
||||
self._refresh_task.cancel()
|
||||
self._refresh_task = None
|
||||
if self._refresh_timer:
|
||||
self._refresh_timer.cancel()
|
||||
self._refresh_timer = None
|
||||
|
||||
self._refresh_interval = None
|
||||
self._network_status = False
|
||||
self._network_info.clear()
|
||||
self._sub_list_network_status.clear()
|
||||
self._sub_list_network_info.clear()
|
||||
self._done_event.clear()
|
||||
async def update_addr_list_async(
|
||||
self,
|
||||
ip_addr_list: Optional[list[str]] = None,
|
||||
url_addr_list: Optional[list[str]] = None,
|
||||
) -> None:
|
||||
new_ip_map: dict = {}
|
||||
for ip in ip_addr_list or self._IP_ADDRESS_LIST:
|
||||
if ip in self._ip_addr_map:
|
||||
new_ip_map[ip] = self._ip_addr_map[ip]
|
||||
else:
|
||||
new_ip_map[ip] = self._DETECT_TIMEOUT
|
||||
self._ip_addr_map = new_ip_map
|
||||
new_url_map: dict = {}
|
||||
for url in url_addr_list or self._URL_ADDRESS_LIST:
|
||||
if url in self._http_addr_map:
|
||||
new_url_map[url] = self._http_addr_map[url]
|
||||
else:
|
||||
new_url_map[url] = self._DETECT_TIMEOUT
|
||||
self._http_addr_map = new_url_map
|
||||
|
||||
def sub_network_status(
|
||||
self, key: str, handler: Callable[[bool], asyncio.Future]
|
||||
self, key: str, handler: Callable[[bool], Coroutine]
|
||||
) -> None:
|
||||
self._sub_list_network_status[key] = handler
|
||||
|
||||
@ -155,65 +195,114 @@ class MIoTNetwork:
|
||||
|
||||
def sub_network_info(
|
||||
self, key: str,
|
||||
handler: Callable[[InterfaceStatus, NetworkInfo], asyncio.Future]
|
||||
handler: Callable[[InterfaceStatus, NetworkInfo], Coroutine]
|
||||
) -> None:
|
||||
self._sub_list_network_info[key] = handler
|
||||
|
||||
def unsub_network_info(self, key: str) -> None:
|
||||
self._sub_list_network_info.pop(key, None)
|
||||
|
||||
async def init_async(self, refresh_interval: int = 30) -> bool:
|
||||
self._refresh_interval = refresh_interval
|
||||
self.__refresh_timer_handler()
|
||||
# MUST get network info before starting
|
||||
return await self._done_event.wait()
|
||||
|
||||
async def refresh_async(self) -> None:
|
||||
self.__refresh_timer_handler()
|
||||
|
||||
async def get_network_status_async(self, timeout: int = 6) -> bool:
|
||||
return await self._main_loop.run_in_executor(
|
||||
None, self.__get_network_status, False, timeout)
|
||||
async def get_network_status_async(self) -> bool:
|
||||
try:
|
||||
ip_addr: str = ''
|
||||
ip_ts: float = self._DETECT_TIMEOUT
|
||||
for ip, ts in self._ip_addr_map.items():
|
||||
if ts < ip_ts:
|
||||
ip_addr = ip
|
||||
ip_ts = ts
|
||||
if (
|
||||
ip_ts < self._DETECT_TIMEOUT
|
||||
and await self.ping_multi_async(ip_list=[ip_addr])
|
||||
):
|
||||
return True
|
||||
url_addr: str = ''
|
||||
url_ts: float = self._DETECT_TIMEOUT
|
||||
for http, ts in self._http_addr_map.items():
|
||||
if ts < url_ts:
|
||||
url_addr = http
|
||||
url_ts = ts
|
||||
if (
|
||||
url_ts < self._DETECT_TIMEOUT
|
||||
and await self.http_multi_async(url_list=[url_addr])
|
||||
):
|
||||
return True
|
||||
# Detect all addresses
|
||||
results = await asyncio.gather(
|
||||
*[self.ping_multi_async(), self.http_multi_async()])
|
||||
return any(results)
|
||||
except Exception as err: # pylint: disable=broad-exception-caught
|
||||
_LOGGER.error('get network status error, %s', err)
|
||||
return False
|
||||
|
||||
async def get_network_info_async(self) -> dict[str, NetworkInfo]:
|
||||
return await self._main_loop.run_in_executor(
|
||||
None, self.__get_network_info)
|
||||
|
||||
async def ping_multi_async(
|
||||
self, ip_list: Optional[list[str]] = None
|
||||
) -> bool:
|
||||
addr_list = ip_list or list(self._ip_addr_map.keys())
|
||||
tasks = []
|
||||
for addr in addr_list:
|
||||
tasks.append(self.__ping_async(addr))
|
||||
results = await asyncio.gather(*tasks)
|
||||
for addr, ts in zip(addr_list, results):
|
||||
if addr in self._ip_addr_map:
|
||||
self._ip_addr_map[addr] = ts
|
||||
return any([ts < self._DETECT_TIMEOUT for ts in results])
|
||||
|
||||
async def http_multi_async(
|
||||
self, url_list: Optional[list[str]] = None
|
||||
) -> bool:
|
||||
addr_list = url_list or list(self._http_addr_map.keys())
|
||||
tasks = []
|
||||
for addr in addr_list:
|
||||
tasks.append(self.__http_async(url=addr))
|
||||
results = await asyncio.gather(*tasks)
|
||||
for addr, ts in zip(addr_list, results):
|
||||
if addr in self._http_addr_map:
|
||||
self._http_addr_map[addr] = ts
|
||||
return any([ts < self._DETECT_TIMEOUT for ts in results])
|
||||
|
||||
def __calc_network_address(self, ip: str, netmask: str) -> str:
|
||||
return str(ipaddress.IPv4Network(
|
||||
f'{ip}/{netmask}', strict=False).network_address)
|
||||
|
||||
def __ping(
|
||||
self, address: Optional[str] = None, timeout: int = 6
|
||||
) -> bool:
|
||||
param = '-n' if platform.system().lower() == 'windows' else '-c'
|
||||
command = ['ping', param, '1', address]
|
||||
async def __ping_async(self, address: Optional[str] = None) -> float:
|
||||
start_ts: float = self._main_loop.time()
|
||||
try:
|
||||
output = subprocess.run(
|
||||
command, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
||||
check=True, timeout=timeout)
|
||||
return output.returncode == 0
|
||||
process = await asyncio.create_subprocess_exec(
|
||||
*(
|
||||
[
|
||||
'ping', '-n', '1', '-w',
|
||||
str(self._DETECT_TIMEOUT*1000), address]
|
||||
if platform.system().lower() == 'windows' else
|
||||
[
|
||||
'ping', '-c', '1', '-w',
|
||||
str(self._DETECT_TIMEOUT), address]),
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE
|
||||
)
|
||||
await process.communicate()
|
||||
if process.returncode == 0:
|
||||
return self._main_loop.time() - start_ts
|
||||
return self._DETECT_TIMEOUT
|
||||
except Exception as err: # pylint: disable=broad-exception-caught
|
||||
print(err)
|
||||
return self._DETECT_TIMEOUT
|
||||
|
||||
async def __http_async(self, url: str) -> float:
|
||||
start_ts: float = self._main_loop.time()
|
||||
try:
|
||||
async with self._http_session.get(
|
||||
url, timeout=self._DETECT_TIMEOUT):
|
||||
return self._main_loop.time() - start_ts
|
||||
except Exception: # pylint: disable=broad-exception-caught
|
||||
return False
|
||||
|
||||
def __get_network_status(
|
||||
self, with_retry: bool = True, timeout: int = 6
|
||||
) -> bool:
|
||||
if self._ping_address_priority >= len(self.PING_ADDRESS_LIST):
|
||||
self._ping_address_priority = 0
|
||||
|
||||
if self.__ping(
|
||||
self.PING_ADDRESS_LIST[self._ping_address_priority], timeout):
|
||||
return True
|
||||
if not with_retry:
|
||||
return False
|
||||
for index in range(len(self.PING_ADDRESS_LIST)):
|
||||
if index == self._ping_address_priority:
|
||||
continue
|
||||
if self.__ping(self.PING_ADDRESS_LIST[index], timeout):
|
||||
self._ping_address_priority = index
|
||||
return True
|
||||
return False
|
||||
pass
|
||||
return self._DETECT_TIMEOUT
|
||||
|
||||
def __get_network_info(self) -> dict[str, NetworkInfo]:
|
||||
interfaces = psutil.net_if_addrs()
|
||||
@ -246,12 +335,10 @@ class MIoTNetwork:
|
||||
for handler in self._sub_list_network_info.values():
|
||||
self._main_loop.create_task(handler(status, info))
|
||||
|
||||
async def __update_status_and_info_async(self, timeout: int = 6) -> None:
|
||||
async def __update_status_and_info_async(self) -> None:
|
||||
try:
|
||||
status: bool = await self._main_loop.run_in_executor(
|
||||
None, self.__get_network_status, timeout)
|
||||
infos = await self._main_loop.run_in_executor(
|
||||
None, self.__get_network_info)
|
||||
status: bool = await self.get_network_status_async()
|
||||
infos = await self.get_network_info_async()
|
||||
|
||||
if self._network_status != status:
|
||||
for handler in self._sub_list_network_status.values():
|
||||
@ -273,7 +360,7 @@ class MIoTNetwork:
|
||||
# Remove
|
||||
self.__call_network_info_change(
|
||||
InterfaceStatus.REMOVE,
|
||||
self._network_info.pop(name, None))
|
||||
self._network_info.pop(name))
|
||||
# Add
|
||||
for name, info in infos.items():
|
||||
self._network_info[name] = info
|
||||
|
@ -49,7 +49,7 @@ import asyncio
|
||||
import json
|
||||
import platform
|
||||
import time
|
||||
from typing import Optional
|
||||
from typing import Any, Optional
|
||||
from urllib.parse import urlencode
|
||||
from urllib.request import Request, urlopen
|
||||
import logging
|
||||
@ -78,9 +78,9 @@ class MIoTSpecBase:
|
||||
|
||||
# External params
|
||||
platform: str
|
||||
device_class: any
|
||||
device_class: Any
|
||||
icon: str
|
||||
external_unit: any
|
||||
external_unit: Any
|
||||
|
||||
spec_id: str
|
||||
|
||||
@ -166,7 +166,7 @@ class MIoTSpecProperty(MIoTSpecBase):
|
||||
def notifiable(self):
|
||||
return self._notifiable
|
||||
|
||||
def value_format(self, value: any) -> any:
|
||||
def value_format(self, value: Any) -> Any:
|
||||
if value is None:
|
||||
return None
|
||||
if self.format_ == 'int':
|
||||
@ -296,7 +296,7 @@ class MIoTSpecInstance:
|
||||
|
||||
# External params
|
||||
platform: str
|
||||
device_class: any
|
||||
device_class: Any
|
||||
icon: str
|
||||
|
||||
def __init__(
|
||||
|
@ -56,7 +56,7 @@ import hashlib
|
||||
from datetime import datetime, timezone
|
||||
from enum import Enum, auto
|
||||
from pathlib import Path
|
||||
from typing import Optional, Union
|
||||
from typing import Any, Optional, Union
|
||||
import logging
|
||||
from urllib.request import Request, urlopen
|
||||
from cryptography.hazmat.primitives import serialization
|
||||
@ -129,7 +129,7 @@ class MIoTStorage:
|
||||
self, full_path: str, type_: type = bytes, with_hash_check: bool = True
|
||||
) -> Union[bytes, str, dict, list, None]:
|
||||
if not os.path.exists(full_path):
|
||||
_LOGGER.debug('load error, file not exists, %s', full_path)
|
||||
_LOGGER.debug('load error, file does not exist, %s', full_path)
|
||||
return None
|
||||
if not os.access(full_path, os.R_OK):
|
||||
_LOGGER.error('load error, file not readable, %s', full_path)
|
||||
@ -160,7 +160,7 @@ class MIoTStorage:
|
||||
if type_ in [dict, list]:
|
||||
return json.loads(data_bytes)
|
||||
_LOGGER.error(
|
||||
'load error, un-support data type, %s', type_.__name__)
|
||||
'load error, unsupported data type, %s', type_.__name__)
|
||||
return None
|
||||
except (OSError, TypeError) as e:
|
||||
_LOGGER.error('load error, %s, %s', e, traceback.format_exc())
|
||||
@ -219,8 +219,8 @@ class MIoTStorage:
|
||||
w_bytes = json.dumps(data).encode('utf-8')
|
||||
else:
|
||||
_LOGGER.error(
|
||||
'save error, un-support data type, %s', type_.__name__)
|
||||
return None
|
||||
'save error, unsupported data type, %s', type_.__name__)
|
||||
return False
|
||||
with open(full_path, 'wb') as w_file:
|
||||
w_file.write(w_bytes)
|
||||
if with_hash:
|
||||
@ -419,7 +419,7 @@ class MIoTStorage:
|
||||
return await fut
|
||||
|
||||
def update_user_config(
|
||||
self, uid: str, cloud_server: str, config: Optional[dict[str, any]],
|
||||
self, uid: str, cloud_server: str, config: Optional[dict[str, Any]],
|
||||
replace: bool = False
|
||||
) -> bool:
|
||||
if config is not None and len(config) == 0:
|
||||
@ -443,7 +443,7 @@ class MIoTStorage:
|
||||
domain=config_domain, name=config_name, data=local_config)
|
||||
|
||||
async def update_user_config_async(
|
||||
self, uid: str, cloud_server: str, config: Optional[dict[str, any]],
|
||||
self, uid: str, cloud_server: str, config: Optional[dict[str, Any]],
|
||||
replace: bool = False
|
||||
) -> bool:
|
||||
"""Update user configuration.
|
||||
@ -480,7 +480,7 @@ class MIoTStorage:
|
||||
|
||||
def load_user_config(
|
||||
self, uid: str, cloud_server: str, keys: Optional[list[str]] = None
|
||||
) -> dict[str, any]:
|
||||
) -> dict[str, Any]:
|
||||
if keys is not None and len(keys) == 0:
|
||||
# Do nothing
|
||||
return {}
|
||||
@ -494,7 +494,7 @@ class MIoTStorage:
|
||||
|
||||
async def load_user_config_async(
|
||||
self, uid: str, cloud_server: str, keys: Optional[list[str]] = None
|
||||
) -> dict[str, any]:
|
||||
) -> dict[str, Any]:
|
||||
"""Load user configuration.
|
||||
|
||||
Args:
|
||||
@ -503,7 +503,7 @@ class MIoTStorage:
|
||||
query key list, return all config item if keys is None
|
||||
|
||||
Returns:
|
||||
dict[str, any]: query result
|
||||
dict[str, Any]: query result
|
||||
"""
|
||||
if keys is not None and len(keys) == 0:
|
||||
# Do nothing
|
||||
|
@ -3,14 +3,20 @@
|
||||
"urn:miot-spec-v2:property:air-cooler:000000EB": "open_close",
|
||||
"urn:miot-spec-v2:property:alarm:00000012": "open_close",
|
||||
"urn:miot-spec-v2:property:anion:00000025": "open_close",
|
||||
"urn:miot-spec-v2:property:anti-fake:00000130": "yes_no",
|
||||
"urn:miot-spec-v2:property:arrhythmia:000000B4": "yes_no",
|
||||
"urn:miot-spec-v2:property:auto-cleanup:00000124": "open_close",
|
||||
"urn:miot-spec-v2:property:auto-deodorization:00000125": "open_close",
|
||||
"urn:miot-spec-v2:property:auto-keep-warm:0000002B": "open_close",
|
||||
"urn:miot-spec-v2:property:automatic-feeding:000000F0": "open_close",
|
||||
"urn:miot-spec-v2:property:blow:000000CD": "open_close",
|
||||
"urn:miot-spec-v2:property:card-insertion-state:00000106": "yes_no",
|
||||
"urn:miot-spec-v2:property:contact-state:0000007C": "contact_state",
|
||||
"urn:miot-spec-v2:property:current-physical-control-lock:00000099": "open_close",
|
||||
"urn:miot-spec-v2:property:delay:0000014F": "yes_no",
|
||||
"urn:miot-spec-v2:property:deodorization:000000C6": "open_close",
|
||||
"urn:miot-spec-v2:property:dns-auto-mode:000000DC": "open_close",
|
||||
"urn:miot-spec-v2:property:current-physical-control-lock:00000099": "open_close",
|
||||
"urn:miot-spec-v2:property:driving-status:000000B9": "yes_no",
|
||||
"urn:miot-spec-v2:property:dryer:00000027": "open_close",
|
||||
"urn:miot-spec-v2:property:eco:00000024": "open_close",
|
||||
"urn:miot-spec-v2:property:glimmer-full-color:00000089": "open_close",
|
||||
@ -20,17 +26,25 @@
|
||||
"urn:miot-spec-v2:property:horizontal-swing:00000017": "open_close",
|
||||
"urn:miot-spec-v2:property:hot-water-recirculation:0000011C": "open_close",
|
||||
"urn:miot-spec-v2:property:image-distortion-correction:0000010F": "open_close",
|
||||
"urn:miot-spec-v2:property:mute:00000040": "open_close",
|
||||
"urn:miot-spec-v2:property:local-storage:0000011E": "yes_no",
|
||||
"urn:miot-spec-v2:property:motion-detection:00000056": "open_close",
|
||||
"urn:miot-spec-v2:property:motion-state:0000007D": "motion_state",
|
||||
"urn:miot-spec-v2:property:motion-tracking:0000008A": "open_close",
|
||||
"urn:miot-spec-v2:property:motor-reverse:00000072": "yes_no",
|
||||
"urn:miot-spec-v2:property:mute:00000040": "open_close",
|
||||
"urn:miot-spec-v2:property:off-delay:00000053": "open_close",
|
||||
"urn:miot-spec-v2:property:on:00000006": "open_close",
|
||||
"urn:miot-spec-v2:property:physical-controls-locked:0000001D": "open_close",
|
||||
"urn:miot-spec-v2:property:plasma:00000132": "yes_no",
|
||||
"urn:miot-spec-v2:property:preheat:00000103": "open_close",
|
||||
"urn:miot-spec-v2:property:seating-state:000000B8": "yes_no",
|
||||
"urn:miot-spec-v2:property:silent-execution:000000FB": "yes_no",
|
||||
"urn:miot-spec-v2:property:sleep-aid-mode:0000010B": "open_close",
|
||||
"urn:miot-spec-v2:property:sleep-mode:00000028": "open_close",
|
||||
"urn:miot-spec-v2:property:snore-state:0000012A": "yes_no",
|
||||
"urn:miot-spec-v2:property:soft-wind:000000CF": "open_close",
|
||||
"urn:miot-spec-v2:property:speed-control:000000E8": "open_close",
|
||||
"urn:miot-spec-v2:property:submersion-state:0000007E": "yes_no",
|
||||
"urn:miot-spec-v2:property:time-watermark:00000087": "open_close",
|
||||
"urn:miot-spec-v2:property:un-straight-blowing:00000100": "open_close",
|
||||
"urn:miot-spec-v2:property:uv:00000029": "open_close",
|
||||
@ -43,41 +57,19 @@
|
||||
"urn:miot-spec-v2:property:wdr-mode:00000088": "open_close",
|
||||
"urn:miot-spec-v2:property:wet:0000002A": "open_close",
|
||||
"urn:miot-spec-v2:property:wifi-band-combine:000000E0": "open_close",
|
||||
"urn:miot-spec-v2:property:anti-fake:00000130": "yes_no",
|
||||
"urn:miot-spec-v2:property:arrhythmia:000000B4": "yes_no",
|
||||
"urn:miot-spec-v2:property:card-insertion-state:00000106": "yes_no",
|
||||
"urn:miot-spec-v2:property:delay:0000014F": "yes_no",
|
||||
"urn:miot-spec-v2:property:driving-status:000000B9": "yes_no",
|
||||
"urn:miot-spec-v2:property:local-storage:0000011E": "yes_no",
|
||||
"urn:miot-spec-v2:property:motor-reverse:00000072": "yes_no",
|
||||
"urn:miot-spec-v2:property:plasma:00000132": "yes_no",
|
||||
"urn:miot-spec-v2:property:seating-state:000000B8": "yes_no",
|
||||
"urn:miot-spec-v2:property:silent-execution:000000FB": "yes_no",
|
||||
"urn:miot-spec-v2:property:snore-state:0000012A": "yes_no",
|
||||
"urn:miot-spec-v2:property:submersion-state:0000007E": "yes_no",
|
||||
"urn:miot-spec-v2:property:wifi-ssid-hidden:000000E3": "yes_no",
|
||||
"urn:miot-spec-v2:property:wind-reverse:00000117": "yes_no",
|
||||
"urn:miot-spec-v2:property:motion-state:0000007D": "motion_state",
|
||||
"urn:miot-spec-v2:property:contact-state:0000007C": "contact_state"
|
||||
"urn:miot-spec-v2:property:wind-reverse:00000117": "yes_no"
|
||||
},
|
||||
"translate": {
|
||||
"default": {
|
||||
"zh-Hans": {
|
||||
"true": "真",
|
||||
"false": "假"
|
||||
},
|
||||
"zh-Hant": {
|
||||
"true": "真",
|
||||
"false": "假"
|
||||
"de": {
|
||||
"true": "Wahr",
|
||||
"false": "Falsch"
|
||||
},
|
||||
"en": {
|
||||
"true": "True",
|
||||
"false": "False"
|
||||
},
|
||||
"de": {
|
||||
"true": "Wahr",
|
||||
"false": "Falsch"
|
||||
},
|
||||
"es": {
|
||||
"true": "Verdadero",
|
||||
"false": "Falso"
|
||||
@ -86,32 +78,44 @@
|
||||
"true": "Vrai",
|
||||
"false": "Faux"
|
||||
},
|
||||
"ja": {
|
||||
"true": "真",
|
||||
"false": "偽"
|
||||
},
|
||||
"nl": {
|
||||
"true": "True",
|
||||
"false": "False"
|
||||
},
|
||||
"pt": {
|
||||
"true": "True",
|
||||
"false": "False"
|
||||
},
|
||||
"pt-BR": {
|
||||
"true": "True",
|
||||
"false": "False"
|
||||
},
|
||||
"ru": {
|
||||
"true": "Истина",
|
||||
"false": "Ложь"
|
||||
},
|
||||
"ja": {
|
||||
"zh-Hans": {
|
||||
"true": "真",
|
||||
"false": "偽"
|
||||
"false": "假"
|
||||
},
|
||||
"zh-Hant": {
|
||||
"true": "真",
|
||||
"false": "假"
|
||||
}
|
||||
},
|
||||
"open_close": {
|
||||
"zh-Hans": {
|
||||
"true": "开启",
|
||||
"false": "关闭"
|
||||
},
|
||||
"zh-Hant": {
|
||||
"true": "開啟",
|
||||
"false": "關閉"
|
||||
"de": {
|
||||
"true": "Öffnen",
|
||||
"false": "Schließen"
|
||||
},
|
||||
"en": {
|
||||
"true": "Open",
|
||||
"false": "Close"
|
||||
},
|
||||
"de": {
|
||||
"true": "Öffnen",
|
||||
"false": "Schließen"
|
||||
},
|
||||
"es": {
|
||||
"true": "Abierto",
|
||||
"false": "Cerrado"
|
||||
@ -120,32 +124,44 @@
|
||||
"true": "Ouvert",
|
||||
"false": "Fermer"
|
||||
},
|
||||
"ja": {
|
||||
"true": "開く",
|
||||
"false": "閉じる"
|
||||
},
|
||||
"nl": {
|
||||
"true": "Open",
|
||||
"false": "Dicht"
|
||||
},
|
||||
"pt": {
|
||||
"true": "Aberto",
|
||||
"false": "Fechado"
|
||||
},
|
||||
"pt-BR": {
|
||||
"true": "Aberto",
|
||||
"false": "Fechado"
|
||||
},
|
||||
"ru": {
|
||||
"true": "Открыть",
|
||||
"false": "Закрыть"
|
||||
},
|
||||
"ja": {
|
||||
"true": "開く",
|
||||
"false": "閉じる"
|
||||
"zh-Hans": {
|
||||
"true": "开启",
|
||||
"false": "关闭"
|
||||
},
|
||||
"zh-Hant": {
|
||||
"true": "開啟",
|
||||
"false": "關閉"
|
||||
}
|
||||
},
|
||||
"yes_no": {
|
||||
"zh-Hans": {
|
||||
"true": "是",
|
||||
"false": "否"
|
||||
},
|
||||
"zh-Hant": {
|
||||
"true": "是",
|
||||
"false": "否"
|
||||
"de": {
|
||||
"true": "Ja",
|
||||
"false": "Nein"
|
||||
},
|
||||
"en": {
|
||||
"true": "Yes",
|
||||
"false": "No"
|
||||
},
|
||||
"de": {
|
||||
"true": "Ja",
|
||||
"false": "Nein"
|
||||
},
|
||||
"es": {
|
||||
"true": "Sí",
|
||||
"false": "No"
|
||||
@ -154,32 +170,44 @@
|
||||
"true": "Oui",
|
||||
"false": "Non"
|
||||
},
|
||||
"ja": {
|
||||
"true": "はい",
|
||||
"false": "いいえ"
|
||||
},
|
||||
"nl": {
|
||||
"true": "Ja",
|
||||
"false": "Nee"
|
||||
},
|
||||
"pt": {
|
||||
"true": "Sim",
|
||||
"false": "Não"
|
||||
},
|
||||
"pt-BR": {
|
||||
"true": "Sim",
|
||||
"false": "Não"
|
||||
},
|
||||
"ru": {
|
||||
"true": "Да",
|
||||
"false": "Нет"
|
||||
},
|
||||
"ja": {
|
||||
"true": "はい",
|
||||
"false": "いいえ"
|
||||
"zh-Hans": {
|
||||
"true": "是",
|
||||
"false": "否"
|
||||
},
|
||||
"zh-Hant": {
|
||||
"true": "是",
|
||||
"false": "否"
|
||||
}
|
||||
},
|
||||
"motion_state": {
|
||||
"zh-Hans": {
|
||||
"true": "有人",
|
||||
"false": "无人"
|
||||
},
|
||||
"zh-Hant": {
|
||||
"true": "有人",
|
||||
"false": "無人"
|
||||
"de": {
|
||||
"true": "Bewegung erkannt",
|
||||
"false": "Keine Bewegung erkannt"
|
||||
},
|
||||
"en": {
|
||||
"true": "Motion Detected",
|
||||
"false": "No Motion Detected"
|
||||
},
|
||||
"de": {
|
||||
"true": "Bewegung erkannt",
|
||||
"false": "Keine Bewegung erkannt"
|
||||
},
|
||||
"es": {
|
||||
"true": "Movimiento detectado",
|
||||
"false": "No se detecta movimiento"
|
||||
@ -188,32 +216,44 @@
|
||||
"true": "Mouvement détecté",
|
||||
"false": "Aucun mouvement détecté"
|
||||
},
|
||||
"ja": {
|
||||
"true": "動きを検知",
|
||||
"false": "動きが検出されません"
|
||||
},
|
||||
"nl": {
|
||||
"true": "Contact",
|
||||
"false": "Geen contact"
|
||||
},
|
||||
"pt": {
|
||||
"true": "Contato",
|
||||
"false": "Sem contato"
|
||||
},
|
||||
"pt-BR": {
|
||||
"true": "Contato",
|
||||
"false": "Sem contato"
|
||||
},
|
||||
"ru": {
|
||||
"true": "Обнаружено движение",
|
||||
"false": "Движение не обнаружено"
|
||||
},
|
||||
"ja": {
|
||||
"true": "動きを検知",
|
||||
"false": "動きが検出されません"
|
||||
"zh-Hans": {
|
||||
"true": "有人",
|
||||
"false": "无人"
|
||||
},
|
||||
"zh-Hant": {
|
||||
"true": "有人",
|
||||
"false": "無人"
|
||||
}
|
||||
},
|
||||
"contact_state": {
|
||||
"zh-Hans": {
|
||||
"true": "接触",
|
||||
"false": "分离"
|
||||
},
|
||||
"zh-Hant": {
|
||||
"true": "接觸",
|
||||
"false": "分離"
|
||||
"de": {
|
||||
"true": "Kontakt",
|
||||
"false": "Kein Kontakt"
|
||||
},
|
||||
"en": {
|
||||
"true": "Contact",
|
||||
"false": "No Contact"
|
||||
},
|
||||
"de": {
|
||||
"true": "Kontakt",
|
||||
"false": "Kein Kontakt"
|
||||
},
|
||||
"es": {
|
||||
"true": "Contacto",
|
||||
"false": "Sin contacto"
|
||||
@ -222,13 +262,33 @@
|
||||
"true": "Contact",
|
||||
"false": "Pas de contact"
|
||||
},
|
||||
"ja": {
|
||||
"true": "接触",
|
||||
"false": "非接触"
|
||||
},
|
||||
"nl": {
|
||||
"true": "Contact",
|
||||
"false": "Geen contact"
|
||||
},
|
||||
"pt": {
|
||||
"true": "Contato",
|
||||
"false": "Sem contato"
|
||||
},
|
||||
"pt-BR": {
|
||||
"true": "Contato",
|
||||
"false": "Sem contato"
|
||||
},
|
||||
"ru": {
|
||||
"true": "Контакт",
|
||||
"false": "Нет контакта"
|
||||
},
|
||||
"ja": {
|
||||
"zh-Hans": {
|
||||
"true": "接触",
|
||||
"false": "非接触"
|
||||
"false": "分离"
|
||||
},
|
||||
"zh-Hant": {
|
||||
"true": "接觸",
|
||||
"false": "分離"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,27 @@
|
||||
{
|
||||
"urn:miot-spec-v2:device:gateway:0000A019:xiaomi-hub1": {
|
||||
"de": {
|
||||
"service:001": "Geräteinformationen",
|
||||
"service:001:property:003": "Geräte-ID",
|
||||
"service:001:property:005": "Seriennummer (SN)",
|
||||
"service:002": "Gateway",
|
||||
"service:002:event:001": "Netzwerk geändert",
|
||||
"service:002:event:002": "Netzwerk geändert",
|
||||
"service:002:property:001": "Zugriffsmethode",
|
||||
"service:002:property:001:valuelist:000": "Kabelgebunden",
|
||||
"service:002:property:001:valuelist:001": "5G Drahtlos",
|
||||
"service:002:property:001:valuelist:002": "2.4G Drahtlos",
|
||||
"service:002:property:002": "IP-Adresse",
|
||||
"service:002:property:003": "WiFi-Netzwerkname",
|
||||
"service:002:property:004": "Aktuelle Zeit",
|
||||
"service:002:property:005": "DHCP-Server-MAC-Adresse",
|
||||
"service:003": "Anzeigelampe",
|
||||
"service:003:property:001": "Schalter",
|
||||
"service:004": "Virtueller Dienst",
|
||||
"service:004:action:001": "Virtuelles Ereignis erzeugen",
|
||||
"service:004:event:001": "Virtuelles Ereignis aufgetreten",
|
||||
"service:004:property:001": "Ereignisname"
|
||||
},
|
||||
"en": {
|
||||
"service:001": "Device Information",
|
||||
"service:001:property:003": "Device ID",
|
||||
@ -66,50 +88,6 @@
|
||||
"service:004:event:001": "Événement virtuel survenu",
|
||||
"service:004:property:001": "Nom de l'événement"
|
||||
},
|
||||
"ru": {
|
||||
"service:001": "Информация об устройстве",
|
||||
"service:001:property:003": "ID устройства",
|
||||
"service:001:property:005": "Серийный номер (SN)",
|
||||
"service:002": "Шлюз",
|
||||
"service:002:event:001": "Сеть изменена",
|
||||
"service:002:event:002": "Сеть изменена",
|
||||
"service:002:property:001": "Метод доступа",
|
||||
"service:002:property:001:valuelist:000": "Проводной",
|
||||
"service:002:property:001:valuelist:001": "5G Беспроводной",
|
||||
"service:002:property:001:valuelist:002": "2.4G Беспроводной",
|
||||
"service:002:property:002": "IP Адрес",
|
||||
"service:002:property:003": "Название WiFi сети",
|
||||
"service:002:property:004": "Текущее время",
|
||||
"service:002:property:005": "MAC адрес DHCP сервера",
|
||||
"service:003": "Световой индикатор",
|
||||
"service:003:property:001": "Переключатель",
|
||||
"service:004": "Виртуальная служба",
|
||||
"service:004:action:001": "Создать виртуальное событие",
|
||||
"service:004:event:001": "Произошло виртуальное событие",
|
||||
"service:004:property:001": "Название события"
|
||||
},
|
||||
"de": {
|
||||
"service:001": "Geräteinformationen",
|
||||
"service:001:property:003": "Geräte-ID",
|
||||
"service:001:property:005": "Seriennummer (SN)",
|
||||
"service:002": "Gateway",
|
||||
"service:002:event:001": "Netzwerk geändert",
|
||||
"service:002:event:002": "Netzwerk geändert",
|
||||
"service:002:property:001": "Zugriffsmethode",
|
||||
"service:002:property:001:valuelist:000": "Kabelgebunden",
|
||||
"service:002:property:001:valuelist:001": "5G Drahtlos",
|
||||
"service:002:property:001:valuelist:002": "2.4G Drahtlos",
|
||||
"service:002:property:002": "IP-Adresse",
|
||||
"service:002:property:003": "WiFi-Netzwerkname",
|
||||
"service:002:property:004": "Aktuelle Zeit",
|
||||
"service:002:property:005": "DHCP-Server-MAC-Adresse",
|
||||
"service:003": "Anzeigelampe",
|
||||
"service:003:property:001": "Schalter",
|
||||
"service:004": "Virtueller Dienst",
|
||||
"service:004:action:001": "Virtuelles Ereignis erzeugen",
|
||||
"service:004:event:001": "Virtuelles Ereignis aufgetreten",
|
||||
"service:004:property:001": "Ereignisname"
|
||||
},
|
||||
"ja": {
|
||||
"service:001": "デバイス情報",
|
||||
"service:001:property:003": "デバイスID",
|
||||
@ -132,6 +110,28 @@
|
||||
"service:004:event:001": "バーチャルイベントが発生しました",
|
||||
"service:004:property:001": "イベント名"
|
||||
},
|
||||
"ru": {
|
||||
"service:001": "Информация об устройстве",
|
||||
"service:001:property:003": "ID устройства",
|
||||
"service:001:property:005": "Серийный номер (SN)",
|
||||
"service:002": "Шлюз",
|
||||
"service:002:event:001": "Сеть изменена",
|
||||
"service:002:event:002": "Сеть изменена",
|
||||
"service:002:property:001": "Метод доступа",
|
||||
"service:002:property:001:valuelist:000": "Проводной",
|
||||
"service:002:property:001:valuelist:001": "5G Беспроводной",
|
||||
"service:002:property:001:valuelist:002": "2.4G Беспроводной",
|
||||
"service:002:property:002": "IP Адрес",
|
||||
"service:002:property:003": "Название WiFi сети",
|
||||
"service:002:property:004": "Текущее время",
|
||||
"service:002:property:005": "MAC адрес DHCP сервера",
|
||||
"service:003": "Световой индикатор",
|
||||
"service:003:property:001": "Переключатель",
|
||||
"service:004": "Виртуальная служба",
|
||||
"service:004:action:001": "Создать виртуальное событие",
|
||||
"service:004:event:001": "Произошло виртуальное событие",
|
||||
"service:004:property:001": "Название события"
|
||||
},
|
||||
"zh-Hant": {
|
||||
"service:001": "設備信息",
|
||||
"service:001:property:003": "設備ID",
|
||||
@ -154,5 +154,19 @@
|
||||
"service:004:event:001": "虛擬事件發生",
|
||||
"service:004:property:001": "事件名稱"
|
||||
}
|
||||
},
|
||||
"urn:miot-spec-v2:device:switch:0000A003:lumi-acn040:1": {
|
||||
"en": {
|
||||
"service:011": "Right Button On and Off",
|
||||
"service:011:property:001": "Right Button On and Off",
|
||||
"service:015:action:001": "Left Button Identify",
|
||||
"service:016:action:001": "Middle Button Identify",
|
||||
"service:017:action:001": "Right Button Identify"
|
||||
},
|
||||
"zh-Hans": {
|
||||
"service:015:action:001": "左键确认",
|
||||
"service:016:action:001": "中键确认",
|
||||
"service:017:action:001": "右键确认"
|
||||
}
|
||||
}
|
||||
}
|
@ -1,26 +1,22 @@
|
||||
{
|
||||
"urn:miot-spec-v2:device:health-pot:0000A051:chunmi-a1": {
|
||||
"urn:miot-spec-v2:device:air-purifier:0000A007:zhimi-ma4": {
|
||||
"properties": [
|
||||
"9.*",
|
||||
"13.*",
|
||||
"15.*"
|
||||
],
|
||||
"services": [
|
||||
"5"
|
||||
"10"
|
||||
]
|
||||
},
|
||||
"urn:miot-spec-v2:device:curtain:0000A00C:lumi-hmcn01": {
|
||||
"properties": [
|
||||
"5.1"
|
||||
],
|
||||
"services": [
|
||||
"4",
|
||||
"7",
|
||||
"8"
|
||||
],
|
||||
"properties": [
|
||||
"5.1"
|
||||
]
|
||||
},
|
||||
"urn:miot-spec-v2:device:light:0000A001:philips-strip3": {
|
||||
"services": [
|
||||
"1",
|
||||
"3"
|
||||
],
|
||||
"properties": [
|
||||
"2.2"
|
||||
]
|
||||
},
|
||||
"urn:miot-spec-v2:device:gateway:0000A019:xiaomi-hub1": {
|
||||
@ -28,10 +24,18 @@
|
||||
"2.1"
|
||||
]
|
||||
},
|
||||
"urn:miot-spec-v2:device:motion-sensor:0000A014:xiaomi-pir1": {
|
||||
"urn:miot-spec-v2:device:health-pot:0000A051:chunmi-a1": {
|
||||
"services": [
|
||||
"5"
|
||||
]
|
||||
},
|
||||
"urn:miot-spec-v2:device:light:0000A001:philips-strip3": {
|
||||
"properties": [
|
||||
"2.2"
|
||||
],
|
||||
"services": [
|
||||
"1",
|
||||
"5"
|
||||
"3"
|
||||
]
|
||||
},
|
||||
"urn:miot-spec-v2:device:light:0000A001:yeelink-color2": {
|
||||
@ -50,14 +54,10 @@
|
||||
"3"
|
||||
]
|
||||
},
|
||||
"urn:miot-spec-v2:device:air-purifier:0000A007:zhimi-ma4": {
|
||||
"urn:miot-spec-v2:device:motion-sensor:0000A014:xiaomi-pir1": {
|
||||
"services": [
|
||||
"10"
|
||||
],
|
||||
"properties": [
|
||||
"9.*",
|
||||
"13.*",
|
||||
"15.*"
|
||||
"1",
|
||||
"5"
|
||||
]
|
||||
}
|
||||
}
|
@ -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', 'heat-level'}
|
||||
},
|
||||
}
|
||||
},
|
||||
'optional': {
|
||||
'environment': {
|
||||
'required': {},
|
||||
'optional': {
|
||||
'properties': {'temperature', 'relative-humidity'}
|
||||
}
|
||||
},
|
||||
},
|
||||
'entity': 'heater'
|
||||
}
|
||||
}
|
||||
|
||||
"""SPEC_SERVICE_TRANS_MAP
|
||||
|
@ -46,14 +46,15 @@ off Xiaomi or its affiliates' products.
|
||||
Notify entities for Xiaomi Home.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
import json
|
||||
import logging
|
||||
from typing import Optional
|
||||
from typing import Any, Optional
|
||||
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.components.notify import NotifyEntity
|
||||
from homeassistant.util import yaml
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
|
||||
from .miot.miot_spec import MIoTSpecAction
|
||||
from .miot.miot_device import MIoTDevice, MIoTActionEntity
|
||||
@ -82,6 +83,7 @@ async def async_setup_entry(
|
||||
|
||||
class Notify(MIoTActionEntity, NotifyEntity):
|
||||
"""Notify entities for Xiaomi Home."""
|
||||
# pylint: disable=unused-argument
|
||||
|
||||
def __init__(self, miot_device: MIoTDevice, spec: MIoTSpecAction) -> None:
|
||||
"""Initialize the Notify."""
|
||||
@ -96,34 +98,58 @@ class Notify(MIoTActionEntity, NotifyEntity):
|
||||
self, message: str, title: Optional[str] = None
|
||||
) -> None:
|
||||
"""Send a message."""
|
||||
del title
|
||||
if not message:
|
||||
_LOGGER.error(
|
||||
'action exec failed, %s(%s), empty action params',
|
||||
self.name, self.entity_id)
|
||||
return
|
||||
in_list: Any = None
|
||||
try:
|
||||
in_list: list = json.loads(message)
|
||||
except json.JSONDecodeError:
|
||||
# YAML will convert yes, no, on, off, true, false to the bool type,
|
||||
# and if it is a string, quotation marks need to be added.
|
||||
in_list = yaml.parse_yaml(content=message)
|
||||
except HomeAssistantError:
|
||||
_LOGGER.error(
|
||||
'action exec failed, %s(%s), invalid action params format, %s',
|
||||
self.name, self.entity_id, message)
|
||||
return
|
||||
|
||||
if len(self.spec.in_) == 1 and not isinstance(in_list, list):
|
||||
in_list = [in_list]
|
||||
if not isinstance(in_list, list) or len(in_list) != len(self.spec.in_):
|
||||
_LOGGER.error(
|
||||
'action exec failed, %s(%s), invalid action params, %s',
|
||||
self.name, self.entity_id, message)
|
||||
return
|
||||
|
||||
in_value: list[dict] = []
|
||||
for index, prop in enumerate(self.spec.in_):
|
||||
if type(in_list[index]).__name__ != prop.format_:
|
||||
logging.error(
|
||||
'action exec failed, %s(%s), invalid params item, '
|
||||
'which item(%s) in the list must be %s, %s',
|
||||
self.name, self.entity_id, prop.description_trans,
|
||||
prop.format_, message)
|
||||
return
|
||||
in_value.append({'piid': prop.iid, 'value': in_list[index]})
|
||||
return await self.action_async(in_list=in_value)
|
||||
if prop.format_ == 'str':
|
||||
if isinstance(in_list[index], (bool, int, float, str)):
|
||||
in_value.append(
|
||||
{'piid': prop.iid, 'value': str(in_list[index])})
|
||||
continue
|
||||
elif prop.format_ == 'bool':
|
||||
if isinstance(in_list[index], (bool, int)):
|
||||
# yes, no, on, off, true, false and other bool types
|
||||
# will also be parsed as 0 and 1 of int.
|
||||
in_value.append(
|
||||
{'piid': prop.iid, 'value': bool(in_list[index])})
|
||||
continue
|
||||
elif prop.format_ == 'float':
|
||||
if isinstance(in_list[index], (int, float)):
|
||||
in_value.append(
|
||||
{'piid': prop.iid, 'value': in_list[index]})
|
||||
continue
|
||||
elif prop.format_ == 'int':
|
||||
if isinstance(in_list[index], int):
|
||||
in_value.append(
|
||||
{'piid': prop.iid, 'value': in_list[index]})
|
||||
continue
|
||||
# Invalid params type, raise error.
|
||||
_LOGGER.error(
|
||||
'action exec failed, %s(%s), invalid params item, '
|
||||
'which item(%s) in the list must be %s, %s type was %s, %s',
|
||||
self.name, self.entity_id, prop.description_trans,
|
||||
prop.format_, in_list[index], type(
|
||||
in_list[index]).__name__, message)
|
||||
return
|
||||
await self.action_async(in_list=in_value)
|
||||
|
@ -47,6 +47,7 @@ Sensor entities for Xiaomi Home.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
import logging
|
||||
from typing import Any
|
||||
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
@ -107,7 +108,7 @@ class Sensor(MIoTPropertyEntity, SensorEntity):
|
||||
self._attr_icon = spec.icon
|
||||
|
||||
@property
|
||||
def native_value(self) -> any:
|
||||
def native_value(self) -> Any:
|
||||
"""Return the current value of the sensor."""
|
||||
if self._value_range and isinstance(self._value, (int, float)):
|
||||
if (
|
||||
|
@ -46,14 +46,15 @@ off Xiaomi or its affiliates' products.
|
||||
Text entities for Xiaomi Home.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
import json
|
||||
import logging
|
||||
from typing import Optional
|
||||
from typing import Any, Optional
|
||||
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.components.text import TextEntity
|
||||
from homeassistant.util import yaml
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
|
||||
from .miot.const import DOMAIN
|
||||
from .miot.miot_spec import MIoTSpecAction, MIoTSpecProperty
|
||||
@ -119,16 +120,18 @@ class ActionText(MIoTActionEntity, TextEntity):
|
||||
async def async_set_value(self, value: str) -> None:
|
||||
if not value:
|
||||
return
|
||||
in_list: list = None
|
||||
in_list: Any = None
|
||||
try:
|
||||
in_list = json.loads(value)
|
||||
except json.JSONDecodeError as e:
|
||||
in_list = yaml.parse_yaml(content=value)
|
||||
except HomeAssistantError as e:
|
||||
_LOGGER.error(
|
||||
'action exec failed, %s(%s), invalid action params format, %s',
|
||||
self.name, self.entity_id, value)
|
||||
raise ValueError(
|
||||
f'action exec failed, {self.name}({self.entity_id}), '
|
||||
f'invalid action params format, {value}') from e
|
||||
if len(self.spec.in_) == 1 and not isinstance(in_list, list):
|
||||
in_list = [in_list]
|
||||
if not isinstance(in_list, list) or len(in_list) != len(self.spec.in_):
|
||||
_LOGGER.error(
|
||||
'action exec failed, %s(%s), invalid action params, %s',
|
||||
@ -138,16 +141,40 @@ class ActionText(MIoTActionEntity, TextEntity):
|
||||
f'invalid action params, {value}')
|
||||
in_value: list[dict] = []
|
||||
for index, prop in enumerate(self.spec.in_):
|
||||
if type(in_list[index]).__name__ != prop.format_:
|
||||
logging.error(
|
||||
'action exec failed, %s(%s), invalid params item, which '
|
||||
'item(%s) in the list must be %s, %s', self.name,
|
||||
self.entity_id, prop.description_trans, prop.format_, value)
|
||||
raise ValueError(
|
||||
f'action exec failed, {self.name}({self.entity_id}), '
|
||||
f'invalid params item, which item({prop.description_trans})'
|
||||
f' in the list must be {prop.format_}, {value}')
|
||||
in_value.append({'piid': prop.iid, 'value': in_list[index]})
|
||||
if prop.format_ == 'str':
|
||||
if isinstance(in_list[index], (bool, int, float, str)):
|
||||
in_value.append(
|
||||
{'piid': prop.iid, 'value': str(in_list[index])})
|
||||
continue
|
||||
elif prop.format_ == 'bool':
|
||||
if isinstance(in_list[index], (bool, int)):
|
||||
# yes, no, on, off, true, false and other bool types
|
||||
# will also be parsed as 0 and 1 of int.
|
||||
in_value.append(
|
||||
{'piid': prop.iid, 'value': bool(in_list[index])})
|
||||
continue
|
||||
elif prop.format_ == 'float':
|
||||
if isinstance(in_list[index], (int, float)):
|
||||
in_value.append(
|
||||
{'piid': prop.iid, 'value': in_list[index]})
|
||||
continue
|
||||
elif prop.format_ == 'int':
|
||||
if isinstance(in_list[index], int):
|
||||
in_value.append(
|
||||
{'piid': prop.iid, 'value': in_list[index]})
|
||||
continue
|
||||
# Invalid params type, raise error.
|
||||
_LOGGER.error(
|
||||
'action exec failed, %s(%s), invalid params item, '
|
||||
'which item(%s) in the list must be %s, %s type was %s, %s',
|
||||
self.name, self.entity_id, prop.description_trans,
|
||||
prop.format_, in_list[index], type(
|
||||
in_list[index]).__name__, value)
|
||||
raise ValueError(
|
||||
f'action exec failed, {self.name}({self.entity_id}), '
|
||||
f'invalid params item, which item({prop.description_trans}) '
|
||||
f'in the list must be {prop.format_}, {in_list[index]} type '
|
||||
f'was {type(in_list[index]).__name__}, {value}')
|
||||
|
||||
self._attr_native_value = value
|
||||
if await self.action_async(in_list=in_value):
|
||||
|
@ -11,26 +11,59 @@
|
||||
},
|
||||
"auth_config": {
|
||||
"title": "Grundkonfiguration",
|
||||
"description": "### Anmeldegebiet\r\nWählen Sie das Gebiet, in dem sich Ihr Xiaomi Home-Konto befindet. Sie können es in der Xiaomi Home App unter `Mein (unten im Menü) > Weitere Einstellungen > Über Xiaomi Home` überprüfen.\r\n### Sprache\r\nWählen Sie die Sprache, in der Geräte und Entitätsnamen angezeigt werden. Teile von Sätzen, die nicht übersetzt sind, werden in Englisch angezeigt.\r\n### OAuth2-Authentifizierungs-Umleitungs-URL\r\nDie Umleitungs-URL für die OAuth2-Authentifizierung lautet **[http://homeassistant.local:8123](http://homeassistant.local:8123)**. Home Assistant muss im selben lokalen Netzwerk wie das aktuelle Betriebsterminal (z. B. ein persönlicher Computer) und das Betriebsterminal muss über diese Adresse auf die Home Assistant-Homepage zugreifen können. Andernfalls kann die Anmeldeauthentifizierung fehlschlagen.\r\n### Hinweis\r\n- Für Benutzer mit Hunderten oder mehr Mi Home-Geräten wird das erste Hinzufügen der Integration einige Zeit in Anspruch nehmen. Bitte haben Sie Geduld.\r\n- Wenn Home Assistant in einer Docker-Umgebung läuft, stellen Sie bitte sicher, dass der Docker-Netzwerkmodus auf host eingestellt ist, da sonst die lokale Steuerungsfunktion möglicherweise nicht richtig funktioniert.\r\n- Die lokale Steuerungsfunktion der Integration hat einige Abhängigkeiten. Bitte lesen Sie das README sorgfältig.",
|
||||
"description": "### Anmeldegebiet\r\nWählen Sie das Gebiet, in dem sich Ihr Xiaomi Home-Konto befindet. Sie können es in der Xiaomi Home App unter `Mein (unten im Menü) > Weitere Einstellungen > Über Xiaomi Home` überprüfen.\r\n### Sprache\r\nWählen Sie die Sprache, in der Geräte und Entitätsnamen angezeigt werden. Teile von Sätzen, die nicht übersetzt sind, werden in Englisch angezeigt.\r\n### OAuth2-Authentifizierungs-Umleitungs-URL\r\nDie Umleitungs-URL für die OAuth2-Authentifizierung lautet **[http://homeassistant.local:8123](http://homeassistant.local:8123)**. Home Assistant muss im selben lokalen Netzwerk wie das aktuelle Betriebsterminal (z. B. ein persönlicher Computer) und das Betriebsterminal muss über diese Adresse auf die Home Assistant-Homepage zugreifen können. Andernfalls kann die Anmeldeauthentifizierung fehlschlagen.\r\n### Integrierte Netzwerkkonfiguration\r\nÜberprüfen Sie, ob das lokale Netzwerk normal funktioniert und ob die zugehörigen Netzwerkressourcen zugänglich sind. **Es wird empfohlen, dies beim ersten Hinzufügen auszuwählen.**\r\n### Hinweis\r\n- Für Benutzer mit Hunderten oder mehr Mi Home-Geräten wird das erste Hinzufügen der Integration einige Zeit in Anspruch nehmen. Bitte haben Sie Geduld.\r\n- Wenn Home Assistant in einer Docker-Umgebung läuft, stellen Sie bitte sicher, dass der Docker-Netzwerkmodus auf host eingestellt ist, da sonst die lokale Steuerungsfunktion möglicherweise nicht richtig funktioniert.\r\n- Die lokale Steuerungsfunktion der Integration hat einige Abhängigkeiten. Bitte lesen Sie das README sorgfältig.",
|
||||
"data": {
|
||||
"cloud_server": "Anmeldegebiet",
|
||||
"integration_language": "Sprache",
|
||||
"oauth_redirect_url": "OAuth2-Authentifizierungs-Umleitungs-URL"
|
||||
"oauth_redirect_url": "OAuth2-Authentifizierungs-Umleitungs-URL",
|
||||
"network_detect_config": "Integrierte Netzwerkkonfiguration"
|
||||
}
|
||||
},
|
||||
"network_detect_config": {
|
||||
"title": "Integrierte Netzwerkkonfiguration",
|
||||
"description": "## Gebrauchsanweisung\r\n### Netzwerk-Erkennungsadresse\r\nWird verwendet, um zu überprüfen, ob das Netzwerk normal funktioniert. Wenn nicht festgelegt, wird die Standardadresse des Systems verwendet. Wenn die Standardadressprüfung fehlschlägt, können Sie versuchen, eine benutzerdefinierte Adresse einzugeben.\r\n- Sie können mehrere Erkennungsadressen eingeben, getrennt durch ein Komma, z. B. `8.8.8.8,https://www.bing.com`\r\n- Wenn es sich um eine IP-Adresse handelt, wird die Erkennung durch Ping durchgeführt. Wenn es sich um eine HTTP(s)-Adresse handelt, wird die Erkennung durch einen HTTP GET-Aufruf durchgeführt.\r\n- Wenn Sie die Standarderkennungsadresse des Systems wiederherstellen möchten, geben Sie ein Komma `,` ein und klicken Sie auf 'Weiter'.\r\n- **Diese Konfiguration ist global und Änderungen wirken sich auf andere Integrationsinstanzen aus. Bitte ändern Sie sie mit Vorsicht.**\r\n### Überprüfung der Netzwerkabhängigkeiten\r\nÜberprüfen Sie nacheinander, ob die folgenden Netzwerkabhängigkeiten zugänglich sind. Wenn die entsprechenden Adressen nicht zugänglich sind, führt dies zu Integrationsfehlern.\r\n- OAuth2-Authentifizierungsadresse: `https://account.xiaomi.com/oauth2/authorize`.\r\n- Xiaomi HTTP API-Adresse: `https://{http_host}/app/v2/ha/oauth/get_token`.\r\n- Xiaomi SPEC API-Adresse: `https://miot-spec.org/miot-spec-v2/template/list/device`.\r\n- Xiaomi MQTT Broker-Adresse: `mqtts://{cloud_server}-ha.mqtt.io.mi.com:8883`.",
|
||||
"data": {
|
||||
"network_detect_addr": "Netzwerkerkennungsadresse",
|
||||
"check_network_deps": "Überprüfung der Netzwerkabhängigkeiten"
|
||||
}
|
||||
},
|
||||
"oauth_error": {
|
||||
"title": "Fehler bei der Anmeldung",
|
||||
"description": "Klicken Sie auf \"Weiter\", um es erneut zu versuchen."
|
||||
},
|
||||
"devices_filter": {
|
||||
"homes_select": {
|
||||
"title": "Familie und Geräte auswählen",
|
||||
"description": "## Gebrauchsanweisung\r\n### Steuerungsmodus\r\n- Automatisch: Wenn im lokalen Netzwerk ein verfügbarer Xiaomi-Zentralgateway vorhanden ist, wird Home Assistant bevorzugt Steuerbefehle über den Zentralgateway senden, um eine lokale Steuerung zu ermöglichen. Wenn im lokalen Netzwerk kein Zentralgateway vorhanden ist, wird versucht, Steuerbefehle über das Xiaomi-OT-Protokoll zu senden, um eine lokale Steuerung zu ermöglichen. Nur wenn die oben genannten Bedingungen für die lokale Steuerung nicht erfüllt sind, werden die Steuerbefehle über die Cloud gesendet.\r\n- Cloud: Steuerbefehle werden nur über die Cloud gesendet.\r\n### Familienimport für importierte Geräte\r\nDie Integration fügt Geräte aus den ausgewählten Familien hinzu.\r\n### Raumnamensynchronisationsmodus\r\nWenn Geräte von der Xiaomi Home App zu Home Assistant synchronisiert werden, wird die Bezeichnung des Bereichs, in dem sich die Geräte in Home Assistant befinden, nach folgenden Regeln benannt. Beachten Sie, dass das Synchronisieren von Geräten den von Xiaomi Home App festgelegten Familien- und Raum-Einstellungen nicht ändert.\r\n- Nicht synchronisieren: Das Gerät wird keinem Bereich hinzugefügt.\r\n- Andere Optionen: Der Bereich, in den das Gerät aufgenommen wird, wird nach dem Namen der Familie oder des Raums in der Xiaomi Home App benannt.\r\n### Action-Debug-Modus\r\nFür von MIoT-Spec-V2 definierte Gerätemethoden wird neben der Benachrichtigungs-Entität auch eine Texteingabe-Entität generiert. Damit können Sie bei der Fehlerbehebung Steuerbefehle an das Gerät senden.\r\n### Verstecke Nicht-Standard-Entitäten\r\nVerstecke Entitäten, die von nicht standardmäßigen MIoT-Spec-V2-Instanzen mit einem Namen beginnen, der mit einem \"*\" beginnt.\r\n\r\n \r\n### Hallo {nick_name}! Bitte wählen Sie den Steuerungsmodus der Integration sowie die Familie aus, in der sich die hinzuzufügenden Geräte befinden.",
|
||||
"description": "## Gebrauchsanweisung\r\n### Familienimport für importierte Geräte\r\nDie Integration fügt Geräte aus den ausgewählten Familien hinzu.\r\n### Raumnamensynchronisationsmodus\r\nWenn Geräte von der Xiaomi Home App zu Home Assistant synchronisiert werden, wird die Bezeichnung des Bereichs, in dem sich die Geräte in Home Assistant befinden, nach folgenden Regeln benannt. Beachten Sie, dass das Synchronisieren von Geräten den von Xiaomi Home App festgelegten Familien- und Raum-Einstellungen nicht ändert.\r\n- Nicht synchronisieren: Das Gerät wird keinem Bereich hinzugefügt.\r\n- Andere Optionen: Der Bereich, in den das Gerät aufgenommen wird, wird nach dem Namen der Familie oder des Raums in der Xiaomi Home App benannt.\r\n### Erweiterte Einstellungen\r\nZeigen Sie erweiterte Einstellungen an, um die professionellen Konfigurationsoptionen der Integration zu ändern.\r\n\r\n \r\n### {nick_name} Hallo! Bitte wählen Sie die Familie aus, zu der Sie das Gerät hinzufügen möchten.",
|
||||
"data": {
|
||||
"ctrl_mode": "Steuerungsmodus",
|
||||
"home_infos": "Familienimport für importierte Geräte",
|
||||
"area_name_rule": "Raumnamensynchronisationsmodus",
|
||||
"advanced_options": "Erweiterte Einstellungen"
|
||||
}
|
||||
},
|
||||
"advanced_options": {
|
||||
"title": "Erweiterte Einstellungen",
|
||||
"description": "## Gebrauchsanweisung\r\n### Wenn Sie die Bedeutung der folgenden Optionen nicht genau kennen, belassen Sie sie bitte auf den Standardeinstellungen.\r\n### Geräte filtern\r\nUnterstützt das Filtern von Geräten nach Raumnamen und Gerätetypen sowie das Filtern nach Gerätedimensionen.\r\n\r\n### Steuerungsmodus\r\n- Automatisch: Wenn ein verfügbarer Xiaomi-Hub im lokalen Netzwerk vorhanden ist, priorisiert Home Assistant das Senden von Steuerbefehlen über den Hub, um eine lokale Steuerung zu ermöglichen. Wenn kein Hub vorhanden ist, wird versucht, Steuerbefehle über das Xiaomi-OT-Protokoll zu senden. Nur wenn diese Bedingungen für die lokale Steuerung nicht erfüllt sind, werden die Befehle über die Cloud gesendet.\r\n- Cloud: Steuerbefehle werden ausschließlich über die Cloud gesendet.\r\n### Action-Debug-Modus\r\nFür Methoden, die von MIoT-Spec-V2-Geräten definiert werden, wird neben der Benachrichtigungsentität auch eine Texteingabe-Entität erstellt, mit der Sie während des Debuggens Steuerbefehle an das Gerät senden können.\r\n### Nicht standardmäßige Entitäten ausblenden\r\nBlendet Entitäten aus, die von nicht-standardmäßigen MIoT-Spec-V2-Instanzen generiert werden und deren Name mit „*“ beginnt.\r\n### Gerätestatusänderungen anzeigen\r\nDetaillierte Anzeige von Gerätestatusänderungen, es werden nur die ausgewählten Benachrichtigungen angezeigt.",
|
||||
"data": {
|
||||
"devices_filter": "Geräte filtern",
|
||||
"ctrl_mode": "Steuerungsmodus",
|
||||
"action_debug": "Action-Debug-Modus",
|
||||
"hide_non_standard_entities": "Verstecke Nicht-Standard-Entitäten"
|
||||
"hide_non_standard_entities": "Nicht standardmäßige Entitäten ausblenden",
|
||||
"display_devices_changed_notify": "Gerätestatusänderungen anzeigen"
|
||||
}
|
||||
},
|
||||
"devices_filter": {
|
||||
"title": "Geräte filtern",
|
||||
"description": "## Gebrauchsanweisung\r\nUnterstützt das Filtern von Geräten nach Raumnamen, Gerätezugriffstyp und Gerätemodell, und unterstützt auch das Filtern nach Gerätegröße. Die Filterlogik ist wie folgt:\r\n- Zuerst wird gemäß der statistischen Logik die Vereinigung oder der Schnittpunkt aller eingeschlossenen Elemente ermittelt, dann der Schnittpunkt oder die Vereinigung der ausgeschlossenen Elemente, und schließlich wird das [eingeschlossene Gesamtergebnis] vom [ausgeschlossenen Gesamtergebnis] subtrahiert, um das [Filterergebnis] zu erhalten.\r\n- Wenn keine eingeschlossenen Elemente ausgewählt sind, bedeutet dies, dass alle eingeschlossen sind.\r\n### Filtermodus\r\n- Ausschließen: Unerwünschte Elemente entfernen.\r\n- Einschließen: Gewünschte Elemente einschließen.\r\n### Statistische Logik\r\n- UND-Logik: Den Schnittpunkt aller Elemente im gleichen Modus nehmen.\r\n- ODER-Logik: Die Vereinigung aller Elemente im gleichen Modus nehmen.\r\n\r\nSie können auch zur Seite [Konfiguration > Geräteliste aktualisieren] des Integrationselements gehen, [Geräte filtern] auswählen, um erneut zu filtern.",
|
||||
"data": {
|
||||
"room_filter_mode": "Familienraum filtern",
|
||||
"room_list": "Familienraum",
|
||||
"type_filter_mode": "Gerätetyp filtern",
|
||||
"type_list": "Gerätetyp",
|
||||
"model_filter_mode": "Gerätemodell filtern",
|
||||
"model_list": "Gerätemodell",
|
||||
"devices_filter_mode": "Geräte filtern",
|
||||
"device_list": "Geräteliste",
|
||||
"statistics_logic": "Statistiklogik"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -44,8 +77,17 @@
|
||||
"mdns_discovery_error": "Lokaler Geräteerkennungsdienst ist nicht verfügbar.",
|
||||
"get_cert_error": "Fehler beim Abrufen des Gateway-Zertifikats.",
|
||||
"no_family_selected": "Keine Familie ausgewählt.",
|
||||
"no_devices": "In der ausgewählten Familie sind keine Geräte enthalten. Bitte wählen Sie eine Familie mit Geräten aus und fahren Sie fort.",
|
||||
"no_central_device": "Im Modus \"Xiaomi Central Hub Gateway\" muss ein verfügbares Xiaomi Central Hub Gateway im lokalen Netzwerk von Home Assistant vorhanden sein. Stellen Sie sicher, dass die ausgewählte Familie diese Anforderungen erfüllt."
|
||||
"no_devices": "Im ausgewählten Haushalt sind keine Geräte vorhanden. Bitte wählen Sie einen Haushalt mit Geräten aus und fahren Sie fort.",
|
||||
"no_filter_devices": "Gefilterte Geräte sind leer. Bitte wählen Sie gültige Filterkriterien aus und fahren Sie fort.",
|
||||
"no_central_device": "Im Modus \"Xiaomi Central Hub Gateway\" muss ein verfügbares Xiaomi Central Hub Gateway im lokalen Netzwerk von Home Assistant vorhanden sein. Stellen Sie sicher, dass die ausgewählte Familie diese Anforderungen erfüllt.",
|
||||
"invalid_network_addr": "Ungültige IP-Adresse oder HTTP-Adresse vorhanden, bitte geben Sie eine gültige Adresse ein.",
|
||||
"invalid_ip_addr": "Unzugängliche IP-Adresse vorhanden, bitte geben Sie eine gültige IP-Adresse ein.",
|
||||
"invalid_http_addr": "Unzugängliche HTTP-Adresse vorhanden, bitte geben Sie eine gültige HTTP-Adresse ein.",
|
||||
"invalid_default_addr": "Die Standard-Netzwerkerkennungsadresse ist nicht erreichbar, bitte überprüfen Sie die Netzwerkkonfiguration oder verwenden Sie eine benutzerdefinierte Netzwerkerkennungsadresse.",
|
||||
"unreachable_oauth2_host": "OAuth2-Authentifizierungsadresse ist nicht erreichbar, bitte überprüfen Sie die Netzwerkkonfiguration.",
|
||||
"unreachable_http_host": "Xiaomi HTTP API-Adresse ist nicht erreichbar, bitte überprüfen Sie die Netzwerkkonfiguration.",
|
||||
"unreachable_spec_host": "Xiaomi SPEC API-Adresse ist nicht erreichbar, bitte überprüfen Sie die Netzwerkkonfiguration.",
|
||||
"unreachable_mqtt_broker": "Xiaomi MQTT Broker-Adresse ist nicht erreichbar, bitte überprüfen Sie die Netzwerkkonfiguration."
|
||||
},
|
||||
"abort": {
|
||||
"network_connect_error": "Konfiguration fehlgeschlagen. Netzwerkverbindung fehlgeschlagen. Überprüfen Sie die Netzwerkkonfiguration des Geräts.",
|
||||
@ -69,15 +111,17 @@
|
||||
},
|
||||
"config_options": {
|
||||
"title": "Konfigurationsoptionen",
|
||||
"description": "### Hallo {nick_name}!\r\n\r\nXiaomi Home-Konto-ID: {uid}\r\nAktuelles Anmeldegebiet: {cloud_server}\r\n\r\nWählen Sie die Optionen aus, die Sie erneut konfigurieren möchten, und klicken Sie dann auf \"Weiter\".",
|
||||
"description": "### Hallo {nick_name}!\r\n\r\nXiaomi Home-Konto-ID: {uid}\r\nAktuelles Anmeldegebiet: {cloud_server}\r\nIntegrationsinstanz-ID: {instance_id}\r\n\r\nWählen Sie die Optionen aus, die Sie erneut konfigurieren möchten, und klicken Sie dann auf \"Weiter\".",
|
||||
"data": {
|
||||
"integration_language": "Integrationsprache",
|
||||
"update_user_info": "Benutzerinformationen aktualisieren",
|
||||
"update_devices": "Geräteliste aktualisieren",
|
||||
"action_debug": "Action-Debug-Modus",
|
||||
"hide_non_standard_entities": "Verstecke Nicht-Standard-Entitäten",
|
||||
"update_trans_rules": "Entitätskonvertierungsregeln aktualisieren (globale konfiguration)",
|
||||
"update_lan_ctrl_config": "LAN-Steuerungskonfiguration aktualisieren (globale Konfiguration)"
|
||||
"display_devices_changed_notify": "Gerätestatusänderungen anzeigen",
|
||||
"update_trans_rules": "Entitätskonvertierungsregeln aktualisieren",
|
||||
"update_lan_ctrl_config": "LAN-Steuerungskonfiguration aktualisieren",
|
||||
"network_detect_config": "Integrierte Netzwerkkonfiguration"
|
||||
}
|
||||
},
|
||||
"update_user_info": {
|
||||
@ -87,12 +131,28 @@
|
||||
"nick_name": "Benutzername"
|
||||
}
|
||||
},
|
||||
"devices_filter": {
|
||||
"homes_select": {
|
||||
"title": "Familie und Geräte neu auswählen",
|
||||
"description": "## Gebrauchsanweisung\r\n### Steuerungsmodus\r\n- Automatisch: Wenn im lokalen Netzwerk ein verfügbarer Xiaomi-Zentralgateway vorhanden ist, wird Home Assistant bevorzugt Steuerbefehle über den Zentralgateway senden, um eine lokale Steuerung zu ermöglichen. Wenn im lokalen Netzwerk kein Zentralgateway vorhanden ist, wird versucht, Steuerbefehle über das Xiaomi-OT-Protokoll zu senden, um eine lokale Steuerung zu ermöglichen. Nur wenn die oben genannten Bedingungen für die lokale Steuerung nicht erfüllt sind, werden die Steuerbefehle über die Cloud gesendet.\r\n- Cloud: Steuerbefehle werden nur über die Cloud gesendet.\r\n### Familienimport für importierte Geräte\r\nDie Integration fügt Geräte aus den ausgewählten Familien hinzu.\r\n \r\n### Hallo {nick_name}! Bitte wählen Sie den Steuerungsmodus der Integration sowie die Familie aus, in der sich die hinzuzufügenden Geräte befinden.",
|
||||
"description": "## Gebrauchsanweisung\r\n### Familienimport für importierte Geräte\r\nDie Integration fügt Geräte aus den ausgewählten Familien hinzu.\r\n### Geräte filtern\r\nUnterstützt das Filtern von Geräten nach Raumnamen, Gerätezugriffstyp und Gerätemodell, und unterstützt auch das Filtern nach Gerätegröße. Es wurden **{local_count}** Geräte gefiltert.\r\n### Steuerungsmodus\r\n- Automatisch: Wenn im lokalen Netzwerk ein verfügbarer Xiaomi-Zentralgateway vorhanden ist, wird Home Assistant bevorzugt Steuerbefehle über den Zentralgateway senden, um eine lokale Steuerung zu ermöglichen. Wenn im lokalen Netzwerk kein Zentralgateway vorhanden ist, wird versucht, Steuerbefehle über das Xiaomi-OT-Protokoll zu senden, um eine lokale Steuerung zu ermöglichen. Nur wenn die oben genannten Bedingungen für die lokale Steuerung nicht erfüllt sind, werden die Steuerbefehle über die Cloud gesendet.\r\n- Cloud: Steuerbefehle werden nur über die Cloud gesendet.",
|
||||
"data": {
|
||||
"ctrl_mode": "Steuerungsmodus",
|
||||
"home_infos": "Familienimport für importierte Geräte"
|
||||
"home_infos": "Familienimport für importierte Geräte",
|
||||
"devices_filter": "Geräte filtern",
|
||||
"ctrl_mode": "Steuerungsmodus"
|
||||
}
|
||||
},
|
||||
"devices_filter": {
|
||||
"title": "Geräte filtern",
|
||||
"description": "## Gebrauchsanweisung\r\nUnterstützt das Filtern von Geräten nach Raumnamen, Gerätezugriffstyp und Gerätemodell, und unterstützt auch das Filtern nach Gerätegröße. Die Filterlogik ist wie folgt:\r\n- Zuerst wird gemäß der statistischen Logik die Vereinigung oder der Schnittpunkt aller eingeschlossenen Elemente ermittelt, dann der Schnittpunkt oder die Vereinigung der ausgeschlossenen Elemente, und schließlich wird das [eingeschlossene Gesamtergebnis] vom [ausgeschlossenen Gesamtergebnis] subtrahiert, um das [Filterergebnis] zu erhalten.\r\n- Wenn keine eingeschlossenen Elemente ausgewählt sind, bedeutet dies, dass alle eingeschlossen sind.\r\n### Filtermodus\r\n- Ausschließen: Unerwünschte Elemente entfernen.\r\n- Einschließen: Gewünschte Elemente einschließen.\r\n### Statistische Logik\r\n- UND-Logik: Den Schnittpunkt aller Elemente im gleichen Modus nehmen.\r\n- ODER-Logik: Die Vereinigung aller Elemente im gleichen Modus nehmen.\r\n\r\nSie können auch zur Seite [Konfiguration > Geräteliste aktualisieren] des Integrationselements gehen, [Geräte filtern] auswählen, um erneut zu filtern.",
|
||||
"data": {
|
||||
"room_filter_mode": "Familienraum filtern",
|
||||
"room_list": "Familienraum",
|
||||
"type_filter_mode": "Gerätetyp filtern",
|
||||
"type_list": "Gerätetyp",
|
||||
"model_filter_mode": "Gerätemodell filtern",
|
||||
"model_list": "Gerätemodell",
|
||||
"devices_filter_mode": "Geräte filtern",
|
||||
"device_list": "Geräteliste",
|
||||
"statistics_logic": "Statistiklogik"
|
||||
}
|
||||
},
|
||||
"update_trans_rules": {
|
||||
@ -110,9 +170,17 @@
|
||||
"enable_subscribe": "LAN-Abonnement aktivieren"
|
||||
}
|
||||
},
|
||||
"network_detect_config": {
|
||||
"title": "Integrierte Netzwerkkonfiguration",
|
||||
"description": "## Gebrauchsanweisung\r\n### Netzwerk-Erkennungsadresse\r\nWird verwendet, um zu überprüfen, ob das Netzwerk normal funktioniert. Wenn nicht festgelegt, wird die Standardadresse des Systems verwendet. Wenn die Standardadressprüfung fehlschlägt, können Sie versuchen, eine benutzerdefinierte Adresse einzugeben.\r\n- Sie können mehrere Erkennungsadressen eingeben, getrennt durch ein Komma, z. B. `8.8.8.8,https://www.bing.com`\r\n- Wenn es sich um eine IP-Adresse handelt, wird die Erkennung durch Ping durchgeführt. Wenn es sich um eine HTTP(s)-Adresse handelt, wird die Erkennung durch einen HTTP GET-Aufruf durchgeführt.\r\n- Wenn Sie die Standarderkennungsadresse des Systems wiederherstellen möchten, geben Sie ein Komma `,` ein und klicken Sie auf 'Weiter'.\r\n- **Diese Konfiguration ist global und Änderungen wirken sich auf andere Integrationsinstanzen aus. Bitte ändern Sie sie mit Vorsicht.**\r\n### Überprüfung der Netzwerkabhängigkeiten\r\nÜberprüfen Sie nacheinander, ob die folgenden Netzwerkabhängigkeiten zugänglich sind. Wenn die entsprechenden Adressen nicht zugänglich sind, führt dies zu Integrationsfehlern.\r\n- OAuth2-Authentifizierungsadresse: `https://account.xiaomi.com/oauth2/authorize`.\r\n- Xiaomi HTTP API-Adresse: `https://{http_host}/app/v2/ha/oauth/get_token`.\r\n- Xiaomi SPEC API-Adresse: `https://miot-spec.org/miot-spec-v2/template/list/device`.\r\n- Xiaomi MQTT Broker-Adresse: `mqtts://{cloud_server}-ha.mqtt.io.mi.com:8883`.",
|
||||
"data": {
|
||||
"network_detect_addr": "Netzwerkerkennungsadresse",
|
||||
"check_network_deps": "Überprüfung der Netzwerkabhängigkeiten"
|
||||
}
|
||||
},
|
||||
"config_confirm": {
|
||||
"title": "Bestätigen Sie die Konfiguration",
|
||||
"description": "**{nick_name}**, bitte bestätigen Sie die neuesten Konfigurationsinformationen und klicken Sie dann auf \"Senden\". Die Integration wird mit den aktualisierten Konfigurationen erneut geladen.\r\n\r\nIntegrationsprache:\t{lang_new}\r\nBenutzername:\t{nick_name_new}\r\nAction-Debug-Modus:\t{action_debug}\r\nVerstecke Nicht-Standard-Entitäten:\t{hide_non_standard_entities}\r\nGeräteänderungen:\t{devices_add} neue Geräte hinzufügen, {devices_remove} Geräte entfernen\r\nKonvertierungsregeländerungen:\tInsgesamt {trans_rules_count} Regeln, aktualisiert {trans_rules_count_success} Regeln",
|
||||
"description": "**{nick_name}**, bitte bestätigen Sie die neuesten Konfigurationsinformationen und klicken Sie dann auf \"Senden\". Die Integration wird mit den aktualisierten Konfigurationen erneut geladen.\r\n\r\nIntegrationsprache:\t{lang_new}\r\nBenutzername:\t{nick_name_new}\r\nAction-Debug-Modus:\t{action_debug}\r\nVerstecke Nicht-Standard-Entitäten:\t{hide_non_standard_entities}\r\nGerätestatusänderungen anzeigen:\t{display_devices_changed_notify}\r\nGeräteänderungen:\t{devices_add} neue Geräte hinzufügen, {devices_remove} Geräte entfernen\r\nKonvertierungsregeländerungen:\tInsgesamt {trans_rules_count} Regeln, aktualisiert {trans_rules_count_success} Regeln",
|
||||
"data": {
|
||||
"confirm": "Änderungen bestätigen"
|
||||
}
|
||||
@ -127,11 +195,20 @@
|
||||
"get_homeinfo_error": "Fehler beim Abrufen von Home-Informationen.",
|
||||
"get_cert_error": "Fehler beim Abrufen des Zentralzertifikats.",
|
||||
"no_family_selected": "Keine Familie ausgewählt.",
|
||||
"no_devices": "In der ausgewählten Familie sind keine Geräte vorhanden. Bitte wählen Sie eine Familie mit Geräten und fahren Sie dann fort.",
|
||||
"no_devices": "Im ausgewählten Haushalt sind keine Geräte vorhanden. Bitte wählen Sie einen Haushalt mit Geräten aus und fahren Sie fort.",
|
||||
"no_filter_devices": "Gefilterte Geräte sind leer. Bitte wählen Sie gültige Filterkriterien aus und fahren Sie fort.",
|
||||
"no_central_device": "Der Modus \"Zentral Gateway\" erfordert ein verfügbares Xiaomi-Zentral-Gateway im lokalen Netzwerk, in dem Home Assistant installiert ist. Überprüfen Sie, ob die ausgewählte Familie diese Anforderung erfüllt.",
|
||||
"mdns_discovery_error": "Lokaler Geräteerkennungsdienstfehler.",
|
||||
"update_config_error": "Fehler beim Aktualisieren der Konfigurationsinformationen.",
|
||||
"not_confirm": "Änderungen wurden nicht bestätigt. Bitte bestätigen Sie die Auswahl, bevor Sie sie einreichen."
|
||||
"not_confirm": "Änderungen wurden nicht bestätigt. Bitte bestätigen Sie die Auswahl, bevor Sie sie einreichen.",
|
||||
"invalid_network_addr": "Ungültige IP-Adresse oder HTTP-Adresse vorhanden, bitte geben Sie eine gültige Adresse ein.",
|
||||
"invalid_ip_addr": "Unzugängliche IP-Adresse vorhanden, bitte geben Sie eine gültige IP-Adresse ein.",
|
||||
"invalid_http_addr": "Unzugängliche HTTP-Adresse vorhanden, bitte geben Sie eine gültige HTTP-Adresse ein.",
|
||||
"invalid_default_addr": "Die Standard-Netzwerkerkennungsadresse ist nicht erreichbar, bitte überprüfen Sie die Netzwerkkonfiguration oder verwenden Sie eine benutzerdefinierte Netzwerkerkennungsadresse.",
|
||||
"unreachable_oauth2_host": "OAuth2-Authentifizierungsadresse ist nicht erreichbar, bitte überprüfen Sie die Netzwerkkonfiguration.",
|
||||
"unreachable_http_host": "Xiaomi HTTP API-Adresse ist nicht erreichbar, bitte überprüfen Sie die Netzwerkkonfiguration.",
|
||||
"unreachable_spec_host": "Xiaomi SPEC API-Adresse ist nicht erreichbar, bitte überprüfen Sie die Netzwerkkonfiguration.",
|
||||
"unreachable_mqtt_broker": "Xiaomi MQTT Broker-Adresse ist nicht erreichbar, bitte überprüfen Sie die Netzwerkkonfiguration."
|
||||
},
|
||||
"abort": {
|
||||
"network_connect_error": "Konfiguration fehlgeschlagen. Netzwerkverbindungsfehler. Überprüfen Sie die Netzwerkkonfiguration des Geräts.",
|
||||
|
@ -11,26 +11,59 @@
|
||||
},
|
||||
"auth_config": {
|
||||
"title": "Basic configuration",
|
||||
"description": "### Login Region\r\nSelect the region of your Xiaomi account. You can find it in the Xiaomi Home APP > Profile (located in the menu at the bottom) > Additional settings > About Xiaomi Home.\r\n### Language\r\nSelect the language of the device and entity names. Some sentences without translation will be displayed in English.\r\n### OAuth2 Redirect URL\r\nThe OAuth2 authentication redirect address is **[http://homeassistant.local:8123](http://homeassistant.local:8123)**. The Home Assistant needs to be in the same local area network as the current operating terminal (e.g., the personal computer) and the operating terminal can access the Home Assistant home page through this address. Otherwise, the login authentication may fail.\r\n### Note\r\n- For users with hundreds or more Mi Home devices, the initial addition of the integration will take some time. Please be patient.\r\n- If Home Assistant is running in a Docker environment, please ensure that the Docker network mode is set to host, otherwise local control functionality may not work properly.\r\n- The local control functionality of the integration has some dependencies. Please read the README carefully.",
|
||||
"description": "### Login Region\r\nSelect the region of your Xiaomi account. You can find it in the Xiaomi Home APP > Profile (located in the menu at the bottom) > Additional settings > About Xiaomi Home.\r\n### Language\r\nSelect the language of the device and entity names. Some sentences without translation will be displayed in English.\r\n### OAuth2 Redirect URL\r\nThe OAuth2 authentication redirect address is **[http://homeassistant.local:8123](http://homeassistant.local:8123)**. The Home Assistant needs to be in the same local area network as the current operating terminal (e.g., the personal computer) and the operating terminal can access the Home Assistant home page through this address. Otherwise, the login authentication may fail.\r\n### Integrated Network Configuration\r\nCheck if the local network is functioning properly and if the related network resources are accessible. **It is recommended to select this when adding for the first time.**\r\n### Note\r\n- For users with hundreds or more Mi Home devices, the initial addition of the integration will take some time. Please be patient.\r\n- If Home Assistant is running in a Docker environment, please ensure that the Docker network mode is set to host, otherwise local control functionality may not work properly.\r\n- The local control functionality of the integration has some dependencies. Please read the README carefully.",
|
||||
"data": {
|
||||
"cloud_server": "Login Region",
|
||||
"integration_language": "Language",
|
||||
"oauth_redirect_url": "OAuth2 Redirect URL"
|
||||
"oauth_redirect_url": "OAuth2 Redirect URL",
|
||||
"network_detect_config": "Integrated Network Configuration"
|
||||
}
|
||||
},
|
||||
"network_detect_config": {
|
||||
"title": "Integrated Network Configuration",
|
||||
"description": "## Usage Introduction\r\n### Network Detection Address\r\nUsed to check if the network is functioning properly. If not set, the system default address will be used. If the default address check fails, you can try entering a custom address.\r\n- You can enter multiple detection addresses, separated by commas, such as `8.8.8.8,https://www.bing.com`\r\n- If it is an IP address, detection will be done via ping. If it is an HTTP(s) address, detection will be done via HTTP GET request.\r\n- If you want to restore the system default detection address, please enter a comma `,` and click 'Next'.\r\n- **This configuration is global, and changes will affect other integration instances. Please modify with caution.**\r\n### Check Network Dependencies\r\nCheck the following network dependencies one by one to see if they are accessible. If the related addresses are not accessible, it will cause integration issues.\r\n- OAuth2 Authentication Address: `https://account.xiaomi.com/oauth2/authorize`.\r\n- Xiaomi HTTP API Address: `https://{http_host}/app/v2/ha/oauth/get_token`.\r\n- Xiaomi SPEC API Address: `https://miot-spec.org/miot-spec-v2/template/list/device`.\r\n- Xiaomi MQTT Broker Address: `mqtts://{cloud_server}-ha.mqtt.io.mi.com:8883`.",
|
||||
"data": {
|
||||
"network_detect_addr": "Network Detection Address",
|
||||
"check_network_deps": "Check Network Dependencies"
|
||||
}
|
||||
},
|
||||
"oauth_error": {
|
||||
"title": "Login Error",
|
||||
"description": "Click NEXT to try again."
|
||||
},
|
||||
"devices_filter": {
|
||||
"title": "Select Home and Devices",
|
||||
"description": "## Usage Instructions\r\n### Control mode\r\n- Auto: When there is an available Xiaomi central hub gateway in the local area network, Home Assistant will prioritize sending device control commands through the central hub gateway to achieve local control. If there is no central hub gateway in the local area network, it will attempt to send control commands through Xiaomi LAN control function. Only when the above local control conditions are not met, the device control commands will be sent through the cloud.\r\n- Cloud: All control commands are sent through the cloud.\r\n### Import devices from home\r\nThe integration will add devices from the selected homes.\n### Room name synchronizing mode\nWhen importing devices from Xiaomi Home APP to Home Assistant, the naming convention of the area where the device is added to is as follows. Note that the device synchronizing process does not change the home or room settings in Xiaomi Home APP.\r\n- Do not synchronize: The device will not be added to any area.\r\n- Other options: The device will be added to an area named as the home and/or room name that already exists in Xiaomi Home APP.\r\n### Debug mode for action\r\nFor the action defined in MIoT-Spec-V2 of the device, a Text entity along with a Notify entity will be created, in which you can send control commands to the device for debugging.\r\n### Hide non-standard created entities\r\nHide the entities generated from non-standard MIoT-Spec-V2 instances, whose names begin with \"*\".\r\n\r\n \r\n### Hello {nick_name}, please select the integration control mode and the home where the device you want to import.",
|
||||
"homes_select": {
|
||||
"title": "Select Family and Device",
|
||||
"description": "## Introduction\r\n### Import Device's Family\r\nThe integration will add devices from the selected family.\r\n### Room Name Sync Mode\r\nWhen syncing devices from the Mi Home APP to Home Assistant, the naming of the area in Home Assistant will follow the rules below. Note that the sync process will not change the family and room settings in the Mi Home APP.\r\n- Do not sync: The device will not be added to any area.\r\n- Other options: The area to which the device is added will be named after the family or room name in the Mi Home APP.\r\n### Advanced Settings\r\nShow advanced settings to modify the professional configuration options of the integration.\r\n\r\n \r\n### {nick_name} Hello! Please select the family to which you want to add the device.",
|
||||
"data": {
|
||||
"ctrl_mode": "Control mode",
|
||||
"home_infos": "Import devices from home",
|
||||
"area_name_rule": "Room name synchronizing mode",
|
||||
"action_debug": "Debug mode for action",
|
||||
"hide_non_standard_entities": "Hide non-standard created entities"
|
||||
"home_infos": "Import Device's Family",
|
||||
"area_name_rule": "Room Name Sync Mode",
|
||||
"advanced_options": "Advanced Settings"
|
||||
}
|
||||
},
|
||||
"advanced_options": {
|
||||
"title": "Advanced Settings",
|
||||
"description": "## Introduction\r\n### Unless you are very clear about the meaning of the following options, please keep the default settings.\r\n### Filter Devices\r\nSupports filtering devices by room name and device type, and also supports device dimension filtering.\r\n### Control Mode\r\n- Auto: When there is an available Xiaomi central hub gateway in the local area network, Home Assistant will prioritize sending device control commands through the central hub gateway to achieve local control. If there is no central hub gateway in the local area network, it will attempt to send control commands through Xiaomi OT protocol to achieve local control. Only when the above local control conditions are not met, the device control commands will be sent through the cloud.\r\n- Cloud: All control commands are sent through the cloud.\r\n### Action Debug Mode\r\nFor the methods defined by the device MIoT-Spec-V2, in addition to generating notification entities, a text input box entity will also be generated. You can use it to send control commands to the device during debugging.\r\n### Hide Non-Standard Generated Entities\r\nHide entities generated by non-standard MIoT-Spec-V2 instances with names starting with \"*\".\r\n### Display Device Status Change Notifications\r\nDisplay detailed device status change notifications, only showing the selected notifications.",
|
||||
"data": {
|
||||
"devices_filter": "Filter Devices",
|
||||
"ctrl_mode": "Control Mode",
|
||||
"action_debug": "Action Debug Mode",
|
||||
"hide_non_standard_entities": "Hide Non-Standard Generated Entities",
|
||||
"display_devices_changed_notify": "Display Device Status Change Notifications"
|
||||
}
|
||||
},
|
||||
"devices_filter": {
|
||||
"title": "Filter Devices",
|
||||
"description": "## Usage Instructions\r\nSupports filtering devices by home room name, device access type, and device model, and also supports device dimension filtering. The filtering logic is as follows:\r\n- First, according to the statistical logic, get the union or intersection of all included items, then get the intersection or union of the excluded items, and finally subtract the [included summary result] from the [excluded summary result] to get the [filter result].\r\n- If no included items are selected, it means all are included.\r\n### Filter Mode\r\n- Exclude: Remove unwanted items.\r\n- Include: Include desired items.\r\n### Statistical Logic\r\n- AND logic: Take the intersection of all items in the same mode.\r\n- OR logic: Take the union of all items in the same mode.\r\n\r\nYou can also go to the [Configuration > Update Device List] page of the integration item, check [Filter Devices] to re-filter.",
|
||||
"data": {
|
||||
"room_filter_mode": "Filter Family Rooms",
|
||||
"room_list": "Family Rooms",
|
||||
"type_filter_mode": "Filter Device Connect Type",
|
||||
"type_list": "Device Connect Type",
|
||||
"model_filter_mode": "Filter Device Model",
|
||||
"model_list": "Device Model",
|
||||
"devices_filter_mode": "Filter Devices",
|
||||
"device_list": "Device List",
|
||||
"statistics_logic": "Statistics Logic"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -44,8 +77,17 @@
|
||||
"mdns_discovery_error": "Local device discovery service exception.",
|
||||
"get_cert_error": "Failed to retrieve the central hub gateway certificate.",
|
||||
"no_family_selected": "No home selected.",
|
||||
"no_devices": "The selected home does not have any devices. Please choose a home containing devices and continue.",
|
||||
"no_central_device": "[Central Hub Gateway Mode] requires a Xiaomi central hub gateway available in the local network where Home Assistant exists. Please check if the selected home meets the requirement."
|
||||
"no_devices": "There are no devices in the selected home. Please select a home with devices and continue.",
|
||||
"no_filter_devices": "Filtered devices are empty. Please select valid filter criteria and continue.",
|
||||
"no_central_device": "[Central Hub Gateway Mode] requires a Xiaomi central hub gateway available in the local network where Home Assistant exists. Please check if the selected home meets the requirement.",
|
||||
"invalid_network_addr": "Invalid IP address or HTTP address detected, please enter a valid address.",
|
||||
"invalid_ip_addr": "Unreachable IP address detected, please enter a valid IP address.",
|
||||
"invalid_http_addr": "Unreachable HTTP address detected, please enter a valid HTTP address.",
|
||||
"invalid_default_addr": "Default network detection address is unreachable, please check network configuration or use a custom network detection address.",
|
||||
"unreachable_oauth2_host": "Unable to reach OAuth2 authentication address, please check network configuration.",
|
||||
"unreachable_http_host": "Unable to reach Xiaomi HTTP API address, please check network configuration.",
|
||||
"unreachable_spec_host": "Unable to reach Xiaomi SPEC API address, please check network configuration.",
|
||||
"unreachable_mqtt_broker": "Unable to reach Xiaomi MQTT Broker address, please check network configuration."
|
||||
},
|
||||
"abort": {
|
||||
"network_connect_error": "Configuration failed. The network connection is abnormal. Please check the equipment network configuration.",
|
||||
@ -69,15 +111,17 @@
|
||||
},
|
||||
"config_options": {
|
||||
"title": "Configuration Options",
|
||||
"description": "### Hello, {nick_name}\r\n\r\nXiaomi ID: {uid}\r\nCurrent Login Region: {cloud_server}\r\n\r\nPlease select the options you need to configure, then click NEXT.",
|
||||
"description": "### Hello, {nick_name}\r\n\r\nXiaomi ID: {uid}\r\nCurrent Login Region: {cloud_server}\r\nIntegration Instance ID: {instance_id}\r\n\r\nPlease select the options you need to configure, then click NEXT.",
|
||||
"data": {
|
||||
"integration_language": "Integration Language",
|
||||
"update_user_info": "Update user information",
|
||||
"update_devices": "Update device list",
|
||||
"action_debug": "Debug mode for action",
|
||||
"hide_non_standard_entities": "Hide non-standard created entities",
|
||||
"display_devices_changed_notify": "Display device status change notifications",
|
||||
"update_trans_rules": "Update entity conversion rules",
|
||||
"update_lan_ctrl_config": "Update LAN control configuration"
|
||||
"update_lan_ctrl_config": "Update LAN control configuration",
|
||||
"network_detect_config": "Integrated Network Configuration"
|
||||
}
|
||||
},
|
||||
"update_user_info": {
|
||||
@ -87,12 +131,28 @@
|
||||
"nick_name": "Nick Name"
|
||||
}
|
||||
},
|
||||
"devices_filter": {
|
||||
"homes_select": {
|
||||
"title": "Re-select Home and Devices",
|
||||
"description": "## Usage Instructions\r\n### Control mode\r\n- Auto: When there is an available Xiaomi central hub gateway in the local area network, Home Assistant will prioritize sending device control commands through the central hub gateway to achieve local control. If there is no central hub gateway in the local area network, it will attempt to send control commands through Xiaomi LAN control function. Only when the above local control conditions are not met, the device control commands will be sent through the cloud.\r\n- Cloud: All control commands are sent through the cloud.\r\n### Import devices from home\r\nThe integration will add devices from the selected homes.\r\n \r\n### Hello {nick_name}, please select the integration control mode and the home where the device you want to import.",
|
||||
"description": "## Usage Instructions\r\n### Import devices from home\r\nThe integration will add devices from the selected homes.\r\n### Filter Devices\r\nSupports filtering devices by home room name, device access type, and device model, and also supports device dimension filtering. **{local_count}** devices have been filtered.\r\n### Control mode\r\n- Auto: When there is an available Xiaomi central hub gateway in the local area network, Home Assistant will prioritize sending device control commands through the central hub gateway to achieve local control. If there is no central hub gateway in the local area network, it will attempt to send control commands through Xiaomi LAN control function. Only when the above local control conditions are not met, the device control commands will be sent through the cloud.\r\n- Cloud: All control commands are sent through the cloud.",
|
||||
"data": {
|
||||
"ctrl_mode": "Control mode",
|
||||
"home_infos": "Import devices from home"
|
||||
"home_infos": "Import devices from home",
|
||||
"devices_filter": "Filter devices",
|
||||
"ctrl_mode": "Control mode"
|
||||
}
|
||||
},
|
||||
"devices_filter": {
|
||||
"title": "Filter Devices",
|
||||
"description": "## Usage Instructions\r\nSupports filtering devices by home room name, device access type, and device model, and also supports device dimension filtering. The filtering logic is as follows:\r\n- First, according to the statistical logic, get the union or intersection of all included items, then get the intersection or union of the excluded items, and finally subtract the [included summary result] from the [excluded summary result] to get the [filter result].\r\n- If no included items are selected, it means all are included.\r\n### Filter Mode\r\n- Exclude: Remove unwanted items.\r\n- Include: Include desired items.\r\n### Statistical Logic\r\n- AND logic: Take the intersection of all items in the same mode.\r\n- OR logic: Take the union of all items in the same mode.\r\n\r\nYou can also go to the [Configuration > Update Device List] page of the integration item, check [Filter Devices] to re-filter.",
|
||||
"data": {
|
||||
"room_filter_mode": "Filter Family Rooms",
|
||||
"room_list": "Family Rooms",
|
||||
"type_filter_mode": "Filter Device Connect Type",
|
||||
"type_list": "Device Connect Type",
|
||||
"model_filter_mode": "Filter Device Model",
|
||||
"model_list": "Device Model",
|
||||
"devices_filter_mode": "Filter Devices",
|
||||
"device_list": "Device List",
|
||||
"statistics_logic": "Statistics Logic"
|
||||
}
|
||||
},
|
||||
"update_trans_rules": {
|
||||
@ -110,9 +170,17 @@
|
||||
"enable_subscribe": "Enable LAN subscription"
|
||||
}
|
||||
},
|
||||
"network_detect_config": {
|
||||
"title": "Integrated Network Configuration",
|
||||
"description": "## Usage Introduction\r\n### Network Detection Address\r\nUsed to check if the network is functioning properly. If not set, the system default address will be used. If the default address check fails, you can try entering a custom address.\r\n- You can enter multiple detection addresses, separated by commas, such as `8.8.8.8,https://www.bing.com`\r\n- If it is an IP address, detection will be done via ping. If it is an HTTP(s) address, detection will be done via HTTP GET request.\r\n- If you want to restore the system default detection address, please enter a comma `,` and click 'Next'.\r\n- **This configuration is global, and changes will affect other integration instances. Please modify with caution.**\r\n### Check Network Dependencies\r\nCheck the following network dependencies one by one to see if they are accessible. If the related addresses are not accessible, it will cause integration issues.\r\n- OAuth2 Authentication Address: `https://account.xiaomi.com/oauth2/authorize`.\r\n- Xiaomi HTTP API Address: `https://{http_host}/app/v2/ha/oauth/get_token`.\r\n- Xiaomi SPEC API Address: `https://miot-spec.org/miot-spec-v2/template/list/device`.\r\n- Xiaomi MQTT Broker Address: `mqtts://{cloud_server}-ha.mqtt.io.mi.com:8883`.",
|
||||
"data": {
|
||||
"network_detect_addr": "Network Detection Address",
|
||||
"check_network_deps": "Check Network Dependencies"
|
||||
}
|
||||
},
|
||||
"config_confirm": {
|
||||
"title": "Confirm Configuration",
|
||||
"description": "Hello **{nick_name}**, please confirm the latest configuration information and then Click SUBMIT.\r\nThe integration will reload using the updated configuration.\r\n\r\nIntegration Language: \t{lang_new}\r\nNickname: \t{nick_name_new}\r\nDebug mode for action: \t{action_debug}\r\nHide non-standard created entities: \t{hide_non_standard_entities}\r\nDevice Changes: \tAdd **{devices_add}** devices, Remove **{devices_remove}** devices\r\nTransformation rules change: \tThere are a total of **{trans_rules_count}** rules, and updated **{trans_rules_count_success}** rules",
|
||||
"description": "Hello **{nick_name}**, please confirm the latest configuration information and then Click SUBMIT.\r\nThe integration will reload using the updated configuration.\r\n\r\nIntegration Language: \t{lang_new}\r\nNickname: \t{nick_name_new}\r\nDebug mode for action: \t{action_debug}\r\nHide non-standard created entities: \t{hide_non_standard_entities}\r\nDisplay device status change notifications:\t{display_devices_changed_notify}\r\nDevice Changes: \tAdd **{devices_add}** devices, Remove **{devices_remove}** devices\r\nTransformation rules change: \tThere are a total of **{trans_rules_count}** rules, and updated **{trans_rules_count_success}** rules",
|
||||
"data": {
|
||||
"confirm": "Confirm the change"
|
||||
}
|
||||
@ -126,12 +194,21 @@
|
||||
"get_token_error": "Failed to retrieve login authorization information (OAuth token).",
|
||||
"get_homeinfo_error": "Failed to retrieve home information.",
|
||||
"get_cert_error": "Failed to retrieve the central hub gateway certificate.",
|
||||
"no_devices": "The selected home does not have any devices. Please choose a home containing devices and continue.",
|
||||
"no_devices": "There are no devices in the selected home. Please select a home with devices and continue.",
|
||||
"no_filter_devices": "Filtered devices are empty. Please select valid filter criteria and continue.",
|
||||
"no_family_selected": "No home selected.",
|
||||
"no_central_device": "[Central Hub Gateway Mode] requires a Xiaomi central hub gateway available in the local network where Home Assistant exists. Please check if the selected home meets the requirement.",
|
||||
"mdns_discovery_error": "Local device discovery service exception.",
|
||||
"update_config_error": "Failed to update configuration information.",
|
||||
"not_confirm": "Changes are not confirmed. Please confirm the change before submitting."
|
||||
"not_confirm": "Changes are not confirmed. Please confirm the change before submitting.",
|
||||
"invalid_network_addr": "Invalid IP address or HTTP address detected, please enter a valid address.",
|
||||
"invalid_ip_addr": "Unreachable IP address detected, please enter a valid IP address.",
|
||||
"invalid_http_addr": "Unreachable HTTP address detected, please enter a valid HTTP address.",
|
||||
"invalid_default_addr": "Default network detection address is unreachable, please check network configuration or use a custom network detection address.",
|
||||
"unreachable_oauth2_host": "Unable to reach OAuth2 authentication address, please check network configuration.",
|
||||
"unreachable_http_host": "Unable to reach Xiaomi HTTP API address, please check network configuration.",
|
||||
"unreachable_spec_host": "Unable to reach Xiaomi SPEC API address, please check network configuration.",
|
||||
"unreachable_mqtt_broker": "Unable to reach Xiaomi MQTT Broker address, please check network configuration."
|
||||
},
|
||||
"abort": {
|
||||
"network_connect_error": "Configuration failed. The network connection is abnormal. Please check the equipment network configuration.",
|
||||
|
@ -11,26 +11,59 @@
|
||||
},
|
||||
"auth_config": {
|
||||
"title": "Configuración básica",
|
||||
"description": "### Región de inicio de sesión\r\nSeleccione la región donde se encuentra su cuenta de Xiaomi. Puede consultar esta información en `Xiaomi Home APP > Yo (ubicado en el menú inferior) > Más ajustes > Acerca de Xiaomi Home`.\r\n### Idioma\r\nSeleccione el idioma utilizado para los nombres de los dispositivos y entidades. Las partes de las frases que no están traducidas se mostrarán en inglés.\r\n### Dirección de redireccionamiento de autenticación de OAuth2\r\nLa dirección de redireccionamiento de autenticación de OAuth2 es **[http://homeassistant.local:8123](http://homeassistant.local:8123)**. Home Assistant debe estar en la misma red local que el terminal de operación actual (por ejemplo, una computadora personal) y el terminal de operación debe poder acceder a la página de inicio de Home Assistant a través de esta dirección, de lo contrario, la autenticación de inicio de sesión podría fallar.\r\n### Nota\r\n- Para los usuarios con cientos o más dispositivos Mi Home, la adición inicial de la integración tomará algún tiempo. Por favor, sea paciente.\r\n- Si Home Assistant se está ejecutando en un entorno Docker, asegúrese de que el modo de red de Docker esté configurado en host, de lo contrario, la funcionalidad de control local puede no funcionar correctamente.\r\n- La funcionalidad de control local de la integración tiene algunas dependencias. Por favor, lea el README cuidadosamente.",
|
||||
"description": "### Región de inicio de sesión\r\nSeleccione la región donde se encuentra su cuenta de Xiaomi. Puede consultar esta información en `Xiaomi Home APP > Yo (ubicado en el menú inferior) > Más ajustes > Acerca de Xiaomi Home`.\r\n### Idioma\r\nSeleccione el idioma utilizado para los nombres de los dispositivos y entidades. Las partes de las frases que no están traducidas se mostrarán en inglés.\r\n### Dirección de redireccionamiento de autenticación de OAuth2\r\nLa dirección de redireccionamiento de autenticación de OAuth2 es **[http://homeassistant.local:8123](http://homeassistant.local:8123)**. Home Assistant debe estar en la misma red local que el terminal de operación actual (por ejemplo, una computadora personal) y el terminal de operación debe poder acceder a la página de inicio de Home Assistant a través de esta dirección, de lo contrario, la autenticación de inicio de sesión podría fallar.\r\n### Configuración de Red Integrada\r\nVerifique si la red local funciona correctamente y si los recursos de red relacionados son accesibles. **Se recomienda seleccionar esto al agregar por primera vez.**\r\n### Nota\r\n- Para los usuarios con cientos o más dispositivos Mi Home, la adición inicial de la integración tomará algún tiempo. Por favor, sea paciente.\r\n- Si Home Assistant se está ejecutando en un entorno Docker, asegúrese de que el modo de red de Docker esté configurado en host, de lo contrario, la funcionalidad de control local puede no funcionar correctamente.\r\n- La funcionalidad de control local de la integración tiene algunas dependencias. Por favor, lea el README cuidadosamente.",
|
||||
"data": {
|
||||
"cloud_server": "Región de inicio de sesión",
|
||||
"integration_language": "Idioma",
|
||||
"oauth_redirect_url": "Dirección de redireccionamiento de autenticación de OAuth2"
|
||||
"oauth_redirect_url": "Dirección de redireccionamiento de autenticación de OAuth2",
|
||||
"network_detect_config": "Configuración de Red Integrada"
|
||||
}
|
||||
},
|
||||
"network_detect_config": {
|
||||
"title": "Configuración de Red Integrada",
|
||||
"description": "## Introducción al Uso\r\n### Dirección de Detección de Red\r\nSe utiliza para verificar si la red funciona correctamente. Si no se establece, se utilizará la dirección predeterminada del sistema. Si la verificación de la dirección predeterminada falla, puede intentar ingresar una dirección personalizada.\r\n- Puede ingresar varias direcciones de detección, separadas por comas, como `8.8.8.8,https://www.bing.com`\r\n- Si es una dirección IP, la detección se realizará mediante ping. Si es una dirección HTTP(s), la detección se realizará mediante una solicitud HTTP GET.\r\n- Si desea restaurar la dirección de detección predeterminada del sistema, ingrese una coma `,` y haga clic en 'Siguiente'.\r\n- **Esta configuración es global y los cambios afectarán a otras instancias de integración. Modifique con precaución.**\r\n### Verificar Dependencias de Red\r\nVerifique una por una las siguientes dependencias de red para ver si son accesibles. Si las direcciones relacionadas no son accesibles, causará problemas de integración.\r\n- Dirección de Autenticación OAuth2: `https://account.xiaomi.com/oauth2/authorize`.\r\n- Dirección de API HTTP de Xiaomi: `https://{http_host}/app/v2/ha/oauth/get_token`.\r\n- Dirección de API SPEC de Xiaomi: `https://miot-spec.org/miot-spec-v2/template/list/device`.\r\n- Dirección del Broker MQTT de Xiaomi: `mqtts://{cloud_server}-ha.mqtt.io.mi.com:8883`.",
|
||||
"data": {
|
||||
"network_detect_addr": "Dirección de Detección de Red",
|
||||
"check_network_deps": "Verificar Dependencias de Red"
|
||||
}
|
||||
},
|
||||
"oauth_error": {
|
||||
"title": "Error de inicio de sesión",
|
||||
"description": "Haga clic en \"Siguiente\" para volver a intentarlo"
|
||||
},
|
||||
"devices_filter": {
|
||||
"title": "Seleccionar hogares y dispositivos",
|
||||
"description": "## Instrucciones de uso\r\n### Modo de control\r\n- Automático: Cuando hay un gateway central de Xiaomi disponible en la red local, Home Assistant priorizará el envío de comandos de control de dispositivos a través del gateway central para lograr un control localizado. Si no hay un gateway central en la red local, intentará enviar comandos de control a través del protocolo Xiaomi OT para lograr un control localizado. Solo cuando no se cumplan las condiciones anteriores de control localizado, los comandos de control del dispositivo se enviarán a través de la nube.\r\n- Nube: Los comandos de control solo se envían a través de la nube.\r\n### Hogares de dispositivos importados\r\nLa integración agregará los dispositivos en los hogares seleccionados.\r\n### Modo de sincronización del nombre de la habitación\r\nCuando se sincronizan los dispositivos desde la aplicación Xiaomi Home a Home Assistant, los nombres de las áreas donde se encuentran los dispositivos en Home Assistant seguirán las reglas de nomenclatura a continuación. Tenga en cuenta que el proceso de sincronización de dispositivos no cambiará la configuración de hogares y habitaciones en la aplicación Xiaomi Home.\r\n- Sin sincronización: el dispositivo no se agregará a ninguna área.\r\n- Otras opciones: la zona donde se agrega el dispositivo tendrá el mismo nombre que el hogar o la habitación en la aplicación Xiaomi Home.\r\n### Modo de depuración de Action\r\nPara los métodos definidos por MIoT-Spec-V2, además de generar una entidad de notificación, también se generará una entidad de cuadro de entrada de texto que se puede utilizar para enviar comandos de control al dispositivo durante la depuración.\r\n### Ocultar entidades generadas no estándar\r\nOcultar las entidades generadas por la instancia no estándar MIoT-Spec-V2 que comienzan con \"*\".\r\n\r\n \r\n### ¡Hola, {nick_name}! Seleccione el modo de control de integración y el hogar donde se encuentran los dispositivos que desea agregar.",
|
||||
"homes_select": {
|
||||
"title": "Seleccionar familia y dispositivo",
|
||||
"description": "## Introducción\r\n### Importar la familia del dispositivo\r\nLa integración añadirá dispositivos de la familia seleccionada.\r\n### Modo de sincronización del nombre de la habitación\r\nAl sincronizar dispositivos desde la APP Mi Home a Home Assistant, el nombre del área en Home Assistant seguirá las siguientes reglas. Tenga en cuenta que el proceso de sincronización no cambiará la configuración de la familia y la habitación en la APP Mi Home.\r\n- No sincronizar: El dispositivo no se añadirá a ninguna área.\r\n- Otras opciones: El área a la que se añade el dispositivo se nombrará según el nombre de la familia o la habitación en la APP Mi Home.\r\n### Configuración avanzada\r\nMostrar configuración avanzada para modificar las opciones de configuración profesional de la integración.\r\n\r\n \r\n### {nick_name} ¡Hola! Por favor, seleccione la familia a la que desea añadir el dispositivo.",
|
||||
"data": {
|
||||
"ctrl_mode": "Modo de control",
|
||||
"home_infos": "Hogares de dispositivos importados",
|
||||
"home_infos": "Importar la familia del dispositivo",
|
||||
"area_name_rule": "Modo de sincronización del nombre de la habitación",
|
||||
"action_debug": "Modo de depuración de Action",
|
||||
"hide_non_standard_entities": "Ocultar entidades generadas no estándar"
|
||||
"advanced_options": "Configuración avanzada"
|
||||
}
|
||||
},
|
||||
"advanced_options": {
|
||||
"title": "Opciones Avanzadas",
|
||||
"description": "## Introducción\r\n### A menos que entienda claramente el significado de las siguientes opciones, manténgalas en su configuración predeterminada.\r\n### Filtrar dispositivos\r\nAdmite la filtración de dispositivos por nombre de habitación y tipo de dispositivo, y también admite la filtración por familia.\r\n### Modo de Control\r\n- Automático: Cuando hay una puerta de enlace central de Xiaomi disponible en la red local, Home Assistant enviará comandos de control de dispositivos a través de la puerta de enlace central para lograr la función de control local. Cuando no hay una puerta de enlace central en la red local, intentará enviar comandos de control a través del protocolo OT de Xiaomi para lograr la función de control local. Solo cuando no se cumplan las condiciones de control local anteriores, los comandos de control de dispositivos se enviarán a través de la nube.\r\n- Nube: Los comandos de control solo se envían a través de la nube.\r\n### Modo de Depuración de Acciones\r\nPara los métodos definidos por el dispositivo MIoT-Spec-V2, además de generar una entidad de notificación, también se generará una entidad de cuadro de texto que se puede utilizar para enviar comandos de control al dispositivo durante la depuración.\r\n### Ocultar Entidades Generadas No Estándar\r\nOcultar entidades generadas por instancias MIoT-Spec-V2 no estándar que comienzan con \"*\".\r\n### Mostrar notificaciones de cambio de estado del dispositivo\r\nMostrar notificaciones detalladas de cambio de estado del dispositivo, mostrando solo las notificaciones seleccionadas.",
|
||||
"data": {
|
||||
"devices_filter": "Filtrar Dispositivos",
|
||||
"ctrl_mode": "Modo de Control",
|
||||
"action_debug": "Modo de Depuración de Acciones",
|
||||
"hide_non_standard_entities": "Ocultar Entidades Generadas No Estándar",
|
||||
"display_devices_changed_notify": "Mostrar notificaciones de cambio de estado del dispositivo"
|
||||
}
|
||||
},
|
||||
"devices_filter": {
|
||||
"title": "Filtrar Dispositivos",
|
||||
"description": "## Instrucciones de uso\r\nAdmite la filtración de dispositivos por nombre de habitación, tipo de acceso del dispositivo y modelo de dispositivo, y también admite la filtración por dimensión del dispositivo. La lógica de filtración es la siguiente:\r\n- Primero, de acuerdo con la lógica estadística, obtenga la unión o intersección de todos los elementos incluidos, luego obtenga la intersección o unión de los elementos excluidos, y finalmente reste el [resultado del resumen incluido] del [resultado del resumen excluido] para obtener el [resultado del filtro].\r\n- Si no se seleccionan elementos incluidos, significa que todos están incluidos.\r\n### Modo de Filtración\r\n- Excluir: Eliminar elementos no deseados.\r\n- Incluir: Incluir elementos deseados.\r\n### Lógica Estadística\r\n- Lógica Y: Tomar la intersección de todos los elementos en el mismo modo.\r\n- Lógica O: Tomar la unión de todos los elementos en el mismo modo.\r\n\r\nTambién puede ir a la página [Configuración > Actualizar lista de dispositivos] del elemento de integración, marcar [Filtrar dispositivos] para volver a filtrar.",
|
||||
"data": {
|
||||
"room_filter_mode": "Filtrar Habitaciones de la Familia",
|
||||
"room_list": "Habitaciones de la Familia",
|
||||
"type_filter_mode": "Filtrar Tipo de Dispositivo",
|
||||
"type_list": "Tipo de Dispositivo",
|
||||
"model_filter_mode": "Filtrar Modelo de Dispositivo",
|
||||
"model_list": "Modelo de Dispositivo",
|
||||
"devices_filter_mode": "Filtrar Dispositivos",
|
||||
"device_list": "Lista de Dispositivos",
|
||||
"statistics_logic": "Lógica de Estadísticas"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -44,8 +77,17 @@
|
||||
"mdns_discovery_error": "Error en el servicio de descubrimiento de dispositivos locales.",
|
||||
"get_cert_error": "Error al obtener el certificado de la puerta de enlace.",
|
||||
"no_family_selected": "No se ha seleccionado ningún hogar.",
|
||||
"no_devices": "No hay dispositivos en el hogar seleccionado. Seleccione un hogar con dispositivos y continúe.",
|
||||
"no_central_device": "【Modo de puerta de enlace central】Se requiere una puerta de enlace Xiaomi disponible en la red local donde se encuentra Home Assistant. Verifique si el hogar seleccionado cumple con este requisito."
|
||||
"no_devices": "No hay dispositivos en el hogar seleccionado. Por favor, seleccione un hogar con dispositivos y continúe.",
|
||||
"no_filter_devices": "Los dispositivos filtrados están vacíos. Por favor, seleccione criterios de filtro válidos y continúe.",
|
||||
"no_central_device": "【Modo de puerta de enlace central】Se requiere una puerta de enlace Xiaomi disponible en la red local donde se encuentra Home Assistant. Verifique si el hogar seleccionado cumple con este requisito.",
|
||||
"invalid_network_addr": "Se detectó una dirección IP o HTTP no válida, por favor ingrese una dirección válida.",
|
||||
"invalid_ip_addr": "Se detectó una dirección IP inaccesible, por favor ingrese una dirección IP válida.",
|
||||
"invalid_http_addr": "Se detectó una dirección HTTP inaccesible, por favor ingrese una dirección HTTP válida.",
|
||||
"invalid_default_addr": "La dirección de detección de red predeterminada no es accesible, por favor verifique la configuración de la red o use una dirección de detección de red personalizada.",
|
||||
"unreachable_oauth2_host": "No se puede acceder a la dirección de autenticación OAuth2, por favor verifique la configuración de la red.",
|
||||
"unreachable_http_host": "No se puede acceder a la dirección de la API HTTP de Xiaomi, por favor verifique la configuración de la red.",
|
||||
"unreachable_spec_host": "No se puede acceder a la dirección de la API SPEC de Xiaomi, por favor verifique la configuración de la red.",
|
||||
"unreachable_mqtt_broker": "No se puede acceder a la dirección del Broker MQTT de Xiaomi, por favor verifique la configuración de la red."
|
||||
},
|
||||
"abort": {
|
||||
"network_connect_error": "La configuración ha fallado. Existe un problema con la conexión de red, verifique la configuración de red del dispositivo.",
|
||||
@ -69,15 +111,17 @@
|
||||
},
|
||||
"config_options": {
|
||||
"title": "Opciones de configuración",
|
||||
"description": "### ¡Hola, {nick_name}!\r\n\r\nID de cuenta de Xiaomi: {uid}\r\nRegión de inicio de sesión actual: {cloud_server}\r\n\r\nSeleccione las opciones que desea reconfigurar y haga clic en \"Siguiente\".",
|
||||
"description": "### ¡Hola, {nick_name}!\r\n\r\nID de cuenta de Xiaomi: {uid}\r\nRegión de inicio de sesión actual: {cloud_server}\r\nID de Instancia de Integración: {instance_id}\r\n\r\nSeleccione las opciones que desea reconfigurar y haga clic en \"Siguiente\".",
|
||||
"data": {
|
||||
"integration_language": "Idioma de la integración",
|
||||
"update_user_info": "Actualizar información de usuario",
|
||||
"update_devices": "Actualizar lista de dispositivos",
|
||||
"action_debug": "Modo de depuración de Action",
|
||||
"hide_non_standard_entities": "Ocultar entidades generadas no estándar",
|
||||
"update_trans_rules": "Actualizar reglas de conversión de entidad (configuración global)",
|
||||
"update_lan_ctrl_config": "Actualizar configuración de control LAN (configuración global)"
|
||||
"display_devices_changed_notify": "Mostrar notificaciones de cambio de estado del dispositivo",
|
||||
"update_trans_rules": "Actualizar reglas de conversión de entidad",
|
||||
"update_lan_ctrl_config": "Actualizar configuración de control LAN",
|
||||
"network_detect_config": "Configuración de Red Integrada"
|
||||
}
|
||||
},
|
||||
"update_user_info": {
|
||||
@ -87,12 +131,28 @@
|
||||
"nick_name": "Apodo de usuario"
|
||||
}
|
||||
},
|
||||
"devices_filter": {
|
||||
"homes_select": {
|
||||
"title": "Recomendar hogares y dispositivos",
|
||||
"description": "## Instrucciones de uso\r\n### Modo de control\r\n- Automático: Cuando hay un gateway central de Xiaomi disponible en la red local, Home Assistant priorizará el envío de comandos de control de dispositivos a través del gateway central para lograr un control localizado. Si no hay un gateway central en la red local, intentará enviar comandos de control a través del protocolo Xiaomi OT para lograr un control localizado. Solo cuando no se cumplan las condiciones anteriores de control localizado, los comandos de control del dispositivo se enviarán a través de la nube.\r\n- Nube: Los comandos de control solo se envían a través de la nube.\r\n### Hogares de dispositivos importados\r\nLa integración agregará los dispositivos en los hogares seleccionados.\r\n \r\n### ¡Hola, {nick_name}! Seleccione el modo de control de integración y el hogar donde se encuentran los dispositivos que desea agregar.",
|
||||
"description": "## Instrucciones de uso\r\n### Hogares de dispositivos importados\r\nLa integración agregará los dispositivos en los hogares seleccionados.\r\n### Filtrar dispositivos\r\nAdmite la filtración de dispositivos por nombre de habitación, tipo de acceso del dispositivo y modelo de dispositivo, y también admite la filtración por dimensión del dispositivo. Se han filtrado **{local_count}** dispositivos.\r\n### Modo de control\r\n- Automático: Cuando hay un gateway central de Xiaomi disponible en la red local, Home Assistant priorizará el envío de comandos de control de dispositivos a través del gateway central para lograr un control localizado. Si no hay un gateway central en la red local, intentará enviar comandos de control a través del protocolo Xiaomi OT para lograr un control localizado. Solo cuando no se cumplan las condiciones anteriores de control localizado, los comandos de control del dispositivo se enviarán a través de la nube.\r\n- Nube: Los comandos de control solo se envían a través de la nube.",
|
||||
"data": {
|
||||
"ctrl_mode": "Modo de control",
|
||||
"home_infos": "Hogares de dispositivos importados"
|
||||
"home_infos": "Hogares de dispositivos importados",
|
||||
"devices_filter": "Filtrar dispositivos",
|
||||
"ctrl_mode": "Modo de control"
|
||||
}
|
||||
},
|
||||
"devices_filter": {
|
||||
"title": "Filtrar Dispositivos",
|
||||
"description": "## Instrucciones de uso\r\nAdmite la filtración de dispositivos por nombre de habitación, tipo de acceso del dispositivo y modelo de dispositivo, y también admite la filtración por dimensión del dispositivo. La lógica de filtración es la siguiente:\r\n- Primero, de acuerdo con la lógica estadística, obtenga la unión o intersección de todos los elementos incluidos, luego obtenga la intersección o unión de los elementos excluidos, y finalmente reste el [resultado del resumen incluido] del [resultado del resumen excluido] para obtener el [resultado del filtro].\r\n- Si no se seleccionan elementos incluidos, significa que todos están incluidos.\r\n### Modo de Filtración\r\n- Excluir: Eliminar elementos no deseados.\r\n- Incluir: Incluir elementos deseados.\r\n### Lógica Estadística\r\n- Lógica Y: Tomar la intersección de todos los elementos en el mismo modo.\r\n- Lógica O: Tomar la unión de todos los elementos en el mismo modo.\r\n\r\nTambién puede ir a la página [Configuración > Actualizar lista de dispositivos] del elemento de integración, marcar [Filtrar dispositivos] para volver a filtrar.",
|
||||
"data": {
|
||||
"room_filter_mode": "Filtrar Habitaciones de la Familia",
|
||||
"room_list": "Habitaciones de la Familia",
|
||||
"type_filter_mode": "Filtrar Tipo de Dispositivo",
|
||||
"type_list": "Tipo de Dispositivo",
|
||||
"model_filter_mode": "Filtrar Modelo de Dispositivo",
|
||||
"model_list": "Modelo de Dispositivo",
|
||||
"devices_filter_mode": "Filtrar Dispositivos",
|
||||
"device_list": "Lista de Dispositivos",
|
||||
"statistics_logic": "Lógica de Estadísticas"
|
||||
}
|
||||
},
|
||||
"update_trans_rules": {
|
||||
@ -110,9 +170,17 @@
|
||||
"enable_subscribe": "Habilitar suscripción LAN"
|
||||
}
|
||||
},
|
||||
"network_detect_config": {
|
||||
"title": "Configuración de Red Integrada",
|
||||
"description": "## Introducción al Uso\r\n### Dirección de Detección de Red\r\nSe utiliza para verificar si la red funciona correctamente. Si no se establece, se utilizará la dirección predeterminada del sistema. Si la verificación de la dirección predeterminada falla, puede intentar ingresar una dirección personalizada.\r\n- Puede ingresar varias direcciones de detección, separadas por comas, como `8.8.8.8,https://www.bing.com`\r\n- Si es una dirección IP, la detección se realizará mediante ping. Si es una dirección HTTP(s), la detección se realizará mediante una solicitud HTTP GET.\r\n- Si desea restaurar la dirección de detección predeterminada del sistema, ingrese una coma `,` y haga clic en 'Siguiente'.\r\n- **Esta configuración es global y los cambios afectarán a otras instancias de integración. Modifique con precaución.**\r\n### Verificar Dependencias de Red\r\nVerifique una por una las siguientes dependencias de red para ver si son accesibles. Si las direcciones relacionadas no son accesibles, causará problemas de integración.\r\n- Dirección de Autenticación OAuth2: `https://account.xiaomi.com/oauth2/authorize`.\r\n- Dirección de API HTTP de Xiaomi: `https://{http_host}/app/v2/ha/oauth/get_token`.\r\n- Dirección de API SPEC de Xiaomi: `https://miot-spec.org/miot-spec-v2/template/list/device`.\r\n- Dirección del Broker MQTT de Xiaomi: `mqtts://{cloud_server}-ha.mqtt.io.mi.com:8883`.",
|
||||
"data": {
|
||||
"network_detect_addr": "Dirección de Detección de Red",
|
||||
"check_network_deps": "Verificar Dependencias de Red"
|
||||
}
|
||||
},
|
||||
"config_confirm": {
|
||||
"title": "Confirmar configuración",
|
||||
"description": "¡Hola, **{nick_name}**! Por favor, confirme la última información de configuración y haga clic en \"Enviar\" para finalizar la configuración.\r\nLa integración se volverá a cargar con la nueva configuración.\r\n\r\nIdioma de la integración:\t{lang_new}\r\nApodo de usuario:\t{nick_name_new}\r\nModo de depuración de Action:\t{action_debug}\r\nOcultar entidades generadas no estándar:\t{hide_non_standard_entities}\r\nCambios de dispositivos:\t{devices_add} dispositivos agregados, {devices_remove} dispositivos eliminados\r\nCambios en las reglas de conversión:\t{trans_rules_count} reglas en total, {trans_rules_count_success} reglas actualizadas",
|
||||
"description": "¡Hola, **{nick_name}**! Por favor, confirme la última información de configuración y haga clic en \"Enviar\" para finalizar la configuración.\r\nLa integración se volverá a cargar con la nueva configuración.\r\n\r\nIdioma de la integración:\t{lang_new}\r\nApodo de usuario:\t{nick_name_new}\r\nModo de depuración de Action:\t{action_debug}\r\nOcultar entidades generadas no estándar:\t{hide_non_standard_entities}\r\nMostrar notificaciones de cambio de estado del dispositivo:\t{display_devices_changed_notify}\r\nCambios de dispositivos:\t{devices_add} dispositivos agregados, {devices_remove} dispositivos eliminados\r\nCambios en las reglas de conversión:\t{trans_rules_count} reglas en total, {trans_rules_count_success} reglas actualizadas",
|
||||
"data": {
|
||||
"confirm": "Confirmar modificación"
|
||||
}
|
||||
@ -127,11 +195,20 @@
|
||||
"get_homeinfo_error": "Error al obtener la información del hogar.",
|
||||
"get_cert_error": "Error al obtener el certificado de la puerta de enlace.",
|
||||
"no_family_selected": "No se ha seleccionado ningún hogar.",
|
||||
"no_devices": "No hay dispositivos en el hogar seleccionado. Seleccione un hogar con dispositivos y continúe.",
|
||||
"no_devices": "No hay dispositivos en el hogar seleccionado. Por favor, seleccione un hogar con dispositivos y continúe.",
|
||||
"no_filter_devices": "Los dispositivos filtrados están vacíos. Por favor, seleccione criterios de filtro válidos y continúe.",
|
||||
"no_central_device": "【Modo de puerta de enlace central】Se requiere una puerta de enlace Xiaomi disponible en la red local donde se encuentra Home Assistant. Verifique si el hogar seleccionado cumple con este requisito.",
|
||||
"mdns_discovery_error": "Error en el servicio de descubrimiento de dispositivos locales.",
|
||||
"update_config_error": "Error al actualizar la información de configuración.",
|
||||
"not_confirm": "No se ha confirmado la opción de modificación. Seleccione y confirme la opción antes de enviar."
|
||||
"not_confirm": "No se ha confirmado la opción de modificación. Seleccione y confirme la opción antes de enviar.",
|
||||
"invalid_network_addr": "Se detectó una dirección IP o HTTP no válida, por favor ingrese una dirección válida.",
|
||||
"invalid_ip_addr": "Se detectó una dirección IP inaccesible, por favor ingrese una dirección IP válida.",
|
||||
"invalid_http_addr": "Se detectó una dirección HTTP inaccesible, por favor ingrese una dirección HTTP válida.",
|
||||
"invalid_default_addr": "La dirección de detección de red predeterminada no es accesible, por favor verifique la configuración de la red o use una dirección de detección de red personalizada.",
|
||||
"unreachable_oauth2_host": "No se puede acceder a la dirección de autenticación OAuth2, por favor verifique la configuración de la red.",
|
||||
"unreachable_http_host": "No se puede acceder a la dirección de la API HTTP de Xiaomi, por favor verifique la configuración de la red.",
|
||||
"unreachable_spec_host": "No se puede acceder a la dirección de la API SPEC de Xiaomi, por favor verifique la configuración de la red.",
|
||||
"unreachable_mqtt_broker": "No se puede acceder a la dirección del Broker MQTT de Xiaomi, por favor verifique la configuración de la red."
|
||||
},
|
||||
"abort": {
|
||||
"network_connect_error": "La configuración ha fallado. Existe un problema con la conexión de red, verifique la configuración de red del dispositivo.",
|
||||
|
@ -11,26 +11,59 @@
|
||||
},
|
||||
"auth_config": {
|
||||
"title": "Configuration de base",
|
||||
"description": "### Région de connexion\r\nSélectionnez la région où se trouve votre compte Xiaomi. Vous pouvez le trouver dans `Xiaomi Home APP > Mon (situé dans le menu inférieur) > Plus de paramètres > À propos de Xiaomi Home`.\r\n### Langue\r\nChoisissez la langue utilisée pour les noms de périphériques et d'entités. Les parties de phrases sans traduction seront affichées en anglais.\r\n### Adresse de redirection de l'authentification OAuth2\r\nL'adresse de redirection de l'authentification OAuth2 est **[http://homeassistant.local:8123](http://homeassistant.local:8123)**. Home Assistant doit être dans le même réseau local que le terminal de l'opération actuelle (par exemple, un ordinateur personnel) et le terminal de l'opération doit pouvoir accéder à la page d'accueil de Home Assistant via cette adresse. Sinon, l'authentification de connexion peut échouer.\r\n### Remarque\r\n- Pour les utilisateurs ayant des centaines ou plus d'appareils Mi Home, l'ajout initial de l'intégration prendra un certain temps. Veuillez être patient.\r\n- Si Home Assistant fonctionne dans un environnement Docker, veuillez vous assurer que le mode réseau Docker est réglé sur host, sinon la fonctionnalité de contrôle local peut ne pas fonctionner correctement.\r\n- La fonctionnalité de contrôle local de l'intégration a quelques dépendances. Veuillez lire attentivement le README.",
|
||||
"description": "### Région de connexion\r\nSélectionnez la région où se trouve votre compte Xiaomi. Vous pouvez le trouver dans `Xiaomi Home APP > Mon (situé dans le menu inférieur) > Plus de paramètres > À propos de Xiaomi Home`.\r\n### Langue\r\nChoisissez la langue utilisée pour les noms de périphériques et d'entités. Les parties de phrases sans traduction seront affichées en anglais.\r\n### Adresse de redirection de l'authentification OAuth2\r\nL'adresse de redirection de l'authentification OAuth2 est **[http://homeassistant.local:8123](http://homeassistant.local:8123)**. Home Assistant doit être dans le même réseau local que le terminal de l'opération actuelle (par exemple, un ordinateur personnel) et le terminal de l'opération doit pouvoir accéder à la page d'accueil de Home Assistant via cette adresse. Sinon, l'authentification de connexion peut échouer.\r\n### Configuration Réseau Intégrée\r\nVérifiez si le réseau local fonctionne correctement et si les ressources réseau associées sont accessibles. **Il est recommandé de sélectionner cela lors du premier ajout.**\r\n### Remarque\r\n- Pour les utilisateurs ayant des centaines ou plus d'appareils Mi Home, l'ajout initial de l'intégration prendra un certain temps. Veuillez être patient.\r\n- Si Home Assistant fonctionne dans un environnement Docker, veuillez vous assurer que le mode réseau Docker est réglé sur host, sinon la fonctionnalité de contrôle local peut ne pas fonctionner correctement.\r\n- La fonctionnalité de contrôle local de l'intégration a quelques dépendances. Veuillez lire attentivement le README.",
|
||||
"data": {
|
||||
"cloud_server": "Région de connexion",
|
||||
"integration_language": "Langue",
|
||||
"oauth_redirect_url": "Adresse de redirection de l'authentification"
|
||||
"oauth_redirect_url": "Adresse de redirection de l'authentification",
|
||||
"network_detect_config": "Configuration Réseau Intégrée"
|
||||
}
|
||||
},
|
||||
"network_detect_config": {
|
||||
"title": "Configuration Réseau Intégrée",
|
||||
"description": "## Introduction à l'Utilisation\r\n### Adresse de Détection Réseau\r\nUtilisé pour vérifier si le réseau fonctionne correctement. Si non défini, l'adresse par défaut du système sera utilisée. Si la vérification de l'adresse par défaut échoue, vous pouvez essayer de saisir une adresse personnalisée.\r\n- Vous pouvez entrer plusieurs adresses de détection, séparées par des virgules, telles que `8.8.8.8,https://www.bing.com`\r\n- S'il s'agit d'une adresse IP, la détection se fera par ping. S'il s'agit d'une adresse HTTP(s), la détection se fera par une requête HTTP GET.\r\n- Si vous souhaitez rétablir l'adresse de détection par défaut du système, veuillez entrer une virgule `,` et cliquer sur 'Suivant'.\r\n- **Cette configuration est globale et les modifications affecteront les autres instances d'intégration. Veuillez modifier avec prudence.**\r\n### Vérification des Dépendances Réseau\r\nVérifiez une par une les dépendances réseau suivantes pour voir si elles sont accessibles. Si les adresses associées ne sont pas accessibles, cela entraînera des problèmes d'intégration.\r\n- Adresse d'Authentification OAuth2: `https://account.xiaomi.com/oauth2/authorize`.\r\n- Adresse de l'API HTTP de Xiaomi: `https://{http_host}/app/v2/ha/oauth/get_token`.\r\n- Adresse de l'API SPEC de Xiaomi: `https://miot-spec.org/miot-spec-v2/template/list/device`.\r\n- Adresse du Broker MQTT de Xiaomi: `mqtts://{cloud_server}-ha.mqtt.io.mi.com:8883`.",
|
||||
"data": {
|
||||
"network_detect_addr": "Adresse de Détection Réseau",
|
||||
"check_network_deps": "Vérification des Dépendances Réseau"
|
||||
}
|
||||
},
|
||||
"oauth_error": {
|
||||
"title": "Erreur de connexion",
|
||||
"description": "Cliquez sur \"Suivant\" pour réessayer"
|
||||
},
|
||||
"devices_filter": {
|
||||
"title": "Sélectionner une maison et des appareils",
|
||||
"description": "## Instructions d'utilisation\r\n### Mode de contrôle\r\n- Automatique: Lorsqu'il y a une passerelle centrale Xiaomi disponible dans le réseau local, Home Assistant priorisera l'envoi des commandes de contrôle des appareils via la passerelle centrale pour réaliser un contrôle localisé. S'il n'y a pas de passerelle centrale dans le réseau local, il tentera d'envoyer des commandes de contrôle via le protocole Xiaomi OT pour réaliser un contrôle localisé. Ce n'est que lorsque les conditions de contrôle localisé ci-dessus ne sont pas remplies que les commandes de contrôle des appareils seront envoyées via le cloud.\r\n- Cloud: Les commandes de contrôle ne sont envoyées que via le cloud.\r\n### Importer une maison pour les appareils\r\nL'intégration ajoutera les appareils de la maison sélectionnée.\r\n### Mode de synchronisation des noms de pièces\r\nLors de la synchronisation des appareils de Xiaomi Home à Home Assistant, le nom de la pièce où se trouve l'appareil sera nommé selon les règles suivantes. Notez que le processus de synchronisation des appareils n'affecte pas les paramètres de la maison et de la pièce dans Xiaomi Home APP.\r\n- Ne pas synchroniser: L'appareil ne sera ajouté à aucune zone.\r\n- Autre option: La zone dans laquelle l'appareil est ajouté est nommée en fonction du nom de la maison ou de la pièce de Xiaomi Home APP.\r\n### Mode de débogage d'action\r\nPour les méthodes définies par MIoT-Spec-V2, en plus de générer une entité de notification, une entité de zone de texte sera également générée pour que vous puissiez envoyer des commandes de contrôle à l'appareil lors du débogage.\r\n### Masquer les entités générées non standard\r\nMasquer les entités générées non standard de MIoT-Spec-V2 commençant par \"*\".\r\n\r\n \r\n### {nick_name} Bonjour ! Veuillez sélectionner le mode de contrôle de l'intégration et la maison où se trouvent les appareils à ajouter.",
|
||||
"homes_select": {
|
||||
"title": "Sélectionner la famille et l'appareil",
|
||||
"description": "## Introduction\r\n### Importer la famille de l'appareil\r\nL'intégration ajoutera des appareils de la famille sélectionnée.\r\n### Mode de synchronisation du nom de la pièce\r\nLors de la synchronisation des appareils de l'application Mi Home avec Home Assistant, le nom de la zone dans Home Assistant suivra les règles ci-dessous. Notez que le processus de synchronisation ne modifiera pas les paramètres de la famille et de la pièce dans l'application Mi Home.\r\n- Ne pas synchroniser : L'appareil ne sera ajouté à aucune zone.\r\n- Autres options : La zone à laquelle l'appareil est ajouté sera nommée d'après le nom de la famille ou de la pièce dans l'application Mi Home.\r\n### Paramètres avancés\r\nAfficher les paramètres avancés pour modifier les options de configuration professionnelle de l'intégration.\r\n\r\n \r\n### {nick_name} Bonjour ! Veuillez sélectionner la famille à laquelle vous souhaitez ajouter l'appareil.",
|
||||
"data": {
|
||||
"ctrl_mode": "Mode de contrôle",
|
||||
"home_infos": "Importer une maison pour les appareils",
|
||||
"area_name_rule": "Mode de synchronisation des noms de pièces",
|
||||
"action_debug": "Mode de débogage d'action",
|
||||
"hide_non_standard_entities": "Masquer les entités générées non standard"
|
||||
"home_infos": "Importer la famille de l'appareil",
|
||||
"area_name_rule": "Mode de synchronisation du nom de la pièce",
|
||||
"advanced_options": "Paramètres avancés"
|
||||
}
|
||||
},
|
||||
"advanced_options": {
|
||||
"title": "Paramètres Avancés",
|
||||
"description": "## Introduction\r\n### Sauf si vous comprenez très bien la signification des options suivantes, veuillez les laisser par défaut.\r\n### Filtrer les appareils\r\nPrend en charge le filtrage des appareils en fonction du nom de la pièce et du type d'appareil, ainsi que le filtrage basé sur les appareils.\r\n### Mode de Contrôle\r\n- Automatique : Lorsqu'une passerelle Xiaomi est disponible dans le réseau local, Home Assistant enverra les commandes de contrôle des appareils via la passerelle pour permettre le contrôle local. Si aucune passerelle n'est disponible dans le réseau local, Home Assistant essaiera d'envoyer les commandes de contrôle des appareils via le protocole OT Xiaomi pour permettre le contrôle local. Seules si les conditions de contrôle local ci-dessus ne sont pas remplies, les commandes de contrôle des appareils seront envoyées via le cloud.\r\n- Cloud : Les commandes de contrôle des appareils sont envoyées uniquement via le cloud.\r\n### Mode de Débogage d’Actions\r\nPour les méthodes définies par les appareils MIoT-Spec-V2, en plus de générer une entité de notification, une entité de champ de texte sera également générée pour vous permettre d'envoyer des commandes de contrôle aux appareils lors du débogage.\r\n### Masquer les Entités Non Standard\r\nMasquer les entités générées par des instances MIoT-Spec-V2 non standard et commençant par \"*\".\r\n### Afficher les notifications de changement d'état de l'appareil\r\nAfficher les notifications détaillées de changement d'état de l'appareil, en affichant uniquement les notifications sélectionnées.",
|
||||
"data": {
|
||||
"devices_filter": "Filtrer les Appareils",
|
||||
"ctrl_mode": "Mode de Contrôle",
|
||||
"action_debug": "Mode de Débogage d’Actions",
|
||||
"hide_non_standard_entities": "Masquer les Entités Non Standard",
|
||||
"display_devices_changed_notify": "Afficher les notifications de changement d'état de l'appareil"
|
||||
}
|
||||
},
|
||||
"devices_filter": {
|
||||
"title": "Filtrer les Appareils",
|
||||
"description": "## Instructions d'utilisation\r\nPrend en charge le filtrage des appareils par nom de pièce de la maison, type d'accès de l'appareil et modèle d'appareil, et prend également en charge le filtrage par dimension de l'appareil. La logique de filtrage est la suivante :\r\n- Tout d'abord, selon la logique statistique, obtenez l'union ou l'intersection de tous les éléments inclus, puis obtenez l'intersection ou l'union des éléments exclus, et enfin soustrayez le [résultat du résumé inclus] du [résultat du résumé exclu] pour obtenir le [résultat du filtre].\r\n- Si aucun élément inclus n'est sélectionné, cela signifie que tous sont inclus.\r\n### Mode de Filtrage\r\n- Exclure : Supprimer les éléments indésirables.\r\n- Inclure : Inclure les éléments souhaités.\r\n### Logique Statistique\r\n- Logique ET : Prendre l'intersection de tous les éléments dans le même mode.\r\n- Logique OU : Prendre l'union de tous les éléments dans le même mode.\r\n\r\nVous pouvez également aller à la page [Configuration > Mettre à jour la liste des appareils] de l'élément d'intégration, cocher [Filtrer les appareils] pour re-filtrer.",
|
||||
"data": {
|
||||
"room_filter_mode": "Filtrer les Pièces",
|
||||
"room_list": "Pièces",
|
||||
"type_filter_mode": "Filtrer les Types d'Appareils",
|
||||
"type_list": "Types d'Appareils",
|
||||
"model_filter_mode": "Filtrer les Modèles d'Appareils",
|
||||
"model_list": "Modèles d'Appareils",
|
||||
"devices_filter_mode": "Filtrer les Appareils",
|
||||
"device_list": "Liste des Appareils",
|
||||
"statistics_logic": "Logique de Statistiques"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -44,8 +77,17 @@
|
||||
"mdns_discovery_error": "Le service de découverte de périphériques locaux est anormal.",
|
||||
"get_cert_error": "Échec de l'obtention du certificat de la passerelle.",
|
||||
"no_family_selected": "Aucune maison sélectionnée.",
|
||||
"no_devices": "Il n'y a pas d'appareil dans la maison sélectionnée. Veuillez sélectionner une maison avec des appareils avant de continuer.",
|
||||
"no_central_device": "Le mode gateway central a besoin d'un Xiaomi Gateway disponible dans le réseau local où se trouve Home Assistant. Veuillez vérifier si la maison sélectionnée répond à cette exigence."
|
||||
"no_devices": "Il n'y a pas d'appareils dans la maison sélectionnée. Veuillez sélectionner une maison avec des appareils et continuer.",
|
||||
"no_filter_devices": "Les appareils filtrés sont vides. Veuillez sélectionner des critères de filtre valides et continuer.",
|
||||
"no_central_device": "Le mode gateway central a besoin d'un Xiaomi Gateway disponible dans le réseau local où se trouve Home Assistant. Veuillez vérifier si la maison sélectionnée répond à cette exigence.",
|
||||
"invalid_network_addr": "Adresse IP ou HTTP invalide détectée, veuillez entrer une adresse valide.",
|
||||
"invalid_ip_addr": "Adresse IP inaccessible détectée, veuillez entrer une adresse IP valide.",
|
||||
"invalid_http_addr": "Adresse HTTP inaccessible détectée, veuillez entrer une adresse HTTP valide.",
|
||||
"invalid_default_addr": "L'adresse de détection réseau par défaut est inaccessible, veuillez vérifier la configuration réseau ou utiliser une adresse de détection réseau personnalisée.",
|
||||
"unreachable_oauth2_host": "Impossible d'atteindre l'adresse d'authentification OAuth2, veuillez vérifier la configuration réseau.",
|
||||
"unreachable_http_host": "Impossible d'atteindre l'adresse de l'API HTTP de Xiaomi, veuillez vérifier la configuration réseau.",
|
||||
"unreachable_spec_host": "Impossible d'atteindre l'adresse de l'API SPEC de Xiaomi, veuillez vérifier la configuration réseau.",
|
||||
"unreachable_mqtt_broker": "Impossible d'atteindre l'adresse du Broker MQTT de Xiaomi, veuillez vérifier la configuration réseau."
|
||||
},
|
||||
"abort": {
|
||||
"network_connect_error": "La configuration a échoué. Erreur de connexion réseau. Veuillez vérifier la configuration du réseau de l'appareil.",
|
||||
@ -69,15 +111,17 @@
|
||||
},
|
||||
"config_options": {
|
||||
"title": "Options de configuration",
|
||||
"description": "### {nick_name} Bonjour !\r\n\r\nID de compte Xiaomi : {uid}\r\nRégion de connexion actuelle : {cloud_server}\r\n\r\nVeuillez sélectionner les options que vous devez reconfigurer et cliquer sur \"Suivant\".",
|
||||
"description": "### {nick_name} Bonjour !\r\n\r\nID de compte Xiaomi : {uid}\r\nRégion de connexion actuelle : {cloud_server}\r\nID d'Instance d'Intégration: {instance_id}\r\n\r\nVeuillez sélectionner les options que vous devez reconfigurer et cliquer sur \"Suivant\".",
|
||||
"data": {
|
||||
"integration_language": "Langue d'intégration",
|
||||
"update_user_info": "Mettre à jour les informations utilisateur",
|
||||
"update_devices": "Mettre à jour la liste des appareils",
|
||||
"action_debug": "Mode de débogage d'action",
|
||||
"hide_non_standard_entities": "Masquer les entités générées non standard",
|
||||
"update_trans_rules": "Mettre à jour les règles de conversion d'entités (configuration globale)",
|
||||
"update_lan_ctrl_config": "Mettre à jour la configuration de contrôle LAN (configuration globale)"
|
||||
"display_devices_changed_notify": "Afficher les notifications de changement d'état de l'appareil",
|
||||
"update_trans_rules": "Mettre à jour les règles de conversion d'entités",
|
||||
"update_lan_ctrl_config": "Mettre à jour la configuration de contrôle LAN",
|
||||
"network_detect_config": "Configuration Réseau Intégrée"
|
||||
}
|
||||
},
|
||||
"update_user_info": {
|
||||
@ -87,12 +131,28 @@
|
||||
"nick_name": "Pseudo utilisateur"
|
||||
}
|
||||
},
|
||||
"devices_filter": {
|
||||
"homes_select": {
|
||||
"title": "Re-sélectionner une maison et des appareils",
|
||||
"description": "## Instructions d'utilisation\r\n### Mode de contrôle\r\n- Automatique: Lorsqu'il y a une passerelle centrale Xiaomi disponible dans le réseau local, Home Assistant priorisera l'envoi des commandes de contrôle des appareils via la passerelle centrale pour réaliser un contrôle localisé. S'il n'y a pas de passerelle centrale dans le réseau local, il tentera d'envoyer des commandes de contrôle via le protocole Xiaomi OT pour réaliser un contrôle localisé. Ce n'est que lorsque les conditions de contrôle localisé ci-dessus ne sont pas remplies que les commandes de contrôle des appareils seront envoyées via le cloud.\r\n- Cloud: Les commandes de contrôle ne sont envoyées que via le cloud.\r\n### Importer une maison pour les appareils\r\nL'intégration ajoutera les appareils de la maison sélectionnée.\r\n \r\n### {nick_name} Bonjour ! Veuillez sélectionner le mode de contrôle de l'intégration et la maison où se trouvent les appareils à ajouter.",
|
||||
"description": "## Instructions d'utilisation\r\n### Importer une maison pour les appareils\r\nL'intégration ajoutera les appareils de la maison sélectionnée.\r\n### Filtrer les appareils\r\nPrend en charge le filtrage des appareils par nom de pièce de la maison, type d'accès de l'appareil et modèle d'appareil, et prend également en charge le filtrage par dimension de l'appareil. **{local_count}** appareils ont été filtrés.\r\n### Mode de contrôle\r\n- Automatique: Lorsqu'il y a une passerelle centrale Xiaomi disponible dans le réseau local, Home Assistant priorisera l'envoi des commandes de contrôle des appareils via la passerelle centrale pour réaliser un contrôle localisé. S'il n'y a pas de passerelle centrale dans le réseau local, il tentera d'envoyer des commandes de contrôle via le protocole Xiaomi OT pour réaliser un contrôle localisé. Ce n'est que lorsque les conditions de contrôle localisé ci-dessus ne sont pas remplies que les commandes de contrôle des appareils seront envoyées via le cloud.\r\n- Cloud: Les commandes de contrôle ne sont envoyées que via le cloud.",
|
||||
"data": {
|
||||
"ctrl_mode": "Mode de contrôle",
|
||||
"home_infos": "Importer une maison pour les appareils"
|
||||
"home_infos": "Importer une maison pour les appareils",
|
||||
"devices_filter": "Filtrer les Appareils",
|
||||
"ctrl_mode": "Mode de contrôle"
|
||||
}
|
||||
},
|
||||
"devices_filter": {
|
||||
"title": "Filtrer les Appareils",
|
||||
"description": "## Instructions d'utilisation\r\nPrend en charge le filtrage des appareils par nom de pièce de la maison, type d'accès de l'appareil et modèle d'appareil, et prend également en charge le filtrage par dimension de l'appareil. La logique de filtrage est la suivante :\r\n- Tout d'abord, selon la logique statistique, obtenez l'union ou l'intersection de tous les éléments inclus, puis obtenez l'intersection ou l'union des éléments exclus, et enfin soustrayez le [résultat du résumé inclus] du [résultat du résumé exclu] pour obtenir le [résultat du filtre].\r\n- Si aucun élément inclus n'est sélectionné, cela signifie que tous sont inclus.\r\n### Mode de Filtrage\r\n- Exclure : Supprimer les éléments indésirables.\r\n- Inclure : Inclure les éléments souhaités.\r\n### Logique Statistique\r\n- Logique ET : Prendre l'intersection de tous les éléments dans le même mode.\r\n- Logique OU : Prendre l'union de tous les éléments dans le même mode.\r\n\r\nVous pouvez également aller à la page [Configuration > Mettre à jour la liste des appareils] de l'élément d'intégration, cocher [Filtrer les appareils] pour re-filtrer.",
|
||||
"data": {
|
||||
"room_filter_mode": "Filtrer les Pièces",
|
||||
"room_list": "Pièces",
|
||||
"type_filter_mode": "Filtrer les Types d'Appareils",
|
||||
"type_list": "Types d'Appareils",
|
||||
"model_filter_mode": "Filtrer les Modèles d'Appareils",
|
||||
"model_list": "Modèles d'Appareils",
|
||||
"devices_filter_mode": "Filtrer les Appareils",
|
||||
"device_list": "Liste des Appareils",
|
||||
"statistics_logic": "Logique de Statistiques"
|
||||
}
|
||||
},
|
||||
"update_trans_rules": {
|
||||
@ -110,9 +170,17 @@
|
||||
"enable_subscribe": "Activer la souscription"
|
||||
}
|
||||
},
|
||||
"network_detect_config": {
|
||||
"title": "Configuration Réseau Intégrée",
|
||||
"description": "## Introduction à l'Utilisation\r\n### Adresse de Détection Réseau\r\nUtilisé pour vérifier si le réseau fonctionne correctement. Si non défini, l'adresse par défaut du système sera utilisée. Si la vérification de l'adresse par défaut échoue, vous pouvez essayer de saisir une adresse personnalisée.\r\n- Vous pouvez entrer plusieurs adresses de détection, séparées par des virgules, telles que `8.8.8.8,https://www.bing.com`\r\n- S'il s'agit d'une adresse IP, la détection se fera par ping. S'il s'agit d'une adresse HTTP(s), la détection se fera par une requête HTTP GET.\r\n- Si vous souhaitez rétablir l'adresse de détection par défaut du système, veuillez entrer une virgule `,` et cliquer sur 'Suivant'.\r\n- **Cette configuration est globale et les modifications affecteront les autres instances d'intégration. Veuillez modifier avec prudence.**\r\n### Vérification des Dépendances Réseau\r\nVérifiez une par une les dépendances réseau suivantes pour voir si elles sont accessibles. Si les adresses associées ne sont pas accessibles, cela entraînera des problèmes d'intégration.\r\n- Adresse d'Authentification OAuth2: `https://account.xiaomi.com/oauth2/authorize`.\r\n- Adresse de l'API HTTP de Xiaomi: `https://{http_host}/app/v2/ha/oauth/get_token`.\r\n- Adresse de l'API SPEC de Xiaomi: `https://miot-spec.org/miot-spec-v2/template/list/device`.\r\n- Adresse du Broker MQTT de Xiaomi: `mqtts://{cloud_server}-ha.mqtt.io.mi.com:8883`.",
|
||||
"data": {
|
||||
"network_detect_addr": "Adresse de Détection Réseau",
|
||||
"check_network_deps": "Vérification des Dépendances Réseau"
|
||||
}
|
||||
},
|
||||
"config_confirm": {
|
||||
"title": "Confirmer la configuration",
|
||||
"description": "**{nick_name}** Bonjour ! Veuillez confirmer les dernières informations de configuration et cliquer sur \"Soumettre\".\r\nL'intégration rechargera avec la nouvelle configuration.\r\n\r\nLangue d'intégration : {lang_new}\r\nPseudo utilisateur : {nick_name_new}\r\nMode de débogage d'action : {action_debug}\r\nMasquer les entités générées non standard : {hide_non_standard_entities}\r\nModifications des appareils : Ajouter **{devices_add}** appareils, supprimer **{devices_remove}** appareils\r\nModifications des règles de conversion : **{trans_rules_count}** règles au total, mise à jour de **{trans_rules_count_success}** règles",
|
||||
"description": "**{nick_name}** Bonjour ! Veuillez confirmer les dernières informations de configuration et cliquer sur \"Soumettre\".\r\nL'intégration rechargera avec la nouvelle configuration.\r\n\r\nLangue d'intégration : {lang_new}\r\nPseudo utilisateur : {nick_name_new}\r\nMode de débogage d'action : {action_debug}\r\nMasquer les entités générées non standard : {hide_non_standard_entities}\r\nAfficher les notifications de changement d'état de l'appareil:\t{display_devices_changed_notify}\r\nModifications des appareils : Ajouter **{devices_add}** appareils, supprimer **{devices_remove}** appareils\r\nModifications des règles de conversion : **{trans_rules_count}** règles au total, mise à jour de **{trans_rules_count_success}** règles",
|
||||
"data": {
|
||||
"confirm": "Confirmer la modification"
|
||||
}
|
||||
@ -127,11 +195,20 @@
|
||||
"get_homeinfo_error": "Impossible d'obtenir les informations de la maison.",
|
||||
"get_cert_error": "Impossible d'obtenir le certificat central.",
|
||||
"no_family_selected": "Aucune maison sélectionnée.",
|
||||
"no_devices": "Aucun périphérique dans la maison sélectionnée. Veuillez sélectionner une maison avec des périphériques et continuer.",
|
||||
"no_devices": "Il n'y a pas d'appareils dans la maison sélectionnée. Veuillez sélectionner une maison avec des appareils et continuer.",
|
||||
"no_filter_devices": "Les appareils filtrés sont vides. Veuillez sélectionner des critères de filtre valides et continuer.",
|
||||
"no_central_device": "Le mode passerelle centrale nécessite une passerelle Xiaomi disponible dans le réseau local où est installé Home Assistant. Veuillez vérifier que la maison sélectionnée répond à cette exigence.",
|
||||
"mdns_discovery_error": "Service de découverte de périphérique local en panne.",
|
||||
"update_config_error": "Échec de la mise à jour des informations de configuration.",
|
||||
"not_confirm": "La modification n'a pas été confirmée. Veuillez cocher la case de confirmation avant de soumettre."
|
||||
"not_confirm": "La modification n'a pas été confirmée. Veuillez cocher la case de confirmation avant de soumettre.",
|
||||
"invalid_network_addr": "Adresse IP ou HTTP invalide détectée, veuillez entrer une adresse valide.",
|
||||
"invalid_ip_addr": "Adresse IP inaccessible détectée, veuillez entrer une adresse IP valide.",
|
||||
"invalid_http_addr": "Adresse HTTP inaccessible détectée, veuillez entrer une adresse HTTP valide.",
|
||||
"invalid_default_addr": "L'adresse de détection réseau par défaut est inaccessible, veuillez vérifier la configuration réseau ou utiliser une adresse de détection réseau personnalisée.",
|
||||
"unreachable_oauth2_host": "Impossible d'atteindre l'adresse d'authentification OAuth2, veuillez vérifier la configuration réseau.",
|
||||
"unreachable_http_host": "Impossible d'atteindre l'adresse de l'API HTTP de Xiaomi, veuillez vérifier la configuration réseau.",
|
||||
"unreachable_spec_host": "Impossible d'atteindre l'adresse de l'API SPEC de Xiaomi, veuillez vérifier la configuration réseau.",
|
||||
"unreachable_mqtt_broker": "Impossible d'atteindre l'adresse du Broker MQTT de Xiaomi, veuillez vérifier la configuration réseau."
|
||||
},
|
||||
"abort": {
|
||||
"network_connect_error": "Échec de la configuration. Problème de connexion réseau, veuillez vérifier la configuration du périphérique.",
|
||||
|
@ -11,26 +11,59 @@
|
||||
},
|
||||
"auth_config": {
|
||||
"title": "基本設定",
|
||||
"description": "### ログインエリア\r\nXiaomi アカウントが属する地域を選択します。 `Xiaomi Home アプリ> マイ(ボトムメニューにあります)> その他の設定> Xiaomi Home について` で確認できます。\r\n### 言語\r\nデバイスおよびエンティティ名に使用される言語を選択します。一部の翻訳が欠落している場合、英語が表示されます。\r\n### OAuth2 認証リダイレクトアドレス\r\nOAuth2 認証リダイレクトアドレスは **[http://homeassistant.local:8123](http://homeassistant.local:8123)** です。Home Assistant は、現在の操作端末(たとえば、パーソナルコンピュータ)と同じ LAN 内にあり、操作端末がこのアドレスで Home Assistant ホームページにアクセスできる場合にのみログイン認証が成功する場合があります。\r\n### 注意事項\r\n- 数百台以上のMi Homeデバイスをお持ちのユーザーの場合、統合の初回追加には時間がかかります。しばらくお待ちください。\r\n- Home AssistantがDocker環境で実行されている場合は、Dockerのネットワークモードがhostに設定されていることを確認してください。そうしないと、ローカル制御機能が正しく動作しない可能性があります。\r\n- 統合のローカル制御機能にはいくつかの依存関係があります。READMEを注意深く読んでください。",
|
||||
"description": "### ログインエリア\r\nXiaomi アカウントが属する地域を選択します。 `Xiaomi Home アプリ> マイ(ボトムメニューにあります)> その他の設定> Xiaomi Home について` で確認できます。\r\n### 言語\r\nデバイスおよびエンティティ名に使用される言語を選択します。一部の翻訳が欠落している場合、英語が表示されます。\r\n### OAuth2 認証リダイレクトアドレス\r\nOAuth2 認証リダイレクトアドレスは **[http://homeassistant.local:8123](http://homeassistant.local:8123)** です。Home Assistant は、現在の操作端末(たとえば、パーソナルコンピュータ)と同じ LAN 内にあり、操作端末がこのアドレスで Home Assistant ホームページにアクセスできる場合にのみログイン認証が成功する場合があります。\r\n### 統合ネットワーク構成\r\nローカルネットワークが正常に機能しているかどうか、および関連するネットワークリソースにアクセスできるかどうかを確認します。**初めて追加する場合は、これを選択することをお勧めします。**\r\n### 注意事項\r\n- 数百台以上のMi Homeデバイスをお持ちのユーザーの場合、統合の初回追加には時間がかかります。しばらくお待ちください。\r\n- Home AssistantがDocker環境で実行されている場合は、Dockerのネットワークモードがhostに設定されていることを確認してください。そうしないと、ローカル制御機能が正しく動作しない可能性があります。\r\n- 統合のローカル制御機能にはいくつかの依存関係があります。READMEを注意深く読んでください。",
|
||||
"data": {
|
||||
"cloud_server": "ログインエリア",
|
||||
"integration_language": "言語",
|
||||
"oauth_redirect_url": "認証リダイレクトアドレス"
|
||||
"oauth_redirect_url": "認証リダイレクトアドレス",
|
||||
"network_detect_config": "統合ネットワーク構成"
|
||||
}
|
||||
},
|
||||
"network_detect_config": {
|
||||
"title": "統合ネットワーク構成",
|
||||
"description": "## 使用方法の紹介\r\n### ネットワーク検出アドレス\r\nネットワークが正常に機能しているかどうかを確認するために使用されます。設定されていない場合、システムのデフォルトアドレスが使用されます。デフォルトアドレスのチェックが失敗した場合は、カスタムアドレスを入力してみてください。\r\n- 複数の検出アドレスを入力できます。アドレスはコンマで区切ります。例:`8.8.8.8,https://www.bing.com`\r\n- IPアドレスの場合、pingによる検出が行われます。HTTP(s)アドレスの場合、HTTP GETリクエストによる検出が行われます。\r\n- システムのデフォルト検出アドレスを復元する場合は、カンマ `,` を入力して「次へ」をクリックしてください。\r\n- **この設定はグローバルであり、変更は他の統合インスタンスに影響を与えます。慎重に変更してください。**\r\n### ネットワーク依存関係のチェック\r\n次のネットワーク依存関係がアクセス可能かどうかを順番に確認します。関連するアドレスにアクセスできない場合、統合に問題が発生します。\r\n- OAuth2 認証アドレス: `https://account.xiaomi.com/oauth2/authorize`.\r\n- Xiaomi HTTP API アドレス: `https://{http_host}/app/v2/ha/oauth/get_token`.\r\n- Xiaomi SPEC API アドレス: `https://miot-spec.org/miot-spec-v2/template/list/device`.\r\n- Xiaomi MQTT ブローカーアドレス: `mqtts://{cloud_server}-ha.mqtt.io.mi.com:8883`.",
|
||||
"data": {
|
||||
"network_detect_addr": "ネットワーク検出アドレス",
|
||||
"check_network_deps": "ネットワーク依存関係のチェック"
|
||||
}
|
||||
},
|
||||
"oauth_error": {
|
||||
"title": "ログインエラー",
|
||||
"description": "「次へ」をクリックして再試行してください"
|
||||
},
|
||||
"devices_filter": {
|
||||
"title": "ホームとデバイスを選択",
|
||||
"description": "## 使用方法\r\n### 制御モード\r\n- 自動: ローカルエリアネットワーク内に利用可能なXiaomi中央ゲートウェイが存在する場合、Home Assistantは中央ゲートウェイを介してデバイス制御コマンドを優先的に送信し、ローカル制御機能を実現します。ローカルエリアネットワーク内に中央ゲートウェイが存在しない場合、Xiaomi OTプロトコルを介して制御コマンドを送信し、ローカル制御機能を実現しようとします。上記のローカル制御条件が満たされない場合にのみ、デバイス制御コマンドはクラウドを介して送信されます。\r\n- クラウド: 制御コマンドはクラウドを介してのみ送信されます。\r\n### 導入されたデバイスのホーム\r\n統合は、選択された家庭にあるデバイスを追加します。\r\n### 部屋名同期モード\r\nXiaomi Home アプリから Home Assistant に同期されるデバイスの場合、デバイスが Home Assistant 内でどのような領域にあるかを示す名前の命名方式は、以下のルールに従います。ただし、デバイスの同期プロセスは、Xiaomi Home アプリで家庭および部屋の設定を変更しないことに注意してください。\r\n- 同期しない:デバイスはどの領域にも追加されません。\r\n- その他のオプション:デバイスが追加される領域は、Xiaomi Home アプリの家庭または部屋の名前に従って命名されます。\r\n### Action デバッグモード\r\nデバイスが MIoT-Spec-V2 で定義された方法を実行する場合、通知エンティティの生成に加えて、テキスト入力ボックスエンティティも生成されます。これを使用して、デバイスに制御命令を送信することができます。\r\n### 非標準生成エンティティを非表示にする\r\n「*」で始まる名前の非標準 MIoT-Spec-V2 インスタンスによって生成されたエンティティを非表示にします。\r\n\r\n \r\n### {nick_name} さん、こんにちは! 統合制御モードと追加するデバイスがあるホームを選択してください。",
|
||||
"homes_select": {
|
||||
"title": "家族とデバイスを選択",
|
||||
"description": "## 紹介\r\n### デバイスの家族をインポート\r\n統合は選択された家族のデバイスを追加します。\r\n### 部屋の名前の同期モード\r\nMi HomeアプリからHome Assistantにデバイスを同期する際、Home Assistantのエリアの名前は以下のルールに従います。同期プロセスはMi Homeアプリの家族と部屋の設定を変更しないことに注意してください。\r\n- 同期しない:デバイスはどのエリアにも追加されません。\r\n- その他のオプション:デバイスが追加されるエリアはMi Homeアプリの家族または部屋の名前にちなんで命名されます。\r\n### 高度な設定\r\n統合のプロフェッショナルな設定オプションを変更するために高度な設定を表示します。\r\n\r\n \r\n### {nick_name} こんにちは!デバイスを追加したい家族を選択してください。",
|
||||
"data": {
|
||||
"ctrl_mode": "制御モード",
|
||||
"home_infos": "導入されたデバイスのホーム",
|
||||
"area_name_rule": "部屋名同期モード",
|
||||
"action_debug": "Action デバッグモード",
|
||||
"hide_non_standard_entities": "非標準生成エンティティを非表示にする"
|
||||
"home_infos": "デバイスの家族をインポート",
|
||||
"area_name_rule": "部屋の名前の同期モード",
|
||||
"advanced_options": "高度な設定"
|
||||
}
|
||||
},
|
||||
"advanced_options": {
|
||||
"title": "高度な設定オプション",
|
||||
"description": "## 紹介\r\n### 以下のオプションの意味がよくわからない場合は、デフォルトのままにしてください。\r\n### デバイスのフィルタリング\r\n部屋名とデバイスタイプでデバイスをフィルタリングすることができます。デバイスの次元でフィルタリングすることもできます。\r\n### コントロールモード\r\n- 自動:ローカルネットワーク内に利用可能なXiaomi中央ゲートウェイがある場合、Home Assistantはデバイス制御命令を送信するために優先的に中央ゲートウェイを使用します。ローカルネットワークに中央ゲートウェイがない場合、Xiaomi OTプロトコルを使用してデバイス制御命令を送信し、ローカル制御機能を実現します。上記のローカル制御条件が満たされない場合のみ、デバイス制御命令はクラウドを介して送信されます。\r\n- クラウド:制御命令はクラウドを介してのみ送信されます。\r\n### Actionデバッグモード\r\nデバイスが定義するMIoT-Spec-V2のメソッドに対して、通知エンティティを生成するだけでなく、デバイスに制御命令を送信するためのテキスト入力ボックスエンティティも生成されます。デバッグ時にデバイスに制御命令を送信するために使用できます。\r\n### 非標準生成エンティティを隠す\r\n「*」で始まる名前の非標準MIoT-Spec-V2インスタンスによって生成されたエンティティを非表示にします。\r\n### デバイスの状態変化通知を表示\r\nデバイスの状態変化通知を詳細に表示し、選択された通知のみを表示します。",
|
||||
"data": {
|
||||
"devices_filter": "デバイスをフィルタリング",
|
||||
"ctrl_mode": "コントロールモード",
|
||||
"action_debug": "Actionデバッグモード",
|
||||
"hide_non_standard_entities": "非標準生成エンティティを隠す",
|
||||
"display_devices_changed_notify": "デバイスの状態変化通知を表示"
|
||||
}
|
||||
},
|
||||
"devices_filter": {
|
||||
"title": "デバイスをフィルタリング",
|
||||
"description": "## 使用方法\r\n家庭の部屋の名前、デバイスの接続タイプ、デバイスのモデルでデバイスをフィルタリングすることをサポートし、デバイスの次元フィルタリングもサポートします。フィルタリングロジックは次のとおりです:\r\n- まず、統計ロジックに従って、すべての含まれる項目の和集合または交差を取得し、次に除外される項目の交差または和集合を取得し、最後に[含まれる集計結果]から[除外される集計結果]を引いて[フィルタ結果]を取得します。\r\n- 含まれる項目が選択されていない場合、すべてが含まれることを意味します。\r\n### フィルターモード\r\n- 除外:不要な項目を削除します。\r\n- 含む:必要な項目を含めます。\r\n### 統計ロジック\r\n- ANDロジック:同じモードのすべての項目の交差を取ります。\r\n- ORロジック:同じモードのすべての項目の和集合を取ります。\r\n\r\n統合項目の[設定 > デバイスリストの更新]ページに移動し、[デバイスをフィルタリング]を選択して再フィルタリングすることもできます。",
|
||||
"data": {
|
||||
"room_filter_mode": "家族の部屋をフィルタリング",
|
||||
"room_list": "家族の部屋",
|
||||
"type_filter_mode": "デバイスタイプをフィルタリング",
|
||||
"type_list": "デバイスタイプ",
|
||||
"model_filter_mode": "デバイスモデルをフィルタリング",
|
||||
"model_list": "デバイスモデル",
|
||||
"devices_filter_mode": "デバイスをフィルタリング",
|
||||
"device_list": "デバイスリスト",
|
||||
"statistics_logic": "統計ロジック"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -44,10 +77,17 @@
|
||||
"mdns_discovery_error": "ローカルデバイス検出サービスに異常があります。",
|
||||
"get_cert_error": "ゲートウェイ証明書を取得できませんでした。",
|
||||
"no_family_selected": "家庭が選択されていません。",
|
||||
"no_devices": "選択された家庭にデバイスがありません。デバイスがある家庭を選択して続行してください。",
|
||||
"no_devices": "選択した家庭にはデバイスがありません。デバイスがある家庭を選択して続行してください。",
|
||||
"no_filter_devices": "フィルタリングされたデバイスが空です。有効なフィルター条件を選択して続行してください。",
|
||||
"no_central_device": "【中央ゲートウェイモード】Home Assistant が存在する LAN 内に使用可能な Xiaomi 中央ゲートウェイがある必要があります。選択された家庭がこの要件を満たしているかどうかを確認してください。",
|
||||
"update_config_error": "設定情報の更新に失敗しました。",
|
||||
"not_confirm": "変更項目が確認されていません。確認を選択してから送信してください。"
|
||||
"invalid_network_addr": "無効なIPアドレスまたはHTTPアドレスが検出されました。有効なアドレスを入力してください。",
|
||||
"invalid_ip_addr": "アクセスできないIPアドレスが検出されました。有効なIPアドレスを入力してください。",
|
||||
"invalid_http_addr": "アクセスできないHTTPアドレスが検出されました。有効なHTTPアドレスを入力してください。",
|
||||
"invalid_default_addr": "デフォルトのネットワーク検出アドレスにアクセスできません。ネットワーク設定を確認するか、カスタムネットワーク検出アドレスを使用してください。",
|
||||
"unreachable_oauth2_host": "OAuth2 認証アドレスにアクセスできません。ネットワーク設定を確認してください。",
|
||||
"unreachable_http_host": "Xiaomi HTTP API アドレスにアクセスできません。ネットワーク設定を確認してください。",
|
||||
"unreachable_spec_host": "Xiaomi SPEC API アドレスにアクセスできません。ネットワーク設定を確認してください。",
|
||||
"unreachable_mqtt_broker": "Xiaomi MQTT ブローカーアドレスにアクセスできません。ネットワーク設定を確認してください。"
|
||||
},
|
||||
"abort": {
|
||||
"network_connect_error": "設定に失敗しました。ネットワーク接続に異常があります。デバイスのネットワーク設定を確認してください。",
|
||||
@ -71,15 +111,17 @@
|
||||
},
|
||||
"config_options": {
|
||||
"title": "設定オプション",
|
||||
"description": "### {nick_name} さん、こんにちは!\r\n\r\nXiaomi アカウントID:{uid}\r\n現在のログインエリア:{cloud_server}\r\n\r\n必要な構成オプションを選択して、[次へ] をクリックしてください。",
|
||||
"description": "### {nick_name} さん、こんにちは!\r\n\r\nXiaomi アカウントID:{uid}\r\n現在のログインエリア:{cloud_server}\r\n統合インスタンスID: {instance_id}\r\n\r\n必要な構成オプションを選択して、[次へ] をクリックしてください。",
|
||||
"data": {
|
||||
"integration_language": "統合言語",
|
||||
"update_user_info": "ユーザー情報を更新する",
|
||||
"update_devices": "デバイスリストを更新する",
|
||||
"action_debug": "Action デバッグモード",
|
||||
"hide_non_standard_entities": "非標準生成エンティティを非表示にする",
|
||||
"update_trans_rules": "エンティティ変換ルールを更新する (グローバル設定)",
|
||||
"update_lan_ctrl_config": "LAN制御構成を更新する(グローバル設定)"
|
||||
"display_devices_changed_notify": "デバイスの状態変化通知を表示",
|
||||
"update_trans_rules": "エンティティ変換ルールを更新する",
|
||||
"update_lan_ctrl_config": "LAN制御構成を更新する",
|
||||
"network_detect_config": "統合ネットワーク構成"
|
||||
}
|
||||
},
|
||||
"update_user_info": {
|
||||
@ -89,12 +131,28 @@
|
||||
"nick_name": "ユーザー名"
|
||||
}
|
||||
},
|
||||
"devices_filter": {
|
||||
"homes_select": {
|
||||
"title": "ホームとデバイスを再度選択",
|
||||
"description": "## 使用方法\r\n### 制御モード\r\n- 自動: ローカルエリアネットワーク内に利用可能なXiaomi中央ゲートウェイが存在する場合、Home Assistantは中央ゲートウェイを介してデバイス制御コマンドを優先的に送信し、ローカル制御機能を実現します。ローカルエリアネットワーク内に中央ゲートウェイが存在しない場合、Xiaomi OTプロトコルを介して制御コマンドを送信し、ローカル制御機能を実現しようとします。上記のローカル制御条件が満たされない場合にのみ、デバイス制御コマンドはクラウドを介して送信されます。\r\n- クラウド: 制御コマンドはクラウドを介してのみ送信されます。\r\n### 導入されたデバイスのホーム\r\n統合は、選択された家庭にあるデバイスを追加します。\r\n \r\n### {nick_name} さん、こんにちは! 統合制御モードと追加するデバイスがあるホームを選択してください。",
|
||||
"description": "## 使用方法\r\n### 導入されたデバイスのホーム\r\n統合は、選択された家庭にあるデバイスを追加します。\r\n### デバイスをフィルタリング\r\n家庭の部屋の名前、デバイスの接続タイプ、デバイスのモデルでデバイスをフィルタリングすることをサポートし、デバイスの次元フィルタリングもサポートします。**{local_count}** 個のデバイスがフィルタリングされました。\r\n### 制御モード\r\n- 自動: ローカルエリアネットワーク内に利用可能なXiaomi中央ゲートウェイが存在する場合、Home Assistantは中央ゲートウェイを介してデバイス制御コマンドを優先的に送信し、ローカル制御機能を実現します。ローカルエリアネットワーク内に中央ゲートウェイが存在しない場合、Xiaomi OTプロトコルを介して制御コマンドを送信し、ローカル制御機能を実現しようとします。上記のローカル制御条件が満たされない場合にのみ、デバイス制御コマンドはクラウドを介して送信されます。\r\n- クラウド: 制御コマンドはクラウドを介してのみ送信されます。",
|
||||
"data": {
|
||||
"ctrl_mode": "制御モード",
|
||||
"home_infos": "導入されたデバイスのホーム"
|
||||
"home_infos": "導入されたデバイスのホーム",
|
||||
"devices_filter": "デバイスをフィルタリング",
|
||||
"ctrl_mode": "制御モード"
|
||||
}
|
||||
},
|
||||
"devices_filter": {
|
||||
"title": "デバイスをフィルタリング",
|
||||
"description": "## 使用方法\r\n家庭の部屋の名前、デバイスの接続タイプ、デバイスのモデルでデバイスをフィルタリングすることをサポートし、デバイスの次元フィルタリングもサポートします。フィルタリングロジックは次のとおりです:\r\n- まず、統計ロジックに従って、すべての含まれる項目の和集合または交差を取得し、次に除外される項目の交差または和集合を取得し、最後に[含まれる集計結果]から[除外される集計結果]を引いて[フィルタ結果]を取得します。\r\n- 含まれる項目が選択されていない場合、すべてが含まれることを意味します。\r\n### フィルターモード\r\n- 除外:不要な項目を削除します。\r\n- 含む:必要な項目を含めます。\r\n### 統計ロジック\r\n- ANDロジック:同じモードのすべての項目の交差を取ります。\r\n- ORロジック:同じモードのすべての項目の和集合を取ります。\r\n\r\n統合項目の[設定 > デバイスリストの更新]ページに移動し、[デバイスをフィルタリング]を選択して再フィルタリングすることもできます。",
|
||||
"data": {
|
||||
"room_filter_mode": "家族の部屋をフィルタリング",
|
||||
"room_list": "家族の部屋",
|
||||
"type_filter_mode": "デバイスタイプをフィルタリング",
|
||||
"type_list": "デバイスタイプ",
|
||||
"model_filter_mode": "デバイスモデルをフィルタリング",
|
||||
"model_list": "デバイスモデル",
|
||||
"devices_filter_mode": "デバイスをフィルタリング",
|
||||
"device_list": "デバイスリスト",
|
||||
"statistics_logic": "統計ロジック"
|
||||
}
|
||||
},
|
||||
"update_trans_rules": {
|
||||
@ -112,9 +170,17 @@
|
||||
"enable_subscribe": "LANサブスクリプションを有効にする"
|
||||
}
|
||||
},
|
||||
"network_detect_config": {
|
||||
"title": "統合ネットワーク構成",
|
||||
"description": "## 使用方法の紹介\r\n### ネットワーク検出アドレス\r\nネットワークが正常に機能しているかどうかを確認するために使用されます。設定されていない場合、システムのデフォルトアドレスが使用されます。デフォルトアドレスのチェックが失敗した場合は、カスタムアドレスを入力してみてください。\r\n- 複数の検出アドレスを入力できます。アドレスはコンマで区切ります。例:`8.8.8.8,https://www.bing.com`\r\n- IPアドレスの場合、pingによる検出が行われます。HTTP(s)アドレスの場合、HTTP GETリクエストによる検出が行われます。\r\n- システムのデフォルト検出アドレスを復元する場合は、カンマ `,` を入力して「次へ」をクリックしてください。\r\n- **この設定はグローバルであり、変更は他の統合インスタンスに影響を与えます。慎重に変更してください。**\r\n### ネットワーク依存関係のチェック\r\n次のネットワーク依存関係がアクセス可能かどうかを順番に確認します。関連するアドレスにアクセスできない場合、統合に問題が発生します。\r\n- OAuth2 認証アドレス: `https://account.xiaomi.com/oauth2/authorize`.\r\n- Xiaomi HTTP API アドレス: `https://{http_host}/app/v2/ha/oauth/get_token`.\r\n- Xiaomi SPEC API アドレス: `https://miot-spec.org/miot-spec-v2/template/list/device`.\r\n- Xiaomi MQTT ブローカーアドレス: `mqtts://{cloud_server}-ha.mqtt.io.mi.com:8883`.",
|
||||
"data": {
|
||||
"network_detect_addr": "ネットワーク検出アドレス",
|
||||
"check_network_deps": "ネットワーク依存関係のチェック"
|
||||
}
|
||||
},
|
||||
"config_confirm": {
|
||||
"title": "構成を確認する",
|
||||
"description": "**{nick_name}** さん、こんにちは! 最新の構成情報を確認してください。[送信] をクリックして、更新された構成を使用して再度読み込みます。\r\n\r\n統合言語:\t{lang_new}\r\nユーザー名:\t{nick_name_new}\r\nAction デバッグモード:\t{action_debug}\r\n非標準生成エンティティを非表示にする:\t{hide_non_standard_entities}\r\nデバイス変更:\t追加 **{devices_add}** 個のデバイス、削除 **{devices_remove}** 個のデバイス\r\n変換ルール変更:\t合計 **{trans_rules_count}** 個の規則、更新 **{trans_rules_count_success}** 個の規則",
|
||||
"description": "**{nick_name}** さん、こんにちは! 最新の構成情報を確認してください。[送信] をクリックして、更新された構成を使用して再度読み込みます。\r\n\r\n統合言語:\t{lang_new}\r\nユーザー名:\t{nick_name_new}\r\nAction デバッグモード:\t{action_debug}\r\n非標準生成エンティティを非表示にする:\t{hide_non_standard_entities}\r\nデバイスの状態変化通知を表示:\t{display_devices_changed_notify}\r\nデバイス変更:\t追加 **{devices_add}** 個のデバイス、削除 **{devices_remove}** 個のデバイス\r\n変換ルール変更:\t合計 **{trans_rules_count}** 個の規則、更新 **{trans_rules_count_success}** 個の規則",
|
||||
"data": {
|
||||
"confirm": "変更を確認する"
|
||||
}
|
||||
@ -129,11 +195,20 @@
|
||||
"get_homeinfo_error": "家庭情報の取得に失敗しました。",
|
||||
"get_cert_error": "中枢証明書の取得に失敗しました。",
|
||||
"no_family_selected": "家族が選択されていません。",
|
||||
"no_devices": "選択された家庭にはデバイスがありません。デバイスがある家庭を選択してから続行してください。",
|
||||
"no_devices": "選択した家庭にはデバイスがありません。デバイスがある家庭を選択して続行してください。",
|
||||
"no_filter_devices": "フィルタリングされたデバイスが空です。有効なフィルター条件を選択して続行してください。",
|
||||
"no_central_device": "【中枢ゲートウェイモード】には、Home Assistantが存在するローカルネットワークに使用可能なXiaomi Central Hub Gatewayが存在する必要があります。選択された家庭がこの要件を満たしているかどうかを確認してください。",
|
||||
"mdns_discovery_error": "ローカルデバイス発見サービスが異常です。",
|
||||
"update_config_error": "構成情報の更新に失敗しました。",
|
||||
"not_confirm": "変更を確認していません。確認をチェックしてから送信してください。"
|
||||
"not_confirm": "変更を確認していません。確認をチェックしてから送信してください。",
|
||||
"invalid_network_addr": "無効なIPアドレスまたはHTTPアドレスが検出されました。有効なアドレスを入力してください。",
|
||||
"invalid_ip_addr": "アクセスできないIPアドレスが検出されました。有効なIPアドレスを入力してください。",
|
||||
"invalid_http_addr": "アクセスできないHTTPアドレスが検出されました。有効なHTTPアドレスを入力してください。",
|
||||
"invalid_default_addr": "デフォルトのネットワーク検出アドレスにアクセスできません。ネットワーク設定を確認するか、カスタムネットワーク検出アドレスを使用してください。",
|
||||
"unreachable_oauth2_host": "OAuth2 認証アドレスにアクセスできません。ネットワーク設定を確認してください。",
|
||||
"unreachable_http_host": "Xiaomi HTTP API アドレスにアクセスできません。ネットワーク設定を確認してください。",
|
||||
"unreachable_spec_host": "Xiaomi SPEC API アドレスにアクセスできません。ネットワーク設定を確認してください。",
|
||||
"unreachable_mqtt_broker": "Xiaomi MQTT ブローカーアドレスにアクセスできません。ネットワーク設定を確認してください。"
|
||||
},
|
||||
"abort": {
|
||||
"network_connect_error": "構成に失敗しました。ネットワーク接続に異常があります。デバイスのネットワーク構成を確認してください。",
|
||||
|
221
custom_components/xiaomi_home/translations/nl.json
Normal file
221
custom_components/xiaomi_home/translations/nl.json
Normal file
@ -0,0 +1,221 @@
|
||||
{
|
||||
"config": {
|
||||
"flow_title": "Xiaomi Home Integratie",
|
||||
"step": {
|
||||
"eula": {
|
||||
"title": "Risiconotitie",
|
||||
"description": "1. Uw Xiaomi-gebruikersinformatie en apparaatinformatie worden opgeslagen in het Home Assistant-systeem. **Xiaomi kan de beveiliging van het opslagmechanisme van Home Assistant niet garanderen**. U bent verantwoordelijk voor het voorkomen dat uw informatie wordt gestolen.\r\n2. Deze integratie wordt onderhouden door de open-sourcegemeenschap. Er kunnen stabiliteitsproblemen of andere problemen optreden. Bij problemen of fouten met deze integratie, **moet u hulp zoeken bij de open-sourcegemeenschap in plaats van contact op te nemen met de Xiaomi klantenservice**.\r\n3. U heeft enige technische vaardigheden nodig om uw lokale werkomgeving te onderhouden. De integratie is niet gebruiksvriendelijk voor beginners.\r\n4. Lees het README-bestand voordat u begint.\n\n5. Om een stabiel gebruik van de integratie te waarborgen en misbruik van de interface te voorkomen, **mag deze integratie alleen worden gebruikt in Home Assistant. Voor details, zie de LICENSE**.",
|
||||
"data": {
|
||||
"eula": "Ik ben me bewust van de bovenstaande risico's en bereid om vrijwillig alle risico's die gepaard gaan met het gebruik van de integratie te aanvaarden."
|
||||
}
|
||||
},
|
||||
"auth_config": {
|
||||
"title": "Basisconfiguratie",
|
||||
"description": "### Inlogregio\r\nSelecteer de regio van uw Xiaomi-account. U kunt deze vinden in de Xiaomi Home APP > Profiel (onderin het menu) > Extra instellingen > Over Xiaomi Home.\r\n### Taal\r\nKies de taal voor de apparaats- en entiteitsnamen. Sommige zinnen zonder vertaling worden in het Engels weergegeven.\r\n### OAuth2 Omleidings-URL\r\nHet OAuth2 authenticatie omleidingsadres is **[http://homeassistant.local:8123](http://homeassistant.local:8123)**. Home Assistant moet zich in hetzelfde lokale netwerk bevinden als de huidige werkterminal (bijv. de persoonlijke computer) en de werkterminal moet toegang hebben tot de startpagina van Home Assistant via dit adres. Anders kan de inlogauthenticatie mislukken.\r\n### Geïntegreerde Netwerkconfiguratie\r\nControleer of het lokale netwerk correct functioneert en of de gerelateerde netwerkbronnen toegankelijk zijn. **Het wordt aanbevolen om dit te selecteren bij het eerste toevoegen.**\r\n### Opmerking\r\n- Voor gebruikers met honderden of meer Mi Home-apparaten kan het aanvankelijke toevoegen van de integratie enige tijd duren. Wees geduldig.\r\n- Als Home Assistant draait in een Docker-omgeving, zorg er dan voor dat de Docker-netwerkmodus is ingesteld op host, anders werkt de lokale controlefunctionaliteit mogelijk niet correct.\r\n- De lokale controlefunctionaliteit van de integratie heeft enkele afhankelijkheden. Lees het README zorgvuldig.",
|
||||
"data": {
|
||||
"cloud_server": "Inlogregio",
|
||||
"integration_language": "Taal",
|
||||
"oauth_redirect_url": "OAuth2 Omleidings-URL",
|
||||
"network_detect_config": "Geïntegreerde Netwerkconfiguratie"
|
||||
}
|
||||
},
|
||||
"network_detect_config": {
|
||||
"title": "Geïntegreerde Netwerkconfiguratie",
|
||||
"description": "## Gebruiksinstructie\r\n### Netwerkdetectieadres\r\nWordt gebruikt om te controleren of het netwerk correct functioneert. Als dit niet is ingesteld, wordt het standaardadres van het systeem gebruikt. Als de standaardadrescontrole mislukt, kunt u proberen een aangepast adres in te voeren.\r\n- U kunt meerdere detectieadressen invoeren, gescheiden door komma's, zoals `8.8.8.8,https://www.bing.com`\r\n- Als het een IP-adres is, wordt de detectie uitgevoerd via ping. Als het een HTTP(s)-adres is, wordt de detectie uitgevoerd via een HTTP GET-verzoek.\r\n- Als u het standaarddetectieadres van het systeem wilt herstellen, voert u een komma `,` in en klikt u op 'Volgende'.\r\n- **Deze configuratie is globaal en wijzigingen zullen andere integratie-instanties beïnvloeden. Wijzig met voorzichtigheid.**\r\n### Controleer Netwerkafhankelijkheden\r\nControleer een voor een de volgende netwerkafhankelijkheden om te zien of ze toegankelijk zijn. Als de gerelateerde adressen niet toegankelijk zijn, zal dit integratieproblemen veroorzaken.\r\n- OAuth2-authenticatieadres: `https://account.xiaomi.com/oauth2/authorize`.\r\n- Xiaomi HTTP API-adres: `https://{http_host}/app/v2/ha/oauth/get_token`.\r\n- Xiaomi SPEC API-adres: `https://miot-spec.org/miot-spec-v2/template/list/device`.\r\n- Xiaomi MQTT Broker-adres: `mqtts://{cloud_server}-ha.mqtt.io.mi.com:8883`.",
|
||||
"data": {
|
||||
"network_detect_addr": "Netwerkdetectieadres",
|
||||
"check_network_deps": "Controleer Netwerkafhankelijkheden"
|
||||
}
|
||||
},
|
||||
"oauth_error": {
|
||||
"title": "Inlogfout",
|
||||
"description": "Klik OP VOLGENDE om het opnieuw te proberen."
|
||||
},
|
||||
"homes_select": {
|
||||
"title": "Selecteer Familie en Apparaat",
|
||||
"description": "## Inleiding\r\n### Importeer de familie van het apparaat\r\nDe integratie voegt apparaten toe uit de geselecteerde familie.\r\n### Kamernaam Synchronisatiemodus\r\nBij het synchroniseren van apparaten van de Mi Home-app naar Home Assistant, wordt de naam van het gebied in Home Assistant volgens de volgende regels genoemd. Houd er rekening mee dat het synchronisatieproces de instellingen van familie en kamer in de Mi Home-app niet zal wijzigen.\r\n- Niet synchroniseren: Het apparaat wordt niet aan een gebied toegevoegd.\r\n- Andere opties: Het gebied waaraan het apparaat wordt toegevoegd, wordt genoemd naar de familie- of kamernaam in de Mi Home-app.\r\n### Geavanceerde instellingen\r\nToon geavanceerde instellingen om de professionele configuratie-opties van de integratie te wijzigen.\r\n\r\n \r\n### {nick_name} Hallo! Selecteer de familie waaraan u het apparaat wilt toevoegen.",
|
||||
"data": {
|
||||
"home_infos": "Importeer de familie van het apparaat",
|
||||
"area_name_rule": "Kamernaam Synchronisatiemodus",
|
||||
"advanced_options": "Geavanceerde instellingen"
|
||||
}
|
||||
},
|
||||
"advanced_options": {
|
||||
"title": "Geavanceerde Instellingen",
|
||||
"description": "## Inleiding\r\n### Tenzij u zeer goed op de hoogte bent van de betekenis van de volgende opties, houdt u de standaardinstellingen.\r\n### Apparaten filteren\r\nOndersteunt het filteren van apparaten op basis van kamer- en apparaattypen, en ondersteunt ook apparaatdimensiefiltering.\r\n### Besturingsmodus\r\n- Automatisch: Wanneer er een beschikbare Xiaomi centrale hubgateway in het lokale netwerk is, zal Home Assistant eerst apparaatbesturingsinstructies via de centrale hubgateway verzenden om lokale controlefunctionaliteit te bereiken. Als er geen centrale hub in het lokale netwerk is, zal het proberen om besturingsinstructies via het Xiaomi OT-protocol te verzenden om lokale controlefunctionaliteit te bereiken. Alleen als de bovenstaande lokale controlevoorwaarden niet worden vervuld, worden apparaatbesturingsinstructies via de cloud verzonden.\r\n- Cloud: Besturingsinstructies worden alleen via de cloud verzonden.\r\n### Actie-debugmodus\r\nVoor methoden die zijn gedefinieerd in de MIoT-Spec-V2 van het apparaat, wordt naast het genereren van een meldingsentiteit ook een tekstinvoerveldentiteit gegenereerd. U kunt dit gebruiken om besturingsinstructies naar het apparaat te sturen tijdens het debuggen.\r\n### Niet-standaard entiteiten verbergen\r\nVerberg entiteiten die zijn gegenereerd door niet-standaard MIoT-Spec-V2-instanties die beginnen met \"*\".\r\n### Apparaatstatuswijzigingen weergeven\r\nGedetailleerde apparaatstatuswijzigingen weergeven, alleen de geselecteerde meldingen weergeven.",
|
||||
"data": {
|
||||
"devices_filter": "Apparaten filteren",
|
||||
"ctrl_mode": "Besturingsmodus",
|
||||
"action_debug": "Actie-debugmodus",
|
||||
"hide_non_standard_entities": "Niet-standaard entiteiten verbergen",
|
||||
"display_devices_changed_notify": "Apparaatstatuswijzigingen weergeven"
|
||||
}
|
||||
},
|
||||
"devices_filter": {
|
||||
"title": "Apparaten filteren",
|
||||
"description": "## Gebruiksinstructies\r\nOndersteunt het filteren van apparaten op kamernaam, apparaattoegangstype en apparaattype, en ondersteunt ook het filteren op apparaatdimensie. De filterlogica is als volgt:\r\n- Eerst, volgens de statistische logica, de vereniging of doorsnede van alle opgenomen items verkrijgen, vervolgens de doorsnede of vereniging van de uitgesloten items verkrijgen, en ten slotte het [opgenomen samenvattingsresultaat] aftrekken van het [uitgesloten samenvattingsresultaat] om het [filterresultaat] te verkrijgen.\r\n- Als er geen opgenomen items zijn geselecteerd, betekent dit dat alles is opgenomen.\r\n### Filtermodus\r\n- Uitsluiten: Ongewenste items verwijderen.\r\n- Opnemen: Gewenste items opnemen.\r\n### Statistische Logica\r\n- EN-logica: Neem de doorsnede van alle items in dezelfde modus.\r\n- OF-logica: Neem de vereniging van alle items in dezelfde modus.\r\n\r\nU kunt ook naar de pagina [Configuratie > Apparaatlijst bijwerken] van het integratie-item gaan, [Apparaten filteren] aanvinken om opnieuw te filteren.",
|
||||
"data": {
|
||||
"room_filter_mode": "Kamerfiltermodus",
|
||||
"room_list": "Kamers",
|
||||
"type_filter_mode": "Apparaattypen filteren",
|
||||
"type_list": "Apparaattypen",
|
||||
"model_filter_mode": "Apparaatmodel filteren",
|
||||
"model_list": "Apparaatmodellen",
|
||||
"devices_filter_mode": "Apparaten filteren",
|
||||
"device_list": "Apparaatlijst",
|
||||
"statistics_logic": "Statistische logica"
|
||||
}
|
||||
}
|
||||
},
|
||||
"progress": {
|
||||
"oauth": "### {link_left}Klik hier om in te loggen{link_right}\r\n(U wordt automatisch doorgestuurd naar de volgende pagina na succesvolle inlog)"
|
||||
},
|
||||
"error": {
|
||||
"eula_not_agree": "Lees de risiconotitie.",
|
||||
"get_token_error": "Mislukt bij het ophalen van inlogautorisatie-informatie (OAuth-token).",
|
||||
"get_homeinfo_error": "Mislukt bij het ophalen van huisinformatie.",
|
||||
"mdns_discovery_error": "Lokaal apparaatsontdekkingsservice-exceptie.",
|
||||
"get_cert_error": "Mislukt bij het ophalen van het certificaat van de centrale hubgateway.",
|
||||
"no_family_selected": "Geen huis geselecteerd.",
|
||||
"no_devices": "Er zijn geen apparaten in het geselecteerde huis. Selecteer een huis met apparaten en ga verder.",
|
||||
"no_filter_devices": "Gefilterde apparaten zijn leeg. Selecteer geldige filtercriteria en ga verder.",
|
||||
"no_central_device": "[Centrale Hub Gateway Modus] vereist een beschikbare Xiaomi centrale hubgateway in het lokale netwerk waar Home Assistant zich bevindt. Controleer of het geselecteerde huis aan deze vereiste voldoet.",
|
||||
"invalid_network_addr": "Ongeldig IP-adres of HTTP-adres gedetecteerd, voer een geldig adres in.",
|
||||
"invalid_ip_addr": "Onbereikbaar IP-adres gedetecteerd, voer een geldig IP-adres in.",
|
||||
"invalid_http_addr": "Onbereikbaar HTTP-adres gedetecteerd, voer een geldig HTTP-adres in.",
|
||||
"invalid_default_addr": "Standaard netwerkdetectieadres is onbereikbaar, controleer de netwerkconfiguratie of gebruik een aangepast netwerkdetectieadres.",
|
||||
"unreachable_oauth2_host": "Kan OAuth2-authenticatieadres niet bereiken, controleer de netwerkconfiguratie.",
|
||||
"unreachable_http_host": "Kan Xiaomi HTTP API-adres niet bereiken, controleer de netwerkconfiguratie.",
|
||||
"unreachable_spec_host": "Kan Xiaomi SPEC API-adres niet bereiken, controleer de netwerkconfiguratie.",
|
||||
"unreachable_mqtt_broker": "Kan Xiaomi MQTT Broker-adres niet bereiken, controleer de netwerkconfiguratie."
|
||||
},
|
||||
"abort": {
|
||||
"network_connect_error": "Configuratie mislukt. De netwerkverbinding is abnormaal. Controleer de netwerkinstellingen van de apparatuur.",
|
||||
"already_configured": "Configuratie voor deze gebruiker is al voltooid. Ga naar de integratiepagina en klik op de CONFIGUREER-knop om wijzigingen aan te brengen.",
|
||||
"invalid_auth_info": "Authenticatie-informatie is verlopen. Ga naar de integratiepagina en klik op de CONFIGUREER-knop om opnieuw te authentiseren.",
|
||||
"config_flow_error": "Integratie configuratiefout: {error}."
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"step": {
|
||||
"auth_config": {
|
||||
"title": "Authenticatieconfiguratie",
|
||||
"description": "Lokale authenticatie-informatie is verlopen. Begin alstublieft het authenticatieproces opnieuw.\r\n### Huidige inlogregio: {cloud_server}\r\n### OAuth2 Omleidings-URL\r\nHet OAuth2 authenticatie omleidingsadres is **[http://homeassistant.local:8123](http://homeassistant.local:8123)**. Home Assistant moet zich in hetzelfde lokale netwerk bevinden als de huidige werkterminal (bijv. de persoonlijke computer) en de werkterminal moet toegang hebben tot de startpagina van Home Assistant via dit adres. Anders kan de inlogauthenticatie mislukken.",
|
||||
"data": {
|
||||
"oauth_redirect_url": "OAuth2 Omleidings-URL"
|
||||
}
|
||||
},
|
||||
"oauth_error": {
|
||||
"title": "Er is een fout opgetreden tijdens het inloggen.",
|
||||
"description": "Klik OP VOLGENDE om opnieuw te proberen."
|
||||
},
|
||||
"config_options": {
|
||||
"title": "Configuratie-opties",
|
||||
"description": "### Hallo, {nick_name}\r\n\r\nXiaomi ID: {uid}\r\nHuidige inlogregio: {cloud_server}\r\nIntegratie-instantie-ID: {instance_id}\r\n\r\nKies de opties die u wilt configureren en klik vervolgens op VOLGENDE.",
|
||||
"data": {
|
||||
"integration_language": "Integratietaal",
|
||||
"update_user_info": "Werk gebruikersinformatie bij",
|
||||
"update_devices": "Werk apparatenlijst bij",
|
||||
"action_debug": "Debugmodus voor actie",
|
||||
"hide_non_standard_entities": "Verberg niet-standaard gemaakte entiteiten",
|
||||
"display_devices_changed_notify": "Apparaatstatuswijzigingen weergeven",
|
||||
"update_trans_rules": "Werk entiteitsconversieregels bij",
|
||||
"update_lan_ctrl_config": "Werk LAN controleconfiguratie bij",
|
||||
"network_detect_config": "Geïntegreerde Netwerkconfiguratie"
|
||||
}
|
||||
},
|
||||
"update_user_info": {
|
||||
"title": "Bijwerken van gebruikersnickname",
|
||||
"description": "Hallo {nick_name}, u kunt uw aangepaste bijnaam hieronder wijzigen.",
|
||||
"data": {
|
||||
"nick_name": "Bijnaam"
|
||||
}
|
||||
},
|
||||
"homes_select": {
|
||||
"title": "Huis en Apparaten opnieuw selecteren",
|
||||
"description": "## Gebruiksinstructies\r\n### Importeer apparaten uit huis\r\nDe integratie voegt apparaten toe van de geselecteerde huizen.\r\n### Apparaten filteren\r\nOndersteunt het filteren van apparaten op kamernaam, apparaattoegangstype en apparaattype, en ondersteunt ook het filteren op apparaatdimensie. **{local_count}** apparaten zijn gefilterd.\r\n### Controlemodus\r\n- Auto: Wanneer er een beschikbare Xiaomi centrale hubgateway in het lokale netwerk is, geeft Home Assistant de voorkeur aan het verzenden van apparaatbedieningscommando's via de centrale hubgateway om lokale controle te bereiken. Als er geen centrale hubgateway in het lokale netwerk is, zal het proberen bedieningscommando's te verzenden via de Xiaomi LAN-controlefunctie. Alleen wanneer de bovenstaande lokale controlevoorwaarden niet zijn vervuld, worden de apparaatbedieningscommando's via de cloud verzonden.\r\n- Cloud: Alle bedieningscommando's worden via de cloud verzonden.",
|
||||
"data": {
|
||||
"home_infos": "Importeer apparaten uit huis",
|
||||
"devices_filter": "Apparaten filteren",
|
||||
"ctrl_mode": "Controlemodus"
|
||||
}
|
||||
},
|
||||
"devices_filter": {
|
||||
"title": "Apparaten filteren",
|
||||
"description": "## Gebruiksinstructies\r\nOndersteunt het filteren van apparaten op kamernaam, apparaattoegangstype en apparaattype, en ondersteunt ook het filteren op apparaatdimensie. De filterlogica is als volgt:\r\n- Eerst, volgens de statistische logica, de vereniging of doorsnede van alle opgenomen items verkrijgen, vervolgens de doorsnede of vereniging van de uitgesloten items verkrijgen, en ten slotte het [opgenomen samenvattingsresultaat] aftrekken van het [uitgesloten samenvattingsresultaat] om het [filterresultaat] te verkrijgen.\r\n- Als er geen opgenomen items zijn geselecteerd, betekent dit dat alles is opgenomen.\r\n### Filtermodus\r\n- Uitsluiten: Ongewenste items verwijderen.\r\n- Opnemen: Gewenste items opnemen.\r\n### Statistische Logica\r\n- EN-logica: Neem de doorsnede van alle items in dezelfde modus.\r\n- OF-logica: Neem de vereniging van alle items in dezelfde modus.\r\n\r\nU kunt ook naar de pagina [Configuratie > Apparaatlijst bijwerken] van het integratie-item gaan, [Apparaten filteren] aanvinken om opnieuw te filteren.",
|
||||
"data": {
|
||||
"room_filter_mode": "Kamerfiltermodus",
|
||||
"room_list": "Kamers",
|
||||
"type_filter_mode": "Apparaattypen filteren",
|
||||
"type_list": "Apparaattypen",
|
||||
"model_filter_mode": "Apparaatmodel filteren",
|
||||
"model_list": "Apparaatmodellen",
|
||||
"devices_filter_mode": "Apparaten filteren",
|
||||
"device_list": "Apparaatlijst",
|
||||
"statistics_logic": "Statistische logica"
|
||||
}
|
||||
},
|
||||
"update_trans_rules": {
|
||||
"title": "Bijwerken van entiteiten transformateregels",
|
||||
"description": "## Gebruiksinstructies\r\n- Werk de entiteitsinformatie van apparaten in de huidige integratie-instantie bij, inclusief MIoT-Spec-V2 meertalige configuratie, booleanvertaling en modelfiltering.\r\n- **Waarschuwing**: Dit is een globale configuratie en zal de lokale cache bijwerken. Dit zal alle integratie-instanties beïnvloeden.\r\n- Deze handeling duurt enige tijd, wees geduldig. Vink \"Bevestig bijwerken\" aan en klik op \"Volgende\" om **{urn_count}** regels bij te werken, anders overslaan.",
|
||||
"data": {
|
||||
"confirm": "Bevestig de update"
|
||||
}
|
||||
},
|
||||
"update_lan_ctrl_config": {
|
||||
"title": "Update LAN controleconfiguratie",
|
||||
"description": "## Gebruiksinstructies\r\nWerk de configuraties voor de Xiaomi LAN controlefunctie bij. Wanneer de cloud en de centrale hubgateway de apparaten niet kunnen bedienen, zal de integratie proberen de apparaten via het LAN te bedienen. Als er geen netwerkkaart is geselecteerd, zal de LAN controlefunctie niet werken.\r\n- Alleen MIoT-Spec-V2 compatibele IP-apparaten in het LAN worden ondersteund. Sommige apparaten die vóór 2020 zijn geproduceerd, ondersteunen mogelijk geen LAN controle of LAN abonnement.\r\n- Selecteer de netwerkkaart(en) op hetzelfde netwerk als de te bedienen apparaten. Meerdere netwerkkaarten kunnen worden geselecteerd. Als Home Assistant vanwege de meervoudige selectie van de netwerkkaarten twee of meer verbindingen heeft met het lokale netwerk, wordt aanbevolen om de verbinding met de beste netwerkverbinding te selecteren, anders kan dit een negatief effect hebben op de apparaten.\r\n- Als er terminalapparaten (Xiaomi-luidsprekers met scherm, mobiele telefoons, enz.) in het LAN zijn die lokale controle ondersteunen, kan het inschakelen van LAN-abonnement leiden tot lokale automatisering- en apparaatanomalieën.\r\n- **Waarschuwing**: Dit is een globale configuratie. Het zal alle integratie-instanties beïnvloeden. Gebruik het met voorzichtigheid.\r\n{notice_net_dup}",
|
||||
"data": {
|
||||
"net_interfaces": "Selecteer alstublieft de te gebruiken netwerkkaart",
|
||||
"enable_subscribe": "Zet LAN-abonnement aan"
|
||||
}
|
||||
},
|
||||
"network_detect_config": {
|
||||
"title": "Geïntegreerde Netwerkconfiguratie",
|
||||
"description": "## Gebruiksinstructie\r\n### Netwerkdetectieadres\r\nWordt gebruikt om te controleren of het netwerk correct functioneert. Als dit niet is ingesteld, wordt het standaardadres van het systeem gebruikt. Als de standaardadrescontrole mislukt, kunt u proberen een aangepast adres in te voeren.\r\n- U kunt meerdere detectieadressen invoeren, gescheiden door komma's, zoals `8.8.8.8,https://www.bing.com`\r\n- Als het een IP-adres is, wordt de detectie uitgevoerd via ping. Als het een HTTP(s)-adres is, wordt de detectie uitgevoerd via een HTTP GET-verzoek.\r\n- Als u het standaarddetectieadres van het systeem wilt herstellen, voert u een komma `,` in en klikt u op 'Volgende'.\r\n- **Deze configuratie is globaal en wijzigingen zullen andere integratie-instanties beïnvloeden. Wijzig met voorzichtigheid.**\r\n### Controleer Netwerkafhankelijkheden\r\nControleer een voor een de volgende netwerkafhankelijkheden om te zien of ze toegankelijk zijn. Als de gerelateerde adressen niet toegankelijk zijn, zal dit integratieproblemen veroorzaken.\r\n- OAuth2-authenticatieadres: `https://account.xiaomi.com/oauth2/authorize`.\r\n- Xiaomi HTTP API-adres: `https://{http_host}/app/v2/ha/oauth/get_token`.\r\n- Xiaomi SPEC API-adres: `https://miot-spec.org/miot-spec-v2/template/list/device`.\r\n- Xiaomi MQTT Broker-adres: `mqtts://{cloud_server}-ha.mqtt.io.mi.com:8883`.",
|
||||
"data": {
|
||||
"network_detect_addr": "Netwerkdetectieadres",
|
||||
"check_network_deps": "Controleer Netwerkafhankelijkheden"
|
||||
}
|
||||
},
|
||||
"config_confirm": {
|
||||
"title": "Bevestig Configuratie",
|
||||
"description": "Hallo **{nick_name}**, bevestig alstublieft de nieuwste configuratie-informatie en klik vervolgens op INDENKEN.\r\nDe integratie zal opnieuw laden met de bijgewerkte configuratie.\r\n\r\nIntegratietaal: \t{lang_new}\r\nBijnaam: \t{nick_name_new}\r\nDebugmodus voor actie: \t{action_debug}\r\nVerberg niet-standaard gemaakte entiteiten: \t{hide_non_standard_entities}\r\nApparaatstatuswijzigingen weergeven:\t{display_devices_changed_notify}\r\nWijzigingen in apparaten: \tVoeg **{devices_add}** apparaten toe, Verwijder **{devices_remove}** apparaten\r\nWijzigingen in transformateregels: \tEr zijn in totaal **{trans_rules_count}** regels, en **{trans_rules_count_success}** regels zijn bijgewerkt",
|
||||
"data": {
|
||||
"confirm": "Bevestig de wijziging"
|
||||
}
|
||||
}
|
||||
},
|
||||
"progress": {
|
||||
"oauth": "### {link_left}Klik hier om opnieuw in te loggen{link_right}"
|
||||
},
|
||||
"error": {
|
||||
"not_auth": "Niet geauthenticeerd. Klik op de authenticatielink om de gebruikersidentiteit te verifiëren.",
|
||||
"get_token_error": "Mislukt bij het ophalen van inlogautorisatie-informatie (OAuth-token).",
|
||||
"get_homeinfo_error": "Mislukt bij het ophalen van huisinformatie.",
|
||||
"get_cert_error": "Mislukt bij het ophalen van het certificaat van de centrale hubgateway.",
|
||||
"no_devices": "Er zijn geen apparaten in het geselecteerde huis. Selecteer een huis met apparaten en ga verder.",
|
||||
"no_filter_devices": "Gefilterde apparaten zijn leeg. Selecteer geldige filtercriteria en ga verder.",
|
||||
"no_family_selected": "Geen huis geselecteerd.",
|
||||
"no_central_device": "[Centrale Hub Gateway Modus] vereist een beschikbare Xiaomi centrale hubgateway in het lokale netwerk waar Home Assistant zich bevindt. Controleer of het geselecteerde huis aan deze vereiste voldoet.",
|
||||
"mdns_discovery_error": "Lokaal apparaatsontdekkingsservice-exceptie.",
|
||||
"update_config_error": "Mislukt bij het bijwerken van configuratie-informatie.",
|
||||
"not_confirm": "Wijzigingen zijn niet bevestigd. Bevestig de wijziging voordat u deze indient.",
|
||||
"invalid_network_addr": "Ongeldig IP-adres of HTTP-adres gedetecteerd, voer een geldig adres in.",
|
||||
"invalid_ip_addr": "Onbereikbaar IP-adres gedetecteerd, voer een geldig IP-adres in.",
|
||||
"invalid_http_addr": "Onbereikbaar HTTP-adres gedetecteerd, voer een geldig HTTP-adres in.",
|
||||
"invalid_default_addr": "Standaard netwerkdetectieadres is onbereikbaar, controleer de netwerkconfiguratie of gebruik een aangepast netwerkdetectieadres.",
|
||||
"unreachable_oauth2_host": "Kan OAuth2-authenticatieadres niet bereiken, controleer de netwerkconfiguratie.",
|
||||
"unreachable_http_host": "Kan Xiaomi HTTP API-adres niet bereiken, controleer de netwerkconfiguratie.",
|
||||
"unreachable_spec_host": "Kan Xiaomi SPEC API-adres niet bereiken, controleer de netwerkconfiguratie.",
|
||||
"unreachable_mqtt_broker": "Kan Xiaomi MQTT Broker-adres niet bereiken, controleer de netwerkconfiguratie."
|
||||
},
|
||||
"abort": {
|
||||
"network_connect_error": "Configuratie mislukt. De netwerkverbinding is abnormaal. Controleer de netwerkinstellingen van de apparatuur.",
|
||||
"options_flow_error": "Integratie herconfiguratiefout: {error}",
|
||||
"re_add": "Voeg de integratie opnieuw toe. Foutmelding: {error}",
|
||||
"storage_error": "Integratie opslagmodule-exceptie. Probeer het opnieuw of voeg de integratie opnieuw toe: {error}",
|
||||
"inconsistent_account": "Accountinformatie is inconsistent. Log in met het juiste account."
|
||||
}
|
||||
}
|
||||
}
|
221
custom_components/xiaomi_home/translations/pt-BR.json
Normal file
221
custom_components/xiaomi_home/translations/pt-BR.json
Normal file
@ -0,0 +1,221 @@
|
||||
{
|
||||
"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### Configuração de Rede Integrada\r\nVerifique se a rede local está funcionando corretamente e se os recursos de rede relacionados estão acessíveis. **Recomenda-se selecionar isso ao adicionar pela primeira vez.**\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",
|
||||
"network_detect_config": "Configuração de Rede Integrada"
|
||||
}
|
||||
},
|
||||
"network_detect_config": {
|
||||
"title": "Configuração de Detecção de Rede",
|
||||
"description": "## Introdução ao Uso\r\n### Endereço de Detecção de Rede\r\nUsado para verificar se a rede está funcionando corretamente. Se não for definido, o endereço padrão do sistema será usado. Se a verificação do endereço padrão falhar, você pode tentar inserir um endereço personalizado.\r\n- Você pode inserir vários endereços de detecção, separados por vírgulas, como `8.8.8.8,https://www.bing.com`\r\n- Se for um endereço IP, a detecção será feita via ping. Se for um endereço HTTP(s), a detecção será feita via solicitação HTTP GET.\r\n- Se você deseja restaurar o endereço de detecção padrão do sistema, insira uma vírgula `,` e clique em 'Próximo'.\r\n- **Esta configuração é global e as alterações afetarão outras instâncias de integração. Modifique com cautela.**\r\n### Verificar Dependências de Rede\r\nVerifique uma por uma as seguintes dependências de rede para ver se são acessíveis. Se os endereços relacionados não forem acessíveis, isso causará problemas de integração.\r\n- Endereço de Autenticação OAuth2: `https://account.xiaomi.com/oauth2/authorize`.\r\n- Endereço da API HTTP da Xiaomi: `https://{http_host}/app/v2/ha/oauth/get_token`.\r\n- Endereço da API SPEC da Xiaomi: `https://miot-spec.org/miot-spec-v2/template/list/device`.\r\n- Endereço do Broker MQTT da Xiaomi: `mqtts://{cloud_server}-ha.mqtt.io.mi.com:8883`.",
|
||||
"data": {
|
||||
"network_detect_addr": "Endereço de Detecção de Rede",
|
||||
"check_network_deps": "Verificar Dependências de Rede"
|
||||
}
|
||||
},
|
||||
"oauth_error": {
|
||||
"title": "Erro de Login",
|
||||
"description": "Clique em AVANÇAR para tentar novamente."
|
||||
},
|
||||
"homes_select": {
|
||||
"title": "Selecionar Família e Dispositivo",
|
||||
"description": "## Introdução\r\n### Importar a Família do Dispositivo\r\nA integração adicionará dispositivos da família selecionada.\r\n### Modo de Sincronização do Nome da Sala\r\nAo sincronizar dispositivos do APP Mi Home para o Home Assistant, a nomeação da área no Home Assistant seguirá as regras abaixo. Observe que o processo de sincronização não alterará as configurações de família e sala no APP Mi Home.\r\n- Não sincronizar: O dispositivo não será adicionado a nenhuma área.\r\n- Outras opções: A área à qual o dispositivo é adicionado será nomeada de acordo com o nome da família ou da sala no APP Mi Home.\r\n### Configurações Avançadas\r\nMostrar configurações avançadas para modificar as opções de configuração profissional da integração.\r\n\r\n \r\n### {nick_name} Olá! Por favor, selecione a família à qual você deseja adicionar o dispositivo.",
|
||||
"data": {
|
||||
"home_infos": "Importar a Família do Dispositivo",
|
||||
"area_name_rule": "Modo de Sincronização do Nome da Sala",
|
||||
"advanced_options": "Configurações Avançadas"
|
||||
}
|
||||
},
|
||||
"advanced_options": {
|
||||
"title": "Configurações Avançadas",
|
||||
"description": "## Introdução\r\n### A menos que você entenda claramente o significado das opções a seguir, mantenha as configurações padrão.\r\n### Filtrar Dispositivos\r\nSuporte para filtrar dispositivos por nome da sala e tipo de dispositivo, bem como filtragem por família.\r\n### Modo de Controle\r\n- Automático: Quando um gateway central Xiaomi disponível na rede local está disponível, o Home Assistant enviará comandos de controle de dispositivo através do gateway central para realizar a função de controle local. Quando não há gateway central na rede local, ele tentará enviar comandos de controle através do protocolo OT da Xiaomi para realizar a função de controle local. Somente quando as condições de controle local acima não forem atendidas, os comandos de controle do dispositivo serão enviados através da nuvem.\r\n- Nuvem: Os comandos de controle são enviados apenas através da nuvem.\r\n### Modo de Depuração de Ações\r\nPara métodos definidos pelo MIoT-Spec-V2 do dispositivo, além de gerar uma entidade de notificação, também será gerada uma entidade de caixa de texto para você enviar comandos de controle ao dispositivo durante a depuração.\r\n### Ocultar Entidades Geradas Não Padrão\r\nOcultar entidades geradas por instâncias MIoT-Spec-V2 não padrão que começam com \"*\".\r\n### Exibir notificações de mudança de status do dispositivo\r\nExibir notificações detalhadas de mudança de status do dispositivo, mostrando apenas as notificações selecionadas.",
|
||||
"data": {
|
||||
"devices_filter": "Filtrar Dispositivos",
|
||||
"ctrl_mode": "Modo de Controle",
|
||||
"action_debug": "Modo de Depuração de Ações",
|
||||
"hide_non_standard_entities": "Ocultar Entidades Geradas Não Padrão",
|
||||
"display_devices_changed_notify": "Exibir notificações de mudança de status do dispositivo"
|
||||
}
|
||||
},
|
||||
"devices_filter": {
|
||||
"title": "Filtrar Dispositivos",
|
||||
"description": "## Instruções de Uso\r\nSuporta a filtragem de dispositivos por nome da sala, tipo de acesso do dispositivo e modelo do dispositivo, e também suporta a filtragem por dimensão do dispositivo. A lógica de filtragem é a seguinte:\r\n- Primeiro, de acordo com a lógica estatística, obtenha a união ou interseção de todos os itens incluídos, depois obtenha a interseção ou união dos itens excluídos, e finalmente subtraia o [resultado do resumo incluído] do [resultado do resumo excluído] para obter o [resultado do filtro].\r\n- Se nenhum item incluído for selecionado, significa que todos estão incluídos.\r\n### Modo de Filtragem\r\n- Excluir: Remover itens indesejados.\r\n- Incluir: Incluir itens desejados.\r\n### Lógica Estatística\r\n- Lógica E: Pegue a interseção de todos os itens no mesmo modo.\r\n- Lógica OU: Pegue a união de todos os itens no mesmo modo.\r\n\r\nVocê também pode ir para a página [Configuração > Atualizar Lista de Dispositivos] do item de integração, marcar [Filtrar Dispositivos] para refiltrar.",
|
||||
"data": {
|
||||
"room_filter_mode": "Filtrar por Sala",
|
||||
"room_list": "Salas",
|
||||
"type_filter_mode": "Filtrar por Tipo de Dispositivo",
|
||||
"type_list": "Tipos de Dispositivo",
|
||||
"model_filter_mode": "Filtrar por Modelo de Dispositivo",
|
||||
"model_list": "Modelos de Dispositivo",
|
||||
"devices_filter_mode": "Filtrar Dispositivos",
|
||||
"device_list": "Lista de Dispositivos",
|
||||
"statistics_logic": "Lógica de Estatísticas"
|
||||
}
|
||||
}
|
||||
},
|
||||
"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": "Não há dispositivos na casa selecionada. Por favor, selecione uma casa com dispositivos e continue.",
|
||||
"no_filter_devices": "Os dispositivos filtrados estão vazios. Por favor, selecione critérios de filtro válidos 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.",
|
||||
"invalid_network_addr": "Endereço IP ou HTTP inválido detectado, por favor insira um endereço válido.",
|
||||
"invalid_ip_addr": "Endereço IP inacessível detectado, por favor insira um endereço IP válido.",
|
||||
"invalid_http_addr": "Endereço HTTP inacessível detectado, por favor insira um endereço HTTP válido.",
|
||||
"invalid_default_addr": "O endereço de detecção de rede padrão está inacessível, por favor verifique a configuração da rede ou use um endereço de detecção de rede personalizado.",
|
||||
"unreachable_oauth2_host": "Não é possível acessar o endereço de autenticação OAuth2, verifique a configuração da rede.",
|
||||
"unreachable_http_host": "Não é possível acessar o endereço da API HTTP da Xiaomi, verifique a configuração da rede.",
|
||||
"unreachable_spec_host": "Não é possível acessar o endereço da API SPEC da Xiaomi, verifique a configuração da rede.",
|
||||
"unreachable_mqtt_broker": "Não é possível acessar o endereço do Broker MQTT da Xiaomi, verifique a configuração da rede."
|
||||
},
|
||||
"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\nID da Instância de Integração: {instance_id}\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",
|
||||
"display_devices_changed_notify": "Exibir notificações de mudança de status do dispositivo",
|
||||
"update_trans_rules": "Atualizar regras de conversão de entidades",
|
||||
"update_lan_ctrl_config": "Atualizar configuração de controle LAN",
|
||||
"network_detect_config": "Configuração de Rede Integrada"
|
||||
}
|
||||
},
|
||||
"update_user_info": {
|
||||
"title": "Atualizar Apelido do Usuário",
|
||||
"description": "Olá {nick_name}, você pode modificar seu apelido personalizado abaixo.",
|
||||
"data": {
|
||||
"nick_name": "Apelido"
|
||||
}
|
||||
},
|
||||
"homes_select": {
|
||||
"title": "Selecionar novamente Casa e Dispositivos",
|
||||
"description": "## Instruções de Uso\r\n### Importar dispositivos da casa\r\nA integração adicionará dispositivos das casas selecionadas.\r\n### Filtrar Dispositivos\r\nSuporta a filtragem de dispositivos por nome da sala, tipo de acesso do dispositivo e modelo do dispositivo, e também suporta a filtragem por dimensão do dispositivo. **{local_count}** dispositivos foram filtrados.\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.",
|
||||
"data": {
|
||||
"home_infos": "Importar dispositivos da casa",
|
||||
"devices_filter": "Filtrar Dispositivos",
|
||||
"ctrl_mode": "Modo de controle"
|
||||
}
|
||||
},
|
||||
"devices_filter": {
|
||||
"title": "Filtrar Dispositivos",
|
||||
"description": "## Instruções de Uso\r\nSuporta a filtragem de dispositivos por nome da sala, tipo de acesso do dispositivo e modelo do dispositivo, e também suporta a filtragem por dimensão do dispositivo. A lógica de filtragem é a seguinte:\r\n- Primeiro, de acordo com a lógica estatística, obtenha a união ou interseção de todos os itens incluídos, depois obtenha a interseção ou união dos itens excluídos, e finalmente subtraia o [resultado do resumo incluído] do [resultado do resumo excluído] para obter o [resultado do filtro].\r\n- Se nenhum item incluído for selecionado, significa que todos estão incluídos.\r\n### Modo de Filtragem\r\n- Excluir: Remover itens indesejados.\r\n- Incluir: Incluir itens desejados.\r\n### Lógica Estatística\r\n- Lógica E: Pegue a interseção de todos os itens no mesmo modo.\r\n- Lógica OU: Pegue a união de todos os itens no mesmo modo.\r\n\r\nVocê também pode ir para a página [Configuração > Atualizar Lista de Dispositivos] do item de integração, marcar [Filtrar Dispositivos] para refiltrar.",
|
||||
"data": {
|
||||
"room_filter_mode": "Filtrar por Sala",
|
||||
"room_list": "Salas",
|
||||
"type_filter_mode": "Filtrar por Tipo de Dispositivo",
|
||||
"type_list": "Tipos de Dispositivo",
|
||||
"model_filter_mode": "Filtrar por Modelo de Dispositivo",
|
||||
"model_list": "Modelos de Dispositivo",
|
||||
"devices_filter_mode": "Filtrar Dispositivos",
|
||||
"device_list": "Lista de Dispositivos",
|
||||
"statistics_logic": "Lógica de Estatísticas"
|
||||
}
|
||||
},
|
||||
"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"
|
||||
}
|
||||
},
|
||||
"network_detect_config": {
|
||||
"title": "Configuração de Detecção de Rede",
|
||||
"description": "## Introdução ao Uso\r\n### Endereço de Detecção de Rede\r\nUsado para verificar se a rede está funcionando corretamente. Se não for definido, o endereço padrão do sistema será usado. Se a verificação do endereço padrão falhar, você pode tentar inserir um endereço personalizado.\r\n- Você pode inserir vários endereços de detecção, separados por vírgulas, como `8.8.8.8,https://www.bing.com`\r\n- Se for um endereço IP, a detecção será feita via ping. Se for um endereço HTTP(s), a detecção será feita via solicitação HTTP GET.\r\n- Se você deseja restaurar o endereço de detecção padrão do sistema, insira uma vírgula `,` e clique em 'Próximo'.\r\n- **Esta configuração é global e as alterações afetarão outras instâncias de integração. Modifique com cautela.**\r\n### Verificar Dependências de Rede\r\nVerifique uma por uma as seguintes dependências de rede para ver se são acessíveis. Se os endereços relacionados não forem acessíveis, isso causará problemas de integração.\r\n- Endereço de Autenticação OAuth2: `https://account.xiaomi.com/oauth2/authorize`.\r\n- Endereço da API HTTP da Xiaomi: `https://{http_host}/app/v2/ha/oauth/get_token`.\r\n- Endereço da API SPEC da Xiaomi: `https://miot-spec.org/miot-spec-v2/template/list/device`.\r\n- Endereço do Broker MQTT da Xiaomi: `mqtts://{cloud_server}-ha.mqtt.io.mi.com:8883`.",
|
||||
"data": {
|
||||
"network_detect_addr": "Endereço de Detecção de Rede",
|
||||
"check_network_deps": "Verificar Dependências de Rede"
|
||||
}
|
||||
},
|
||||
"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\nExibir notificações de mudança de status do dispositivo:\t{display_devices_changed_notify}\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": "Não há dispositivos na casa selecionada. Por favor, selecione uma casa com dispositivos e continue.",
|
||||
"no_filter_devices": "Os dispositivos filtrados estão vazios. Por favor, selecione critérios de filtro válidos 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.",
|
||||
"invalid_network_addr": "Endereço IP ou HTTP inválido detectado, por favor insira um endereço válido.",
|
||||
"invalid_ip_addr": "Endereço IP inacessível detectado, por favor insira um endereço IP válido.",
|
||||
"invalid_http_addr": "Endereço HTTP inacessível detectado, por favor insira um endereço HTTP válido.",
|
||||
"invalid_default_addr": "O endereço de detecção de rede padrão está inacessível, por favor verifique a configuração da rede ou use um endereço de detecção de rede personalizado.",
|
||||
"unreachable_oauth2_host": "Não é possível acessar o endereço de autenticação OAuth2, verifique a configuração da rede.",
|
||||
"unreachable_http_host": "Não é possível acessar o endereço da API HTTP da Xiaomi, verifique a configuração da rede.",
|
||||
"unreachable_spec_host": "Não é possível acessar o endereço da API SPEC da Xiaomi, verifique a configuração da rede.",
|
||||
"unreachable_mqtt_broker": "Não é possível acessar o endereço do Broker MQTT da Xiaomi, verifique a configuração da rede."
|
||||
},
|
||||
"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."
|
||||
}
|
||||
}
|
||||
}
|
221
custom_components/xiaomi_home/translations/pt.json
Normal file
221
custom_components/xiaomi_home/translations/pt.json
Normal file
@ -0,0 +1,221 @@
|
||||
{
|
||||
"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### Configuração de Rede Integrada\r\nVerifique se a rede local está funcionando corretamente e se os recursos de rede relacionados estão acessíveis. **Recomenda-se selecionar isso ao adicionar pela primeira vez.**\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",
|
||||
"network_detect_config": "Configuração de Rede Integrada"
|
||||
}
|
||||
},
|
||||
"network_detect_config": {
|
||||
"title": "Configuração de Rede Integrada",
|
||||
"description": "## Introdução ao Uso\r\n### Endereço de Detecção de Rede\r\nUsado para verificar se a rede está funcionando corretamente. Se não for definido, o endereço padrão do sistema será usado. Se a verificação do endereço padrão falhar, você pode tentar inserir um endereço personalizado.\r\n- Você pode inserir vários endereços de detecção, separados por vírgulas, como `8.8.8.8,https://www.bing.com`\r\n- Se for um endereço IP, a detecção será feita via ping. Se for um endereço HTTP(s), a detecção será feita via solicitação HTTP GET.\r\n- Se você deseja restaurar o endereço de detecção padrão do sistema, insira uma vírgula `,` e clique em 'Próximo'.\r\n- **Esta configuração é global e as alterações afetarão outras instâncias de integração. Modifique com cautela.**\r\n### Verificar Dependências de Rede\r\nVerifique uma por uma as seguintes dependências de rede para ver se são acessíveis. Se os endereços relacionados não forem acessíveis, isso causará problemas de integração.\r\n- Endereço de Autenticação OAuth2: `https://account.xiaomi.com/oauth2/authorize`.\r\n- Endereço da API HTTP da Xiaomi: `https://{http_host}/app/v2/ha/oauth/get_token`.\r\n- Endereço da API SPEC da Xiaomi: `https://miot-spec.org/miot-spec-v2/template/list/device`.\r\n- Endereço do Broker MQTT da Xiaomi: `mqtts://{cloud_server}-ha.mqtt.io.mi.com:8883`.",
|
||||
"data": {
|
||||
"network_detect_addr": "Endereço de Detecção de Rede",
|
||||
"check_network_deps": "Verificar Dependências de Rede"
|
||||
}
|
||||
},
|
||||
"oauth_error": {
|
||||
"title": "Erro de Login",
|
||||
"description": "Clique em SEGUINTE para tentar novamente."
|
||||
},
|
||||
"homes_select": {
|
||||
"title": "Selecionar Família e Dispositivo",
|
||||
"description": "## Introdução\r\n### Importar a Família do Dispositivo\r\nA integração adicionará dispositivos da família selecionada.\r\n### Modo de Sincronização do Nome da Sala\r\nAo sincronizar dispositivos do APP Mi Home para o Home Assistant, a nomeação da área no Home Assistant seguirá as regras abaixo. Observe que o processo de sincronização não alterará as configurações de família e sala no APP Mi Home.\r\n- Não sincronizar: O dispositivo não será adicionado a nenhuma área.\r\n- Outras opções: A área à qual o dispositivo é adicionado será nomeada de acordo com o nome da família ou da sala no APP Mi Home.\r\n### Configurações Avançadas\r\nMostrar configurações avançadas para modificar as opções de configuração profissional da integração.\r\n\r\n \r\n### {nick_name} Olá! Por favor, selecione a família à qual você deseja adicionar o dispositivo.",
|
||||
"data": {
|
||||
"home_infos": "Importar a Família do Dispositivo",
|
||||
"area_name_rule": "Modo de Sincronização do Nome da Sala",
|
||||
"advanced_options": "Configurações Avançadas"
|
||||
}
|
||||
},
|
||||
"advanced_options": {
|
||||
"title": "Opções Avançadas",
|
||||
"description": "## Introdução\r\n### A menos que você entenda claramente o significado das opções abaixo, mantenha as configurações padrão.\r\n### Filtrar Dispositivos\r\nSuporte para filtrar dispositivos por nome da sala e tipo de dispositivo, bem como filtragem por família.\r\n### Modo de Controle\r\n- Automático: Quando um gateway central Xiaomi está disponível na rede local, o Home Assistant enviará comandos de controlo de dispositivos através do gateway central para realizar o controlo local. Quando não há gateway central na rede local, tentará enviar comandos de controlo através do protocolo Xiaomi OT para realizar o controlo local. Apenas quando as condições de controlo local acima não são atendidas, os comandos de controlo de dispositivos serão enviados através da nuvem.\r\n- Nuvem: Os comandos de controlo são enviados apenas através da nuvem.\r\n### Modo de Depuração de Ações\r\nPara métodos definidos pelo MIoT-Spec-V2, além de gerar uma entidade de notificação, também será gerada uma entidade de caixa de texto para depuração de controlo de dispositivos.\r\n### Ocultar Entidades Geradas Não Padrão\r\nOcultar entidades geradas por instâncias MIoT-Spec-V2 não padrão, cujos nomes começam com \"*\".\r\n### Exibir notificações de mudança de status do dispositivo\r\nExibir notificações detalhadas de mudança de status do dispositivo, mostrando apenas as notificações selecionadas.",
|
||||
"data": {
|
||||
"devices_filter": "Filtrar Dispositivos",
|
||||
"ctrl_mode": "Modo de Controlo",
|
||||
"action_debug": "Modo de Depuração de Ações",
|
||||
"hide_non_standard_entities": "Ocultar Entidades Geradas Não Padrão",
|
||||
"display_devices_changed_notify": "Exibir notificações de mudança de status do dispositivo"
|
||||
}
|
||||
},
|
||||
"devices_filter": {
|
||||
"title": "Filtrar Dispositivos",
|
||||
"description": "## Instruções de Utilização\r\nSuporta a filtragem de dispositivos por nome da sala, tipo de acesso do dispositivo e modelo do dispositivo, e também suporta a filtragem por dimensão do dispositivo. A lógica de filtragem é a seguinte:\r\n- Primeiro, de acordo com a lógica estatística, obtenha a união ou interseção de todos os itens incluídos, depois obtenha a interseção ou união dos itens excluídos, e finalmente subtraia o [resultado do resumo incluído] do [resultado do resumo excluído] para obter o [resultado do filtro].\r\n- Se nenhum item incluído for selecionado, significa que todos estão incluídos.\r\n### Modo de Filtragem\r\n- Excluir: Remover itens indesejados.\r\n- Incluir: Incluir itens desejados.\r\n### Lógica Estatística\r\n- Lógica E: Pegue a interseção de todos os itens no mesmo modo.\r\n- Lógica OU: Pegue a união de todos os itens no mesmo modo.\r\n\r\nVocê também pode ir para a página [Configuração > Atualizar Lista de Dispositivos] do item de integração, marcar [Filtrar Dispositivos] para refiltrar.",
|
||||
"data": {
|
||||
"room_filter_mode": "Filtrar por Sala",
|
||||
"room_list": "Salas",
|
||||
"type_filter_mode": "Filtrar por Tipo de Dispositivo",
|
||||
"type_list": "Tipos de Dispositivo",
|
||||
"model_filter_mode": "Filtrar por Modelo de Dispositivo",
|
||||
"model_list": "Modelos de Dispositivo",
|
||||
"devices_filter_mode": "Filtrar Dispositivos",
|
||||
"device_list": "Lista de Dispositivos",
|
||||
"statistics_logic": "Lógica de Estatísticas"
|
||||
}
|
||||
}
|
||||
},
|
||||
"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": "Não há dispositivos na casa selecionada. Por favor, selecione uma casa com dispositivos e continue.",
|
||||
"no_filter_devices": "Os dispositivos filtrados estão vazios. Por favor, selecione critérios de filtro válidos 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.",
|
||||
"invalid_network_addr": "Endereço IP ou HTTP inválido detectado, por favor insira um endereço válido.",
|
||||
"invalid_ip_addr": "Endereço IP inacessível detectado, por favor insira um endereço IP válido.",
|
||||
"invalid_http_addr": "Endereço HTTP inacessível detectado, por favor insira um endereço HTTP válido.",
|
||||
"invalid_default_addr": "O endereço de detecção de rede padrão está inacessível, por favor verifique a configuração da rede ou use um endereço de detecção de rede personalizado.",
|
||||
"unreachable_oauth2_host": "Não é possível acessar o endereço de autenticação OAuth2, verifique a configuração da rede.",
|
||||
"unreachable_http_host": "Não é possível acessar o endereço da API HTTP da Xiaomi, verifique a configuração da rede.",
|
||||
"unreachable_spec_host": "Não é possível acessar o endereço da API SPEC da Xiaomi, verifique a configuração da rede.",
|
||||
"unreachable_mqtt_broker": "Não é possível acessar o endereço do Broker MQTT da Xiaomi, verifique a configuração da rede."
|
||||
},
|
||||
"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\nID da Instância de Integração: {instance_id}\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",
|
||||
"display_devices_changed_notify": "Exibir notificações de mudança de status do dispositivo",
|
||||
"update_trans_rules": "Atualizar regras de conversão de entidades",
|
||||
"update_lan_ctrl_config": "Atualizar configuração de controlo LAN",
|
||||
"network_detect_config": "Configuração de Rede Integrada"
|
||||
}
|
||||
},
|
||||
"update_user_info": {
|
||||
"title": "Atualizar Alcunha do Utilizador",
|
||||
"description": "Olá {nick_name}, pode modificar a sua alcunha personalizada abaixo.",
|
||||
"data": {
|
||||
"nick_name": "Alcunha"
|
||||
}
|
||||
},
|
||||
"homes_select": {
|
||||
"title": "Selecionar novamente a Casa e os Dispositivos",
|
||||
"description": "## Instruções de Utilização\r\n### Importar dispositivos da casa\r\nA integração adicionará dispositivos das casas selecionadas.\r\n### Filtrar Dispositivos\r\nSuporta a filtragem de dispositivos por nome da sala, tipo de acesso do dispositivo e modelo do dispositivo, e também suporta a filtragem por dimensão do dispositivo. **{local_count}** dispositivos foram filtrados.\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.",
|
||||
"data": {
|
||||
"home_infos": "Importar dispositivos da casa",
|
||||
"devices_filter": "Filtrar Dispositivos",
|
||||
"ctrl_mode": "Modo de Controlo"
|
||||
}
|
||||
},
|
||||
"devices_filter": {
|
||||
"title": "Filtrar Dispositivos",
|
||||
"description": "## Instruções de Utilização\r\nSuporta a filtragem de dispositivos por nome da sala, tipo de acesso do dispositivo e modelo do dispositivo, e também suporta a filtragem por dimensão do dispositivo. A lógica de filtragem é a seguinte:\r\n- Primeiro, de acordo com a lógica estatística, obtenha a união ou interseção de todos os itens incluídos, depois obtenha a interseção ou união dos itens excluídos, e finalmente subtraia o [resultado do resumo incluído] do [resultado do resumo excluído] para obter o [resultado do filtro].\r\n- Se nenhum item incluído for selecionado, significa que todos estão incluídos.\r\n### Modo de Filtragem\r\n- Excluir: Remover itens indesejados.\r\n- Incluir: Incluir itens desejados.\r\n### Lógica Estatística\r\n- Lógica E: Pegue a interseção de todos os itens no mesmo modo.\r\n- Lógica OU: Pegue a união de todos os itens no mesmo modo.\r\n\r\nVocê também pode ir para a página [Configuração > Atualizar Lista de Dispositivos] do item de integração, marcar [Filtrar Dispositivos] para refiltrar.",
|
||||
"data": {
|
||||
"room_filter_mode": "Filtrar por Sala",
|
||||
"room_list": "Salas",
|
||||
"type_filter_mode": "Filtrar por Tipo de Dispositivo",
|
||||
"type_list": "Tipos de Dispositivo",
|
||||
"model_filter_mode": "Filtrar por Modelo de Dispositivo",
|
||||
"model_list": "Modelos de Dispositivo",
|
||||
"devices_filter_mode": "Filtrar Dispositivos",
|
||||
"device_list": "Lista de Dispositivos",
|
||||
"statistics_logic": "Lógica de Estatísticas"
|
||||
}
|
||||
},
|
||||
"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"
|
||||
}
|
||||
},
|
||||
"network_detect_config": {
|
||||
"title": "Configuração de Rede Integrada",
|
||||
"description": "## Introdução ao Uso\r\n### Endereço de Detecção de Rede\r\nUsado para verificar se a rede está funcionando corretamente. Se não for definido, o endereço padrão do sistema será usado. Se a verificação do endereço padrão falhar, você pode tentar inserir um endereço personalizado.\r\n- Você pode inserir vários endereços de detecção, separados por vírgulas, como `8.8.8.8,https://www.bing.com`\r\n- Se for um endereço IP, a detecção será feita via ping. Se for um endereço HTTP(s), a detecção será feita via solicitação HTTP GET.\r\n- Se você deseja restaurar o endereço de detecção padrão do sistema, insira uma vírgula `,` e clique em 'Próximo'.\r\n- **Esta configuração é global e as alterações afetarão outras instâncias de integração. Modifique com cautela.**\r\n### Verificar Dependências de Rede\r\nVerifique uma por uma as seguintes dependências de rede para ver se são acessíveis. Se os endereços relacionados não forem acessíveis, isso causará problemas de integração.\r\n- Endereço de Autenticação OAuth2: `https://account.xiaomi.com/oauth2/authorize`.\r\n- Endereço da API HTTP da Xiaomi: `https://{http_host}/app/v2/ha/oauth/get_token`.\r\n- Endereço da API SPEC da Xiaomi: `https://miot-spec.org/miot-spec-v2/template/list/device`.\r\n- Endereço do Broker MQTT da Xiaomi: `mqtts://{cloud_server}-ha.mqtt.io.mi.com:8883`.",
|
||||
"data": {
|
||||
"network_detect_addr": "Endereço de Detecção de Rede",
|
||||
"check_network_deps": "Verificar Dependências de Rede"
|
||||
}
|
||||
},
|
||||
"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\nExibir notificações de mudança de status do dispositivo:\t{display_devices_changed_notify}\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": "Não há dispositivos na casa selecionada. Por favor, selecione uma casa com dispositivos e continue.",
|
||||
"no_filter_devices": "Os dispositivos filtrados estão vazios. Por favor, selecione critérios de filtro válidos 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.",
|
||||
"invalid_network_addr": "Endereço IP ou HTTP inválido detectado, por favor insira um endereço válido.",
|
||||
"invalid_ip_addr": "Endereço IP inacessível detectado, por favor insira um endereço IP válido.",
|
||||
"invalid_http_addr": "Endereço HTTP inacessível detectado, por favor insira um endereço HTTP válido.",
|
||||
"invalid_default_addr": "O endereço de detecção de rede padrão está inacessível, por favor verifique a configuração da rede ou use um endereço de detecção de rede personalizado.",
|
||||
"unreachable_oauth2_host": "Não é possível acessar o endereço de autenticação OAuth2, verifique a configuração da rede.",
|
||||
"unreachable_http_host": "Não é possível acessar o endereço da API HTTP da Xiaomi, verifique a configuração da rede.",
|
||||
"unreachable_spec_host": "Não é possível acessar o endereço da API SPEC da Xiaomi, verifique a configuração da rede.",
|
||||
"unreachable_mqtt_broker": "Não é possível acessar o endereço do Broker MQTT da Xiaomi, verifique a configuração da rede."
|
||||
},
|
||||
"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."
|
||||
}
|
||||
}
|
||||
}
|
@ -11,26 +11,59 @@
|
||||
},
|
||||
"auth_config": {
|
||||
"title": "Основные настройки",
|
||||
"description": "### Регион входа в систему\r\nВыберите регион, в котором находится ваша учетная запись Xiaomi. Вы можете узнать об этом в `Xiaomi Home> Мой (в нижнем меню)> Дополнительные настройки> О Xiaomi Home`.\r\n### Язык\r\nВыберите язык, используемый для имен устройств и сущностей. Части предложений, которые не имеют перевода, будут отображаться на английском языке.\r\n### Адрес перенаправления для аутентификации OAuth2\r\nАдрес перенаправления для аутентификации OAuth2 - ** [http: //homeassistant.local: 8123] (http: //homeassistant.local: 8123) **, Home Assistant должен находиться в одной локальной сети с текущим терминалом (например, персональный компьютер), и терминал должен иметь доступ к домашней странице Home Assistant по этому адресу, в противном случае аутентификация входа может завершиться неудачно.\r\n### Примечание\r\n- Для пользователей с сотнями или более устройств Mi Home первоначальное добавление интеграции займет некоторое время. Пожалуйста, будьте терпеливы.\r\n- Если Home Assistant работает в среде Docker, убедитесь, что сетевой режим Docker установлен на host, иначе функция локального управления может работать неправильно.\r\n- Функция локального управления интеграции имеет некоторые зависимости. Пожалуйста, внимательно прочитайте README.",
|
||||
"description": "### Регион входа в систему\r\nВыберите регион, в котором находится ваша учетная запись Xiaomi. Вы можете узнать об этом в `Xiaomi Home> Мой (в нижнем меню)> Дополнительные настройки> О Xiaomi Home`.\r\n### Язык\r\nВыберите язык, используемый для имен устройств и сущностей. Части предложений, которые не имеют перевода, будут отображаться на английском языке.\r\n### Адрес перенаправления для аутентификации OAuth2\r\nАдрес перенаправления для аутентификации OAuth2 - ** [http: //homeassistant.local: 8123] (http: //homeassistant.local: 8123) **, Home Assistant должен находиться в одной локальной сети с текущим терминалом (например, персональный компьютер), и терминал должен иметь доступ к домашней странице Home Assistant по этому адресу, в противном случае аутентификация входа может завершиться неудачно.\r\n### Интегрированная Сетевая Конфигурация\r\nПроверьте, нормально ли функционирует локальная сеть и доступны ли связанные сетевые ресурсы. **Рекомендуется выбрать это при первом добавлении.**\r\n### Примечание\r\n- Для пользователей с сотнями или более устройств Mi Home первоначальное добавление интеграции займет некоторое время. Пожалуйста, будьте терпеливы.\r\n- Если Home Assistant работает в среде Docker, убедитесь, что сетевой режим Docker установлен на host, иначе функция локального управления может работать неправильно.\r\n- Функция локального управления интеграции имеет некоторые зависимости. Пожалуйста, внимательно прочитайте README.",
|
||||
"data": {
|
||||
"cloud_server": "Регион входа в систему",
|
||||
"integration_language": "Язык",
|
||||
"oauth_redirect_url": "Адрес перенаправления для аутентификации OAuth2"
|
||||
"oauth_redirect_url": "Адрес перенаправления для аутентификации OAuth2",
|
||||
"network_detect_config": "Интегрированная Сетевая Конфигурация"
|
||||
}
|
||||
},
|
||||
"network_detect_config": {
|
||||
"title": "Интегрированная Сетевая Конфигурация",
|
||||
"description": "## Введение в Использование\r\n### Адрес Обнаружения Сети\r\nИспользуется для проверки работоспособности сети. Если не задано, будет использоваться адрес по умолчанию. Если проверка адреса по умолчанию не удалась, вы можете попробовать ввести пользовательский адрес.\r\n- Вы можете ввести несколько адресов для проверки, разделенных запятыми, например `8.8.8.8,https://www.bing.com`\r\n- Если это IP-адрес, проверка будет выполняться с помощью ping. Если это HTTP(s)-адрес, проверка будет выполняться с помощью HTTP GET запроса.\r\n- Если вы хотите восстановить адрес обнаружения по умолчанию, введите запятую `,` и нажмите 'Далее'.\r\n- **Эта конфигурация является глобальной, и изменения повлияют на другие экземпляры интеграции. Пожалуйста, изменяйте с осторожностью.**\r\n### Проверка Сетевых Зависимостей\r\nПроверьте поочередно следующие сетевые зависимости, чтобы убедиться, что они доступны. Если соответствующие адреса недоступны, это приведет к проблемам с интеграцией.\r\n- Адрес аутентификации OAuth2: `https://account.xiaomi.com/oauth2/authorize`.\r\n- Адрес HTTP API Xiaomi: `https://{http_host}/app/v2/ha/oauth/get_token`.\r\n- Адрес SPEC API Xiaomi: `https://miot-spec.org/miot-spec-v2/template/list/device`.\r\n- Адрес MQTT брокера Xiaomi: `mqtts://{cloud_server}-ha.mqtt.io.mi.com:8883`.",
|
||||
"data": {
|
||||
"network_detect_addr": "Адрес Обнаружения Сети",
|
||||
"check_network_deps": "Проверка Сетевых Зависимостей"
|
||||
}
|
||||
},
|
||||
"oauth_error": {
|
||||
"title": "Ошибка входа в систему",
|
||||
"description": "Нажмите кнопку «Далее», чтобы повторить попытку"
|
||||
},
|
||||
"devices_filter": {
|
||||
"title": "Выберите дом и устройства",
|
||||
"description": "## Инструкция по использованию\r\n### Режим управления\r\n- Авто: Когда в локальной сети доступен центральный шлюз Xiaomi, Home Assistant будет в первую очередь отправлять команды управления устройствами через центральный шлюз для достижения локализованного управления. Если в локальной сети нет центрального шлюза, он попытается отправить команды управления через протокол Xiaomi OT для достижения локализованного управления. Только если вышеуказанные условия локализованного управления не выполняются, команды управления устройствами будут отправляться через облако.\r\n- Облако: Команды управления отправляются только через облако.\r\n### Импорт домашнего устройства\r\nИнтеграция добавит устройства из выбранных домов.\r\n### Режим синхронизации имен комнат\r\nПри синхронизации устройств из приложения Xiaomi Home в Home Assistant имена комнат устройств в Home Assistant будут именоваться в соответствии с именами дома или комнаты в приложении Xiaomi Home.\r\n- Не синхронизировать: устройство не будет добавлено в любую область.\r\n- Другие параметры: область, в которую добавляется устройство, называется именем дома или комнаты в приложении Xiaomi Home.\r\n### Режим отладки Action\r\nДля методов, определенных в MIoT-Spec-V2, помимо создания уведомительной сущности будет создана сущность текстового поля ввода, которую можно использовать для отправки команд управления устройством во время отладки.\r\n### Скрыть нестандартные сущности\r\nСкрыть сущности, созданные нестандартными примерами MIoT-Spec-V2, имена которых начинаются с « * ».\r\n\r\n \r\n### {nick_name} Здравствуйте! Выберите режим управления интеграцией и дом, в котором находятся устройства, которые вы хотите добавить.",
|
||||
"homes_select": {
|
||||
"title": "Выберите семью и устройство",
|
||||
"description": "## Введение\r\n### Импорт семьи устройства\r\nИнтеграция добавит устройства из выбранной семьи.\r\n### Режим синхронизации имени комнаты\r\nПри синхронизации устройств из приложения Mi Home с Home Assistant, название области в Home Assistant будет следовать следующим правилам. Обратите внимание, что процесс синхронизации не изменит настройки семьи и комнаты в приложении Mi Home.\r\n- Не синхронизировать: Устройство не будет добавлено ни в одну область.\r\n- Другие варианты: Область, в которую добавляется устройство, будет названа в честь имени семьи или комнаты в приложении Mi Home.\r\n### Расширенные настройки\r\nПоказать расширенные настройки для изменения профессиональных параметров конфигурации интеграции.\r\n\r\n \r\n### {nick_name} Здравствуйте! Пожалуйста, выберите семью, в которую вы хотите добавить устройство.",
|
||||
"data": {
|
||||
"home_infos": "Импорт семьи устройства",
|
||||
"area_name_rule": "Режим синхронизации имени комнаты",
|
||||
"advanced_options": "Расширенные настройки"
|
||||
}
|
||||
},
|
||||
"advanced_options": {
|
||||
"title": "Расширенные настройки",
|
||||
"description": "## Введение\r\n### Если вы не очень хорошо понимаете значение следующих параметров, оставьте их по умолчанию.\r\n### Фильтрация устройств\r\nПоддерживает фильтрацию устройств по названию комнаты и типу устройства, а также фильтрацию по уровню устройства.\r\n### Режим управления\r\n- Автоматически: при наличии доступного центрального шлюза Xiaomi в локальной сети Home Assistant Home Assistant будет отправлять команды управления устройствами через центральный шлюз для локального управления. Если центрального шлюза нет в локальной сети, Home Assistant попытается отправить команды управления устройствами через протокол OT Xiaomi для локального управления. Только если вышеуказанные условия локального управления не выполняются, команды управления устройствами будут отправляться через облако.\r\n- Облако: команды управления отправляются только через облако.\r\n### Режим отладки действий\r\nДля методов, определенных устройством MIoT-Spec-V2, помимо создания уведомления, будет создана сущность текстового поля, которую вы можете использовать для отправки команд управления устройством во время отладки.\r\n### Скрыть нестандартные сущности\r\nСкрыть сущности, созданные нестандартными экземплярами MIoT-Spec-V2, имена которых начинаются с «*».\r\n### Отображать уведомления о изменении состояния устройства\r\nОтображать подробные уведомления о изменении состояния устройства, показывая только выбранные уведомления.",
|
||||
"data": {
|
||||
"devices_filter": "Фильтрация устройств",
|
||||
"ctrl_mode": "Режим управления",
|
||||
"home_infos": "Импорт домашнего устройства",
|
||||
"area_name_rule": "Режим синхронизации имен комнат",
|
||||
"action_debug": "Режим отладки Action",
|
||||
"hide_non_standard_entities": "Скрыть нестандартные сущности"
|
||||
"action_debug": "Режим отладки действий",
|
||||
"hide_non_standard_entities": "Скрыть нестандартные сущности",
|
||||
"display_devices_changed_notify": "Отображать уведомления о изменении состояния устройства"
|
||||
}
|
||||
},
|
||||
"devices_filter": {
|
||||
"title": "Фильтрация устройств",
|
||||
"description": "## Инструкция по использованию\r\nПоддерживает фильтрацию устройств по названию комнаты, типу доступа устройства и модели устройства, а также поддерживает фильтрацию по размеру устройства. Логика фильтрации следующая:\r\n- Сначала, согласно статистической логике, получите объединение или пересечение всех включенных элементов, затем получите пересечение или объединение исключенных элементов, и, наконец, вычтите [включенный итоговый результат] из [исключенного итогового результата], чтобы получить [результат фильтрации].\r\n- Если не выбраны включенные элементы, это означает, что все включены.\r\n### Режим фильтрации\r\n- Исключить: Удалить ненужные элементы.\r\n- Включить: Включить нужные элементы.\r\n### Статистическая логика\r\n- Логика И: Взять пересечение всех элементов в одном режиме.\r\n- Логика ИЛИ: Взять объединение всех элементов в одном режиме.\r\n\r\nВы также можете перейти на страницу [Конфигурация > Обновить список устройств] элемента интеграции, установить флажок [Фильтровать устройства], чтобы повторно отфильтровать.",
|
||||
"data": {
|
||||
"room_filter_mode": "Фильтрация по комнатам семьи",
|
||||
"room_list": "Комнаты семьи",
|
||||
"type_filter_mode": "Фильтрация по типу устройства",
|
||||
"type_list": "Типы устройств",
|
||||
"model_filter_mode": "Фильтрация по модели устройства",
|
||||
"model_list": "Модели устройств",
|
||||
"devices_filter_mode": "Фильтрация устройств",
|
||||
"device_list": "Список устройств",
|
||||
"statistics_logic": "Логика статистики"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -44,14 +77,23 @@
|
||||
"mdns_discovery_error": "Сервис обнаружения локальных устройств недоступен.",
|
||||
"get_cert_error": "Не удалось получить сертификат центрального шлюза.",
|
||||
"no_family_selected": "Не выбрана домашняя сеть.",
|
||||
"no_devices": "В выбранной домашней сети нет устройств. Пожалуйста, выберите домашнюю сеть с устройствами и продолжайте.",
|
||||
"no_devices": "В выбранном доме нет устройств. Пожалуйста, выберите дом с устройствами и продолжите.",
|
||||
"no_filter_devices": "Список устройств после фильтрации пуст. Пожалуйста, выберите действительные условия фильтрации и продолжите.",
|
||||
"no_central_device": "Для режима центрального шлюза Xiaomi необходимо наличие доступного центрального шлюза Xiaomi в локальной сети Home Assistant. Проверьте, соответствует ли выбранная домашняя сеть этому требованию.",
|
||||
"abort": {
|
||||
"network_connect_error": "Ошибка настройки. Сетевое подключение недоступно. Проверьте настройки сети устройства.",
|
||||
"already_configured": "Этот пользователь уже настроен. Перейдите на страницу интеграции и нажмите кнопку «Настроить», чтобы изменить настройки.",
|
||||
"invalid_auth_info": "Информация об авторизации истекла. Перейдите на страницу интеграции и нажмите кнопку «Настроить», чтобы переавторизоваться.",
|
||||
"config_flow_error": "Ошибка настройки интеграции: {error}"
|
||||
}
|
||||
"invalid_network_addr": "Обнаружен недействительный IP-адрес или HTTP-адрес, пожалуйста, введите действительный адрес.",
|
||||
"invalid_ip_addr": "Обнаружен недоступный IP-адрес, пожалуйста, введите действительный IP-адрес.",
|
||||
"invalid_http_addr": "Обнаружен недоступный HTTP-адрес, пожалуйста, введите действительный HTTP-адрес.",
|
||||
"invalid_default_addr": "Адрес обнаружения сети по умолчанию недоступен, пожалуйста, проверьте конфигурацию сети или используйте пользовательский адрес обнаружения сети.",
|
||||
"unreachable_oauth2_host": "Не удается подключиться к адресу аутентификации OAuth2, проверьте настройки сети.",
|
||||
"unreachable_http_host": "Не удается подключиться к адресу HTTP API Xiaomi, проверьте настройки сети.",
|
||||
"unreachable_spec_host": "Не удается подключиться к адресу SPEC API Xiaomi, проверьте настройки сети.",
|
||||
"unreachable_mqtt_broker": "Не удается подключиться к адресу MQTT брокера Xiaomi, проверьте настройки сети."
|
||||
},
|
||||
"abort": {
|
||||
"network_connect_error": "Ошибка настройки. Сетевое подключение недоступно. Проверьте настройки сети устройства.",
|
||||
"already_configured": "Этот пользователь уже настроен. Перейдите на страницу интеграции и нажмите кнопку «Настроить», чтобы изменить настройки.",
|
||||
"invalid_auth_info": "Информация об авторизации истекла. Перейдите на страницу интеграции и нажмите кнопку «Настроить», чтобы переавторизоваться.",
|
||||
"config_flow_error": "Ошибка настройки интеграции: {error}"
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
@ -69,15 +111,17 @@
|
||||
},
|
||||
"config_options": {
|
||||
"title": "Параметры настройки",
|
||||
"description": "### {nick_name} Здравствуйте!\r\n\r\nID учетной записи Xiaomi: {uid}\r\nТекущий регион входа в систему: {cloud_server}\r\n\r\nВыберите параметры, которые нужно настроить заново, а затем нажмите «Далее».",
|
||||
"description": "### {nick_name} Здравствуйте!\r\n\r\nID учетной записи Xiaomi: {uid}\r\nТекущий регион входа в систему: {cloud_server}\r\nID экземпляра интеграции: {instance_id}\r\n\r\nВыберите параметры, которые нужно настроить заново, а затем нажмите «Далее».",
|
||||
"data": {
|
||||
"integration_language": "Язык интеграции",
|
||||
"update_user_info": "Обновить информацию о пользователе",
|
||||
"update_devices": "Обновить список устройств",
|
||||
"action_debug": "Режим отладки Action",
|
||||
"hide_non_standard_entities": "Скрыть нестандартные сущности",
|
||||
"update_trans_rules": "Обновить правила преобразования сущностей (глобальная настройка)",
|
||||
"update_lan_ctrl_config": "Обновить конфигурацию управления LAN (глобальная настройка)"
|
||||
"display_devices_changed_notify": "Отображать уведомления о изменении состояния устройства",
|
||||
"update_trans_rules": "Обновить правила преобразования сущностей",
|
||||
"update_lan_ctrl_config": "Обновить конфигурацию управления LAN",
|
||||
"network_detect_config": "Интегрированная Сетевая Конфигурация"
|
||||
}
|
||||
},
|
||||
"update_user_info": {
|
||||
@ -87,12 +131,28 @@
|
||||
"nick_name": "Имя пользователя"
|
||||
}
|
||||
},
|
||||
"devices_filter": {
|
||||
"homes_select": {
|
||||
"title": "Выберите дом и устройства",
|
||||
"description": "## Инструкция по использованию\r\n### Режим управления\r\n- Авто: Когда в локальной сети доступен центральный шлюз Xiaomi, Home Assistant будет в первую очередь отправлять команды управления устройствами через центральный шлюз для достижения локализованного управления. Если в локальной сети нет центрального шлюза, он попытается отправить команды управления через протокол Xiaomi OT для достижения локализованного управления. Только если вышеуказанные условия локализованного управления не выполняются, команды управления устройствами будут отправляться через облако.\r\n- Облако: Команды управления отправляются только через облако.\r\n### Импорт домашнего устройства\r\nИнтеграция добавит устройства из выбранных домов.\r\n \r\n### {nick_name} Здравствуйте! Выберите режим управления интеграцией и дом, в котором находятся устройства, которые вы хотите добавить.",
|
||||
"description": "## Инструкция по использованию\r\n### Импорт домашнего устройства\r\nИнтеграция добавит устройства из выбранных домов.\r\n### Фильтрация устройств\r\nПоддерживает фильтрацию устройств по названию комнаты, типу доступа устройства и модели устройства, а также поддерживает фильтрацию по размеру устройства. Отфильтровано **{local_count}** устройств.\r\n### Режим управления\r\n- Авто: Когда в локальной сети доступен центральный шлюз Xiaomi, Home Assistant будет в первую очередь отправлять команды управления устройствами через центральный шлюз для достижения локализованного управления. Если в локальной сети нет центрального шлюза, он попытается отправить команды управления через протокол Xiaomi OT для достижения локализованного управления. Только если вышеуказанные условия локализованного управления не выполняются, команды управления устройствами будут отправляться через облако.\r\n- Облако: Команды управления отправляются только через облако.",
|
||||
"data": {
|
||||
"ctrl_mode": "Режим управления",
|
||||
"home_infos": "Импорт домашнего устройства"
|
||||
"home_infos": "Импорт домашнего устройства",
|
||||
"devices_filter": "Фильтрация устройств",
|
||||
"ctrl_mode": "Режим управления"
|
||||
}
|
||||
},
|
||||
"devices_filter": {
|
||||
"title": "Фильтрация устройств",
|
||||
"description": "## Инструкция по использованию\r\nПоддерживает фильтрацию устройств по названию комнаты, типу доступа устройства и модели устройства, а также поддерживает фильтрацию по размеру устройства. Логика фильтрации следующая:\r\n- Сначала, согласно статистической логике, получите объединение или пересечение всех включенных элементов, затем получите пересечение или объединение исключенных элементов, и, наконец, вычтите [включенный итоговый результат] из [исключенного итогового результата], чтобы получить [результат фильтрации].\r\n- Если не выбраны включенные элементы, это означает, что все включены.\r\n### Режим фильтрации\r\n- Исключить: Удалить ненужные элементы.\r\n- Включить: Включить нужные элементы.\r\n### Статистическая логика\r\n- Логика И: Взять пересечение всех элементов в одном режиме.\r\n- Логика ИЛИ: Взять объединение всех элементов в одном режиме.\r\n\r\nВы также можете перейти на страницу [Конфигурация > Обновить список устройств] элемента интеграции, установить флажок [Фильтровать устройства], чтобы повторно отфильтровать.",
|
||||
"data": {
|
||||
"room_filter_mode": "Фильтрация по комнатам семьи",
|
||||
"room_list": "Комнаты семьи",
|
||||
"type_filter_mode": "Фильтрация по типу устройства",
|
||||
"type_list": "Типы устройств",
|
||||
"model_filter_mode": "Фильтрация по модели устройства",
|
||||
"model_list": "Модели устройств",
|
||||
"devices_filter_mode": "Фильтрация устройств",
|
||||
"device_list": "Список устройств",
|
||||
"statistics_logic": "Логика статистики"
|
||||
}
|
||||
},
|
||||
"update_trans_rules": {
|
||||
@ -110,9 +170,17 @@
|
||||
"enable_subscribe": "Включить подписку LAN"
|
||||
}
|
||||
},
|
||||
"network_detect_config": {
|
||||
"title": "Интегрированная Сетевая Конфигурация",
|
||||
"description": "## Введение в Использование\r\n### Адрес Обнаружения Сети\r\nИспользуется для проверки работоспособности сети. Если не задано, будет использоваться адрес по умолчанию. Если проверка адреса по умолчанию не удалась, вы можете попробовать ввести пользовательский адрес.\r\n- Вы можете ввести несколько адресов для проверки, разделенных запятыми, например `8.8.8.8,https://www.bing.com`\r\n- Если это IP-адрес, проверка будет выполняться с помощью ping. Если это HTTP(s)-адрес, проверка будет выполняться с помощью HTTP GET запроса.\r\n- Если вы хотите восстановить адрес обнаружения по умолчанию, введите запятую `,` и нажмите 'Далее'.\r\n- **Эта конфигурация является глобальной, и изменения повлияют на другие экземпляры интеграции. Пожалуйста, изменяйте с осторожностью.**\r\n### Проверка Сетевых Зависимостей\r\nПроверьте поочередно следующие сетевые зависимости, чтобы убедиться, что они доступны. Если соответствующие адреса недоступны, это приведет к проблемам с интеграцией.\r\n- Адрес аутентификации OAuth2: `https://account.xiaomi.com/oauth2/authorize`.\r\n- Адрес HTTP API Xiaomi: `https://{http_host}/app/v2/ha/oauth/get_token`.\r\n- Адрес SPEC API Xiaomi: `https://miot-spec.org/miot-spec-v2/template/list/device`.\r\n- Адрес MQTT брокера Xiaomi: `mqtts://{cloud_server}-ha.mqtt.io.mi.com:8883`.",
|
||||
"data": {
|
||||
"network_detect_addr": "Адрес Обнаружения Сети",
|
||||
"check_network_deps": "Проверка Сетевых Зависимостей"
|
||||
}
|
||||
},
|
||||
"config_confirm": {
|
||||
"title": "Подтверждение настройки",
|
||||
"description": "**{nick_name}** Здравствуйте! Подтвердите последнюю информацию о настройке и нажмите «Отправить». Интеграция будет перезагружена с использованием обновленных настроек.\r\n\r\nЯзык интеграции:\t{lang_new}\r\nИмя пользователя:\t{nick_name_new}\r\nРежим отладки Action:\t{action_debug}\r\nСкрыть непроизводственные сущности:\t{hide_non_standard_entities}\r\nИзменение устройства:\tДобавлено **{devices_add}** устройство, удалено **{devices_remove}** устройства\r\nИзменение правил преобразования:\tВсего **{trans_rules_count}** правил, обновлено **{trans_rules_count_success}** правил",
|
||||
"description": "**{nick_name}** Здравствуйте! Подтвердите последнюю информацию о настройке и нажмите «Отправить». Интеграция будет перезагружена с использованием обновленных настроек.\r\n\r\nЯзык интеграции:\t{lang_new}\r\nИмя пользователя:\t{nick_name_new}\r\nРежим отладки Action:\t{action_debug}\r\nСкрыть непроизводственные сущности:\t{hide_non_standard_entities}\r\nОтображать уведомления о изменении состояния устройства:\t{display_devices_changed_notify}\r\nИзменение устройства:\tДобавлено **{devices_add}** устройство, удалено **{devices_remove}** устройства\r\nИзменение правил преобразования:\tВсего **{trans_rules_count}** правил, обновлено **{trans_rules_count_success}** правил",
|
||||
"data": {
|
||||
"confirm": "Подтвердить изменения"
|
||||
}
|
||||
@ -127,11 +195,20 @@
|
||||
"get_homeinfo_error": "Не удалось получить информацию о домашней сети.",
|
||||
"get_cert_error": "Не удалось получить центральный сертификат.",
|
||||
"no_family_selected": "Не выбрана семья.",
|
||||
"no_devices": "В выбранной семье нет устройств. Пожалуйста, выберите семью с устройствами и продолжайте.",
|
||||
"no_devices": "В выбранном доме нет устройств. Пожалуйста, выберите дом с устройствами и продолжите.",
|
||||
"no_filter_devices": "Список устройств после фильтрации пуст. Пожалуйста, выберите действительные условия фильтрации и продолжите.",
|
||||
"no_central_device": "Для режима центрального шлюза необходим существующий в локальной сети Home Assistant с доступным Xiaomi-шлюзом. Пожалуйста, проверьте, соответствует ли выбранная семья этому требованию.",
|
||||
"mdns_discovery_error": "Ошибка сервиса поиска локальных устройств.",
|
||||
"update_config_error": "Не удалось обновить информацию о конфигурации.",
|
||||
"not_confirm": "Изменение не подтверждено. Пожалуйста, отметьте для подтверждения и отправки."
|
||||
"not_confirm": "Изменение не подтверждено. Пожалуйста, отметьте для подтверждения и отправки.",
|
||||
"invalid_network_addr": "Обнаружен недействительный IP-адрес или HTTP-адрес, пожалуйста, введите действительный адрес.",
|
||||
"invalid_ip_addr": "Обнаружен недоступный IP-адрес, пожалуйста, введите действительный IP-адрес.",
|
||||
"invalid_http_addr": "Обнаружен недоступный HTTP-адрес, пожалуйста, введите действительный HTTP-адрес.",
|
||||
"invalid_default_addr": "Адрес обнаружения сети по умолчанию недоступен, пожалуйста, проверьте конфигурацию сети или используйте пользовательский адрес обнаружения сети.",
|
||||
"unreachable_oauth2_host": "Не удается подключиться к адресу аутентификации OAuth2, проверьте настройки сети.",
|
||||
"unreachable_http_host": "Не удается подключиться к адресу HTTP API Xiaomi, проверьте настройки сети.",
|
||||
"unreachable_spec_host": "Не удается подключиться к адресу SPEC API Xiaomi, проверьте настройки сети.",
|
||||
"unreachable_mqtt_broker": "Не удается подключиться к адресу MQTT брокера Xiaomi, проверьте настройки сети."
|
||||
},
|
||||
"abort": {
|
||||
"network_connect_error": "Ошибка конфигурации. Сбой сетевого подключения. Проверьте настройки сети устройства.",
|
||||
|
@ -11,26 +11,59 @@
|
||||
},
|
||||
"auth_config": {
|
||||
"title": "基础配置",
|
||||
"description": "### 登录地区\r\n选择小米账号所在的地区。您可以在 `米家APP > 我的(位于底部菜单) > 更多设置 > 关于米家` 中查看。\r\n### 语言\r\n选择设备及实体名称所用的语言。缺少翻译的部分语句将使用英文显示。\r\n### OAuth2 认证跳转地址\r\nOAuth2 认证跳转地址为 **[http://homeassistant.local:8123](http://homeassistant.local:8123)**,Home Assistant 需要与当前操作终端(例如,个人电脑)在同一局域网内,且操作终端能通过该地址访问 Home Assistant 首页,否则登录认证可能会失败。\r\n### 注意事项\r\n- 对于数百个及以上米家设备的用户,首次添加集成会耗费一些时间,请耐心等待。\r\n- 如果 Home Assistant 运行在docker环境下,请确保docker网络模式为host,否则会导致本地控制功能异常。\r\n- 集成本地控制功能存在一些依赖项,请仔细阅读README。",
|
||||
"description": "### 登录地区\r\n选择小米账号所在的地区。您可以在 `米家APP > 我的(位于底部菜单) > 更多设置 > 关于米家` 中查看。\r\n### 语言\r\n选择设备及实体名称所用的语言。缺少翻译的部分语句将使用英文显示。\r\n### OAuth2 认证跳转地址\r\nOAuth2 认证跳转地址为 **[http://homeassistant.local:8123](http://homeassistant.local:8123)**,Home Assistant 需要与当前操作终端(例如,个人电脑)在同一局域网内,且操作终端能通过该地址访问 Home Assistant 首页,否则登录认证可能会失败。\r\n### 集成网络配置\r\n检测本地网络是否正常,相关网络资源是否可访问。**首次添加时建议勾选。**\r\n### 注意事项\r\n- 对于数百个及以上米家设备的用户,首次添加集成会耗费一些时间,请耐心等待。\r\n- 如果 Home Assistant 运行在docker环境下,请确保docker网络模式为host,否则会导致本地控制功能异常。\r\n- 集成本地控制功能存在一些依赖项,请仔细阅读README。",
|
||||
"data": {
|
||||
"cloud_server": "登录地区",
|
||||
"integration_language": "语言",
|
||||
"oauth_redirect_url": "认证跳转地址"
|
||||
"oauth_redirect_url": "认证跳转地址",
|
||||
"network_detect_config": "集成网络配置"
|
||||
}
|
||||
},
|
||||
"network_detect_config": {
|
||||
"title": "网络检测配置",
|
||||
"description": "## 使用介绍\r\n### 网络检测地址\r\n用于检测网络是否正常,未设置时将使用系统默认地址检测。如果默认地址检测异常时,可尝试输入可用的自定义地址检测。\r\n- 可输入多个检测地址,地址之间使用`,`号间隔,如`8.8.8.8,https://www.bing.com`\r\n- 如果为IP地址,将采用ping方式检测,如果为http(s)地址,将采用 HTTP GET 访问该地址检测。\r\n- 如果想恢复系统默认检测地址,请输入`,`号,然后点击'下一步'。\r\n- **该配置为全局配置,修改会影响其它集成实例的网络检测,请谨慎修改。**\r\n### 检测网络依赖项\r\n依次检查下述网络依赖项是否可访问。如果相关地址无法访问,将会导致集成异常。\r\n- OAuth2 认证地址:`https://account.xiaomi.com/oauth2/authorize`。\r\n- 小米 HTTP API 地址:`https://{http_host}/app/v2/ha/oauth/get_token`。\r\n- 小米 SPEC API 地址:`https://miot-spec.org/miot-spec-v2/template/list/device`。\r\n- 小米 MQTT Broker 地址:`mqtts://{cloud_server}-ha.mqtt.io.mi.com:8883`。",
|
||||
"data": {
|
||||
"network_detect_addr": "网络检测地址",
|
||||
"check_network_deps": "检测网络依赖项"
|
||||
}
|
||||
},
|
||||
"oauth_error": {
|
||||
"title": "登录出现错误",
|
||||
"description": "点击“下一步”重试"
|
||||
},
|
||||
"devices_filter": {
|
||||
"homes_select": {
|
||||
"title": "选择家庭与设备",
|
||||
"description": "## 使用介绍\r\n### 控制模式\r\n- 自动:本地局域网内存在可用的小米中枢网关时, Home Assistant 会优先通过中枢网关发送设备控制指令,以实现本地化控制功能。本地局域网不存在中枢时,会尝试通过小米OT协议发送控制指令,以实现本地化控制功能。只有当上述本地化控制条件不满足时,设备控制指令才会通过云端发送。\r\n- 云端:控制指令仅通过云端发送。\r\n### 导入设备的家庭\r\n集成将添加已选中家庭中的设备。\r\n### 房间名同步模式\r\n将设备从米家APP同步到 Home Assistant 时,设备在 Home Assistant 中所处区域的名称的命名方式将遵循以下规则。注意,设备同步过程不会改变米家APP中家庭和房间的设置。\r\n- 不同步:设备不会被添加至任何区域。\r\n- 其它选项:设备所添加到的区域以米家APP中的家庭或房间名称命名。\r\n### Action 调试模式\r\n对于设备 MIoT-Spec-V2 定义的方法,在生成通知实体之外,还会生成一个文本输入框实体,您可以在调试时用它向设备发送控制指令。\r\n### 隐藏非标准生成实体\r\n隐藏名称以“*”开头的非标准 MIoT-Spec-V2 实例生成的实体。\r\n\r\n \r\n### {nick_name} 您好!请选择集成控制模式以及您想要添加的设备所处的家庭。",
|
||||
"description": "## 使用介绍\r\n### 导入设备的家庭\r\n集成将添加已选中家庭中的设备。\r\n### 房间名同步模式\r\n将设备从米家APP同步到 Home Assistant 时,设备在 Home Assistant 中所处区域的名称的命名方式将遵循以下规则。注意,设备同步过程不会改变米家APP中家庭和房间的设置。\r\n- 不同步:设备不会被添加至任何区域。\r\n- 其它选项:设备所添加到的区域以米家APP中的家庭或房间名称命名。\r\n### 高级设置选项\r\n展示高级设置选项,对集成的专业配置选项进行修改。\r\n\r\n \r\n### {nick_name} 您好!请选择您想要添加的设备所处家庭。",
|
||||
"data": {
|
||||
"ctrl_mode": "控制模式",
|
||||
"home_infos": "导入设备的家庭",
|
||||
"area_name_rule": "房间名同步模式",
|
||||
"advanced_options": "高级设置选项"
|
||||
}
|
||||
},
|
||||
"advanced_options": {
|
||||
"title": "高级设置选项",
|
||||
"description": "## 使用介绍\r\n### 除非您非常清楚下列选项的含义,否则请保持默认。\r\n### 筛选设备\r\n支持按照家庭房间名称、设备接入类型、设备型号筛选设备,同时也支持设备维度筛选。\r\n### 控制模式\r\n- 自动:本地局域网内存在可用的小米中枢网关时, Home Assistant 会优先通过中枢网关发送设备控制指令,以实现本地化控制功能。本地局域网不存在中枢时,会尝试通过小米OT协议发送控制指令,以实现本地化控制功能。只有当上述本地化控制条件不满足时,设备控制指令才会通过云端发送。\r\n- 云端:控制指令仅通过云端发送。\r\n### Action 调试模式\r\n对于设备 MIoT-Spec-V2 定义的方法,在生成通知实体之外,还会生成一个文本输入框实体,您可以在调试时用它向设备发送控制指令。\r\n### 隐藏非标准生成实体\r\n隐藏名称以“*”开头的非标准 MIoT-Spec-V2 实例生成的实体。\r\n### 显示设备状态变化通知\r\n细化显示设备状态变化通知,只显示勾选的通知消息。",
|
||||
"data": {
|
||||
"devices_filter": "筛选设备",
|
||||
"ctrl_mode": "控制模式",
|
||||
"action_debug": "Action 调试模式",
|
||||
"hide_non_standard_entities": "隐藏非标准生成实体"
|
||||
"hide_non_standard_entities": "隐藏非标准生成实体",
|
||||
"display_devices_changed_notify": "显示设备状态变化通知"
|
||||
}
|
||||
},
|
||||
"devices_filter": {
|
||||
"title": "筛选设备",
|
||||
"description": "## 使用介绍\r\n支持按照家庭房间名称、设备接入类型、设备型号筛选设备,同时也支持设备维度筛选,筛选逻辑如下:\r\n- 会先根据统计逻辑获取所有包含项的并集或者交集,然后再获取排除项的交集或者并集,最后将【包含汇总结果】减去【排除汇总结果】得到【筛选结果】\r\n- 如未选择包含项,表示包含全部。\r\n### 筛选模式\r\n- 排除:移除不需要的项。\r\n- 包含:包含需要的项。\r\n### 统计逻辑\r\n- 与逻辑:取所有同模式筛选项的交集。\r\n- 或逻辑:取所有同模式筛选项的并集。\r\n\r\n您也可以进入集成项的【配置>更新设备列表】页面,勾选【筛选设备】重新筛选。",
|
||||
"data": {
|
||||
"room_filter_mode": "筛选家庭房间",
|
||||
"room_list": "家庭房间",
|
||||
"type_filter_mode": "筛选设备接入类型",
|
||||
"type_list": "设备接入类型",
|
||||
"model_filter_mode": "筛选设备型号",
|
||||
"model_list": "设备型号",
|
||||
"devices_filter_mode": "筛选设备",
|
||||
"device_list": "设备列表",
|
||||
"statistics_logic": "统计逻辑"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -44,8 +77,17 @@
|
||||
"mdns_discovery_error": "本地设备发现服务异常。",
|
||||
"get_cert_error": "获取中枢证书失败。",
|
||||
"no_family_selected": "未选择家庭。",
|
||||
"no_devices": "选择的家庭中没有设备。请选择有设备的家庭,而后继续。",
|
||||
"no_central_device": "【中枢网关模式】需要 Home Assistant 所在的局域网中存在可用的小米中枢网关。请检查选择的家庭是否符合该要求。"
|
||||
"no_devices": "选择的家庭中没有设备。请选择有设备的家庭,然后继续。",
|
||||
"no_filter_devices": "筛选设备为空。请选择有效的筛选条件,然后继续。",
|
||||
"no_central_device": "【中枢网关模式】需要 Home Assistant 所在的局域网中存在可用的小米中枢网关。请检查选择的家庭是否符合该要求。",
|
||||
"invalid_network_addr": "存在无效的IP地址或者HTTP地址,请输入有效的地址。",
|
||||
"invalid_ip_addr": "存在无法访问的IP地址,请输入有效的IP地址。",
|
||||
"invalid_http_addr": "存在无法访问的HTTP地址,请输入有效的HTTP地址。",
|
||||
"invalid_default_addr": "默认网络检测地址无法访问,请检查网络配置或者使用自定义网络检测地址。",
|
||||
"unreachable_oauth2_host": "无法访问 OAuth2 认证地址,请检查网络配置。",
|
||||
"unreachable_http_host": "无法访问小米 HTTP API 地址,请检查网络配置。",
|
||||
"unreachable_spec_host": "无法访问小米 SPEC API 地址,请检查网络配置。",
|
||||
"unreachable_mqtt_broker": "无法访问小米 MQTT Broker 地址,请检查网络配置。"
|
||||
},
|
||||
"abort": {
|
||||
"network_connect_error": "配置失败。网络连接异常,请检查设备网络配置。",
|
||||
@ -69,15 +111,17 @@
|
||||
},
|
||||
"config_options": {
|
||||
"title": "配置选项",
|
||||
"description": "### {nick_name} 您好!\r\n\r\n小米账号ID:{uid}\r\n当前登录区域:{cloud_server}\r\n\r\n请勾选需要重新配置的选项,然后点击“下一步”。",
|
||||
"description": "### {nick_name} 您好!\r\n\r\n小米账号ID:{uid}\r\n当前登录区域:{cloud_server}\r\n集成实例ID:{instance_id}\r\n\r\n请勾选需要重新配置的选项,然后点击“下一步”。",
|
||||
"data": {
|
||||
"integration_language": "集成语言",
|
||||
"update_user_info": "更新用户信息",
|
||||
"update_devices": "更新设备列表",
|
||||
"action_debug": "Action 调试模式",
|
||||
"hide_non_standard_entities": "隐藏非标准生成实体",
|
||||
"display_devices_changed_notify": "显示设备状态变化通知",
|
||||
"update_trans_rules": "更新实体转换规则",
|
||||
"update_lan_ctrl_config": "更新局域网控制配置"
|
||||
"update_lan_ctrl_config": "更新局域网控制配置",
|
||||
"network_detect_config": "集成网络配置"
|
||||
}
|
||||
},
|
||||
"update_user_info": {
|
||||
@ -87,12 +131,28 @@
|
||||
"nick_name": "用户昵称"
|
||||
}
|
||||
},
|
||||
"devices_filter": {
|
||||
"homes_select": {
|
||||
"title": "重新选择家庭与设备",
|
||||
"description": "## 使用介绍\r\n### 控制模式\r\n- 自动:本地局域网内存在可用的小米中枢网关时, Home Assistant 会优先通过中枢网关发送设备控制指令,以实现本地化控制功能。本地局域网不存在中枢时,会尝试通过小米OT协议发送控制指令,以实现本地化控制功能。只有当上述本地化控制条件不满足时,设备控制指令才会通过云端发送。\r\n- 云端:控制指令仅通过云端发送。\r\n### 导入设备的家庭\r\n集成将添加已选中家庭中的设备。\r\n \r\n### {nick_name} 您好!请选择集成控制模式以及您想要添加的设备所处的家庭。",
|
||||
"description": "## 使用介绍\r\n### 导入设备的家庭\r\n集成将添加已选中家庭中的设备。\r\n### 筛选设备\r\n支持按照家庭房间名称、设备接入类型、设备型号筛选设备,同时也支持设备维度筛选,已筛选出 **{local_count}** 个设备。\r\n### 控制模式\r\n- 自动:本地局域网内存在可用的小米中枢网关时, Home Assistant 会优先通过中枢网关发送设备控制指令,以实现本地化控制功能。本地局域网不存在中枢时,会尝试通过小米OT协议发送控制指令,以实现本地化控制功能。只有当上述本地化控制条件不满足时,设备控制指令才会通过云端发送。\r\n- 云端:控制指令仅通过云端发送。",
|
||||
"data": {
|
||||
"ctrl_mode": "控制模式",
|
||||
"home_infos": "导入设备的家庭"
|
||||
"home_infos": "导入设备的家庭",
|
||||
"devices_filter": "筛选设备",
|
||||
"ctrl_mode": "控制模式"
|
||||
}
|
||||
},
|
||||
"devices_filter": {
|
||||
"title": "筛选设备",
|
||||
"description": "## 使用介绍\r\n支持按照家庭房间名称、设备接入类型、设备型号筛选设备,同时也支持设备维度筛选,筛选逻辑如下:\r\n- 会先根据统计逻辑获取所有包含项的并集或者交集,然后再获取排除项的交集或者并集,最后将【包含汇总结果】减去【排除汇总结果】得到【筛选结果】\r\n- 如未选择包含项,表示包含全部。\r\n### 筛选模式\r\n- 排除:移除不需要的项。\r\n- 包含:包含需要的项。\r\n### 统计逻辑\r\n- 与逻辑:取所有同模式筛选项的交集。\r\n- 或逻辑:取所有同模式筛选项的并集。\r\n\r\n您也可以进入集成项的【配置>更新设备列表】页面,勾选【筛选设备】重新筛选。",
|
||||
"data": {
|
||||
"room_filter_mode": "筛选家庭房间",
|
||||
"room_list": "家庭房间",
|
||||
"type_filter_mode": "筛选设备接入类型",
|
||||
"type_list": "设备接入类型",
|
||||
"model_filter_mode": "筛选设备型号",
|
||||
"model_list": "设备型号",
|
||||
"devices_filter_mode": "筛选设备",
|
||||
"device_list": "设备列表",
|
||||
"statistics_logic": "统计逻辑"
|
||||
}
|
||||
},
|
||||
"update_trans_rules": {
|
||||
@ -110,9 +170,17 @@
|
||||
"enable_subscribe": "启用局域网订阅"
|
||||
}
|
||||
},
|
||||
"network_detect_config": {
|
||||
"title": "网络检测配置",
|
||||
"description": "## 使用介绍\r\n### 网络检测地址\r\n用于检测网络是否正常,未设置时将使用系统默认地址检测。如果默认地址检测异常时,可尝试输入可用的自定义地址检测。\r\n- 可输入多个检测地址,地址之间使用`,`号间隔,如`8.8.8.8,https://www.bing.com`\r\n- 如果为IP地址,将采用ping方式检测,如果为http(s)地址,将采用 HTTP GET 访问该地址检测。\r\n- 如果想恢复系统默认检测地址,请输入`,`号,然后点击'下一步'。\r\n- **该配置为全局配置,修改会影响其它集成实例的网络检测,请谨慎修改。**\r\n### 检测网络依赖项\r\n依次检查下述网络依赖项是否可访问。如果相关地址无法访问,将会导致集成异常。\r\n- OAuth2 认证地址:`https://account.xiaomi.com/oauth2/authorize`。\r\n- 小米 HTTP API 地址:`https://{http_host}/app/v2/ha/oauth/get_token`。\r\n- 小米 SPEC API 地址:`https://miot-spec.org/miot-spec-v2/template/list/device`。\r\n- 小米 MQTT Broker 地址:`mqtts://{cloud_server}-ha.mqtt.io.mi.com:8883`。",
|
||||
"data": {
|
||||
"network_detect_addr": "网络检测地址",
|
||||
"check_network_deps": "检测网络依赖项"
|
||||
}
|
||||
},
|
||||
"config_confirm": {
|
||||
"title": "确认配置",
|
||||
"description": "**{nick_name}** 您好!请确认最新的配置信息,然后点击“提交”。\r\n集成将会使用更新后的配置重新载入。\r\n\r\n集成语言:\t{lang_new}\r\n用户昵称:\t{nick_name_new}\r\nAction 调试模式:\t{action_debug}\r\n隐藏非标准生成实体:\t{hide_non_standard_entities}\r\n设备变化:\t新增 **{devices_add}** 个设备,移除 **{devices_remove}** 个设备\r\n转换规则变化:\t共条 **{trans_rules_count}** 规则,更新 **{trans_rules_count_success}** 条规则",
|
||||
"description": "**{nick_name}** 您好!请确认最新的配置信息,然后点击“提交”。\r\n集成将会使用更新后的配置重新载入。\r\n\r\n集成语言:\t{lang_new}\r\n用户昵称:\t{nick_name_new}\r\nAction 调试模式:\t{action_debug}\r\n隐藏非标准生成实体:\t{hide_non_standard_entities}\r\n显示设备状态变化通知:\t{display_devices_changed_notify}\r\n设备变化:\t新增 **{devices_add}** 个设备,移除 **{devices_remove}** 个设备\r\n转换规则变化:\t共条 **{trans_rules_count}** 规则,更新 **{trans_rules_count_success}** 条规则",
|
||||
"data": {
|
||||
"confirm": "确认修改"
|
||||
}
|
||||
@ -127,11 +195,20 @@
|
||||
"get_homeinfo_error": "获取家庭信息失败。",
|
||||
"get_cert_error": "获取中枢证书失败。",
|
||||
"no_family_selected": "未选择家庭。",
|
||||
"no_devices": "选择的家庭中没有设备,请选择有设备的家庭,而后继续。",
|
||||
"no_devices": "选择的家庭中没有设备,请选择有设备的家庭,然后继续。",
|
||||
"no_filter_devices": "筛选设备为空。请选择有效的筛选条件,然后继续。",
|
||||
"no_central_device": "【中枢网关模式】需要 Home Assistant 所在的局域网中存在可用的小米中枢网关。请检查选择的家庭是否符合该要求。",
|
||||
"mdns_discovery_error": "本地设备发现服务异常。",
|
||||
"update_config_error": "配置信息更新失败。",
|
||||
"not_confirm": "未确认修改项。请勾选确认后再提交。"
|
||||
"not_confirm": "未确认修改项。请勾选确认后再提交。",
|
||||
"invalid_network_addr": "存在无效的IP地址或者HTTP地址,请输入有效的地址。",
|
||||
"invalid_ip_addr": "存在无法访问的IP地址,请输入有效的IP地址。",
|
||||
"invalid_http_addr": "存在无法访问的HTTP地址,请输入有效的HTTP地址。",
|
||||
"invalid_default_addr": "默认网络检测地址无法访问,请检查网络配置或者使用自定义网络检测地址。",
|
||||
"unreachable_oauth2_host": "无法访问 OAuth2 认证地址,请检查网络配置。",
|
||||
"unreachable_http_host": "无法访问小米 HTTP API 地址,请检查网络配置。",
|
||||
"unreachable_spec_host": "无法访问小米 SPEC API 地址,请检查网络配置。",
|
||||
"unreachable_mqtt_broker": "无法访问小米 MQTT Broker 地址,请检查网络配置。"
|
||||
},
|
||||
"abort": {
|
||||
"network_connect_error": "配置失败。网络连接异常,请检查设备网络配置。",
|
||||
|
@ -11,26 +11,59 @@
|
||||
},
|
||||
"auth_config": {
|
||||
"title": "基礎配置",
|
||||
"description": "### 登錄地區\r\n選擇小米帳號所在的地區。您可以在 `米家APP > 我的(位於底部菜單) > 更多設置 > 關於米家` 中查看。\r\n### 語言\r\n選擇設備及實體名稱所用的語言。缺少翻譯的部分語句將使用英文顯示。\r\n### OAuth2 認證跳轉地址\r\nOAuth2 認證跳轉地址為 **[http://homeassistant.local:8123](http://homeassistant.local:8123)**,Home Assistant 需要與當前操作終端(例如,個人電腦)在同一局域網內,且操作終端能通過該地址訪問 Home Assistant 首頁,否則登錄認證可能會失敗。\r\n### 注意事項\r\n- 對於數百個及以上米家設備的用戶,首次添加集成會耗費一些時間,請耐心等待。\r\n- 如果 Home Assistant 運行在docker環境下,請確保docker網絡模式為host,否則會導致本地控制功能異常。\r\n- 集成本地控制功能存在一些依賴項,請仔細閱讀README。",
|
||||
"description": "### 登錄地區\r\n選擇小米帳號所在的地區。您可以在 `米家APP > 我的(位於底部菜單) > 更多設置 > 關於米家` 中查看。\r\n### 語言\r\n選擇設備及實體名稱所用的語言。缺少翻譯的部分語句將使用英文顯示。\r\n### OAuth2 認證跳轉地址\r\nOAuth2 認證跳轉地址為 **[http://homeassistant.local:8123](http://homeassistant.local:8123)**,Home Assistant 需要與當前操作終端(例如,個人電腦)在同一局域網內,且操作終端能通過該地址訪問 Home Assistant 首頁,否則登錄認證可能會失敗。\r\n### 集成網絡配置\r\n檢測本地網絡是否正常,相關網絡資源是否可訪問。**首次添加時建議勾選。**\r\n### 注意事項\r\n- 對於數百個及以上米家設備的用戶,首次添加集成會耗費一些時間,請耐心等待。\r\n- 如果 Home Assistant 運行在docker環境下,請確保docker網絡模式為host,否則會導致本地控制功能異常。\r\n- 集成本地控制功能存在一些依賴項,請仔細閱讀README。",
|
||||
"data": {
|
||||
"cloud_server": "登錄地區",
|
||||
"integration_language": "語言",
|
||||
"oauth_redirect_url": "認證跳轉地址"
|
||||
"oauth_redirect_url": "認證跳轉地址",
|
||||
"network_detect_config": "集成網絡配置"
|
||||
}
|
||||
},
|
||||
"network_detect_config": {
|
||||
"title": "集成網絡配置",
|
||||
"description": "## 使用介紹\r\n### 網絡檢測地址\r\n用於檢測網絡是否正常,未設置時將使用系統默認地址檢測。如果默認地址檢測異常時,可嘗試輸入可用的自定義地址檢測。\r\n- 可輸入多個檢測地址,地址之間使用`,`號間隔,如`8.8.8.8,https://www.bing.com`\r\n- 如果為IP地址,將採用ping方式檢測,如果為http(s)地址,將採用 HTTP GET 訪問該地址檢測。\r\n- 如果想恢復系統默認檢測地址,請輸入`,`號,然後點擊'下一步'。\r\n- **該配置為全局配置,修改會影響其它集成實例的網絡檢測,請謹慎修改。**\r\n### 檢測網絡依賴項\r\n依次檢查下述網絡依賴項是否可訪問。如果相關地址無法訪問,將會導致集成異常。\r\n- OAuth2 認證地址:`https://account.xiaomi.com/oauth2/authorize`。\r\n- 小米 HTTP API 地址:`https://{http_host}/app/v2/ha/oauth/get_token`。\r\n- 小米 SPEC API 地址:`https://miot-spec.org/miot-spec-v2/template/list/device`。\r\n- 小米 MQTT Broker 地址:`mqtts://{cloud_server}-ha.mqtt.io.mi.com:8883`。",
|
||||
"data": {
|
||||
"network_detect_addr": "網絡檢測地址",
|
||||
"check_network_deps": "檢測網絡依賴項"
|
||||
}
|
||||
},
|
||||
"oauth_error": {
|
||||
"title": "登錄出現錯誤",
|
||||
"description": "點擊“下一步”重試"
|
||||
},
|
||||
"devices_filter": {
|
||||
"homes_select": {
|
||||
"title": "選擇家庭與設備",
|
||||
"description": "## 使用介紹\r\n### 控制模式\r\n- 自動:本地區域網內存在可用的小米中樞網關時, Home Assistant 會優先通過中樞網關發送設備控制指令,以實現本地化控制功能。本地區域網不存在中樞時,會嘗試通過小米OT協議發送控制指令,以實現本地化控制功能。只有當上述本地化控制條件不滿足時,設備控制指令才會通過雲端發送。\r\n- 雲端:控制指令僅通過雲端發送。\r\n### 導入設備的家庭\r\n集成將添加已選中家庭中的設備。\r\n### 房間名同步模式\r\n將設備從米家APP同步到 Home Assistant 時,設備在 Home Assistant 中所處區域的名稱的命名方式將遵循以下規則。注意,設備同步過程不會改變米家APP中家庭和房間的設置。\r\n- 不同步:設備不會被添加至任何區域。\r\n- 其它選項:設備所添加到的區域以米家APP中的家庭或房間名稱命名。\r\n### Action 調試模式\r\n對於設備 MIoT-Spec-V2 定義的方法,在生成通知實體之外,還會生成一個文本輸入框實體,您可以在調試時用它向設備發送控制指令。\r\n### 隱藏非標準生成實體\r\n隱藏名稱以“*”開頭的非標準 MIoT-Spec-V2 實例生成的實體。\r\n\r\n \r\n### {nick_name} 您好!請選擇集成控制模式以及您想要添加的設備所處的家庭。",
|
||||
"description": "## 使用介紹\r\n### 導入設備的家庭\r\n集成將添加已選中家庭中的設備。\r\n### 房間名同步模式\r\n將設備從米家APP同步到 Home Assistant 時,設備在 Home Assistant 中所處區域的名稱的命名方式將遵循以下規則。注意,設備同步過程不會改變米家APP中家庭和房間的設置。\r\n- 不同步:設備不會被添加至任何區域。\r\n- 其它選項:設備所添加到的區域以米家APP中的家庭或房間名稱命名。\r\n### 高級設置選項\r\n展示高級設置選項,對集成的專業配置選項進行修改。\r\n\r\n \r\n### {nick_name} 您好!請選擇您想要添加的設備所處家庭。",
|
||||
"data": {
|
||||
"ctrl_mode": "控制模式",
|
||||
"home_infos": "導入設備的家庭",
|
||||
"area_name_rule": "房間名同步模式",
|
||||
"advanced_options": "高級設置選項"
|
||||
}
|
||||
},
|
||||
"advanced_options": {
|
||||
"title": "高級設置選項",
|
||||
"description": "## 使用介紹\r\n### 除非您非常清楚下列選項的含義,否則請保持默認。\r\n### 篩選設備\r\n支持按照房間名稱和設備類型篩選設備,同時也支持設備維度篩選。\r\n### 控制模式\r\n- 自動:本地局域網內存在可用的小米中樞網關時, Home Assistant 會優先通過中樞網關發送設備控制指令,以實現本地化控制功能。本地局域網不存在中樞時,會嘗試通過小米OT協議發送控制指令,以實現本地化控制功能。只有當上述本地化控制條件不滿足時,設備控制指令才會通過雲端發送。\r\n- 雲端:控制指令僅通過雲端發送。\r\n### Action 調試模式\r\n對於設備 MIoT-Spec-V2 定義的方法,在生成通知實體之外,還會生成一個文本輸入框實體,您可以在調試時用它向設備發送控制指令。\r\n### 隱藏非標準生成實體\r\n隱藏名稱以“*”開頭的非標準 MIoT-Spec-V2 實例生成的實體。\r\n### 顯示設備狀態變化通知\r\n細化顯示設備狀態變化通知,只顯示勾選的通知消息。",
|
||||
"data": {
|
||||
"devices_filter": "篩選設備",
|
||||
"ctrl_mode": "控制模式",
|
||||
"action_debug": "Action 調試模式",
|
||||
"hide_non_standard_entities": "隱藏非標準生成實體"
|
||||
"hide_non_standard_entities": "隱藏非標準生成實體",
|
||||
"display_devices_changed_notify": "顯示設備狀態變化通知"
|
||||
}
|
||||
},
|
||||
"devices_filter": {
|
||||
"title": "篩選設備",
|
||||
"description": "## 使用介紹\r\n支持按照家庭房間名稱、設備接入類型、設備型號篩選設備,同時也支持設備維度篩選,篩選邏輯如下:\r\n- 會先根據統計邏輯獲取所有包含項的並集或者交集,然後再獲取排除項的交集或者並集,最後將【包含匯總結果】減去【排除匯總結果】得到【篩選結果】\r\n- 如未選擇包含項,表示包含全部。\r\n### 篩選模式\r\n- 排除:移除不需要的項。\r\n- 包含:包含需要的項。\r\n### 統計邏輯\r\n- 與邏輯:取所有同模式篩選項的交集。\r\n- 或邏輯:取所有同模式篩選項的並集。\r\n\r\n您也可以進入集成項的【配置>更新設備列表】頁面,勾選【篩選設備】重新篩選。",
|
||||
"data": {
|
||||
"room_filter_mode": "篩選家庭房間",
|
||||
"room_list": "家庭房間",
|
||||
"type_filter_mode": "篩選設備接入類型",
|
||||
"type_list": "設備接入類型",
|
||||
"model_filter_mode": "篩選設備型號",
|
||||
"model_list": "設備型號",
|
||||
"devices_filter_mode": "篩選設備",
|
||||
"device_list": "設備列表",
|
||||
"statistics_logic": "統計邏輯"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -44,8 +77,17 @@
|
||||
"mdns_discovery_error": "本地設備發現服務異常。",
|
||||
"get_cert_error": "獲取中樞證書失敗。",
|
||||
"no_family_selected": "未選擇家庭。",
|
||||
"no_devices": "選擇的家庭中沒有設備。請選擇有設備的家庭,而後繼續。",
|
||||
"no_central_device": "【中樞網關模式】需要 Home Assistant 所在的局域網中存在可用的小米中樞網關。請檢查選擇的家庭是否符合該要求。"
|
||||
"no_devices": "選擇的家庭中沒有設備。請選擇有設備的家庭,然後繼續。",
|
||||
"no_filter_devices": "篩選設備為空。請選擇有效的篩選條件,然後繼續。",
|
||||
"no_central_device": "【中樞網關模式】需要 Home Assistant 所在的局域網中存在可用的小米中樞網關。請檢查選擇的家庭是否符合該要求。",
|
||||
"invalid_network_addr": "存在無效的IP地址或者HTTP地址,請輸入有效的地址。",
|
||||
"invalid_ip_addr": "存在無法訪問的IP地址,請輸入有效的IP地址。",
|
||||
"invalid_http_addr": "存在無法訪問的HTTP地址,請輸入有效的HTTP地址。",
|
||||
"invalid_default_addr": "默認網絡檢測地址無法訪問,請檢查網絡配置或者使用自定義網絡檢測地址。",
|
||||
"unreachable_oauth2_host": "無法訪問 OAuth2 認證地址,請檢查網絡配置。",
|
||||
"unreachable_http_host": "無法訪問小米 HTTP API 地址,請檢查網絡配置。",
|
||||
"unreachable_spec_host": "無法訪問小米 SPEC API 地址,請檢查網絡配置。",
|
||||
"unreachable_mqtt_broker": "無法訪問小米 MQTT Broker 地址,請檢查網絡配置。"
|
||||
},
|
||||
"abort": {
|
||||
"network_connect_error": "配置失敗。網絡連接異常,請檢查設備網絡配置。",
|
||||
@ -69,15 +111,17 @@
|
||||
},
|
||||
"config_options": {
|
||||
"title": "配置選項",
|
||||
"description": "### {nick_name} 您好!\r\n\r\n小米帳號ID:{uid}\r\n當前登錄區域:{cloud_server}\r\n\r\n請勾選需要重新配置的選項,然後點擊“下一步”。",
|
||||
"description": "### {nick_name} 您好!\r\n\r\n小米帳號ID:{uid}\r\n當前登錄區域:{cloud_server}\r\n集成實例ID:{instance_id}\r\n\r\n請勾選需要重新配置的選項,然後點擊“下一步”。",
|
||||
"data": {
|
||||
"integration_language": "集成語言",
|
||||
"update_user_info": "更新用戶信息",
|
||||
"update_devices": "更新設備列表",
|
||||
"action_debug": "Action 調試模式",
|
||||
"hide_non_standard_entities": "隱藏非標準生成實體",
|
||||
"display_devices_changed_notify": "顯示設備狀態變化通知",
|
||||
"update_trans_rules": "更新實體轉換規則",
|
||||
"update_lan_ctrl_config": "更新局域網控制配置"
|
||||
"update_lan_ctrl_config": "更新局域網控制配置",
|
||||
"network_detect_config": "集成網絡配置"
|
||||
}
|
||||
},
|
||||
"update_user_info": {
|
||||
@ -87,12 +131,28 @@
|
||||
"nick_name": "用戶暱稱"
|
||||
}
|
||||
},
|
||||
"devices_filter": {
|
||||
"homes_select": {
|
||||
"title": "重新選擇家庭與設備",
|
||||
"description": "\r\n## 使用介紹\r\n### 控制模式\r\n- 自動:本地局域網內存在可用的小米中樞網關時, Home Assistant 會優先通過中樞網關發送設備控制指令,以實現本地化控制功能。只有當本地化控制條件不滿足時,設備控制指令才會通過雲端發送。\r\n- 雲端:控制指令強制通過雲端發送。\r\n### 導入設備的家庭\r\n集成將添加已選中家庭中的設備。\r\n \r\n### {nick_name} 您好!請選擇集成控制模式以及您想要添加的設備所處的家庭。",
|
||||
"description": "## 使用介紹\r\n### 導入設備的家庭\r\n集成將添加已選中家庭中的設備。\r\n### 篩選設備\r\n支持按照家庭房間名稱、設備接入類型、設備型號篩選設備,同時也支持設備維度篩選,已篩選出 **{local_count}** 個設備。\r\n### 控制模式\r\n- 自動:本地局域網內存在可用的小米中樞網關時, Home Assistant 會優先通過中樞網關發送設備控制指令,以實現本地化控制功能。只有當本地化控制條件不滿足時,設備控制指令才會通過雲端發送。\r\n- 雲端:控制指令強制通過雲端發送。",
|
||||
"data": {
|
||||
"ctrl_mode": "控制模式",
|
||||
"home_infos": "導入設備的家庭"
|
||||
"home_infos": "導入設備的家庭",
|
||||
"devices_filter": "篩選設備",
|
||||
"ctrl_mode": "控制模式"
|
||||
}
|
||||
},
|
||||
"devices_filter": {
|
||||
"title": "篩選設備",
|
||||
"description": "## 使用介紹\r\n支持按照家庭房間名稱、設備接入類型、設備型號篩選設備,同時也支持設備維度篩選,篩選邏輯如下:\r\n- 會先根據統計邏輯獲取所有包含項的並集或者交集,然後再獲取排除項的交集或者並集,最後將【包含匯總結果】減去【排除匯總結果】得到【篩選結果】\r\n- 如未選擇包含項,表示包含全部。\r\n### 篩選模式\r\n- 排除:移除不需要的項。\r\n- 包含:包含需要的項。\r\n### 統計邏輯\r\n- 與邏輯:取所有同模式篩選項的交集。\r\n- 或邏輯:取所有同模式篩選項的並集。\r\n\r\n您也可以進入集成項的【配置>更新設備列表】頁面,勾選【篩選設備】重新篩選。",
|
||||
"data": {
|
||||
"room_filter_mode": "篩選家庭房間",
|
||||
"room_list": "家庭房間",
|
||||
"type_filter_mode": "篩選設備接入類型",
|
||||
"type_list": "設備接入類型",
|
||||
"model_filter_mode": "篩選設備型號",
|
||||
"model_list": "設備型號",
|
||||
"devices_filter_mode": "篩選設備",
|
||||
"device_list": "設備列表",
|
||||
"statistics_logic": "統計邏輯"
|
||||
}
|
||||
},
|
||||
"update_trans_rules": {
|
||||
@ -110,9 +170,17 @@
|
||||
"enable_subscribe": "啟用局域網訂閱"
|
||||
}
|
||||
},
|
||||
"network_detect_config": {
|
||||
"title": "集成網絡配置",
|
||||
"description": "## 使用介紹\r\n### 網絡檢測地址\r\n用於檢測網絡是否正常,未設置時將使用系統默認地址檢測。如果默認地址檢測異常時,可嘗試輸入可用的自定義地址檢測。\r\n- 可輸入多個檢測地址,地址之間使用`,`號間隔,如`8.8.8.8,https://www.bing.com`\r\n- 如果為IP地址,將採用ping方式檢測,如果為http(s)地址,將採用 HTTP GET 訪問該地址檢測。\r\n- 如果想恢復系統默認檢測地址,請輸入`,`號,然後點擊'下一步'。\r\n- **該配置為全局配置,修改會影響其它集成實例的網絡檢測,請謹慎修改。**\r\n### 檢測網絡依賴項\r\n依次檢查下述網絡依賴項是否可訪問。如果相關地址無法訪問,將會導致集成異常。\r\n- OAuth2 認證地址:`https://account.xiaomi.com/oauth2/authorize`。\r\n- 小米 HTTP API 地址:`https://{http_host}/app/v2/ha/oauth/get_token`。\r\n- 小米 SPEC API 地址:`https://miot-spec.org/miot-spec-v2/template/list/device`。\r\n- 小米 MQTT Broker 地址:`mqtts://{cloud_server}-ha.mqtt.io.mi.com:8883`。",
|
||||
"data": {
|
||||
"network_detect_addr": "網絡檢測地址",
|
||||
"check_network_deps": "檢測網絡依賴項"
|
||||
}
|
||||
},
|
||||
"config_confirm": {
|
||||
"title": "確認配置",
|
||||
"description": "**{nick_name}** 您好!請確認最新的配置信息,然後點擊“提交”。\r\n集成將會使用更新後的配置重新載入。\r\n\r\n集成語言:\t{lang_new}\r\n用戶暱稱:\t{nick_name_new}\r\nAction 調試模式:\t{action_debug}\r\n隱藏非標準生成實體:\t{hide_non_standard_entities}\r\n設備變化:\t新增 **{devices_add}** 個設備,移除 **{devices_remove}** 個設備\r\n轉換規則變化:\t共條 **{trans_rules_count}** 規則,更新 **{trans_rules_count_success}** 條規則",
|
||||
"description": "**{nick_name}** 您好!請確認最新的配置信息,然後點擊“提交”。\r\n集成將會使用更新後的配置重新載入。\r\n\r\n集成語言:\t{lang_new}\r\n用戶暱稱:\t{nick_name_new}\r\nAction 調試模式:\t{action_debug}\r\n隱藏非標準生成實體:\t{hide_non_standard_entities}\r\n顯示設備狀態變化通知:\t{display_devices_changed_notify}\r\n設備變化:\t新增 **{devices_add}** 個設備,移除 **{devices_remove}** 個設備\r\n轉換規則變化:\t共條 **{trans_rules_count}** 規則,更新 **{trans_rules_count_success}** 條規則",
|
||||
"data": {
|
||||
"confirm": "確認修改"
|
||||
}
|
||||
@ -127,11 +195,20 @@
|
||||
"get_homeinfo_error": "獲取家庭信息失敗。",
|
||||
"get_cert_error": "獲取中樞證書失敗。",
|
||||
"no_family_selected": "未選擇家庭。",
|
||||
"no_devices": "選擇的家庭中沒有設備,請選擇有設備的家庭,而後繼續。",
|
||||
"no_devices": "選擇的家庭中沒有設備。請選擇有設備的家庭,然後繼續。",
|
||||
"no_filter_devices": "篩選設備為空。請選擇有效的篩選條件,然後繼續。",
|
||||
"no_central_device": "【中樞網關模式】需要 Home Assistant 所在的局域網中存在可用的小米中樞網關。請檢查選擇的家庭是否符合該要求。",
|
||||
"mdns_discovery_error": "本地設備發現服務異常。",
|
||||
"update_config_error": "配置信息更新失敗。",
|
||||
"not_confirm": "未確認修改項。請勾選確認後再提交。"
|
||||
"not_confirm": "未確認修改項。請勾選確認後再提交。",
|
||||
"invalid_network_addr": "存在無效的IP地址或者HTTP地址,請輸入有效的地址。",
|
||||
"invalid_ip_addr": "存在無法訪問的IP地址,請輸入有效的IP地址。",
|
||||
"invalid_http_addr": "存在無法訪問的HTTP地址,請輸入有效的HTTP地址。",
|
||||
"invalid_default_addr": "默認網絡檢測地址無法訪問,請檢查網絡配置或者使用自定義網絡檢測地址。",
|
||||
"unreachable_oauth2_host": "無法訪問 OAuth2 認證地址,請檢查網絡配置。",
|
||||
"unreachable_http_host": "無法訪問小米 HTTP API 地址,請檢查網絡配置。",
|
||||
"unreachable_spec_host": "無法訪問小米 SPEC API 地址,請檢查網絡配置。",
|
||||
"unreachable_mqtt_broker": "無法訪問小米 MQTT Broker 地址,請檢查網絡配置。"
|
||||
},
|
||||
"abort": {
|
||||
"network_connect_error": "配置失敗。網絡連接異常,請檢查設備網絡配置。",
|
||||
|
@ -47,7 +47,7 @@ Water heater entities for Xiaomi Home.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
import logging
|
||||
from typing import Optional
|
||||
from typing import Any, Optional
|
||||
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
@ -93,7 +93,7 @@ class WaterHeater(MIoTServiceEntity, WaterHeaterEntity):
|
||||
_prop_target_temp: Optional[MIoTSpecProperty]
|
||||
_prop_mode: Optional[MIoTSpecProperty]
|
||||
|
||||
_mode_list: Optional[dict[any, any]]
|
||||
_mode_list: Optional[dict[Any, Any]]
|
||||
|
||||
def __init__(
|
||||
self, miot_device: MIoTDevice, entity_data: MIoTEntityData
|
||||
@ -164,7 +164,7 @@ class WaterHeater(MIoTServiceEntity, WaterHeaterEntity):
|
||||
"""Turn the water heater off."""
|
||||
await self.set_property_async(prop=self._prop_on, value=False)
|
||||
|
||||
async def async_set_temperature(self, **kwargs: any) -> None:
|
||||
async def async_set_temperature(self, **kwargs: Any) -> None:
|
||||
"""Set the temperature the water heater should heat water to."""
|
||||
await self.set_property_async(
|
||||
prop=self._prop_target_temp, value=kwargs[ATTR_TEMPERATURE])
|
||||
|
@ -1,7 +0,0 @@
|
||||
# CHANGELOG
|
||||
|
||||
## 0.1.0
|
||||
### Added
|
||||
- first version
|
||||
### Changed
|
||||
### Fixed
|
@ -1,6 +1,6 @@
|
||||
# 贡献指南
|
||||
|
||||
[English](./CONTRIBUTING.md) | [简体中文](./CONTRIBUTING_zh.md)
|
||||
[English](../CONTRIBUTING.md) | [简体中文](./CONTRIBUTING_zh.md)
|
||||
|
||||
感谢您考虑为我们的项目做出贡献!您的努力将使我们的项目变得更好。
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
> Home Assistant 版本要求:
|
||||
>
|
||||
> - Core $\geq$ 2024.11.0
|
||||
> - Core $\geq$ 2024.4.4
|
||||
> - Operating System $\geq$ 13.0
|
||||
|
||||
### 方法 1:使用 git clone 命令从 GitHub 下载
|
||||
@ -32,7 +32,7 @@ git checkout v1.0.0
|
||||
|
||||
### 方法 2: [HACS](https://hacs.xyz/)
|
||||
|
||||
HACS > Overflow Menu > Custom repositories > Repository: https://github.com/XiaoMi/ha_xiaomi_home.git & Category: Integration > ADD
|
||||
HACS > 右上角三个点 > Custom repositories > Repository: https://github.com/XiaoMi/ha_xiaomi_home.git & Category or Type: Integration > ADD > 点击 HACS 的 New 或 Available for download 分类下的 Xiaomi Home ,进入集成详情页 > DOWNLOAD
|
||||
|
||||
> 米家集成暂未添加到 HACS 商店,敬请期待。
|
||||
|
||||
@ -76,6 +76,8 @@ HACS > Overflow Menu > Custom repositories > Repository: https://github.com/Xiao
|
||||
|
||||
米家集成及其使用的云端接口由小米官方提供。您需要使用小米账号登录以获取设备列表。米家集成使用 OAuth 2.0 的登录方式,不会在 Home Assistant 中保存您的小米账号密码。但由于 Home Assistant 平台的限制,登录成功后,您的小米用户信息(包括设备信息、证书、 token 等)会明文保存在 Home Assistant 的配置文件中。因此,您需要保管好自己 Home Assistant 配置文件。一旦该文件泄露,其他人可能会冒用您的身份登录。
|
||||
|
||||
> 如果您怀疑您的 OAuth 2.0 令牌已泄露,您可以通过以下步骤取消小米账号的登录授权: 米家 APP -> 我的 -> 点击用户名进入小米账号页面 -> 应用授权 -> Xiaomi Home (Home Assistant Integration) -> 取消授权
|
||||
|
||||
## 常见问题
|
||||
|
||||
- 米家集成是否支持所有的小米米家设备?
|
||||
@ -325,7 +327,7 @@ event instance name 下的值表示转换后实体所用的 `_attr_device_class`
|
||||
|
||||
## 多语言支持
|
||||
|
||||
米家集成配置选项中可选择的集成使用的语言有简体中文、繁体中文、英文、西班牙语、俄语、法语、德语、日语这八种语言。目前,米家集成配置页面的简体中文和英文已经过人工校审,其他语言由机器翻译。如果您希望修改配置页面的词句,则需要修改 `custom_components/xiaomi_home/translations/` 目录下相应语言的 json 文件。
|
||||
米家集成配置选项中可选择的集成使用的语言有简体中文、繁体中文、英文、西班牙语、俄语、法语、德语、日语这八种语言。目前,米家集成配置页面的简体中文和英文已经过人工校审,其他语言由机器翻译。如果您希望修改配置页面的词句,则需要修改 `custom_components/xiaomi_home/translations/` 以及 `custom_components/xiaomi_home/miot/i18n/` 目录下相应语言的 json 文件。
|
||||
|
||||
在显示 Home Assistant 实体名称时,米家集成会从小米云下载设备厂商为设备配置的多语言文件,该文件包含设备 MIoT-Spec-V2 实例的多语言翻译。 `multi_lang.json` 是本地维护的多语言配置字典,其优先级高于从云端获取的多语言文件,可用于补充或修改设备的多语言翻译。
|
||||
|
||||
@ -378,8 +380,8 @@ siid、piid、eiid、aiid、value 均为十进制三位整数。
|
||||
## 文档
|
||||
|
||||
- [许可证](../LICENSE.md)
|
||||
- 贡献指南: [English](./CONTRIBUTING.md) | [简体中文](./CONTRIBUTING_zh.md)
|
||||
- [更新日志](./CHANGELOG.md)
|
||||
- 贡献指南: [English](../CONTRIBUTING.md) | [简体中文](./CONTRIBUTING_zh.md)
|
||||
- [更新日志](../CHANGELOG.md)
|
||||
- 开发文档: https://developers.home-assistant.io/docs/creating_component_index
|
||||
|
||||
## 目录结构
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "Xiaomi Home",
|
||||
"homeassistant": "2024.11.0",
|
||||
"homeassistant": "2024.4.4",
|
||||
"hacs": "1.34.0"
|
||||
}
|
||||
|
17
install.sh
17
install.sh
@ -14,14 +14,21 @@ if [ ! -d "$config_path" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Remove the old version.
|
||||
rm -rf "$config_path/custom_components/xiaomi_home"
|
||||
# Get the script path.
|
||||
script_path=$(dirname "$0")
|
||||
# Change to the script path.
|
||||
cd "$script_path"
|
||||
|
||||
# Set source and target
|
||||
component_name=xiaomi_home
|
||||
source_path="$script_path/custom_components/$component_name"
|
||||
target_root="$config_path/custom_components"
|
||||
target_path="$target_root/$component_name"
|
||||
|
||||
# Remove the old version.
|
||||
rm -rf "$target_path"
|
||||
|
||||
# Copy the new version.
|
||||
cp -r custom_components/xiaomi_home/ "$config_path/custom_components/"
|
||||
mkdir -p "$target_root"
|
||||
cp -r "$source_path" "$target_path"
|
||||
|
||||
# Done.
|
||||
echo "Xiaomi Home installation is completed. Please restart Home Assistant."
|
||||
|
@ -4,8 +4,22 @@ import json
|
||||
from os import listdir, path
|
||||
from typing import Optional
|
||||
import pytest
|
||||
import yaml
|
||||
|
||||
SOURCE_DIR: str = path.dirname(path.abspath(__file__))
|
||||
ROOT_PATH: str = path.dirname(path.abspath(__file__))
|
||||
TRANS_RELATIVE_PATH: str = path.join(
|
||||
ROOT_PATH, '../custom_components/xiaomi_home/translations')
|
||||
MIOT_I18N_RELATIVE_PATH: str = path.join(
|
||||
ROOT_PATH, '../custom_components/xiaomi_home/miot/i18n')
|
||||
SPEC_BOOL_TRANS_FILE = path.join(
|
||||
ROOT_PATH,
|
||||
'../custom_components/xiaomi_home/miot/specs/bool_trans.json')
|
||||
SPEC_MULTI_LANG_FILE = path.join(
|
||||
ROOT_PATH,
|
||||
'../custom_components/xiaomi_home/miot/specs/multi_lang.json')
|
||||
SPEC_FILTER_FILE = path.join(
|
||||
ROOT_PATH,
|
||||
'../custom_components/xiaomi_home/miot/specs/spec_filter.json')
|
||||
|
||||
|
||||
def load_json_file(file_path: str) -> Optional[dict]:
|
||||
@ -20,6 +34,23 @@ def load_json_file(file_path: str) -> Optional[dict]:
|
||||
return None
|
||||
|
||||
|
||||
def save_json_file(file_path: str, data: dict) -> None:
|
||||
with open(file_path, 'w', encoding='utf-8') as file:
|
||||
json.dump(data, file, ensure_ascii=False, indent=4)
|
||||
|
||||
|
||||
def load_yaml_file(file_path: str) -> Optional[dict]:
|
||||
try:
|
||||
with open(file_path, 'r', encoding='utf-8') as file:
|
||||
return yaml.safe_load(file)
|
||||
except FileNotFoundError:
|
||||
print(file_path, 'is not found.')
|
||||
return None
|
||||
except yaml.YAMLError:
|
||||
print(file_path, 'is not a valid YAML file.')
|
||||
return None
|
||||
|
||||
|
||||
def dict_str_str(d: dict) -> bool:
|
||||
"""restricted format: dict[str, str]"""
|
||||
if not isinstance(d, dict):
|
||||
@ -83,45 +114,180 @@ def bool_trans(d: dict) -> bool:
|
||||
return False
|
||||
if not nested_3_dict_str_str(d['translate']):
|
||||
return False
|
||||
default_trans: dict = d['translate'].pop('default')
|
||||
if not default_trans:
|
||||
print('default trans is empty')
|
||||
return False
|
||||
default_keys: set[str] = set(default_trans.keys())
|
||||
for key, trans in d['translate'].items():
|
||||
trans_keys: set[str] = set(trans.keys())
|
||||
if set(trans.keys()) != default_keys:
|
||||
print('bool trans inconsistent', key, default_keys, trans_keys)
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def compare_dict_structure(dict1: dict, dict2: dict) -> bool:
|
||||
if not isinstance(dict1, dict) or not isinstance(dict2, dict):
|
||||
print('invalid type')
|
||||
return False
|
||||
if dict1.keys() != dict2.keys():
|
||||
print('inconsistent key values, ', dict1.keys(), dict2.keys())
|
||||
return False
|
||||
for key in dict1:
|
||||
if isinstance(dict1[key], dict) and isinstance(dict2[key], dict):
|
||||
if not compare_dict_structure(dict1[key], dict2[key]):
|
||||
print('inconsistent key values, dict, ', key)
|
||||
return False
|
||||
elif isinstance(dict1[key], list) and isinstance(dict2[key], list):
|
||||
if not all(
|
||||
isinstance(i, type(j))
|
||||
for i, j in zip(dict1[key], dict2[key])):
|
||||
print('inconsistent key values, list, ', key)
|
||||
return False
|
||||
elif not isinstance(dict1[key], type(dict2[key])):
|
||||
print('inconsistent key values, type, ', key)
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def sort_bool_trans(file_path: str):
|
||||
trans_data: dict = load_json_file(file_path=file_path)
|
||||
trans_data['data'] = dict(sorted(trans_data['data'].items()))
|
||||
for key, trans in trans_data['translate'].items():
|
||||
trans_data['translate'][key] = dict(sorted(trans.items()))
|
||||
return trans_data
|
||||
|
||||
|
||||
def sort_multi_lang(file_path: str):
|
||||
multi_lang: dict = load_json_file(file_path=file_path)
|
||||
multi_lang = dict(sorted(multi_lang.items()))
|
||||
for urn, trans in multi_lang.items():
|
||||
multi_lang[urn] = dict(sorted(trans.items()))
|
||||
for lang, spec in multi_lang[urn].items():
|
||||
multi_lang[urn][lang] = dict(sorted(spec.items()))
|
||||
return multi_lang
|
||||
|
||||
|
||||
def sort_spec_filter(file_path: str):
|
||||
filter_data: dict = load_json_file(file_path=file_path)
|
||||
filter_data = dict(sorted(filter_data.items()))
|
||||
for urn, spec in filter_data.items():
|
||||
filter_data[urn] = dict(sorted(spec.items()))
|
||||
return filter_data
|
||||
|
||||
|
||||
@pytest.mark.github
|
||||
def test_bool_trans():
|
||||
data: dict = load_json_file(
|
||||
path.join(
|
||||
SOURCE_DIR,
|
||||
'../custom_components/xiaomi_home/miot/specs/bool_trans.json'))
|
||||
assert data
|
||||
assert bool_trans(data)
|
||||
data: dict = load_json_file(SPEC_BOOL_TRANS_FILE)
|
||||
assert data, f'load {SPEC_BOOL_TRANS_FILE} failed'
|
||||
assert bool_trans(data), f'{SPEC_BOOL_TRANS_FILE} format error'
|
||||
|
||||
|
||||
@pytest.mark.github
|
||||
def test_spec_filter():
|
||||
data: dict = load_json_file(
|
||||
path.join(
|
||||
SOURCE_DIR,
|
||||
'../custom_components/xiaomi_home/miot/specs/spec_filter.json'))
|
||||
assert data
|
||||
assert spec_filter(data)
|
||||
data: dict = load_json_file(SPEC_FILTER_FILE)
|
||||
assert data, f'load {SPEC_FILTER_FILE} failed'
|
||||
assert spec_filter(data), f'{SPEC_FILTER_FILE} format error'
|
||||
|
||||
|
||||
@pytest.mark.github
|
||||
def test_multi_lang():
|
||||
data: dict = load_json_file(
|
||||
path.join(
|
||||
SOURCE_DIR,
|
||||
'../custom_components/xiaomi_home/miot/specs/multi_lang.json'))
|
||||
assert data
|
||||
assert nested_3_dict_str_str(data)
|
||||
data: dict = load_json_file(SPEC_MULTI_LANG_FILE)
|
||||
assert data, f'load {SPEC_MULTI_LANG_FILE} failed'
|
||||
assert nested_3_dict_str_str(data), f'{SPEC_MULTI_LANG_FILE} format error'
|
||||
|
||||
|
||||
@pytest.mark.github
|
||||
def test_miot_i18n():
|
||||
i18n_path: str = path.join(
|
||||
SOURCE_DIR, '../custom_components/xiaomi_home/miot/i18n')
|
||||
for file_name in listdir(i18n_path):
|
||||
file_path: str = path.join(i18n_path, file_name)
|
||||
for file_name in listdir(MIOT_I18N_RELATIVE_PATH):
|
||||
file_path: str = path.join(MIOT_I18N_RELATIVE_PATH, file_name)
|
||||
data: dict = load_json_file(file_path)
|
||||
assert data
|
||||
assert nested_3_dict_str_str(data)
|
||||
assert data, f'load {file_path} failed'
|
||||
assert nested_3_dict_str_str(data), f'{file_path} format error'
|
||||
|
||||
|
||||
@pytest.mark.github
|
||||
def test_translations():
|
||||
for file_name in listdir(TRANS_RELATIVE_PATH):
|
||||
file_path: str = path.join(TRANS_RELATIVE_PATH, file_name)
|
||||
data: dict = load_json_file(file_path)
|
||||
assert data, f'load {file_path} failed'
|
||||
assert dict_str_dict(data), f'{file_path} format error'
|
||||
|
||||
|
||||
@pytest.mark.github
|
||||
def test_miot_lang_integrity():
|
||||
# pylint: disable=import-outside-toplevel
|
||||
from miot.const import INTEGRATION_LANGUAGES
|
||||
integration_lang_list: list[str] = [
|
||||
f'{key}.json' for key in list(INTEGRATION_LANGUAGES.keys())]
|
||||
translations_names: set[str] = set(listdir(TRANS_RELATIVE_PATH))
|
||||
assert len(translations_names) == len(integration_lang_list)
|
||||
assert translations_names == set(integration_lang_list)
|
||||
i18n_names: set[str] = set(listdir(MIOT_I18N_RELATIVE_PATH))
|
||||
assert len(i18n_names) == len(translations_names)
|
||||
assert i18n_names == translations_names
|
||||
bool_trans_data: set[str] = load_json_file(SPEC_BOOL_TRANS_FILE)
|
||||
bool_trans_names: set[str] = set(
|
||||
bool_trans_data['translate']['default'].keys())
|
||||
assert len(bool_trans_names) == len(translations_names)
|
||||
# Check translation files structure
|
||||
default_dict: dict = load_json_file(
|
||||
path.join(TRANS_RELATIVE_PATH, integration_lang_list[0]))
|
||||
for name in list(integration_lang_list)[1:]:
|
||||
compare_dict: dict = load_json_file(
|
||||
path.join(TRANS_RELATIVE_PATH, name))
|
||||
if not compare_dict_structure(default_dict, compare_dict):
|
||||
print('compare_dict_structure failed /translations, ', name)
|
||||
assert False
|
||||
# Check i18n files structure
|
||||
default_dict = load_json_file(
|
||||
path.join(MIOT_I18N_RELATIVE_PATH, integration_lang_list[0]))
|
||||
for name in list(integration_lang_list)[1:]:
|
||||
compare_dict: dict = load_json_file(
|
||||
path.join(MIOT_I18N_RELATIVE_PATH, name))
|
||||
if not compare_dict_structure(default_dict, compare_dict):
|
||||
print('compare_dict_structure failed /miot/i18n, ', name)
|
||||
assert False
|
||||
|
||||
|
||||
@pytest.mark.github
|
||||
def test_miot_data_sort():
|
||||
# pylint: disable=import-outside-toplevel
|
||||
from miot.const import INTEGRATION_LANGUAGES
|
||||
sort_langs: dict = dict(sorted(INTEGRATION_LANGUAGES.items()))
|
||||
assert list(INTEGRATION_LANGUAGES.keys()) == list(sort_langs.keys()), (
|
||||
'INTEGRATION_LANGUAGES not sorted, correct order\r\n'
|
||||
f'{list(sort_langs.keys())}')
|
||||
assert json.dumps(
|
||||
load_json_file(file_path=SPEC_BOOL_TRANS_FILE)) == json.dumps(
|
||||
sort_bool_trans(file_path=SPEC_BOOL_TRANS_FILE)), (
|
||||
f'{SPEC_BOOL_TRANS_FILE} not sorted, goto project root path'
|
||||
' and run the following command sorting, ',
|
||||
'pytest -s -v -m update ./test/check_rule_format.py')
|
||||
assert json.dumps(
|
||||
load_json_file(file_path=SPEC_MULTI_LANG_FILE)) == json.dumps(
|
||||
sort_multi_lang(file_path=SPEC_MULTI_LANG_FILE)), (
|
||||
f'{SPEC_MULTI_LANG_FILE} not sorted, goto project root path'
|
||||
' and run the following command sorting, ',
|
||||
'pytest -s -v -m update ./test/check_rule_format.py')
|
||||
assert json.dumps(
|
||||
load_json_file(file_path=SPEC_FILTER_FILE)) == json.dumps(
|
||||
sort_spec_filter(file_path=SPEC_FILTER_FILE)), (
|
||||
f'{SPEC_FILTER_FILE} not sorted, goto project root path'
|
||||
' and run the following command sorting, ',
|
||||
'pytest -s -v -m update ./test/check_rule_format.py')
|
||||
|
||||
|
||||
@pytest.mark.update
|
||||
def test_sort_spec_data():
|
||||
sort_data: dict = sort_bool_trans(file_path=SPEC_BOOL_TRANS_FILE)
|
||||
save_json_file(file_path=SPEC_BOOL_TRANS_FILE, data=sort_data)
|
||||
print(SPEC_BOOL_TRANS_FILE, 'formatted.')
|
||||
sort_data = sort_multi_lang(file_path=SPEC_MULTI_LANG_FILE)
|
||||
save_json_file(file_path=SPEC_MULTI_LANG_FILE, data=sort_data)
|
||||
print(SPEC_MULTI_LANG_FILE, 'formatted.')
|
||||
sort_data = sort_spec_filter(file_path=SPEC_FILTER_FILE)
|
||||
save_json_file(file_path=SPEC_FILTER_FILE, data=sort_data)
|
||||
print(SPEC_FILTER_FILE, 'formatted.')
|
||||
|
@ -43,6 +43,13 @@ def load_py_file():
|
||||
dst=path.join(TEST_FILES_PATH, 'specs'),
|
||||
dirs_exist_ok=True)
|
||||
print('loaded spec test folder, specs')
|
||||
# Copy lan files to test folder
|
||||
shutil.copytree(
|
||||
src=path.join(
|
||||
TEST_ROOT_PATH, '../custom_components/xiaomi_home/miot/lan'),
|
||||
dst=path.join(TEST_FILES_PATH, 'lan'),
|
||||
dirs_exist_ok=True)
|
||||
print('loaded lan test folder, lan')
|
||||
# Copy i18n files to test folder
|
||||
shutil.copytree(
|
||||
src=path.join(
|
||||
|
@ -1,3 +1,4 @@
|
||||
[pytest]
|
||||
markers:
|
||||
github: tests for github actions
|
||||
update: update or re-sort config file
|
@ -1,5 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Unit test for miot_lan.py."""
|
||||
from typing import Any
|
||||
import pytest
|
||||
import asyncio
|
||||
from zeroconf import IPVersion
|
||||
@ -8,8 +9,37 @@ from zeroconf.asyncio import AsyncZeroconf
|
||||
# pylint: disable=import-outside-toplevel, unused-argument
|
||||
|
||||
|
||||
@pytest.mark.parametrize('test_devices', [{
|
||||
# specv2 model
|
||||
'123456': {
|
||||
'token': '11223344556677d9a03d43936fc384205',
|
||||
'model': 'xiaomi.gateway.hub1'
|
||||
},
|
||||
# profile model
|
||||
'123457': {
|
||||
'token': '11223344556677d9a03d43936fc384205',
|
||||
'model': 'yeelink.light.lamp9'
|
||||
},
|
||||
'123458': {
|
||||
'token': '11223344556677d9a03d43936fc384205',
|
||||
'model': 'zhimi.heater.ma1'
|
||||
},
|
||||
# Non -digital did
|
||||
'group.123456': {
|
||||
'token': '11223344556677d9a03d43936fc384205',
|
||||
'model': 'mijia.light.group3'
|
||||
},
|
||||
'proxy.123456.1': {
|
||||
'token': '11223344556677d9a03d43936fc384205',
|
||||
'model': 'xiaomi.light.p1'
|
||||
},
|
||||
'miwifi_123456': {
|
||||
'token': '11223344556677d9a03d43936fc384205',
|
||||
'model': 'xiaomi.light.p1'
|
||||
}
|
||||
}])
|
||||
@pytest.mark.asyncio
|
||||
async def test_lan_async():
|
||||
async def test_lan_async(test_devices: dict):
|
||||
"""
|
||||
Use the central hub gateway as a test equipment, and through the local area
|
||||
network control central hub gateway indicator light switch. Please replace
|
||||
@ -21,10 +51,13 @@ async def test_lan_async():
|
||||
from miot.miot_lan import MIoTLan
|
||||
from miot.miot_mdns import MipsService
|
||||
|
||||
test_did = '<Your central hub gateway did>'
|
||||
test_token = '<Your central hub gateway token>'
|
||||
# Your central hub gateway did
|
||||
test_did = '111111'
|
||||
# Your central hub gateway did
|
||||
test_token = '11223344556677d9a03d43936fc384205'
|
||||
test_model = 'xiaomi.gateway.hub1'
|
||||
test_if_names = ['<Your computer interface list, such as enp3s0, wlp5s0>']
|
||||
# Your computer interface list, such as enp3s0, wlp5s0
|
||||
test_if_names = ['enp3s0', 'wlp5s0']
|
||||
|
||||
# Check test params
|
||||
assert int(test_did) > 0
|
||||
@ -47,7 +80,7 @@ async def test_lan_async():
|
||||
evt_push_unavailable = asyncio.Event()
|
||||
await miot_lan.vote_for_lan_ctrl_async(key='test', vote=True)
|
||||
|
||||
async def device_state_change(did: str, state: dict, ctx: any):
|
||||
async def device_state_change(did: str, state: dict, ctx: Any):
|
||||
print('device state change, ', did, state)
|
||||
if did != test_did:
|
||||
return
|
||||
@ -76,7 +109,8 @@ async def test_lan_async():
|
||||
test_did: {
|
||||
'token': test_token,
|
||||
'model': test_model
|
||||
}
|
||||
},
|
||||
**test_devices
|
||||
})
|
||||
|
||||
# Test sub device state
|
||||
|
44
tools/common.py
Normal file
44
tools/common.py
Normal file
@ -0,0 +1,44 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Common functions."""
|
||||
import json
|
||||
import yaml
|
||||
from urllib.parse import urlencode
|
||||
from urllib.request import Request, urlopen
|
||||
|
||||
|
||||
def load_yaml_file(yaml_file: str) -> dict:
|
||||
with open(yaml_file, 'r', encoding='utf-8') as file:
|
||||
return yaml.safe_load(file)
|
||||
|
||||
|
||||
def save_yaml_file(yaml_file: str, data: dict) -> None:
|
||||
with open(yaml_file, 'w', encoding='utf-8') as file:
|
||||
yaml.safe_dump(
|
||||
data=data, stream=file, allow_unicode=True)
|
||||
|
||||
|
||||
def load_json_file(json_file: str) -> dict:
|
||||
with open(json_file, 'r', encoding='utf-8') as file:
|
||||
return json.load(file)
|
||||
|
||||
|
||||
def save_json_file(json_file: str, data: dict) -> None:
|
||||
with open(json_file, 'w', encoding='utf-8') as file:
|
||||
json.dump(data, file, ensure_ascii=False, indent=4)
|
||||
|
||||
|
||||
def http_get(
|
||||
url: str, params: dict = None, headers: dict = None
|
||||
) -> dict:
|
||||
if params:
|
||||
encoded_params = urlencode(params)
|
||||
full_url = f'{url}?{encoded_params}'
|
||||
else:
|
||||
full_url = url
|
||||
request = Request(full_url, method='GET', headers=headers or {})
|
||||
content: bytes = None
|
||||
with urlopen(request) as response:
|
||||
content = response.read()
|
||||
return (
|
||||
json.loads(str(content, 'utf-8'))
|
||||
if content is not None else None)
|
80
tools/update_lan_rule.py
Normal file
80
tools/update_lan_rule.py
Normal file
@ -0,0 +1,80 @@
|
||||
""" Update LAN rule."""
|
||||
# -*- coding: utf-8 -*-
|
||||
# pylint: disable=relative-beyond-top-level
|
||||
from os import path
|
||||
from common import (
|
||||
http_get,
|
||||
load_yaml_file,
|
||||
save_yaml_file)
|
||||
|
||||
|
||||
ROOT_PATH: str = path.dirname(path.abspath(__file__))
|
||||
LAN_PROFILE_MODELS_FILE: str = path.join(
|
||||
ROOT_PATH,
|
||||
'../custom_components/xiaomi_home/miot/lan/profile_models.yaml')
|
||||
|
||||
|
||||
SPECIAL_MODELS: list[str] = [
|
||||
# model2class-v2
|
||||
'chuangmi.camera.ipc007b', 'chuangmi.camera.ipc019b',
|
||||
'chuangmi.camera.ipc019e', 'chuangmi.camera.ipc020',
|
||||
'chuangmi.camera.v2', 'chuangmi.camera.v5',
|
||||
'chuangmi.camera.v6', 'chuangmi.camera.xiaobai',
|
||||
'chuangmi.radio.v1', 'chuangmi.radio.v2',
|
||||
'hith.foot_bath.q2', 'imou99.camera.tp2',
|
||||
'isa.camera.hl5', 'isa.camera.isc5',
|
||||
'jiqid.mistory.pro', 'jiqid.mistory.v1',
|
||||
'lumi.airrtc.tcpco2ecn01', 'lumi.airrtc.tcpecn02',
|
||||
'lumi.camera.gwagl01', 'miir.light.ir01',
|
||||
'miir.projector.ir01', 'miir.tv.hir01',
|
||||
'miir.tvbox.ir01', 'roome.bhf_light.yf6002',
|
||||
'smith.waterpuri.jnt600', 'viomi.fridge.u2',
|
||||
'xiaovv.camera.lamp', 'xiaovv.camera.ptz',
|
||||
'xiaovv.camera.xva3', 'xiaovv.camera.xvb4',
|
||||
'xiaovv.camera.xvsnowman', 'zdeer.ajh.a8',
|
||||
'zdeer.ajh.a9', 'zdeer.ajh.zda10',
|
||||
'zdeer.ajh.zda9', 'zdeer.ajh.zjy', 'zimi.clock.myk01',
|
||||
# specialModels
|
||||
'chuangmi.camera.ipc004b', 'chuangmi.camera.ipc009',
|
||||
'chuangmi.camera.ipc010', 'chuangmi.camera.ipc013',
|
||||
'chuangmi.camera.ipc013d', 'chuangmi.camera.ipc016',
|
||||
'chuangmi.camera.ipc017', 'chuangmi.camera.ipc019',
|
||||
'chuangmi.camera.ipc021', 'chuangmi.camera.v3',
|
||||
'chuangmi.camera.v4', 'isa.camera.df3',
|
||||
'isa.camera.hlc6', 'lumi.acpartner.v1',
|
||||
'lumi.acpartner.v2', 'lumi.acpartner.v3',
|
||||
'lumi.airrtc.tcpecn01', 'lumi.camera.aq1',
|
||||
'miir.aircondition.ir01', 'miir.aircondition.ir02',
|
||||
'miir.fan.ir01', 'miir.stb.ir01',
|
||||
'miir.tv.ir01', 'mijia.camera.v1',
|
||||
'mijia.camera.v3', 'roborock.sweeper.s5v2',
|
||||
'roborock.vacuum.c1', 'roborock.vacuum.e2',
|
||||
'roborock.vacuum.m1s', 'roborock.vacuum.s5',
|
||||
'rockrobo.vacuum.v1', 'xiaovv.camera.xvd5']
|
||||
|
||||
|
||||
def update_profile_model(file_path: str):
|
||||
profile_rules: dict = http_get(
|
||||
url='https://miot-spec.org/instance/translate/models')
|
||||
if not profile_rules and 'models' not in profile_rules and not isinstance(
|
||||
profile_rules['models'], dict):
|
||||
raise ValueError('Failed to get profile rule')
|
||||
local_rules: dict = load_yaml_file(
|
||||
yaml_file=file_path) or {}
|
||||
for rule, ts in profile_rules['models'].items():
|
||||
if rule not in local_rules:
|
||||
local_rules[rule] = {'ts': ts}
|
||||
else:
|
||||
local_rules[rule]['ts'] = ts
|
||||
for mode in SPECIAL_MODELS:
|
||||
if mode not in local_rules:
|
||||
local_rules[mode] = {'ts': 1531108800}
|
||||
else:
|
||||
local_rules[mode]['ts'] = 1531108800
|
||||
local_rules = dict(sorted(local_rules.items()))
|
||||
save_yaml_file(
|
||||
yaml_file=file_path, data=local_rules)
|
||||
|
||||
|
||||
update_profile_model(file_path=LAN_PROFILE_MODELS_FILE)
|
||||
print('profile model list updated.')
|
Reference in New Issue
Block a user