50 lines
2.2 KiB
Python
50 lines
2.2 KiB
Python
#!/usr/bin/env python3
|
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
"""Render the MQTT kiosk Home Assistant package from its parameterized template."""
|
|
import argparse
|
|
import json
|
|
import re
|
|
from pathlib import Path
|
|
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument("--name", required=True)
|
|
parser.add_argument("--entity-prefix", required=True, help="HA device/entity slug, e.g. lounge_kiosk")
|
|
parser.add_argument("--command-root", required=True, help="MQTT command topic root, e.g. kiosk/commands/lounge")
|
|
parser.add_argument("--status-root", required=True, help="MQTT status topic root, e.g. kiosk/status/lounge")
|
|
parser.add_argument("--manufacturer", default="Generic")
|
|
parser.add_argument("--model", default="Linux Touchscreen Kiosk")
|
|
parser.add_argument("--area", default="")
|
|
parser.add_argument("--output", required=True, type=Path)
|
|
args = parser.parse_args()
|
|
|
|
if not re.fullmatch(r"[a-z][a-z0-9_]*", args.entity_prefix):
|
|
parser.error("--entity-prefix must contain lowercase letters, digits, and underscores")
|
|
topic_pattern = r"[A-Za-z0-9_.-]+(?:/[A-Za-z0-9_.-]+)*"
|
|
if not re.fullmatch(topic_pattern, args.command_root):
|
|
parser.error("--command-root must be a non-empty MQTT topic path without wildcards")
|
|
if not re.fullmatch(topic_pattern, args.status_root):
|
|
parser.error("--status-root must be a non-empty MQTT topic path without wildcards")
|
|
|
|
text = Path(__file__).with_name("kiosk-package.yaml.in").read_text()
|
|
quoted_values = {
|
|
"__KIOSK_NAME__": args.name,
|
|
"__MANUFACTURER__": args.manufacturer,
|
|
"__MODEL__": args.model,
|
|
"__AREA__": args.area,
|
|
}
|
|
for marker, value in quoted_values.items():
|
|
text = text.replace(f'"{marker}"', json.dumps(value, ensure_ascii=False))
|
|
text = text.replace(marker, value)
|
|
for marker, value in {
|
|
"__KIOSK_ENTITY_PREFIX__": args.entity_prefix,
|
|
"__COMMAND_TOPIC_ROOT__": args.command_root,
|
|
"__STATUS_TOPIC_ROOT__": args.status_root,
|
|
}.items():
|
|
text = text.replace(marker, value)
|
|
if re.search(r"__[A-Z_]+__", text):
|
|
raise SystemExit("Unresolved template marker remains")
|
|
if not args.area:
|
|
text = text.replace(' suggested_area: ""\n', "")
|
|
args.output.parent.mkdir(parents=True, exist_ok=True)
|
|
args.output.write_text(text)
|