diff --git a/cbpi/config/config.json b/cbpi/config/config.json index f686bbc..26399a7 100644 --- a/cbpi/config/config.json +++ b/cbpi/config/config.json @@ -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", diff --git a/cbpi/craftbeerpi.py b/cbpi/craftbeerpi.py index 8166aff..c23ffa8 100644 --- a/cbpi/craftbeerpi.py +++ b/cbpi/craftbeerpi.py @@ -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) diff --git a/cbpi/extension/RecipeUpload/__init__.py b/cbpi/extension/RecipeUpload/__init__.py index eb51295..beca115 100644 --- a/cbpi/extension/RecipeUpload/__init__.py +++ b/cbpi/extension/RecipeUpload/__init__.py @@ -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 diff --git a/cbpi/extension/mashstep/__init__.py b/cbpi/extension/mashstep/__init__.py index 4bf04d1..dac9a8d 100644 --- a/cbpi/extension/mashstep/__init__.py +++ b/cbpi/extension/mashstep/__init__.py @@ -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")) diff --git a/cbpi/http_endpoints/http_step.py b/cbpi/http_endpoints/http_step.py index c499d36..d7b2242 100644 --- a/cbpi/http_endpoints/http_step.py +++ b/cbpi/http_endpoints/http_step.py @@ -286,7 +286,6 @@ class StepHttpEndpoints(): await self.controller.savetobook() return web.Response(status=204) - diff --git a/cbpi/http_endpoints/http_upload.py b/cbpi/http_endpoints/http_upload.py new file mode 100644 index 0000000..07a94ae --- /dev/null +++ b/cbpi/http_endpoints/http_upload.py @@ -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()) + diff --git a/setup.py b/setup.py index a5dd517..72b9a28 100644 --- a/setup.py +++ b/setup.py @@ -34,6 +34,7 @@ setup(name='cbpi', 'shortuuid==1.0.1', 'tabulate==0.8.7', 'asyncio-mqtt', + 'scipy', 'cbpi4ui', 'RPi.GPIO; sys_platform == "linux"' ], @@ -46,4 +47,4 @@ setup(name='cbpi', "cbpi=cbpi.cli:main", ] } -) \ No newline at end of file +)