From 23cc1130fe56a21cc4cced7c7e3138532e5491c1 Mon Sep 17 00:00:00 2001 From: Li Shuzhen Date: Thu, 22 May 2025 11:28:37 +0800 Subject: [PATCH] Fix specs (#1110) * fix: the power consumption, the voltage and the current of lxzn.switch.cbcsmj * fix: the fan direction of shhf.light.sfla10 * fix: the door state value-list description in Chinese of loock.lock.t2pv1 * fix: the stepless fan level of zhimi.fan.za4 * fix: the stepless fan level of zhimi.fan.sa1 --- .../xiaomi_home/miot/specs/multi_lang.json | 381 +++++++++--------- .../xiaomi_home/miot/specs/spec_modify.yaml | 20 +- doc/README_zh.md | 2 +- test/check_rule_format.py | 30 ++ 4 files changed, 245 insertions(+), 188 deletions(-) diff --git a/custom_components/xiaomi_home/miot/specs/multi_lang.json b/custom_components/xiaomi_home/miot/specs/multi_lang.json index c9501ce..b2e7979 100644 --- a/custom_components/xiaomi_home/miot/specs/multi_lang.json +++ b/custom_components/xiaomi_home/miot/specs/multi_lang.json @@ -1,187 +1,198 @@ { - "urn:miot-spec-v2:device:gateway:0000A019:xiaomi-hub1": { - "de": { - "service:001": "Geräteinformationen", - "service:001:property:003": "Geräte-ID", - "service:001:property:005": "Seriennummer (SN)", - "service:002": "Gateway", - "service:002:event:001": "Netzwerk geändert", - "service:002:event:002": "Netzwerk geändert", - "service:002:property:001": "Zugriffsmethode", - "service:002:property:001:valuelist:000": "Kabelgebunden", - "service:002:property:001:valuelist:001": "5G Drahtlos", - "service:002:property:001:valuelist:002": "2.4G Drahtlos", - "service:002:property:002": "IP-Adresse", - "service:002:property:003": "WiFi-Netzwerkname", - "service:002:property:004": "Aktuelle Zeit", - "service:002:property:005": "DHCP-Server-MAC-Adresse", - "service:003": "Anzeigelampe", - "service:003:property:001": "Schalter", - "service:004": "Virtueller Dienst", - "service:004:action:001": "Virtuelles Ereignis erzeugen", - "service:004:event:001": "Virtuelles Ereignis aufgetreten", - "service:004:property:001": "Ereignisname" - }, - "en": { - "service:001": "Device Information", - "service:001:property:003": "Device ID", - "service:001:property:005": "Serial Number (SN)", - "service:002": "Gateway", - "service:002:event:001": "Network Changed", - "service:002:event:002": "Network Changed", - "service:002:property:001": "Access Method", - "service:002:property:001:valuelist:000": "Wired", - "service:002:property:001:valuelist:001": "5G Wireless", - "service:002:property:001:valuelist:002": "2.4G Wireless", - "service:002:property:002": "IP Address", - "service:002:property:003": "WiFi Network Name", - "service:002:property:004": "Current Time", - "service:002:property:005": "DHCP Server MAC Address", - "service:003": "Indicator Light", - "service:003:property:001": "Switch", - "service:004": "Virtual Service", - "service:004:action:001": "Generate Virtual Event", - "service:004:event:001": "Virtual Event Occurred", - "service:004:property:001": "Event Name" - }, - "es": { - "service:001": "Información del dispositivo", - "service:001:property:003": "ID del dispositivo", - "service:001:property:005": "Número de serie (SN)", - "service:002": "Puerta de enlace", - "service:002:event:001": "Cambio de red", - "service:002:event:002": "Cambio de red", - "service:002:property:001": "Método de acceso", - "service:002:property:001:valuelist:000": "Cableado", - "service:002:property:001:valuelist:001": "5G inalámbrico", - "service:002:property:001:valuelist:002": "2.4G inalámbrico", - "service:002:property:002": "Dirección IP", - "service:002:property:003": "Nombre de red WiFi", - "service:002:property:004": "Hora actual", - "service:002:property:005": "Dirección MAC del servidor DHCP", - "service:003": "Luz indicadora", - "service:003:property:001": "Interruptor", - "service:004": "Servicio virtual", - "service:004:action:001": "Generar evento virtual", - "service:004:event:001": "Ocurrió un evento virtual", - "service:004:property:001": "Nombre del evento" - }, - "fr": { - "service:001": "Informations sur l'appareil", - "service:001:property:003": "ID de l'appareil", - "service:001:property:005": "Numéro de série (SN)", - "service:002": "Passerelle", - "service:002:event:001": "Changement de réseau", - "service:002:event:002": "Changement de réseau", - "service:002:property:001": "Méthode d'accès", - "service:002:property:001:valuelist:000": "Câblé", - "service:002:property:001:valuelist:001": "Sans fil 5G", - "service:002:property:001:valuelist:002": "Sans fil 2.4G", - "service:002:property:002": "Adresse IP", - "service:002:property:003": "Nom du réseau WiFi", - "service:002:property:004": "Heure actuelle", - "service:002:property:005": "Adresse MAC du serveur DHCP", - "service:003": "Voyant lumineux", - "service:003:property:001": "Interrupteur", - "service:004": "Service virtuel", - "service:004:action:001": "Générer un événement virtuel", - "service:004:event:001": "Événement virtuel survenu", - "service:004:property:001": "Nom de l'événement" - }, - "ja": { - "service:001": "デバイス情報", - "service:001:property:003": "デバイスID", - "service:001:property:005": "シリアル番号 (SN)", - "service:002": "ゲートウェイ", - "service:002:event:001": "ネットワークが変更されました", - "service:002:event:002": "ネットワークが変更されました", - "service:002:property:001": "アクセス方法", - "service:002:property:001:valuelist:000": "有線", - "service:002:property:001:valuelist:001": "5G ワイヤレス", - "service:002:property:001:valuelist:002": "2.4G ワイヤレス", - "service:002:property:002": "IPアドレス", - "service:002:property:003": "WiFiネットワーク名", - "service:002:property:004": "現在の時間", - "service:002:property:005": "DHCPサーバーMACアドレス", - "service:003": "インジケータライト", - "service:003:property:001": "スイッチ", - "service:004": "バーチャルサービス", - "service:004:action:001": "バーチャルイベントを生成", - "service:004:event:001": "バーチャルイベントが発生しました", - "service:004:property:001": "イベント名" - }, - "ru": { - "service:001": "Информация об устройстве", - "service:001:property:003": "ID устройства", - "service:001:property:005": "Серийный номер (SN)", - "service:002": "Шлюз", - "service:002:event:001": "Сеть изменена", - "service:002:event:002": "Сеть изменена", - "service:002:property:001": "Метод доступа", - "service:002:property:001:valuelist:000": "Проводной", - "service:002:property:001:valuelist:001": "5G Беспроводной", - "service:002:property:001:valuelist:002": "2.4G Беспроводной", - "service:002:property:002": "IP Адрес", - "service:002:property:003": "Название WiFi сети", - "service:002:property:004": "Текущее время", - "service:002:property:005": "MAC адрес DHCP сервера", - "service:003": "Световой индикатор", - "service:003:property:001": "Переключатель", - "service:004": "Виртуальная служба", - "service:004:action:001": "Создать виртуальное событие", - "service:004:event:001": "Произошло виртуальное событие", - "service:004:property:001": "Название события" - }, - "zh-Hant": { - "service:001": "設備信息", - "service:001:property:003": "設備ID", - "service:001:property:005": "序號 (SN)", - "service:002": "網關", - "service:002:event:001": "網路發生變化", - "service:002:event:002": "網路發生變化", - "service:002:property:001": "接入方式", - "service:002:property:001:valuelist:000": "有線", - "service:002:property:001:valuelist:001": "5G 無線", - "service:002:property:001:valuelist:002": "2.4G 無線", - "service:002:property:002": "IP地址", - "service:002:property:003": "WiFi網路名稱", - "service:002:property:004": "當前時間", - "service:002:property:005": "DHCP伺服器MAC地址", - "service:003": "指示燈", - "service:003:property:001": "開關", - "service:004": "虛擬服務", - "service:004:action:001": "產生虛擬事件", - "service:004:event:001": "虛擬事件發生", - "service:004:property:001": "事件名稱" - } - }, - "urn:miot-spec-v2:device:switch:0000A003:lumi-acn040": { - "en": { - "service:011": "Right Button On and Off", - "service:011:property:001": "Right Button On and Off", - "service:015:action:001": "Left Button Identify", - "service:016:action:001": "Middle Button Identify", - "service:017:action:001": "Right Button Identify" - }, - "zh-Hans": { - "service:015:action:001": "左键确认", - "service:016:action:001": "中键确认", - "service:017:action:001": "右键确认" - } - }, - "urn:miot-spec-v2:device:bath-heater:0000A028:yeelink-v10": { - "en": { - "service:003:property:001:valuelist:000": "Idle", - "service:003:property:001:valuelist:001": "Dry" - } - }, - "urn:miot-spec-v2:device:plant-monitor:0000A030:hhcc-v1": { - "en": { - "service:002:property:001": "Soil Moisture" - }, - "zh-Hans": { - "service:002:property:001": "土壤湿度", - "service:002:property:003": "光照强度" - } + "urn:miot-spec-v2:device:bath-heater:0000A028:yeelink-v10": { + "en": { + "service:003:property:001:valuelist:000": "Idle", + "service:003:property:001:valuelist:001": "Dry" } -} \ No newline at end of file + }, + "urn:miot-spec-v2:device:gateway:0000A019:xiaomi-hub1": { + "de": { + "service:001": "Geräteinformationen", + "service:001:property:003": "Geräte-ID", + "service:001:property:005": "Seriennummer (SN)", + "service:002": "Gateway", + "service:002:event:001": "Netzwerk geändert", + "service:002:event:002": "Netzwerk geändert", + "service:002:property:001": "Zugriffsmethode", + "service:002:property:001:valuelist:000": "Kabelgebunden", + "service:002:property:001:valuelist:001": "5G Drahtlos", + "service:002:property:001:valuelist:002": "2.4G Drahtlos", + "service:002:property:002": "IP-Adresse", + "service:002:property:003": "WiFi-Netzwerkname", + "service:002:property:004": "Aktuelle Zeit", + "service:002:property:005": "DHCP-Server-MAC-Adresse", + "service:003": "Anzeigelampe", + "service:003:property:001": "Schalter", + "service:004": "Virtueller Dienst", + "service:004:action:001": "Virtuelles Ereignis erzeugen", + "service:004:event:001": "Virtuelles Ereignis aufgetreten", + "service:004:property:001": "Ereignisname" + }, + "en": { + "service:001": "Device Information", + "service:001:property:003": "Device ID", + "service:001:property:005": "Serial Number (SN)", + "service:002": "Gateway", + "service:002:event:001": "Network Changed", + "service:002:event:002": "Network Changed", + "service:002:property:001": "Access Method", + "service:002:property:001:valuelist:000": "Wired", + "service:002:property:001:valuelist:001": "5G Wireless", + "service:002:property:001:valuelist:002": "2.4G Wireless", + "service:002:property:002": "IP Address", + "service:002:property:003": "WiFi Network Name", + "service:002:property:004": "Current Time", + "service:002:property:005": "DHCP Server MAC Address", + "service:003": "Indicator Light", + "service:003:property:001": "Switch", + "service:004": "Virtual Service", + "service:004:action:001": "Generate Virtual Event", + "service:004:event:001": "Virtual Event Occurred", + "service:004:property:001": "Event Name" + }, + "es": { + "service:001": "Información del dispositivo", + "service:001:property:003": "ID del dispositivo", + "service:001:property:005": "Número de serie (SN)", + "service:002": "Puerta de enlace", + "service:002:event:001": "Cambio de red", + "service:002:event:002": "Cambio de red", + "service:002:property:001": "Método de acceso", + "service:002:property:001:valuelist:000": "Cableado", + "service:002:property:001:valuelist:001": "5G inalámbrico", + "service:002:property:001:valuelist:002": "2.4G inalámbrico", + "service:002:property:002": "Dirección IP", + "service:002:property:003": "Nombre de red WiFi", + "service:002:property:004": "Hora actual", + "service:002:property:005": "Dirección MAC del servidor DHCP", + "service:003": "Luz indicadora", + "service:003:property:001": "Interruptor", + "service:004": "Servicio virtual", + "service:004:action:001": "Generar evento virtual", + "service:004:event:001": "Ocurrió un evento virtual", + "service:004:property:001": "Nombre del evento" + }, + "fr": { + "service:001": "Informations sur l'appareil", + "service:001:property:003": "ID de l'appareil", + "service:001:property:005": "Numéro de série (SN)", + "service:002": "Passerelle", + "service:002:event:001": "Changement de réseau", + "service:002:event:002": "Changement de réseau", + "service:002:property:001": "Méthode d'accès", + "service:002:property:001:valuelist:000": "Câblé", + "service:002:property:001:valuelist:001": "Sans fil 5G", + "service:002:property:001:valuelist:002": "Sans fil 2.4G", + "service:002:property:002": "Adresse IP", + "service:002:property:003": "Nom du réseau WiFi", + "service:002:property:004": "Heure actuelle", + "service:002:property:005": "Adresse MAC du serveur DHCP", + "service:003": "Voyant lumineux", + "service:003:property:001": "Interrupteur", + "service:004": "Service virtuel", + "service:004:action:001": "Générer un événement virtuel", + "service:004:event:001": "Événement virtuel survenu", + "service:004:property:001": "Nom de l'événement" + }, + "ja": { + "service:001": "デバイス情報", + "service:001:property:003": "デバイスID", + "service:001:property:005": "シリアル番号 (SN)", + "service:002": "ゲートウェイ", + "service:002:event:001": "ネットワークが変更されました", + "service:002:event:002": "ネットワークが変更されました", + "service:002:property:001": "アクセス方法", + "service:002:property:001:valuelist:000": "有線", + "service:002:property:001:valuelist:001": "5G ワイヤレス", + "service:002:property:001:valuelist:002": "2.4G ワイヤレス", + "service:002:property:002": "IPアドレス", + "service:002:property:003": "WiFiネットワーク名", + "service:002:property:004": "現在の時間", + "service:002:property:005": "DHCPサーバーMACアドレス", + "service:003": "インジケータライト", + "service:003:property:001": "スイッチ", + "service:004": "バーチャルサービス", + "service:004:action:001": "バーチャルイベントを生成", + "service:004:event:001": "バーチャルイベントが発生しました", + "service:004:property:001": "イベント名" + }, + "ru": { + "service:001": "Информация об устройстве", + "service:001:property:003": "ID устройства", + "service:001:property:005": "Серийный номер (SN)", + "service:002": "Шлюз", + "service:002:event:001": "Сеть изменена", + "service:002:event:002": "Сеть изменена", + "service:002:property:001": "Метод доступа", + "service:002:property:001:valuelist:000": "Проводной", + "service:002:property:001:valuelist:001": "5G Беспроводной", + "service:002:property:001:valuelist:002": "2.4G Беспроводной", + "service:002:property:002": "IP Адрес", + "service:002:property:003": "Название WiFi сети", + "service:002:property:004": "Текущее время", + "service:002:property:005": "MAC адрес DHCP сервера", + "service:003": "Световой индикатор", + "service:003:property:001": "Переключатель", + "service:004": "Виртуальная служба", + "service:004:action:001": "Создать виртуальное событие", + "service:004:event:001": "Произошло виртуальное событие", + "service:004:property:001": "Название события" + }, + "zh-Hant": { + "service:001": "設備信息", + "service:001:property:003": "設備ID", + "service:001:property:005": "序號 (SN)", + "service:002": "網關", + "service:002:event:001": "網路發生變化", + "service:002:event:002": "網路發生變化", + "service:002:property:001": "接入方式", + "service:002:property:001:valuelist:000": "有線", + "service:002:property:001:valuelist:001": "5G 無線", + "service:002:property:001:valuelist:002": "2.4G 無線", + "service:002:property:002": "IP地址", + "service:002:property:003": "WiFi網路名稱", + "service:002:property:004": "當前時間", + "service:002:property:005": "DHCP伺服器MAC地址", + "service:003": "指示燈", + "service:003:property:001": "開關", + "service:004": "虛擬服務", + "service:004:action:001": "產生虛擬事件", + "service:004:event:001": "虛擬事件發生", + "service:004:property:001": "事件名稱" + } + }, + "urn:miot-spec-v2:device:lock:0000A038:loock-t2pv1": { + "zh-Hans": { + "service:003:property:1021:valuelist:000": "已上锁", + "service:003:property:1021:valuelist:001": "已上锁(童锁)", + "service:003:property:1021:valuelist:002": "已上锁(反锁)", + "service:003:property:1021:valuelist:003": "已上锁(反锁+童锁)", + "service:003:property:1021:valuelist:004": "已开锁", + "service:003:property:1021:valuelist:008": "门未关(门超时未关)", + "service:003:property:1021:valuelist:012": "门虚掩" + } + }, + "urn:miot-spec-v2:device:plant-monitor:0000A030:hhcc-v1": { + "en": { + "service:002:property:001": "Soil Moisture" + }, + "zh-Hans": { + "service:002:property:001": "土壤湿度", + "service:002:property:003": "光照强度" + } + }, + "urn:miot-spec-v2:device:switch:0000A003:lumi-acn040": { + "en": { + "service:011": "Right Button On and Off", + "service:011:property:001": "Right Button On and Off", + "service:015:action:001": "Left Button Identify", + "service:016:action:001": "Middle Button Identify", + "service:017:action:001": "Right Button Identify" + }, + "zh-Hans": { + "service:015:action:001": "左键确认", + "service:016:action:001": "中键确认", + "service:017:action:001": "右键确认" + } + } +} diff --git a/custom_components/xiaomi_home/miot/specs/spec_modify.yaml b/custom_components/xiaomi_home/miot/specs/spec_modify.yaml index c9cf170..657c56a 100644 --- a/custom_components/xiaomi_home/miot/specs/spec_modify.yaml +++ b/custom_components/xiaomi_home/miot/specs/spec_modify.yaml @@ -48,13 +48,19 @@ urn:miot-spec-v2:device:bath-heater:0000A028:xiaomi-s1:1: prop.4.4: name: fan-level-ventilation urn:miot-spec-v2:device:fan:0000A005:dmaker-p5:1: - prop.2.6: + prop.2.4: name: fan-level-a urn:miot-spec-v2:device:fan:0000A005:xiaomi-p51:1: prop.2.2: name: fan-level-a +urn:miot-spec-v2:device:fan:0000A005:zhimi-sa1:3: + prop.2.2: + name: fan-level-a urn:miot-spec-v2:device:fan:0000A005:zhimi-v3:3: - prop.2.6: + prop.2.2: + name: fan-level-a +urn:miot-spec-v2:device:fan:0000A005:zhimi-za4:3: + prop.2.2: name: fan-level-a urn:miot-spec-v2:device:gateway:0000A019:lumi-mcn001:1: prop.2.1: @@ -90,6 +96,9 @@ urn:miot-spec-v2:device:gateway:0000A019:xiaomi-hub1:3: urn:miot-spec-v2:device: urn:miot-spec-v2:device:kettle:0000A009:yunmi-r3:1: prop.3.1: unit: ppm +urn:miot-spec-v2:device:light:0000A001:shhf-sfla10:1: + prop.8.9: + name: wind-reverse urn:miot-spec-v2:device:light:0000A001:shhf-sfla12:1: prop.8.11: name: on-a @@ -172,6 +181,13 @@ urn:miot-spec-v2:device:safe-box:0000A042:loock-v1:1: prop.5.1: name: contact-state expr: src_value!=1 +urn:miot-spec-v2:device:switch:0000A003:lxzn-cbcsmj:1:0000D00D: + prop.3.1: + expr: round(src_value/100, 2) + prop.3.2: + expr: round(src_value/1000, 2) + prop.3.3: + expr: round(src_value/10, 1) urn:miot-spec-v2:device:thermostat:0000A031:suittc-wk168:1: prop.2.3: value-list: diff --git a/doc/README_zh.md b/doc/README_zh.md index b31930e..2fd315b 100644 --- a/doc/README_zh.md +++ b/doc/README_zh.md @@ -353,7 +353,7 @@ instance code 为 MIoT-Spec-V2 实例代码,格式如下: ``` service: # 服务 service::property: # 属性 -service::property::valuelist: # 属性取值列表的值 +service::property::valuelist: # 属性取值列表的索引值 service::event: # 事件 service::action: # 方法 ``` diff --git a/test/check_rule_format.py b/test/check_rule_format.py index 4a13e4b..d4bf956 100644 --- a/test/check_rule_format.py +++ b/test/check_rule_format.py @@ -18,6 +18,8 @@ SPEC_BOOL_TRANS_FILE = path.join( ROOT_PATH, '../custom_components/xiaomi_home/miot/specs/bool_trans.yaml') SPEC_FILTER_FILE = path.join( ROOT_PATH, '../custom_components/xiaomi_home/miot/specs/spec_filter.yaml') +SPEC_MULTI_LANG_FILE = path.join( + ROOT_PATH, '../custom_components/xiaomi_home/miot/specs/multi_lang.json') SPEC_ADD_FILE = path.join( ROOT_PATH, '../custom_components/xiaomi_home/miot/specs/spec_add.json') SPEC_MODIFY_FILE = path.join( @@ -140,6 +142,14 @@ def bool_trans(d: dict) -> bool: return True +def multi_lang(data: dict) -> bool: + """dict[str, dict[str, dict[str, str]]]""" + for key in data.keys(): + if key.count(':') != 5: + return False + return nested_3_dict_str_str(data) + + def spec_add(data: dict) -> bool: """dict[str, list[dict[str, int| str | list]]]""" if not isinstance(data, dict): @@ -304,6 +314,10 @@ def sort_spec_add(file_path: str): return dict(sorted(filter_data.items())) +def sort_multi_lang(file_path: str): + return sort_spec_add(file_path) + + def sort_spec_modify(file_path: str): filter_data = load_yaml_file(file_path=file_path) assert isinstance(filter_data, dict), f'{file_path} format error' @@ -326,6 +340,14 @@ def test_spec_filter(): assert spec_filter(data), f'{SPEC_FILTER_FILE} format error' +@pytest.mark.github +def test_multi_lang(): + data = load_json_file(SPEC_MULTI_LANG_FILE) + assert isinstance(data, dict) + assert data, f'load {SPEC_MULTI_LANG_FILE} failed' + assert multi_lang(data), f'{SPEC_MULTI_LANG_FILE} format error' + + @pytest.mark.github def test_spec_add(): data = load_json_file(SPEC_ADD_FILE) @@ -418,6 +440,12 @@ def test_miot_data_sort(): f'{SPEC_FILTER_FILE} not sorted, goto project root path' ' and run the following command sorting, ', 'pytest -s -v -m update ./test/check_rule_format.py') + assert json.dumps( + load_json_file(file_path=SPEC_MULTI_LANG_FILE)) == json.dumps( + sort_multi_lang(file_path=SPEC_MULTI_LANG_FILE)), ( + f'{SPEC_MULTI_LANG_FILE} not sorted, goto project root path' + ' and run the following command sorting, ', + 'pytest -s -v -m update ./test/check_rule_format.py') assert json.dumps(load_json_file(file_path=SPEC_ADD_FILE)) == json.dumps( sort_spec_add(file_path=SPEC_ADD_FILE)), ( f'{SPEC_ADD_FILE} not sorted, goto project root path' @@ -438,6 +466,8 @@ def test_sort_spec_data(): sort_data = sort_spec_filter(file_path=SPEC_FILTER_FILE) save_yaml_file(file_path=SPEC_FILTER_FILE, data=sort_data) _LOGGER.info('%s formatted.', SPEC_FILTER_FILE) + sort_data = sort_multi_lang(file_path=SPEC_MULTI_LANG_FILE) + save_json_file(file_path=SPEC_MULTI_LANG_FILE, data=sort_data) sort_data = sort_spec_add(file_path=SPEC_ADD_FILE) save_json_file(file_path=SPEC_ADD_FILE, data=sort_data) _LOGGER.info('%s formatted.', SPEC_ADD_FILE)