Smarthome Functionen
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. #
  4. from devices.base import base
  5. import json
  6. import task
  7. import time
  8. class brennenstuhl_heatingvalve(base):
  9. """ Communication (MQTT)
  10. brennenstuhl_heatingvalve {
  11. | "away_mode": ["ON", "OFF"]
  12. | "battery": [0...100] %
  13. | "child_lock": ["LOCK", "UNLOCK"]
  14. | "current_heating_setpoint": [5...30] °C
  15. | "linkquality": [0...255] lqi
  16. | "local_temperature": [numeric] °C
  17. | "preset": ["manual", ...]
  18. | "system_mode": ["heat", ...]
  19. | "valve_detection": ["ON", "OFF"]
  20. | "window_detection": ["ON", "OFF"]
  21. | }
  22. +- set {
  23. "away_mode": ["ON", "OFF", "TOGGLE"]
  24. "child_lock": ["LOCK", "UNLOCK"]
  25. "current_heating_setpoint": [5...30] °C
  26. "preset": ["manual", ...]
  27. "system_mode": ["heat", ...]
  28. "valve_detection": ["ON", "OFF", "TOGGLE"]
  29. "window_detection": ["ON", "OFF", "TOGGLE"]
  30. }
  31. """
  32. KEY_LINKQUALITY = "linkquality"
  33. KEY_BATTERY = "battery"
  34. KEY_HEATING_SETPOINT = "current_heating_setpoint"
  35. KEY_TEMPERATURE = "local_temperature"
  36. #
  37. KEY_AWAY_MODE = "away_mode"
  38. KEY_CHILD_LOCK = "child_lock"
  39. KEY_PRESET = "preset"
  40. KEY_SYSTEM_MODE = "system_mode"
  41. KEY_VALVE_DETECTION = "valve_detection"
  42. KEY_WINDOW_DETECTION = "window_detection"
  43. #
  44. RETRY_CYCLE_TIME = 2.5
  45. MAX_TX_RETRIES = 20
  46. RETRY_TIMEOUT = RETRY_CYCLE_TIME * MAX_TX_RETRIES
  47. #
  48. TX_TYPE = base.TX_DICT
  49. #
  50. RX_KEYS = [KEY_LINKQUALITY, KEY_BATTERY, KEY_HEATING_SETPOINT, KEY_TEMPERATURE]
  51. RX_IGNORE_KEYS = [KEY_AWAY_MODE, KEY_CHILD_LOCK, KEY_PRESET, KEY_SYSTEM_MODE, KEY_VALVE_DETECTION, KEY_WINDOW_DETECTION]
  52. #
  53. CFG_DATA = {
  54. KEY_WINDOW_DETECTION: "ON",
  55. KEY_VALVE_DETECTION: "ON",
  56. KEY_SYSTEM_MODE: "heat",
  57. KEY_PRESET: "manual"
  58. }
  59. def __init__(self, mqtt_client, topic):
  60. super().__init__(mqtt_client, topic)
  61. self.add_callback(self.KEY_HEATING_SETPOINT, None, self.__valave_temp_rx__)
  62. self.__tx_temperature__ = None
  63. self.__rx_temperature__ = None
  64. self.__tx_timestamp__ = 0
  65. #
  66. self.task = task.periodic(self.RETRY_CYCLE_TIME, self.__task__)
  67. self.task.run()
  68. def __state_logging__(self, inst, key, data):
  69. if key in [self.KEY_HEATING_SETPOINT, self.KEY_CHILD_LOCK, self.KEY_WINDOW_DETECTION, self.KEY_VALVE_DETECTION]:
  70. self.logger.info("State change of '%s' to '%s'", key, repr(data))
  71. def send_command(self, key, data):
  72. if key == self.KEY_HEATING_SETPOINT:
  73. self.__tx_temperature__ = data
  74. self.__tx_timestamp__ = time.time()
  75. base.send_command(self, key, data)
  76. def __valave_temp_rx__(self, inst, key, data):
  77. if key == self.KEY_HEATING_SETPOINT:
  78. self.__rx_temperature__ = data
  79. def __task__(self, rt):
  80. if self.__tx_temperature__ is not None and self.__tx_timestamp__ is not None: # Already send a setpoint
  81. if self.__tx_temperature__ != self.__rx_temperature__: # Setpoint and valve feedback are unequal
  82. if time.time() - self.__tx_timestamp__ < self.RETRY_TIMEOUT: # Timeout condition allows resend of setpoint
  83. self.logger.warning("Setpoint not yet acknoledged by device. Sending setpoint again")
  84. self.set_heating_setpoint(self.__tx_temperature__)
  85. return
  86. else:
  87. self.__tx_timestamp__ = None # Disable resend logic, if setpoint and valve setpoint are equal
  88. #
  89. # RX
  90. #
  91. @property
  92. def linkqulity(self):
  93. return self.get(self.KEY_LINKQUALITY)
  94. @property
  95. def heating_setpoint(self):
  96. return self.get(self.KEY_HEATING_SETPOINT)
  97. @property
  98. def temperature(self):
  99. return self.get(self.KEY_TEMPERATURE)
  100. #
  101. # TX
  102. #
  103. def set_heating_setpoint(self, setpoint):
  104. self.send_command(self.KEY_HEATING_SETPOINT, setpoint)
  105. def set_heating_setpoint_mcb(self, device, key, data):
  106. self.set_heating_setpoint(data)