Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

260 řádky
9.6KB

  1. from proptypes import *
  2. class BaseAPI(object):
  3. def __init__(self, cbpi):
  4. self.cbpi = cbpi
  5. self.cbpi.cache[self.key] = {}
  6. def init(self):
  7. for name, value in self.cbpi.cache[self.key].iteritems():
  8. value["class"].init_global()
  9. def parseProps(self, key, cls, **options):
  10. name = cls.__name__
  11. tmpObj = cls()
  12. try:
  13. doc = tmpObj.__doc__.strip()
  14. except:
  15. doc = ""
  16. if self.cbpi.cache.get(key) is None:
  17. self.cbpi.cache[key] = {}
  18. self.cbpi.logger.debug(name)
  19. self.cbpi.cache.get(key)[name] = {"name": name, "class": cls, "description":doc, "properties": [], "actions": []}
  20. self.cbpi.cache.get(key)[name].update(options)
  21. members = [attr for attr in dir(tmpObj) if not callable(getattr(tmpObj, attr)) and not attr.startswith("__")]
  22. for m in members:
  23. t = tmpObj.__getattribute__(m)
  24. if isinstance(t, Property.Number):
  25. self.cbpi.cache.get(key)[name]["properties"].append({"name": m, "label": t.label, "type": "number", "configurable": t.configurable, "description": t.description, "default_value": t.default_value, "unit": t.unit})
  26. elif isinstance(t, Property.Text):
  27. self.cbpi.cache.get(key)[name]["properties"].append({"name": m, "label": t.label, "type": "text", "required": t.required, "configurable": t.configurable, "description": t.description, "default_value": t.default_value})
  28. elif isinstance(t, Property.Select):
  29. self.cbpi.cache.get(key)[name]["properties"].append({"name": m, "label": t.label, "type": "select", "configurable": True, "options": t.options, "description": t.description})
  30. elif isinstance(t, Property.Actor):
  31. self.cbpi.cache.get(key)[name]["properties"].append({"name": m, "label": t.label, "type": "actor", "configurable": True, "description": t.description})
  32. elif isinstance(t, Property.Sensor):
  33. self.cbpi.cache.get(key)[name]["properties"].append({"name": m, "label": t.label, "type": "sensor", "configurable": True, "description": t.description})
  34. elif isinstance(t, Property.Kettle):
  35. self.cbpi.cache.get(key)[name]["properties"].append({"name": m, "label": t.label, "type": "kettle", "configurable": True, "description": t.description})
  36. for method_name, method in cls.__dict__.iteritems():
  37. if hasattr(method, "action"):
  38. label = method.__getattribute__("label")
  39. parameters = method.__getattribute__("parameters")
  40. props = []
  41. if parameters is not None:
  42. for k, t in parameters.iteritems():
  43. if isinstance(t, Property.Number):
  44. props.append({"name": k, "label": t.label, "type": "number", "configurable": t.configurable, "description": t.description, "default_value": t.default_value, "unit": t.unit})
  45. elif isinstance(t, Property.Text):
  46. props.append({"name": k, "label": t.label, "type": "text", "required": t.required, "configurable": t.configurable, "description": t.description, "default_value": t.default_value})
  47. elif isinstance(t, Property.Select):
  48. props.append({"name": k, "label": t.label, "type": "select", "configurable": True, "options": t.options, "description": t.description})
  49. elif isinstance(t, Property.Actor):
  50. props.append({"name": k, "label": t.label, "type": "actor", "configurable": True, "description": t.description})
  51. elif isinstance(t, Property.Sensor):
  52. props.append({"name": k, "label": t.label, "type": "sensor", "configurable": True, "description": t.description})
  53. elif isinstance(t, Property.Kettle):
  54. props.append({"name": k, "label": t.label, "type": "kettle", "configurable": True, "description": t.description})
  55. self.cbpi.cache.get(key)[name]["actions"].append({"method": method_name, "label": label, "properties":props })
  56. return cls
  57. class SensorAPI(BaseAPI):
  58. key = "sensor_types"
  59. def type(self, description="Step", **options):
  60. def decorator(f):
  61. BaseAPI.parseProps(self, self.key,f, description=description)
  62. return f
  63. return decorator
  64. def action(self, label, parameters=None):
  65. def real_decorator(func):
  66. func.action = True
  67. func.parameters = parameters
  68. func.label = label
  69. return func
  70. return real_decorator
  71. class StepAPI(BaseAPI):
  72. key = "step_types"
  73. def init(self):
  74. pass
  75. def type(self, description="Step", **options):
  76. def decorator(f):
  77. BaseAPI.parseProps(self, self.key,f, description=description)
  78. return f
  79. return decorator
  80. def action(self, label, parameters=None):
  81. def real_decorator(func):
  82. func.action = True
  83. func.label = label
  84. func.parameters = parameters
  85. return func
  86. return real_decorator
  87. class ActorAPI(BaseAPI):
  88. key = "actor_types"
  89. def type(self, description="", **options):
  90. def decorator(f):
  91. BaseAPI.parseProps(self, self.key, f, description=description)
  92. return f
  93. return decorator
  94. def action(self, label, parameters=None):
  95. def real_decorator(func):
  96. func.action = True
  97. func.label = label
  98. func.parameters = parameters
  99. return func
  100. return real_decorator
  101. class KettleAPI(BaseAPI):
  102. key = "controller_types"
  103. def controller(self, description="", **options):
  104. def decorator(f):
  105. BaseAPI.parseProps(self, self.key,f,description=description)
  106. return f
  107. return decorator
  108. def action(self, label, parameters=None):
  109. def real_decorator(func):
  110. func.action = True
  111. func.label = label
  112. func.parameters = parameters
  113. return func
  114. return real_decorator
  115. class FermenterAPI(BaseAPI):
  116. key = "fermentation_controller_types"
  117. def controller(self, description="Step", **options):
  118. def decorator(f):
  119. BaseAPI.parseProps(self, self.key,f,description=description)
  120. return f
  121. return decorator
  122. def action(self, label, parameters=None):
  123. def real_decorator(func):
  124. func.action = True
  125. func.label = label
  126. func.parameters = parameters
  127. return func
  128. return real_decorator
  129. class CoreAPI(BaseAPI):
  130. key = "core"
  131. def __init__(self, cbpi):
  132. self.cbpi = cbpi
  133. self.cbpi.cache["actions"] = {}
  134. self.cbpi.cache["init"] = []
  135. self.cbpi.cache["js"] = {}
  136. self.cbpi.cache["background"] = []
  137. self.cbpi.cache["web_menu"] =[]
  138. def init(self):
  139. self.cbpi.cache["init"] = sorted(self.cbpi.cache["init"], key=lambda k: k['order'])
  140. for value in self.cbpi.cache.get("init"):
  141. value["function"](self.cbpi)
  142. def job(interval, method):
  143. while True:
  144. try:
  145. method(self.cbpi)
  146. except Exception as e:
  147. self.cbpi.logger.error(e)
  148. self.cbpi.sleep(interval)
  149. for value in self.cbpi.cache.get("background"):
  150. t = self.cbpi.start_background_task(target=job, interval=value.get("interval"), method=value.get("function"))
  151. def action(self, **options):
  152. def decorator(f):
  153. BaseAPI.parseProps(self, "actions", f)
  154. return f
  155. return decorator
  156. def add_js(self, name, file):
  157. self.cbpi.cache["js"][name] = file
  158. def add_menu_link(self, name, path):
  159. self.cbpi.cache["web_menu"].append(dict(name=name, path=path))
  160. def initializer(self, order=0, **options):
  161. def decorator(f):
  162. self.cbpi.cache.get("init").append({"function": f, "order": order})
  163. return f
  164. return decorator
  165. def backgroundtask(self, key, interval, **options):
  166. def decorator(f):
  167. self.cbpi.cache.get("background").append({"function": f, "key": key, "interval": interval})
  168. return f
  169. return decorator
  170. def listen(self, name, method=None, async=False):
  171. if method is not None:
  172. if self.cbpi.eventbus.get(name) is None:
  173. self.cbpi.eventbus[name] = []
  174. self.cbpi.eventbus[name].append({"function": method, "async": async})
  175. else:
  176. def real_decorator(function):
  177. if self.cbpi.eventbus.get(name) is None:
  178. self.cbpi.eventbus[name] = []
  179. self.cbpi.eventbus[name].append({"function": function, "async": async})
  180. def wrapper(*args, **kwargs):
  181. return function(*args, **kwargs)
  182. return wrapper
  183. return real_decorator
  184. class Buzzer(object):
  185. def beep(self):
  186. pass
  187. class Addon(object):
  188. def __init__(self, cbpi):
  189. self.step = StepAPI(cbpi)
  190. self.actor = ActorAPI(cbpi)
  191. self.sensor = SensorAPI(cbpi)
  192. self.kettle = KettleAPI(cbpi)
  193. self.fermenter = FermenterAPI(cbpi)
  194. self.core = CoreAPI(cbpi)
  195. def init(self):
  196. self.core.init()
  197. self.step.init()
  198. self.actor.init()
  199. self.sensor.init()