Added api path for recipe creation

- Added path parameter in config.json for settings
- If empty, 'upload' will be used per default as api path
- If something is entered, a different api path will be used for the creation of recipes.
-> this allows the standard usage of the recipe upload and selection via cbpi4, but adds the possibility that custom plugins can be written to create cbpi recipe flows from the uploaded files
*********************
+ some prep work to create the http endpoints
This commit is contained in:
avollkopf 2021-05-30 11:58:18 +02:00
parent 40020ba64d
commit b3d87bc027
7 changed files with 169 additions and 7 deletions

View file

@ -20,6 +20,13 @@
"type": "kettle",
"value": ""
},
"RECIPE_CREATION_PATH": {
"description": "API path to creation plugin. Default: empty",
"name": "RECIPE_CREATION_PATH",
"options": null,
"type": "string",
"value": ""
},
"TEMP_UNIT": {
"description": "Temperature Unit",
"name": "TEMP_UNIT",

View file

@ -46,6 +46,7 @@ from cbpi.http_endpoints.http_plugin import PluginHttpEndpoints
from cbpi.http_endpoints.http_system import SystemHttpEndpoints
from cbpi.http_endpoints.http_log import LogHttpEndpoints
from cbpi.http_endpoints.http_notification import NotificationHttpEndpoints
from cbpi.http_endpoints.http_upload import UploadHttpEndpoints
import shortuuid
logger = logging.getLogger(__name__)
@ -123,6 +124,8 @@ class CraftBeerPi:
self.http_system = SystemHttpEndpoints(self)
self.http_log = LogHttpEndpoints(self)
self.http_notification = NotificationHttpEndpoints(self)
self.http_upload = UploadHttpEndpoints(self)
self.login = Login(self)
@ -219,7 +222,6 @@ class CraftBeerPi:
contact="info@craftbeerpi.com")
def notify(self, title: str, message: str, type: NotificationType = NotificationType.INFO, action=[]) -> None:
self.notification.notify(title, message, type, action)

View file

@ -57,6 +57,12 @@ class RecipeUpload(CBPiExtension):
def allowed_file(self, filename, extension):
return '.' in filename and filename.rsplit('.', 1)[1] in set([extension])
def get_creation_path(self):
creation_path = self.cbpi.config.get("RECIPE_CREATION_PATH", "upload")
path = {'path': 'upload'} if creation_path == '' else {'path': creation_path}
return path
@request_mapping(path='/', method="POST", auth_required=False)
async def RecipeUpload(self, request):
data = await request.post()
@ -123,6 +129,21 @@ class RecipeUpload(CBPiExtension):
await self.xml_recipe_creation(xml_id['id'])
return web.Response(status=200)
@request_mapping(path="/getpath", auth_required=False)
async def http_getpath(self, request):
"""
---
description: get path for recipe creation
tags:
- Upload
responses:
"200":
description: successful operation
"""
return web.json_response(data=self.get_creation_path())
async def kbh_recipe_creation(self, Recipe_ID):
self.kettle = None

View file

@ -15,9 +15,11 @@ from typing import KeysView
from cbpi.api.config import ConfigType
from cbpi.api.base import CBPiBase
import numpy as np
#import scipy.optimize
import warnings
@parameters([Property.Text(label="Notification",configurable = True, description = "Text for notification"),
Property.Select(label="AutoNext",options=["Yes","No"], description="Automatically move to next step (Yes) or pause after Notification (No)")])
class NotificationStep(CBPiStep):
@ -412,7 +414,7 @@ class CooldownStep(CBPiStep):
self.kettle = self.get_kettle(self.props.get("Kettle", None))
self.actor = self.props.get("Actor", None)
self.target_temp = int(self.props.get("Temp",0))
self.Interval = 10 # Interval in minutes on how often cooldwon end time is calculated
self.Interval = 15 # Interval in minutes on how often cooldwon end time is calculated
self.cbpi.notify(self.name, 'Cool down to {}°'.format(self.target_temp), NotificationType.INFO)
if self.timer is None:
@ -422,6 +424,7 @@ class CooldownStep(CBPiStep):
self.time_array.append(time.time())
self.next_check = self.start_time + self.Interval * 60
self.count = 0
self.initial_date = None
async def on_stop(self):
await self.timer.stop()
@ -441,13 +444,17 @@ class CooldownStep(CBPiStep):
await self.push_update()
while self.running == True:
current_temp = self.get_sensor_value(self.props.get("Sensor", None)).get("value")
if self.count == 19:
if self.count == 10:
self.temp_array.append(current_temp)
self.time_array.append(time.time())
current_time = time.time()
if self.initial_date == None:
self.initial_date = current_time
self.time_array.append(current_time)
self.count = 0
if time.time() >= self.next_check:
self.next_check = time.time() + (self.Interval * 60)
cooldown_model = np.poly1d(np.polyfit(self.temp_array, self.time_array, 4))
cooldown_model = np.poly1d(np.polyfit(self.temp_array, self.time_array, 2))
target_time=cooldown_model(self.target_temp)
target_timestring= datetime.fromtimestamp(target_time)
self.summary="ECT: {}".format(target_timestring.strftime("%H:%M"))

View file

@ -289,4 +289,3 @@ class StepHttpEndpoints():

View file

@ -0,0 +1,125 @@
#from cbpi.controller.recipe_controller import RecipeController
from cbpi.api.dataclasses import Props, Step
from aiohttp import web
from cbpi.api import *
class UploadHttpEndpoints():
def __init__(self, cbpi):
self.cbpi = cbpi
# self.controller : RecipeController = cbpi.recipe
self.cbpi.register(self, "/fileupload")
@request_mapping(path='/', method="POST", auth_required=False)
async def RecipeUpload(self, request):
"""
---
description: Upload XML file or database from KBH V2
tags:
- FileUpload
requestBody:
content:
multipart/form-data:
schema:
type: object
properties:
orderId:
type: integer
userId:
type: integer
fileName:
type: string
format: binary
responses:
"200":
description: successful operation
"""
data = await request.post()
fileData = data['File']
logging.info(fileData)
@request_mapping(path='/kbh', method="GET", auth_required=False)
async def get_kbh_list(self, request):
"""
---
description: Get Recipe list from Kleiner Brauhelfer
tags:
- FileUpload
responses:
"200":
description: successful operation
"""
kbh_list = await get_kbh_recipes()
return web.json_response(kbh_list)
@request_mapping(path='/kbh', method="POST", auth_required=False)
async def create_kbh_recipe(self, request):
"""
---
description: Create Recipe from KBH database with selected ID
tags:
- FileUpload
responses:
"200":
description: successful operation
"""
kbh_id = await request.json()
await self.kbh_recipe_creation(kbh_id['id'])
return web.Response(status=200)
@request_mapping(path='/xml', method="GET", auth_required=False)
async def get_xml_list(self, request):
"""
---
description: Get recipe list from xml file
tags:
- FileUpload
responses:
"200":
description: successful operation
"""
xml_list = await get_xml_recipes()
return web.json_response(xml_list)
@request_mapping(path='/xml', method="POST", auth_required=False)
async def create_xml_recipe(self, request):
"""
---
description: Create recipe from xml file with selected id
tags:
- FileUpload
responses:
"200":
description: successful operation
"""
xml_id = await request.json()
await self.xml_recipe_creation(xml_id['id'])
return web.Response(status=200)
@request_mapping(path="/getpath", auth_required=False)
async def http_getpath(self, request):
"""
---
description: get path for recipe creation
tags:
- FileUpload
responses:
"200":
description: successful operation
"""
return web.json_response(data=self.get_creation_path())

View file

@ -34,6 +34,7 @@ setup(name='cbpi',
'shortuuid==1.0.1',
'tabulate==0.8.7',
'asyncio-mqtt',
'scipy',
'cbpi4ui',
'RPi.GPIO; sys_platform == "linux"'
],