mirror of
https://github.com/PiBrewing/craftbeerpi4.git
synced 2024-11-21 14:38:15 +01:00
changes for ui
This commit is contained in:
parent
d0b751a0d4
commit
8cf373c993
13 changed files with 844 additions and 408 deletions
File diff suppressed because it is too large
Load diff
|
@ -26,9 +26,6 @@ def create_home_folder_structure():
|
|||
|
||||
|
||||
def main():
|
||||
#import sys
|
||||
#arg1, arg2 = sys.argv[1], sys.argv[2]
|
||||
|
||||
|
||||
create_home_folder_structure()
|
||||
create_plugin_file()
|
||||
|
|
|
@ -54,7 +54,7 @@ class ActorController(CRUDController):
|
|||
await self.cbpi.bus.fire(topic="actor/%s/stopped" % actor.id, id=actor.id)
|
||||
|
||||
@on_event(topic="actor/+/switch/on")
|
||||
async def on(self, actor_id, future: Future, power=100, **kwargs) -> None:
|
||||
async def on(self, actor_id, power=100, **kwargs) -> None:
|
||||
"""
|
||||
Method to switch an actor on.
|
||||
Supporting Event Topic "actor/+/on"
|
||||
|
@ -70,10 +70,9 @@ class ActorController(CRUDController):
|
|||
if actor_id in self.cache:
|
||||
self.logger.debug("ON %s" % actor_id)
|
||||
actor = self.cache[actor_id].instance
|
||||
await self.cbpi.bus.fire("actor/%s/on/ok" % actor_id)
|
||||
actor.on(power)
|
||||
await self.cbpi.bus.fire("actor/%s/on/ok" % actor_id)
|
||||
|
||||
future.set_result("OK")
|
||||
|
||||
@on_event(topic="actor/+/toggle")
|
||||
async def toggle(self, actor_id, power=100, **kwargs) -> None:
|
||||
|
@ -91,9 +90,13 @@ class ActorController(CRUDController):
|
|||
if actor_id in self.cache:
|
||||
actor = self.cache[actor_id].instance
|
||||
if actor.state is True:
|
||||
actor.off()
|
||||
|
||||
await self.off(actor_id=actor_id)
|
||||
else:
|
||||
actor.on()
|
||||
|
||||
|
||||
await self.on(actor_id=actor_id)
|
||||
|
||||
|
||||
|
||||
@on_event(topic="actor/+/off")
|
||||
|
@ -111,6 +114,7 @@ class ActorController(CRUDController):
|
|||
if actor_id in self.cache:
|
||||
actor = self.cache[actor_id].instance
|
||||
actor.off()
|
||||
await self.cbpi.bus.fire("actor/%s/off/ok" % actor_id)
|
||||
|
||||
@on_event(topic="actor/+/action")
|
||||
async def call_action(self, actor_id, data, **kwargs) -> None:
|
||||
|
|
|
@ -36,8 +36,6 @@ from cbpi.http_endpoints.http_translation import TranslationHttpEndpoint
|
|||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
|
||||
|
||||
@web.middleware
|
||||
async def error_middleware(request, handler):
|
||||
try:
|
||||
|
@ -46,6 +44,7 @@ async def error_middleware(request, handler):
|
|||
return response
|
||||
message = response.message
|
||||
except web.HTTPException as ex:
|
||||
print(ex)
|
||||
if ex.status != 404:
|
||||
raise
|
||||
message = ex.reason
|
||||
|
@ -60,7 +59,6 @@ class CraftBeerPi():
|
|||
|
||||
def __init__(self):
|
||||
|
||||
|
||||
self.static_config = load_config("./config/config.yaml")
|
||||
self.database_file = "./craftbeerpi.db"
|
||||
logger.info("Init CraftBeerPI")
|
||||
|
@ -71,15 +69,18 @@ class CraftBeerPi():
|
|||
|
||||
self._setup_shutdownhook()
|
||||
self.initializer = []
|
||||
|
||||
self.bus = CBPiEventBus(self.app.loop, self)
|
||||
self.ws = CBPiWebSocket(self)
|
||||
self.job = JobController(self)
|
||||
self.config = ConfigController(self)
|
||||
self.ws = CBPiWebSocket(self)
|
||||
|
||||
self.translation = TranslationController(self)
|
||||
self.actor = ActorController(self)
|
||||
self.sensor = SensorController(self)
|
||||
self.plugin = PluginController(self)
|
||||
self.system = SystemController(self)
|
||||
self.config = ConfigController(self)
|
||||
|
||||
self.kettle = KettleController(self)
|
||||
self.step = StepController(self)
|
||||
self.dashboard = DashboardController(self)
|
||||
|
@ -97,6 +98,7 @@ class CraftBeerPi():
|
|||
|
||||
def _setup_shutdownhook(self):
|
||||
self.shutdown = False
|
||||
|
||||
async def on_cleanup(app):
|
||||
self.shutdown = True
|
||||
|
||||
|
@ -158,6 +160,7 @@ class CraftBeerPi():
|
|||
}
|
||||
switcher[http_method]()
|
||||
|
||||
print("ADDD ", routes)
|
||||
if url_prefix != "/":
|
||||
logger.debug("URL Prefix: %s " % (url_prefix,))
|
||||
sub = web.Application()
|
||||
|
@ -166,6 +169,7 @@ class CraftBeerPi():
|
|||
sub.add_routes([web.static('/static', static, show_index=False)])
|
||||
self.app.add_subapp(url_prefix, sub)
|
||||
else:
|
||||
print("ADDD ", routes)
|
||||
self.app.add_routes(routes)
|
||||
|
||||
def _swagger_setup(self):
|
||||
|
|
|
@ -115,6 +115,8 @@ class CBPiEventBus(object):
|
|||
|
||||
futures = {}
|
||||
|
||||
print("FIRE",topic, kwargs)
|
||||
|
||||
async def wait(futures):
|
||||
if(len(futures) > 0):
|
||||
await asyncio.wait(futures.values())
|
||||
|
|
|
@ -1,16 +1,15 @@
|
|||
import asyncio
|
||||
import logging
|
||||
import random
|
||||
|
||||
from aiohttp import web
|
||||
from cbpi.api import *
|
||||
|
||||
|
||||
class CustomSensor(CBPiSensor):
|
||||
|
||||
# Custom Properties which will can be configured by the user
|
||||
|
||||
p1 = Property.Number(label="Test")
|
||||
p2 = Property.Text(label="Test")
|
||||
interval = Property.Number(label="interval")
|
||||
interval = Property.Number(label="interval", configurable=True)
|
||||
|
||||
# Internal runtime variable
|
||||
value = 0
|
||||
|
@ -44,10 +43,90 @@ class CustomSensor(CBPiSensor):
|
|||
self.log_data(10)
|
||||
self.value = self.value + 1
|
||||
|
||||
await cbpi.bus.fire("sensor/%s" % self.id, value=self.value)
|
||||
await cbpi.bus.fire("sensor/%s/data" % self.id, value=self.value)
|
||||
|
||||
cache = {}
|
||||
|
||||
|
||||
class HTTPSensor(CBPiSensor):
|
||||
|
||||
# Custom Properties which will can be configured by the user
|
||||
|
||||
key = Property.Text(label="Key", configurable=True)
|
||||
|
||||
def init(self):
|
||||
super().init()
|
||||
self.state = True
|
||||
|
||||
def get_state(self):
|
||||
return self.state
|
||||
|
||||
def get_value(self):
|
||||
|
||||
return self.value
|
||||
|
||||
def stop(self):
|
||||
pass
|
||||
|
||||
async def run(self, cbpi):
|
||||
self.value = 0
|
||||
while True:
|
||||
await asyncio.sleep(1)
|
||||
|
||||
try:
|
||||
value = cache.pop(self.key, None)
|
||||
if value is not None:
|
||||
self.log_data(value)
|
||||
await cbpi.bus.fire("sensor/%s" % self.id, value=value)
|
||||
except:
|
||||
pass
|
||||
|
||||
class HTTPSensorEndpoint(CBPiExtension):
|
||||
|
||||
|
||||
def __init__(self, cbpi):
|
||||
'''
|
||||
Initializer
|
||||
|
||||
:param cbpi:
|
||||
'''
|
||||
|
||||
self.cbpi = cbpi
|
||||
# register component for http, events
|
||||
# In addtion the sub folder static is exposed to access static content via http
|
||||
self.cbpi.register(self, "/httpsensor")
|
||||
|
||||
|
||||
@request_mapping(path="/{key}/{value}", auth_required=False)
|
||||
async def http_new_value2(self, request):
|
||||
"""
|
||||
---
|
||||
description: Kettle Heater on
|
||||
tags:
|
||||
- HttpSensor
|
||||
parameters:
|
||||
- name: "key"
|
||||
in: "path"
|
||||
description: "Sensor Key"
|
||||
required: true
|
||||
type: "string"
|
||||
- name: "value"
|
||||
in: "path"
|
||||
description: "Value"
|
||||
required: true
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
responses:
|
||||
"204":
|
||||
description: successful operation
|
||||
"""
|
||||
print("HALLO")
|
||||
global cache
|
||||
key = request.match_info['key']
|
||||
value = request.match_info['value']
|
||||
cache[key] = value
|
||||
print(cache)
|
||||
return web.Response(status=204)
|
||||
|
||||
|
||||
def setup(cbpi):
|
||||
|
@ -59,5 +138,6 @@ def setup(cbpi):
|
|||
:param cbpi: the cbpi core
|
||||
:return:
|
||||
'''
|
||||
|
||||
cbpi.plugin.register("HTTPSensor", HTTPSensor)
|
||||
cbpi.plugin.register("HTTPSensorEndpoint", HTTPSensorEndpoint)
|
||||
cbpi.plugin.register("CustomSensor", CustomSensor)
|
||||
|
|
|
@ -33,18 +33,9 @@ class ActorHttpEndpoints(HttpCrudEndpoints):
|
|||
description: Switch actor on
|
||||
tags:
|
||||
- Actor
|
||||
parameters:
|
||||
- name: "id"
|
||||
in: "path"
|
||||
description: "Actor ID"
|
||||
required: true
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
responses:
|
||||
"204":
|
||||
description: successful operation
|
||||
"405":
|
||||
description: invalid HTTP Met
|
||||
"""
|
||||
return await super().http_get_all(request)
|
||||
|
||||
|
@ -74,7 +65,7 @@ class ActorHttpEndpoints(HttpCrudEndpoints):
|
|||
async def http_add(self, request):
|
||||
"""
|
||||
---
|
||||
description: Get one Actor
|
||||
description: add one Actor
|
||||
tags:
|
||||
- Actor
|
||||
parameters:
|
||||
|
|
|
@ -7,6 +7,146 @@ auth = False
|
|||
|
||||
|
||||
class KettleHttpEndpoints(HttpCrudEndpoints):
|
||||
@request_mapping(path="/types", auth_required=False)
|
||||
async def get_types(self, request):
|
||||
return await super().get_types(request)
|
||||
|
||||
@request_mapping(path="/", auth_required=False)
|
||||
async def http_get_all(self, request):
|
||||
"""
|
||||
---
|
||||
description: Get all kettles
|
||||
tags:
|
||||
- Kettle
|
||||
responses:
|
||||
"204":
|
||||
description: successful operation
|
||||
"""
|
||||
return await super().http_get_all(request)
|
||||
|
||||
@request_mapping(path="/{id:\d+}", auth_required=False)
|
||||
async def http_get_one(self, request):
|
||||
"""
|
||||
---
|
||||
description: Get Kettle by Id
|
||||
tags:
|
||||
- Kettle
|
||||
parameters:
|
||||
- name: "id"
|
||||
in: "path"
|
||||
description: "Actor ID"
|
||||
required: true
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
responses:
|
||||
"204":
|
||||
description: successful operation
|
||||
"""
|
||||
return await super().http_get_one(request)
|
||||
|
||||
@request_mapping(path="/", method="POST", auth_required=False)
|
||||
async def http_add(self, request):
|
||||
"""
|
||||
---
|
||||
description: add a kettle
|
||||
tags:
|
||||
- Kettle
|
||||
parameters:
|
||||
- in: body
|
||||
name: body
|
||||
description: Created an kettle
|
||||
required: false
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
sensor:
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
heater:
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
agitator:
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
target_temp:
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
logic:
|
||||
type: string
|
||||
config:
|
||||
type: object
|
||||
responses:
|
||||
"204":
|
||||
description: successful operation
|
||||
"""
|
||||
return await super().http_add(request)
|
||||
|
||||
@request_mapping(path="/{id}", method="PUT", auth_required=False)
|
||||
async def http_update(self, request):
|
||||
"""
|
||||
---
|
||||
description: Update a kettle
|
||||
tags:
|
||||
- Kettle
|
||||
parameters:
|
||||
- name: "id"
|
||||
in: "path"
|
||||
description: "Kettle ID"
|
||||
required: true
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
- in: body
|
||||
name: body
|
||||
description: Created an kettle
|
||||
required: false
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
sensor:
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
heater:
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
agitator:
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
target_temp:
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
logic:
|
||||
type: string
|
||||
config:
|
||||
type: object
|
||||
responses:
|
||||
"204":
|
||||
description: successful operation
|
||||
"""
|
||||
return await super().http_update(request)
|
||||
|
||||
@request_mapping(path="/{id}", method="DELETE", auth_required=False)
|
||||
async def http_delete_one(self, request):
|
||||
"""
|
||||
---
|
||||
description: Delete a kettle
|
||||
tags:
|
||||
- Kettle
|
||||
parameters:
|
||||
- name: "id"
|
||||
in: "path"
|
||||
description: "kettle ID"
|
||||
required: true
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
responses:
|
||||
"204":
|
||||
description: successful operation
|
||||
"""
|
||||
return await super().http_delete_one(request)
|
||||
|
||||
def __init__(self, cbpi):
|
||||
super().__init__(cbpi)
|
||||
|
@ -15,37 +155,149 @@ class KettleHttpEndpoints(HttpCrudEndpoints):
|
|||
|
||||
@request_mapping(path="/{id:\d+}/automatic", auth_required=False)
|
||||
async def http_automatic(self, request):
|
||||
"""
|
||||
---
|
||||
description: Toggle Automatic
|
||||
tags:
|
||||
- Kettle
|
||||
parameters:
|
||||
- name: "id"
|
||||
in: "path"
|
||||
description: "Kettle ID"
|
||||
required: true
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
responses:
|
||||
"204":
|
||||
description: successful operation
|
||||
"""
|
||||
await self.controller.toggle_automtic(int(request.match_info['id']))
|
||||
return web.Response(status=204)
|
||||
|
||||
@request_mapping(path="/{id:\d+}/heater/on", auth_required=False)
|
||||
async def http_heater_on(self, request):
|
||||
"""
|
||||
---
|
||||
description: Kettle Heater on
|
||||
tags:
|
||||
- Kettle
|
||||
parameters:
|
||||
- name: "id"
|
||||
in: "path"
|
||||
description: "Kettle ID"
|
||||
required: true
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
responses:
|
||||
"204":
|
||||
description: successful operation
|
||||
"""
|
||||
await self.controller.heater_on(int(request.match_info['id']))
|
||||
return web.Response(status=204)
|
||||
|
||||
@request_mapping(path="/{id:\d+}/heater/off", auth_required=False)
|
||||
async def http_heater_off(self, request):
|
||||
"""
|
||||
---
|
||||
description: Kettle Heater off
|
||||
tags:
|
||||
- Kettle
|
||||
parameters:
|
||||
- name: "id"
|
||||
in: "path"
|
||||
description: "Kettle ID"
|
||||
required: true
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
responses:
|
||||
"204":
|
||||
description: successful operation
|
||||
"""
|
||||
await self.controller.heater_off(int(request.match_info['id']))
|
||||
return web.Response(status=204)
|
||||
|
||||
@request_mapping(path="/{id:\d+}/agitator/on", auth_required=False)
|
||||
async def http_agitator_on(self, request):
|
||||
"""
|
||||
---
|
||||
description: Kettle Agitator on
|
||||
tags:
|
||||
- Kettle
|
||||
parameters:
|
||||
- name: "id"
|
||||
in: "path"
|
||||
description: "Kettle ID"
|
||||
required: true
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
responses:
|
||||
"204":
|
||||
description: successful operation
|
||||
"""
|
||||
await self.controller.agitator_on(int(request.match_info['id']))
|
||||
return web.Response(status=204)
|
||||
|
||||
@request_mapping(path="/{id:\d+}/agitator/off", auth_required=False)
|
||||
async def http_agitator_off(self, request):
|
||||
"""
|
||||
---
|
||||
description: Kettle Agitator off
|
||||
tags:
|
||||
- Kettle
|
||||
parameters:
|
||||
- name: "id"
|
||||
in: "path"
|
||||
description: "Kettle ID"
|
||||
required: true
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
responses:
|
||||
"204":
|
||||
description: successful operation
|
||||
"""
|
||||
await self.controller.agitator_off(int(request.match_info['id']))
|
||||
return web.Response(status=204)
|
||||
|
||||
@request_mapping(path="/{id:\d+}/targettemp", auth_required=False)
|
||||
async def http_taget_temp(self, request):
|
||||
"""
|
||||
---
|
||||
description: Get Target Temp of kettle
|
||||
tags:
|
||||
- Kettle
|
||||
parameters:
|
||||
- name: "id"
|
||||
in: "path"
|
||||
description: "Kettle ID"
|
||||
required: true
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
responses:
|
||||
"204":
|
||||
description: successful operation
|
||||
"""
|
||||
kettle_id = int(request.match_info['id'])
|
||||
temp = await self.controller.get_traget_temp(kettle_id)
|
||||
return web.json_response(data=dict(target_temp=temp, kettle_id=kettle_id))
|
||||
|
||||
@request_mapping(path="/{id:\d+}/temp", auth_required=False)
|
||||
async def http_temp(self, request):
|
||||
"""
|
||||
---
|
||||
description: Get Temp of kettle
|
||||
tags:
|
||||
- Kettle
|
||||
parameters:
|
||||
- name: "id"
|
||||
in: "path"
|
||||
description: "Kettle ID"
|
||||
required: true
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
responses:
|
||||
"204":
|
||||
description: successful operation
|
||||
"""
|
||||
kettle_id = int(request.match_info['id'])
|
||||
temp = await self.controller.get_temp(kettle_id)
|
||||
return web.json_response(data=dict(temp=temp, kettle_id=kettle_id))
|
||||
|
|
|
@ -12,7 +12,7 @@ class ComplexEncoder(JSONEncoder):
|
|||
try:
|
||||
|
||||
if isinstance(obj, ActorModel):
|
||||
data = dict(**obj.__dict__, state=obj.instance.get_state())
|
||||
data = dict(**obj.__dict__, state=obj.instance.get_state())
|
||||
del data["instance"]
|
||||
return data
|
||||
|
||||
|
@ -23,7 +23,7 @@ class ComplexEncoder(JSONEncoder):
|
|||
#elif callable(getattr(obj, "reprJSON")):
|
||||
# return obj.reprJSON()
|
||||
elif isinstance(obj, DBModel):
|
||||
return None
|
||||
return obj.__dict__
|
||||
#elif hasattr(obj, "callback"):
|
||||
# return obj()
|
||||
else:
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import logging
|
||||
import re
|
||||
import weakref
|
||||
from collections import defaultdict
|
||||
|
||||
|
@ -19,12 +20,28 @@ class CBPiWebSocket:
|
|||
self.cbpi.app.add_routes([web.get('/ws', self.websocket_handler)])
|
||||
self.cbpi.bus.register_object(self)
|
||||
|
||||
@on_event(topic="#")
|
||||
#if self.cbpi.config.static.get("ws_push_all", False):
|
||||
#self.cbpi.bus.register("#", self.listen)
|
||||
self.patters = {}
|
||||
#self.add_mapper("(actor)\/([\d])\/(on|toggle|off)\/(ok)$", self.map_actor)
|
||||
|
||||
def add_mapper(self, pattern, method):
|
||||
self.patters[re.compile(pattern)] = method
|
||||
|
||||
async def map_actor(self, regex_result, **kwargs):
|
||||
|
||||
actor_id = int(regex_result.group(2))
|
||||
return dict(topic="ACTOR_UPDATE", data=await self.cbpi.actor.get_one(actor_id))
|
||||
|
||||
|
||||
|
||||
async def listen(self, topic, **kwargs):
|
||||
|
||||
data = dict(topic=topic, data=dict(**kwargs))
|
||||
self.logger.debug("PUSH %s " % data)
|
||||
self.send(data)
|
||||
|
||||
|
||||
def send(self, data):
|
||||
self.logger.debug("broadcast to ws clients. Data: %s" % data)
|
||||
for ws in self._clients:
|
||||
|
|
|
@ -10,3 +10,5 @@ port: 8080
|
|||
username: cbpi
|
||||
password: 123
|
||||
|
||||
ws_push_all: true
|
||||
|
||||
|
|
BIN
craftbeerpi.db
BIN
craftbeerpi.db
Binary file not shown.
13
sample.py
Normal file
13
sample.py
Normal file
|
@ -0,0 +1,13 @@
|
|||
import re
|
||||
|
||||
pattern = "(actor)\/([\d])\/(on|toggle|off)$"
|
||||
|
||||
p = re.compile(pattern)
|
||||
result = p.match("actor/1/toggle")
|
||||
|
||||
print(result, result.group(3))
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in a new issue