From 921fc033810ddb21d06444c6d5e25125e2a5898e Mon Sep 17 00:00:00 2001 From: Alone Date: Tue, 6 Jul 2021 17:03:50 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=87=A8=F0=9F=87=B3=20add=20support=20for?= =?UTF-8?q?=20custom=20translations?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- custom_components/xiaomi_miot/__init__.py | 10 ++++ custom_components/xiaomi_miot/core/const.py | 47 ++++++++++++++++ .../xiaomi_miot/core/miot_spec.py | 54 ++++++++++++++++--- custom_components/xiaomi_miot/fan.py | 4 ++ custom_components/xiaomi_miot/vacuum.py | 4 ++ 5 files changed, 112 insertions(+), 7 deletions(-) diff --git a/custom_components/xiaomi_miot/__init__.py b/custom_components/xiaomi_miot/__init__.py index 0f3ed9c43..1fc83d606 100644 --- a/custom_components/xiaomi_miot/__init__.py +++ b/custom_components/xiaomi_miot/__init__.py @@ -692,6 +692,16 @@ def __init__(self, miot_service=None, device=None, **kwargs): self._success_code = 0 self._subs = {} + async def async_added_to_hass(self): + await super().async_added_to_hass() + if not self._miot_service: + return + dic = self.global_config('translations') or {} + lan = self.global_config('language') + if lan and isinstance(TRANSLATION_LANGUAGES.get(lan), dict): + dic = {**TRANSLATION_LANGUAGES[lan], **dic} + self._miot_service.set_translations(dic) + @property def miot_device(self): if self.hass and not self._device and CONF_TOKEN in self._config: diff --git a/custom_components/xiaomi_miot/core/const.py b/custom_components/xiaomi_miot/core/const.py index e85c6db62..81d6eb55e 100644 --- a/custom_components/xiaomi_miot/core/const.py +++ b/custom_components/xiaomi_miot/core/const.py @@ -53,3 +53,50 @@ }, } + +TRANSLATION_LANGUAGES = { + 'zh': { + 'off': '关闭', + 'idle': '空闲', + 'busy': '工作中', + 'pause': '暂停', + 'fault': '错误', + + 'vacuum.mode': { + 'Silent': '安静', + 'Basic': '标准', + 'Strong': '强力', + }, + + 'washer.mode': { + 'Daily Wash': '日常洗', + 'Quick Wash': '快速洗', + 'Delicate Wash': '轻柔洗', + 'Down Coat': '羽绒服', + 'Heavy Wash': '强力洗', + 'User Define': '自定义', + 'Rinse': '单漂洗', + 'Spin': '单脱水', + 'Cotton': '棉麻洗', + 'Synthetic': '化纤洗', + 'Shirt': '衬衣洗', + 'Boiling': '高温洗', + 'Wool': '羊毛洗', + 'Drum Clean': '筒自洁', + 'Baby Care': '婴童洗', + 'Intensive': '精细洗', + 'Jacket': '夹克洗', + 'Wash Dry': '洗+烘', + 'Underwear': '内衣洗', + 'Dry': '单烘干', + 'Dry Air Wash': '空气洗', + 'Quick Wash Dry': '快洗烘', + }, + 'washer.drying_level': { + 'moist': '微湿', + 'normal': '正常', + 'extra': '特干', + 'none': '无烘干', + }, + }, +} diff --git a/custom_components/xiaomi_miot/core/miot_spec.py b/custom_components/xiaomi_miot/core/miot_spec.py index caf19e6de..30751ce1c 100644 --- a/custom_components/xiaomi_miot/core/miot_spec.py +++ b/custom_components/xiaomi_miot/core/miot_spec.py @@ -122,6 +122,7 @@ def __init__(self, dat: dict, spec: MiotSpec): self.name = MiotSpec.name_by_type(self.type) self.unique_name = f'{self.name}-{self.iid}' self.description = dat.get('description') or self.name + self.translations = {} spec.services_count.setdefault(self.name, 0) spec.services_count[self.name] += 1 self.properties = {} @@ -201,12 +202,20 @@ def entity_icon(self): icon = 'mdi:fountain' return icon + def set_translations(self, dic: dict, merge=False): + if merge: + self.translations.update(dic) + else: + self.translations = dic + return self + class MiotProperty: def __init__(self, dat: dict, service: MiotService): self.service = service self.raw = dat self.iid = int(dat.get('iid') or 0) + self.siid = service.iid self.type = str(dat.get('type') or '') self.name = MiotSpec.name_by_type(self.type) self.full_name = '' @@ -236,6 +245,33 @@ def readable(self): def writeable(self): return 'write' in self.access + @property + def translations(self): + dic = self.service.translations + kls = [ + self.service.name, + self.name, + f'{self.service.name}.{self.name}', + ] + for k in kls: + d = dic.get(k) + if not isinstance(d, dict): + continue + dic = {**dic, **d} + return dic + + def get_translation(self, des): + dls = [ + des, + des.lower(), + ] + tls = self.translations + for d in dls: + if d not in tls: + continue + return tls[d] + return des + def from_dict(self, dat: dict, default=None): return dat.get(self.full_name, default) @@ -254,16 +290,17 @@ def list_value(self, des): rls = [] for v in self.value_list: val = v.get('value') + vde = v.get('description') if des is None: rls.append(val) - elif des == v.get('description'): + elif des == vde or des == self.get_translation(vde): return val return rls if des is None else None def list_description(self, val): rls = [] for v in self.value_list: - des = v.get('description') + des = self.get_translation(v.get('description')) if val is None: if des == '': des = v.get('value') @@ -303,13 +340,15 @@ def list_search(self, *args, **kwargs): dls = [ des, des.lower(), - re.sub(r'\W+', '_', des), + re.sub(r'\W+', '_', des).lower(), + self.get_translation(des), ] for d in dls: - if d in args: - if get_first: - return v.get('value') - rls.append(v.get('value')) + if d not in args: + continue + if get_first: + return v.get('value') + rls.append(v.get('value')) return rls if not get_first else None def list_first(self, *args): @@ -399,6 +438,7 @@ def __init__(self, dat: dict, service: MiotService): self.service = service self.raw = dat self.iid = int(dat.get('iid') or 0) + self.siid = service.iid self.type = str(dat.get('type') or '') self.name = MiotSpec.name_by_type(self.type) self.full_name = f'{service.name}.{self.name}' diff --git a/custom_components/xiaomi_miot/fan.py b/custom_components/xiaomi_miot/fan.py index 82efb1db5..dbafb2c44 100644 --- a/custom_components/xiaomi_miot/fan.py +++ b/custom_components/xiaomi_miot/fan.py @@ -314,6 +314,10 @@ def __init__(self, parent, miot_property: MiotProperty, option=None): def icon(self): return self._miot_property.entity_icon or super().icon + def update(self): + super().update() + self._miot_property.description_to_dict(self._state_attrs) + @property def is_on(self): if self._prop_power: diff --git a/custom_components/xiaomi_miot/vacuum.py b/custom_components/xiaomi_miot/vacuum.py index 62d937c9d..ebd868206 100644 --- a/custom_components/xiaomi_miot/vacuum.py +++ b/custom_components/xiaomi_miot/vacuum.py @@ -204,6 +204,10 @@ def clean_spot(self, **kwargs): def fan_speed(self): if self._prop_mode: val = self._prop_mode.from_dict(self._state_attrs) + try: + val = int(val) + except (TypeError, ValueError): + val = None if val is not None: return self._prop_mode.list_description(val) return None