2023-04-22 23:36:31 +02:00
|
|
|
#!/usr/bin/env python
|
|
|
|
|
2023-04-17 23:18:27 +02:00
|
|
|
import re
|
2023-04-22 23:36:31 +02:00
|
|
|
import sys
|
2023-04-17 23:18:27 +02:00
|
|
|
from pathlib import Path
|
|
|
|
|
2023-11-20 23:38:43 +01:00
|
|
|
from homeassistant.util import yaml
|
2023-05-10 18:13:05 +02:00
|
|
|
|
2023-04-22 23:36:31 +02:00
|
|
|
if __name__ == "__main__":
|
|
|
|
sys.path.insert(0, str(Path(__file__).parent.parent))
|
|
|
|
|
2023-07-01 01:44:23 +02:00
|
|
|
from custom_components.hon.const import APPLIANCES
|
2023-04-16 23:35:43 +02:00
|
|
|
from custom_components.hon.binary_sensor import BINARY_SENSORS
|
|
|
|
from custom_components.hon.button import BUTTONS
|
2023-05-10 18:13:05 +02:00
|
|
|
from custom_components.hon.climate import CLIMATES
|
2023-07-01 14:24:04 +02:00
|
|
|
from custom_components.hon.fan import FANS
|
|
|
|
from custom_components.hon.light import LIGHTS
|
|
|
|
from custom_components.hon.lock import LOCKS
|
2023-04-16 23:35:43 +02:00
|
|
|
from custom_components.hon.number import NUMBERS
|
|
|
|
from custom_components.hon.select import SELECTS
|
|
|
|
from custom_components.hon.sensor import SENSORS
|
2023-05-28 07:50:59 +02:00
|
|
|
from custom_components.hon.switch import (
|
|
|
|
SWITCHES,
|
|
|
|
HonControlSwitchEntityDescription,
|
|
|
|
HonSwitchEntityDescription,
|
|
|
|
)
|
2023-04-16 23:35:43 +02:00
|
|
|
|
|
|
|
ENTITY_CATEGORY_SORT = ["control", "config", "sensor"]
|
|
|
|
|
2023-11-20 23:38:43 +01:00
|
|
|
ENTITIES = {
|
2023-04-16 23:35:43 +02:00
|
|
|
"binary_sensor": BINARY_SENSORS,
|
|
|
|
"button": BUTTONS,
|
2023-07-01 01:44:23 +02:00
|
|
|
"climate": CLIMATES,
|
2023-07-01 14:24:04 +02:00
|
|
|
"fan": FANS,
|
|
|
|
"light": LIGHTS,
|
|
|
|
"lock": LOCKS,
|
2023-04-16 23:35:43 +02:00
|
|
|
"number": NUMBERS,
|
|
|
|
"select": SELECTS,
|
|
|
|
"sensor": SENSORS,
|
2023-07-01 01:44:23 +02:00
|
|
|
"switch": SWITCHES,
|
2023-04-16 23:35:43 +02:00
|
|
|
}
|
|
|
|
|
2023-11-20 23:38:43 +01:00
|
|
|
|
|
|
|
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")
|