| @@ -9,6 +9,11 @@ modules/plugins/* | |||
| !modules/plugins/__init__.py | |||
| *.pyc | |||
| *.js | |||
| *.css | |||
| modules/ui/package.json | |||
| modules/ui/.babelrc | |||
| yarn.lock | |||
| modules/ui/package-lock.json | |||
| @@ -21,7 +21,7 @@ class MashStep(StepBase): | |||
| def init(self): | |||
| ''' | |||
| Initialize Step. This method is called once at the beginning of the step | |||
| :return: | |||
| :return: | |||
| ''' | |||
| # set target tep | |||
| self.set_target_temp(self.temp, self.kettle) | |||
| @@ -31,7 +31,7 @@ class MashStep(StepBase): | |||
| ''' | |||
| Custom Action which can be execute form the brewing dashboard. | |||
| All method with decorator @cbpi.action("YOUR CUSTOM NAME") will be available in the user interface | |||
| :return: | |||
| :return: | |||
| ''' | |||
| if self.is_timer_finished() is None: | |||
| self.start_timer(int(self.timer) * 60) | |||
| @@ -46,7 +46,7 @@ class MashStep(StepBase): | |||
| def execute(self): | |||
| ''' | |||
| This method is execute in an interval | |||
| :return: | |||
| :return: | |||
| ''' | |||
| # Check if Target Temp is reached | |||
| @@ -57,6 +57,7 @@ class MashStep(StepBase): | |||
| # Check if timer finished and go to next step | |||
| if self.is_timer_finished() == True: | |||
| self.notify("Mash Step Completed!", "Starting the next step", timeout=None) | |||
| self.next() | |||
| @@ -77,7 +78,7 @@ class MashInStep(StepBase): | |||
| def init(self): | |||
| ''' | |||
| Initialize Step. This method is called once at the beginning of the step | |||
| :return: | |||
| :return: | |||
| ''' | |||
| # set target tep | |||
| self.s = False | |||
| @@ -88,7 +89,7 @@ class MashInStep(StepBase): | |||
| def execute(self): | |||
| ''' | |||
| This method is execute in an interval | |||
| :return: | |||
| :return: | |||
| ''' | |||
| # Check if Target Temp is reached | |||
| @@ -169,7 +170,7 @@ class BoilStep(StepBase): | |||
| def init(self): | |||
| ''' | |||
| Initialize Step. This method is called once at the beginning of the step | |||
| :return: | |||
| :return: | |||
| ''' | |||
| # set target tep | |||
| self.set_target_temp(self.temp, self.kettle) | |||
| @@ -182,7 +183,7 @@ class BoilStep(StepBase): | |||
| ''' | |||
| Custom Action which can be execute form the brewing dashboard. | |||
| All method with decorator @cbpi.action("YOUR CUSTOM NAME") will be available in the user interface | |||
| :return: | |||
| :return: | |||
| ''' | |||
| if self.is_timer_finished() is None: | |||
| self.start_timer(int(self.timer) * 60) | |||
| @@ -205,7 +206,7 @@ class BoilStep(StepBase): | |||
| def execute(self): | |||
| ''' | |||
| This method is execute in an interval | |||
| :return: | |||
| :return: | |||
| ''' | |||
| # Check if Target Temp is reached | |||
| if self.get_kettle_temp(self.kettle) >= float(self.temp): | |||
| @@ -218,4 +219,5 @@ class BoilStep(StepBase): | |||
| self.check_hop_timer(3, self.hop_3) | |||
| # Check if timer finished and go to next step | |||
| if self.is_timer_finished() == True: | |||
| self.notify("Boil Step Completed!", "Starting the next step", timeout=None) | |||
| self.next() | |||
| @@ -9,7 +9,7 @@ except Exception as e: | |||
| class Buzzer(object): | |||
| sound = ["H", 0.1, "L"] | |||
| sound = ["H", 0.1, "L", 0.1, "H", 0.1, "L", 0.1, "H", 0.1, "L"] | |||
| def __init__(self, gpio): | |||
| try: | |||
| cbpi.app.logger.info("INIT BUZZER NOW GPIO%s" % gpio) | |||
| @@ -74,6 +74,14 @@ class ControllerBase(object): | |||
| class KettleController(ControllerBase, ActorController, SensorController): | |||
| @staticmethod | |||
| def chart(kettle): | |||
| result = [] | |||
| result.append({"name": "Temp", "data_type": "sensor", "data_id": kettle.sensor}) | |||
| result.append({"name": "Target Temp", "data_type": "kettle", "data_id": kettle.id}) | |||
| return result | |||
| def __init__(self, *args, **kwds): | |||
| ControllerBase.__init__(self, *args, **kwds) | |||
| self.kettle_id = kwds.get("kettle_id") | |||
| @@ -107,6 +115,13 @@ class KettleController(ControllerBase, ActorController, SensorController): | |||
| class FermenterController(ControllerBase, ActorController, SensorController): | |||
| @staticmethod | |||
| def chart(fermenter): | |||
| result = [] | |||
| result.append({"name": "Temp", "data_type": "sensor", "data_id": fermenter.sensor}) | |||
| result.append({"name": "Target Temp", "data_type": "fermenter", "data_id": fermenter.id}) | |||
| return result | |||
| def __init__(self, *args, **kwds): | |||
| ControllerBase.__init__(self, *args, **kwds) | |||
| self.fermenter_id = kwds.get("fermenter_id") | |||
| @@ -65,6 +65,8 @@ class LogView(FlaskView): | |||
| pass | |||
| return array | |||
| def convert_chart_data_to_json(self, chart_data): | |||
| return {"name": chart_data["name"], "data": self.read_log_as_json(chart_data["data_type"], chart_data["data_id"])} | |||
| @route('/<t>/<int:id>', methods=["POST"]) | |||
| def get_logs_as_json(self, t, id): | |||
| @@ -76,13 +78,12 @@ class LogView(FlaskView): | |||
| if t == "k": | |||
| kettle = cbpi.cache.get("kettle").get(id) | |||
| result.append({"name": "Temp", "data": self.read_log_as_json("sensor", kettle.sensor)}) | |||
| result.append({"name": "Target Temp", "data": self.read_log_as_json("kettle", kettle.id)}) | |||
| result = map(self.convert_chart_data_to_json, cbpi.get_controller(kettle.logic).get("class").chart(kettle)) | |||
| if t == "f": | |||
| fermenter = cbpi.cache.get("fermenter").get(id) | |||
| result.append({"name": "Temp", "data": self.read_log_as_json("sensor", fermenter.sensor)}) | |||
| result.append({"name": "Target Temp", "data": self.read_log_as_json("fermenter", fermenter.id)}) | |||
| result = map(self.convert_chart_data_to_json, cbpi.get_fermentation_controller(fermenter.logic).get("class").chart(fermenter)) | |||
| return json.dumps(result) | |||
| @route('/download/<file>') | |||
| @@ -1,5 +1,6 @@ | |||
| from flask import Blueprint, render_template, request | |||
| from modules import cbpi | |||
| from flask import Blueprint | |||
| from modules import cbpi | |||
| react = Blueprint('react', __name__, template_folder='templates', static_folder='static') | |||
| @@ -1,6 +1,3 @@ | |||
| .App { | |||
| } | |||
| .container { | |||
| padding-right: 5px; | |||
| @@ -10,7 +7,27 @@ | |||
| } | |||
| .container-fluid { | |||
| padding-right: 5px; | |||
| padding-left: 5px; | |||
| padding-right: 5px; | |||
| padding-left: 5px; | |||
| } | |||
| .col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 { | |||
| position: relative; | |||
| min-height: 1px; | |||
| padding-right: 8px; | |||
| padding-left: 8px; | |||
| } | |||
| .panel-heading { | |||
| padding: 5px 5px; | |||
| } | |||
| .panel-footer { | |||
| padding: 2px 2px; | |||
| } | |||
| .modal-footer { | |||
| padding: 5px; | |||
| } | |||
| @@ -1,5 +1,5 @@ | |||
| body { | |||
| margin: 0; | |||
| padding: 0; | |||
| font-family: sans-serif; | |||
| margin: 0; | |||
| padding: 0; | |||
| font-family: sans-serif; | |||
| } | |||
| @@ -10,67 +10,12 @@ | |||
| <link rel="stylesheet" href="static/bootstrap.dark.css"> | |||
| <style> | |||
| .col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 { | |||
| position: relative; | |||
| min-height: 1px; | |||
| padding-right: 8px; | |||
| padding-left: 8px; | |||
| } | |||
| .panel-heading { | |||
| padding: 5px 5px; | |||
| } | |||
| .panel-footer { | |||
| padding: 2px 2px; | |||
| } | |||
| .modal-footer { | |||
| padding: 5px; | |||
| } | |||
| .row { | |||
| display: -webkit-box; | |||
| display: -webkit-flex; | |||
| display: -ms-flexbox; | |||
| display: flex !important; | |||
| flex-wrap: wrap; | |||
| } | |||
| .row > [class*='col-'] { | |||
| display: flex; | |||
| flex-direction: column; | |||
| } | |||
| /* Einschränken des sichtbaren Ausschnitts */ | |||
| </style> | |||
| <title>CraftBeerPi 3.0</title> | |||
| </head> | |||
| <body> | |||
| <div id="root" ></div> | |||
| <script src="static/bundle.js" type="text/javascript"></script> | |||
| <!-- | |||
| This HTML file is a template. | |||
| If you open it directly in the browser, you will see an empty page. | |||
| You can add webfonts, meta tags, or analytics to this file. | |||
| The build step will place the bundled scripts into the <body> tag. | |||
| To begin the development, run `npm start`. | |||
| To create a production bundle, use `npm run build`. | |||
| --> | |||
| </body> | |||
| </html> | |||
| @@ -1,6 +1,11 @@ | |||
| #!/usr/bin/env python | |||
| from modules import socketio, app | |||
| from modules import socketio, app, cbpi | |||
| socketio.run(app, host='0.0.0.0') | |||
| try: | |||
| port = int(cbpi.get_config_parameter('port', '5000')) | |||
| except ValueError: | |||
| port = 5000 | |||
| socketio.run(app, host='0.0.0.0', port=port) | |||
| @@ -0,0 +1 @@ | |||
| INSERT OR IGNORE INTO config VALUES ('port', 5000, 'number', 'Port to run server (requires restart)', NULL ); | |||