mirror of
https://github.com/PiBrewing/craftbeerpi4.git
synced 2024-11-25 16:38:36 +01:00
Event Bus unregister added
This commit is contained in:
parent
4f74b39e39
commit
35ee2fbad9
20 changed files with 922 additions and 966 deletions
|
@ -2,7 +2,7 @@
|
||||||
<module type="PYTHON_MODULE" version="4">
|
<module type="PYTHON_MODULE" version="4">
|
||||||
<component name="NewModuleRootManager">
|
<component name="NewModuleRootManager">
|
||||||
<content url="file://$MODULE_DIR$" />
|
<content url="file://$MODULE_DIR$" />
|
||||||
<orderEntry type="jdk" jdkName="Python 3.6.1 virtualenv at ~/cbpi41" jdkType="Python SDK" />
|
<orderEntry type="jdk" jdkName="Python 3.7.1 virtualenv at ~/cbp42" jdkType="Python SDK" />
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
</component>
|
</component>
|
||||||
<component name="TestRunnerService">
|
<component name="TestRunnerService">
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.6.1 virtualenv at ~/cbpi41" project-jdk-type="Python SDK" />
|
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.7.1 virtualenv at ~/cbp42" project-jdk-type="Python SDK" />
|
||||||
</project>
|
</project>
|
1390
.idea/workspace.xml
1390
.idea/workspace.xml
File diff suppressed because it is too large
Load diff
|
@ -44,6 +44,7 @@ def on_event(topic):
|
||||||
def real_decorator(func):
|
def real_decorator(func):
|
||||||
func.eventbus = True
|
func.eventbus = True
|
||||||
func.topic = topic
|
func.topic = topic
|
||||||
|
func.c = None
|
||||||
return func
|
return func
|
||||||
|
|
||||||
return real_decorator
|
return real_decorator
|
||||||
|
@ -51,6 +52,7 @@ def on_event(topic):
|
||||||
def action(key, parameters):
|
def action(key, parameters):
|
||||||
def real_decorator(func):
|
def real_decorator(func):
|
||||||
func.action = True
|
func.action = True
|
||||||
|
|
||||||
func.key = key
|
func.key = key
|
||||||
func.parameters = parameters
|
func.parameters = parameters
|
||||||
return func
|
return func
|
||||||
|
|
|
@ -3,4 +3,29 @@ from core.api.extension import CBPiExtension
|
||||||
|
|
||||||
class CBPiKettleLogic(CBPiExtension):
|
class CBPiKettleLogic(CBPiExtension):
|
||||||
|
|
||||||
|
'''
|
||||||
|
Base Class for a Kettle logic.
|
||||||
|
'''
|
||||||
|
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
'''
|
||||||
|
test
|
||||||
|
|
||||||
|
|
||||||
|
:return:
|
||||||
|
'''
|
||||||
|
pass
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
'''
|
||||||
|
This method is running as background process when logic is started.
|
||||||
|
Typically a while loop responsible that the method keeps running
|
||||||
|
|
||||||
|
while self.running:
|
||||||
|
await asyncio.sleep(1)
|
||||||
|
|
||||||
|
:return:
|
||||||
|
'''
|
||||||
|
|
||||||
pass
|
pass
|
|
@ -5,7 +5,14 @@ class PropertyType(object):
|
||||||
|
|
||||||
class Property(object):
|
class Property(object):
|
||||||
class Select(PropertyType):
|
class Select(PropertyType):
|
||||||
|
|
||||||
def __init__(self, label, options, description=""):
|
def __init__(self, label, options, description=""):
|
||||||
|
'''
|
||||||
|
|
||||||
|
:param label:
|
||||||
|
:param options:
|
||||||
|
:param description:
|
||||||
|
'''
|
||||||
PropertyType.__init__(self)
|
PropertyType.__init__(self)
|
||||||
self.label = label
|
self.label = label
|
||||||
self.options = options
|
self.options = options
|
||||||
|
@ -13,6 +20,16 @@ class Property(object):
|
||||||
|
|
||||||
class Number(PropertyType):
|
class Number(PropertyType):
|
||||||
def __init__(self, label, configurable=False, default_value=None, unit="", description=""):
|
def __init__(self, label, configurable=False, default_value=None, unit="", description=""):
|
||||||
|
'''
|
||||||
|
Test
|
||||||
|
|
||||||
|
|
||||||
|
:param label:
|
||||||
|
:param configurable:
|
||||||
|
:param default_value:
|
||||||
|
:param unit:
|
||||||
|
:param description:
|
||||||
|
'''
|
||||||
PropertyType.__init__(self)
|
PropertyType.__init__(self)
|
||||||
self.label = label
|
self.label = label
|
||||||
self.configurable = configurable
|
self.configurable = configurable
|
||||||
|
@ -21,6 +38,13 @@ class Property(object):
|
||||||
|
|
||||||
class Text(PropertyType):
|
class Text(PropertyType):
|
||||||
def __init__(self, label, configurable=False, default_value="", description=""):
|
def __init__(self, label, configurable=False, default_value="", description=""):
|
||||||
|
'''
|
||||||
|
|
||||||
|
:param label:
|
||||||
|
:param configurable:
|
||||||
|
:param default_value:
|
||||||
|
:param description:
|
||||||
|
'''
|
||||||
PropertyType.__init__(self)
|
PropertyType.__init__(self)
|
||||||
self.label = label
|
self.label = label
|
||||||
self.configurable = configurable
|
self.configurable = configurable
|
||||||
|
@ -29,6 +53,11 @@ class Property(object):
|
||||||
|
|
||||||
class Actor(PropertyType):
|
class Actor(PropertyType):
|
||||||
def __init__(self, label, description=""):
|
def __init__(self, label, description=""):
|
||||||
|
'''
|
||||||
|
|
||||||
|
:param label:
|
||||||
|
:param description:
|
||||||
|
'''
|
||||||
PropertyType.__init__(self)
|
PropertyType.__init__(self)
|
||||||
self.label = label
|
self.label = label
|
||||||
self.configurable = True
|
self.configurable = True
|
||||||
|
@ -36,6 +65,11 @@ class Property(object):
|
||||||
|
|
||||||
class Sensor(PropertyType):
|
class Sensor(PropertyType):
|
||||||
def __init__(self, label, description=""):
|
def __init__(self, label, description=""):
|
||||||
|
'''
|
||||||
|
|
||||||
|
:param label:
|
||||||
|
:param description:
|
||||||
|
'''
|
||||||
PropertyType.__init__(self)
|
PropertyType.__init__(self)
|
||||||
self.label = label
|
self.label = label
|
||||||
self.configurable = True
|
self.configurable = True
|
||||||
|
@ -43,6 +77,12 @@ class Property(object):
|
||||||
|
|
||||||
class Kettle(PropertyType):
|
class Kettle(PropertyType):
|
||||||
def __init__(self, label, description=""):
|
def __init__(self, label, description=""):
|
||||||
|
'''
|
||||||
|
|
||||||
|
:param label:
|
||||||
|
:param description:
|
||||||
|
'''
|
||||||
|
|
||||||
PropertyType.__init__(self)
|
PropertyType.__init__(self)
|
||||||
self.label = label
|
self.label = label
|
||||||
self.configurable = True
|
self.configurable = True
|
||||||
|
|
|
@ -90,15 +90,22 @@ class ActorController(ActorHttp, CRUDController):
|
||||||
self.cache[id].instance = clazz(**cfg)
|
self.cache[id].instance = clazz(**cfg)
|
||||||
print("gpIO", self.cache[id].instance, self.cache[id].instance.gpio)
|
print("gpIO", self.cache[id].instance, self.cache[id].instance.gpio)
|
||||||
|
|
||||||
|
@on_event(topic="actor/1/on")
|
||||||
|
def on1(self, **kwargs) -> None:
|
||||||
|
print("WOOOOHOOO111111")
|
||||||
|
|
||||||
|
@on_event(topic="actor/1/on")
|
||||||
|
def on3(self, **kwargs) -> None:
|
||||||
|
print("WOOOOHOOO22222")
|
||||||
|
|
||||||
|
|
||||||
@on_event(topic="actor/+/on")
|
@on_event(topic="actor/+/on")
|
||||||
def on(self, id, power=100, **kwargs) -> None:
|
def on(self, id , power=100, **kwargs) -> None:
|
||||||
'''
|
'''
|
||||||
Method to switch an actor on.
|
Method to switch an actor on.
|
||||||
Supporting Event Topic "actor/+/on"
|
Supporting Event Topic "actor/+/on"
|
||||||
|
|
||||||
:param id: the actor id
|
:param actor_id: the actor id
|
||||||
:param power: as integer value between 1 and 100
|
:param power: as integer value between 1 and 100
|
||||||
:param kwargs:
|
:param kwargs:
|
||||||
:return:
|
:return:
|
||||||
|
@ -107,7 +114,7 @@ class ActorController(ActorHttp, CRUDController):
|
||||||
id = int(id)
|
id = int(id)
|
||||||
if id in self.cache:
|
if id in self.cache:
|
||||||
print("POWER ON")
|
print("POWER ON")
|
||||||
actor = self.cache[id].instance
|
actor = self.cache[id ].instance
|
||||||
print("ONNNNN", actor)
|
print("ONNNNN", actor)
|
||||||
actor.on(power)
|
actor.on(power)
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,10 @@ class CRUDController(object):
|
||||||
self.cache = {}
|
self.cache = {}
|
||||||
|
|
||||||
async def init(self):
|
async def init(self):
|
||||||
|
'''
|
||||||
|
|
||||||
|
:return:
|
||||||
|
'''
|
||||||
if self.caching is True:
|
if self.caching is True:
|
||||||
self.cache = await self.model.get_all()
|
self.cache = await self.model.get_all()
|
||||||
|
|
||||||
|
@ -24,19 +28,35 @@ class CRUDController(object):
|
||||||
return self.cache
|
return self.cache
|
||||||
|
|
||||||
async def get_one(self, id):
|
async def get_one(self, id):
|
||||||
|
'''
|
||||||
|
|
||||||
|
:param id:
|
||||||
|
:return:
|
||||||
|
'''
|
||||||
return self.cache.get(id)
|
return self.cache.get(id)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async def _pre_add_callback(self, data):
|
async def _pre_add_callback(self, data):
|
||||||
|
'''
|
||||||
|
|
||||||
|
:param data:
|
||||||
|
:return:
|
||||||
|
'''
|
||||||
pass
|
pass
|
||||||
|
|
||||||
async def _post_add_callback(self, m):
|
async def _post_add_callback(self, m):
|
||||||
|
'''
|
||||||
|
|
||||||
|
:param m:
|
||||||
|
:return:
|
||||||
|
'''
|
||||||
pass
|
pass
|
||||||
|
|
||||||
async def add(self, **data):
|
async def add(self, **data):
|
||||||
|
'''
|
||||||
|
|
||||||
|
:param data:
|
||||||
|
:return:
|
||||||
|
'''
|
||||||
await self._pre_add_callback(data)
|
await self._pre_add_callback(data)
|
||||||
m = await self.model.insert(**data)
|
m = await self.model.insert(**data)
|
||||||
await self._post_add_callback(m)
|
await self._post_add_callback(m)
|
||||||
|
@ -50,6 +70,12 @@ class CRUDController(object):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
async def update(self, id, data):
|
async def update(self, id, data):
|
||||||
|
'''
|
||||||
|
|
||||||
|
:param id:
|
||||||
|
:param data:
|
||||||
|
:return:
|
||||||
|
'''
|
||||||
id = int(id)
|
id = int(id)
|
||||||
data["id"] = id
|
data["id"] = id
|
||||||
|
|
||||||
|
@ -71,18 +97,29 @@ class CRUDController(object):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async def _pre_delete_callback(self, m):
|
async def _pre_delete_callback(self, m):
|
||||||
|
'''
|
||||||
|
|
||||||
|
:param m:
|
||||||
|
:return:
|
||||||
|
'''
|
||||||
pass
|
pass
|
||||||
|
|
||||||
async def _post_delete_callback(self, id):
|
async def _post_delete_callback(self, id):
|
||||||
|
'''
|
||||||
|
|
||||||
|
:param id:
|
||||||
|
:return:
|
||||||
|
'''
|
||||||
pass
|
pass
|
||||||
|
|
||||||
async def delete(self, id):
|
async def delete(self, id):
|
||||||
|
|
||||||
|
'''
|
||||||
|
|
||||||
|
:param id:
|
||||||
|
:return:
|
||||||
|
'''
|
||||||
await self._pre_delete_callback(id)
|
await self._pre_delete_callback(id)
|
||||||
m = await self.model.delete(id)
|
m = await self.model.delete(id)
|
||||||
await self._post_delete_callback(id)
|
await self._post_delete_callback(id)
|
||||||
|
@ -95,6 +132,10 @@ class CRUDController(object):
|
||||||
#self.cbpi.push("DELETE_%s" % self.key, id)
|
#self.cbpi.push("DELETE_%s" % self.key, id)
|
||||||
|
|
||||||
async def delete_all(self):
|
async def delete_all(self):
|
||||||
|
'''
|
||||||
|
|
||||||
|
:return:
|
||||||
|
'''
|
||||||
self.model.delete_all()
|
self.model.delete_all()
|
||||||
if self.caching is True:
|
if self.caching is True:
|
||||||
self.cache = {}
|
self.cache = {}
|
||||||
|
|
|
@ -11,12 +11,12 @@ class KettleHttp(HttpAPI):
|
||||||
|
|
||||||
@request_mapping(path="/types", auth_required=False)
|
@request_mapping(path="/types", auth_required=False)
|
||||||
async def get_types(self, request):
|
async def get_types(self, request):
|
||||||
web.json_response(data=self.types, dumps=json_dumps)
|
web.json_response(data=self.cbpi.kettle.types, dumps=json_dumps)
|
||||||
|
|
||||||
@request_mapping(path="/{id:\d+}/automatic", auth_required=False)
|
@request_mapping(path="/{id:\d+}/automatic", auth_required=False)
|
||||||
async def start2(self, request):
|
async def start2(self, request):
|
||||||
id = int(request.match_info['id'])
|
id = int(request.match_info['id'])
|
||||||
result = await self.toggle_automtic(id)
|
result = await self.cbpi.kettle.toggle_automtic(id)
|
||||||
if result[0] is True:
|
if result[0] is True:
|
||||||
return web.Response(text="OK")
|
return web.Response(text="OK")
|
||||||
else:
|
else:
|
||||||
|
@ -25,15 +25,15 @@ class KettleHttp(HttpAPI):
|
||||||
@request_mapping(path="/{id:\d+}/heater", auth_required=False)
|
@request_mapping(path="/{id:\d+}/heater", auth_required=False)
|
||||||
async def start(self, request):
|
async def start(self, request):
|
||||||
id = int(request.match_info['id'])
|
id = int(request.match_info['id'])
|
||||||
result = await self.heater_on(id)
|
result = await self.cbpi.kettle.heater_on(id)
|
||||||
if result[0] is True:
|
if result[0] is True:
|
||||||
return web.Response(text="OK")
|
return web.Response(text="OK")
|
||||||
else:
|
else:
|
||||||
return web.Response(status=404, text=result[1])
|
return web.Response(status=404, text=result[1])
|
||||||
|
|
||||||
class KettleController(CRUDController, KettleHttp):
|
class KettleController(CRUDController):
|
||||||
'''
|
'''
|
||||||
The main actor controller
|
The main kettle controller
|
||||||
'''
|
'''
|
||||||
model = KettleModel
|
model = KettleModel
|
||||||
|
|
||||||
|
@ -41,7 +41,9 @@ class KettleController(CRUDController, KettleHttp):
|
||||||
super(KettleController, self).__init__(cbpi)
|
super(KettleController, self).__init__(cbpi)
|
||||||
self.cbpi = cbpi
|
self.cbpi = cbpi
|
||||||
self.types = {}
|
self.types = {}
|
||||||
self.cbpi.register(self, "/kettle")
|
self.cbpi.register(self, None)
|
||||||
|
self.http = KettleHttp(cbpi)
|
||||||
|
self.cbpi.register(self.http, "/kettle")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -56,8 +58,10 @@ class KettleController(CRUDController, KettleHttp):
|
||||||
async def toggle_automtic(self, id):
|
async def toggle_automtic(self, id):
|
||||||
'''
|
'''
|
||||||
|
|
||||||
:param id:
|
Convenience Method to toggle automatic
|
||||||
:return:
|
|
||||||
|
:param id: kettle id as int
|
||||||
|
:return: (boolean, string)
|
||||||
'''
|
'''
|
||||||
kettle = await self.get_one(id)
|
kettle = await self.get_one(id)
|
||||||
if kettle is None:
|
if kettle is None:
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
class StepController():
|
||||||
|
|
||||||
|
|
||||||
|
async def start(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
async def stop(self):
|
||||||
|
pass
|
|
@ -74,7 +74,7 @@ class CraftBeerPi():
|
||||||
doc["topic"] = method.__getattribute__("topic")
|
doc["topic"] = method.__getattribute__("topic")
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
self.bus.register(method.__getattribute__("topic"), method, doc)
|
self.bus.register(method.__getattribute__("topic"), method)
|
||||||
|
|
||||||
def register_background_task(self, obj):
|
def register_background_task(self, obj):
|
||||||
'''
|
'''
|
||||||
|
@ -234,7 +234,7 @@ class CraftBeerPi():
|
||||||
await self.kettle.init()
|
await self.kettle.init()
|
||||||
|
|
||||||
async def load_plugins(app):
|
async def load_plugins(app):
|
||||||
await PluginController.load_plugin_list()
|
#await PluginController.load_plugin_list()
|
||||||
await self.plugin.load_plugins()
|
await self.plugin.load_plugins()
|
||||||
|
|
||||||
async def call_initializer(app):
|
async def call_initializer(app):
|
||||||
|
|
|
@ -1,8 +1,14 @@
|
||||||
import inspect
|
import inspect
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
import asyncio
|
||||||
|
|
||||||
|
|
||||||
class EventBus(object):
|
class EventBus(object):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Node(object):
|
class Node(object):
|
||||||
__slots__ = '_children', '_content'
|
__slots__ = '_children', '_content'
|
||||||
|
|
||||||
|
@ -10,18 +16,39 @@ class EventBus(object):
|
||||||
self._children = {}
|
self._children = {}
|
||||||
self._content = None
|
self._content = None
|
||||||
|
|
||||||
def register(self, key, value, doc=None):
|
|
||||||
|
|
||||||
if doc is not None:
|
|
||||||
self.docs[key] = doc
|
class Content(object):
|
||||||
self.logger.info("key %s", key)
|
def __init__(self, parent, topic, method, once):
|
||||||
|
|
||||||
|
self.parent = parent
|
||||||
|
self.method = method
|
||||||
|
self.name = method.__name__
|
||||||
|
self.once = once
|
||||||
|
self.topic = topic
|
||||||
|
|
||||||
|
def register(self, topic, method, once=False):
|
||||||
|
print("REGISTER", topic, method)
|
||||||
|
if method in self.registry:
|
||||||
|
raise RuntimeError("Method %s already registerd. Please unregister first!" % method.__name__)
|
||||||
|
self.logger.info("Topic %s", topic)
|
||||||
|
|
||||||
node = self._root
|
node = self._root
|
||||||
for sym in key.split('/'):
|
for sym in topic.split('/'):
|
||||||
node = node._children.setdefault(sym, self.Node())
|
node = node._children.setdefault(sym, self.Node())
|
||||||
|
|
||||||
if not isinstance(node._content, list):
|
if not isinstance(node._content, list):
|
||||||
node._content = []
|
node._content = []
|
||||||
node._content.append(value)
|
|
||||||
|
|
||||||
|
c = self.Content(node, topic, method, once)
|
||||||
|
|
||||||
|
|
||||||
|
node._content.append(c)
|
||||||
|
print(c, node._content, topic)
|
||||||
|
self.registry[method] = c
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def get_callbacks(self, key):
|
def get_callbacks(self, key):
|
||||||
try:
|
try:
|
||||||
|
@ -34,20 +61,27 @@ class EventBus(object):
|
||||||
except KeyError:
|
except KeyError:
|
||||||
raise KeyError(key)
|
raise KeyError(key)
|
||||||
|
|
||||||
def unregister(self, key, method=None):
|
|
||||||
|
|
||||||
|
def unregister(self, method):
|
||||||
|
self.logger.info("Unregister %s", method.__name__)
|
||||||
|
if method in self.registry:
|
||||||
|
content = self.registry[method]
|
||||||
|
clean_idx = None
|
||||||
|
for idx, content_obj in enumerate(content.parent._content):
|
||||||
|
if method == content_obj.method:
|
||||||
|
clean_idx = idx
|
||||||
|
break
|
||||||
|
if clean_idx is not None:
|
||||||
|
del content.parent._content[clean_idx]
|
||||||
|
|
||||||
|
'''
|
||||||
|
def unregister(self, key, method):
|
||||||
lst = []
|
lst = []
|
||||||
try:
|
try:
|
||||||
parent, node = None, self._root
|
parent, node = None, self._root
|
||||||
for k in key.split('/'):
|
for k in key.split('/'):
|
||||||
parent, node = node, node._children[k]
|
parent, node = node, node._children[k]
|
||||||
lst.append((parent, k, node))
|
lst.append((parent, k, node))
|
||||||
# TODO
|
|
||||||
print(node._content)
|
|
||||||
if method is not None:
|
|
||||||
node._content = None
|
|
||||||
else:
|
|
||||||
node._content = None
|
|
||||||
except KeyError:
|
except KeyError:
|
||||||
raise KeyError(key)
|
raise KeyError(key)
|
||||||
else: # cleanup
|
else: # cleanup
|
||||||
|
@ -55,23 +89,43 @@ class EventBus(object):
|
||||||
if node._children or node._content is not None:
|
if node._children or node._content is not None:
|
||||||
break
|
break
|
||||||
del parent._children[k]
|
del parent._children[k]
|
||||||
|
'''
|
||||||
|
|
||||||
def __init__(self, cbpi):
|
def __init__(self, cbpi):
|
||||||
self.logger = logging.getLogger(__name__)
|
self.logger = logging.getLogger(__name__)
|
||||||
self._root = self.Node()
|
self._root = self.Node()
|
||||||
|
self.registry = {}
|
||||||
self.docs = {}
|
self.docs = {}
|
||||||
self.cbpi = cbpi
|
self.cbpi = cbpi
|
||||||
|
|
||||||
def fire(self, topic: str, **kwargs) -> None:
|
def fire(self, topic: str, **kwargs) -> None:
|
||||||
|
print("#### FIRE", topic)
|
||||||
self.logger.info("EMIT EVENT %s", topic)
|
self.logger.info("EMIT EVENT %s", topic)
|
||||||
for methods in self.iter_match(topic):
|
|
||||||
for f in methods:
|
cleanup_methods = []
|
||||||
if inspect.iscoroutinefunction(f):
|
for content_array in self.iter_match(topic):
|
||||||
print("ITS ASYNC")
|
|
||||||
self.cbpi.app.loop.create_task(f(**kwargs, topic = topic))
|
print(content_array)
|
||||||
|
cleanup = []
|
||||||
|
for idx, content_obj in enumerate(content_array):
|
||||||
|
print("#################")
|
||||||
|
|
||||||
|
print("TOPIC", content_obj.method, content_obj.topic)
|
||||||
|
print("#################")
|
||||||
|
if inspect.iscoroutinefunction(content_obj.method):
|
||||||
|
self.cbpi.app.loop.create_task(content_obj.method(**kwargs, topic = topic))
|
||||||
else:
|
else:
|
||||||
f(**kwargs, topic = topic)
|
content_obj.method(**kwargs, topic = topic)
|
||||||
|
|
||||||
|
if content_obj.once is True:
|
||||||
|
cleanup.append(idx)
|
||||||
|
for idx in cleanup:
|
||||||
|
del content_array[idx]
|
||||||
|
|
||||||
|
|
||||||
|
print(self._root)
|
||||||
|
print("#### FIRE END ######")
|
||||||
|
|
||||||
|
|
||||||
def iter_match(self, topic):
|
def iter_match(self, topic):
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import asyncio
|
import asyncio
|
||||||
|
|
||||||
from core.api import Property
|
from core.api import Property, on_event
|
||||||
from core.api.kettle_logic import CBPiKettleLogic
|
from core.api.kettle_logic import CBPiKettleLogic
|
||||||
|
|
||||||
|
|
||||||
|
@ -11,17 +11,64 @@ class CustomLogic(CBPiKettleLogic):
|
||||||
|
|
||||||
running = True
|
running = True
|
||||||
|
|
||||||
|
|
||||||
|
async def wait_for_event(self, topic, timeout=None):
|
||||||
|
|
||||||
|
|
||||||
|
future_obj = self.cbpi.app.loop.create_future()
|
||||||
|
|
||||||
|
async def callback(id, **kwargs):
|
||||||
|
print("---------------------------------- CALLBACK ----------------")
|
||||||
|
print(kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if int(id) == 1:
|
||||||
|
self.cbpi.bus.unregister(callback)
|
||||||
|
future_obj.set_result("HELLO")
|
||||||
|
elif int(id) == 2:
|
||||||
|
self.cbpi.bus.unregister(callback)
|
||||||
|
else:
|
||||||
|
print("ID", id)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
print("TOPIC", topic)
|
||||||
|
self.cbpi.bus.register(topic=topic, method=callback)
|
||||||
|
|
||||||
|
if timeout is not None:
|
||||||
|
|
||||||
|
try:
|
||||||
|
print("----> WAIT FOR FUTURE")
|
||||||
|
await asyncio.wait_for(future_obj, timeout=10.0)
|
||||||
|
print("------> RETURN RESULT")
|
||||||
|
return future_obj.result()
|
||||||
|
except asyncio.TimeoutError:
|
||||||
|
print('timeout!')
|
||||||
|
else:
|
||||||
|
print("----> WAIT FOR FUTURE")
|
||||||
|
await future_obj
|
||||||
|
return future_obj.result()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async def run(self):
|
async def run(self):
|
||||||
|
|
||||||
|
result = await self.wait_for_event("actor/+/on")
|
||||||
|
print("THE RESULT", result)
|
||||||
|
|
||||||
|
|
||||||
|
'''
|
||||||
while self.running:
|
while self.running:
|
||||||
|
|
||||||
|
|
||||||
print("RUN", self.test)
|
print("RUN", self.test)
|
||||||
value = await self.cbpi.sensor.get_value(1)
|
value = await self.cbpi.sensor.get_value(1)
|
||||||
print(value)
|
print(value)
|
||||||
if value >= 10:
|
if value >= 10:
|
||||||
break
|
break
|
||||||
await asyncio.sleep(1)
|
await asyncio.sleep(1)
|
||||||
|
'''
|
||||||
print("STOP LOGIC")
|
print("STOP LOGIC")
|
||||||
|
|
||||||
def setup(cbpi):
|
def setup(cbpi):
|
||||||
|
|
|
@ -11,14 +11,27 @@ Architecture
|
||||||
ActorController
|
ActorController
|
||||||
^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
.. automodule:: core.controller.actor_controller
|
.. autoclass:: core.controller.actor_controller.ActorController
|
||||||
:members:
|
:members:
|
||||||
:inherited-members:
|
:private-members:
|
||||||
|
:undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
|
|
||||||
|
CBPiActor
|
||||||
|
^^^^^^^^^
|
||||||
|
|
||||||
|
.. autoclass:: core.api.actor.CBPiActor
|
||||||
|
:members:
|
||||||
|
:private-members:
|
||||||
|
:undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
|
|
||||||
Custom Actor
|
Custom Actor
|
||||||
^^^^^^^^^^^^^
|
^^^^^^^^^^^^^
|
||||||
|
|
||||||
.. literalinclude:: ../../core/extension/dummy/__init__.py
|
.. literalinclude:: ../../core/extension/dummyactor/__init__.py
|
||||||
:caption: __init__.py
|
:caption: __init__.py
|
||||||
:name: __init__-py
|
:name: __init__-py
|
||||||
:language: python
|
:language: python
|
||||||
|
@ -27,6 +40,6 @@ Custom Actor
|
||||||
|
|
||||||
config.yaml
|
config.yaml
|
||||||
|
|
||||||
.. literalinclude:: ../../core/extension/dummy/config.yaml
|
.. literalinclude:: ../../core/extension/dummyactor/config.yaml
|
||||||
:language: yaml
|
:language: yaml
|
||||||
:linenos:
|
:linenos:
|
|
@ -75,8 +75,8 @@ pygments_style = None
|
||||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||||
# a list of builtin themes.
|
# a list of builtin themes.
|
||||||
#
|
#
|
||||||
#html_theme = 'alabaster'
|
html_theme = 'alabaster'
|
||||||
html_theme = 'sphinx_rtd_theme'
|
#html_theme = 'sphinx_rtd_theme'
|
||||||
|
|
||||||
# Theme options are theme-specific and customize the look and feel of a theme
|
# Theme options are theme-specific and customize the look and feel of a theme
|
||||||
# further. For a list of options available for each theme, see the
|
# further. For a list of options available for each theme, see the
|
||||||
|
|
|
@ -14,7 +14,8 @@ Welcome to CraftBeerPi's documentation!
|
||||||
core
|
core
|
||||||
actor
|
actor
|
||||||
sensor
|
sensor
|
||||||
|
kettle_controller
|
||||||
|
properties
|
||||||
|
|
||||||
|
|
||||||
..
|
..
|
||||||
|
|
39
docs_src/source/kettle_controller.rst
Normal file
39
docs_src/source/kettle_controller.rst
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
Kettle
|
||||||
|
================
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
KettleController
|
||||||
|
^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
.. autoclass:: core.controller.kettle_controller.KettleController
|
||||||
|
:members:
|
||||||
|
:private-members:
|
||||||
|
:undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
|
CBPiKettleLogic
|
||||||
|
^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
|
||||||
|
.. autoclass:: core.api.kettle_logic.CBPiKettleLogic
|
||||||
|
:members:
|
||||||
|
:show-inheritance:
|
||||||
|
:inherited-members:
|
||||||
|
|
||||||
|
|
||||||
|
Custom Logic
|
||||||
|
^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
.. literalinclude:: ../../core/extension/dummylogic/__init__.py
|
||||||
|
:caption: __init__.py
|
||||||
|
:name: __init__-py
|
||||||
|
:language: python
|
||||||
|
:linenos:
|
||||||
|
|
||||||
|
|
||||||
|
config.yaml
|
||||||
|
|
||||||
|
.. literalinclude:: ../../core/extension/dummylogic/config.yaml
|
||||||
|
:language: yaml
|
||||||
|
:linenos:
|
10
docs_src/source/properties.rst
Normal file
10
docs_src/source/properties.rst
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
Properties
|
||||||
|
===========
|
||||||
|
|
||||||
|
|
||||||
|
.. autoclass:: core.api.property.Property
|
||||||
|
:members:
|
||||||
|
:private-members:
|
||||||
|
:undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
80
main2.py
Normal file
80
main2.py
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
import asyncio
|
||||||
|
|
||||||
|
from core.eventbus import EventBus
|
||||||
|
|
||||||
|
|
||||||
|
async def waiter(event):
|
||||||
|
print('waiting for it ...')
|
||||||
|
await asyncio.sleep(4)
|
||||||
|
print('... got it!')
|
||||||
|
event.set()
|
||||||
|
|
||||||
|
async def main(loop):
|
||||||
|
# Create an Event object.
|
||||||
|
event = asyncio.Event()
|
||||||
|
|
||||||
|
# Spawn a Task to wait until 'event' is set.
|
||||||
|
#waiter_task = asyncio.create_task(waiter(event))
|
||||||
|
|
||||||
|
waiter_task = loop.create_task(waiter(event))
|
||||||
|
print("WAIT FOR EVENT")
|
||||||
|
await event.wait()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Wait until the waiter task is finished.
|
||||||
|
await waiter_task
|
||||||
|
|
||||||
|
#loop = asyncio.get_event_loop()
|
||||||
|
#loop.run_until_complete(main(loop))
|
||||||
|
#loop.close()
|
||||||
|
|
||||||
|
|
||||||
|
bus = EventBus(None)
|
||||||
|
|
||||||
|
def test(**kwargs):
|
||||||
|
print("")
|
||||||
|
print("------------> HALLO WILD CARD")
|
||||||
|
print("")
|
||||||
|
print(hex(id(test)))
|
||||||
|
print("BUS",bus)
|
||||||
|
|
||||||
|
|
||||||
|
def test2(**kwargs):
|
||||||
|
print("------------> HALLO NAME")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Name():
|
||||||
|
|
||||||
|
def test(self, **kwargs):
|
||||||
|
print("---->OK")
|
||||||
|
bus.unregister(self.test)
|
||||||
|
print("#################### ID2", hex(id(n.test)))
|
||||||
|
|
||||||
|
|
||||||
|
n = Name()
|
||||||
|
print("the ID", hex(id(n.test)))
|
||||||
|
id1 = bus.register("test/#", n.test)
|
||||||
|
print("the ID2", hex(id(n.test)))
|
||||||
|
|
||||||
|
if n.test == n.test:
|
||||||
|
print("SAME")
|
||||||
|
id1 = bus.register("test/#", test)
|
||||||
|
id2 = bus.register("test/name", test2)
|
||||||
|
|
||||||
|
print(id1, id2)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
print(hex(id(test2)))
|
||||||
|
|
||||||
|
print(bus.get_callbacks("test/name"))
|
||||||
|
|
||||||
|
bus.fire("test/name")
|
||||||
|
|
||||||
|
bus.fire("test/name")
|
||||||
|
|
||||||
|
bus.unregister(test2)
|
||||||
|
|
||||||
|
bus.fire("test/name")
|
|
@ -6,33 +6,48 @@ aiohttp-session==2.7.0
|
||||||
aiohttp-swagger==1.0.5
|
aiohttp-swagger==1.0.5
|
||||||
aiojobs==0.2.2
|
aiojobs==0.2.2
|
||||||
aiosqlite==0.7.0
|
aiosqlite==0.7.0
|
||||||
|
alabaster==0.7.12
|
||||||
asn1crypto==0.24.0
|
asn1crypto==0.24.0
|
||||||
async-timeout==3.0.1
|
async-timeout==3.0.1
|
||||||
atomicwrites==1.2.1
|
atomicwrites==1.2.1
|
||||||
attrs==18.2.0
|
attrs==18.2.0
|
||||||
|
Babel==2.6.0
|
||||||
|
certifi==2018.10.15
|
||||||
cffi==1.11.5
|
cffi==1.11.5
|
||||||
chardet==3.0.4
|
chardet==3.0.4
|
||||||
cryptography==2.3.1
|
cryptography==2.3.1
|
||||||
docopt==0.6.2
|
docopt==0.6.2
|
||||||
|
docutils==0.14
|
||||||
hbmqtt==0.9.4
|
hbmqtt==0.9.4
|
||||||
idna==2.7
|
idna==2.7
|
||||||
idna-ssl==1.1.0
|
idna-ssl==1.1.0
|
||||||
|
imagesize==1.1.0
|
||||||
Jinja2==2.10
|
Jinja2==2.10
|
||||||
MarkupSafe==1.0
|
MarkupSafe==1.0
|
||||||
more-itertools==4.3.0
|
more-itertools==4.3.0
|
||||||
multidict==4.4.2
|
multidict==4.4.2
|
||||||
|
packaging==18.0
|
||||||
passlib==1.7.1
|
passlib==1.7.1
|
||||||
pluggy==0.7.1
|
pluggy==0.7.1
|
||||||
py==1.7.0
|
py==1.7.0
|
||||||
pycparser==2.19
|
pycparser==2.19
|
||||||
|
pyfiglet==0.7.6
|
||||||
|
Pygments==2.2.0
|
||||||
pync==2.0.3
|
pync==2.0.3
|
||||||
|
pyparsing==2.3.0
|
||||||
pytest==3.8.2
|
pytest==3.8.2
|
||||||
pytest-aiohttp==0.3.0
|
pytest-aiohttp==0.3.0
|
||||||
python-dateutil==2.7.5
|
python-dateutil==2.7.5
|
||||||
|
pytz==2018.7
|
||||||
PyYAML==3.13
|
PyYAML==3.13
|
||||||
|
requests==2.20.1
|
||||||
six==1.11.0
|
six==1.11.0
|
||||||
|
snowballstemmer==1.2.1
|
||||||
|
Sphinx==1.8.2
|
||||||
|
sphinx-rtd-theme==0.4.2
|
||||||
|
sphinxcontrib-websupport==1.1.0
|
||||||
ticket-auth==0.1.4
|
ticket-auth==0.1.4
|
||||||
transitions==0.6.8
|
transitions==0.6.8
|
||||||
|
urllib3==1.24.1
|
||||||
websockets==6.0
|
websockets==6.0
|
||||||
yarl==1.2.6
|
yarl==1.2.6
|
||||||
pyfiglet
|
|
Loading…
Reference in a new issue