Config update

This commit is contained in:
Martin Bauer 2019-06-11 19:28:39 +02:00
parent 4f3c9abd0d
commit fab83c86f4
9 changed files with 157 additions and 297 deletions

View File

@ -46,10 +46,10 @@ def add_knx_devices(devices, groups):
]
scene_button_names = ['ObenLinks', 'ObenRechts', 'MitteLinks', 'MitteRechts', 'UntenLinks', 'UntenRechts']
scene_button_names = [(i, e) for i, e in enumerate(scene_button_names)]
switches += [DeviceInfo(f"SzeneEsszimmer{n}", "Esszimmer Szene {i}") for i, n in scene_button_names]
switches += [DeviceInfo(f"SzeneWohnzimmer{n}", "Wohnzimmer Szene {i}") for i, n in scene_button_names]
switches += [DeviceInfo(f"SzeneEingang{n}", "Eingang Szene {i}") for i, n in scene_button_names[2:]]
switches += [DeviceInfo(f"SzeneTerrassentuer{n}", "Wohnzimmer Terrassentür Szene {i}")
switches += [DeviceInfo(f"SzeneEsszimmer{n}", f"Esszimmer Szene {i}") for i, n in scene_button_names]
switches += [DeviceInfo(f"SzeneWohnzimmer{n}", f"Wohnzimmer Szene {i}") for i, n in scene_button_names]
switches += [DeviceInfo(f"SzeneEingang{n}", f"Eingang Szene {i}") for i, n in scene_button_names[2:]]
switches += [DeviceInfo(f"SzeneTerrassentuer{n}", f"Wohnzimmer Terrassentür Szene {i}")
for i, n in scene_button_names[2: 4]]
power_plugs = [
@ -82,8 +82,9 @@ def add_knx_devices(devices, groups):
knx.extent(devices, knx.create_switches(switches, imported_csv))
knx.extent(devices, knx.create_power_plug(power_plugs, imported_csv))
for device in lights + shutters + switches + power_plugs:
add_to_group(groups, device.groups, device.display_name)
for device_type, devices in [('light', lights), ('cover', shutters), ('switch', switches)]:
for device in devices:
add_to_group(groups, device.groups, device.display_name, device_type)
def add_fhem_devices(devices, groups):
@ -94,7 +95,7 @@ def add_fhem_devices(devices, groups):
for device in device_list:
device['platform'] = 'fhem'
if 'groups' in device:
add_to_group(groups, device['groups'], device['name'])
add_to_group(groups, device['groups'], device['name'], device_type)
del device['groups']
devices[device_type].append(device)
@ -109,7 +110,7 @@ def main():
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'))
yaml.dump(group_dict, open('output/groups.yaml', 'w'))
if __name__ == '__main__':

View File

@ -14,6 +14,11 @@ homeassistant:
latitude: 49.369477
longitude: 10.9831468
customize_glob:
cover.*:
half_position: 25
# Sensors
#sensor:
# Weather prediction

View File

@ -0,0 +1,103 @@
resources:
- type: js
url: /local/custom_ui/state-card-custom-cover.js
title: Home
views:
- cards:
- entities:
- light.wohnzimmer_deckenlampe
- light.wohnzimmer_kugel
image: /local/living_room.jpg
title: Wohnzimmer
type: picture-glance
- entities:
- entity: light.kuche_deckenlampe
name: Decke Küche
- entity: light.esszimmer_deckenlampe_mitte
name: Decke Esszimmer Mitte
- entity: light.esszimmer_deckenlampe_west
name: Decke Esszimmer
- type: divider
- entity: light.kuche_links
name: Küche LED links
- entity: light.kuche_rechts
name: Küche LED rechts
- entity: light.kuche_vorne
name: Küche LED vorne
- type: divider
- entity: cover.kuche_fenster_rollo
name: Küche
type: 'custom:state-card-custom-cover'
- entity: cover.esszimmer_fenster_rollo
name: Esszimmer
type: 'custom:state-card-custom-cover'
show_header_toggle: true
title: Küche/Esszimmer
type: entities
- entities:
- entity: light.wohnzimmer_deckenlampe
name: Decke
- type: divider
- entity: light.wohnzimmer_kugel
name: Kugel
- entity: light.wohnzimmer_regal_links
name: Regal links
- entity: light.wohnzimmer_regal_rechts
name: Regal rechts
- type: divider
- entity: light.wohnzimmer_stehlampe_oben
name: Stehlampe oben
- entity: light.wohnzimmer_stehlampe
name: Stehlampe unten
- type: divider
- entity: cover.wohnzimmer_fenster_rollo
name: Fenster
type: 'custom:state-card-custom-cover'
- entity: cover.wohnzimmer_terrassentur_rollo
name: Tür
type: 'custom:state-card-custom-cover'
show_header_toggle: true
title: Wohnzimmer
type: entities
- entities:
- entity: light.gang_licht
name: Licht
- entity: light.gang_bogen
name: Bogen
show_header_toggle: true
title: Gang
type: entities
title: Wohnbereich
- badges:
- sensor.fritz_box_7490_kbyte_sec_received
- sensor.fritz_box_7490_kbyte_sec_sent
cards:
- entities:
- entity: sensor.trockner_verbrauch
name: Trockner aktuell
- entity: sensor.trockner_verbrauch_summe
name: Trockner insgesamt
- entity: sensor.trockner_betriebsstunden
name: Trockner Stunden
- type: divider
- entity: sensor.waschmaschine_verbrauch
name: Waschmaschine aktuell
- entity: sensor.waschmaschine_verbrauch_summe
name: Waschmaschine insgesamt
- entity: sensor.waschmaschine_betriebsstunden
name: Waschmaschine Stunden
show_header_toggle: false
title: Verbrauch
type: entities
- entities:
- switch.trockner
- switch.waschmaschine
- switch.spulmaschine
- switch.backofen
- switch.herd_phase_1
- switch.herd_phase_2
- switch.herd_phase_3
show_header_toggle: false
title: Sicherheitsabschaltung
type: entities
title: Admin

View File

@ -19,14 +19,14 @@ def extent(result_dict, input_dict, platform):
result_dict[k] += v
def name_to_id(name):
return slugify.slugify(name, separator='_')
def name_to_id(name, device_type):
return "{}.{}".format(device_type, slugify.slugify(name, separator='_'))
def add_to_group(groups_dict, device_groups, device_name):
def add_to_group(groups_dict, device_groups, device_name, device_type):
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))
groups_dict[group]['entities'].append(name_to_id(device_name, device_type))

View File

@ -58,6 +58,9 @@ class FhemConnection:
_LOGGER.info("Connected to FHEM {}:{}".format(self._host, self._port))
self._writer = writer
self.connected = True
for device in self.devices.values():
await device.async_update_ha_state()
self.reconnect_time = self.reconnect_time_start
writer.writelines([
"displayattr .*\n".encode(),
@ -71,6 +74,8 @@ class FhemConnection:
except OSError:
_LOGGER.warning("Connection to FHEM failed {}:{}".format(self._host, self._port))
self.connected = False
for device in self.devices.values():
await device.async_update_ha_state()
await asyncio.sleep(self.reconnect_time)
self.reconnect_time = min(2 * self.reconnect_time, self.reconnect_time)
self.hass.loop.create_task(self._connection())

View File

@ -25,7 +25,6 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
"""Set up lights for KNX platform."""
connection = hass.data[DATA_FHEM]
#_LOGGER.error("FHEM platform config\n" + str(config))
light = FhemLight(connection, config[CONF_NAME], config[CONF_FHEM_IDS], dimmer=config[CONF_DIMMER])
for dev_id in config[CONF_FHEM_IDS]:
@ -91,7 +90,7 @@ class FhemLight(Light):
self.connection.fhem_set(self._ids[0], 'off')
async def line_received(self, line):
_LOGGER.info("FHEM line received (device): " + self.name + ": " + line)
_LOGGER.debug("FHEM line received (device): " + self.name + ": " + line)
if line.startswith('dim:'):
self._available = True
_, new_dim_state, new_level = line.split(':')

View File

@ -1,61 +0,0 @@
light:
- platform: knx
address: 0/1/3
state_address: 0/1/8
name: Wohnzimmer Deckenlampe
brightness_address: 0/1/7
brightness_state_address: 0/1/9
- platform: knx
address: 0/1/21
state_address: 0/1/26
name: Esszimmer Deckenlampe West
brightness_address: 0/1/25
brightness_state_address: 0/1/27
- platform: knx
address: 0/1/39
state_address: 0/1/44
name: Esszimmer Deckenlampe Mitte
brightness_address: 0/1/43
brightness_state_address: 0/1/45
- platform: knx
address: 0/2/39
state_address: 0/2/44
name: Esszimmer Schrankleuchte
brightness_address: 0/2/43
brightness_state_address: 0/2/45
- platform: knx
address: 0/1/57
state_address: 0/1/62
name: Küche Deckenlampe
brightness_address: 0/1/61
brightness_state_address: 0/1/63
- platform: knx
address: 0/2/21
state_address: 0/2/26
name: Aussen Terassenlicht
brightness_address: 0/2/25
brightness_state_address: 0/2/27
- platform: knx
address: 0/3/3
state_address: 0/3/8
name: Gang Licht
brightness_address: 0/3/7
brightness_state_address: 0/3/9
- platform: knx
address: 0/3/21
state_address: 0/3/26
name: Bad Licht
brightness_address: 0/3/25
brightness_state_address: 0/3/27
- platform: knx
address: 0/3/39
state_address: 0/3/44
name: Gang Einganglicht
brightness_address: 0/3/43
brightness_state_address: 0/3/45
- platform: knx
address: 0/3/57
state_address: 0/3/62
name: Waschküche Licht
brightness_address: 0/3/61
brightness_state_address: 0/3/63

View File

@ -1,158 +0,0 @@
from collections import namedtuple
from typing import List
from ruamel.yaml import YAML
DeviceInfo = namedtuple("DeviceInfo", ['csv_name', 'display_name'])
yaml = YAML()
def first_lower(s):
if len(s) == 0:
return s
else:
return s[0].lower() + s[1:]
def import_ets5_csv_file(csv_file):
result = dict()
with open(csv_file, encoding='utf-8') as f:
for line in f:
splitted_line = line.split(",")
name = splitted_line[0].replace('"', "")
group_address = splitted_line[1].replace('"', "")
if '-' not in group_address:
result[name.strip()] = splitted_line[1].replace('"', "").strip()
return result
def create_dimmable_lights(device_info : List[DeviceInfo],
csv_contents,
postfix_on_off_write=" Schalten",
postfix_on_off_read=" RM Schalten",
postfix_dim=" Dimmen",
postfix_brightness_write=" Helligkeit",
postfix_brightness_read=" RM Helligkeit"):
result = []
for entry in device_info:
try:
display_name = entry.display_name
on_off_write_addr = csv_contents[entry.csv_name + postfix_on_off_write]
on_off_read_addr = csv_contents[entry.csv_name + postfix_on_off_read]
dimm_addr = csv_contents[entry.csv_name + postfix_dim]
brightness_write_addr = csv_contents[entry.csv_name + postfix_brightness_write]
brightness_read_addr = csv_contents[entry.csv_name + postfix_brightness_read]
result.append({
'platform': 'knx',
'address': on_off_write_addr,
'state_address': on_off_read_addr,
'name': display_name,
'brightness_address': brightness_write_addr,
'brightness_state_address': brightness_read_addr,
})
except KeyError as e:
raise ValueError("Skipping %s - Could not find CSV File entry: %s" % (entry.csv_name, str(e)))
return result
def write_yaml(device_dict):
pass
if __name__ == '__main__':
knx_dimmable_lights = [
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"),
]
imported_csv = import_ets5_csv_file('export_project1.csv')
imported_csv.update(import_ets5_csv_file('export_project2.csv'))
devices = {
'light': create_dimmable_lights(knx_dimmable_lights, imported_csv),
}
yaml.dump(devices, open('knx_devices.yaml', 'w'))
def createLights(csvContents, idToRoomMap, knxSendClient, knxRecvClient,
postfixWrite=" Schalten", postfixRead=" RM Schalten"):
from pysmarthome.backends.knx.devices import Light
result = []
for csvName, info in idToRoomMap.items():
try:
room = info['room']
displayName = info['displayName']
deviceId = info['id']
onOffWriteAddr = csvContents[csvName + postfixWrite]
onOffReadAddr = csvContents[csvName + postfixRead]
l = Light(deviceId, displayName, room, onOffWriteAddr, onOffReadAddr, knxSendClient, knxRecvClient, )
result.append(l)
except KeyError as e:
raise ValueError("Skipping %s - Could not find CSV File entry: %s" % (csvName, str(e)))
return result
def createBells(csvContents, idToRoomMap, knxSendClient, knxRecvClient,
postfixWrite=" Schalten", postfixRead=" RM Schalten"):
from pysmarthome.backends.knx.devices import Bell
result = []
for csvName, info in idToRoomMap.items():
try:
room = info['room']
displayName = info['displayName']
deviceId = info['id']
onOffWriteAddr = csvContents[csvName + postfixWrite]
if csvName + postfixRead in csvContents:
onOffReadAddr = csvContents[csvName + postfixRead]
else:
onOffReadAddr = None
l = Bell(deviceId, displayName, room, onOffWriteAddr, onOffReadAddr, knxSendClient, knxRecvClient, )
result.append(l)
except KeyError as e:
raise ValueError("Skipping %s - Could not find CSV File entry: %s" % (csvName, str(e)))
return result
def createShutters(csvContents, idToRoomMap, knxSendClient, knxRecvClient,
postfixLongAddr=" Lang", postfixShortAddr=" Kurz", postfixReadPosition=" RM Position",
postfixSetPosition=" Position"):
from pysmarthome.backends.knx.devices import Shutter
result = []
for csvName, contents in idToRoomMap.items():
try:
longAddr = csvContents[csvName + postfixLongAddr]
shortAddr = csvContents[csvName + postfixShortAddr]
readPosAddr = csvContents[csvName + postfixReadPosition]
setPosAddr = csvContents[csvName + postfixSetPosition]
if type(contents) is dict:
displayName = contents['displayName']
room = contents['room']
deviceId = contents['id']
else:
displayName = csvName
room = contents
deviceId = first_lower(csvName)
s = Shutter(deviceId, displayName, room, shortAddr, longAddr, setPosAddr, readPosAddr,
knxSendClient, knxRecvClient)
result.append(s)
except KeyError as e:
raise ValueError("Skipping %s - Could not find CSV File entry: %s" % (csvName, str(e)))
return result

94
todo
View File

@ -1,74 +1,40 @@
KNX:
- add shutters
- add sensors
- check out read addresses
- in bus monitor
- KNX config files -> add to git
- add fhem devices [ok]
- generate config [ok]
- test config [ok]
- add shutters [ok]
- add sensors [ok]
- check out read addresses [ok]
- in bus monitor [ok]
- KNX config files -> add to git [ok]
- configure frontend
- add scenes
- add brighter/darker action
- fix door light [ok]
- check out motion detectors in frontend
- check out shutters in frontend
Config:
- add rooms as groups
- frontend room grouping
-> how to configure frontend?
- set up scenes for living room
Frontend:
- change cover state card for half open
FHEM:
- add FHEM shutters
- add
- check FHEM reconnection
- what happens when FHEM stops?
- what happens when stick is pulled?
CUL_HM ArbeitszimmerMartin_Deckenlampe_Sw deviceMsg: 50 (to 62A77D)
CUL_HM ArbeitszimmerMartin_Deckenlampe_Sw dim: stop:50
CUL_HM ArbeitszimmerMartin_Deckenlampe_Sw level: 50
CUL_HM ArbeitszimmerMartin_Deckenlampe_Sw overheat: off
CUL_HM ArbeitszimmerMartin_Deckenlampe_Sw overload: off
CUL_HM ArbeitszimmerMartin_Deckenlampe_Sw pct: 50
CUL_HM ArbeitszimmerMartin_Deckenlampe_Sw phyLevel: 50
CUL_HM ArbeitszimmerMartin_Deckenlampe_Sw reduced: off
CUL_HM ArbeitszimmerMartin_Deckenlampe_Sw 50
CUL_HM ArbeitszimmerMartin_Deckenlampe_Sw timedOn: off
CUL_HM ArbeitszimmerMartin_Deckenlampe_Sw1_V_01 phyLevel: 50
CUL_HM ArbeitszimmerMartin_Deckenlampe_Sw1_V_01 chn:??? phys:50
CUL_HM ArbeitszimmerMartin_Deckenlampe_Sw1_V_02 phyLevel: 50
CUL_HM ArbeitszimmerMartin_Deckenlampe_Sw1_V_02 chn:??? phys:50
CUL_HM ArbeitszimmerMartin_Deckenlampe_Sw deviceMsg: off (to 62A77D)
CUL_HM ArbeitszimmerMartin_Deckenlampe_Sw dim: stop:off
CUL_HM ArbeitszimmerMartin_Deckenlampe_Sw level: 0
CUL_HM ArbeitszimmerMartin_Deckenlampe_Sw overheat: off
CUL_HM ArbeitszimmerMartin_Deckenlampe_Sw overload: off
CUL_HM ArbeitszimmerMartin_Deckenlampe_Sw pct: 0
CUL_HM ArbeitszimmerMartin_Deckenlampe_Sw phyLevel: 0
CUL_HM ArbeitszimmerMartin_Deckenlampe_Sw reduced: off
CUL_HM ArbeitszimmerMartin_Deckenlampe_Sw off
CUL_HM ArbeitszimmerMartin_Deckenlampe_Sw timedOn: off
CUL_HM ArbeitszimmerMartin_Deckenlampe_Sw1_V_01 phyLevel: 0
CUL_HM ArbeitszimmerMartin_Deckenlampe_Sw1_V_01 chn:??? phys:0
CUL_HM ArbeitszimmerMartin_Deckenlampe_Sw1_V_02 phyLevel: 0
CUL_HM ArbeitszimmerMartin_Deckenlampe_Sw1_V_02 chn:??? phys:0
CUL_HM ArbeitszimmerMartin_Bewegungsmelder brightness: 45
CUL_HM ArbeitszimmerMartin_Bewegungsmelder motion: on (to 62A77D)
CUL_HM ArbeitszimmerMartin_Bewegungsmelder motionCount: 3_next:29s
CUL_HM ArbeitszimmerMartin_Bewegungsmelder motion
CUL_HM ArbeitszimmerMartin_Bewegungsmelder trigDst_62A77D: noConfig
CUL_HM ArbeitszimmerMartin_Bewegungsmelder trigger_cnt: 3
CUL_HM ArbeitszimmerMartin_Deckenlampe_Sw deviceMsg: 50 (to 62A77D)
Owntracks
- try basic owntracks setup
Other:
- media player card:
https://github.com/kalkih/mini-media-player
2019-06-03 19:20:46 WARNING (MainThread) [xknx.log] Could not read value of <Light name="Haustür Licht NW" switch="GroupAddress("0/0/3")/GroupAddress("0/0/4")/None/None" /> 0/0/4
2019-06-03 19:20:48 WARNING (MainThread) [xknx.log] Could not read value of <Light name="Haustür Licht" switch="GroupAddress("0/0/1")/GroupAddress("0/0/2")/None/None" /> 0/0/2