|
@@ -11,7 +11,7 @@ COLOR_SHELLY = colored.fg("light_magenta")
|
11
|
11
|
COLOR_POWERPLUG = colored.fg("light_cyan")
|
12
|
12
|
COLOR_LIGHT_ACTIVE = colored.fg("yellow")
|
13
|
13
|
COLOR_LIGHT_PASSIVE = COLOR_LIGHT_ACTIVE + colored.attr("dim")
|
14
|
|
-COLOR_MOTION_SENSOR = colored.fg("dark_orange_3b")
|
|
14
|
+COLOR_WARNINGS = colored.fg("dark_orange_3b")
|
15
|
15
|
COLOR_HEATING_VALVE = colored.fg("red")
|
16
|
16
|
COLOR_REMOTE = colored.fg("green")
|
17
|
17
|
|
|
@@ -125,8 +125,10 @@ class shelly(base):
|
125
|
125
|
KEY_INPUT_1 = "input/1"
|
126
|
126
|
KEY_LONGPUSH_0 = "longpush/0"
|
127
|
127
|
KEY_LONGPUSH_1 = "longpush/1"
|
|
128
|
+ KEY_TEMPERATURE = "temperature"
|
|
129
|
+ KEY_OVERTEMPERATURE = "overtemperature"
|
128
|
130
|
#
|
129
|
|
- BOOL_KEYS = [KEY_OUTPUT_0, KEY_OUTPUT_1, KEY_INPUT_0, KEY_INPUT_1, KEY_LONGPUSH_0, KEY_LONGPUSH_1, ]
|
|
131
|
+ BOOL_KEYS = [KEY_OUTPUT_0, KEY_OUTPUT_1, KEY_INPUT_0, KEY_INPUT_1, KEY_LONGPUSH_0, KEY_LONGPUSH_1, KEY_OVERTEMPERATURE, ]
|
130
|
132
|
#
|
131
|
133
|
INPUT_FUNC_OUT1_FOLLOW = "out1_follow"
|
132
|
134
|
INPUT_FUNC_OUT1_TRIGGER = "out1_trigger"
|
|
@@ -139,11 +141,13 @@ class shelly(base):
|
139
|
141
|
"get_input_0", "toggle_input_0",
|
140
|
142
|
"get_input_1", "toggle_input_1",
|
141
|
143
|
"trigger_input_0_longpress", "trigger_input_1_longpress",
|
|
144
|
+ "toggle_overtemperature",
|
142
|
145
|
]
|
143
|
146
|
|
144
|
147
|
def __init__(self, mqtt_client, topic, input_0_func=None, input_1_func=None, output_0_auto_off=None):
|
145
|
148
|
super().__init__(mqtt_client, topic, default_values={self.KEY_OUTPUT_0: False, self.KEY_OUTPUT_1: False,
|
146
|
|
- self.KEY_INPUT_0: False, self.KEY_INPUT_1: False})
|
|
149
|
+ self.KEY_INPUT_0: False, self.KEY_INPUT_1: False,
|
|
150
|
+ self.KEY_TEMPERATURE: 35.2, self.KEY_OVERTEMPERATURE: False})
|
147
|
151
|
#
|
148
|
152
|
self.__input_0_func = input_0_func
|
149
|
153
|
self.__input_1_func = input_1_func
|
|
@@ -154,6 +158,8 @@ class shelly(base):
|
154
|
158
|
# publish state changes
|
155
|
159
|
self.add_callback(self.KEY_OUTPUT_0, None, self.__send__, True)
|
156
|
160
|
self.add_callback(self.KEY_OUTPUT_1, None, self.__send__, True)
|
|
161
|
+ self.add_callback(self.KEY_TEMPERATURE, None, self.__send__, True)
|
|
162
|
+ self.add_callback(self.KEY_OVERTEMPERATURE, None, self.__send__, True)
|
157
|
163
|
#
|
158
|
164
|
if self.__output_0_auto_off__ is not None:
|
159
|
165
|
self.__delayed_off__ = task.delayed(float(self.__output_0_auto_off__), self.__auto_off__, self.KEY_OUTPUT_0)
|
|
@@ -164,6 +170,11 @@ class shelly(base):
|
164
|
170
|
#
|
165
|
171
|
self.__tx__((self.KEY_OUTPUT_0, self.KEY_OUTPUT_1))
|
166
|
172
|
|
|
173
|
+ def __int_to_ext__(self, key, value):
|
|
174
|
+ if key == self.KEY_OVERTEMPERATURE:
|
|
175
|
+ return int(value)
|
|
176
|
+ return super().__int_to_ext__(key, value)
|
|
177
|
+
|
167
|
178
|
def __rx__(self, client, userdata, message):
|
168
|
179
|
value = self.__payload_filter__(message.payload)
|
169
|
180
|
if message.topic.startswith(self.topic) and message.topic.endswith("/command"):
|
|
@@ -235,6 +246,11 @@ class shelly(base):
|
235
|
246
|
time.sleep(0.1)
|
236
|
247
|
self.set(self.KEY_INPUT_1, not self[self.KEY_INPUT_1])
|
237
|
248
|
self.set(self.KEY_LONGPUSH_1, False)
|
|
249
|
+ elif command == self.COMMANDS[10]:
|
|
250
|
+ if self.get(self.KEY_OVERTEMPERATURE):
|
|
251
|
+ self.warning_state_off()
|
|
252
|
+ else:
|
|
253
|
+ self.warning_state_on()
|
238
|
254
|
else:
|
239
|
255
|
print("%s: not yet implemented!" % command)
|
240
|
256
|
else:
|
|
@@ -246,6 +262,14 @@ class shelly(base):
|
246
|
262
|
channel = "(%s%s)" % (self.names.get(key, key), info)
|
247
|
263
|
self.print_formatted_light(COLOR_SHELLY, value, channel)
|
248
|
264
|
|
|
265
|
+ def warning_state_on(self):
|
|
266
|
+ self.set(self.KEY_TEMPERATURE, 78.3)
|
|
267
|
+ self.set(self.KEY_OVERTEMPERATURE, True)
|
|
268
|
+
|
|
269
|
+ def warning_state_off(self):
|
|
270
|
+ self.set(self.KEY_TEMPERATURE, 34.1)
|
|
271
|
+ self.set(self.KEY_OVERTEMPERATURE, False)
|
|
272
|
+
|
249
|
273
|
|
250
|
274
|
class my_powerplug(base):
|
251
|
275
|
KEY_OUTPUT_0 = "state"
|
|
@@ -312,8 +336,11 @@ class silvercrest_powerplug(base):
|
312
|
336
|
self.set(self.KEY_OUTPUT_0, self.__ext_to_int__(self.KEY_OUTPUT_0, state))
|
313
|
337
|
|
314
|
338
|
def __tx__(self, keys_changed):
|
|
339
|
+ data = {}
|
|
340
|
+ for key in self:
|
|
341
|
+ data[key] = self.__int_to_ext__(key, self[key])
|
315
|
342
|
for key in keys_changed:
|
316
|
|
- self.mqtt_client.send(self.topic + '/' + key, self.__int_to_ext__(self.KEY_OUTPUT_0, self.get(self.KEY_OUTPUT_0)))
|
|
343
|
+ self.mqtt_client.send(self.topic, json.dumps(data))
|
317
|
344
|
|
318
|
345
|
def command(self, command):
|
319
|
346
|
if command in self.COMMANDS:
|
|
@@ -454,20 +481,23 @@ class brennenstuhl_heating_valve(base):
|
454
|
481
|
#
|
455
|
482
|
KEY_TEMPERATURE_SETPOINT = "current_heating_setpoint"
|
456
|
483
|
KEY_TEMPERATURE = "local_temperature"
|
|
484
|
+ KEY_BATTERY = "battery"
|
457
|
485
|
#
|
458
|
486
|
COMMANDS = [
|
459
|
|
- "get_temperature_setpoint", "set_temperature_setpoint", "set_local_temperature",
|
|
487
|
+ "get_temperature_setpoint", "set_temperature_setpoint", "set_local_temperature", "set_battery",
|
460
|
488
|
]
|
461
|
489
|
|
462
|
490
|
def __init__(self, mqtt_client, topic):
|
463
|
491
|
super().__init__(mqtt_client, topic, default_values={
|
464
|
492
|
self.KEY_TEMPERATURE_SETPOINT: 20,
|
465
|
493
|
self.KEY_TEMPERATURE: 20.7,
|
|
494
|
+ self.KEY_BATTERY: 97,
|
466
|
495
|
})
|
467
|
496
|
#
|
468
|
497
|
self.add_callback(self.KEY_TEMPERATURE_SETPOINT, None, self.print_formatted, True)
|
469
|
498
|
self.add_callback(self.KEY_TEMPERATURE_SETPOINT, None, self.__send__, True)
|
470
|
499
|
self.add_callback(self.KEY_TEMPERATURE, None, self.__send__, True)
|
|
500
|
+ self.add_callback(self.KEY_BATTERY, None, self.__send__, True)
|
471
|
501
|
#
|
472
|
502
|
self.__tx__((self.KEY_TEMPERATURE_SETPOINT, ))
|
473
|
503
|
|
|
@@ -495,6 +525,8 @@ class brennenstuhl_heating_valve(base):
|
495
|
525
|
self.set(self.KEY_TEMPERATURE_SETPOINT, self.__command_float_value__(value))
|
496
|
526
|
elif command == self.COMMANDS[2]:
|
497
|
527
|
self.set(self.KEY_TEMPERATURE, self.__command_float_value__(value))
|
|
528
|
+ elif command == self.COMMANDS[3]:
|
|
529
|
+ self.set(self.KEY_BATTERY, self.__command_float_value__(value))
|
498
|
530
|
|
499
|
531
|
def print_formatted(self, device, key, value):
|
500
|
532
|
if key == self.KEY_TEMPERATURE_SETPOINT:
|
|
@@ -503,6 +535,12 @@ class brennenstuhl_heating_valve(base):
|
503
|
535
|
perc = 0 if perc < 0 else perc
|
504
|
536
|
self.print_formatted_percent(COLOR_HEATING_VALVE, '\u03d1', perc, "%4.1f°C" % value, "")
|
505
|
537
|
|
|
538
|
+ def warning_state_on(self):
|
|
539
|
+ self.set(self.KEY_BATTERY, 7)
|
|
540
|
+
|
|
541
|
+ def warning_state_off(self):
|
|
542
|
+ self.set(self.KEY_BATTERY, 97)
|
|
543
|
+
|
506
|
544
|
|
507
|
545
|
class videv_light(base_videv):
|
508
|
546
|
KEY_OUTPUT_0 = "state"
|
|
@@ -733,8 +771,44 @@ class videv_heating(base_videv):
|
733
|
771
|
self.print_formatted_percent(COLOR_GUI_ACTIVE, 't', perc, '%3d%%' % perc, '(%.1f)' % disp_value)
|
734
|
772
|
|
735
|
773
|
|
|
774
|
+class videv_warnings(base):
|
|
775
|
+ KEY_WARNING = "html_short"
|
|
776
|
+ #
|
|
777
|
+ COMMANDS = [
|
|
778
|
+ "get_warnings",
|
|
779
|
+ ]
|
|
780
|
+
|
|
781
|
+ def __init__(self, mqtt_client, topic):
|
|
782
|
+ super().__init__(mqtt_client, topic, dict.fromkeys([self.KEY_WARNING]))
|
|
783
|
+ #
|
|
784
|
+ self.add_callback(self.KEY_WARNING, None, self.print_formatted, True)
|
|
785
|
+
|
|
786
|
+ def __rx__(self, client, userdata, message):
|
|
787
|
+ if message.topic == self.topic + "/" + self.KEY_WARNING:
|
|
788
|
+ self.set(self.KEY_WARNING, message.payload.decode("utf-8"))
|
|
789
|
+
|
|
790
|
+ def command(self, command):
|
|
791
|
+ if command in self.COMMANDS:
|
|
792
|
+ if command == self.COMMANDS[0]:
|
|
793
|
+ self.print_formatted(self, self.KEY_WARNING, self.get(self.KEY_WARNING))
|
|
794
|
+ else:
|
|
795
|
+ print("%s: not yet implemented!" % command)
|
|
796
|
+ else:
|
|
797
|
+ print("Unknown command!")
|
|
798
|
+
|
|
799
|
+ def print_formatted(self, device, key, value):
|
|
800
|
+ if OUTPUT_ACTIVE:
|
|
801
|
+ value = value.replace("<br><br>", "\n")
|
|
802
|
+ value = value.replace("<br>", " - ")
|
|
803
|
+ print(COLOR_WARNINGS + "** WARNINGS: *************************************************")
|
|
804
|
+ for line in value.split("\n"):
|
|
805
|
+ print(" ", line)
|
|
806
|
+ print("**************************************************************" + colored.attr("reset"))
|
|
807
|
+
|
736
|
808
|
# class silvercrest_motion_sensor(base):
|
737
|
809
|
# KEY_OCCUPANCY = "occupancy"
|
|
810
|
+# KEY_BATTERY = "battery"
|
|
811
|
+# KEY_BATTERY_LOW = "battery_low"
|
738
|
812
|
# COMMANDS = ['motion']
|
739
|
813
|
|
740
|
814
|
# def __init__(self, mqtt_client, topic):
|
|
@@ -761,9 +835,17 @@ class videv_heating(base_videv):
|
761
|
835
|
# if value is not None:
|
762
|
836
|
# print_light(COLOR_MOTION_SENSOR, value, self.topic, "")
|
763
|
837
|
|
|
838
|
+# def warning_state_on(self):
|
|
839
|
+# self.set(self.KEY_BATTERY, 7)
|
|
840
|
+# self.set(self.KEY_BATTERY_LOW, True)
|
|
841
|
+# def warning_state_off(self):
|
|
842
|
+# self.set(self.KEY_BATTERY, 97)
|
|
843
|
+# self.set(self.KEY_BATTERY_LOW, False)
|
|
844
|
+
|
764
|
845
|
|
765
|
846
|
# class tradfri_button(base):
|
766
|
847
|
# KEY_ACTION = "action"
|
|
848
|
+# KEY_BATTERY = "battery"
|
767
|
849
|
# #
|
768
|
850
|
# ACTION_TOGGLE = "toggle"
|
769
|
851
|
# ACTION_BRIGHTNESS_UP = "brightness_up_click"
|
|
@@ -800,6 +882,11 @@ class videv_heating(base_videv):
|
800
|
882
|
# time.sleep(value or 0.5)
|
801
|
883
|
# action = '_'.join(action.split('_')[:-1] + ['release'])
|
802
|
884
|
# self.mqtt_client.send(self.topic, json.dumps({self.KEY_ACTION: action}))
|
|
885
|
+#
|
|
886
|
+# def warning_state_on(self):
|
|
887
|
+# self.set(self.KEY_BATTERY, 7)
|
|
888
|
+# def warning_state_off(self):
|
|
889
|
+# self.set(self.KEY_BATTERY, 97)
|
803
|
890
|
|
804
|
891
|
|
805
|
892
|
# class remote(base):
|