Control for Window lights
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. #
  4. from devices.base import base_output
  5. import logging
  6. import task
  7. class shelly(base_output):
  8. """ Communication (MQTT)
  9. shelly
  10. +- relay
  11. | +- 0 ["on" / "off"] <- status
  12. | | +- command ["on"/ "off"] <- command
  13. | | +- energy [numeric] <- status
  14. | +- 1 ["on" / "off"] <- status
  15. | +- command ["on"/ "off"] <- command
  16. | +- energy [numeric] <- status
  17. +- input
  18. | +- 0 [0 / 1] <- status
  19. | +- 1 [0 / 1] <- status
  20. +- input_event
  21. | +- 0 <- status
  22. | +- 1 <- status
  23. +- logpush
  24. | +- 0 [0 / 1] <- status
  25. | +- 1 [0 / 1] <- status
  26. +- temperature [numeric] °C <- status
  27. +- temperature_f [numeric] F <- status
  28. +- overtemperature [0 / 1] <- status
  29. +- id <- status
  30. +- model <- status
  31. +- mac <- status
  32. +- ip <- status
  33. +- new_fw <- status
  34. +- fw_ver <- status
  35. """
  36. KEY_OUTPUT_0 = "relay/0"
  37. KEY_OUTPUT_1 = "relay/1"
  38. KEY_INPUT_0 = "input/0"
  39. KEY_INPUT_1 = "input/1"
  40. KEY_LONGPUSH_0 = "longpush/0"
  41. KEY_LONGPUSH_1 = "longpush/1"
  42. KEY_TEMPERATURE = "temperature"
  43. KEY_OVERTEMPERATURE = "overtemperature"
  44. KEY_ID = "id"
  45. KEY_MODEL = "model"
  46. KEY_MAC = "mac"
  47. KEY_IP = "ip"
  48. KEY_NEW_FIRMWARE = "new_fw"
  49. KEY_FIRMWARE_VERSION = "fw_ver"
  50. #
  51. TX_TOPIC = "command"
  52. TX_TYPE = base_output.TX_VALUE
  53. TX_FILTER_DATA_KEYS = [KEY_OUTPUT_0, KEY_OUTPUT_1]
  54. #
  55. RX_KEYS = [KEY_OUTPUT_0, KEY_OUTPUT_1, KEY_INPUT_0, KEY_INPUT_1, KEY_LONGPUSH_0, KEY_LONGPUSH_1, KEY_OVERTEMPERATURE, KEY_TEMPERATURE,
  56. KEY_ID, KEY_MODEL, KEY_MAC, KEY_IP, KEY_NEW_FIRMWARE, KEY_FIRMWARE_VERSION]
  57. RX_IGNORE_TOPICS = [KEY_OUTPUT_0 + '/' + "energy", KEY_OUTPUT_1 + '/' + "energy", 'input_event/0', 'input_event/1']
  58. RX_IGNORE_KEYS = ['temperature_f']
  59. RX_FILTER_DATA_KEYS = [KEY_INPUT_0, KEY_INPUT_1, KEY_LONGPUSH_0, KEY_LONGPUSH_1, KEY_OUTPUT_0, KEY_OUTPUT_1, KEY_OVERTEMPERATURE]
  60. def __init__(self, mqtt_client, topic):
  61. super().__init__(mqtt_client, topic)
  62. #
  63. self.output_key_delayed = None
  64. self.delayed_flash_task = task.delayed(0.3, self.flash_task)
  65. self.delayed_off_task = task.delayed(0.3, self.off_task)
  66. #
  67. self.all_off_requested = False
  68. def __state_logging__(self, inst, key, data):
  69. if key in [self.KEY_OUTPUT_0, self.KEY_OUTPUT_1]:
  70. self.logger.info("State change of '%s' to '%s'", key, repr(data))
  71. elif key in [self.KEY_INPUT_0, self.KEY_INPUT_1, self.KEY_LONGPUSH_0, self.KEY_LONGPUSH_1]:
  72. self.logger.info("Input action '%s' with '%s'", key, repr(data))
  73. def flash_task(self, *args):
  74. if self.flash_active:
  75. self.send_command(self.output_key_delayed, not self.get(self.output_key_delayed))
  76. self.output_key_delayed = None
  77. if self.all_off_requested:
  78. self.delayed_off_task.run()
  79. def off_task(self, *args):
  80. self.all_off()
  81. @property
  82. def flash_active(self):
  83. return self.output_key_delayed is not None
  84. #
  85. # RX
  86. #
  87. @property
  88. def output_0(self):
  89. """rv: [True, False]"""
  90. return self.get(self.KEY_OUTPUT_0)
  91. @property
  92. def output_1(self):
  93. """rv: [True, False]"""
  94. return self.get(self.KEY_OUTPUT_1)
  95. @property
  96. def input_0(self):
  97. """rv: [True, False]"""
  98. return self.get(self.KEY_INPUT_0)
  99. @property
  100. def input_1(self):
  101. """rv: [True, False]"""
  102. return self.get(self.KEY_INPUT_1)
  103. @property
  104. def longpush_0(self):
  105. """rv: [True, False]"""
  106. return self.get(self.KEY_LONGPUSH_0)
  107. @property
  108. def longpush_1(self):
  109. """rv: [True, False]"""
  110. return self.get(self.KEY_LONGPUSH_1)
  111. @property
  112. def temperature(self):
  113. """rv: numeric value"""
  114. return self.get(self.KEY_TEMPERATURE)
  115. #
  116. # TX
  117. #
  118. def set_output_0(self, state):
  119. """state: [True, False]"""
  120. self.send_command(self.KEY_OUTPUT_0, state)
  121. def set_output_0_mcb(self, device, key, data):
  122. self.set_output_0(data)
  123. def toggle_output_0_mcb(self, device, key, data):
  124. self.set_output_0(not self.output_0)
  125. def set_output_1(self, state):
  126. """state: [True, False]"""
  127. self.send_command(self.KEY_OUTPUT_1, state)
  128. def set_output_1_mcb(self, device, key, data):
  129. self.set_output_1(data)
  130. def toggle_output_1_mcb(self, device, key, data):
  131. self.set_output_1(not self.output_1)
  132. def flash_0_mcb(self, device, key, data):
  133. self.output_key_delayed = self.KEY_OUTPUT_0
  134. self.toggle_output_0_mcb(device, key, data)
  135. self.delayed_flash_task.run()
  136. def flash_1_mcb(self, device, key, data):
  137. self.output_key_delayed = self.KEY_OUTPUT_1
  138. self.toggle_output_1_mcb(device, key, data)
  139. self.delayed_flash_task.run()
  140. def __all_off__(self):
  141. if self.flash_active:
  142. self.all_off_requested = True
  143. else:
  144. if self.output_0:
  145. self.set_output_0(False)
  146. if self.output_1:
  147. self.set_output_1(False)