Control for Window lights
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. import config
  2. import devices
  3. import geo
  4. import logging
  5. import geo.sun
  6. import mqtt
  7. import random
  8. import report
  9. import state_machine
  10. import time
  11. logger = logging.getLogger(config.APP_NAME)
  12. class day_states(state_machine.state_machine):
  13. LOG_PREFIX = 'Day states:'
  14. STATE_NIGHT = 'state_night'
  15. STATE_MORNING = 'state_morning'
  16. STATE_DAY = 'state_day'
  17. STATE_EVENING = 'state_evening'
  18. CONDITION_NIGHT_END = 'condition_night_end'
  19. CONDITION_MORNING_END = 'condition_morning_end'
  20. CONDITION_DAY_END = 'condition_day_end'
  21. CONDITION_EVENING_END = 'condition_evening_end'
  22. TRANSITIONS = {
  23. STATE_NIGHT: (
  24. (CONDITION_NIGHT_END, 1, STATE_MORNING),
  25. ),
  26. STATE_MORNING: (
  27. (CONDITION_MORNING_END, 1, STATE_DAY),
  28. ),
  29. STATE_DAY: (
  30. (CONDITION_DAY_END, 1, STATE_EVENING),
  31. ),
  32. STATE_EVENING: (
  33. (CONDITION_EVENING_END, 1, STATE_NIGHT),
  34. ),
  35. }
  36. def condition_night_end(self):
  37. ltime = time.localtime(time.time())
  38. return ltime.tm_hour >= 5 and ltime.tm_min >= 20 and not self.condition_morning_end() # 2nd condition to ensure day change
  39. def condition_morning_end(self):
  40. ltime = time.mktime(time.localtime(time.time()))
  41. sunrise = time.mktime(geo.sun.sunrise(config.GEO_POSITION)) + 30 * 60
  42. return ltime > sunrise
  43. def condition_day_end(self):
  44. ltime = time.mktime(time.localtime(time.time()))
  45. sunset = time.mktime(geo.sun.sunset(config.GEO_POSITION)) - 30 * 60
  46. return ltime > sunset
  47. def condition_evening_end(self):
  48. ltime = time.localtime(time.time())
  49. return ltime.tm_hour >= 20 and ltime.tm_min >= 30
  50. def get_sorted_sw_offs(num):
  51. SWITCH_DURATION = 30 * 60
  52. rv = []
  53. for i in range(0, num):
  54. rv.append(random.randint(0, SWITCH_DURATION))
  55. rv.sort()
  56. return rv
  57. def switch_x(state: bool, sm: day_states, mydevs: list):
  58. tm = time.time()
  59. random.shuffle(mydevs)
  60. offsets = get_sorted_sw_offs(len(mydevs))
  61. logger.info("State changed to %s with offsets = %s", repr(sm.this_state()), repr(offsets))
  62. allowed_states = [sm.STATE_EVENING, sm.STATE_MORNING] if state else [sm.STATE_DAY, sm.STATE_NIGHT]
  63. while (len(mydevs) > 0 and sm.this_state() in allowed_states):
  64. sm.work()
  65. dt = time.time() - tm
  66. if dt > offsets[0]:
  67. offsets.pop(0)
  68. d: devices.tradfri_sw_br_ct = mydevs.pop()
  69. logger.info("Swiching %s to state %s", d.topic, repr(state))
  70. d.set_output_0(state)
  71. time.sleep(0.25)
  72. def switch_on(sm: day_states, devs: list):
  73. switch_x(True, sm, devs[:])
  74. def switch_off(sm: day_states, devs: list):
  75. switch_x(False, sm, devs[:])
  76. if __name__ == "__main__":
  77. #
  78. # Logging
  79. #
  80. if config.DEBUG:
  81. report.appLoggingConfigure(None, 'stdout', ((config.APP_NAME, logging.DEBUG), ),
  82. target_level=logging.WARNING, fmt=report.SHORT_FMT, host='localhost', port=19996)
  83. else:
  84. report.stdoutLoggingConfigure(((config.APP_NAME, config.LOGLEVEL), ), report.SHORT_FMT)
  85. #
  86. # MQTT Client
  87. #
  88. mc = mqtt.mqtt_client(host=config.MQTT_SERVER, port=config.MQTT_PORT, username=config.MQTT_USER,
  89. password=config.MQTT_PASSWORD, name=config.APP_NAME)
  90. #
  91. # Smarthome physical Devices
  92. devs = []
  93. devs.append(devices.tradfri_sw_br_ct(mc, "zigbee_gfe/gfe/room1/window_light"))
  94. devs.append(devices.tradfri_sw_br_ct(mc, "zigbee_gfe/gfe/room2/window_light"))
  95. devs.append(devices.tradfri_sw_br_ct(mc, "zigbee_gfe/gfe/room3/window_light"))
  96. #
  97. # Functionality
  98. #
  99. sm = day_states(day_states.STATE_DAY, logging.DEBUG)
  100. sm.register_state_change_callback(sm.STATE_NIGHT, None, switch_off, sm, devs)
  101. sm.register_state_change_callback(sm.STATE_MORNING, None, switch_on, sm, devs)
  102. sm.register_state_change_callback(sm.STATE_DAY, None, switch_off, sm, devs)
  103. sm.register_state_change_callback(sm.STATE_EVENING, None, switch_on, sm, devs)
  104. while True:
  105. sm.work()
  106. time.sleep(0.25)