all_off functionality added

This commit is contained in:
Dirk Alders 2023-01-31 19:17:10 +01:00
parent 6b22855ab5
commit 6c1f81f0be
7 changed files with 135 additions and 80 deletions

View File

@ -1,11 +1,14 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# #
import config
import devices import devices
from function.stairway import stairway from function.stairway import stairway
from function.ground_floor_west import ground_floor_west_floor, ground_floor_west_marion, ground_floor_west_dirk from function.ground_floor_west import ground_floor_west
from function.first_floor_west import first_floor_west_julian, first_floor_west_living, first_floor_west_bath, first_floor_west_sleep from function.first_floor_west import first_floor_west
from function.first_floor_east import first_floor_east_floor, first_floor_east_kitchen, first_floor_east_dining, first_floor_east_sleep, first_floor_east_living from function.first_floor_east import first_floor_east
from function.rooms import room_collection
from function.videv import all_off
import inspect import inspect
import logging import logging
@ -19,31 +22,20 @@ logger = logging.getLogger(ROOT_LOGGER_NAME).getChild(__name__)
# TODO: implement warning message # TODO: implement warning message
class all_functions(object): class all_functions(room_collection):
def __init__(self, mqtt_client): def __init__(self, mqtt_client):
self.mqtt_client = mqtt_client super().__init__(mqtt_client)
#
self.__devices__ = None
# #
# Rooms # Rooms
# #
# stairway # stairway
self.stw_stairway = stairway(self.mqtt_client) self.stw = stairway(self.mqtt_client)
# ground floor west # ground floor west
self.gfw_floor = ground_floor_west_floor(self.mqtt_client) self.gfw = ground_floor_west(self.mqtt_client)
self.gfw_marion = ground_floor_west_marion(self.mqtt_client)
self.gfw_dirk = ground_floor_west_dirk(self.mqtt_client)
# first floor west # first floor west
self.ffw_julian = first_floor_west_julian(self.mqtt_client) self.ffw = first_floor_west(self.mqtt_client)
self.ffw_bath = first_floor_west_bath(self.mqtt_client)
self.ffw_living = first_floor_west_living(self.mqtt_client)
self.ffw_sleep = first_floor_west_sleep(self.mqtt_client)
# first floor east # first floor east
self.ffe_floor = first_floor_east_floor(self.mqtt_client) self.ffe = first_floor_east(self.mqtt_client)
self.ffe_kitchen = first_floor_east_kitchen(self.mqtt_client)
self.ffe_dining = first_floor_east_dining(self.mqtt_client)
self.ffe_sleep = first_floor_east_sleep(self.mqtt_client)
self.ffe_living = first_floor_east_living(self.mqtt_client)
# #
# Interactions # Interactions
# #
@ -55,71 +47,28 @@ class all_functions(object):
def init_cross_room_interactions(self): def init_cross_room_interactions(self):
# shelly dirk input 1 # shelly dirk input 1
self.last_gfw_dirk_input_1 = None self.last_gfw_dirk_input_1 = None
self.gfw_dirk.main_light_shelly.add_callback(devices.shelly.KEY_INPUT_1, None, self.gfw_dirk_input_1) self.gfw.dirk.main_light_shelly.add_callback(devices.shelly.KEY_INPUT_1, None, self.gfw_dirk_input_1)
# tradfri button ffe_sleep right click # tradfri button ffe_sleep right click
self.ffe_sleep.button_tradfri.add_callback(devices.tradfri_button.KEY_ACTION, self.ffe.sleep.button_tradfri.add_callback(devices.tradfri_button.KEY_ACTION,
devices.tradfri_button.ACTION_RIGHT, self.ffe_floor.main_light_shelly.toggle_output_0_mcb) devices.tradfri_button.ACTION_RIGHT, self.ffe.floor.main_light_shelly.toggle_output_0_mcb)
def init_off_functionality(self): def init_off_functionality(self):
##### TEMPORARY ################################################################################################################### # ALL OFF - Virtual device
# # Off Buttons self.videv_all_off = all_off(self.mqtt_client, config.TOPIC_ALL_OFF_VIDEV, self)
# self.gui_button_all_off = devices.nodered_gui_button(self.mqtt_client, "gui/all/common/off/button")
# self.gui_button_gfw_off = devices.nodered_gui_button(self.mqtt_client, "gui/gfw/common/off/button")
# self.gui_button_ffw_off = devices.nodered_gui_button(self.mqtt_client, "gui/ffw/common/off/button")
# self.gui_button_ffe_off = devices.nodered_gui_button(self.mqtt_client, "gui/ffe/common/off/button")
# #
# self.gui_button_all_off.add_callback(devices.nodered_gui_button.KEY_STATE, True, self.all_off)
# self.gui_button_gfw_off.add_callback(devices.nodered_gui_button.KEY_STATE, True, self.gfw_off)
# self.gui_button_ffw_off.add_callback(devices.nodered_gui_button.KEY_STATE, True, self.ffw_off)
# self.gui_button_ffe_off.add_callback(devices.nodered_gui_button.KEY_STATE, True, self.ffe_off)
##### TEMPORARY ###################################################################################################################
# ALL OFF - Long push stairway # ALL OFF - Long push stairway
self.stw_stairway.main_light_shelly.add_callback(devices.shelly.KEY_LONGPUSH_0, True, self.stw_stairway.main_light_shelly.flash_0_mcb) self.stw.stairway.main_light_shelly.add_callback(devices.shelly.KEY_LONGPUSH_0, True, self.stw.stairway.main_light_shelly.flash_0_mcb)
self.stw_stairway.main_light_shelly.add_callback(devices.shelly.KEY_LONGPUSH_0, True, self.all_off) self.stw.stairway.main_light_shelly.add_callback(devices.shelly.KEY_LONGPUSH_0, True, self.all_off)
# FFE ALL OFF - Long push ffe_floor # FFE ALL OFF - Long push ffe_floor
self.ffe_floor.main_light_shelly.add_callback(devices.shelly.KEY_LONGPUSH_0, True, self.ffe_floor.main_light_shelly.flash_0_mcb) self.ffe.floor.main_light_shelly.add_callback(devices.shelly.KEY_LONGPUSH_0, True, self.ffe.floor.main_light_shelly.flash_0_mcb)
self.ffe_floor.main_light_shelly.add_callback(devices.shelly.KEY_LONGPUSH_0, True, self.ffe_off) self.ffe.floor.main_light_shelly.add_callback(devices.shelly.KEY_LONGPUSH_0, True, self.ffe.all_off)
# FFE ALL OFF - Long push input device # FFE ALL OFF - Long push input device
self.ffe_sleep.button_tradfri.add_callback(devices.tradfri_button.KEY_ACTION, devices.tradfri_button.ACTION_RIGHT_LONG, self.ffe_off) self.ffe.sleep.button_tradfri.add_callback(devices.tradfri_button.KEY_ACTION, devices.tradfri_button.ACTION_RIGHT_LONG, self.ffe.all_off)
def gfw_dirk_input_1(self, device, key, data): def gfw_dirk_input_1(self, device, key, data):
if self.last_gfw_dirk_input_1 is not None: if self.last_gfw_dirk_input_1 is not None:
if self.last_gfw_dirk_input_1 != data: if self.last_gfw_dirk_input_1 != data:
self.gfw_floor.main_light_shelly.toggle_output_0_mcb(device, key, data) self.gfw.floor.main_light_shelly.toggle_output_0_mcb(device, key, data)
self.last_gfw_dirk_input_1 = data self.last_gfw_dirk_input_1 = data
def getmembers(self, prefix):
rv = []
for name, obj in inspect.getmembers(self):
if name.startswith(prefix) and obj.__module__.split('.')[0] == 'function' and len(obj.__module__.split('.')) == 2:
rv.append(obj)
return rv
def gfw_off(self, device=None, key=None, data=None):
logger.info("Switching \"ground floor west\" off.")
for gfw in self.getmembers('gfw'):
gfw.all_off()
def ffw_off(self, device=None, key=None, data=None):
logger.info("Switching \"first floor west\" off.")
for ffw in self.getmembers('ffw'):
ffw.all_off()
def ffe_off(self, device=None, key=None, data=None):
logger.info("Switching \"first floor east\" off.")
for ffe in self.getmembers('ffe'):
ffe.all_off()
def stw_off(self, device=None, key=None, data=None):
logger.info("Switching \"stairway\" off.")
for stw in self.getmembers('stw'):
stw.all_off()
def all_off(self, device=None, key=None, data=None):
for name, obj in inspect.getmembers(self):
parent_name = obj.__class__.__base__.__name__
if parent_name == "room":
obj.all_off()

View File

@ -5,7 +5,7 @@
import config import config
import devices import devices
from function.modules import brightness_choose_n_action, timer_on_activation, heating_function from function.modules import brightness_choose_n_action, timer_on_activation, heating_function
from function.rooms import room from function.rooms import room, room_collection
from function.videv import videv_switching, videv_switch_brightness, videv_switching_timer, videv_switch_brightness_color_temp, videv_heating, videv_multistate from function.videv import videv_switching, videv_switch_brightness, videv_switching_timer, videv_switch_brightness_color_temp, videv_heating, videv_multistate
import logging import logging
@ -16,6 +16,16 @@ except ImportError:
logger = logging.getLogger(ROOT_LOGGER_NAME).getChild(__name__) logger = logging.getLogger(ROOT_LOGGER_NAME).getChild(__name__)
class first_floor_east(room_collection):
def __init__(self, mqtt_client):
super().__init__(mqtt_client)
self.dining = first_floor_east_dining(mqtt_client)
self.floor = first_floor_east_floor(mqtt_client)
self.kitchen = first_floor_east_kitchen(mqtt_client)
self.livingroom = first_floor_east_living(mqtt_client)
self.sleep = first_floor_east_sleep(mqtt_client)
class first_floor_east_floor(room): class first_floor_east_floor(room):
def __init__(self, mqtt_client): def __init__(self, mqtt_client):
# #

View File

@ -5,7 +5,7 @@
import config import config
import devices import devices
from function.modules import heating_function from function.modules import heating_function
from function.rooms import room from function.rooms import room, room_collection
from function.videv import videv_switch_brightness, videv_switch_brightness_color_temp, videv_heating from function.videv import videv_switch_brightness, videv_switch_brightness_color_temp, videv_heating
import logging import logging
@ -17,6 +17,15 @@ except ImportError:
logger = logging.getLogger(ROOT_LOGGER_NAME).getChild(__name__) logger = logging.getLogger(ROOT_LOGGER_NAME).getChild(__name__)
class first_floor_west(room_collection):
def __init__(self, mqtt_client):
super().__init__(mqtt_client)
self.bath = first_floor_west_bath(mqtt_client)
self.julian = first_floor_west_julian(mqtt_client)
self.livingroom = first_floor_west_living(mqtt_client)
self.sleep = first_floor_west_sleep(mqtt_client)
class first_floor_west_julian(room): class first_floor_west_julian(room):
def __init__(self, mqtt_client): def __init__(self, mqtt_client):
# #

View File

@ -5,7 +5,7 @@
import config import config
import devices import devices
from function.modules import brightness_choose_n_action, heating_function, switched_light from function.modules import brightness_choose_n_action, heating_function, switched_light
from function.rooms import room from function.rooms import room, room_collection
from function.videv import videv_switching, videv_switch_brightness_color_temp, videv_heating, videv_multistate, videv_audio_player from function.videv import videv_switching, videv_switch_brightness_color_temp, videv_heating, videv_multistate, videv_audio_player
import logging import logging
import task import task
@ -17,6 +17,14 @@ except ImportError:
logger = logging.getLogger(ROOT_LOGGER_NAME).getChild(__name__) logger = logging.getLogger(ROOT_LOGGER_NAME).getChild(__name__)
class ground_floor_west(room_collection):
def __init__(self, mqtt_client):
super().__init__(mqtt_client)
self.dirk = ground_floor_west_dirk(mqtt_client)
self.floor = ground_floor_west_floor(mqtt_client)
self.marion = ground_floor_west_marion(mqtt_client)
class ground_floor_west_floor(room): class ground_floor_west_floor(room):
def __init__(self, mqtt_client): def __init__(self, mqtt_client):
# #

View File

@ -24,3 +24,19 @@ class room(object):
obj.all_off() obj.all_off()
except AttributeError: except AttributeError:
pass # not a module or has no method all_off pass # not a module or has no method all_off
class room_collection(object):
ALLOWED_CLASSES = ("room", "room_collection")
def __init__(self, mqtt_client):
self.mqtt_client = mqtt_client
def all_off(self, device=None, key=None, data=None):
logger.info("Switching all off \"%s\"", type(self).__name__)
for sub_name in dir(self):
# attribute name is not private
if not sub_name.startswith("__"):
sub = getattr(self, sub_name)
if sub.__class__.__bases__[0].__name__ in self.ALLOWED_CLASSES:
sub.all_off()

View File

@ -6,7 +6,7 @@ import config
import devices import devices
import logging import logging
from function.modules import motion_sensor_light from function.modules import motion_sensor_light
from function.rooms import room from function.rooms import room, room_collection
from function.videv import videv_switching_motion from function.videv import videv_switching_motion
try: try:
@ -16,7 +16,13 @@ except ImportError:
logger = logging.getLogger(ROOT_LOGGER_NAME).getChild(__name__) logger = logging.getLogger(ROOT_LOGGER_NAME).getChild(__name__)
class stairway(room): class stairway(room_collection):
def __init__(self, mqtt_client):
super().__init__(mqtt_client)
self.stairway = stairway_stairway(mqtt_client)
class stairway_stairway(room):
def __init__(self, mqtt_client): def __init__(self, mqtt_client):
# #
# Device initialisation # Device initialisation

View File

@ -11,7 +11,7 @@ Targets:
""" """
from base import mqtt_base from base import mqtt_base
import devices from function.rooms import room, room_collection
import json import json
import time import time
@ -258,3 +258,60 @@ class videv_audio_player(base):
super().capabilities super().capabilities
self.__capabilities__[self.KEY_TITLE] = {'display': True} self.__capabilities__[self.KEY_TITLE] = {'display': True}
return self.__capabilities__ return self.__capabilities__
class all_off(base):
ALLOWED_CLASSES = (room, room_collection, )
def __init__(self, mqtt_client, topic, room_collection):
super().__init__(mqtt_client, topic)
self.__room_collection__ = room_collection
# init __inst_dict__
self.__inst_dict__ = {}
self.__add_instances__("all", self.__room_collection__)
# register mqtt callbacks for all my keys
for key in self.__inst_dict__:
mqtt_client.add_callback(topic + "/" + key, self.all_off)
#
self.__tx_capabilities__()
def __check_inst_capabilities__(self, name, inst):
# fits to specified classes
if isinstance(inst, self.ALLOWED_CLASSES):
try:
# all_off method is callable
return callable(inst.all_off)
except AttributeError:
# all_off method does not exist
return False
return False
def __add_instances__(self, name, inst, level=0):
if self.__check_inst_capabilities__(name, inst):
# add given instance to my __inst_dict__
self.__inst_dict__[name] = inst
# iterate over all attribute names of instance
for sub_name in dir(inst):
# attribute name is not private
if not sub_name.startswith("__"):
sub = getattr(inst, sub_name)
# recurse with this object
if level == 0:
self.__add_instances__(sub_name, sub, level=level+1)
else:
self.__add_instances__(name + "/" + sub_name, sub, level=level+1)
def all_off(self, client, userdata, message):
key = message.topic[len(self.topic) + 1:]
self.__inst_dict__[key].all_off()
self.__tx_capabilities__()
@property
def capabilities(self):
if self.__capabilities__ is None:
self.__capabilities__ = {}
self.__capabilities__['__type__'] = self.__class__.__name__
for key in self.__inst_dict__:
self.__capabilities__[key] = {}
self.__capabilities__[key]['control'] = True
return self.__capabilities__