From 4f3c9abd0d4ddeb87b06db3ea04743668f8f66e5 Mon Sep 17 00:00:00 2001 From: Martin Bauer Date: Sun, 2 Jun 2019 14:34:08 +0200 Subject: [PATCH] Added groups to config generation --- config_creation/fhem.yaml | 58 +++++++++++++++ config_creation/groups.yaml | 40 ++++++++++ config_creation/input.yaml | 0 config_creation/knx_conf.py | 7 +- config_creation/main.py | 116 ++++++++++++++++++----------- config_creation/manual_config.yaml | 44 +++++++++++ config_creation/util.py | 33 +++++++- 7 files changed, 252 insertions(+), 46 deletions(-) create mode 100644 config_creation/fhem.yaml create mode 100644 config_creation/groups.yaml delete mode 100644 config_creation/input.yaml create mode 100644 config_creation/manual_config.yaml diff --git a/config_creation/fhem.yaml b/config_creation/fhem.yaml new file mode 100644 index 0000000..9f3286a --- /dev/null +++ b/config_creation/fhem.yaml @@ -0,0 +1,58 @@ + +light: +- name: Schlafzimmer Deckenlampe + dimmer: True + fhem_ids: + - Schlafzimmer_Deckenlampe_Sw + - Schlafzimmer_Deckenlampe + - Schlafzimmer_Deckenlampe_Sw1_V_01 + - Schlafzimmer_Deckenlampe_Sw1_V_02 + groups: + - bedroom +- name: Arbeitszimmer Martin Deckenlampe + dimmer: True + fhem_ids: + - ArbeitszimmerMartin_Deckenlampe_Sw + - ArbeitszimmerMartin_Deckenlampe + - ArbeitszimmerMartin_Deckenlampe_Sw1_V_01 + - ArbeitszimmerMartin_Deckenlampe_Sw1_V_02 + groups: + - office_martin +- name: Arbeitszimmer Rebecca Deckenlampe + dimmer: True + fhem_ids: + - ArbeitszimmerRebecca_Deckenlampe_Sw + - ArbeitszimmerRebecca_Deckenlampe + - ArbeitszimmerRebecca_Deckenlampe_Sw1_V_01 + - ArbeitszimmerRebecca_Deckenlampe_Sw1_V_02 + groups: + - office_rebecca + +#switch: +#- name: Bad Lüfter +# dimmer: False +# fhem_ids: +# - Bad_Luefter +# +#cover: +#- name: Arbeitszimmer Martin Rollo +# fhem_ids: +# - ArbeitszimmerMartin_Rollo +# groups: +# - office_martin +#- name: Schlafzimmer Rollo klein +# fhem_ids: +# - Schlafzimmer_RolloKlein +# groups: +# - bedroom +#- name: Schlafzimmer Rollo groß +# fhem_ids: +# - Schlafzimmer_RolloGross +# groups: +# - bedroom +#- name: Arbeitszimmer Rebecca Rollo +# fhem_ids: +# - ArbeitszimmerRebecca_Rollo +# groups: +# - office_rebecca +# \ No newline at end of file diff --git a/config_creation/groups.yaml b/config_creation/groups.yaml new file mode 100644 index 0000000..5387dd7 --- /dev/null +++ b/config_creation/groups.yaml @@ -0,0 +1,40 @@ +default_view: + view: true + icon: mdi:home + +living_area: + name: Wohnbereich + view: true + +bedroom: + name: Schlafzimmer + view: true + +hallway: + name: Gang + view: true + +outside: + name: Außen + view: true + +office_martin: + name: Arbeitszimmer + view: true + +office_rebecca: + name: Arbeitszimmer Rebecca + view: true + +bathroom: + name: Bad + view: true + +other: + name: Rest + view: true + +first_floor: + name: Oben + view: true + diff --git a/config_creation/input.yaml b/config_creation/input.yaml deleted file mode 100644 index e69de29..0000000 diff --git a/config_creation/knx_conf.py b/config_creation/knx_conf.py index f3a8cac..95d8e98 100644 --- a/config_creation/knx_conf.py +++ b/config_creation/knx_conf.py @@ -1,5 +1,7 @@ from typing import List from util import DeviceInfo +from util import extent as extend_general +import functools __all__ = ['extent', 'import_ets5_csv_file', 'create_power_plug', 'create_lights', 'create_shutters', 'create_switches'] @@ -11,12 +13,15 @@ def first_lower(s): return s[0].lower() + s[1:] +extend = functools.partial(extend_general, platform='knx') + + def extent(result_dict, input_dict): for k, v in input_dict.items(): if k not in result_dict: result_dict[k] = [] for entry in v: - entry['platform'] = 'knx_data' + entry['platform'] = 'knx' result_dict[k] += v diff --git a/config_creation/main.py b/config_creation/main.py index 534e5ce..768349f 100644 --- a/config_creation/main.py +++ b/config_creation/main.py @@ -1,45 +1,48 @@ -from util import DeviceInfo +from util import DeviceInfo, add_to_group from ruamel.yaml import YAML import knx_conf as knx -def create_config(): +yaml = YAML() + + +def add_knx_devices(devices, groups): lights = [ # Dimmers - DeviceInfo('Wohnzimmerlampe', 'Wohnzimmer Deckenlampe'), - DeviceInfo('EsszimmerlampeWest', 'Esszimmer Deckenlampe West'), - DeviceInfo('EsszimmerlampeMitte', 'Esszimmer Deckenlampe Mitte'), - DeviceInfo("EsszimmerWandlampe", 'Esszimmer Schrankleuchte'), - DeviceInfo("Küchenlampe", "Küche Deckenlampe"), - DeviceInfo("AussenleuchteUntenSO", "Aussen Terassenlicht"), - DeviceInfo("Gang", "Gang Licht"), - DeviceInfo("Bad", "Bad Licht"), - DeviceInfo("GangWindfang", "Gang Einganglicht"), - DeviceInfo("LichtWaschküche", "Waschküche Licht"), + DeviceInfo('Wohnzimmerlampe', 'Wohnzimmer Deckenlampe', 'living_area'), + DeviceInfo('EsszimmerlampeWest', 'Esszimmer Deckenlampe West', 'living_area'), + DeviceInfo('EsszimmerlampeMitte', 'Esszimmer Deckenlampe Mitte', 'living_area'), + DeviceInfo("EsszimmerWandlampe", 'Esszimmer Schrankleuchte', 'living_area'), + DeviceInfo("Küchenlampe", "Küche Deckenlampe", 'living_area'), + DeviceInfo("AussenleuchteUntenSO", "Aussen Terassenlicht", 'outside'), + DeviceInfo("Gang", "Gang Licht", 'hallway'), + DeviceInfo("Bad", "Bad Licht", 'bathroom'), + DeviceInfo("GangWindfang", "Gang Einganglicht", 'hallway'), + DeviceInfo("LichtWaschküche", "Waschküche Licht", 'hallway'), # Normal lights - DeviceInfo('AussenleuchteHaustüren', 'Haustür Licht'), - DeviceInfo('AussenleuchteObenNW', 'Haustür Licht NW'), - DeviceInfo('TreppenhausLicht', "Treppenhaus Licht"), - DeviceInfo('WCLicht', "WC Licht"), - DeviceInfo('LampeVorratsraum', "Vorratsraum Licht"), + DeviceInfo('AussenleuchteHaustüren', 'Haustür Licht', 'outside'), + DeviceInfo('AussenleuchteObenNW', 'Haustür Licht NW', 'outside'), + DeviceInfo('TreppenhausLicht', "Treppenhaus Licht", 'first_floor'), + DeviceInfo('WCLicht', "WC Licht", 'other'), + DeviceInfo('LampeVorratsraum', "Vorratsraum Licht", 'other'), ] shutters = [ - DeviceInfo('Wohnzimmer Fenster Rollo', 'Wohnzimmer Fenster Rollo'), - DeviceInfo('Terassentür Rollo', 'Wohnzimmer Terrassentür Rollo'), - DeviceInfo('Küchenfenster Rollo', 'Küche Fenster Rollo'), - DeviceInfo('Esszimmerfenster Rollo', 'Esszimmer Fenster Rollo'), + DeviceInfo('Wohnzimmer Fenster Rollo', 'Wohnzimmer Fenster Rollo', 'living_area'), + DeviceInfo('Terassentür Rollo', 'Wohnzimmer Terrassentür Rollo', 'living_area'), + DeviceInfo('Küchenfenster Rollo', 'Küche Fenster Rollo', 'living_area'), + DeviceInfo('Esszimmerfenster Rollo', 'Esszimmer Fenster Rollo', 'living_area'), ] switches = [ # Bells - DeviceInfo("KlingelOben", "Klingel Oben"), - DeviceInfo("Klingel Innen", "Klingel Innentür"), - DeviceInfo("Klingel Aussen", "Klingen Außentür"), + DeviceInfo("KlingelOben", "Klingel Oben", 'first_floor'), + DeviceInfo("Klingel Innen", "Klingel Innentür", 'other'), + DeviceInfo("Klingel Aussen", "Klingen Außentür", 'other'), # Bewegungsmelder LEDs - DeviceInfo("BewegungsmelderMitte LED", "Bewegungsmelder Mitte LED"), - DeviceInfo("BewegungsmelderWest LED", "Bewegungsmelder West LED"), - DeviceInfo("BewegungsmelderOst LED", "Bewegungsmelder Ost LED"), + DeviceInfo("BewegungsmelderMitte LED", "Bewegungsmelder Mitte LED", 'hallway'), + DeviceInfo("BewegungsmelderWest LED", "Bewegungsmelder West LED", 'hallway'), + DeviceInfo("BewegungsmelderOst LED", "Bewegungsmelder Ost LED", 'hallway'), ] scene_button_names = ['ObenLinks', 'ObenRechts', 'MitteLinks', 'MitteRechts', 'UntenLinks', 'UntenRechts'] scene_button_names = [(i, e) for i, e in enumerate(scene_button_names)] @@ -51,36 +54,63 @@ def create_config(): power_plugs = [ # Vorratsraum - DeviceInfo("VorratsraumSteckdose1", "Vorratsraum Steckdose"), - DeviceInfo("VorratsraumSteckdose2", "Vorratsraum Steckdose"), - DeviceInfo("VorratsraumSteckdose3", "Gefrierschrank"), + DeviceInfo("VorratsraumSteckdose1", "Vorratsraum Steckdose", 'other'), + DeviceInfo("VorratsraumSteckdose2", "Vorratsraum Steckdose", 'other'), + DeviceInfo("VorratsraumSteckdose3", "Gefrierschrank", 'other'), # Waschraum - DeviceInfo("Trockner", "Trockner"), - DeviceInfo("Waschmaschine", "Waschmaschine"), + DeviceInfo("Trockner", "Trockner", 'other'), + DeviceInfo("Waschmaschine", "Waschmaschine", 'other'), # Küche DeviceInfo("KücheSteckdose1", "Küche Steckdose 1"), DeviceInfo("KücheSteckdose2", "Küche Steckdose 2"), - DeviceInfo("Spülmaschine", "Spülmaschine"), - DeviceInfo("Backofen", "Backofen"), - DeviceInfo("HerdP1", "Herd Phase 1"), - DeviceInfo("HerdP2", "Herd Phase 2"), - DeviceInfo("HerdP3", "Herd Phase 3"), + DeviceInfo("Spülmaschine", "Spülmaschine", 'living_area'), + DeviceInfo("Backofen", "Backofen", 'living_area'), + DeviceInfo("HerdP1", "Herd Phase 1", 'living_area'), + DeviceInfo("HerdP2", "Herd Phase 2", 'living_area'), + DeviceInfo("HerdP3", "Herd Phase 3", 'living_area'), # Rest - DeviceInfo("ArbeitszimmerSteckdose", "Arbeitszimmer Steckdose"), - DeviceInfo("WohnzimmerSteckdose1", "Wohnzimmer Steckdose 1"), - DeviceInfo("WohnzimmerSteckdose2", "Wohnzimmer Steckdose 2"), + DeviceInfo("ArbeitszimmerSteckdose", "Arbeitszimmer Steckdose", 'office_martin'), + DeviceInfo("WohnzimmerSteckdose1", "Wohnzimmer Steckdose 1", 'living_area'), + DeviceInfo("WohnzimmerSteckdose2", "Wohnzimmer Steckdose 2", 'living_area'), ] imported_csv = knx.import_ets5_csv_file('knx_data/export_project1.csv') imported_csv.update(knx.import_ets5_csv_file('knx_data/export_project2.csv')) - devices = {} knx.extent(devices, knx.create_lights(lights, imported_csv)) knx.extent(devices, knx.create_shutters(shutters, imported_csv)) knx.extent(devices, knx.create_switches(switches, imported_csv)) knx.extent(devices, knx.create_power_plug(power_plugs, imported_csv)) - YAML().dump(devices, open('knx_devices.yaml', 'w')) + + for device in lights + shutters + switches + power_plugs: + add_to_group(groups, device.groups, device.display_name) + + +def add_fhem_devices(devices, groups): + fhem_yaml = yaml.load(open('fhem.yaml')) + for device_type, device_list in fhem_yaml.items(): + if device_type not in devices: + devices[device_type] = [] + for device in device_list: + device['platform'] = 'fhem' + if 'groups' in device: + add_to_group(groups, device['groups'], device['name']) + del device['groups'] + devices[device_type].append(device) + + +def main(): + group_dict = yaml.load(open('groups.yaml')) + + all_devices = {} + add_knx_devices(all_devices, group_dict) + add_fhem_devices(all_devices, group_dict) + + with open('output/configuration.yaml', 'w') as output: + output.write(open('manual_config.yaml', 'r').read()) + yaml.dump(all_devices, output) + yaml.dump(group_dict, open('output/groups.yaml', 'a')) if __name__ == '__main__': - create_config() + main() diff --git a/config_creation/manual_config.yaml b/config_creation/manual_config.yaml new file mode 100644 index 0000000..6d1299d --- /dev/null +++ b/config_creation/manual_config.yaml @@ -0,0 +1,44 @@ + +# Configure a default setup of Home Assistant (frontend, api, etc) +default_config: + +# Uncomment this if you are using SSL/TLS, running in Docker container, etc. +# http: +# base_url: example.duckdns.org:8123 + +# Discover some devices automatically +#discovery: + +homeassistant: + name: MyHome + latitude: 49.369477 + longitude: 10.9831468 + +# Sensors +#sensor: + # Weather prediction +# - platform: yr + +# Text to speech +tts: + - platform: google_translate + +knx: + rate_limit: 20 + tunneling: + host: 192.168.178.80 # knxd to work together with old home automation server + #host: 192.168.178.65 # network bridge + port: 3671 + local_ip: 192.168.178.74 + +fhem: + host: 192.168.178.80 + port: 7072 + cul_device_name: CUL_HM + + +group: !include groups.yaml +automation: !include automations.yaml +script: !include scripts.yaml + + diff --git a/config_creation/util.py b/config_creation/util.py index 2f5738f..e6e9fe0 100644 --- a/config_creation/util.py +++ b/config_creation/util.py @@ -1,3 +1,32 @@ -from collections import namedtuple +import slugify -DeviceInfo = namedtuple("DeviceInfo", ['csv_name', 'display_name']) + +class DeviceInfo: + def __init__(self, csv_name, display_name, groups=()): + self.csv_name = csv_name + self.display_name = display_name + if not (isinstance(groups, list) or isinstance(groups, tuple)): + groups = [groups] + self.groups = groups + + +def extent(result_dict, input_dict, platform): + for k, v in input_dict.items(): + if k not in result_dict: + result_dict[k] = [] + for entry in v: + entry['platform'] = platform + result_dict[k] += v + + +def name_to_id(name): + return slugify.slugify(name, separator='_') + + +def add_to_group(groups_dict, device_groups, device_name): + for group in device_groups: + if group not in groups_dict: + raise ValueError(f"FHEM device {device_name} wants to be added to unknown group {group}") + if 'entities' not in groups_dict[group]: + groups_dict[group]['entities'] = [] + groups_dict[group]['entities'].append(name_to_id(device_name))