From 398d74ee813537664aa4f9f6e1f7db7e173031b9 Mon Sep 17 00:00:00 2001
From: Dirk Alders <dirk@mount-mockery.de>
Date: Sat, 11 Feb 2023 19:46:49 +0100
Subject: [PATCH] Device information added (comment); clean up

---
 base.py                       |   1 -
 devices/__init__.py           | 208 ++++++++++++++++++++++++++++++++--
 function/ground_floor_west.py |   8 +-
 function/rooms.py             |   6 +-
 smart_brain.py                |   2 +-
 5 files changed, 208 insertions(+), 17 deletions(-)

diff --git a/base.py b/base.py
index 1897931..8023118 100644
--- a/base.py
+++ b/base.py
@@ -11,7 +11,6 @@ class common_base(dict):
 
     def __init__(self, default_values=None):
         super().__init__(default_values or self.DEFAULT_VALUES)
-        self['__type__'] = self.__class__.__name__
         #
         self.__callback_list__ = []
         self.logger = logging.getLogger(ROOT_LOGGER_NAME).getChild("devices")
diff --git a/devices/__init__.py b/devices/__init__.py
index b7f15a4..2e4220e 100644
--- a/devices/__init__.py
+++ b/devices/__init__.py
@@ -199,6 +199,35 @@ class base(mqtt_base):
 
 
 class shelly(base):
+    """ Communication (MQTT)
+
+        shelly
+            +- relay
+            |      +- 0 ["on" / "off"]              <- status 
+            |      |  +- command ["on"/ "off"]      <- command
+            |      |  +- energy [numeric]           <- status
+            |      +- 1 ["on" / "off"]              <- status
+            |         +- command ["on"/ "off"]      <- command
+            |         +- energy [numeric]           <- status
+            +- input
+            |      +- 0 [0 / 1]                     <- status
+            |      +- 1 [0 / 1]                     <- status
+            +- input_event
+            |      +- 0                             <- status
+            |      +- 1                             <- status
+            +- logpush
+            |      +- 0 [0 / 1]                     <- status
+            |      +- 1 [0 / 1]                     <- status
+            +- temperature [numeric] °C             <- status
+            +- temperature_f [numeric] F            <- status
+            +- overtemperature [0 / 1]              <- status
+            +- id                                   <- status
+            +- model                                <- status
+            +- mac                                  <- status
+            +- ip                                   <- status
+            +- new_fw                               <- status
+            +- fw_ver                               <- status
+    """
     KEY_OUTPUT_0 = "relay/0"
     KEY_OUTPUT_1 = "relay/1"
     KEY_INPUT_0 = "input/0"
@@ -343,6 +372,19 @@ class shelly(base):
 
 
 class silvercrest_powerplug(base):
+    """ Communication (MQTT)
+
+        silvercrest_powerplug {
+                            |      "state": ["ON" / "OFF"]
+                            |      "linkquality": [0...255] lqi
+                            | }
+                            +- get {
+                            |           "state": ""
+                            |      }
+                            +- set {
+                                        "state": ["ON" / "OFF"]
+                                   }
+    """
     KEY_LINKQUALITY = "linkquality"
     KEY_OUTPUT_0 = "state"
     #
@@ -389,6 +431,17 @@ class silvercrest_powerplug(base):
 
 
 class silvercrest_motion_sensor(base):
+    """ Communication (MQTT)
+
+        silvercrest_motion_sensor {
+                                      battery: [0...100] %
+                                      battery_low: [True, False]
+                                      linkquality: [0...255] lqi
+                                      occupancy: [True, False]
+                                      tamper: [True, False]
+                                      voltage: [0...] mV
+                                  }
+    """
     KEY_BATTERY = "battery"
     KEY_BATTERY_LOW = "battery_low"
     KEY_LINKQUALITY = "linkquality"
@@ -426,6 +479,21 @@ class silvercrest_motion_sensor(base):
 
 
 class my_powerplug(base):
+    """ Communication (MQTT)
+
+        my_powerplug
+                   +- output
+                           +- 1 [True, False]                   <- status
+                           |  +- set [True, False, "toggle"]    <- command
+                           +- 2 [True, False]                   <- status
+                           |  +- set [True, False, "toggle"]    <- command
+                           +- 3 [True, False]                   <- status
+                           |  +- set [True, False, "toggle"]    <- command
+                           +- 4 [True, False]                   <- status
+                           |  +- set [True, False, "toggle"]    <- command
+                           +- all
+                              +- set [True, False, "toggle"]    <- command
+    """
     KEY_OUTPUT_0 = "output/1"
     KEY_OUTPUT_1 = "output/2"
     KEY_OUTPUT_2 = "output/3"
@@ -533,6 +601,31 @@ class my_powerplug(base):
 
 
 class tradfri_light(base):
+    """ Communication (MQTT)
+
+        tradfri_light {
+                    |      "state": ["ON" / "OFF" / "TOGGLE"]
+                    |      "linkquality": [0...255] lqi
+                    |      "brightness": [0...254]
+                    |      "color_mode": ["color_temp"]
+                    |      "color_temp": ["coolest", "cool", "neutral", "warm", "warmest", 250...454]
+                    |      "color_temp_startup": ["coolest", "cool", "neutral", "warm", "warmest", "previous", 250...454]
+                    |      "update": []
+                    | }
+                    +- get {
+                    |           "state": ""
+                    |      }
+                    +- set {
+                                "state": ["ON" / "OFF"]
+                                "brightness": [0...256]
+                                "color_temp": [250...454]
+                                "transition": [0...] seconds
+                                "brightness_move": [-X...0...X] X/s
+                                "brightness_step": [-X...0...X]
+                                "color_temp_move": [-X...0...X] X/s
+                                "color_temp_step": [-X...0...X]
+                            }
+    """
     KEY_LINKQUALITY = "linkquality"
     KEY_OUTPUT_0 = "state"
     KEY_BRIGHTNESS = "brightness"
@@ -635,6 +728,30 @@ class tradfri_light(base):
 
 
 class tradfri_button(base):
+    """ Communication (MQTT)
+
+        tradfri_button {
+                            "action": [
+                                           "arrow_left_click",
+                                           "arrow_left_hold",
+                                           "arrow_left_release",
+                                           "arrow_right_click",
+                                           "arrow_right_hold",
+                                           "arrow_right_release",
+                                           "brightness_down_click",
+                                           "brightness_down_hold",
+                                           "brightness_down_release",
+                                           "brightness_up_click",
+                                           "brightness_up_hold",
+                                           "brightness_up_release",
+                                           "toggle"
+                                      ]
+                            "action_duration": [0...] s
+                            "battery": [0...100] %
+                            "linkquality": [0...255] lqi
+                            "update": []
+                       }
+    """
     ACTION_TOGGLE = "toggle"
     ACTION_BRIGHTNESS_UP = "brightness_up_click"
     ACTION_BRIGHTNESS_DOWN = "brightness_down_click"
@@ -685,6 +802,30 @@ class tradfri_button(base):
 
 
 class brennenstuhl_heatingvalve(base):
+    """ Communication (MQTT)
+
+        brennenstuhl_heatingvalve {
+                                |      "away_mode": ["ON", "OFF"]
+                                |      "battery": [0...100] %
+                                |      "child_lock": ["LOCK", "UNLOCK"]
+                                |      "current_heating_setpoint": [5...30] °C
+                                |      "linkquality": [0...255] lqi
+                                |      "local_temperature": [numeric] °C
+                                |      "preset": ["manual", ...]
+                                |      "system_mode": ["heat", ...]
+                                |      "valve_detection": ["ON", "OFF"]
+                                |      "window_detection": ["ON", "OFF"]
+                                | }
+                                +- set {
+                                           "away_mode": ["ON", "OFF", "TOGGLE"]
+                                           "child_lock": ["LOCK", "UNLOCK"]
+                                           "current_heating_setpoint": [5...30] °C
+                                           "preset": ["manual", ...]
+                                           "system_mode": ["heat", ...]
+                                           "valve_detection": ["ON", "OFF", "TOGGLE"]
+                                           "window_detection": ["ON", "OFF", "TOGGLE"]
+                                       }
+    """
     KEY_LINKQUALITY = "linkquality"
     KEY_BATTERY = "battery"
     KEY_HEATING_SETPOINT = "current_heating_setpoint"
@@ -750,6 +891,56 @@ class brennenstuhl_heatingvalve(base):
 
 
 class remote(base):
+    """ Communication (MQTT)
+
+        remote (RAS5)                               <- command
+             +- CD [dc]
+             +- LINE1 [dc]
+             +- LINE2 [dc]
+             +- LINE3 [dc]
+             +- MUTE [dc]
+             +- POWER [dc]
+             +- VOLDOWN [dc]
+             +- VOLUP [dc]
+             +- PHONO [dc]
+             +- DOCK [dc]
+
+        remote (EUR642100)                          <- command
+             +- OPEN_CLOSE [dc]
+             +- VOLDOWN [dc]
+             +- VOLUP [dc]
+             +- ONE [dc]
+             +- TWO [dc]
+             +- THREE [dc]
+             +- FOUR [dc]
+             +- FIVE [dc]
+             +- SIX [dc]
+             +- SEVEN [dc]
+             +- EIGHT [dc]
+             +- NINE [dc]
+             +- ZERO [dc]
+             +- TEN [dc]
+             +- TEN_PLUS [dc]
+             +- PROGRAM [dc]
+             +- CLEAR [dc]
+             +- RECALL [dc]
+             +- TIME_MODE [dc]
+             +- A_B_REPEAT [dc]
+             +- REPEAT [dc]
+             +- RANDOM [dc]
+             +- AUTO_CUE [dc]
+             +- TAPE_LENGTH [dc]
+             +- SIDE_A_B [dc]
+             +- TIME_FADE [dc]
+             +- PEAK_SEARCH [dc]
+             +- SEARCH_BACK [dc]
+             +- SEARCH_FOR [dc]
+             +- TRACK_NEXT [dc]
+             +- TRACK_PREV [dc]
+             +- STOP [dc]
+             +- PAUSE [dc]
+             +- PLAY [dc]
+    """
     KEY_CD = "CD"
     KEY_LINE1 = "LINE1"
     KEY_LINE3 = "LINE3"
@@ -796,12 +987,19 @@ class remote(base):
         self.set_volume_up(False)
 
 
-class status(base):
+class audio_status(base):
+    """ Communication (MQTT)
+
+        audio_status
+            +- state [True, False]                  <- status
+            +- title [text]                         <- status
+    """
     KEY_STATE = "state"
+    KEY_TITLE = "title"
     #
     TX_TYPE = base.TX_VALUE
     #
-    RX_KEYS = [KEY_STATE]
+    RX_KEYS = [KEY_STATE, KEY_TITLE]
 
     def set_state(self, num, data):
         """data: [True, False]"""
@@ -810,9 +1008,3 @@ class status(base):
     def set_state_mcb(self, device, key, data):
         self.logger.info("Changing state to %s", str(data))
         self.set_state(data)
-
-
-class audio_status(status):
-    KEY_TITLE = "title"
-    #
-    RX_KEYS = [status.KEY_STATE, KEY_TITLE]
diff --git a/function/ground_floor_west.py b/function/ground_floor_west.py
index fd2afea..3577fe1 100644
--- a/function/ground_floor_west.py
+++ b/function/ground_floor_west.py
@@ -140,13 +140,13 @@ class ground_floor_west_dirk(room):
 
         # Mediaplayer - Amplifier auto on
         self.powerplug_common.add_callback(self.KEY_POWERPLUG_CD_PLAYER, None, self.powerplug_common.set_output_0_mcb, True)
-        self.spotify_state.add_callback(devices.status.KEY_STATE, None, self.powerplug_common.set_output_0_mcb, True)
-        self.mpd_state.add_callback(devices.status.KEY_STATE, None, self.powerplug_common.set_output_0_mcb, True)
+        self.spotify_state.add_callback(devices.audio_status.KEY_STATE, None, self.powerplug_common.set_output_0_mcb, True)
+        self.mpd_state.add_callback(devices.audio_status.KEY_STATE, None, self.powerplug_common.set_output_0_mcb, True)
         # Mediaplayer - Audio source selection
         self.powerplug_common.add_callback(self.KEY_POWERPLUG_AMPLIFIER, True, self.audio_source_selector, True)
         self.powerplug_common.add_callback(self.KEY_POWERPLUG_CD_PLAYER, True, self.audio_source_selector, True)
-        self.spotify_state.add_callback(devices.status.KEY_STATE, True, self.audio_source_selector, True)
-        self.mpd_state.add_callback(devices.status.KEY_STATE, True, self.audio_source_selector, True)
+        self.spotify_state.add_callback(devices.audio_status.KEY_STATE, True, self.audio_source_selector, True)
+        self.mpd_state.add_callback(devices.audio_status.KEY_STATE, True, self.audio_source_selector, True)
         self.audio_source = self.AUDIO_SOURCE_PC
 
         # heating function
diff --git a/function/rooms.py b/function/rooms.py
index 2d2f9c6..d0c7836 100644
--- a/function/rooms.py
+++ b/function/rooms.py
@@ -41,15 +41,15 @@ class room_collection(object):
                 if sub.__class__.__bases__[0].__name__ in self.ALLOWED_CLASSES:
                     sub.all_off()
 
-    def all_devices(self, object_to_analyse=None):
+    def all_devices(self, object_to_analyse=None, depth=0):
         target = object_to_analyse or self
         #
         devices = []
         for name, obj in inspect.getmembers(target):
             if not callable(obj):                                       # sort out methods
                 try:
-                    if obj.__module__.startswith('function.'):
-                        devices.extend(self.all_devices(obj))           # rekurse in function instances
+                    if obj.__module__.startswith('function.') and not obj.__module__.endswith('.videv'):
+                        devices.extend(self.all_devices(obj, depth+1))           # rekurse in function instances
                     elif obj.__module__ == "devices":
                         devices.append(obj)
                 except AttributeError:
diff --git a/smart_brain.py b/smart_brain.py
index 658cc60..fb8a2c7 100644
--- a/smart_brain.py
+++ b/smart_brain.py
@@ -15,7 +15,7 @@ logger = logging.getLogger(config.APP_NAME)
 
 VERS_MAJOR = 1
 VERS_MINOR = 1
-VERS_PATCH = 1
+VERS_PATCH = 2
 
 INFO_TOPIC = "__info__"
 INFO_DATA = {