timer and led status integrated in gui_light class
This commit is contained in:
parent
9907924e54
commit
94f089dd93
@ -504,10 +504,19 @@ class gui_light(tradfri_light):
|
||||
AUTOSEND = False
|
||||
#
|
||||
KEY_ENABLE = "enable"
|
||||
KEY_TIMER = "timer"
|
||||
KEY_LED_X = "led%d"
|
||||
|
||||
def __init__(self, mqtt_client, topic, enable_state=True, enable_brightness=False, enable_color_temp=False):
|
||||
super().__init__(mqtt_client, topic, enable_state, enable_brightness, enable_color_temp)
|
||||
self.add_callback(self.KEY_ENABLE, self.print_formatted, None)
|
||||
self.add_callback(self.KEY_TIMER, self.print_formatted, None)
|
||||
for i in range(0, 10):
|
||||
self.add_callback(self.KEY_LED_X % i, self.print_formatted, None)
|
||||
self.led_names = {}
|
||||
#
|
||||
self.maxvalue = None
|
||||
self.last_printed = None
|
||||
|
||||
def __init_data__(self, enable_state, enable_brightness, enable_color_temp):
|
||||
data = {}
|
||||
@ -518,6 +527,9 @@ class gui_light(tradfri_light):
|
||||
data[self.KEY_BRIGHTNESS] = 50
|
||||
if enable_color_temp:
|
||||
data[self.KEY_COLOR_TEMP] = 5
|
||||
data[self.KEY_TIMER] = '-'
|
||||
for i in range(0, 10):
|
||||
data[self.KEY_LED_X % i] = False
|
||||
self.store_data(**data)
|
||||
|
||||
def __rx__(self, client, userdata, message):
|
||||
@ -559,14 +571,18 @@ class gui_light(tradfri_light):
|
||||
else:
|
||||
print("Unknown command!")
|
||||
|
||||
def add_led_name(self, key, name):
|
||||
self.led_names[key] = name
|
||||
|
||||
def print_formatted(self, device, key, value):
|
||||
if value is not None:
|
||||
color = COLOR_GUI_ACTIVE
|
||||
device = " - ".join(self.topic.split('/')[1:])
|
||||
if key == self.KEY_STATE:
|
||||
if value == True:
|
||||
print(color + 10 * ' ' + u'\u25a0' + 9 * ' ' + " - ".join(self.topic.split('/')[1:]) + colored.attr("reset"))
|
||||
print(color + 10 * ' ' + u'\u25a0' + 9 * ' ' + device + colored.attr("reset"))
|
||||
else:
|
||||
print(color + 10 * ' ' + u'\u25a1' + 9*' ' + " - ".join(self.topic.split('/')[1:]) + colored.attr("reset"))
|
||||
print(color + 10 * ' ' + u'\u25a1' + 9 * ' ' + device + colored.attr("reset"))
|
||||
elif key == self.KEY_ENABLE:
|
||||
self.print_formatted(device, self.KEY_BRIGHTNESS, self.data.get(self.KEY_BRIGHTNESS))
|
||||
self.print_formatted(device, self.KEY_COLOR_TEMP, self.data.get(self.KEY_COLOR_TEMP))
|
||||
@ -577,8 +593,26 @@ class gui_light(tradfri_light):
|
||||
sys.stdout.write(color)
|
||||
sys.stdout.write('B' if key == self.KEY_BRIGHTNESS else 'C')
|
||||
sys.stdout.write(percent_bar(value))
|
||||
sys.stdout.write("%3d%%" % value + 5 * " ")
|
||||
print(" - ".join(self.topic.split('/')[1:]) + colored.attr("reset"))
|
||||
print("%3d%%" % value + 5 * " " + device + colored.attr("reset"))
|
||||
elif key == self.KEY_TIMER:
|
||||
if isinstance(value, (int, float, complex)) and not isinstance(value, bool):
|
||||
if self.maxvalue is None:
|
||||
self.maxvalue = value
|
||||
disp_value = value
|
||||
perc = disp_value / self.maxvalue * 100
|
||||
else:
|
||||
disp_value = 0
|
||||
perc = 0
|
||||
self.maxvalue = None
|
||||
self.last_printed = None
|
||||
if self.last_printed is None or abs(self.last_printed - perc) >= 4.95:
|
||||
print(color + 't' + percent_bar(perc) + '%3d%%' % perc + 5 * ' ' + device + ' (%.1f)' % disp_value + colored.attr('reset'))
|
||||
self.last_printed = perc
|
||||
elif key.startswith(self.KEY_LED_X[:-2]):
|
||||
led = green_led() if value else grey_led()
|
||||
ledname = '(%s)' % self.led_names.get(key, key)
|
||||
devicename = ' - '.join(self.topic.split('/')[1:])
|
||||
print(10 * ' ' + led + 9 * ' ' + COLOR_GUI_ACTIVE + devicename + ' ' + ledname + colored.attr("reset"))
|
||||
|
||||
|
||||
class tradfri_button(base):
|
||||
@ -676,34 +710,6 @@ class remote(base):
|
||||
print(COLOR_REMOTE + 10 * ' ' + icon + 6 * ' ' + devicename + colored.attr("reset"))
|
||||
|
||||
|
||||
class gui_timer(base):
|
||||
AUTOSEND = False
|
||||
|
||||
def __init__(self, mqtt_client, topic):
|
||||
super().__init__(mqtt_client, topic)
|
||||
self.maxvalue = None
|
||||
self.last_printed = None
|
||||
|
||||
def __rx__(self, client, userdata, message):
|
||||
payload = payload_filter(message.payload)
|
||||
if message.topic.startswith(self.topic) and message.topic.endswith('/feedback/set'):
|
||||
if isinstance(payload, (int, float, complex)) and not isinstance(payload, bool):
|
||||
if self.maxvalue is None:
|
||||
self.maxvalue = payload
|
||||
perc = payload / self.maxvalue * 100
|
||||
if self.last_printed is None or abs(self.last_printed - perc) >= 4.8:
|
||||
sys.stdout.write(COLOR_GUI_ACTIVE + 't' + percent_bar(perc))
|
||||
print('%3d%%' % perc + 2 * ' ' + ' - '.join(self.topic.split('/')[1:]) + ' (%.1f)' % payload + colored.attr('reset'))
|
||||
self.last_printed = perc
|
||||
else:
|
||||
self.maxvalue = None
|
||||
self.last_printed = None
|
||||
sys.stdout.write(COLOR_GUI_ACTIVE + 't' + percent_bar(0))
|
||||
print('%3d%%' % 0 + 2 * ' ' + ' - '.join(self.topic.split('/')[1:]) + colored.attr('reset'))
|
||||
else:
|
||||
print("Unknown Message")
|
||||
|
||||
|
||||
class brennenstuhl_radiator_valve(base):
|
||||
TEMP_RANGE = [10, 30]
|
||||
#
|
||||
|
@ -1,6 +1,6 @@
|
||||
import config
|
||||
from __simulation__.devices import shelly, silvercrest_powerplug, tradfri_light, tradfri_button, silvercrest_motion_sensor, my_powerplug, remote, brennenstuhl_radiator_valve
|
||||
from __simulation__.devices import gui_light, gui_led_array, gui_timer, gui_radiator_valve
|
||||
from __simulation__.devices import gui_light, gui_led_array, gui_radiator_valve
|
||||
import inspect
|
||||
|
||||
|
||||
@ -136,7 +136,6 @@ class ffe_kitchen(base):
|
||||
self.circulation_pump = shelly(mqtt_client, config.TOPIC_FFE_KITCHEN_CIRCULATION_PUMP_SHELLY,
|
||||
input_0_func=shelly.INPUT_FUNC_OUT1_TRIGGER, output_0_auto_off=10*60)
|
||||
self.circulation_pump.add_channel_name(shelly.KEY_OUTPUT_0, "Circulation Pump")
|
||||
self.gui_timer_circulation_pump = gui_timer(mqtt_client, config.TOPIC_FFE_KITCHEN_CIRCULATION_PUMP_GUI_TIMER)
|
||||
|
||||
|
||||
class ffe_diningroom(base):
|
||||
@ -206,6 +205,8 @@ class ffe(base):
|
||||
class stairway(base):
|
||||
def __init__(self, mqtt_client):
|
||||
self.gui_main_light = gui_light(mqtt_client, config.TOPIC_STW_STAIRWAY_MAIN_LIGHT_GUI, True, False, False)
|
||||
self.gui_main_light.add_led_name(self.gui_main_light.KEY_LED_X % 0, "Motion Ground Floor")
|
||||
self.gui_main_light.add_led_name(self.gui_main_light.KEY_LED_X % 1, "Motion First Floor")
|
||||
self.main_light = shelly(mqtt_client, config.TOPIC_STW_STAIRWAY_MAIN_LIGHT_SHELLY, input_0_func=shelly.INPUT_FUNC_OUT1_TRIGGER)
|
||||
self.main_light.add_channel_name(shelly.KEY_OUTPUT_0, "Main Light")
|
||||
self.motion_sensor_gf = silvercrest_motion_sensor(mqtt_client, config.TOPIC_STW_STAIRWAY_MAIN_LIGHT_MOTION_SENSOR_GF)
|
||||
|
@ -186,6 +186,41 @@ class base(dict):
|
||||
return self.__previous__.get(key)
|
||||
|
||||
|
||||
class nodered_gui_leds(base):
|
||||
KEY_LED_0 = "led0"
|
||||
KEY_LED_1 = "led1"
|
||||
KEY_LED_2 = "led2"
|
||||
KEY_LED_3 = "led3"
|
||||
KEY_LED_4 = "led4"
|
||||
KEY_LED_5 = "led5"
|
||||
KEY_LED_6 = "led6"
|
||||
KEY_LED_7 = "led7"
|
||||
KEY_LED_8 = "led8"
|
||||
KEY_LED_9 = "led9"
|
||||
KEY_LED_LIST = [KEY_LED_0, KEY_LED_1, KEY_LED_2, KEY_LED_3, KEY_LED_4, KEY_LED_5, KEY_LED_6, KEY_LED_7, KEY_LED_8, KEY_LED_9]
|
||||
#
|
||||
TX_TYPE = base.TX_VALUE
|
||||
|
||||
def set_led(self, key, data):
|
||||
"""data: [True, False]"""
|
||||
self.logger.debug("Sending %s with content %s", key, str(data))
|
||||
self.pack(key, data)
|
||||
|
||||
|
||||
class nodered_gui_timer(base):
|
||||
KEY_TIMER = "timer"
|
||||
#
|
||||
TX_TYPE = base.TX_VALUE
|
||||
|
||||
def set_timer(self, data):
|
||||
"""data: numeric"""
|
||||
self.pack(self.KEY_TIMER, data)
|
||||
|
||||
def set_timer_mcb(self, device, key, data):
|
||||
self.logger.debug("Sending %s with content %s", key, str(data))
|
||||
self.set_timer(data)
|
||||
|
||||
|
||||
class shelly(base):
|
||||
KEY_OUTPUT_0 = "relay/0"
|
||||
KEY_OUTPUT_1 = "relay/1"
|
||||
@ -700,7 +735,7 @@ class nodered_gui_switch(nodered_gui_button):
|
||||
self.set_state(data)
|
||||
|
||||
|
||||
class nodered_gui_light(nodered_gui_switch):
|
||||
class nodered_gui_light(nodered_gui_switch, nodered_gui_leds, nodered_gui_timer):
|
||||
KEY_ENABLE = "enable"
|
||||
KEY_BRIGHTNESS = "brightness"
|
||||
KEY_COLOR_TEMP = "color_temp"
|
||||
@ -755,28 +790,6 @@ class nodered_gui_light(nodered_gui_switch):
|
||||
self.set_color_temp(data)
|
||||
|
||||
|
||||
class nodered_gui_leds(base):
|
||||
KEY_LED_0 = "led0"
|
||||
KEY_LED_1 = "led1"
|
||||
KEY_LED_2 = "led2"
|
||||
KEY_LED_3 = "led3"
|
||||
KEY_LED_4 = "led4"
|
||||
KEY_LED_5 = "led5"
|
||||
KEY_LED_6 = "led6"
|
||||
KEY_LED_7 = "led7"
|
||||
KEY_LED_8 = "led8"
|
||||
KEY_LED_9 = "led9"
|
||||
#
|
||||
TX_TYPE = base.TX_VALUE
|
||||
#
|
||||
RX_KEYS = [KEY_LED_0, KEY_LED_1, KEY_LED_2, KEY_LED_3, KEY_LED_4, KEY_LED_5, KEY_LED_6, KEY_LED_7, KEY_LED_8, KEY_LED_9]
|
||||
|
||||
def set_led(self, key, data):
|
||||
"""data: [True, False]"""
|
||||
self.logger.debug("Sending %s with content %s", key, str(data))
|
||||
self.pack(key, data)
|
||||
|
||||
|
||||
class brennenstuhl_heatingvalve(base):
|
||||
KEY_LINKQUALITY = "linkquality"
|
||||
KEY_BATTERY = "battery"
|
||||
|
@ -16,10 +16,8 @@ except ImportError:
|
||||
ROOT_LOGGER_NAME = 'root'
|
||||
logger = logging.getLogger(ROOT_LOGGER_NAME).getChild(__name__)
|
||||
|
||||
# TODO: implement devices.nodered_gui_timer (for circulation pump)
|
||||
# TODO: implement devices.nodered_gui_heatvalve incl. setpoint, boost, ... + replace led with timer
|
||||
# TODO: improve heating function
|
||||
# TODO: implement timer and motion leds for stairwasy
|
||||
# TODO: improve heating function (away mode (reduced setpoint), return to default button, default values in config)
|
||||
# TODO: improve devices.brennenstuhl_heatvalve
|
||||
# TODO: implement garland (incl. day events like sunset, sunrise, ...)
|
||||
# TODO: implement warning message
|
||||
|
@ -23,8 +23,7 @@ class common_circulation_pump(room_shelly):
|
||||
#
|
||||
self.main_light_shelly.add_callback(devices.shelly.KEY_OUTPUT_0, None, self.circ_pump_actions, True)
|
||||
#
|
||||
self.gui_timer_view = devices.nodered_gui_heatvalve(mqtt_client, config.TOPIC_FFE_KITCHEN_CIRCULATION_PUMP_GUI_TIMER)
|
||||
self.gui_timer_view.set_feedback('-')
|
||||
self.gui_main_light.set_timer('-')
|
||||
#
|
||||
self.ct = task.periodic(6, self.cyclic_task)
|
||||
self.pump_timer = None
|
||||
@ -34,18 +33,18 @@ class common_circulation_pump(room_shelly):
|
||||
def circ_pump_actions(self, device, key, data):
|
||||
if data is True:
|
||||
self.pump_timer = 10
|
||||
self.gui_timer_view.set_feedback(self.pump_timer)
|
||||
self.gui_main_light.set_timer(self.pump_timer)
|
||||
else:
|
||||
self.pump_timer = None
|
||||
self.gui_timer_view.set_feedback('-')
|
||||
self.gui_main_light.set_timer('-')
|
||||
|
||||
def cyclic_task(self, rt):
|
||||
if self.pump_timer is not None:
|
||||
if self.pump_timer <= 0:
|
||||
self.pump_timer = None
|
||||
self.gui_timer_view.set_feedback('-')
|
||||
self.gui_main_light.set_timer('-')
|
||||
else:
|
||||
self.gui_timer_view.set_feedback(self.pump_timer)
|
||||
self.gui_main_light.set_timer(self.pump_timer)
|
||||
self.pump_timer -= self.ct.cycle_time / 60
|
||||
|
||||
|
||||
|
@ -43,7 +43,7 @@ class brightness_choose_n_action(object):
|
||||
callback_device: A device for installing callback which are executed, when the device is switched on or off. It needs the following method:
|
||||
* .add_callback(key, data or None, callback, on_changes_only)
|
||||
"""
|
||||
if len(self.brightness_device_list) >= len(devices.nodered_gui_leds.RX_KEYS):
|
||||
if len(self.brightness_device_list) >= len(devices.nodered_gui_leds.KEY_LED_LIST):
|
||||
raise ValueError("Number of devices is limited by number of leds in devices.nodered_gui_leds.")
|
||||
self.brightness_device_list.append(brightness_device)
|
||||
self.callback_device_list.append((callback_device, callback_key))
|
||||
@ -61,7 +61,7 @@ class brightness_choose_n_action(object):
|
||||
|
||||
def update_active_device_led(self):
|
||||
for i in range(0, len(self.brightness_device_list)):
|
||||
self.gui_led_active_device.set_led(devices.nodered_gui_leds.RX_KEYS[i], self.active_device_state == i)
|
||||
self.gui_led_active_device.set_led(devices.nodered_gui_leds.KEY_LED_LIST[i], self.active_device_state == i)
|
||||
|
||||
def choose_prev_device(self, device=None, key=None, data=None):
|
||||
if self.active_device_state is not None:
|
||||
|
@ -59,9 +59,11 @@ class room_shelly(room):
|
||||
|
||||
|
||||
class room_shelly_motion_sensor(room_shelly):
|
||||
def __init__(self, mqtt_client, topic_shelly, topic_gui, topic_motion_sensor_1, topic_motion_sensor_2=None, timer_value=config.DEFAULT_ON_TIME_LIGHT):
|
||||
def __init__(self, mqtt_client, topic_shelly, topic_gui, topic_motion_sensor_1, topic_motion_sensor_2=None, timer_value=30):
|
||||
super().__init__(mqtt_client, topic_shelly, topic_gui)
|
||||
self.timer_value = timer_value
|
||||
self.motion_detected_1 = False
|
||||
self.motion_detected_2 = False
|
||||
#
|
||||
self.main_light_shelly.add_callback(devices.shelly.KEY_OUTPUT_0, True, self.reload_timer, True)
|
||||
self.main_light_shelly.add_callback(devices.shelly.KEY_OUTPUT_0, False, self.reset_timer, True)
|
||||
@ -79,11 +81,13 @@ class room_shelly_motion_sensor(room_shelly):
|
||||
cyclic_task.run()
|
||||
|
||||
def set_motion_detected(self, device, key, data):
|
||||
if now() < sunrise_time(60) or now() > sunset_time(-60) or data is False:
|
||||
if device == self.motion_sensor_silvercrest_1:
|
||||
self.motion_detected_1 = data
|
||||
elif device == self.motion_sensor_silvercrest_2:
|
||||
self.motion_detected_2 = data
|
||||
self.gui_main_light.set_led(devices.nodered_gui_light.KEY_LED_0, self.motion_detected_1)
|
||||
self.gui_main_light.set_led(devices.nodered_gui_light.KEY_LED_1, self.motion_detected_2)
|
||||
if now() < sunrise_time(60) or now() > sunset_time(-60):
|
||||
if data is True:
|
||||
logger.info("%s: Motion detected - Switching on main light %s", device.topic, self.main_light_shelly.topic)
|
||||
self.main_light_shelly.set_output_0(True)
|
||||
@ -99,12 +103,17 @@ class room_shelly_motion_sensor(room_shelly):
|
||||
def cyclic_task(self, cyclic_task):
|
||||
if self.main_light_timer is not None:
|
||||
if self.main_light_timer <= 0:
|
||||
if not self.motion_detected_1 and not self.motion_detected_2:
|
||||
logger.info("No motion and time ran out - Switching off main light %s", self.main_light_shelly.topic)
|
||||
self.main_light_shelly.set_output_0(False)
|
||||
self.main_light_timer = None
|
||||
else:
|
||||
self.gui_main_light.set_timer(self.main_light_timer)
|
||||
if (self.motion_detected_1 or self.motion_detected_2) and self.main_light_timer <= self.timer_value / 10:
|
||||
self.main_light_timer = self.timer_value / 10
|
||||
else:
|
||||
self.main_light_timer -= cyclic_task.cycle_time
|
||||
else:
|
||||
self.gui_main_light.set_timer('-')
|
||||
|
||||
|
||||
class room_shelly_tradfri_light(room_shelly):
|
||||
|
@ -17,5 +17,5 @@ class stairway(room_shelly_motion_sensor):
|
||||
def __init__(self, mqtt_client):
|
||||
# http://shelly1-3494546A9364
|
||||
super().__init__(mqtt_client, config.TOPIC_STW_STAIRWAY_MAIN_LIGHT_SHELLY, config.TOPIC_STW_STAIRWAY_MAIN_LIGHT_GUI,
|
||||
config.TOPIC_STW_STAIRWAY_MAIN_LIGHT_MOTION_SENSOR_GF,
|
||||
config.TOPIC_STW_STAIRWAY_MAIN_LIGHT_MOTION_SENSOR_FF, config.TOPIC_STW_STAIRWAY_MAIN_LIGHT_MIN_ON_TIME)
|
||||
config.TOPIC_STW_STAIRWAY_MAIN_LIGHT_MOTION_SENSOR_GF, config.TOPIC_STW_STAIRWAY_MAIN_LIGHT_MOTION_SENSOR_FF,
|
||||
timer_value=config.USER_ON_TIME_STAIRWAYS)
|
||||
|
Loading…
x
Reference in New Issue
Block a user