Module to run and control leyk lightning
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

piface_function.py 21KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588
  1. #!/usr/bin/env python
  2. # -*- coding: UTF-8 -*-
  3. try:
  4. import pifacedigitalio
  5. except ImportError:
  6. pifacedigitalio = None
  7. import config
  8. import geo
  9. import json
  10. import logging
  11. import mqtt
  12. import state_machine
  13. import task
  14. import random
  15. import socket
  16. import time
  17. try:
  18. from config import APP_NAME as ROOT_LOGGER_NAME
  19. except ImportError:
  20. ROOT_LOGGER_NAME = 'root'
  21. logger = logging.getLogger(ROOT_LOGGER_NAME).getChild(__name__)
  22. geo_position = geo.gps.coordinate(lat=49.976596, lon=9.1481443)
  23. class pi_face(object):
  24. LOG_PREFIX = 'PiFace:'
  25. PF_OUT_NAMES = ['Output 0', # 0
  26. 'Output 1', # 1
  27. 'Output 2', # 2
  28. 'Ploenlein', # 3
  29. 'Bakery', # 4
  30. 'Mill', # 5
  31. 'Reese House', # 6
  32. 'Bake House'] # 7
  33. def __init__(self, client):
  34. self.__client__ = client
  35. if pifacedigitalio is not None:
  36. pifacedigitalio.init()
  37. pi = pifacedigitalio.PiFaceDigital()
  38. self.__pf_outputs__ = pi.output_pins
  39. self.__pf_output_states__ = 8 * [False]
  40. #
  41. self._reload = 0
  42. self._task_10ms = task.periodic(0.01 - 0.007, self.task_10ms)
  43. #
  44. for i in range(0, 8):
  45. self.set_output(i, self.__pf_output_states__[i])
  46. def set_output(self, index, state, tries=5):
  47. tries = min(max(1, tries), 5)
  48. try_txt = ['1st', '2nd', '3rd', '4th', '5th']
  49. state = state is True
  50. if pifacedigitalio is not None:
  51. cnt = 0
  52. while (cnt < tries) and (self.__pf_outputs__[index].value != state):
  53. self.__pf_outputs__[index].value = 1 * state
  54. time.sleep(0.1)
  55. cnt += 1
  56. if self.__pf_outputs__[index].value != state:
  57. logger.warning('%s Control of output[%d] (%s) after %s try not successfull!', self.LOG_PREFIX, index, self.PF_OUT_NAMES[index], try_txt[cnt - 1])
  58. else:
  59. logger.info('%s Set output "%s" to %s.', self.LOG_PREFIX, self.PF_OUT_NAMES[index], repr(state))
  60. self.__pf_output_states__[index] = self.__pf_outputs__[index].value == 1
  61. else:
  62. logger.info('%s Set virtual output "%s" to %s.', self.LOG_PREFIX, self.PF_OUT_NAMES[index], repr(state))
  63. self.__pf_output_states__[index] = state
  64. def get_output(self, index):
  65. return self.__pf_output_states__[index]
  66. def get_ploenlein(self):
  67. return self.get_output(3)
  68. def set_bakery(self, state):
  69. self.set_output(4, state)
  70. def get_bakery(self):
  71. return self.get_output(4)
  72. def set_mill(self, state):
  73. self.set_output(5, state)
  74. def get_mill(self):
  75. return self.get_output(5)
  76. def set_ploenlein(self, state):
  77. self.set_output(3, state)
  78. def set_reese_house(self, state):
  79. self.set_output(6, state)
  80. def get_reese_house(self):
  81. return self.get_output(6)
  82. def set_bake_house(self, state):
  83. if state is True:
  84. self.set_output(7, state)
  85. self._task_10ms.run()
  86. elif state is False:
  87. self._task_10ms.stop()
  88. self.join()
  89. time.sleep(0.1)
  90. self.set_output(7, state)
  91. def get_bake_house(self):
  92. return not self._task_10ms._stopped
  93. def task_10ms(self, task_inst):
  94. if self._reload <= 0:
  95. if pifacedigitalio is not None:
  96. self.__pf_outputs__[7].turn_on()
  97. self._reload = random.choice(2 * [0] + 20 * [1] + 1 * [2])
  98. else:
  99. if pifacedigitalio is not None:
  100. self.__pf_outputs__[7].turn_off()
  101. self._reload -= 1
  102. def join(self):
  103. self._task_10ms.join()
  104. def stop(self):
  105. self._task_10ms.stop()
  106. self._task_10ms.join()
  107. for i in range(0, 8):
  108. self.set_output(i, False)
  109. pifacedigitalio.deinit()
  110. def __del__(self):
  111. self.stop()
  112. class state_machine_mode(state_machine.state_machine):
  113. LOG_PREFIX = 'LeykMode:'
  114. STATE_AUTOMATIC = 'automatic'
  115. STATE_MANUAL = 'manual'
  116. CONDITION_EXTERNAL_TRIGGER = 'external_trigger'
  117. TRANSITIONS = {
  118. STATE_AUTOMATIC: (
  119. (CONDITION_EXTERNAL_TRIGGER, 1, STATE_MANUAL),
  120. ),
  121. STATE_MANUAL: (
  122. (CONDITION_EXTERNAL_TRIGGER, 1, STATE_AUTOMATIC),
  123. ),
  124. }
  125. def __init__(self, **kwargs):
  126. state_machine.state_machine.__init__(self, self.STATE_AUTOMATIC, logging.INFO)
  127. self.__reset_triggers__()
  128. def __reset_triggers__(self):
  129. self.__to_automatic__ = False
  130. self.__to_manual__ = False
  131. def external_trigger(self):
  132. rv = False
  133. if self.this_state() == self.STATE_AUTOMATIC:
  134. rv = self.__to_manual__
  135. elif self.this_state() == self.STATE_MANUAL:
  136. rv = self.__to_automatic__
  137. self.__reset_triggers__()
  138. return rv
  139. def trigger_to_maual(self):
  140. if self.this_state() == self.STATE_AUTOMATIC:
  141. self.__to_manual__ = True
  142. return True
  143. return False
  144. def trigger_to_automatic(self):
  145. if self.this_state() == self.STATE_MANUAL:
  146. self.__to_automatic__ = True
  147. return True
  148. return False
  149. class state_machine_day_state(state_machine.state_machine):
  150. LOG_PREFIX = 'LeykState:'
  151. STATE_IDLE = 'idle'
  152. STATE_WAKE = 'wake'
  153. STATE_SUNRISE = 'sunrise'
  154. STATE_SUNSET = 'sunset'
  155. STATE_SLEEP = 'sleep'
  156. CONDITION_WAKE = 'condition_wake'
  157. CONDITION_SUNRISE = 'condition_sunrise'
  158. CONDITION_SUNSET = 'condition_sunset'
  159. CONDITION_SLEEP = 'condition_sleep'
  160. CONDITION_IDLE = 'condition_idle'
  161. TRANSITIONS = {
  162. STATE_IDLE: (
  163. (CONDITION_WAKE, 1, STATE_WAKE),
  164. (CONDITION_SUNRISE, 1, STATE_SUNRISE),
  165. (CONDITION_SUNSET, 1, STATE_SUNSET),
  166. (CONDITION_SLEEP, 1, STATE_SLEEP),
  167. ),
  168. STATE_WAKE: (
  169. (CONDITION_SUNRISE, 1, STATE_SUNRISE),
  170. (CONDITION_IDLE, 1, STATE_IDLE),
  171. ),
  172. STATE_SUNRISE: (
  173. (CONDITION_SLEEP, 1, STATE_SLEEP),
  174. (CONDITION_SUNSET, 1, STATE_SUNSET),
  175. (CONDITION_IDLE, 1, STATE_IDLE),
  176. ),
  177. STATE_SUNSET: (
  178. (CONDITION_SLEEP, 1, STATE_SLEEP),
  179. (CONDITION_IDLE, 1, STATE_IDLE),
  180. ),
  181. STATE_SLEEP: (
  182. (CONDITION_WAKE, 1, STATE_WAKE),
  183. (CONDITION_SUNRISE, 1, STATE_SUNRISE),
  184. (CONDITION_IDLE, 1, STATE_IDLE),
  185. ),
  186. }
  187. def __init__(self, **kwargs):
  188. state_machine.state_machine.__init__(self, self.STATE_IDLE, logging.INFO, **kwargs)
  189. def __current_state_calc__(self):
  190. def wake_time():
  191. tm = time.localtime()
  192. tm = list(tm)
  193. tm[3] = 6 # tm_hour
  194. tm[4] = 0 # tm_min
  195. tm[5] = 0 # tm_sec=0
  196. return time.mktime(time.struct_time(tm))
  197. def sunrise_time():
  198. return time.mktime(geo.sun.sunrise(geo_position)) + 30 * 60
  199. def sunset_time():
  200. return time.mktime(geo.sun.sunset(geo_position)) - 30 * 60
  201. def sleep_time():
  202. tm = time.localtime()
  203. tm = list(tm)
  204. tm[3] = 21 # tm_hour
  205. tm[4] = 15 # tm_min
  206. tm[5] = 0 # tm_sec=0
  207. return time.mktime(time.struct_time(tm))
  208. now = time.mktime(time.localtime())
  209. if now > sleep_time():
  210. return self.STATE_SLEEP
  211. elif now > sunset_time():
  212. return self.STATE_SUNSET
  213. elif now > sunrise_time():
  214. return self.STATE_SUNRISE
  215. elif now > wake_time():
  216. return self.STATE_WAKE
  217. else:
  218. return self.STATE_IDLE
  219. def condition_wake(self):
  220. if self.condition_idle():
  221. return False
  222. return self.__current_state_calc__() == self.STATE_WAKE
  223. def condition_sunrise(self):
  224. if self.condition_idle():
  225. return False
  226. return self.__current_state_calc__() == self.STATE_SUNRISE
  227. def condition_sunset(self):
  228. if self.condition_idle():
  229. return False
  230. return self.__current_state_calc__() == self.STATE_SUNSET
  231. def condition_sleep(self):
  232. if self.condition_idle():
  233. return False
  234. return self.__current_state_calc__() == self.STATE_SLEEP
  235. def condition_idle(self):
  236. return not self.sm_mode.this_state_is(self.sm_mode.STATE_AUTOMATIC)
  237. def report_sunset_sunrise(self):
  238. state_machine.logger.debug('Sunrise: %s - Sunset: %s;', time.strftime("%H:%M", geo.sun.sunrise(geo_position)), time.strftime("%H:%M", geo.sun.sunset(geo_position))
  239. )
  240. class leyk(object):
  241. LOG_PREFIX = 'Leyk:'
  242. TOPIC_BAKE_HOUSE = config.MQTT_TOPIC + '/status/Bake House'
  243. TOPIC_BAKERY = config.MQTT_TOPIC + '/status/Bakery'
  244. TOPIC_MILL = config.MQTT_TOPIC + '/status/Mill'
  245. TOPIC_MODE = config.MQTT_TOPIC + '/status/mode'
  246. TOPIC_MODE_BOOL = config.MQTT_TOPIC + '/status/mode_bool'
  247. TOPIC_PLOENLEIN = config.MQTT_TOPIC + '/status/Ploenlein'
  248. TOPIC_REESE_HOUSE = config.MQTT_TOPIC + '/status/Reese House'
  249. TOPIC_STATE = config.MQTT_TOPIC + '/status/state'
  250. RX_TOPIC_BAKE_HOUSE = config.MQTT_TOPIC + '/set/Bake House'
  251. RX_TOPIC_BAKERY = config.MQTT_TOPIC + '/set/Bakery'
  252. RX_TOPIC_MILL = config.MQTT_TOPIC + '/set/Mill'
  253. RX_TOPIC_MODE = config.MQTT_TOPIC + '/set/mode'
  254. RX_TOPIC_PLOENLEIN = config.MQTT_TOPIC + '/set/Ploenlein'
  255. RX_TOPIC_REESE_HOUSE = config.MQTT_TOPIC + '/set/Reese House'
  256. RX_TOPICS = [
  257. RX_TOPIC_BAKE_HOUSE,
  258. RX_TOPIC_BAKERY,
  259. RX_TOPIC_MILL,
  260. RX_TOPIC_MODE,
  261. RX_TOPIC_PLOENLEIN,
  262. RX_TOPIC_REESE_HOUSE
  263. ]
  264. def __init__(self):
  265. self.__client__ = mqtt.mqtt_client(config.APP_NAME, config.MQTT_SERVER, 1883, config.MQTT_USER, config.MQTT_PASS)
  266. self.__client__.add_callback(self.RX_TOPIC_BAKE_HOUSE, self.__rx_bake_house__)
  267. self.__client__.add_callback(self.RX_TOPIC_BAKERY, self.__rx_bakery__)
  268. self.__client__.add_callback(self.RX_TOPIC_MILL, self.__rx_mill__)
  269. self.__client__.add_callback(self.RX_TOPIC_PLOENLEIN, self.__rx_ploenlein__)
  270. self.__client__.add_callback(self.RX_TOPIC_REESE_HOUSE, self.__rx_reese_house__)
  271. self.__client__.add_callback(self.RX_TOPIC_MODE, self.__rx_mode__)
  272. self.TOPIC_DATA = {
  273. self.TOPIC_BAKE_HOUSE: self.get_bake_house,
  274. self.TOPIC_BAKERY: self.get_bakery,
  275. self.TOPIC_MILL: self.get_mill,
  276. self.TOPIC_MODE: self.get_mode,
  277. self.TOPIC_MODE_BOOL: self.get_mode_bool,
  278. self.TOPIC_PLOENLEIN: self.get_ploenlein,
  279. self.TOPIC_REESE_HOUSE: self.get_reese_house,
  280. self.TOPIC_STATE: self.get_state
  281. }
  282. self.sm_mode = state_machine_mode()
  283. self.sm_day_state = state_machine_day_state(sm_mode=self.sm_mode)
  284. self.__pf__ = pi_face(self.__client__)
  285. self._queue = task.threaded_queue()
  286. self._queue.run()
  287. self._task_1s = task.periodic(1, self.task_1s)
  288. self._task_1s.run()
  289. self.sm_mode.register_state_change_callback(self.sm_mode.STATE_MANUAL, None, self._queue.clean_queue)
  290. self.sm_mode.register_state_change_callback(None, None, self.publish, self.TOPIC_MODE)
  291. self.sm_mode.register_state_change_callback(None, None, self.publish, self.TOPIC_MODE_BOOL)
  292. self.sm_day_state.register_state_change_callback(None, None, self.clean_queue)
  293. self.sm_day_state.register_state_change_callback(None, None, self.publish, self.TOPIC_STATE)
  294. self.sm_day_state.register_state_change_callback(self.sm_day_state.STATE_SLEEP, None, self.sm_day_state.report_sunset_sunrise)
  295. self.sm_day_state.register_state_change_callback(self.sm_day_state.STATE_SLEEP, None, self.fill_sleep_queue)
  296. self.sm_day_state.register_state_change_callback(self.sm_day_state.STATE_SUNRISE, None, self.sm_day_state.report_sunset_sunrise)
  297. self.sm_day_state.register_state_change_callback(self.sm_day_state.STATE_SUNRISE, None, self.fill_sunrise_queue)
  298. self.sm_day_state.register_state_change_callback(self.sm_day_state.STATE_SUNSET, None, self.sm_day_state.report_sunset_sunrise)
  299. self.sm_day_state.register_state_change_callback(self.sm_day_state.STATE_SUNSET, None, self.fill_sunset_queue)
  300. self.sm_day_state.register_state_change_callback(self.sm_day_state.STATE_WAKE, None, self.sm_day_state.report_sunset_sunrise)
  301. self.sm_day_state.register_state_change_callback(self.sm_day_state.STATE_WAKE, None, self.fill_wake_queue)
  302. self.publish(self.TOPIC_MODE)
  303. self.publish(self.TOPIC_MODE_BOOL)
  304. self.publish(self.TOPIC_STATE)
  305. def __rx_bake_house__(self, client, userdata, message):
  306. self.set_bake_house(message.payload == b'true')
  307. def __rx_bakery__(self, client, userdata, message):
  308. self.set_bakery(message.payload == b'true')
  309. def __rx_mill__(self, client, userdata, message):
  310. self.set_mill(message.payload == b'true')
  311. def __rx_ploenlein__(self, client, userdata, message):
  312. self.set_ploenlein(message.payload == b'true')
  313. def __rx_reese_house__(self, client, userdata, message):
  314. self.set_reese_house(message.payload == b'true')
  315. def __rx_mode__(self, client, userdata, message):
  316. self.set_mode(self.sm_mode.STATE_AUTOMATIC if message.payload == b'true' else self.sm_mode.STATE_MANUAL)
  317. def publish_states(self):
  318. for name in self.TOPIC_DATA:
  319. self.publish(name)
  320. def publish(self, topic):
  321. logger.info("Sending Leyk status information to mqtt %s = %s", topic, json.dumps(self.TOPIC_DATA[topic]()))
  322. try:
  323. self.__client__.send(topic, json.dumps(self.TOPIC_DATA[topic]()))
  324. except (socket.timeout, OSError) as e:
  325. logger.warning("Error while sending state information information")
  326. def set_mode(self, mode):
  327. if mode == self.sm_mode.STATE_AUTOMATIC:
  328. rv = self.sm_mode.trigger_to_automatic()
  329. elif mode == self.sm_mode.STATE_MANUAL:
  330. rv = self.sm_mode.trigger_to_maual()
  331. else:
  332. rv = False
  333. return rv
  334. def get_mode(self):
  335. return self.sm_mode.this_state()
  336. def get_mode_bool(self):
  337. return self.get_mode() == self.sm_mode.STATE_AUTOMATIC
  338. def get_state(self):
  339. return self.sm_day_state.this_state()
  340. def __queue_wrapper__(self, queue_inst, function, *args, **kwargs):
  341. function(*args, **kwargs)
  342. def set_ploenlein(self, state, force=False):
  343. if force or self.sm_mode.this_state_is(self.sm_mode.STATE_MANUAL):
  344. self.__pf__.set_ploenlein(state)
  345. self.publish(self.TOPIC_PLOENLEIN)
  346. return True
  347. else:
  348. return False
  349. def get_ploenlein(self):
  350. return self.__pf__.get_ploenlein()
  351. def set_bakery(self, state, force=False):
  352. if force or self.sm_mode.this_state_is(self.sm_mode.STATE_MANUAL):
  353. self.__pf__.set_bakery(state)
  354. self.publish(self.TOPIC_BAKERY)
  355. return True
  356. else:
  357. return False
  358. def get_bakery(self):
  359. return self.__pf__.get_bakery()
  360. def set_bake_house(self, state, force=False):
  361. if force or self.sm_mode.this_state_is(self.sm_mode.STATE_MANUAL):
  362. self.__pf__.set_bake_house(state)
  363. self.publish(self.TOPIC_BAKE_HOUSE)
  364. return True
  365. else:
  366. return False
  367. def get_bake_house(self):
  368. return self.__pf__.get_bake_house()
  369. def set_mill(self, state, force=False):
  370. if force or self.sm_mode.this_state_is(self.sm_mode.STATE_MANUAL):
  371. self.__pf__.set_mill(state)
  372. self.publish(self.TOPIC_MILL)
  373. return True
  374. else:
  375. return False
  376. def get_mill(self):
  377. return self.__pf__.get_mill()
  378. def set_reese_house(self, state, force=False):
  379. if force or self.sm_mode.this_state_is(self.sm_mode.STATE_MANUAL):
  380. self.__pf__.set_reese_house(state)
  381. self.publish(self.TOPIC_REESE_HOUSE)
  382. return True
  383. else:
  384. return False
  385. def get_reese_house(self):
  386. return self.__pf__.get_reese_house()
  387. def wake_time(self):
  388. tm = time.localtime()
  389. tm = list(tm)
  390. tm[3] = 6 # tm_hour
  391. tm[4] = 0 # tm_min
  392. tm[5] = 0 # tm_sec=0
  393. return time.mktime(time.struct_time(tm))
  394. def sunrise_time(self):
  395. return time.mktime(geo.sun.sunrise(geo_position)) + 30 * 60
  396. def sunset_time(self):
  397. return time.mktime(geo.sun.sunset(geo_position)) - 30 * 60
  398. def sleep_time(self):
  399. tm = time.localtime()
  400. tm = list(tm)
  401. tm[3] = 21 # tm_hour
  402. tm[4] = 15 # tm_min
  403. tm[5] = 0 # tm_sec=0
  404. return time.mktime(time.struct_time(tm))
  405. def identify_current_state(self):
  406. now = time.mktime(time.localtime())
  407. if now > self.sleep_time():
  408. return self.ST_SLEEP
  409. elif now > self.sunset_time():
  410. return self.ST_SUNSET
  411. elif now > self.sunrise_time():
  412. return self.ST_SUNRISE
  413. elif now > self.wake_time():
  414. return self.ST_WAKE
  415. else:
  416. return self.ST_SLEEP
  417. def wait(self, queue_inst, delay):
  418. if delay > 0:
  419. logger.debug('%s Wait for %d seconds initiated. %d elements left in queue.', self.LOG_PREFIX, delay, queue_inst.qsize())
  420. cnt = 0
  421. while cnt < delay * 5:
  422. if queue_inst.qsize() == 0:
  423. logger.debug('%s Quit wait for %d seconds. %d elements left in queue.', self.LOG_PREFIX, delay, queue_inst.qsize())
  424. break
  425. time.sleep(0.2)
  426. cnt += 1
  427. def clean_queue(self):
  428. if self._queue.qsize() > 0:
  429. logger.info('Cleaning up remaining %d elements from queue', self._queue.qsize())
  430. self._queue.clean_queue()
  431. def fill_wake_queue(self):
  432. no_delay = self.sm_day_state.previous_state_was(self.sm_day_state.STATE_IDLE)
  433. # WAKE
  434. self._queue.enqueue(1, self.__queue_wrapper__, self.set_bakery, True, True)
  435. self._queue.enqueue(2, self.wait, 0 if no_delay else 5 * 60)
  436. self._queue.enqueue(3, self.__queue_wrapper__, self.set_bake_house, True, True)
  437. self._queue.enqueue(4, self.wait, 0 if no_delay else 10 * 60)
  438. self._queue.enqueue(5, self.__queue_wrapper__, self.set_reese_house, True, True)
  439. self._queue.enqueue(6, self.wait, 0 if no_delay else 7 * 60)
  440. self._queue.enqueue(7, self.__queue_wrapper__, self.set_ploenlein, True, True)
  441. self._queue.enqueue(8, self.wait, 0 if no_delay else 8 * 60)
  442. self._queue.enqueue(9, self.__queue_wrapper__, self.set_mill, True, True)
  443. def fill_sunrise_queue(self):
  444. no_delay = self.sm_day_state.previous_state_was(self.sm_day_state.STATE_IDLE)
  445. # SUNRISE
  446. self._queue.enqueue(1, self.__queue_wrapper__, self.set_bake_house, True, True)
  447. self._queue.enqueue(2, self.__queue_wrapper__, self.set_ploenlein, False, True)
  448. self._queue.enqueue(3, self.wait, 0 if no_delay else 5 * 60)
  449. self._queue.enqueue(4, self.__queue_wrapper__, self.set_mill, False, True)
  450. self._queue.enqueue(5, self.wait, 0 if no_delay else 8 * 60)
  451. self._queue.enqueue(6, self.__queue_wrapper__, self.set_bakery, False, True)
  452. self._queue.enqueue(7, self.wait, 0 if no_delay else 12 * 60)
  453. self._queue.enqueue(8, self.__queue_wrapper__, self.set_reese_house, False, True)
  454. def fill_sunset_queue(self):
  455. no_delay = self.sm_day_state.previous_state_was(self.sm_day_state.STATE_IDLE)
  456. # SUNSET
  457. self._queue.enqueue(1, self.__queue_wrapper__, self.set_bake_house, True, True)
  458. self._queue.enqueue(2, self.__queue_wrapper__, self.set_bakery, True, True)
  459. self._queue.enqueue(3, self.wait, 0 if no_delay else 10 * 60)
  460. self._queue.enqueue(4, self.__queue_wrapper__, self.set_reese_house, True, True)
  461. self._queue.enqueue(5, self.wait, 0 if no_delay else 8 * 60)
  462. self._queue.enqueue(6, self.__queue_wrapper__, self.set_mill, True, True)
  463. self._queue.enqueue(7, self.wait, 0 if no_delay else 7 * 60)
  464. self._queue.enqueue(8, self.__queue_wrapper__, self.set_ploenlein, True, True)
  465. def fill_sleep_queue(self):
  466. no_delay = self.sm_day_state.previous_state_was(self.sm_day_state.STATE_IDLE)
  467. # SLEEP
  468. self._queue.enqueue(1, self.__queue_wrapper__, self.set_bake_house, False, True)
  469. self._queue.enqueue(2, self.wait, 0 if no_delay else 5 * 60)
  470. self._queue.enqueue(3, self.__queue_wrapper__, self.set_bakery, False, True)
  471. self._queue.enqueue(4, self.wait, 0 if no_delay else 9 * 60)
  472. self._queue.enqueue(5, self.__queue_wrapper__, self.set_ploenlein, False, True)
  473. self._queue.enqueue(6, self.wait, 0 if no_delay else 9 * 60)
  474. self._queue.enqueue(7, self.__queue_wrapper__, self.set_mill, False, True)
  475. self._queue.enqueue(8, self.wait, 0 if no_delay else 6 * 60)
  476. self._queue.enqueue(9, self.__queue_wrapper__, self.set_reese_house, False, True)
  477. def task_1s(self, task_inst):
  478. self.sm_mode.work()
  479. self.sm_day_state.work()
  480. def join(self):
  481. self._task_1s.join()
  482. self._queue.join()
  483. def stop(self):
  484. self._task_1s.stop()
  485. self._queue.stop()
  486. def __del__(self):
  487. self.__client__.loop_stop() # stop the loop
  488. self.stop()