Compare commits

...

31 Commits

Author SHA1 Message Date
Gavin
0c7c433da4
Merge 4fd7a7272b into 8cbb451153 2025-07-24 06:19:05 +00:00
GavinIves
4fd7a7272b make better 2025-07-24 06:18:54 +00:00
GavinIves
0497ca0ff1 Merge remote-tracking branch 'upstream/main' into add-command-sending-mode-for-lights 2025-07-24 06:18:37 +00:00
Li Shuzhen
8cbb451153
docs: update changelog and version to v0.4.0 (#1281)
Some checks failed
Tests / check-rule-format (push) Has been cancelled
Validate / validate-hassfest (push) Has been cancelled
Validate / validate-hacs (push) Has been cancelled
Validate / validate-lint (push) Has been cancelled
Validate / validate-setup (push) Has been cancelled
2025-07-22 09:06:01 +08:00
Li Shuzhen
0fee02ae5c
feat: add notifications for the local connection to the central hub gateway (#1280)
Some checks are pending
Tests / check-rule-format (push) Waiting to run
Validate / validate-hassfest (push) Waiting to run
Validate / validate-hacs (push) Waiting to run
Validate / validate-lint (push) Waiting to run
Validate / validate-setup (push) Waiting to run
* feat: add notifications for the central hub gateway connection status (#1103)

* fix: i18n langurage support

* fix: add notification of disconnection when ServiceStateChange.REMOVED
2025-07-21 16:49:42 +08:00
Li Shuzhen
580ff87e7f
fix: specs (#1256)
* fix: xiaomi.aircondition.c24 total power consumption unit (#1243)

* fix: adp.motor.adswb4 motor switch (#1257)

* docs: modify README

* fix: cgllc.airm.cgd1st environment temperature (#1270)

* fix: shhf.light.sflt11 fan switch status (#1276)
2025-07-21 16:44:47 +08:00
Li Shuzhen
94583a23d1
fix: subscribe when connected to the central hub gateway (#1266)
Some checks failed
Tests / check-rule-format (push) Has been cancelled
Validate / validate-hassfest (push) Has been cancelled
Validate / validate-hacs (push) Has been cancelled
Validate / validate-lint (push) Has been cancelled
Validate / validate-setup (push) Has been cancelled
2025-07-16 14:43:50 +08:00
Li Shuzhen
925cf3b90f
feat: do not subscribe BLE device online/offline state message (#1264) 2025-07-16 13:57:43 +08:00
Li Shuzhen
836bd01ead
fix: cover status (#1262) 2025-07-16 13:57:18 +08:00
Li Shuzhen
4ad040d2ea
feat: get devices from the third party cloud (#1258)
Some checks are pending
Tests / check-rule-format (push) Waiting to run
Validate / validate-hassfest (push) Waiting to run
Validate / validate-hacs (push) Waiting to run
Validate / validate-lint (push) Waiting to run
Validate / validate-setup (push) Waiting to run
2025-07-15 16:26:35 +08:00
Li Shuzhen
981429670a
feat: add an alongside switch entity for viomi.waterheater.m1 (#1255) 2025-07-15 16:26:13 +08:00
Li Shuzhen
a82fd86c60
fix: mdns discovered ip address (#1250)
Some checks are pending
Tests / check-rule-format (push) Waiting to run
Validate / validate-hassfest (push) Waiting to run
Validate / validate-hacs (push) Waiting to run
Validate / validate-lint (push) Waiting to run
Validate / validate-setup (push) Waiting to run
2025-07-14 09:04:38 +08:00
Li Shuzhen
df3faea257
feat: set the cover closed position (#1242)
* feat: add the cover closed position configure option

* feat: estimate the cover entity's is_closed property by the cover closed position (#944)

* fix: translations

* feat: set max cover closed position as 5

* docs: modify README

* fix: remove useless spaces
2025-07-14 09:03:54 +08:00
GavinIves
c1a6c7e6d2 fix bug 2025-07-09 05:36:50 +00:00
GavinIves
ed76ae9cd1 fix bug 2025-07-09 03:42:05 +00:00
GavinIves
99ddf9bbc0 fix bug 2025-07-09 03:08:08 +00:00
GavinIves
052428febb Remove set_property_async and convert all to set_properties_async to keep the code concise 2025-07-09 02:46:57 +00:00
GavinIves
044f5486ec Merge remote-tracking branch 'upstream/main' into add-command-sending-mode-for-lights 2025-07-09 02:26:21 +00:00
GavinIves
c9a46662ae Add it to all devices with light entities, because some bathroom heaters and clothes drying racks also have lights. 2025-07-09 01:59:07 +00:00
GavinIves
1b58dc75fb fix bug 2025-07-08 05:51:52 +00:00
GavinIves
1cf52a3f78 Search entityid through unique_id to avoid the user modifying entityid and causing command_send_mode to not match 2025-07-08 03:10:33 +00:00
GavinIves
8ad214a672 Merge remote-tracking branch 'upstream/main' into add-command-sending-mode-for-lights 2025-07-07 01:45:39 +00:00
GavinIves
8dc840c51c resolve conflict 2025-06-20 02:14:30 +00:00
GavinIves
819be56bd8 Merge remote-tracking branch 'upstream/main' into add-command-sending-mode-for-lights 2025-06-20 02:13:08 +00:00
GavinIves
10cb50210b Merge remote-tracking branch 'upstream/main' into add-command-sending-mode-for-lights 2025-06-19 02:28:27 +00:00
GavinIves
41c47b8894 formatted code 2025-06-05 06:02:32 +00:00
GavinIves
da45938656 Modify the order in which the light-on properties are sent 2025-06-04 20:20:37 +08:00
GavinIves
f271336670 Modify the order in which the light-on properties are sent 2025-06-04 20:16:12 +08:00
GavinIves
3d50562eec fomatted code 2025-06-04 09:05:45 +00:00
GavinIves
83899f8084 fomatted code 2025-06-04 08:52:48 +00:00
GavinIves
b72ec85ae9 Added command sending mode for lights to optimize the lighting effect 2025-06-04 08:19:00 +00:00
40 changed files with 3501 additions and 2749 deletions

View File

@ -1,4 +1,20 @@
# CHANGELOG # CHANGELOG
## v0.4.0
### Added
- Add the watch as the device tracker entity. [#1189](https://github.com/XiaoMi/ha_xiaomi_home/pull/1189)
- Add the wifi speaker and the television as the media player entity. [#706](https://github.com/XiaoMi/ha_xiaomi_home/pull/706)
- Add an option in CONFIGURE to set the cover closed position. [#1242](https://github.com/XiaoMi/ha_xiaomi_home/pull/1242)
- Add notifications to show the status of the local connection to the central hub gateway. [#1280](https://github.com/XiaoMi/ha_xiaomi_home/pull/1280)
- Import the device from the third party cloud. [#1258](https://github.com/XiaoMi/ha_xiaomi_home/pull/1258)
### Changed
- Add an alongside switch entity for viomi.waterheater.m1. [#1255](https://github.com/XiaoMi/ha_xiaomi_home/pull/1255)
- Do not subscribe BLE device online/offline state message. [#1264](https://github.com/XiaoMi/ha_xiaomi_home/pull/1264)
### Fixed
- Keep the first element of the discovered ip address list as the recently added address when getting mdns result. [#1250](https://github.com/XiaoMi/ha_xiaomi_home/pull/1250)
- Subscribe local topics every time when connected to the central hub gateway. [#1266](https://github.com/XiaoMi/ha_xiaomi_home/pull/1266)
- Record the "closing" and "closed" status that occur frequently in the motor-controller, the window-opener and the curtain service. [#1262](https://github.com/XiaoMi/ha_xiaomi_home/pull/1262)
- Fix xiaomi.aircondition.c24 total power consumption unit, adp.motor.adswb4 motor switch, cgllc.airm.cgd1st environment temperature, and shhf.light.sflt11 fan switch status. [#1256](https://github.com/XiaoMi/ha_xiaomi_home/pull/1256)
## v0.3.4 ## v0.3.4
### Added ### Added
- Exclude the unsupported device models. [#1205](https://github.com/XiaoMi/ha_xiaomi_home/pull/1205) - Exclude the unsupported device models. [#1205](https://github.com/XiaoMi/ha_xiaomi_home/pull/1205)

View File

@ -83,9 +83,9 @@ Xiaomi Home Integration and the affiliated cloud interface is provided by Xiaomi
## FAQ ## FAQ
- Does Xiaomi Home Integration support all Xiaomi Home devices? - Does Xiaomi Home Integration support all Xiaomi smart devices?
Xiaomi Home Integration currently supports most categories of Home device. Only a few categories are not supported. They are Bluetooth device, infrared device and virtual device. Xiaomi Home Integration currently supports most categories of the smart device. Only a few categories are not supported. They are Bluetooth device, infrared device and virtual device.
- Does Xiaomi Home Integration support multiple Xiaomi accounts? - Does Xiaomi Home Integration support multiple Xiaomi accounts?
@ -93,7 +93,7 @@ Xiaomi Home Integration and the affiliated cloud interface is provided by Xiaomi
- Does Xiaomi Home Integration support local control? - Does Xiaomi Home Integration support local control?
Local control is implemented by [Xiaomi Central Hub Gateway](https://www.mi.com/shop/buy/detail?product_id=15755&cfrom=search) (firmware version 3.4.0_0000 above) or Xiaomi home devices with built-in central hub gateway (software version 0.8.0 above) inside. If you do not have a Xiaomi central hub gateway or other devices having central hub gateway function, all control commands are sent through Xiaomi Cloud. The firmware for Xiaomi central hub gateway including the built-in central hub gateway supporting Home Assistant local control feature has not been released yet. Please refer to MIoT team's notification for upgrade plans. Local control is implemented by [Xiaomi Central Hub Gateway](https://www.mi.com/shop/buy/detail?product_id=15755&cfrom=search) (firmware version 3.3.0_0023 and above) or Xiaomi smart devices with built-in central hub gateway (software version 0.8.9 and above) inside. If you do not have a Xiaomi central hub gateway or other devices having central hub gateway function, all control commands are sent through Xiaomi Cloud. The firmware for Xiaomi central hub gateway including the built-in central hub gateway supporting Home Assistant local control feature has not been released yet. Please refer to MIoT team's notification for upgrade plans.
Xiaomi central hub gateway is only available in mainland China. In other regions, it is not available. Xiaomi central hub gateway is only available in mainland China. In other regions, it is not available.
@ -293,7 +293,7 @@ The value of the event instance name indicates `_attr_device_class` of the Home
`spec_filter.yaml` is used to filter out the MIoT-Spec-V2 instance that will not be converted to Home Assistant entity. `spec_filter.yaml` is used to filter out the MIoT-Spec-V2 instance that will not be converted to Home Assistant entity.
The format of `spec_filter.json` is as follows. The format of `spec_filter.yaml` is as follows.
```yaml ```yaml
<MIoT-Spec-V2 device instance urn without the version field>: <MIoT-Spec-V2 device instance urn without the version field>:

View File

@ -75,6 +75,9 @@ from .miot.const import (
DEFAULT_CLOUD_SERVER, DEFAULT_CLOUD_SERVER,
DEFAULT_CTRL_MODE, DEFAULT_CTRL_MODE,
DEFAULT_INTEGRATION_LANGUAGE, DEFAULT_INTEGRATION_LANGUAGE,
DEFAULT_COVER_CLOSED_POSITION,
MIN_COVER_CLOSED_POSITION,
MAX_COVER_CLOSED_POSITION,
DEFAULT_NICK_NAME, DEFAULT_NICK_NAME,
DEFAULT_OAUTH2_API_HOST, DEFAULT_OAUTH2_API_HOST,
DOMAIN, DOMAIN,
@ -129,6 +132,7 @@ class XiaomiMihomeConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
_cloud_server: str _cloud_server: str
_integration_language: str _integration_language: str
_cover_closed_position: int
_auth_info: dict _auth_info: dict
_nick_name: str _nick_name: str
_home_selected: dict _home_selected: dict
@ -151,6 +155,7 @@ class XiaomiMihomeConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
self._main_loop = asyncio.get_running_loop() self._main_loop = asyncio.get_running_loop()
self._cloud_server = DEFAULT_CLOUD_SERVER self._cloud_server = DEFAULT_CLOUD_SERVER
self._integration_language = DEFAULT_INTEGRATION_LANGUAGE self._integration_language = DEFAULT_INTEGRATION_LANGUAGE
self._cover_closed_position = DEFAULT_COVER_CLOSED_POSITION
self._storage_path = '' self._storage_path = ''
self._virtual_did = '' self._virtual_did = ''
self._uid = '' self._uid = ''
@ -951,6 +956,7 @@ class XiaomiMihomeConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
'action_debug': self._action_debug, 'action_debug': self._action_debug,
'hide_non_standard_entities': 'hide_non_standard_entities':
self._hide_non_standard_entities, self._hide_non_standard_entities,
'cover_closed_position': self._cover_closed_position,
'display_binary_mode': self._display_binary_mode, 'display_binary_mode': self._display_binary_mode,
'display_devices_changed_notify': 'display_devices_changed_notify':
self._display_devices_changed_notify self._display_devices_changed_notify
@ -995,6 +1001,7 @@ class OptionsFlowHandler(config_entries.OptionsFlow):
_hide_non_standard_entities: bool _hide_non_standard_entities: bool
_display_binary_mode: list[str] _display_binary_mode: list[str]
_display_devs_notify: list[str] _display_devs_notify: list[str]
_cover_closed_position: int
_oauth_redirect_url_full: str _oauth_redirect_url_full: str
_auth_info: dict _auth_info: dict
@ -1015,6 +1022,7 @@ class OptionsFlowHandler(config_entries.OptionsFlow):
_opt_lan_ctrl_cfg: bool _opt_lan_ctrl_cfg: bool
_opt_network_detect_cfg: bool _opt_network_detect_cfg: bool
_opt_check_network_deps: bool _opt_check_network_deps: bool
_cover_pos_new: int
_trans_rules_count: int _trans_rules_count: int
_trans_rules_count_success: int _trans_rules_count_success: int
@ -1043,6 +1051,8 @@ class OptionsFlowHandler(config_entries.OptionsFlow):
self._ctrl_mode = self._entry_data.get('ctrl_mode', DEFAULT_CTRL_MODE) self._ctrl_mode = self._entry_data.get('ctrl_mode', DEFAULT_CTRL_MODE)
self._integration_language = self._entry_data.get( self._integration_language = self._entry_data.get(
'integration_language', DEFAULT_INTEGRATION_LANGUAGE) 'integration_language', DEFAULT_INTEGRATION_LANGUAGE)
self._cover_closed_position = self._entry_data.get(
'cover_closed_position', DEFAULT_COVER_CLOSED_POSITION)
self._nick_name = self._entry_data.get('nick_name', DEFAULT_NICK_NAME) self._nick_name = self._entry_data.get('nick_name', DEFAULT_NICK_NAME)
self._action_debug = self._entry_data.get('action_debug', False) self._action_debug = self._entry_data.get('action_debug', False)
self._hide_non_standard_entities = self._entry_data.get( self._hide_non_standard_entities = self._entry_data.get(
@ -1068,6 +1078,7 @@ class OptionsFlowHandler(config_entries.OptionsFlow):
self._action_debug_new = False self._action_debug_new = False
self._hide_non_standard_entities_new = False self._hide_non_standard_entities_new = False
self._display_binary_mode_new = [] self._display_binary_mode_new = []
self._cover_pos_new = self._cover_closed_position
self._update_user_info = False self._update_user_info = False
self._update_devices = False self._update_devices = False
self._update_trans_rules = False self._update_trans_rules = False
@ -1340,6 +1351,12 @@ class OptionsFlowHandler(config_entries.OptionsFlow):
): cv.multi_select( ): cv.multi_select(
self._miot_i18n.translate( self._miot_i18n.translate(
'config.binary_mode')), # type: ignore 'config.binary_mode')), # type: ignore
vol.Optional(
'cover_closed_position',
default=self._cover_closed_position # type: ignore
): vol.All(vol.Coerce(int), vol.Range(
min=MIN_COVER_CLOSED_POSITION,
max=MAX_COVER_CLOSED_POSITION)),
vol.Required( vol.Required(
'update_trans_rules', 'update_trans_rules',
default=self._update_trans_rules # type: ignore default=self._update_trans_rules # type: ignore
@ -1378,6 +1395,8 @@ class OptionsFlowHandler(config_entries.OptionsFlow):
'update_lan_ctrl_config', self._opt_lan_ctrl_cfg) 'update_lan_ctrl_config', self._opt_lan_ctrl_cfg)
self._opt_network_detect_cfg = user_input.get( self._opt_network_detect_cfg = user_input.get(
'network_detect_config', self._opt_network_detect_cfg) 'network_detect_config', self._opt_network_detect_cfg)
self._cover_pos_new = user_input.get(
'cover_closed_position', self._cover_closed_position)
return await self.async_step_update_user_info() return await self.async_step_update_user_info()
@ -1926,6 +1945,7 @@ class OptionsFlowHandler(config_entries.OptionsFlow):
'nick_name': self._nick_name, 'nick_name': self._nick_name,
'lang_new': INTEGRATION_LANGUAGES[self._lang_new], 'lang_new': INTEGRATION_LANGUAGES[self._lang_new],
'nick_name_new': self._nick_name_new, 'nick_name_new': self._nick_name_new,
'cover_pos_new': self._cover_pos_new,
'devices_add': len(self._devices_add), 'devices_add': len(self._devices_add),
'devices_remove': len(self._devices_remove), 'devices_remove': len(self._devices_remove),
'trans_rules_count': self._trans_rules_count, 'trans_rules_count': self._trans_rules_count,
@ -1952,6 +1972,9 @@ class OptionsFlowHandler(config_entries.OptionsFlow):
if self._lang_new != self._integration_language: if self._lang_new != self._integration_language:
self._entry_data['integration_language'] = self._lang_new self._entry_data['integration_language'] = self._lang_new
self._need_reload = True self._need_reload = True
if self._cover_pos_new != self._cover_closed_position:
self._entry_data['cover_closed_position'] = self._cover_pos_new
self._need_reload = True
if self._update_user_info: if self._update_user_info:
self._entry_data['nick_name'] = self._nick_name_new self._entry_data['nick_name'] = self._nick_name_new
if self._update_devices: if self._update_devices:

View File

@ -91,6 +91,7 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry,
class Cover(MIoTServiceEntity, CoverEntity): class Cover(MIoTServiceEntity, CoverEntity):
"""Cover entities for Xiaomi Home.""" """Cover entities for Xiaomi Home."""
# pylint: disable=unused-argument # pylint: disable=unused-argument
_cover_closed_position: int
_prop_motor_control: Optional[MIoTSpecProperty] _prop_motor_control: Optional[MIoTSpecProperty]
_prop_motor_value_open: Optional[int] _prop_motor_value_open: Optional[int]
_prop_motor_value_close: Optional[int] _prop_motor_value_close: Optional[int]
@ -115,6 +116,9 @@ class Cover(MIoTServiceEntity, CoverEntity):
self._attr_supported_color_modes = set() self._attr_supported_color_modes = set()
self._attr_supported_features = CoverEntityFeature(0) self._attr_supported_features = CoverEntityFeature(0)
self._cover_closed_position = (
miot_device.miot_client.cover_closed_position)
self._prop_motor_control = None self._prop_motor_control = None
self._prop_motor_value_open = None self._prop_motor_value_open = None
self._prop_motor_value_close = None self._prop_motor_value_close = None
@ -166,12 +170,13 @@ class Cover(MIoTServiceEntity, CoverEntity):
self._prop_status_opening.append(item.value) self._prop_status_opening.append(item.value)
elif item_name in { elif item_name in {
'closing', 'close', 'down', 'dowm', 'falling', 'closing', 'close', 'down', 'dowm', 'falling',
'dropping', 'downing', 'lower' 'fallin', 'dropping', 'downing', 'lower'
}: }:
self._prop_status_closing.append(item.value) self._prop_status_closing.append(item.value)
elif item_name in { elif item_name in {
'stopatlowest', 'stoplowerlimit', 'lowerlimitstop', 'closed', 'closeover', 'stopatlowest',
'floor', 'lowerlimit' 'stoplowerlimit', 'lowerlimitstop', 'floor',
'lowerlimit'
}: }:
self._prop_status_closed.append(item.value) self._prop_status_closed.append(item.value)
self._prop_status = prop self._prop_status = prop
@ -297,7 +302,7 @@ class Cover(MIoTServiceEntity, CoverEntity):
def is_closed(self) -> Optional[bool]: def is_closed(self) -> Optional[bool]:
"""Return if the cover is closed.""" """Return if the cover is closed."""
if self.current_cover_position is not None: if self.current_cover_position is not None:
return self.current_cover_position == 0 return self.current_cover_position <= self._cover_closed_position
# The current position is prior to the status when determining # The current position is prior to the status when determining
# whether the cover is closed. # whether the cover is closed.
if self._prop_status and self._prop_status_closed: if self._prop_status and self._prop_status_closed:

View File

@ -45,13 +45,15 @@ off Xiaomi or its affiliates' products.
Light entities for Xiaomi Home. Light entities for Xiaomi Home.
""" """
from __future__ import annotations from __future__ import annotations
import logging import logging
from typing import Any, Optional from typing import Any, Optional, List, Dict
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.entity_registry import async_get as async_get_entity_registry
from homeassistant.components.light import ( from homeassistant.components.light import (
ATTR_BRIGHTNESS, ATTR_BRIGHTNESS,
ATTR_COLOR_TEMP_KELVIN, ATTR_COLOR_TEMP_KELVIN,
@ -59,34 +61,31 @@ from homeassistant.components.light import (
ATTR_EFFECT, ATTR_EFFECT,
LightEntity, LightEntity,
LightEntityFeature, LightEntityFeature,
ColorMode ColorMode,
)
from homeassistant.util.color import (
value_to_brightness,
brightness_to_value
) )
from homeassistant.util.color import value_to_brightness, brightness_to_value
from .miot.miot_spec import MIoTSpecProperty from .miot.miot_spec import MIoTSpecProperty
from .miot.miot_device import MIoTDevice, MIoTEntityData, MIoTServiceEntity from .miot.miot_device import MIoTDevice, MIoTEntityData, MIoTServiceEntity
from .miot.const import DOMAIN from .miot.const import DOMAIN
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
async def async_setup_entry( async def async_setup_entry(
hass: HomeAssistant, hass: HomeAssistant,
config_entry: ConfigEntry, config_entry: ConfigEntry,
async_add_entities: AddEntitiesCallback, async_add_entities: AddEntitiesCallback,
) -> None: ) -> None:
"""Set up a config entry.""" """Set up a config entry."""
device_list: list[MIoTDevice] = hass.data[DOMAIN]['devices'][ device_list: list[MIoTDevice] = hass.data[DOMAIN]["devices"][
config_entry.entry_id] config_entry.entry_id]
new_entities = [] new_entities = []
for miot_device in device_list: for miot_device in device_list:
for data in miot_device.entity_list.get('light', []): for data in miot_device.entity_list.get("light", []):
new_entities.append( new_entities.append(
Light(miot_device=miot_device, entity_data=data)) Light(miot_device=miot_device, entity_data=data, hass=hass))
if new_entities: if new_entities:
async_add_entities(new_entities) async_add_entities(new_entities)
@ -94,6 +93,7 @@ async def async_setup_entry(
class Light(MIoTServiceEntity, LightEntity): class Light(MIoTServiceEntity, LightEntity):
"""Light entities for Xiaomi Home.""" """Light entities for Xiaomi Home."""
# pylint: disable=unused-argument # pylint: disable=unused-argument
_VALUE_RANGE_MODE_COUNT_MAX = 30 _VALUE_RANGE_MODE_COUNT_MAX = 30
_prop_on: Optional[MIoTSpecProperty] _prop_on: Optional[MIoTSpecProperty]
@ -105,16 +105,17 @@ class Light(MIoTServiceEntity, LightEntity):
_brightness_scale: Optional[tuple[int, int]] _brightness_scale: Optional[tuple[int, int]]
_mode_map: Optional[dict[Any, Any]] _mode_map: Optional[dict[Any, Any]]
def __init__( def __init__(self, miot_device: MIoTDevice, entity_data: MIoTEntityData,
self, miot_device: MIoTDevice, entity_data: MIoTEntityData hass: HomeAssistant) -> None:
) -> None:
"""Initialize the Light.""" """Initialize the Light."""
super().__init__(miot_device=miot_device, entity_data=entity_data) super().__init__(miot_device=miot_device, entity_data=entity_data)
self.hass = hass
self._attr_color_mode = None self._attr_color_mode = None
self._attr_supported_color_modes = set() self._attr_supported_color_modes = set()
self._attr_supported_features = LightEntityFeature(0) self._attr_supported_features = LightEntityFeature(0)
if miot_device.did.startswith('group.'): self.miot_device = miot_device
self._attr_icon = 'mdi:lightbulb-group' if miot_device.did.startswith("group."):
self._attr_icon = "mdi:lightbulb-group"
self._prop_on = None self._prop_on = None
self._prop_brightness = None self._prop_brightness = None
@ -123,37 +124,38 @@ class Light(MIoTServiceEntity, LightEntity):
self._prop_mode = None self._prop_mode = None
self._brightness_scale = None self._brightness_scale = None
self._mode_map = None self._mode_map = None
self._command_send_mode_entity_id = None
# properties # properties
for prop in entity_data.props: for prop in entity_data.props:
# on # on
if prop.name == 'on': if prop.name == "on":
self._prop_on = prop self._prop_on = prop
# brightness # brightness
if prop.name == 'brightness': if prop.name == "brightness":
if prop.value_range: if prop.value_range:
self._brightness_scale = ( self._brightness_scale = (
prop.value_range.min_, prop.value_range.max_) prop.value_range.min_,
prop.value_range.max_,
)
self._prop_brightness = prop self._prop_brightness = prop
elif ( elif self._mode_map is None and prop.value_list:
self._mode_map is None
and prop.value_list
):
# For value-list brightness # For value-list brightness
self._mode_map = prop.value_list.to_map() self._mode_map = prop.value_list.to_map()
self._attr_effect_list = list(self._mode_map.values()) self._attr_effect_list = list(self._mode_map.values())
self._attr_supported_features |= LightEntityFeature.EFFECT self._attr_supported_features |= LightEntityFeature.EFFECT
self._prop_mode = prop self._prop_mode = prop
else: else:
_LOGGER.info( _LOGGER.info("invalid brightness format, %s",
'invalid brightness format, %s', self.entity_id) self.entity_id)
continue continue
# color-temperature # color-temperature
if prop.name == 'color-temperature': if prop.name == "color-temperature":
if not prop.value_range: if not prop.value_range:
_LOGGER.info( _LOGGER.info(
'invalid color-temperature value_range format, %s', "invalid color-temperature value_range format, %s",
self.entity_id) self.entity_id,
)
continue continue
self._attr_min_color_temp_kelvin = prop.value_range.min_ self._attr_min_color_temp_kelvin = prop.value_range.min_
self._attr_max_color_temp_kelvin = prop.value_range.max_ self._attr_max_color_temp_kelvin = prop.value_range.max_
@ -161,40 +163,40 @@ class Light(MIoTServiceEntity, LightEntity):
self._attr_color_mode = ColorMode.COLOR_TEMP self._attr_color_mode = ColorMode.COLOR_TEMP
self._prop_color_temp = prop self._prop_color_temp = prop
# color # color
if prop.name == 'color': if prop.name == "color":
self._attr_supported_color_modes.add(ColorMode.RGB) self._attr_supported_color_modes.add(ColorMode.RGB)
self._attr_color_mode = ColorMode.RGB self._attr_color_mode = ColorMode.RGB
self._prop_color = prop self._prop_color = prop
# mode # mode
if prop.name == 'mode': if prop.name == "mode":
mode_list = None mode_list = None
if prop.value_list: if prop.value_list:
mode_list = prop.value_list.to_map() mode_list = prop.value_list.to_map()
elif prop.value_range: elif prop.value_range:
mode_list = {} mode_list = {}
if ( if (int((prop.value_range.max_ - prop.value_range.min_) /
int(( prop.value_range.step)
prop.value_range.max_ > self._VALUE_RANGE_MODE_COUNT_MAX):
- prop.value_range.min_
) / prop.value_range.step)
> self._VALUE_RANGE_MODE_COUNT_MAX
):
_LOGGER.error( _LOGGER.error(
'too many mode values, %s, %s, %s', "too many mode values, %s, %s, %s",
self.entity_id, prop.name, prop.value_range) self.entity_id,
prop.name,
prop.value_range,
)
else: else:
for value in range( for value in range(
prop.value_range.min_, prop.value_range.min_,
prop.value_range.max_, prop.value_range.max_,
prop.value_range.step): prop.value_range.step,
mode_list[value] = f'mode {value}' ):
mode_list[value] = f"mode {value}"
if mode_list: if mode_list:
self._mode_map = mode_list self._mode_map = mode_list
self._attr_effect_list = list(self._mode_map.values()) self._attr_effect_list = list(self._mode_map.values())
self._attr_supported_features |= LightEntityFeature.EFFECT self._attr_supported_features |= LightEntityFeature.EFFECT
self._prop_mode = prop self._prop_mode = prop
else: else:
_LOGGER.info('invalid mode format, %s', self.entity_id) _LOGGER.info("invalid mode format, %s", self.entity_id)
continue continue
if not self._attr_supported_color_modes: if not self._attr_supported_color_modes:
@ -241,9 +243,8 @@ class Light(MIoTServiceEntity, LightEntity):
@property @property
def effect(self) -> Optional[str]: def effect(self) -> Optional[str]:
"""Return the current mode.""" """Return the current mode."""
return self.get_map_value( return self.get_map_value(map_=self._mode_map,
map_=self._mode_map, key=self.get_prop_value(prop=self._prop_mode))
key=self.get_prop_value(prop=self._prop_mode))
async def async_turn_on(self, **kwargs) -> None: async def async_turn_on(self, **kwargs) -> None:
"""Turn the light on. """Turn the light on.
@ -252,42 +253,176 @@ class Light(MIoTServiceEntity, LightEntity):
""" """
# on # on
# Dirty logic for lumi.gateway.mgl03 indicator light # Dirty logic for lumi.gateway.mgl03 indicator light
if self._prop_on: # Determine whether the device sends the light-on properties in batches or one by one
value_on = True if self._prop_on.format_ == bool else 1 # Search entityid through unique_id to avoid the user modifying entityid and causing command_send_mode to not match
await self.set_property_async( if self._command_send_mode_entity_id is None:
prop=self._prop_on, value=value_on) entity_registry = async_get_entity_registry(self.hass)
# brightness device_id = list(
self.miot_device.device_info.get("identifiers"))[0][1]
self._command_send_mode_entity_id = entity_registry.async_get_entity_id(
"select", DOMAIN, f"select.light_{device_id}_command_send_mode")
if self._command_send_mode_entity_id is None:
_LOGGER.error(
"light command_send_mode not found, %s",
self.entity_id,
)
return
command_send_mode = self.hass.states.get(
self._command_send_mode_entity_id)
send_brightness_first = False
if ATTR_BRIGHTNESS in kwargs: if ATTR_BRIGHTNESS in kwargs:
brightness = brightness_to_value( brightness_new = kwargs[ATTR_BRIGHTNESS]
self._brightness_scale, kwargs[ATTR_BRIGHTNESS]) brightness_old = self.brightness
await self.set_property_async( if brightness_old and brightness_new <= brightness_old:
prop=self._prop_brightness, value=brightness, send_brightness_first = True
write_ha_state=False) if command_send_mode and command_send_mode.state == "Send Together":
# color-temperature set_properties_list: List[Dict[str, Any]] = []
if ATTR_COLOR_TEMP_KELVIN in kwargs: # mode
await self.set_property_async( if ATTR_EFFECT in kwargs:
prop=self._prop_color_temp, set_properties_list.append({
value=kwargs[ATTR_COLOR_TEMP_KELVIN], "prop":
write_ha_state=False) self._prop_mode,
self._attr_color_mode = ColorMode.COLOR_TEMP "value":
# rgb color self.get_map_key(map_=self._mode_map,
if ATTR_RGB_COLOR in kwargs: value=kwargs[ATTR_EFFECT]),
r = kwargs[ATTR_RGB_COLOR][0] })
g = kwargs[ATTR_RGB_COLOR][1] # brightness
b = kwargs[ATTR_RGB_COLOR][2] if send_brightness_first and ATTR_BRIGHTNESS in kwargs:
rgb = (r << 16) | (g << 8) | b brightness = brightness_to_value(self._brightness_scale,
await self.set_property_async( kwargs[ATTR_BRIGHTNESS])
prop=self._prop_color, value=rgb, set_properties_list.append({
write_ha_state=False) "prop": self._prop_brightness,
self._attr_color_mode = ColorMode.RGB "value": brightness
# mode })
if ATTR_EFFECT in kwargs: # color-temperature
await self.set_property_async( if ATTR_COLOR_TEMP_KELVIN in kwargs:
prop=self._prop_mode, set_properties_list.append({
value=self.get_map_key( "prop": self._prop_color_temp,
map_=self._mode_map, value=kwargs[ATTR_EFFECT]), "value": kwargs[ATTR_COLOR_TEMP_KELVIN],
write_ha_state=False) })
self.async_write_ha_state() self._attr_color_mode = ColorMode.COLOR_TEMP
# rgb color
if ATTR_RGB_COLOR in kwargs:
r = kwargs[ATTR_RGB_COLOR][0]
g = kwargs[ATTR_RGB_COLOR][1]
b = kwargs[ATTR_RGB_COLOR][2]
rgb = (r << 16) | (g << 8) | b
set_properties_list.append({
"prop": self._prop_color,
"value": rgb
})
self._attr_color_mode = ColorMode.RGB
# brightness
if not send_brightness_first and ATTR_BRIGHTNESS in kwargs:
brightness = brightness_to_value(self._brightness_scale,
kwargs[ATTR_BRIGHTNESS])
set_properties_list.append({
"prop": self._prop_brightness,
"value": brightness
})
if self._prop_on:
value_on = True if self._prop_on.format_ == bool else 1 # noqa: E721
set_properties_list.append({
"prop": self._prop_on,
"value": value_on
})
await self.set_properties_async(set_properties_list)
self.async_write_ha_state()
elif command_send_mode and command_send_mode.state == "Send Turn On First":
set_properties_list: List[Dict[str, Any]] = []
if self._prop_on:
value_on = True if self._prop_on.format_ == bool else 1 # noqa: E721
set_properties_list.append({
"prop": self._prop_on,
"value": value_on
})
# mode
if ATTR_EFFECT in kwargs:
set_properties_list.append({
"prop":
self._prop_mode,
"value":
self.get_map_key(map_=self._mode_map,
value=kwargs[ATTR_EFFECT]),
})
# brightness
if send_brightness_first and ATTR_BRIGHTNESS in kwargs:
brightness = brightness_to_value(self._brightness_scale,
kwargs[ATTR_BRIGHTNESS])
set_properties_list.append({
"prop": self._prop_brightness,
"value": brightness
})
# color-temperature
if ATTR_COLOR_TEMP_KELVIN in kwargs:
set_properties_list.append({
"prop": self._prop_color_temp,
"value": kwargs[ATTR_COLOR_TEMP_KELVIN],
})
self._attr_color_mode = ColorMode.COLOR_TEMP
# rgb color
if ATTR_RGB_COLOR in kwargs:
r = kwargs[ATTR_RGB_COLOR][0]
g = kwargs[ATTR_RGB_COLOR][1]
b = kwargs[ATTR_RGB_COLOR][2]
rgb = (r << 16) | (g << 8) | b
set_properties_list.append({
"prop": self._prop_color,
"value": rgb
})
self._attr_color_mode = ColorMode.RGB
# brightness
if not send_brightness_first and ATTR_BRIGHTNESS in kwargs:
brightness = brightness_to_value(self._brightness_scale,
kwargs[ATTR_BRIGHTNESS])
set_properties_list.append({
"prop": self._prop_brightness,
"value": brightness
})
await self.set_properties_async(set_properties_list)
self.async_write_ha_state()
else:
if self._prop_on:
value_on = True if self._prop_on.format_ == bool else 1 # noqa: E721
await self.set_property_async(prop=self._prop_on,
value=value_on)
# color-temperature
if ATTR_COLOR_TEMP_KELVIN in kwargs:
await self.set_property_async(
prop=self._prop_color_temp,
value=kwargs[ATTR_COLOR_TEMP_KELVIN],
write_ha_state=False,
)
self._attr_color_mode = ColorMode.COLOR_TEMP
# rgb color
if ATTR_RGB_COLOR in kwargs:
r = kwargs[ATTR_RGB_COLOR][0]
g = kwargs[ATTR_RGB_COLOR][1]
b = kwargs[ATTR_RGB_COLOR][2]
rgb = (r << 16) | (g << 8) | b
await self.set_property_async(prop=self._prop_color,
value=rgb,
write_ha_state=False)
self._attr_color_mode = ColorMode.RGB
# brightness
if ATTR_BRIGHTNESS in kwargs:
brightness = brightness_to_value(self._brightness_scale,
kwargs[ATTR_BRIGHTNESS])
await self.set_property_async(prop=self._prop_brightness,
value=brightness,
write_ha_state=False)
# mode
if ATTR_EFFECT in kwargs:
await self.set_property_async(
prop=self._prop_mode,
value=self.get_map_key(map_=self._mode_map,
value=kwargs[ATTR_EFFECT]),
write_ha_state=False,
)
self.async_write_ha_state()
async def async_turn_off(self, **kwargs) -> None: async def async_turn_off(self, **kwargs) -> None:
"""Turn the light off.""" """Turn the light off."""

View File

@ -25,7 +25,7 @@
"cryptography", "cryptography",
"psutil" "psutil"
], ],
"version": "v0.3.4", "version": "v0.4.0",
"zeroconf": [ "zeroconf": [
"_miot-central._tcp.local." "_miot-central._tcp.local."
] ]

View File

@ -120,6 +120,10 @@ INTEGRATION_LANGUAGES = {
'zh-Hant': '繁體中文' 'zh-Hant': '繁體中文'
} }
DEFAULT_COVER_CLOSED_POSITION: int = 0
MIN_COVER_CLOSED_POSITION: int = 0
MAX_COVER_CLOSED_POSITION: int = 5
DEFAULT_CTRL_MODE: str = 'auto' DEFAULT_CTRL_MODE: str = 'auto'
# Registered in Xiaomi OAuth 2.0 Service # Registered in Xiaomi OAuth 2.0 Service

View File

@ -99,6 +99,10 @@
"device_list_offline": "\n**{count} Geräte offline:** \n{message}", "device_list_offline": "\n**{count} Geräte offline:** \n{message}",
"network_status_online": "Online", "network_status_online": "Online",
"network_status_offline": "Offline", "network_status_offline": "Offline",
"central_state_changed_title": "Verbindungsstatus des Zentral-Gateways",
"central_state_changed": "**{nick_name}({uid}, {cloud_server})** Lokale Verbindungsstrecke des Zentral-Gateways: {conn_status}",
"central_state_connected": "verbunden",
"central_state_disconnected": "getrennt",
"device_exec_error": "Fehler bei der Ausführung" "device_exec_error": "Fehler bei der Ausführung"
} }
}, },

View File

@ -99,6 +99,10 @@
"device_list_offline": "\n**{count} devices offline:** \n{message}", "device_list_offline": "\n**{count} devices offline:** \n{message}",
"network_status_online": "Online", "network_status_online": "Online",
"network_status_offline": "Offline", "network_status_offline": "Offline",
"central_state_changed_title": "Central Hub Gateway Connection Status",
"central_state_changed":"**{nick_name}({uid}, {cloud_server})** local connection to Xiaomi central hub gateway: {conn_status}",
"central_state_connected": "Connected",
"central_state_disconnected": "Disconnected",
"device_exec_error": "Execution error" "device_exec_error": "Execution error"
} }
}, },

View File

@ -99,6 +99,10 @@
"device_list_offline": "\n**{count} dispositivos sin conexión:** \n{message}", "device_list_offline": "\n**{count} dispositivos sin conexión:** \n{message}",
"network_status_online": "En línea", "network_status_online": "En línea",
"network_status_offline": "Desconectado", "network_status_offline": "Desconectado",
"central_state_changed_title": "Estado de conexión de la puerta de enlace central",
"central_state_changed": "**{nick_name}({uid}, {cloud_server})** enlace de conexión local de la puerta de enlace central: {conn_status}",
"central_state_connected": "conectado",
"central_state_disconnected": "desconectado",
"device_exec_error": "Error de ejecución" "device_exec_error": "Error de ejecución"
} }
}, },

View File

@ -99,6 +99,10 @@
"device_list_offline": "\n**{count} appareils hors ligne :** \n{message}", "device_list_offline": "\n**{count} appareils hors ligne :** \n{message}",
"network_status_online": "En ligne", "network_status_online": "En ligne",
"network_status_offline": "Hors ligne", "network_status_offline": "Hors ligne",
"central_state_changed_title": "État de connexion de la passerelle centrale",
"central_state_changed": "**{nick_name}({uid}, {cloud_server})** liaison de connexion locale de la passerelle centrale : {conn_status}",
"central_state_connected": "connecté",
"central_state_disconnected": "déconnecté",
"device_exec_error": "Erreur d'exécution" "device_exec_error": "Erreur d'exécution"
} }
}, },

View File

@ -99,6 +99,10 @@
"device_list_offline": "\n**{count} dispositivi offline:** \n{message}", "device_list_offline": "\n**{count} dispositivi offline:** \n{message}",
"network_status_online": "Online", "network_status_online": "Online",
"network_status_offline": "Offline", "network_status_offline": "Offline",
"central_state_changed_title": "Stato di connessione del gateway centrale",
"central_state_changed": "**{nick_name}({uid}, {cloud_server})** collegamento locale del gateway centrale: {conn_status}",
"central_state_connected": "connesso",
"central_state_disconnected": "disconnesso",
"device_exec_error": "Errore di esecuzione" "device_exec_error": "Errore di esecuzione"
} }
}, },

View File

@ -99,6 +99,10 @@
"device_list_offline": "\n**{count} デバイスがオフライン:** \n{message}", "device_list_offline": "\n**{count} デバイスがオフライン:** \n{message}",
"network_status_online": "オンライン", "network_status_online": "オンライン",
"network_status_offline": "オフライン", "network_status_offline": "オフライン",
"central_state_changed_title": "中枢ゲートウェイ接続ステータス",
"central_state_changed": "**{nick_name}({uid}, {cloud_server})** 中枢ゲートウェイのローカル接続リンク: {conn_status}",
"central_state_connected": "接続済み",
"central_state_disconnected": "切断されました",
"device_exec_error": "実行エラー" "device_exec_error": "実行エラー"
} }
}, },

View File

@ -99,6 +99,10 @@
"device_list_offline": "\n**{count} apparaten offline:** \n{message}", "device_list_offline": "\n**{count} apparaten offline:** \n{message}",
"network_status_online": "Online", "network_status_online": "Online",
"network_status_offline": "Offline", "network_status_offline": "Offline",
"central_state_changed_title": "Verbindingsstatus van centrale gateway",
"central_state_changed": "**{nick_name}({uid}, {cloud_server})** Lokale verbinding van centrale gateway: {conn_status}",
"central_state_connected": "verbonden",
"central_state_disconnected": "verbinding verbroken",
"device_exec_error": "Uitvoeringsfout" "device_exec_error": "Uitvoeringsfout"
} }
}, },

View File

@ -99,6 +99,10 @@
"device_list_offline": "\n**{count} dispositivos offline**: \n{message}", "device_list_offline": "\n**{count} dispositivos offline**: \n{message}",
"network_status_online": "online", "network_status_online": "online",
"network_status_offline": "offline", "network_status_offline": "offline",
"central_state_changed_title": "Status de conexão do gateway central",
"central_state_changed": "**{nick_name}({uid}, {cloud_server})** conexão local do gateway central: {conn_status}",
"central_state_connected": "conectado",
"central_state_disconnected": "desconectado",
"device_exec_error": "Erro na execução" "device_exec_error": "Erro na execução"
} }
}, },

View File

@ -99,6 +99,10 @@
"device_list_offline": "\n**{count} dispositivos offline**: \n{message}", "device_list_offline": "\n**{count} dispositivos offline**: \n{message}",
"network_status_online": "Online", "network_status_online": "Online",
"network_status_offline": "Offline", "network_status_offline": "Offline",
"central_state_changed_title": "Estado da ligação do gateway central",
"central_state_changed": "**{nick_name}({uid}, {cloud_server})** ligação local do gateway central: {conn_status}",
"central_state_connected": "ligado",
"central_state_disconnected": "desligado",
"device_exec_error": "Erro de execução" "device_exec_error": "Erro de execução"
} }
}, },

View File

@ -99,6 +99,10 @@
"device_list_offline": "\n**{count} устройств недоступно:** \n{message}", "device_list_offline": "\n**{count} устройств недоступно:** \n{message}",
"network_status_online": "В сети", "network_status_online": "В сети",
"network_status_offline": "Не в сети", "network_status_offline": "Не в сети",
"central_state_changed_title": "Статус подключения центрального шлюза",
"central_state_changed": "**{nick_name}({uid}, {cloud_server})** локальное подключение центрального шлюза: {conn_status}",
"central_state_connected": "подключено",
"central_state_disconnected": "разъединено",
"device_exec_error": "Ошибка выполнения" "device_exec_error": "Ошибка выполнения"
} }
}, },

View File

@ -99,6 +99,10 @@
"device_list_offline": "\n**{count} 个设备离线**: \n{message}", "device_list_offline": "\n**{count} 个设备离线**: \n{message}",
"network_status_online": "在线", "network_status_online": "在线",
"network_status_offline": "离线", "network_status_offline": "离线",
"central_state_changed_title": "中枢网关连接状态",
"central_state_changed":"**{nick_name}({uid}, {cloud_server})** 中枢网关本地连接链路: {conn_status}",
"central_state_connected": "已连接",
"central_state_disconnected": "断连",
"device_exec_error": "执行错误" "device_exec_error": "执行错误"
} }
}, },

View File

@ -99,6 +99,10 @@
"device_list_offline": "\n**{count} 個設備離線:** \n{message}", "device_list_offline": "\n**{count} 個設備離線:** \n{message}",
"network_status_online": "在線", "network_status_online": "在線",
"network_status_offline": "離線", "network_status_offline": "離線",
"central_state_changed_title": "中枢網關連接狀態",
"central_state_changed":"**{nick_name}({uid}, {cloud_server})** 中枢網關本地連接鏈路: {conn_status}",
"central_state_connected": "已連接",
"central_state_disconnected": "断連",
"device_exec_error": "執行錯誤" "device_exec_error": "執行錯誤"
} }
}, },

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -110,7 +110,6 @@ class MipsServiceData:
version=IPVersion.V4Only) version=IPVersion.V4Only)
if not self.addresses: if not self.addresses:
raise MipsServiceError('invalid addresses') raise MipsServiceError('invalid addresses')
self.addresses.sort()
if not service_info.port: if not service_info.port:
raise MipsServiceError('invalid port') raise MipsServiceError('invalid port')
self.port = service_info.port self.port = service_info.port
@ -226,7 +225,7 @@ class MipsService:
state_change: ServiceStateChange state_change: ServiceStateChange
) -> None: ) -> None:
_LOGGER.debug( _LOGGER.debug(
'mips service state changed, %s, %s, %s', 'mdns discovery changed, %s, %s, %s',
state_change, name, service_type) state_change, name, service_type)
if state_change is ServiceStateChange.Removed: if state_change is ServiceStateChange.Removed:

File diff suppressed because it is too large Load Diff

View File

@ -203,6 +203,26 @@
] ]
} }
], ],
"urn:miot-spec-v2:device:water-heater:0000A02A:viomi-m1:2": [
{
"iid": 2,
"type": "urn:miot-spec-v2:service:switch:0000780C:viomi-m1:1",
"description": "Water Heater",
"properties": [
{
"iid": 6,
"type": "urn:miot-spec-v2:property:on:00000006:viomi-m1:1",
"description": "Switch Status",
"format": "bool",
"access": [
"read",
"write",
"notify"
]
}
]
}
],
"urn:miot-spec-v2:device:water-heater:0000A02A:xiaomi-yms2:1": [ "urn:miot-spec-v2:device:water-heater:0000A02A:xiaomi-yms2:1": [
{ {
"iid": 2, "iid": 2,

View File

@ -6,6 +6,8 @@ urn:miot-spec-v2:device:air-conditioner:0000A004:xiaomi-c20:1:
unit: none unit: none
urn:miot-spec-v2:device:air-conditioner:0000A004:xiaomi-c20:2: urn:miot-spec-v2:device:air-conditioner:0000A004:xiaomi-c20:1 urn:miot-spec-v2:device:air-conditioner:0000A004:xiaomi-c20:2: urn:miot-spec-v2:device:air-conditioner:0000A004:xiaomi-c20:1
urn:miot-spec-v2:device:air-conditioner:0000A004:xiaomi-c24:1: urn:miot-spec-v2:device:air-conditioner:0000A004:xiaomi-c24:1:
prop.8.6:
unit: kWh
prop.10.6: prop.10.6:
unit: none unit: none
urn:miot-spec-v2:device:air-conditioner:0000A004:xiaomi-c24:2: urn:miot-spec-v2:device:air-conditioner:0000A004:xiaomi-c24:1 urn:miot-spec-v2:device:air-conditioner:0000A004:xiaomi-c24:2: urn:miot-spec-v2:device:air-conditioner:0000A004:xiaomi-c24:1
@ -26,6 +28,12 @@ urn:miot-spec-v2:device:air-conditioner:0000A004:xiaomi-mt0:1:
prop.10.6: prop.10.6:
unit: none unit: none
urn:miot-spec-v2:device:air-conditioner:0000A004:xiaomi-mt0:2: urn:miot-spec-v2:device:air-conditioner:0000A004:xiaomi-mt0:1 urn:miot-spec-v2:device:air-conditioner:0000A004:xiaomi-mt0:2: urn:miot-spec-v2:device:air-conditioner:0000A004:xiaomi-mt0:1
urn:miot-spec-v2:device:air-monitor:0000A008:cgllc-cgd1st:1:
prop.3.7:
value-range:
- -30
- 100
- 0.1
urn:miot-spec-v2:device:air-monitor:0000A008:cgllc-s1:1: urn:miot-spec-v2:device:air-monitor:0000A008:cgllc-s1:1:
prop.2.5: prop.2.5:
name: voc-density name: voc-density
@ -153,6 +161,9 @@ urn:miot-spec-v2:device:light:0000A001:shhf-sfla10:1:
urn:miot-spec-v2:device:light:0000A001:shhf-sfla12:1: urn:miot-spec-v2:device:light:0000A001:shhf-sfla12:1:
prop.8.11: prop.8.11:
name: on-a name: on-a
urn:miot-spec-v2:device:light:0000A001:shhf-sflt11:1:0000C802:
prop.11.14:
name: on-power
urn:miot-spec-v2:device:magnet-sensor:0000A016:linp-m1:1: urn:miot-spec-v2:device:magnet-sensor:0000A016:linp-m1:1:
prop.2.1004: prop.2.1004:
name: contact-state name: contact-state
@ -168,6 +179,9 @@ urn:miot-spec-v2:device:motion-sensor:0000A014:lumi-acn001:1:
- read - read
- notify - notify
unit: mV unit: mV
urn:miot-spec-v2:device:motor-controller:0000A01D:adp-adswb4:1:0000C837:
prop.2.1:
name: motor-switch
urn:miot-spec-v2:device:occupancy-sensor:0000A0BF:ainice-3b:1: urn:miot-spec-v2:device:occupancy-sensor:0000A0BF:ainice-3b:2 urn:miot-spec-v2:device:occupancy-sensor:0000A0BF:ainice-3b:1: urn:miot-spec-v2:device:occupancy-sensor:0000A0BF:ainice-3b:2
urn:miot-spec-v2:device:occupancy-sensor:0000A0BF:ainice-3b:2: urn:miot-spec-v2:device:occupancy-sensor:0000A0BF:ainice-3b:2:
prop.2.8: prop.2.8:

View File

@ -45,18 +45,24 @@ off Xiaomi or its affiliates' products.
Select entities for Xiaomi Home. Select entities for Xiaomi Home.
""" """
from __future__ import annotations from __future__ import annotations
import logging
from typing import Optional from typing import Optional
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.components.select import SelectEntity from homeassistant.components.select import SelectEntity
from homeassistant.helpers.entity import EntityCategory
from homeassistant.helpers.restore_state import RestoreEntity
from .miot.const import DOMAIN from .miot.const import DOMAIN
from .miot.miot_device import MIoTDevice, MIoTPropertyEntity from .miot.miot_device import MIoTDevice, MIoTPropertyEntity
from .miot.miot_spec import MIoTSpecProperty from .miot.miot_spec import MIoTSpecProperty
_LOGGER = logging.getLogger(__name__)
async def async_setup_entry( async def async_setup_entry(
hass: HomeAssistant, hass: HomeAssistant,
@ -64,17 +70,30 @@ async def async_setup_entry(
async_add_entities: AddEntitiesCallback, async_add_entities: AddEntitiesCallback,
) -> None: ) -> None:
"""Set up a config entry.""" """Set up a config entry."""
device_list: list[MIoTDevice] = hass.data[DOMAIN]['devices'][ device_list: list[MIoTDevice] = hass.data[DOMAIN]["devices"][
config_entry.entry_id] config_entry.entry_id]
new_entities = [] new_entities = []
for miot_device in device_list: for miot_device in device_list:
for prop in miot_device.prop_list.get('select', []): for prop in miot_device.prop_list.get("select", []):
new_entities.append(Select(miot_device=miot_device, spec=prop)) new_entities.append(Select(miot_device=miot_device, spec=prop))
if new_entities: if new_entities:
async_add_entities(new_entities) async_add_entities(new_entities)
# create select for light
new_light_select_entities = []
for miot_device in device_list:
# Add it to all devices with light entities, because some bathroom heaters and clothes drying racks also have lights.
# if "device:light" in miot_device.spec_instance.urn:
if miot_device.entity_list.get("light", []):
device_id = list(miot_device.device_info.get("identifiers"))[0][1]
new_light_select_entities.append(
LightCommandSendMode(hass=hass, device_id=device_id))
if new_light_select_entities:
async_add_entities(new_light_select_entities)
class Select(MIoTPropertyEntity, SelectEntity): class Select(MIoTPropertyEntity, SelectEntity):
"""Select entities for Xiaomi Home.""" """Select entities for Xiaomi Home."""
@ -87,10 +106,47 @@ class Select(MIoTPropertyEntity, SelectEntity):
async def async_select_option(self, option: str) -> None: async def async_select_option(self, option: str) -> None:
"""Change the selected option.""" """Change the selected option."""
await self.set_property_async( await self.set_property_async(value=self.get_vlist_value(
value=self.get_vlist_value(description=option)) description=option))
@property @property
def current_option(self) -> Optional[str]: def current_option(self) -> Optional[str]:
"""Return the current selected option.""" """Return the current selected option."""
return self.get_vlist_description(value=self._value) return self.get_vlist_description(value=self._value)
class LightCommandSendMode(SelectEntity, RestoreEntity):
"""To control whether to turn on the light, you need to send the light-on command first and
then send other color temperatures and brightness or send them all at the same time.
The default is to send one by one."""
def __init__(self, hass: HomeAssistant, device_id: str):
super().__init__()
self.hass = hass
self._device_id = device_id
self._attr_name = "Command Send Mode"
self.entity_id = f"select.light_{device_id}_command_send_mode"
self._attr_unique_id = self.entity_id
self._attr_options = [
"Send One by One", "Send Turn On First", "Send Together"
]
self._attr_device_info = {"identifiers": {(DOMAIN, device_id)}}
self._attr_current_option = self._attr_options[0]
self._attr_entity_category = EntityCategory.CONFIG
async def async_select_option(self, option: str):
if option in self._attr_options:
self._attr_current_option = option
self.async_write_ha_state()
async def async_added_to_hass(self):
await super().async_added_to_hass()
if (last_state := await self.async_get_last_state()
) and last_state.state in self._attr_options:
self._attr_current_option = last_state.state
@property
def current_option(self):
return self._attr_current_option

View File

@ -4,7 +4,7 @@
"step": { "step": {
"eula": { "eula": {
"title": "Risikohinweis", "title": "Risikohinweis",
"description": "1. Ihre **Xiaomi-Benutzerinformationen und Geräteinformationen** werden in Ihrem Home Assistant-System gespeichert. **Xiaomi kann die Sicherheit des Home Assistant-Speichermechanismus nicht garantieren**. Sie sind dafür verantwortlich, Ihre Informationen vor Diebstahl zu schützen.\r\n2. Diese Integration wird von der Open-Source-Community unterstützt und gewartet. Es können jedoch Stabilitätsprobleme oder andere Probleme auftreten. Wenn Sie auf ein Problem stoßen, das mit dieser Integration zusammenhängt, sollten Sie **die Open-Source-Community um Hilfe bitten, anstatt sich an den Xiaomi Home Kundendienst zu wenden**.\r\n3. Sie benötigen bestimmte technische Fähigkeiten, um Ihre lokale Laufzeitumgebung zu warten. Diese Integration ist für Anfänger nicht geeignet. \r\n4. Bevor Sie diese Integration verwenden, lesen Sie bitte die **README-Datei sorgfältig durch**.\r\n5. Um eine stabile Nutzung der Integration zu gewährleisten und Missbrauch der Schnittstelle zu verhindern, **darf diese Integration nur in Home Assistant verwendet werden. Weitere Informationen finden Sie in der LICENSE**.", "description": "1. Ihre **Xiaomi-Benutzerinformationen und Geräteinformationen** werden in Ihrem Home Assistant-System gespeichert. **Xiaomi kann die Sicherheit des Home Assistant-Speichermechanismus nicht garantieren**. Sie sind dafür verantwortlich, Ihre Informationen vor Diebstahl zu schützen.\r\n2. Diese Integration wird von der Open-Source-Community unterstützt und gewartet. Es können jedoch Stabilitätsprobleme oder andere Probleme auftreten. Wenn Sie auf ein Problem stoßen, das mit dieser Integration zusammenhängt, sollten Sie **die Open-Source-Community um Hilfe bitten, anstatt sich an den Xiaomi Home Kundendienst zu wenden**.\r\n3. Sie benötigen bestimmte technische Fähigkeiten, um Ihre lokale Laufzeitumgebung zu warten. Diese Integration ist für Anfänger nicht geeignet.\r\n4. Bevor Sie diese Integration verwenden, lesen Sie bitte die **README-Datei sorgfältig durch**.\r\n5. Um eine stabile Nutzung der Integration zu gewährleisten und Missbrauch der Schnittstelle zu verhindern, **darf diese Integration nur in Home Assistant verwendet werden. Weitere Informationen finden Sie in der LICENSE**.",
"data": { "data": {
"eula": "Ich habe das oben genannte Risiko zur Kenntnis genommen und übernehme freiwillig die damit verbundenen Risiken durch die Verwendung der Integration." "eula": "Ich habe das oben genannte Risiko zur Kenntnis genommen und übernehme freiwillig die damit verbundenen Risiken durch die Verwendung der Integration."
} }
@ -124,7 +124,8 @@
"display_devices_changed_notify": "Gerätestatusänderungen anzeigen", "display_devices_changed_notify": "Gerätestatusänderungen anzeigen",
"update_trans_rules": "Entitätskonvertierungsregeln aktualisieren", "update_trans_rules": "Entitätskonvertierungsregeln aktualisieren",
"update_lan_ctrl_config": "LAN-Steuerungskonfiguration aktualisieren", "update_lan_ctrl_config": "LAN-Steuerungskonfiguration aktualisieren",
"network_detect_config": "Integrierte Netzwerkkonfiguration" "network_detect_config": "Integrierte Netzwerkkonfiguration",
"cover_closed_position": "Die Position der geschlossenen Vorhänge"
} }
}, },
"update_user_info": { "update_user_info": {
@ -183,7 +184,7 @@
}, },
"config_confirm": { "config_confirm": {
"title": "Bestätigen Sie die Konfiguration", "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ä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", "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\nDie Position der geschlossenen Vorhänge:\t{cover_pos_new}\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": { "data": {
"confirm": "Änderungen bestätigen" "confirm": "Änderungen bestätigen"
} }

View File

@ -124,7 +124,8 @@
"display_devices_changed_notify": "Display device status change notifications", "display_devices_changed_notify": "Display device status change notifications",
"update_trans_rules": "Update entity conversion rules", "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" "network_detect_config": "Integrated network configuration",
"cover_closed_position": "Cover closed position"
} }
}, },
"update_user_info": { "update_user_info": {
@ -183,7 +184,7 @@
}, },
"config_confirm": { "config_confirm": {
"title": "Confirm Configuration", "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\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", "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\nCover closed position:\t{cover_pos_new}\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": { "data": {
"confirm": "Confirm the change" "confirm": "Confirm the change"
} }

View File

@ -4,7 +4,7 @@
"step": { "step": {
"eula": { "eula": {
"title": "Aviso de riesgo", "title": "Aviso de riesgo",
"description": "1. Su **información de usuario de Xiaomi e información del dispositivo** se almacenará en su sistema Home Assistant. **Xiaomi no puede garantizar la seguridad del mecanismo de almacenamiento de Home Assistant**. Usted es responsable de evitar que su información sea robada.\r\n2. Esta integración es mantenida por la comunidad de código abierto y puede haber problemas de estabilidad u otros problemas. Cuando tenga problemas relacionados con el uso de esta integración, **busque ayuda en la comunidad de código abierto en lugar de contactar al servicio al cliente de Xiaomi**.\r\n3. Es necesario tener ciertas habilidades técnicas para mantener su entorno de ejecución local, esta integración no es amigable para los usuarios novatos.\r\n4. Antes de utilizar esta integración, por favor **lea detenidamente el archivo README**. \r\n5. Para garantizar el uso estable de la integración y prevenir el abuso de la interfaz, **esta integración solo está permitida en Home Assistant. Para más detalles, consulte la LICENSE**.", "description": "1. Su **información de usuario de Xiaomi e información del dispositivo** se almacenará en su sistema Home Assistant. **Xiaomi no puede garantizar la seguridad del mecanismo de almacenamiento de Home Assistant**. Usted es responsable de evitar que su información sea robada.\r\n2. Esta integración es mantenida por la comunidad de código abierto y puede haber problemas de estabilidad u otros problemas. Cuando tenga problemas relacionados con el uso de esta integración, **busque ayuda en la comunidad de código abierto en lugar de contactar al servicio al cliente de Xiaomi**.\r\n3. Es necesario tener ciertas habilidades técnicas para mantener su entorno de ejecución local, esta integración no es amigable para los usuarios novatos.\r\n4. Antes de utilizar esta integración, por favor **lea detenidamente el archivo README**.\r\n5. Para garantizar el uso estable de la integración y prevenir el abuso de la interfaz, **esta integración solo está permitida en Home Assistant. Para más detalles, consulte la LICENSE**.",
"data": { "data": {
"eula": "He leído y entiendo los riesgos anteriores, y estoy dispuesto a asumir cualquier riesgo relacionado con el uso de esta integración." "eula": "He leído y entiendo los riesgos anteriores, y estoy dispuesto a asumir cualquier riesgo relacionado con el uso de esta integración."
} }
@ -124,7 +124,8 @@
"display_devices_changed_notify": "Mostrar notificaciones de cambio de estado del dispositivo", "display_devices_changed_notify": "Mostrar notificaciones de cambio de estado del dispositivo",
"update_trans_rules": "Actualizar reglas de conversión de entidad", "update_trans_rules": "Actualizar reglas de conversión de entidad",
"update_lan_ctrl_config": "Actualizar configuración de control LAN", "update_lan_ctrl_config": "Actualizar configuración de control LAN",
"network_detect_config": "Configuración de Red Integrada" "network_detect_config": "Configuración de Red Integrada",
"cover_closed_position": "La posición de las cortinas cerradas"
} }
}, },
"update_user_info": { "update_user_info": {
@ -183,7 +184,7 @@
}, },
"config_confirm": { "config_confirm": {
"title": "Confirmar configuración", "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\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", "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\nLa posición de las cortinas cerradas:\t{cover_pos_new}\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": { "data": {
"confirm": "Confirmar modificación" "confirm": "Confirmar modificación"
} }

View File

@ -124,7 +124,8 @@
"display_devices_changed_notify": "Afficher les notifications de changement d'état de l'appareil", "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_trans_rules": "Mettre à jour les règles de conversion d'entités",
"update_lan_ctrl_config": "Mettre à jour la configuration de contrôle LAN", "update_lan_ctrl_config": "Mettre à jour la configuration de contrôle LAN",
"network_detect_config": "Configuration Réseau Intégrée" "network_detect_config": "Configuration Réseau Intégrée",
"cover_closed_position": "La position des rideaux fermés"
} }
}, },
"update_user_info": { "update_user_info": {
@ -183,7 +184,7 @@
}, },
"config_confirm": { "config_confirm": {
"title": "Confirmer la configuration", "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\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", "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\nLa position des rideaux fermés:\t{cover_pos_new}\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": { "data": {
"confirm": "Confirmer la modification" "confirm": "Confirmer la modification"
} }

View File

@ -124,7 +124,8 @@
"display_devices_changed_notify": "Mostra notifiche di cambio stato del dispositivo", "display_devices_changed_notify": "Mostra notifiche di cambio stato del dispositivo",
"update_trans_rules": "Aggiorna le regole di conversione delle entità", "update_trans_rules": "Aggiorna le regole di conversione delle entità",
"update_lan_ctrl_config": "Aggiorna configurazione del controllo LAN", "update_lan_ctrl_config": "Aggiorna configurazione del controllo LAN",
"network_detect_config": "Configurazione di Rete Integrata" "network_detect_config": "Configurazione di Rete Integrata",
"cover_closed_position": "La posizione delle tende chiuse"
} }
}, },
"update_user_info": { "update_user_info": {
@ -183,7 +184,7 @@
}, },
"config_confirm": { "config_confirm": {
"title": "Conferma Configurazione", "title": "Conferma Configurazione",
"description": "Ciao **{nick_name}**, si prega di confermare le informazioni di configurazione più recenti e poi fare clic su INVIA.\r\nL'integrazione verrà ricaricata utilizzando la configurazione aggiornata.\r\n\r\nLingua dell'Integrazione: \t{lang_new}\r\nSoprannome: \t{nick_name_new}\r\nModalità di debug per azione: \t{action_debug}\r\nNascondi entità create non standard: \t{hide_non_standard_entities}\r\nMostra notifiche di cambio stato del dispositivo:\t{display_devices_changed_notify}\r\nCambiamenti del Dispositivo: \tAggiungi **{devices_add}** dispositivi, Rimuovi **{devices_remove}** dispositivi\r\nCambiamenti delle regole di trasformazione: \tCi sono un totale di **{trans_rules_count}** regole, e aggiornate **{trans_rules_count_success}** regole", "description": "Ciao **{nick_name}**, si prega di confermare le informazioni di configurazione più recenti e poi fare clic su INVIA.\r\nL'integrazione verrà ricaricata utilizzando la configurazione aggiornata.\r\n\r\nLingua dell'Integrazione:\t{lang_new}\r\nSoprannome:\t{nick_name_new}\r\nModalità di debug per azione:\t{action_debug}\r\nNascondi entità create non standard:\t{hide_non_standard_entities}\r\nLa posizione delle tende chiuse:\t{cover_pos_new}\r\nMostra notifiche di cambio stato del dispositivo:\t{display_devices_changed_notify}\r\nCambiamenti del Dispositivo:\tAggiungi **{devices_add}** dispositivi, Rimuovi **{devices_remove}** dispositivi\r\nCambiamenti delle regole di trasformazione:\tCi sono un totale di **{trans_rules_count}** regole, e aggiornate **{trans_rules_count_success}** regole",
"data": { "data": {
"confirm": "Conferma la modifica" "confirm": "Conferma la modifica"
} }

View File

@ -124,7 +124,8 @@
"display_devices_changed_notify": "デバイスの状態変化通知を表示", "display_devices_changed_notify": "デバイスの状態変化通知を表示",
"update_trans_rules": "エンティティ変換ルールを更新する", "update_trans_rules": "エンティティ変換ルールを更新する",
"update_lan_ctrl_config": "LAN制御構成を更新する", "update_lan_ctrl_config": "LAN制御構成を更新する",
"network_detect_config": "統合ネットワーク構成" "network_detect_config": "統合ネットワーク構成",
"cover_closed_position": "カーテンを閉じた位置"
} }
}, },
"update_user_info": { "update_user_info": {
@ -183,7 +184,7 @@
}, },
"config_confirm": { "config_confirm": {
"title": "構成を確認する", "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{display_devices_changed_notify}\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{cover_pos_new}\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": { "data": {
"confirm": "変更を確認する" "confirm": "変更を確認する"
} }

View File

@ -124,7 +124,8 @@
"display_devices_changed_notify": "Apparaatstatuswijzigingen weergeven", "display_devices_changed_notify": "Apparaatstatuswijzigingen weergeven",
"update_trans_rules": "Werk entiteitsconversieregels bij", "update_trans_rules": "Werk entiteitsconversieregels bij",
"update_lan_ctrl_config": "Werk LAN controleconfiguratie bij", "update_lan_ctrl_config": "Werk LAN controleconfiguratie bij",
"network_detect_config": "Geïntegreerde Netwerkconfiguratie" "network_detect_config": "Geïntegreerde Netwerkconfiguratie",
"cover_closed_position": "De positie van de gesloten gordijnen"
} }
}, },
"update_user_info": { "update_user_info": {
@ -183,7 +184,7 @@
}, },
"config_confirm": { "config_confirm": {
"title": "Bevestig Configuratie", "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", "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\nDe positie van de gesloten gordijnen:\t{cover_pos_new}\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": { "data": {
"confirm": "Bevestig de wijziging" "confirm": "Bevestig de wijziging"
} }

View File

@ -124,7 +124,8 @@
"display_devices_changed_notify": "Exibir notificações de mudança de status do dispositivo", "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_trans_rules": "Atualizar regras de conversão de entidades",
"update_lan_ctrl_config": "Atualizar configuração de controle LAN", "update_lan_ctrl_config": "Atualizar configuração de controle LAN",
"network_detect_config": "Configuração de Rede Integrada" "network_detect_config": "Configuração de Rede Integrada",
"cover_closed_position": "A posição das cortinas fechadas"
} }
}, },
"update_user_info": { "update_user_info": {
@ -183,7 +184,7 @@
}, },
"config_confirm": { "config_confirm": {
"title": "Confirmar Configuração", "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", "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\nA posição das cortinas fechadas:\t{cover_pos_new}\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": { "data": {
"confirm": "Confirmar a mudança" "confirm": "Confirmar a mudança"
} }

View File

@ -124,7 +124,8 @@
"display_devices_changed_notify": "Exibir notificações de mudança de status do dispositivo", "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_trans_rules": "Atualizar regras de conversão de entidades",
"update_lan_ctrl_config": "Atualizar configuração de controlo LAN", "update_lan_ctrl_config": "Atualizar configuração de controlo LAN",
"network_detect_config": "Configuração de Rede Integrada" "network_detect_config": "Configuração de Rede Integrada",
"cover_closed_position": "A posição das cortinas fechadas"
} }
}, },
"update_user_info": { "update_user_info": {
@ -183,7 +184,7 @@
}, },
"config_confirm": { "config_confirm": {
"title": "Confirmar Configuração", "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", "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\nA posição das cortinas fechadas:\t{cover_pos_new}\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": { "data": {
"confirm": "Confirmar a alteração" "confirm": "Confirmar a alteração"
} }

View File

@ -124,7 +124,8 @@
"display_devices_changed_notify": "Отображать уведомления о изменении состояния устройства", "display_devices_changed_notify": "Отображать уведомления о изменении состояния устройства",
"update_trans_rules": "Обновить правила преобразования сущностей", "update_trans_rules": "Обновить правила преобразования сущностей",
"update_lan_ctrl_config": "Обновить конфигурацию управления LAN", "update_lan_ctrl_config": "Обновить конфигурацию управления LAN",
"network_detect_config": "Интегрированная Сетевая Конфигурация" "network_detect_config": "Интегрированная Сетевая Конфигурация",
"cover_closed_position": "Положение закрытых штор"
} }
}, },
"update_user_info": { "update_user_info": {
@ -183,7 +184,7 @@
}, },
"config_confirm": { "config_confirm": {
"title": "Подтверждение настройки", "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{display_devices_changed_notify}\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{cover_pos_new}\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": { "data": {
"confirm": "Подтвердить изменения" "confirm": "Подтвердить изменения"
} }

View File

@ -124,7 +124,8 @@
"display_devices_changed_notify": "显示设备状态变化通知", "display_devices_changed_notify": "显示设备状态变化通知",
"update_trans_rules": "更新实体转换规则", "update_trans_rules": "更新实体转换规则",
"update_lan_ctrl_config": "更新局域网控制配置", "update_lan_ctrl_config": "更新局域网控制配置",
"network_detect_config": "集成网络配置" "network_detect_config": "集成网络配置",
"cover_closed_position": "窗帘关闭位置"
} }
}, },
"update_user_info": { "update_user_info": {
@ -183,7 +184,7 @@
}, },
"config_confirm": { "config_confirm": {
"title": "确认配置", "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{display_devices_changed_notify}\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{cover_pos_new}\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": { "data": {
"confirm": "确认修改" "confirm": "确认修改"
} }

View File

@ -124,7 +124,8 @@
"display_devices_changed_notify": "顯示設備狀態變化通知", "display_devices_changed_notify": "顯示設備狀態變化通知",
"update_trans_rules": "更新實體轉換規則", "update_trans_rules": "更新實體轉換規則",
"update_lan_ctrl_config": "更新局域網控制配置", "update_lan_ctrl_config": "更新局域網控制配置",
"network_detect_config": "集成網絡配置" "network_detect_config": "集成網絡配置",
"cover_closed_position": "窗簾關閉位置"
} }
}, },
"update_user_info": { "update_user_info": {
@ -183,7 +184,7 @@
}, },
"config_confirm": { "config_confirm": {
"title": "確認配置", "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{display_devices_changed_notify}\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{cover_pos_new}\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": { "data": {
"confirm": "確認修改" "confirm": "確認修改"
} }