mirror of
https://github.com/XiaoMi/ha_xiaomi_home.git
synced 2025-03-31 14:55:31 +08:00
chore: Improve multi-language translation actions (#256)
* test: check bool trans integrity * feat: add tools to update and format data * style: sort data * feat: update check_rule_format.py * style: remove unuse SUPPORTED_PLATFORMS item * test: check spec rule sort * fix: fix py import * feat: remove unuse code * feat: add spec data sort
This commit is contained in:
parent
b955c199fc
commit
571483b302
@ -67,24 +67,16 @@ SPEC_STD_LIB_EFFECTIVE_TIME = 3600*24*14
|
||||
MANUFACTURER_EFFECTIVE_TIME = 3600*24*14
|
||||
|
||||
SUPPORTED_PLATFORMS: list = [
|
||||
# 'alarm_control_panel',
|
||||
'binary_sensor',
|
||||
'button',
|
||||
'climate',
|
||||
# 'camera',
|
||||
# 'conversation',
|
||||
'cover',
|
||||
# 'device_tracker',
|
||||
'event',
|
||||
'fan',
|
||||
'humidifier',
|
||||
'light',
|
||||
# 'lock',
|
||||
# 'media_player',
|
||||
'notify',
|
||||
'number',
|
||||
# 'remote',
|
||||
# 'scene',
|
||||
'select',
|
||||
'sensor',
|
||||
'switch',
|
||||
@ -107,17 +99,17 @@ SUPPORT_CENTRAL_GATEWAY_CTRL: list = ['cn']
|
||||
|
||||
DEFAULT_INTEGRATION_LANGUAGE: str = 'en'
|
||||
INTEGRATION_LANGUAGES = {
|
||||
'zh-Hans': '简体中文',
|
||||
'zh-Hant': '繁體中文',
|
||||
'en': 'English',
|
||||
'de': 'Deutsch',
|
||||
'en': 'English',
|
||||
'es': 'Español',
|
||||
'fr': 'Français',
|
||||
'ja': '日本語',
|
||||
'nl': 'Nederlands',
|
||||
'pt': 'Português',
|
||||
'pt-BR': 'Português (Brasil)',
|
||||
'ru': 'Русский',
|
||||
'nl': 'Nederlands'
|
||||
'zh-Hans': '简体中文',
|
||||
'zh-Hant': '繁體中文'
|
||||
}
|
||||
|
||||
DEFAULT_CTRL_MODE: str = 'auto'
|
||||
|
@ -3,14 +3,20 @@
|
||||
"urn:miot-spec-v2:property:air-cooler:000000EB": "open_close",
|
||||
"urn:miot-spec-v2:property:alarm:00000012": "open_close",
|
||||
"urn:miot-spec-v2:property:anion:00000025": "open_close",
|
||||
"urn:miot-spec-v2:property:anti-fake:00000130": "yes_no",
|
||||
"urn:miot-spec-v2:property:arrhythmia:000000B4": "yes_no",
|
||||
"urn:miot-spec-v2:property:auto-cleanup:00000124": "open_close",
|
||||
"urn:miot-spec-v2:property:auto-deodorization:00000125": "open_close",
|
||||
"urn:miot-spec-v2:property:auto-keep-warm:0000002B": "open_close",
|
||||
"urn:miot-spec-v2:property:automatic-feeding:000000F0": "open_close",
|
||||
"urn:miot-spec-v2:property:blow:000000CD": "open_close",
|
||||
"urn:miot-spec-v2:property:card-insertion-state:00000106": "yes_no",
|
||||
"urn:miot-spec-v2:property:contact-state:0000007C": "contact_state",
|
||||
"urn:miot-spec-v2:property:current-physical-control-lock:00000099": "open_close",
|
||||
"urn:miot-spec-v2:property:delay:0000014F": "yes_no",
|
||||
"urn:miot-spec-v2:property:deodorization:000000C6": "open_close",
|
||||
"urn:miot-spec-v2:property:dns-auto-mode:000000DC": "open_close",
|
||||
"urn:miot-spec-v2:property:current-physical-control-lock:00000099": "open_close",
|
||||
"urn:miot-spec-v2:property:driving-status:000000B9": "yes_no",
|
||||
"urn:miot-spec-v2:property:dryer:00000027": "open_close",
|
||||
"urn:miot-spec-v2:property:eco:00000024": "open_close",
|
||||
"urn:miot-spec-v2:property:glimmer-full-color:00000089": "open_close",
|
||||
@ -20,17 +26,25 @@
|
||||
"urn:miot-spec-v2:property:horizontal-swing:00000017": "open_close",
|
||||
"urn:miot-spec-v2:property:hot-water-recirculation:0000011C": "open_close",
|
||||
"urn:miot-spec-v2:property:image-distortion-correction:0000010F": "open_close",
|
||||
"urn:miot-spec-v2:property:mute:00000040": "open_close",
|
||||
"urn:miot-spec-v2:property:local-storage:0000011E": "yes_no",
|
||||
"urn:miot-spec-v2:property:motion-detection:00000056": "open_close",
|
||||
"urn:miot-spec-v2:property:motion-state:0000007D": "motion_state",
|
||||
"urn:miot-spec-v2:property:motion-tracking:0000008A": "open_close",
|
||||
"urn:miot-spec-v2:property:motor-reverse:00000072": "yes_no",
|
||||
"urn:miot-spec-v2:property:mute:00000040": "open_close",
|
||||
"urn:miot-spec-v2:property:off-delay:00000053": "open_close",
|
||||
"urn:miot-spec-v2:property:on:00000006": "open_close",
|
||||
"urn:miot-spec-v2:property:physical-controls-locked:0000001D": "open_close",
|
||||
"urn:miot-spec-v2:property:plasma:00000132": "yes_no",
|
||||
"urn:miot-spec-v2:property:preheat:00000103": "open_close",
|
||||
"urn:miot-spec-v2:property:seating-state:000000B8": "yes_no",
|
||||
"urn:miot-spec-v2:property:silent-execution:000000FB": "yes_no",
|
||||
"urn:miot-spec-v2:property:sleep-aid-mode:0000010B": "open_close",
|
||||
"urn:miot-spec-v2:property:sleep-mode:00000028": "open_close",
|
||||
"urn:miot-spec-v2:property:snore-state:0000012A": "yes_no",
|
||||
"urn:miot-spec-v2:property:soft-wind:000000CF": "open_close",
|
||||
"urn:miot-spec-v2:property:speed-control:000000E8": "open_close",
|
||||
"urn:miot-spec-v2:property:submersion-state:0000007E": "yes_no",
|
||||
"urn:miot-spec-v2:property:time-watermark:00000087": "open_close",
|
||||
"urn:miot-spec-v2:property:un-straight-blowing:00000100": "open_close",
|
||||
"urn:miot-spec-v2:property:uv:00000029": "open_close",
|
||||
@ -43,41 +57,19 @@
|
||||
"urn:miot-spec-v2:property:wdr-mode:00000088": "open_close",
|
||||
"urn:miot-spec-v2:property:wet:0000002A": "open_close",
|
||||
"urn:miot-spec-v2:property:wifi-band-combine:000000E0": "open_close",
|
||||
"urn:miot-spec-v2:property:anti-fake:00000130": "yes_no",
|
||||
"urn:miot-spec-v2:property:arrhythmia:000000B4": "yes_no",
|
||||
"urn:miot-spec-v2:property:card-insertion-state:00000106": "yes_no",
|
||||
"urn:miot-spec-v2:property:delay:0000014F": "yes_no",
|
||||
"urn:miot-spec-v2:property:driving-status:000000B9": "yes_no",
|
||||
"urn:miot-spec-v2:property:local-storage:0000011E": "yes_no",
|
||||
"urn:miot-spec-v2:property:motor-reverse:00000072": "yes_no",
|
||||
"urn:miot-spec-v2:property:plasma:00000132": "yes_no",
|
||||
"urn:miot-spec-v2:property:seating-state:000000B8": "yes_no",
|
||||
"urn:miot-spec-v2:property:silent-execution:000000FB": "yes_no",
|
||||
"urn:miot-spec-v2:property:snore-state:0000012A": "yes_no",
|
||||
"urn:miot-spec-v2:property:submersion-state:0000007E": "yes_no",
|
||||
"urn:miot-spec-v2:property:wifi-ssid-hidden:000000E3": "yes_no",
|
||||
"urn:miot-spec-v2:property:wind-reverse:00000117": "yes_no",
|
||||
"urn:miot-spec-v2:property:motion-state:0000007D": "motion_state",
|
||||
"urn:miot-spec-v2:property:contact-state:0000007C": "contact_state"
|
||||
"urn:miot-spec-v2:property:wind-reverse:00000117": "yes_no"
|
||||
},
|
||||
"translate": {
|
||||
"default": {
|
||||
"zh-Hans": {
|
||||
"true": "真",
|
||||
"false": "假"
|
||||
},
|
||||
"zh-Hant": {
|
||||
"true": "真",
|
||||
"false": "假"
|
||||
"de": {
|
||||
"true": "Wahr",
|
||||
"false": "Falsch"
|
||||
},
|
||||
"en": {
|
||||
"true": "True",
|
||||
"false": "False"
|
||||
},
|
||||
"de": {
|
||||
"true": "Wahr",
|
||||
"false": "Falsch"
|
||||
},
|
||||
"es": {
|
||||
"true": "Verdadero",
|
||||
"false": "Falso"
|
||||
@ -86,32 +78,44 @@
|
||||
"true": "Vrai",
|
||||
"false": "Faux"
|
||||
},
|
||||
"ja": {
|
||||
"true": "真",
|
||||
"false": "偽"
|
||||
},
|
||||
"nl": {
|
||||
"true": "True",
|
||||
"false": "False"
|
||||
},
|
||||
"pt": {
|
||||
"true": "True",
|
||||
"false": "False"
|
||||
},
|
||||
"pt-BR": {
|
||||
"true": "True",
|
||||
"false": "False"
|
||||
},
|
||||
"ru": {
|
||||
"true": "Истина",
|
||||
"false": "Ложь"
|
||||
},
|
||||
"ja": {
|
||||
"zh-Hans": {
|
||||
"true": "真",
|
||||
"false": "偽"
|
||||
"false": "假"
|
||||
},
|
||||
"zh-Hant": {
|
||||
"true": "真",
|
||||
"false": "假"
|
||||
}
|
||||
},
|
||||
"open_close": {
|
||||
"zh-Hans": {
|
||||
"true": "开启",
|
||||
"false": "关闭"
|
||||
},
|
||||
"zh-Hant": {
|
||||
"true": "開啟",
|
||||
"false": "關閉"
|
||||
"de": {
|
||||
"true": "Öffnen",
|
||||
"false": "Schließen"
|
||||
},
|
||||
"en": {
|
||||
"true": "Open",
|
||||
"false": "Close"
|
||||
},
|
||||
"de": {
|
||||
"true": "Öffnen",
|
||||
"false": "Schließen"
|
||||
},
|
||||
"es": {
|
||||
"true": "Abierto",
|
||||
"false": "Cerrado"
|
||||
@ -120,32 +124,44 @@
|
||||
"true": "Ouvert",
|
||||
"false": "Fermer"
|
||||
},
|
||||
"ja": {
|
||||
"true": "開く",
|
||||
"false": "閉じる"
|
||||
},
|
||||
"nl": {
|
||||
"true": "Open",
|
||||
"false": "Dicht"
|
||||
},
|
||||
"pt": {
|
||||
"true": "Aberto",
|
||||
"false": "Fechado"
|
||||
},
|
||||
"pt-BR": {
|
||||
"true": "Aberto",
|
||||
"false": "Fechado"
|
||||
},
|
||||
"ru": {
|
||||
"true": "Открыть",
|
||||
"false": "Закрыть"
|
||||
},
|
||||
"ja": {
|
||||
"true": "開く",
|
||||
"false": "閉じる"
|
||||
"zh-Hans": {
|
||||
"true": "开启",
|
||||
"false": "关闭"
|
||||
},
|
||||
"zh-Hant": {
|
||||
"true": "開啟",
|
||||
"false": "關閉"
|
||||
}
|
||||
},
|
||||
"yes_no": {
|
||||
"zh-Hans": {
|
||||
"true": "是",
|
||||
"false": "否"
|
||||
},
|
||||
"zh-Hant": {
|
||||
"true": "是",
|
||||
"false": "否"
|
||||
"de": {
|
||||
"true": "Ja",
|
||||
"false": "Nein"
|
||||
},
|
||||
"en": {
|
||||
"true": "Yes",
|
||||
"false": "No"
|
||||
},
|
||||
"de": {
|
||||
"true": "Ja",
|
||||
"false": "Nein"
|
||||
},
|
||||
"es": {
|
||||
"true": "Sí",
|
||||
"false": "No"
|
||||
@ -154,32 +170,44 @@
|
||||
"true": "Oui",
|
||||
"false": "Non"
|
||||
},
|
||||
"ja": {
|
||||
"true": "はい",
|
||||
"false": "いいえ"
|
||||
},
|
||||
"nl": {
|
||||
"true": "Ja",
|
||||
"false": "Nee"
|
||||
},
|
||||
"pt": {
|
||||
"true": "Sim",
|
||||
"false": "Não"
|
||||
},
|
||||
"pt-BR": {
|
||||
"true": "Sim",
|
||||
"false": "Não"
|
||||
},
|
||||
"ru": {
|
||||
"true": "Да",
|
||||
"false": "Нет"
|
||||
},
|
||||
"ja": {
|
||||
"true": "はい",
|
||||
"false": "いいえ"
|
||||
"zh-Hans": {
|
||||
"true": "是",
|
||||
"false": "否"
|
||||
},
|
||||
"zh-Hant": {
|
||||
"true": "是",
|
||||
"false": "否"
|
||||
}
|
||||
},
|
||||
"motion_state": {
|
||||
"zh-Hans": {
|
||||
"true": "有人",
|
||||
"false": "无人"
|
||||
},
|
||||
"zh-Hant": {
|
||||
"true": "有人",
|
||||
"false": "無人"
|
||||
"de": {
|
||||
"true": "Bewegung erkannt",
|
||||
"false": "Keine Bewegung erkannt"
|
||||
},
|
||||
"en": {
|
||||
"true": "Motion Detected",
|
||||
"false": "No Motion Detected"
|
||||
},
|
||||
"de": {
|
||||
"true": "Bewegung erkannt",
|
||||
"false": "Keine Bewegung erkannt"
|
||||
},
|
||||
"es": {
|
||||
"true": "Movimiento detectado",
|
||||
"false": "No se detecta movimiento"
|
||||
@ -188,32 +216,44 @@
|
||||
"true": "Mouvement détecté",
|
||||
"false": "Aucun mouvement détecté"
|
||||
},
|
||||
"ja": {
|
||||
"true": "動きを検知",
|
||||
"false": "動きが検出されません"
|
||||
},
|
||||
"nl": {
|
||||
"true": "Contact",
|
||||
"false": "Geen contact"
|
||||
},
|
||||
"pt": {
|
||||
"true": "Contato",
|
||||
"false": "Sem contato"
|
||||
},
|
||||
"pt-BR": {
|
||||
"true": "Contato",
|
||||
"false": "Sem contato"
|
||||
},
|
||||
"ru": {
|
||||
"true": "Обнаружено движение",
|
||||
"false": "Движение не обнаружено"
|
||||
},
|
||||
"ja": {
|
||||
"true": "動きを検知",
|
||||
"false": "動きが検出されません"
|
||||
"zh-Hans": {
|
||||
"true": "有人",
|
||||
"false": "无人"
|
||||
},
|
||||
"zh-Hant": {
|
||||
"true": "有人",
|
||||
"false": "無人"
|
||||
}
|
||||
},
|
||||
"contact_state": {
|
||||
"zh-Hans": {
|
||||
"true": "接触",
|
||||
"false": "分离"
|
||||
},
|
||||
"zh-Hant": {
|
||||
"true": "接觸",
|
||||
"false": "分離"
|
||||
"de": {
|
||||
"true": "Kontakt",
|
||||
"false": "Kein Kontakt"
|
||||
},
|
||||
"en": {
|
||||
"true": "Contact",
|
||||
"false": "No Contact"
|
||||
},
|
||||
"de": {
|
||||
"true": "Kontakt",
|
||||
"false": "Kein Kontakt"
|
||||
},
|
||||
"es": {
|
||||
"true": "Contacto",
|
||||
"false": "Sin contacto"
|
||||
@ -222,13 +262,33 @@
|
||||
"true": "Contact",
|
||||
"false": "Pas de contact"
|
||||
},
|
||||
"ja": {
|
||||
"true": "接触",
|
||||
"false": "非接触"
|
||||
},
|
||||
"nl": {
|
||||
"true": "Contact",
|
||||
"false": "Geen contact"
|
||||
},
|
||||
"pt": {
|
||||
"true": "Contato",
|
||||
"false": "Sem contato"
|
||||
},
|
||||
"pt-BR": {
|
||||
"true": "Contato",
|
||||
"false": "Sem contato"
|
||||
},
|
||||
"ru": {
|
||||
"true": "Контакт",
|
||||
"false": "Нет контакта"
|
||||
},
|
||||
"ja": {
|
||||
"zh-Hans": {
|
||||
"true": "接触",
|
||||
"false": "非接触"
|
||||
"false": "分离"
|
||||
},
|
||||
"zh-Hant": {
|
||||
"true": "接觸",
|
||||
"false": "分離"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,27 @@
|
||||
{
|
||||
"urn:miot-spec-v2:device:gateway:0000A019:xiaomi-hub1": {
|
||||
"de": {
|
||||
"service:001": "Geräteinformationen",
|
||||
"service:001:property:003": "Geräte-ID",
|
||||
"service:001:property:005": "Seriennummer (SN)",
|
||||
"service:002": "Gateway",
|
||||
"service:002:event:001": "Netzwerk geändert",
|
||||
"service:002:event:002": "Netzwerk geändert",
|
||||
"service:002:property:001": "Zugriffsmethode",
|
||||
"service:002:property:001:valuelist:000": "Kabelgebunden",
|
||||
"service:002:property:001:valuelist:001": "5G Drahtlos",
|
||||
"service:002:property:001:valuelist:002": "2.4G Drahtlos",
|
||||
"service:002:property:002": "IP-Adresse",
|
||||
"service:002:property:003": "WiFi-Netzwerkname",
|
||||
"service:002:property:004": "Aktuelle Zeit",
|
||||
"service:002:property:005": "DHCP-Server-MAC-Adresse",
|
||||
"service:003": "Anzeigelampe",
|
||||
"service:003:property:001": "Schalter",
|
||||
"service:004": "Virtueller Dienst",
|
||||
"service:004:action:001": "Virtuelles Ereignis erzeugen",
|
||||
"service:004:event:001": "Virtuelles Ereignis aufgetreten",
|
||||
"service:004:property:001": "Ereignisname"
|
||||
},
|
||||
"en": {
|
||||
"service:001": "Device Information",
|
||||
"service:001:property:003": "Device ID",
|
||||
@ -66,50 +88,6 @@
|
||||
"service:004:event:001": "Événement virtuel survenu",
|
||||
"service:004:property:001": "Nom de l'événement"
|
||||
},
|
||||
"ru": {
|
||||
"service:001": "Информация об устройстве",
|
||||
"service:001:property:003": "ID устройства",
|
||||
"service:001:property:005": "Серийный номер (SN)",
|
||||
"service:002": "Шлюз",
|
||||
"service:002:event:001": "Сеть изменена",
|
||||
"service:002:event:002": "Сеть изменена",
|
||||
"service:002:property:001": "Метод доступа",
|
||||
"service:002:property:001:valuelist:000": "Проводной",
|
||||
"service:002:property:001:valuelist:001": "5G Беспроводной",
|
||||
"service:002:property:001:valuelist:002": "2.4G Беспроводной",
|
||||
"service:002:property:002": "IP Адрес",
|
||||
"service:002:property:003": "Название WiFi сети",
|
||||
"service:002:property:004": "Текущее время",
|
||||
"service:002:property:005": "MAC адрес DHCP сервера",
|
||||
"service:003": "Световой индикатор",
|
||||
"service:003:property:001": "Переключатель",
|
||||
"service:004": "Виртуальная служба",
|
||||
"service:004:action:001": "Создать виртуальное событие",
|
||||
"service:004:event:001": "Произошло виртуальное событие",
|
||||
"service:004:property:001": "Название события"
|
||||
},
|
||||
"de": {
|
||||
"service:001": "Geräteinformationen",
|
||||
"service:001:property:003": "Geräte-ID",
|
||||
"service:001:property:005": "Seriennummer (SN)",
|
||||
"service:002": "Gateway",
|
||||
"service:002:event:001": "Netzwerk geändert",
|
||||
"service:002:event:002": "Netzwerk geändert",
|
||||
"service:002:property:001": "Zugriffsmethode",
|
||||
"service:002:property:001:valuelist:000": "Kabelgebunden",
|
||||
"service:002:property:001:valuelist:001": "5G Drahtlos",
|
||||
"service:002:property:001:valuelist:002": "2.4G Drahtlos",
|
||||
"service:002:property:002": "IP-Adresse",
|
||||
"service:002:property:003": "WiFi-Netzwerkname",
|
||||
"service:002:property:004": "Aktuelle Zeit",
|
||||
"service:002:property:005": "DHCP-Server-MAC-Adresse",
|
||||
"service:003": "Anzeigelampe",
|
||||
"service:003:property:001": "Schalter",
|
||||
"service:004": "Virtueller Dienst",
|
||||
"service:004:action:001": "Virtuelles Ereignis erzeugen",
|
||||
"service:004:event:001": "Virtuelles Ereignis aufgetreten",
|
||||
"service:004:property:001": "Ereignisname"
|
||||
},
|
||||
"ja": {
|
||||
"service:001": "デバイス情報",
|
||||
"service:001:property:003": "デバイスID",
|
||||
@ -132,6 +110,28 @@
|
||||
"service:004:event:001": "バーチャルイベントが発生しました",
|
||||
"service:004:property:001": "イベント名"
|
||||
},
|
||||
"ru": {
|
||||
"service:001": "Информация об устройстве",
|
||||
"service:001:property:003": "ID устройства",
|
||||
"service:001:property:005": "Серийный номер (SN)",
|
||||
"service:002": "Шлюз",
|
||||
"service:002:event:001": "Сеть изменена",
|
||||
"service:002:event:002": "Сеть изменена",
|
||||
"service:002:property:001": "Метод доступа",
|
||||
"service:002:property:001:valuelist:000": "Проводной",
|
||||
"service:002:property:001:valuelist:001": "5G Беспроводной",
|
||||
"service:002:property:001:valuelist:002": "2.4G Беспроводной",
|
||||
"service:002:property:002": "IP Адрес",
|
||||
"service:002:property:003": "Название WiFi сети",
|
||||
"service:002:property:004": "Текущее время",
|
||||
"service:002:property:005": "MAC адрес DHCP сервера",
|
||||
"service:003": "Световой индикатор",
|
||||
"service:003:property:001": "Переключатель",
|
||||
"service:004": "Виртуальная служба",
|
||||
"service:004:action:001": "Создать виртуальное событие",
|
||||
"service:004:event:001": "Произошло виртуальное событие",
|
||||
"service:004:property:001": "Название события"
|
||||
},
|
||||
"zh-Hant": {
|
||||
"service:001": "設備信息",
|
||||
"service:001:property:003": "設備ID",
|
||||
|
@ -1,26 +1,22 @@
|
||||
{
|
||||
"urn:miot-spec-v2:device:health-pot:0000A051:chunmi-a1": {
|
||||
"urn:miot-spec-v2:device:air-purifier:0000A007:zhimi-ma4": {
|
||||
"properties": [
|
||||
"9.*",
|
||||
"13.*",
|
||||
"15.*"
|
||||
],
|
||||
"services": [
|
||||
"5"
|
||||
"10"
|
||||
]
|
||||
},
|
||||
"urn:miot-spec-v2:device:curtain:0000A00C:lumi-hmcn01": {
|
||||
"properties": [
|
||||
"5.1"
|
||||
],
|
||||
"services": [
|
||||
"4",
|
||||
"7",
|
||||
"8"
|
||||
],
|
||||
"properties": [
|
||||
"5.1"
|
||||
]
|
||||
},
|
||||
"urn:miot-spec-v2:device:light:0000A001:philips-strip3": {
|
||||
"services": [
|
||||
"1",
|
||||
"3"
|
||||
],
|
||||
"properties": [
|
||||
"2.2"
|
||||
]
|
||||
},
|
||||
"urn:miot-spec-v2:device:gateway:0000A019:xiaomi-hub1": {
|
||||
@ -28,10 +24,18 @@
|
||||
"2.1"
|
||||
]
|
||||
},
|
||||
"urn:miot-spec-v2:device:motion-sensor:0000A014:xiaomi-pir1": {
|
||||
"urn:miot-spec-v2:device:health-pot:0000A051:chunmi-a1": {
|
||||
"services": [
|
||||
"5"
|
||||
]
|
||||
},
|
||||
"urn:miot-spec-v2:device:light:0000A001:philips-strip3": {
|
||||
"properties": [
|
||||
"2.2"
|
||||
],
|
||||
"services": [
|
||||
"1",
|
||||
"5"
|
||||
"3"
|
||||
]
|
||||
},
|
||||
"urn:miot-spec-v2:device:light:0000A001:yeelink-color2": {
|
||||
@ -50,14 +54,10 @@
|
||||
"3"
|
||||
]
|
||||
},
|
||||
"urn:miot-spec-v2:device:air-purifier:0000A007:zhimi-ma4": {
|
||||
"urn:miot-spec-v2:device:motion-sensor:0000A014:xiaomi-pir1": {
|
||||
"services": [
|
||||
"10"
|
||||
],
|
||||
"properties": [
|
||||
"9.*",
|
||||
"13.*",
|
||||
"15.*"
|
||||
"1",
|
||||
"5"
|
||||
]
|
||||
}
|
||||
}
|
@ -6,9 +6,20 @@ from typing import Optional
|
||||
import pytest
|
||||
import yaml
|
||||
|
||||
SOURCE_PATH: str = path.dirname(path.abspath(__file__))
|
||||
TRANS_RELATIVE_PATH: str = '../custom_components/xiaomi_home/translations'
|
||||
MIOT_I18N_RELATIVE_PATH: str = '../custom_components/xiaomi_home/miot/i18n'
|
||||
ROOT_PATH: str = path.dirname(path.abspath(__file__))
|
||||
TRANS_RELATIVE_PATH: str = path.join(
|
||||
ROOT_PATH, '../custom_components/xiaomi_home/translations')
|
||||
MIOT_I18N_RELATIVE_PATH: str = path.join(
|
||||
ROOT_PATH, '../custom_components/xiaomi_home/miot/i18n')
|
||||
SPEC_BOOL_TRANS_FILE = path.join(
|
||||
ROOT_PATH,
|
||||
'../custom_components/xiaomi_home/miot/specs/bool_trans.json')
|
||||
SPEC_MULTI_LANG_FILE = path.join(
|
||||
ROOT_PATH,
|
||||
'../custom_components/xiaomi_home/miot/specs/multi_lang.json')
|
||||
SPEC_FILTER_FILE = path.join(
|
||||
ROOT_PATH,
|
||||
'../custom_components/xiaomi_home/miot/specs/spec_filter.json')
|
||||
|
||||
|
||||
def load_json_file(file_path: str) -> Optional[dict]:
|
||||
@ -23,6 +34,11 @@ def load_json_file(file_path: str) -> Optional[dict]:
|
||||
return None
|
||||
|
||||
|
||||
def save_json_file(file_path: str, data: dict) -> None:
|
||||
with open(file_path, 'w', encoding='utf-8') as file:
|
||||
json.dump(data, file, ensure_ascii=False, indent=4)
|
||||
|
||||
|
||||
def load_yaml_file(file_path: str) -> Optional[dict]:
|
||||
try:
|
||||
with open(file_path, 'r', encoding='utf-8') as file:
|
||||
@ -98,6 +114,16 @@ def bool_trans(d: dict) -> bool:
|
||||
return False
|
||||
if not nested_3_dict_str_str(d['translate']):
|
||||
return False
|
||||
default_trans: dict = d['translate'].pop('default')
|
||||
if not default_trans:
|
||||
print('default trans is empty')
|
||||
return False
|
||||
default_keys: set[str] = set(default_trans.keys())
|
||||
for key, trans in d['translate'].items():
|
||||
trans_keys: set[str] = set(trans.keys())
|
||||
if set(trans.keys()) != default_keys:
|
||||
print('bool trans inconsistent', key, default_keys, trans_keys)
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
@ -125,54 +151,69 @@ def compare_dict_structure(dict1: dict, dict2: dict) -> bool:
|
||||
return True
|
||||
|
||||
|
||||
def sort_bool_trans(file_path: str):
|
||||
trans_data: dict = load_json_file(file_path=file_path)
|
||||
trans_data['data'] = dict(sorted(trans_data['data'].items()))
|
||||
for key, trans in trans_data['translate'].items():
|
||||
trans_data['translate'][key] = dict(sorted(trans.items()))
|
||||
return trans_data
|
||||
|
||||
|
||||
def sort_multi_lang(file_path: str):
|
||||
multi_lang: dict = load_json_file(file_path=file_path)
|
||||
multi_lang = dict(sorted(multi_lang.items()))
|
||||
for urn, trans in multi_lang.items():
|
||||
multi_lang[urn] = dict(sorted(trans.items()))
|
||||
for lang, spec in multi_lang[urn].items():
|
||||
multi_lang[urn][lang] = dict(sorted(spec.items()))
|
||||
return multi_lang
|
||||
|
||||
|
||||
def sort_spec_filter(file_path: str):
|
||||
filter_data: dict = load_json_file(file_path=file_path)
|
||||
filter_data = dict(sorted(filter_data.items()))
|
||||
for urn, spec in filter_data.items():
|
||||
filter_data[urn] = dict(sorted(spec.items()))
|
||||
return filter_data
|
||||
|
||||
|
||||
@pytest.mark.github
|
||||
def test_bool_trans():
|
||||
data: dict = load_json_file(
|
||||
path.join(
|
||||
SOURCE_PATH,
|
||||
'../custom_components/xiaomi_home/miot/specs/bool_trans.json'))
|
||||
assert data
|
||||
assert bool_trans(data)
|
||||
data: dict = load_json_file(SPEC_BOOL_TRANS_FILE)
|
||||
assert data, f'load {SPEC_BOOL_TRANS_FILE} failed'
|
||||
assert bool_trans(data), f'{SPEC_BOOL_TRANS_FILE} format error'
|
||||
|
||||
|
||||
@pytest.mark.github
|
||||
def test_spec_filter():
|
||||
data: dict = load_json_file(
|
||||
path.join(
|
||||
SOURCE_PATH,
|
||||
'../custom_components/xiaomi_home/miot/specs/spec_filter.json'))
|
||||
assert data
|
||||
assert spec_filter(data)
|
||||
data: dict = load_json_file(SPEC_FILTER_FILE)
|
||||
assert data, f'load {SPEC_FILTER_FILE} failed'
|
||||
assert spec_filter(data), f'{SPEC_FILTER_FILE} format error'
|
||||
|
||||
|
||||
@pytest.mark.github
|
||||
def test_multi_lang():
|
||||
data: dict = load_json_file(
|
||||
path.join(
|
||||
SOURCE_PATH,
|
||||
'../custom_components/xiaomi_home/miot/specs/multi_lang.json'))
|
||||
assert data
|
||||
assert nested_3_dict_str_str(data)
|
||||
data: dict = load_json_file(SPEC_MULTI_LANG_FILE)
|
||||
assert data, f'load {SPEC_MULTI_LANG_FILE} failed'
|
||||
assert nested_3_dict_str_str(data), f'{SPEC_MULTI_LANG_FILE} format error'
|
||||
|
||||
|
||||
@pytest.mark.github
|
||||
def test_miot_i18n():
|
||||
i18n_path: str = path.join(SOURCE_PATH, MIOT_I18N_RELATIVE_PATH)
|
||||
for file_name in listdir(i18n_path):
|
||||
file_path: str = path.join(i18n_path, file_name)
|
||||
for file_name in listdir(MIOT_I18N_RELATIVE_PATH):
|
||||
file_path: str = path.join(MIOT_I18N_RELATIVE_PATH, file_name)
|
||||
data: dict = load_json_file(file_path)
|
||||
assert data
|
||||
assert nested_3_dict_str_str(data)
|
||||
assert data, f'load {file_path} failed'
|
||||
assert nested_3_dict_str_str(data), f'{file_path} format error'
|
||||
|
||||
|
||||
@pytest.mark.github
|
||||
def test_translations():
|
||||
i18n_path: str = path.join(SOURCE_PATH, TRANS_RELATIVE_PATH)
|
||||
for file_name in listdir(i18n_path):
|
||||
file_path: str = path.join(i18n_path, file_name)
|
||||
for file_name in listdir(TRANS_RELATIVE_PATH):
|
||||
file_path: str = path.join(TRANS_RELATIVE_PATH, file_name)
|
||||
data: dict = load_json_file(file_path)
|
||||
assert data
|
||||
assert dict_str_dict(data)
|
||||
assert data, f'load {file_path} failed'
|
||||
assert dict_str_dict(data), f'{file_path} format error'
|
||||
|
||||
|
||||
@pytest.mark.github
|
||||
@ -181,30 +222,72 @@ def test_miot_lang_integrity():
|
||||
from miot.const import INTEGRATION_LANGUAGES
|
||||
integration_lang_list: list[str] = [
|
||||
f'{key}.json' for key in list(INTEGRATION_LANGUAGES.keys())]
|
||||
translations_names: set[str] = set(listdir(
|
||||
path.join(SOURCE_PATH, TRANS_RELATIVE_PATH)))
|
||||
translations_names: set[str] = set(listdir(TRANS_RELATIVE_PATH))
|
||||
assert len(translations_names) == len(integration_lang_list)
|
||||
assert translations_names == set(integration_lang_list)
|
||||
i18n_names: set[str] = set(listdir(
|
||||
path.join(SOURCE_PATH, MIOT_I18N_RELATIVE_PATH)))
|
||||
i18n_names: set[str] = set(listdir(MIOT_I18N_RELATIVE_PATH))
|
||||
assert len(i18n_names) == len(translations_names)
|
||||
assert i18n_names == translations_names
|
||||
bool_trans_data: set[str] = load_json_file(SPEC_BOOL_TRANS_FILE)
|
||||
bool_trans_names: set[str] = set(
|
||||
bool_trans_data['translate']['default'].keys())
|
||||
assert len(bool_trans_names) == len(translations_names)
|
||||
# Check translation files structure
|
||||
default_dict: dict = load_json_file(
|
||||
path.join(SOURCE_PATH, TRANS_RELATIVE_PATH, integration_lang_list[0]))
|
||||
path.join(TRANS_RELATIVE_PATH, integration_lang_list[0]))
|
||||
for name in list(integration_lang_list)[1:]:
|
||||
compare_dict: dict = load_json_file(
|
||||
path.join(SOURCE_PATH, TRANS_RELATIVE_PATH, name))
|
||||
path.join(TRANS_RELATIVE_PATH, name))
|
||||
if not compare_dict_structure(default_dict, compare_dict):
|
||||
print('compare_dict_structure failed /translations, ', name)
|
||||
assert False
|
||||
# Check i18n files structure
|
||||
default_dict = load_json_file(
|
||||
path.join(
|
||||
SOURCE_PATH, MIOT_I18N_RELATIVE_PATH, integration_lang_list[0]))
|
||||
path.join(MIOT_I18N_RELATIVE_PATH, integration_lang_list[0]))
|
||||
for name in list(integration_lang_list)[1:]:
|
||||
compare_dict: dict = load_json_file(
|
||||
path.join(SOURCE_PATH, MIOT_I18N_RELATIVE_PATH, name))
|
||||
path.join(MIOT_I18N_RELATIVE_PATH, name))
|
||||
if not compare_dict_structure(default_dict, compare_dict):
|
||||
print('compare_dict_structure failed /miot/i18n, ', name)
|
||||
assert False
|
||||
|
||||
|
||||
@pytest.mark.github
|
||||
def test_miot_data_sort():
|
||||
# pylint: disable=import-outside-toplevel
|
||||
from miot.const import INTEGRATION_LANGUAGES
|
||||
sort_langs: dict = dict(sorted(INTEGRATION_LANGUAGES.items()))
|
||||
assert list(INTEGRATION_LANGUAGES.keys()) == list(sort_langs.keys()), (
|
||||
'INTEGRATION_LANGUAGES not sorted, correct order\r\n'
|
||||
f'{list(sort_langs.keys())}')
|
||||
assert json.dumps(
|
||||
load_json_file(file_path=SPEC_BOOL_TRANS_FILE)) == json.dumps(
|
||||
sort_bool_trans(file_path=SPEC_BOOL_TRANS_FILE)), (
|
||||
f'{SPEC_BOOL_TRANS_FILE} not sorted, goto project root path'
|
||||
' and run the following command sorting, ',
|
||||
'pytest -s -v -m update ./test/check_rule_format.py')
|
||||
assert json.dumps(
|
||||
load_json_file(file_path=SPEC_MULTI_LANG_FILE)) == json.dumps(
|
||||
sort_multi_lang(file_path=SPEC_MULTI_LANG_FILE)), (
|
||||
f'{SPEC_MULTI_LANG_FILE} not sorted, goto project root path'
|
||||
' and run the following command sorting, ',
|
||||
'pytest -s -v -m update ./test/check_rule_format.py')
|
||||
assert json.dumps(
|
||||
load_json_file(file_path=SPEC_FILTER_FILE)) == json.dumps(
|
||||
sort_spec_filter(file_path=SPEC_FILTER_FILE)), (
|
||||
f'{SPEC_FILTER_FILE} not sorted, goto project root path'
|
||||
' and run the following command sorting, ',
|
||||
'pytest -s -v -m update ./test/check_rule_format.py')
|
||||
|
||||
|
||||
@pytest.mark.update
|
||||
def test_sort_spec_data():
|
||||
sort_data: dict = sort_bool_trans(file_path=SPEC_BOOL_TRANS_FILE)
|
||||
save_json_file(file_path=SPEC_BOOL_TRANS_FILE, data=sort_data)
|
||||
print(SPEC_BOOL_TRANS_FILE, 'formatted.')
|
||||
sort_data = sort_multi_lang(file_path=SPEC_MULTI_LANG_FILE)
|
||||
save_json_file(file_path=SPEC_MULTI_LANG_FILE, data=sort_data)
|
||||
print(SPEC_MULTI_LANG_FILE, 'formatted.')
|
||||
sort_data = sort_spec_filter(file_path=SPEC_FILTER_FILE)
|
||||
save_json_file(file_path=SPEC_FILTER_FILE, data=sort_data)
|
||||
print(SPEC_FILTER_FILE, 'formatted.')
|
||||
|
@ -1,3 +1,4 @@
|
||||
[pytest]
|
||||
markers:
|
||||
github: tests for github actions
|
||||
github: tests for github actions
|
||||
update: update or re-sort config file
|
Loading…
x
Reference in New Issue
Block a user