Skip to content

WMO: multilingual CAP bodies fall through to infos[0] — no language selection #59

Description

@MF-142

Description

🐛 Bug Description / 问题描述

EN: When a user configures zh-Hans as their preferred language but the CAP XML <info> blocks use zh-CN, the provider fails to match the correct language block. This is because _select_info(), _select_region_info(), and _merge_languages() in providers/eccc.py all use strict string equality (==) for language comparison, with no BCP 47 prefix-based fallback. The same issue applies to any other BCP 47 variant pair (e.g., en-GB vs en-US, pt-BR vs pt-PT).

CN: 当用户配置首选语言为 zh-Hans,而 CAP XML 的 <info> 块使用 zh-CN 时,provider 无法正确匹配对应的语言块。原因是 providers/eccc.py 中的 _select_info()_select_region_info()_merge_languages() 均使用严格字符串相等(==)进行语言比较,没有基于 BCP 47 前缀的回退机制。同样的问题也适用于其他 BCP 47 变体对(如 en-GB vs en-USpt-BR vs pt-PT)。

🔍 Root Cause Analysis / 根因分析

EN: Verified across all three relevant files:

File Language Logic BCP 47 Fallback
providers/cap.py Pure parser; stores all <info> blocks unconditionally ❌ None
coordinator.py Resolves "auto" → concrete code, then passes through ❌ None
providers/eccc.py Strict == comparison; falls back to first <info> on miss None

When no exact match is found, the current fallback silently returns doc.infos[0], which may be in an entirely different language depending on XML document order.

CN: 经三个相关文件验证:

文件 语言逻辑 BCP 47 回退
providers/cap.py 纯解析器;无条件存储所有 <info> ❌ 无
coordinator.py "auto" 解析为具体代码后透传 ❌ 无
providers/eccc.py 严格 == 比较;未命中时回退到第一个 <info>

当没有精确匹配时,当前的回退逻辑会静默返回 doc.infos[0],这可能是完全不同的语言,具体取决于 XML 文档中 <info> 块的排列顺序。

💡 Suggested Fix / 建议修复方案

EN: Add a helper function in providers/eccc.py that implements BCP 47 primary-subtag prefix matching, and replace all info.language == language comparisons with it:

def _language_matches(info_lang: str, preferred: str) -> bool:
    """Check language match with BCP 47 prefix fallback."""
    if not info_lang or not preferred:
        return False
    if info_lang == preferred:
        return True
    # Compare primary subtags: zh-Hans ↔ zh-CN, en-GB ↔ en-US, etc.
    return (
        "-" in preferred
        and "-" in info_lang
        and preferred.split("-", 1)[0].casefold() == info_lang.split("-", 1)[0].casefold()
    )

Then update the three call sites:

  • _select_info(): if _language_matches(info.language, language)
  • _select_region_info(): [info for info in doc.infos if _language_matches(info.language, language)]
  • _merge_languages(): if _language_matches(v.language, preferred_lang)

CN: 建议在 providers/eccc.py 中添加一个实现 BCP 47 主子标签前缀匹配的辅助函数,并将所有 info.language == language 比较替换为该函数:

def _language_matches(info_lang: str, preferred: str) -> bool:
    """检查语言匹配,支持 BCP 47 前缀回退。"""
    if not info_lang or not preferred:
        return False
    if info_lang == preferred:
        return True
    # 比较主子标签:zh-Hans ↔ zh-CN、en-GB ↔ en-US 等
    return (
        "-" in preferred
        and "-" in info_lang
        and preferred.split("-", 1)[0].casefold() == info_lang.split("-", 1)[0].casefold()
    )

然后更新三处调用点:

  • _select_info()if _language_matches(info.language, language)
  • _select_region_info()[info for info in doc.infos if _language_matches(info.language, language)]
  • _merge_languages()if _language_matches(v.language, preferred_lang)

⚠️ Impact / 影响范围

EN: Any user whose Home Assistant language setting does not exactly match the CAP XML <language> tag will receive alerts in an unpredictable language. This affects all non-English/French ECCC users and potentially MeteoAlarm users with regional locale variants.

CN: 任何 Home Assistant 语言设置与 CAP XML <language> 标签不完全一致的用户,都将收到不可预测语言的预警信息。这影响所有非英语/法语的 ECCC 用户,以及可能使用区域变体的 MeteoAlarm 用户。

🏷️ Labels / 标签建议

bug, i18n, language-matching

Integration Version

0.1.1

Home Assistant Version

Core 2026.7.4 Supervisor 2026.07.3 Operating System 18.1 Frontend 20260624.6

Provider

WMO (rest of world)

Location Mode & Value

No response

Integration Configuration

Home Assistant Logs


Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions