7 Commits

Author SHA1 Message Date
Li Shuzhen
c04fa542a3 docs: update changelog and version to v0.4.3 (#1453)
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-10-14 08:33:36 +08:00
Li Shuzhen
fbddaf80a7 fix: pylint 4.0.0 (#1455)
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-10-13 17:11:30 +08:00
Li Shuzhen
a11c3e2fda Fix specs (#1394)
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
* fix: xiaomi.airc.rr0r00 swing mode (#1386)

* fix: hyd.airer.lyjpro current-position (#1376)

* feat: add an alongside button entity for xiaomi.wifispeaker.l05b play action (#1372)

* fix: ignore the unsupported property 2.3 of 759413.aircondition.iez (#1391)

* fix: ignore unsupported properties of xiaomi.wifispeaker.l15a

* feat: zhimi.fan.za1 fan mode description in zh_Hans (#1424)

* fix: roidmi.vacuum.v60 siid=2 aiid=3 out field format (#1437)
2025-10-11 11:33:07 +08:00
Li Shuzhen
739998211e feat: remove VacuumEntityFeature.BATTERY from the vacuum entity (#1433)
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-10-10 16:31:02 +08:00
Li Shuzhen
ec833b6539 feat: subscribe the proxy gateway child device up messages even though the device is offline (#1393)
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
* feat: subscribe the proxy gateway child device up messages even though the device is offline (#1313)

* feat: do not subscribe proxy gateway child device online/offline state message
2025-09-02 17:22:40 +08:00
Li Shuzhen
f2200ba003 fix: contact-state value format (#1387)
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-08-29 17:36:25 +08:00
Li Shuzhen
073cdf2dcb fix: integer value step (#1388) 2025-08-29 17:35:46 +08:00
13 changed files with 107 additions and 33 deletions

View File

@@ -1,10 +1,24 @@
# CHANGELOG
## v0.4.3
### Changed
- Remove `VacuumEntityFeature.BATTERY` from the vacuum entity. [#1433](https://github.com/XiaoMi/ha_xiaomi_home/pull/1433)
- Subscribe the proxy gateway child device up messages even though the device is offline. [#1393](https://github.com/XiaoMi/ha_xiaomi_home/pull/1393)
### Fixed
- Fix the integer value step. [#1388](https://github.com/XiaoMi/ha_xiaomi_home/pull/1388)
- Fix the contact-state property value format. [#1387](https://github.com/XiaoMi/ha_xiaomi_home/pull/1387)
- Fix the MIoT-Spec-V2 of xiaomi.airc.rr0r00 swing mode and hyd.airer.lyjpro current-position. [#1394](https://github.com/XiaoMi/ha_xiaomi_home/pull/1394)
- Fix roidmi.vacuum.v60 siid=2 aiid=3 out field format.
- Ignore unsupported properties of xiaomi.wifispeaker.l15a and 759413.aircondition.iez.
- Add an alongside button entity for xiaomi.wifispeaker.l05b play action.
- Add zhimi.fan.za1 fan mode description in zh_Hans.
- Fix the error reported by pylint-4.0.0. [#1455](https://github.com/XiaoMi/ha_xiaomi_home/pull/1455)
## v0.4.2
### Changed
- Set the battery service's start-charge action as the fallback action to support RETURN_HOME feature of the vacuum entity. [#1344](https://github.com/XiaoMi/ha_xiaomi_home/pull/1344)
### Fixed
- Correct the property value format after expression calculation. [#1366](https://github.com/XiaoMi/ha_xiaomi_home/pull/1366)
- Fix the MIoT-Spec-V2 of fix: xiaomi.fan.p70 and fix: xiaomi.fan.p76 fan level, xiaomi.airc.rr0r00 and xiaomi.airc.h43h00 humidity-range, and zhimi.humidifier.ca4 water level. [#1367](https://github.com/XiaoMi/ha_xiaomi_home/pull/1367)
- Fix the MIoT-Spec-V2 of xiaomi.fan.p70 and xiaomi.fan.p76 fan level, xiaomi.airc.rr0r00 and xiaomi.airc.h43h00 humidity-range, and zhimi.humidifier.ca4 water level. [#1367](https://github.com/XiaoMi/ha_xiaomi_home/pull/1367)
- Ignore the unsupported model hmpace.motion.v6nfc.
- Delete all unsupported MIoT-Spec-V2 instances of narwa.vacuum.001 and narwa.vacuum.ax11. [#1355](https://github.com/XiaoMi/ha_xiaomi_home/pull/1355)

View File

@@ -70,8 +70,8 @@ async def async_setup_entry(
for miot_device in device_list:
if miot_device.miot_client.display_binary_bool:
for prop in miot_device.prop_list.get('binary_sensor', []):
new_entities.append(BinarySensor(
miot_device=miot_device, spec=prop))
new_entities.append(
BinarySensor(miot_device=miot_device, spec=prop))
if new_entities:
async_add_entities(new_entities)
@@ -90,7 +90,7 @@ class BinarySensor(MIoTPropertyEntity, BinarySensorEntity):
def is_on(self) -> bool:
"""On/Off state. True if the binary sensor is on, False otherwise."""
if self.spec.name == 'contact-state':
return self._value is False
return bool(self._value) is False
elif self.spec.name == 'occupancy-status':
return bool(self._value)
return self._value is True

View File

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

View File

@@ -1374,10 +1374,13 @@ class MIoTClient:
"""Update cloud devices.
NOTICE: This function will operate the cloud_list
"""
# MIoT cloud service may not publish the online state updating message
# MIoT cloud may not publish the online state updating message
# for the BLE device. Assume that all BLE devices are online.
# MIoT cloud does not publish the online state updating message for the
# child device under the proxy gateway (eg, VRF air conditioner
# controller). Assume that all proxy gateway child devices are online.
for did, info in cloud_list.items():
if did.startswith('blt.'):
if did.startswith('blt.') or did.startswith('proxy.'):
info['online'] = True
for did, info in self._device_list_cache.items():
if filter_dids and did not in filter_dids:

View File

@@ -998,9 +998,11 @@ class MipsCloudClient(_MipsClient):
did, MIoTDeviceState.ONLINE if msg['event'] == 'online'
else MIoTDeviceState.OFFLINE, ctx)
if did.startswith('blt.'):
# MIoT cloud may not publish BLE device online/offline state message.
# Do not subscribe BLE device online/offline state.
if did.startswith('blt.') or did.startswith('proxy.'):
# MIoT cloud may not publish BLE device or proxy gateway child device
# online/offline state message.
# Do not subscribe BLE device or proxy gateway child device
# online/offline state.
return True
return self.__reg_broadcast_external(
topic=topic, handler=on_state_msg, handler_ctx=handler_ctx)

View File

@@ -601,7 +601,10 @@ class MIoTSpecProperty(_MIoTSpecBase):
if value is None:
return None
if self.format_ == int:
return int(round(value))
if self.value_range is None:
return int(round(value))
return int(
round(value / self.value_range.step) * self.value_range.step)
if self.format_ == float:
return round(value, self.precision)
if self.format_ == bool:

View File

@@ -5,6 +5,12 @@
"service:003:property:001:valuelist:001": "Dry"
}
},
"urn:miot-spec-v2:device:fan:0000A005:zhimi-za1": {
"zh-Hans": {
"service:002:property:005:valuelist:000": "自然风",
"service:002:property:005:valuelist:001": "直吹风"
}
},
"urn:miot-spec-v2:device:gateway:0000A019:xiaomi-hub1": {
"de": {
"service:001": "Geräteinformationen",
@@ -274,13 +280,13 @@
"service:002:property:002": "Air Conditioner Mode",
"service:004": "Air Conditioner"
},
"zh_cn": {
"zh-Hans": {
"service:002": "地暖",
"service:004": "空调"
}
},
"urn:miot-spec-v2:device:vacuum:0000A006:ijai-v1": {
"zh_cn": {
"zh-Hans": {
"service:007:property:005:valuelist:000": "安静",
"service:007:property:005:valuelist:001": "标准",
"service:007:property:005:valuelist:002": "中档",

View File

@@ -82,6 +82,22 @@
]
}
],
"urn:miot-spec-v2:device:speaker:0000A015:xiaomi-l05b:1": [
{
"iid": 3,
"type": "urn:miot-spec-v2:service:play:0000781D:xiaomi-l05b:1",
"description": "Play Control",
"actions": [
{
"iid": 2,
"type": "urn:miot-spec-v2:action:play:0000280B:xiaomi-l05b:1",
"description": "Play",
"in": [],
"out": []
}
]
}
],
"urn:miot-spec-v2:device:thermostat:0000A031:tofan-wk01:1:0000C822": [
{
"iid": 2,
@@ -1660,6 +1676,24 @@
]
}
],
"urn:miot-spec-v2:device:vacuum:0000A006:roidmi-v60:3": [
{
"iid": 2,
"type": "urn:miot-spec-v2:service:vacuum:00007810:roidmi-v60:1",
"description": "Robot Cleaner",
"actions": [
{
"iid": 3,
"type": "urn:miot-spec-v2:action:start-room-sweep:00002826:roidmi-v60:1",
"description": "Start Room Sweep",
"in": [
9
],
"out": []
}
]
}
],
"urn:miot-spec-v2:device:water-heater:0000A02A:viomi-m1:2": [
{
"iid": 2,

View File

@@ -1,6 +1,9 @@
urn:miot-spec-v2:device:air-conditioner:0000A004:090615-ktf:
services:
- '4'
urn:miot-spec-v2:device:air-conditioner:0000A004:759413-iez:
properties:
- '2.3'
urn:miot-spec-v2:device:air-purifier:0000A007:zhimi-ma4:
properties:
- 9.*
@@ -44,6 +47,13 @@ urn:miot-spec-v2:device:motion-sensor:0000A014:xiaomi-pir1:
services:
- '1'
- '5'
urn:miot-spec-v2:device:speaker:0000A015:xiaomi-l15a:
properties:
- '3.3'
- '6.1'
- '6.2'
- '6.3'
- '6.4'
urn:miot-spec-v2:device:thermostat:0000A031:tofan-wk01:
services:
- '2'
@@ -54,3 +64,6 @@ urn:miot-spec-v2:device:vacuum:0000A006:narwa-001:
urn:miot-spec-v2:device:vacuum:0000A006:narwa-ax11:
services:
- '*'
urn:miot-spec-v2:device:vacuum:0000A006:roidmi-v60:
actions:
- '2.3'

View File

@@ -48,6 +48,18 @@ urn:miot-spec-v2:device:air-conditioner:0000A004:xiaomi-mt0:2: urn:miot-spec-v2:
urn:miot-spec-v2:device:air-conditioner:0000A004:xiaomi-rr0r00:1:
prop.10.6:
unit: none
prop.3.12:
name: vertical-swing-left-up
prop.3.13:
name: vertical-swing-left-down
prop.3.14:
name: vertical-swing-right-up
prop.3.15:
name: vertical-swing-right-down
prop.3.20:
name: horizontal-swing-left
prop.3.22:
name: horizontal-swing-right
urn:miot-spec-v2:device:air-conditioner:0000A004:xiaomi-rr0r00:2: urn:miot-spec-v2:device:air-conditioner:0000A004:xiaomi-rr0r00:1
urn:miot-spec-v2:device:air-conditioner:0000A004:xiaomi-rr0r00:3: urn:miot-spec-v2:device:air-conditioner:0000A004:xiaomi-rr0r00:1
urn:miot-spec-v2:device:air-conditioner:0000A004:xiaomi-rr0r00:4: urn:miot-spec-v2:device:air-conditioner:0000A004:xiaomi-rr0r00:1
@@ -72,6 +84,8 @@ urn:miot-spec-v2:device:airer:0000A00D:hyd-lyjpro:1:
name: target-position-a
prop.2.9:
name: target-position-b
prop.2.11:
expr: (100-src_value)
urn:miot-spec-v2:device:airer:0000A00D:hyd-znlyj5:1:
prop.2.3:
value-range:

View File

@@ -167,11 +167,6 @@ SPEC_DEVICE_TRANS_MAP: dict = {
},
'battery': {
'required': {
'properties': {
'battery-level': {'read'}
}
},
'optional': {
'actions': {
'start-charge'
}

View File

@@ -49,7 +49,7 @@ MIoT redirect web pages.
import os
import asyncio
_template = ''
web_template = ''
def _load_page_template():
@@ -57,18 +57,18 @@ def _load_page_template():
os.path.dirname(os.path.abspath(__file__)),
'resource/oauth_redirect_page.html')
with open(path, 'r', encoding='utf-8') as f:
global _template
_template = f.read()
global web_template
web_template = f.read()
async def oauth_redirect_page(
title: str, content: str, button: str, success: bool
) -> str:
"""Return oauth redirect page."""
if _template == '':
if web_template == '':
await asyncio.get_running_loop().run_in_executor(
None, _load_page_template)
web_page = _template.replace('TITLE_PLACEHOLDER', title)
web_page = web_template.replace('TITLE_PLACEHOLDER', title)
web_page = web_page.replace('CONTENT_PLACEHOLDER', content)
web_page = web_page.replace('BUTTON_PLACEHOLDER', button)
web_page = web_page.replace(

View File

@@ -90,7 +90,6 @@ class Vacuum(MIoTServiceEntity, StateVacuumEntity):
# pylint: disable=unused-argument
_prop_status: Optional[MIoTSpecProperty]
_prop_fan_level: Optional[MIoTSpecProperty]
_prop_battery_level: Optional[MIoTSpecProperty]
_prop_status_cleaning: Optional[list[int]]
_prop_status_docked: Optional[list[int]]
_prop_status_paused: Optional[list[int]]
@@ -117,7 +116,6 @@ class Vacuum(MIoTServiceEntity, StateVacuumEntity):
self._prop_status = None
self._prop_fan_level = None
self._prop_battery_level = None
self._prop_status_cleaning = []
self._prop_status_docked = []
self._prop_status_paused = []
@@ -180,9 +178,6 @@ class Vacuum(MIoTServiceEntity, StateVacuumEntity):
self._attr_fan_speed_list = list(self._fan_level_map.values())
self._attr_supported_features |= VacuumEntityFeature.FAN_SPEED
self._prop_fan_level = prop
elif prop.name == 'battery-level':
self._attr_supported_features |= VacuumEntityFeature.BATTERY
self._prop_battery_level = prop
# action
for action in entity_data.actions:
if action.name == 'start-sweep':
@@ -251,11 +246,6 @@ class Vacuum(MIoTServiceEntity, StateVacuumEntity):
"""Name of the vacuum entity."""
return self._device_name
@property
def battery_level(self) -> Optional[int]:
"""The current battery level of the vacuum cleaner."""
return self.get_prop_value(prop=self._prop_battery_level)
@property
def fan_speed(self) -> Optional[str]:
"""The current fan speed of the vacuum cleaner."""