Skip to content

Instantly share code, notes, and snippets.

@KapJI
Created April 11, 2024 10:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save KapJI/046aef1426dd3c3487565aa99f8c5ece to your computer and use it in GitHub Desktop.
Save KapJI/046aef1426dd3c3487565aa99f8c5ece to your computer and use it in GitHub Desktop.
Scripts for generating lights.yaml for Home Assistant
#!/usr/bin/env python3
import sys
from collections import OrderedDict
from dataclasses import dataclass
from typing import Any
import yaml
@dataclass
class LightEntry:
entity_id: str
friendly_name: str
source_entity: str
target_entity: str
icon: str
supports_color_temp: bool
ENTRIES = [
LightEntry(
"hallway_custom",
"Hallway custom",
"light.hallway_bulb_3",
"light.hallway",
"mdi:lightbulb-group",
True,
),
LightEntry(
"office_custom",
"Office",
"light.office_group",
"light.office_group",
"mdi:lightbulb-group",
True,
),
]
class DoubleQuoted(str):
pass
def service_call(service_name: str, entity_id: str) -> OrderedDict:
service: OrderedDict[str, Any] = OrderedDict()
service["service"] = service_name
service["data"] = OrderedDict()
service["data"]["entity_id"] = entity_id
return service
def get_item(entry: LightEntry) -> OrderedDict:
item: OrderedDict[str, Any] = OrderedDict()
item["unique_id"] = entry.entity_id
item["friendly_name"] = entry.friendly_name
item["value_template"] = DoubleQuoted(f"{{{{ states('{entry.source_entity}') }}}}")
item["level_template"] = DoubleQuoted(
f"{{{{ state_attr('{entry.source_entity}', 'brightness') }}}}"
)
item["supports_transition_template"] = True
if entry.supports_color_temp:
item["temperature_template"] = DoubleQuoted(
f"{{{{ state_attr('{entry.source_entity}', 'color_temp') }}}}"
)
item["effect_list_template"] = DoubleQuoted(
f"{{{{ state_attr('{entry.source_entity}', 'effect_list') }}}}"
)
item["effect_template"] = DoubleQuoted(
f"{{{{ state_attr('{entry.source_entity}', 'effect') }}}}"
)
item["min_mireds_template"] = DoubleQuoted(
f"{{{{ state_attr('{entry.source_entity}', 'min_mireds') }}}}"
)
item["max_mireds_template"] = DoubleQuoted(
f"{{{{ state_attr('{entry.source_entity}', 'max_mireds') }}}}"
)
item["icon_template"] = entry.icon
item["availability_template"] = DoubleQuoted(
f"{{{{ states('{entry.source_entity}') != 'unknown' }}}}"
)
item["turn_on"] = service_call("light.turn_on", entry.target_entity)
item["turn_off"] = service_call("light.turn_off", entry.target_entity)
set_level = service_call("light.turn_on", entry.target_entity)
set_level["data"]["brightness"] = DoubleQuoted("{{ brightness }}")
set_level["data"]["transition"] = DoubleQuoted(
"{{ transition if transition is defined else 1 }}"
)
item["set_level"] = set_level
if entry.supports_color_temp:
set_temperature = service_call("light.turn_on", entry.target_entity)
set_temperature["data"]["color_temp"] = DoubleQuoted("{{ color_temp }}")
set_temperature["data"]["transition"] = DoubleQuoted(
"{{ transition if transition is defined else 1 }}"
)
item["set_temperature"] = set_temperature
set_effect = service_call("light.turn_on", entry.target_entity)
set_effect["data"]["effect"] = DoubleQuoted("{{ effect }}")
item["set_effect"] = set_effect
return item
def main() -> int:
yaml.add_representer(
OrderedDict,
lambda dumper, data: dumper.represent_mapping(
"tag:yaml.org,2002:map", data.items()
),
)
yaml.add_representer(
DoubleQuoted,
lambda dumper, data: dumper.represent_scalar(
"tag:yaml.org,2002:str", data, style='"'
),
)
template_lights: OrderedDict[str, Any] = OrderedDict()
template_lights["platform"] = "template"
lights = OrderedDict()
for entry in ENTRIES:
lights[entry.entity_id] = get_item(entry)
template_lights["lights"] = lights
with open("lights.yaml", "w") as file:
file.write("# Generated with gen-lights.py, do not edit!\n")
yaml.dump([template_lights], file, width=1000)
return 0
if __name__ == "__main__":
sys.exit(main())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment