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

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