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

245 строки
6.8KB

  1. import time
  2. from flask import json, request
  3. from flask_classy import route
  4. from modules.core.db import DBModel
  5. from modules.core.baseview import BaseView
  6. from modules.core.core import cbpi
  7. from modules.database.dbmodel import Step
  8. class StepView(BaseView):
  9. model = Step
  10. def _pre_post_callback(self, data):
  11. order = self.model.get_max_order()
  12. data["order"] = 1 if order is None else order + 1
  13. data["state"] = "I"
  14. @route('/sort', methods=["POST"])
  15. def sort_steps(self):
  16. """
  17. Sort all steps
  18. ---
  19. tags:
  20. - steps
  21. responses:
  22. 204:
  23. description: Steps sorted. Update delivered via web socket
  24. """
  25. Step.sort(request.json)
  26. cbpi.ws_emit("UPDATE_ALL_STEPS", self.model.get_all())
  27. return ('', 204)
  28. @route('/', methods=["DELETE"])
  29. def deleteAll(self):
  30. """
  31. Delete all Steps
  32. ---
  33. tags:
  34. - steps
  35. responses:
  36. 204:
  37. description: All steps deleted
  38. """
  39. self.model.delete_all()
  40. self.api.emit("ALL_BREWING_STEPS_DELETED")
  41. cbpi.ws_emit("UPDATE_ALL_STEPS", self.model.get_all())
  42. return ('', 204)
  43. @route('/action/<method>', methods=["POST"])
  44. def action(self, method):
  45. """
  46. Call Step Action
  47. ---
  48. tags:
  49. - steps
  50. responses:
  51. 204:
  52. description: Step action called
  53. """
  54. self.api.emit("BREWING_STEP_ACTION_INVOKED", method=method)
  55. cbpi.cache["active_step"].__getattribute__(method)()
  56. return ('', 204)
  57. @route('/reset', methods=["POST"])
  58. def reset(self):
  59. """
  60. Reset All Steps
  61. ---
  62. tags:
  63. - steps
  64. responses:
  65. 200:
  66. description: Steps reseted
  67. """
  68. self.model.reset_all_steps()
  69. self.stop_step()
  70. self.api.emit("ALL_BREWING_STEPS_RESET")
  71. cbpi.ws_emit("UPDATE_ALL_STEPS", self.model.get_all())
  72. return ('', 204)
  73. def stop_step(self):
  74. '''
  75. stop active step
  76. :return:
  77. '''
  78. step = cbpi.cache.get("active_step")
  79. cbpi.cache["active_step"] = None
  80. self.api.emit("BREWING_STEPS_STOP")
  81. if step is not None:
  82. step.finish()
  83. @route('/reset/current', methods=['POST'])
  84. def resetCurrentStep(self):
  85. """
  86. Reset current Steps
  87. ---
  88. tags:
  89. - steps
  90. responses:
  91. 200:
  92. description: Current Steps reseted
  93. """
  94. step = cbpi.cache.get("active_step")
  95. if step is not None:
  96. step.reset()
  97. if step.is_dirty():
  98. state = {}
  99. for field in step.managed_fields:
  100. state[field] = step.__getattribute__(field)
  101. Step.update_step_state(step.id, state)
  102. step.reset_dirty()
  103. self.api.emit("BREWING_STEPS_RESET_CURRENT")
  104. cbpi.ws_emit("UPDATE_ALL_STEPS", self.model.get_all())
  105. return ('', 204)
  106. def init_step(self, step):
  107. cbpi.brewing.log_action("Start Step %s" % step.name)
  108. type_cfg = cbpi.cache.get("step_types").get(step.type)
  109. if type_cfg is None:
  110. # if type not found
  111. return
  112. # copy config to stepstate
  113. # init step
  114. cfg = step.config.copy()
  115. cfg.update(dict(name=step.name, api=cbpi, id=step.id, timer_end=None, managed_fields=get_manged_fields_as_array(type_cfg)))
  116. instance = type_cfg.get("class")(**cfg)
  117. instance.init()
  118. # set step instance to ache
  119. cbpi.cache["active_step"] = instance
  120. @route('/next', methods=['POST'])
  121. @route('/start', methods=['POST'])
  122. def start(self):
  123. """
  124. Next Step
  125. ---
  126. tags:
  127. - steps
  128. responses:
  129. 200:
  130. description: Next Step
  131. """
  132. active = Step.get_by_state("A")
  133. inactive = Step.get_by_state('I')
  134. if (active is not None):
  135. active.state = 'D'
  136. active.end = int(time.time())
  137. self.stop_step()
  138. Step.update(**active.__dict__)
  139. self.api.emit("BREWING_STEP_DONE")
  140. if (inactive is not None):
  141. self.init_step(inactive)
  142. inactive.state = 'A'
  143. inactive.stepstate = inactive.config
  144. inactive.start = int(time.time())
  145. Step.update(**inactive.__dict__)
  146. self.api.emit("BREWING_STEP_STARTED")
  147. else:
  148. cbpi.brewing.log_action("Brewing Finished")
  149. self.api.emit("BREWING_FINISHED")
  150. cbpi.notify("Brewing Finished", "You are done!", timeout=None)
  151. cbpi.ws_emit("UPDATE_ALL_STEPS", Step.get_all())
  152. return ('', 204)
  153. def get_manged_fields_as_array(type_cfg):
  154. result = []
  155. for f in type_cfg.get("properties"):
  156. result.append(f.get("name"))
  157. return result
  158. def init_after_startup():
  159. '''
  160. Restart after startup. Check is a step is in state A and reinitialize
  161. :return: None
  162. '''
  163. step = Step.get_by_state('A')
  164. # We have an active step
  165. if step is not None:
  166. # get the type
  167. type_cfg = cbpi.cache.get("step_types").get(step.type)
  168. if type_cfg is None:
  169. # step type not found. cant restart step
  170. return
  171. cfg = step.stepstate.copy()
  172. cfg.update(dict(api=cbpi, id=step.id, managed_fields=get_manged_fields_as_array(type_cfg)))
  173. instance = type_cfg.get("class")(**cfg)
  174. instance.init()
  175. cbpi.cache["active_step"] = instance
  176. @cbpi.addon.core.initializer(order=2000)
  177. def init(cbpi):
  178. StepView.register(cbpi._app, route_base='/api/step')
  179. def get_all():
  180. with cbpi._app.app_context():
  181. return Step.get_all()
  182. with cbpi._app.app_context():
  183. init_after_startup()
  184. cbpi.add_cache_callback("steps", get_all)
  185. @cbpi.addon.core.backgroundjob(key="step_task", interval=0.1)
  186. def execute_step(api):
  187. '''
  188. Background job which executes the step
  189. :return:
  190. '''
  191. with cbpi._app.app_context():
  192. step = cbpi.cache.get("active_step")
  193. if step is not None:
  194. step.execute()
  195. if step.is_dirty():
  196. state = {}
  197. for field in step.managed_fields:
  198. state[field] = step.__getattribute__(field)
  199. Step.update_step_state(step.id, state)
  200. step.reset_dirty()
  201. cbpi.ws_emit("UPDATE_ALL_STEPS", Step.get_all())
  202. if step.n is True:
  203. StepView().start()
  204. cbpi.ws_emit("UPDATE_ALL_STEPS", Step.get_all())