diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..e4c9cdc --- /dev/null +++ b/__init__.py @@ -0,0 +1,189 @@ + +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +from devdi import props +import logging +import sys + +try: + from config import APP_NAME as ROOT_LOGGER_NAME +except ImportError: + ROOT_LOGGER_NAME = 'root' +logger = logging.getLogger(ROOT_LOGGER_NAME).getChild(__name__) + + +class devices(dict): + """ + Class to select a device and hold the device information + """ + + def __init__(self, mqtt_client): + dict.__init__(self) + ####### + # GFW # + ####### + loc = props.LOC_GFW + + # MARION + roo = props.ROO_MAR + # + self.add(mqtt_client, props.STG_SHE, loc, roo, props.FUN_MAL, props.DTY_SHY_SW1) # Shelly Main Light + self.add(mqtt_client, props.STG_ZGW, loc, roo, props.FUN_HEA, props.DTY_BVL_xxx) # Brennenstuhl Heatingvalve + + # FLOOR + roo = props.ROO_FLO + # + self.add(mqtt_client, props.STG_SHE, loc, roo, props.FUN_MAL, props.DTY_SHY_SW1) # Shelly Main Light + self.add(mqtt_client, props.STG_ZGW, loc, roo, props.FUN_MAL, props.DTY_LLI_SBT, 1) # Tradfri Main Light + self.add(mqtt_client, props.STG_ZGW, loc, roo, props.FUN_MAL, props.DTY_LLI_SBT, 2) # Tradfri Main Light + + # DIRK + roo = props.ROO_DIR + # + self.add(mqtt_client, props.STG_SHE, loc, roo, props.FUN_MAL, props.DTY_SHY_SW1) # Shelly Main Light + self.add(mqtt_client, props.STG_ZGW, loc, roo, props.FUN_MAL, props.DTY_TLI_SBT) # Tradfri Main Light + self.add(mqtt_client, props.STG_ZGW, loc, roo, props.FUN_CTR, props.DTY_TIN_5xx) # Tradfri Input Device 5 Buttons + self.add(mqtt_client, props.STG_MYA, loc, roo, props.FUN_MPP, props.DTY_MPP_4xx) # My 4 port Powerplug + self.add(mqtt_client, props.STG_ZGW, loc, roo, props.FUN_DEL, props.DTY_TLI_SBT) , # Tradfri Desklight + self.add(mqtt_client, props.STG_MYA, loc, roo, props.FUN_RCA, props.DTY_MRE_xxx) # Remote Control IR Amplifier + self.add(mqtt_client, props.STG_MYA, loc, roo, props.FUN_ASS, props.DTY_MAS_xxx) # Audio status Spotify + self.add(mqtt_client, props.STG_MYA, loc, roo, props.FUN_ASM, props.DTY_MAS_xxx) # Audio status MPD + self.add(mqtt_client, props.STG_ZGW, loc, roo, props.FUN_HEA, props.DTY_BVL_xxx) # Brennenstuhl Heatingvalve + + + ####### + # FFW # + ####### + loc = props.LOC_FFW + # JULIAN + roo = props.ROO_JUL + # + self.add(mqtt_client, props.STG_SHE, loc, roo, props.FUN_MAL, props.DTY_SHY_SW1) # Shelly Main Light + self.add(mqtt_client, props.STG_ZFW, loc, roo, props.FUN_MAL, props.DTY_TLI_SBT) # Tradfri Main Light + self.add(mqtt_client, props.STG_ZFW, loc, roo, props.FUN_HEA, props.DTY_BVL_xxx) # Brennenstuhl Heatingvalve + + # BATH + roo = props.ROO_BAT + # + self.add(mqtt_client, props.STG_ZFW, loc, roo, props.FUN_HEA, props.DTY_BVL_xxx) # Brennenstuhl Heatingvalve + + # LIVINGROOM + roo = props.ROO_LIV + # + self.add(mqtt_client, props.STG_SHE, loc, roo, props.FUN_MAL, props.DTY_SHY_SW1) # Shelly Main Light + self.add(mqtt_client, props.STG_ZFW, loc, roo, props.FUN_MAL, props.DTY_TLI_SBT) # Tradfri Main Light + + # SLEEP + roo = props.ROO_SLP + # + self.add(mqtt_client, props.STG_SHE, loc, roo, props.FUN_MAL, props.DTY_SHY_SW1) # Shelly Main Light + self.add(mqtt_client, props.STG_ZFW, loc, roo, props.FUN_MAL, props.DTY_TLI_SBx) # Tradfri Main Light + self.add(mqtt_client, props.STG_ZFW, loc, roo, props.FUN_HEA, props.DTY_BVL_xxx) # Brennenstuhl Heatingvalve + + ####### + # FFE # + ####### + loc = props.LOC_FFE + # FLOOR + roo = props.ROO_FLO + # + self.add(mqtt_client, props.STG_SHE, loc, roo, props.FUN_MAL, props.DTY_SHY_SW1) # Shelly Main Light + + # KITCHEN + roo = props.ROO_KIT + # + self.add(mqtt_client, props.STG_SHE, loc, roo, props.FUN_MAL, props.DTY_SHY_SW1) # Shelly Main Light + self.add(mqtt_client, props.STG_SHE, loc, roo, props.FUN_CIR, props.DTY_SHY_SW1) # Shelly Main Light + self.add(mqtt_client, props.STG_ZFE, loc, roo, props.FUN_HEA, props.DTY_BVL_xxx) # Brennenstuhl Heatingvalve + + # DININGROOM + roo = props.ROO_DIN + # + self.add(mqtt_client, props.STG_SHE, loc, roo, props.FUN_MAL, props.DTY_SHY_SW1) # Shelly Main Light + self.add(mqtt_client, props.STG_ZFE, loc, roo, props.FUN_FLL, props.DTY_SPP_SW1) # Powerplug Floor Light + self.add(mqtt_client, props.STG_ZFE, loc, roo, props.FUN_GAR, props.DTY_SPP_SW1) # Powerplug Garland + self.add(mqtt_client, props.STG_ZFE, loc, roo, props.FUN_HEA, props.DTY_BVL_xxx) # Brennenstuhl Heatingvalve + + # SLEEP + roo = props.ROO_SLP + # + self.add(mqtt_client, props.STG_SHE, loc, roo, props.FUN_MAL, props.DTY_SHY_SW1) # Shelly Main Light + self.add(mqtt_client, props.STG_ZFE, loc, roo, props.FUN_MAL, props.DTY_TLI_SBT) # Tradfri Main Light + self.add(mqtt_client, props.STG_ZFE, loc, roo, props.FUN_CTR, props.DTY_TIN_5xx) # Tradfri Input Device 5 Buttons + self.add(mqtt_client, props.STG_ZFE, loc, roo, props.FUN_BLD, props.DTY_TLI_SBx) # Tradfri Bed Light Dirk + self.add(mqtt_client, props.STG_ZFE, loc, roo, props.FUN_BLM, props.DTY_SPP_SW1) # Powerplug Bed Light Marion + self.add(mqtt_client, props.STG_ZFE, loc, roo, props.FUN_HEA, props.DTY_BVL_xxx) # Brennenstuhl Heatingvalve + + # LIVINGROOM + roo = props.ROO_LIV + # + self.add(mqtt_client, props.STG_SHE, loc, roo, props.FUN_MAL, props.DTY_SHY_SW1) # Shelly Main Light + self.add(mqtt_client, props.STG_ZFE, loc, roo, props.FUN_MAL, props.DTY_TLI_SBT) # Tradfri Main Light + for i in range(1, 7): + self.add(mqtt_client, props.STG_ZFE, loc, roo, props.FUN_FLL, props.DTY_TLI_SBT, i) # Tradfri Main Light + self.add(mqtt_client, props.STG_ZFE, loc, roo, props.FUN_XTR, props.DTY_SPP_SW1) # Tradfri Main Light + self.add(mqtt_client, props.STG_ZFE, loc, roo, props.FUN_XST, props.DTY_SPP_SW1) # Tradfri Main Light + self.add(mqtt_client, props.STG_ZFE, loc, roo, props.FUN_HEA, props.DTY_BVL_xxx) # Brennenstuhl Heatingvalve + + ####### + # STW # + ####### + loc = props.LOC_STW + # FLOOR + roo = props.ROO_STW + # + self.add(mqtt_client, props.STG_SHE, loc, roo, props.FUN_MAL, props.DTY_SHY_SW1) # Shelly Main Light + self.add(mqtt_client, props.STG_ZFW, loc, roo, props.FUN_MSE, props.DTY_SMS_xxx, 1) # Motion Sensor Ground Floor + self.add(mqtt_client, props.STG_ZFE, loc, roo, props.FUN_MSE, props.DTY_SMS_xxx, 2) # Motion Sensor Ground Floor + + def add(self, mqtt_client, stg, loc, roo, fun, dty, num=None): + """Method to initilise a device + + Args: + stg (numeric): Source transmittion group (see SIS_* in props) + loc (numeric): Location (see LOC_* in props) + roo (numeric): Room (see ROO_* in props) + fun (numeric): Function (see FUN_* in props) + dty (numeric): Device type (see DTP_* in props) + num (numeric): Device number in case of multiple devices + """ + topic = self.__topic__(stg, loc, roo, fun, num) + dev_class = props.dty_repr(dty) + if dev_class is None: + logger.warning('Device type %d is not yet implemented. Topic %s will not be supported.', dty, topic) + else: + self[topic] = dev_class(mqtt_client, topic) + + def get(self, stg, loc, roo, fun, num=None): + """Method to get a device + + Args: + stg (numeric): Source transmittion group (see SIS_* in props) + loc (numeric): Location (see LOC_* in props) + roo (numeric): Room (see ROO_* in props) + fun (numeric): Function (see FUN_* in props) + num (numeric): Device number in case of multiple devices + """ + return self[self.__topic__(stg, loc, roo, fun, num)] + + def __topic__(self, stg, loc, roo, fun, num): + if num is None: + postfix = "" + else: + postfix = "_%d" % num + # + if stg in [props.STG_ZFE, props.STG_ZFW, props.STG_ZGW]: + # Temporary to fit to current implementation + return '/'.join([ + props.stg_repr(stg), + props.roo_repr(roo), + props.fun_repr(fun) + ]) + postfix + else: + return '/'.join([ + props.stg_repr(stg), + props.loc_repr(loc), + props.roo_repr(roo), + props.fun_repr(fun) + ]) + postfix diff --git a/props.py b/props.py new file mode 100644 index 0000000..52f4038 --- /dev/null +++ b/props.py @@ -0,0 +1,185 @@ +import devices + + +# +# Device TYpe definitions +# +DTY_SHY_SW1 = 1 +""" Shelly """ +DTY_TLI_Sxx = 2 +""" Tradfri Light (Switching only) """ +DTY_TLI_SBx = 3 +""" Tradfri Light (Switching and Brightnes) """ +DTY_TLI_SBT = 4 +""" Tradfri Light (Switching, Brightnes and Colortemperature) """ +DTY_TIN_5xx = 5 +""" Tradfri Input Device (5 Buttons) """ +DTY_LLI_SBT = 6 +""" Livarno Light (Switching, Brightnes and Colortemperature) """ +DTY_BVL_xxx = 7 +""" Brennenstuhl Heatingvalve """ +DTY_SPP_SW1 = 8 +""" Silvercrest Powerplug """ +DTY_SMS_xxx = 9 +""" Silvercrest Motion Sensor """ +DTY_MPP_4xx = 10 +""" My Powerplug (4 plugs) """ +DTY_MAS_xxx = 11 +""" My Audio status (MPD) """ +DTY_MRE_xxx = 12 +""" My Remote control """ +def dty_repr(dty): + return { + DTY_SHY_SW1: devices.shelly_sw1, + DTY_TLI_Sxx: devices.tradfri_sw, + DTY_TLI_SBx: devices.tradfri_sw_br, + DTY_TLI_SBT: devices.tradfri_sw_br_ct, + DTY_TIN_5xx: devices.tradfri_button, + DTY_LLI_SBT: devices.livarno_sw_br_ct, + DTY_BVL_xxx: devices.brennenstuhl_heatingvalve, + DTY_SPP_SW1: devices.silvercrest_powerplug, + DTY_SMS_xxx: devices.silvercrest_motion_sensor, + DTY_MPP_4xx: devices.my_powerplug, + DTY_MAS_xxx: devices.audio_status, + DTY_MRE_xxx: devices.remote, + }.get(dty) + +# +# Source Transmission Group +# +STG_ZGW = 1 +""" Zigbee ground floor west """ +STG_ZFW = 2 +""" Zigbee first floor west """ +STG_ZFE = 3 +""" Zigbee first floor east """ +STG_SHE = 4 +""" Shellies """ +STG_MYA = 5 +""" My Applications """ +def stg_repr(stg): + return { + STG_ZGW: 'zigbee/gfw', # TODO: -> zigbee_gfw + STG_ZFW: 'zigbee/ffw', # TODO: -> zigbee_ffw + STG_ZFE: 'zigbee/ffe', # TODO: -> zigbee_ffe + STG_SHE: 'shellies', + STG_MYA: 'my_apps', + }.get(stg) + +# +# LOCation +# +LOC_GFW = 1 +""" Grounf floor west """ +LOC_GFE = 2 +""" Ground floor east """ +LOC_STW = 3 +""" Stairway """ +LOC_FFW = 4 +""" First floor west """ +LOC_FFE = 5 +""" First floor east """ +def loc_repr(loc): + return { + LOC_GFW: 'gfw', + LOC_GFE: 'gfe', + LOC_STW: 'stw', + LOC_FFW: 'ffw', + LOC_FFE: 'ffe', + }.get(loc) + +# +# ROOms +# +ROO_DIN = 1 +""" Diningroom """ +ROO_KIT = 2 +""" Kitchen """ +ROO_LIV = 3 +""" Livingroom """ +ROO_FLO = 4 +""" Floor """ +ROO_SLP = 5 +""" Sleep """ +ROO_BAT = 6 +""" Bath """ +ROO_DIR = 7 +""" Dirk """ +ROO_MAR = 8 +""" Marion """ +ROO_JUL = 9 +""" Julian """ +ROO_STW = 10 +""" Stairway """ +def roo_repr(roo): + return { + ROO_DIN: 'diningroom', + ROO_KIT: 'kitchen', + ROO_LIV: 'livingroom', + ROO_FLO: 'floor', + ROO_SLP: 'sleep', + ROO_BAT: 'bath', + ROO_DIR: 'dirk', + ROO_MAR: 'marion', + ROO_JUL: 'julian', + ROO_STW: 'stairway', + }.get(roo) + +# +# FUNctions +# +FUN_MAL = 1 +""" Main Light """ +FUN_DEL = 2 +""" Desk Light """ +FUN_FLL = 3 +""" Floor Light """ +FUN_BLD = 4 +""" Bed Light Dirk """ +FUN_BLM = 5 +""" Bed Light Marion """ +FUN_HEA = 6 +""" Heating """ +FUN_MPP = 7 +""" Multiple Powerplugs """ +FUN_CTR = 8 +""" Control """ +FUN_CIR = 9 +""" Circulation Pump """ +FUN_GAR = 10 +""" Garland """ +FUN_XTR = 11 +""" X-Mas Tree """ +FUN_XST = 12 +""" X-Mas Star """ +FUN_MSE = 13 +""" Motion Sensor """ +FUN_RCA = 14 +""" Remote Control Amplifier """ +FUN_RCC = 15 +""" Remote Control CD-Player """ +FUN_ASS = 16 +""" Audio status spotify """ +FUN_ASM = 17 +""" Audio status mpd """ + +def fun_repr(fun): + return { + FUN_MAL: 'main_light', + FUN_DEL: 'desk_light', + FUN_FLL: 'floorlamp', # TODO: -> floor_light + FUN_BLD: 'bed_light_di', + FUN_BLM: 'bed_light_ma', + FUN_HEA: 'heating_valve', # TODO: -> heating + FUN_MPP: 'powerplug', + FUN_CTR: 'input_device', + FUN_CIR: 'circulation_pump', + FUN_GAR: 'garland', + FUN_XTR: 'xmas-tree', + FUN_XST: 'xmas-star', + FUN_MSE: 'motion_sensor', + FUN_RCA: 'remote_ctrl_amp', + FUN_RCC: 'remote_ctrl_cd', + FUN_ASS: 'audio_status_spotify', + FUN_ASM: 'audio_status_mpd', + }.get(fun)