Auto generate supported models list
This commit is contained in:
		@@ -4,6 +4,7 @@ import re
 | 
			
		||||
import sys
 | 
			
		||||
from pathlib import Path
 | 
			
		||||
 | 
			
		||||
from homeassistant.util import yaml
 | 
			
		||||
 | 
			
		||||
if __name__ == "__main__":
 | 
			
		||||
    sys.path.insert(0, str(Path(__file__).parent.parent))
 | 
			
		||||
@@ -26,7 +27,7 @@ from custom_components.hon.switch import (
 | 
			
		||||
 | 
			
		||||
ENTITY_CATEGORY_SORT = ["control", "config", "sensor"]
 | 
			
		||||
 | 
			
		||||
entities = {
 | 
			
		||||
ENTITIES = {
 | 
			
		||||
    "binary_sensor": BINARY_SENSORS,
 | 
			
		||||
    "button": BUTTONS,
 | 
			
		||||
    "climate": CLIMATES,
 | 
			
		||||
@@ -39,47 +40,84 @@ entities = {
 | 
			
		||||
    "switch": SWITCHES,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
result = {}
 | 
			
		||||
for entity_type, appliances in entities.items():
 | 
			
		||||
    for appliance, data in appliances.items():
 | 
			
		||||
        for entity in data:
 | 
			
		||||
            if isinstance(entity, HonControlSwitchEntityDescription):
 | 
			
		||||
                key = f"{entity.turn_on_key}` / `{entity.turn_off_key}"
 | 
			
		||||
            else:
 | 
			
		||||
                key = entity.key
 | 
			
		||||
            attributes = (key, entity.name, entity.icon, entity_type)
 | 
			
		||||
            category = (
 | 
			
		||||
                "control"
 | 
			
		||||
                if entity.key.startswith("settings")
 | 
			
		||||
                or isinstance(entity, HonSwitchEntityDescription)
 | 
			
		||||
                or isinstance(entity, HonControlSwitchEntityDescription)
 | 
			
		||||
                or entity_type in ["button", "climate", "lock", "light", "fan"]
 | 
			
		||||
                else "sensor"
 | 
			
		||||
            )
 | 
			
		||||
            result.setdefault(appliance, {}).setdefault(
 | 
			
		||||
                entity.entity_category or category, []
 | 
			
		||||
            ).append(attributes)
 | 
			
		||||
text = ""
 | 
			
		||||
for appliance, categories in sorted(result.items()):
 | 
			
		||||
    text += f"\n### {APPLIANCES[appliance]}\n"
 | 
			
		||||
    categories = {k: categories[k] for k in ENTITY_CATEGORY_SORT if k in categories}
 | 
			
		||||
    for category, data in categories.items():
 | 
			
		||||
        text += f"#### {str(category).capitalize()}s\n"
 | 
			
		||||
        text += "| Name | Icon | Entity | Key |\n"
 | 
			
		||||
        text += "| --- | --- | --- | --- |\n"
 | 
			
		||||
        for key, name, icon, entity_type in sorted(data, key=lambda d: d[1]):
 | 
			
		||||
            icon = f"`{icon.replace('mdi:', '')}`" if icon else ""
 | 
			
		||||
            text += f"| {name} | {icon} | `{entity_type}` | `{key}` |\n"
 | 
			
		||||
 | 
			
		||||
with open(Path(__file__).parent.parent / "README.md", "r") as file:
 | 
			
		||||
    readme = file.read()
 | 
			
		||||
readme = re.sub(
 | 
			
		||||
    "(## Appliance Features\n)(?:.|\\s)+?([^#]## |\\Z)",
 | 
			
		||||
    f"\\1{text}\\2",
 | 
			
		||||
    readme,
 | 
			
		||||
    re.DOTALL,
 | 
			
		||||
)
 | 
			
		||||
entities = sum(len(x) for cat in result.values() for x in cat.values())
 | 
			
		||||
readme = re.sub("badge/Entities-\\d+", f"badge/Entities-{entities}", readme)
 | 
			
		||||
with open(Path(__file__).parent.parent / "README.md", "w") as file:
 | 
			
		||||
    file.write(readme)
 | 
			
		||||
def get_models():
 | 
			
		||||
    return yaml.load_yaml(str(Path(__file__).parent.parent / "supported_models.yml"))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def get_entites():
 | 
			
		||||
    result = {}
 | 
			
		||||
    for entity_type, appliances in ENTITIES.items():
 | 
			
		||||
        for appliance, data in appliances.items():
 | 
			
		||||
            for entity in data:
 | 
			
		||||
                if isinstance(entity, HonControlSwitchEntityDescription):
 | 
			
		||||
                    key = f"{entity.turn_on_key}` / `{entity.turn_off_key}"
 | 
			
		||||
                else:
 | 
			
		||||
                    key = entity.key
 | 
			
		||||
                attributes = (key, entity.name, entity.icon, entity_type)
 | 
			
		||||
                category = (
 | 
			
		||||
                    "control"
 | 
			
		||||
                    if entity.key.startswith("settings")
 | 
			
		||||
                    or isinstance(entity, HonSwitchEntityDescription)
 | 
			
		||||
                    or isinstance(entity, HonControlSwitchEntityDescription)
 | 
			
		||||
                    or entity_type in ["button", "climate", "lock", "light", "fan"]
 | 
			
		||||
                    else "sensor"
 | 
			
		||||
                )
 | 
			
		||||
                result.setdefault(appliance, {}).setdefault(
 | 
			
		||||
                    entity.entity_category or category, []
 | 
			
		||||
                ).append(attributes)
 | 
			
		||||
    return result
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def generate_text(entites, models):
 | 
			
		||||
    text = "_Click to expand..._\n\n"
 | 
			
		||||
    for appliance, categories in sorted(entites.items()):
 | 
			
		||||
        text += f"<details>\n<summary>{APPLIANCES[appliance]}</summary>\n\n"
 | 
			
		||||
        example = f"example_{appliance.lower()}.png"
 | 
			
		||||
        if (Path(__file__).parent.parent / "assets" / example).exists():
 | 
			
		||||
            text += f"### {APPLIANCES[appliance]} Example\n![{APPLIANCES[appliance]}](assets/{example})\n\n"
 | 
			
		||||
        support_number = sum([len(e) for e in models[appliance.lower()].values()])
 | 
			
		||||
        text += (
 | 
			
		||||
            f"### Supported {APPLIANCES[appliance]} models\nSupport has been confirmed for these "
 | 
			
		||||
            f"**{support_number} models**, but many more will work. Please add already supported devices "
 | 
			
		||||
            f"[with this form to complete the list](https://forms.gle/bTSD8qFotdZFytbf8).\n"
 | 
			
		||||
        )
 | 
			
		||||
        for brand, items in models[appliance.lower()].items():
 | 
			
		||||
            text += f"\n#### {brand[0].upper()}{brand[1:]}\n- "
 | 
			
		||||
            text += "\n- ".join(items) + "\n"
 | 
			
		||||
        categories = {k: categories[k] for k in ENTITY_CATEGORY_SORT if k in categories}
 | 
			
		||||
        text += f"\n### {APPLIANCES[appliance]} Entities\n"
 | 
			
		||||
        for category, data in categories.items():
 | 
			
		||||
            text += f"#### {str(category).capitalize()}s\n"
 | 
			
		||||
            text += "| Name | Icon | Entity | Key |\n"
 | 
			
		||||
            text += "| --- | --- | --- | --- |\n"
 | 
			
		||||
            for key, name, icon, entity_type in sorted(data, key=lambda d: d[1]):
 | 
			
		||||
                icon = f"`{icon.replace('mdi:', '')}`" if icon else ""
 | 
			
		||||
                text += f"| {name} | {icon} | `{entity_type}` | `{key}` |\n"
 | 
			
		||||
        text += "\n</details>\n\n"
 | 
			
		||||
    return text
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def update_readme(text, entities, models, file_name="README.md"):
 | 
			
		||||
    with open(Path(__file__).parent.parent / file_name, "r") as file:
 | 
			
		||||
        readme = file.read()
 | 
			
		||||
    readme = re.sub(
 | 
			
		||||
        "(## Supported Appliances\n)(?:.|\\s)+?([^#]## |\\Z)",
 | 
			
		||||
        f"\\1{text}\\2",
 | 
			
		||||
        readme,
 | 
			
		||||
        re.DOTALL,
 | 
			
		||||
    )
 | 
			
		||||
    entities = sum(len(x) for cat in entities.values() for x in cat.values())
 | 
			
		||||
    readme = re.sub("badge/Entities-\\d+", f"badge/Entities-{entities}", readme)
 | 
			
		||||
    models = sum(len(x) for cat in models.values() for x in cat.values())
 | 
			
		||||
    readme = re.sub("badge/Models-\\d+", f"badge/Models-{models}", readme)
 | 
			
		||||
    with open(Path(__file__).parent.parent / file_name, "w") as file:
 | 
			
		||||
        file.write(readme)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if __name__ == "__main__":
 | 
			
		||||
    entities = get_entites()
 | 
			
		||||
    models = get_models()
 | 
			
		||||
    text = generate_text(entities, models)
 | 
			
		||||
    update_readme(text, entities, models)
 | 
			
		||||
    update_readme(text, entities, models, "info.md")
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user