Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

228 lines
7.5KB

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