Skip to content

Commit

Permalink
Merge pull request #143 from PiBrewing/development
Browse files Browse the repository at this point in the history
Development
  • Loading branch information
avollkopf authored Jul 13, 2024
2 parents edbd231 + 90289ef commit 8b42600
Show file tree
Hide file tree
Showing 11 changed files with 296 additions and 50 deletions.
2 changes: 1 addition & 1 deletion cbpi/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
__version__ = "4.4.1.rc1"
__version__ = "4.4.3"
__codename__ = "Yeast Starter"

8 changes: 7 additions & 1 deletion cbpi/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@
from zipfile import ZipFile
from cbpi.craftbeerpi import CraftBeerPi
import os
try:
import pwd
module_pwd=True
except:
module_pwd=False
import pkgutil
import shutil
import click
Expand Down Expand Up @@ -165,7 +170,8 @@ def autostart(self, name):
else:
print("CraftBeerPi Autostart is {}OFF{}".format(Fore.RED,Style.RESET_ALL))
elif(name == "on"):
user=os.getlogin()
#user=os.getlogin()
user=pwd.getpwuid(os.getuid()).pw_name
path="/usr/local/bin/cbpi"
if os.path.exists("/home/"+user+"/.local/bin/cbpi") is True:
path="/home/"+user+"/.local/bin/cbpi"
Expand Down
1 change: 1 addition & 0 deletions cbpi/config/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ mqtt_host: localhost
mqtt_port: 1883
mqtt_username: ""
mqtt_password: ""
mqtt_offset: false

username: cbpi
password: 123
Expand Down
106 changes: 81 additions & 25 deletions cbpi/controller/upload_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,12 @@
from os import listdir
from os.path import isfile, join
import json
import shortuuid
import math
import yaml
from ..api.step import StepMove, StepResult, StepState
import re
import base64


class UploadController:

def __init__(self, cbpi):
Expand Down Expand Up @@ -70,9 +69,12 @@ async def get_json_recipes(self):
return []

async def get_brewfather_recipes(self,offset=0):
limit = 50
length = self.cbpi.config.get('brewfather_list_length',50)
repeat = True
brewfather = True
result=[]
self.url="https://api.brewfather.app/v1/recipes"
self.url="https://api.brewfather.app/v2/recipes"
brewfather_user_id = self.cbpi.config.get("brewfather_user_id", None)
if brewfather_user_id == "" or brewfather_user_id is None:
brewfather = False
Expand All @@ -84,25 +86,63 @@ async def get_brewfather_recipes(self,offset=0):
if brewfather == True:
encodedData = base64.b64encode(bytes(f"{brewfather_user_id}:{brewfather_api_key}", "ISO-8859-1")).decode("ascii")
headers={"Authorization": "Basic %s" % encodedData}
parameters={"limit": 50, 'offset': offset}
async with aiohttp.ClientSession(headers=headers) as bf_session:
async with bf_session.get(self.url, params=parameters) as r:
bf_recipe_list = await r.json()
await bf_session.close()

if bf_recipe_list:
for row in bf_recipe_list:
recipe_id = row['_id']
name = row['name']
element = {'value': recipe_id, 'label': name}
result.append(element)
return result
else:
return []

else:
return []

parameters={"limit": limit}
while repeat == True:
try:
async with aiohttp.ClientSession(headers=headers) as bf_session:
async with bf_session.get(self.url, params=parameters) as r:
if r.status == 429:
try:
seconds=int(r.headers['Retry-After'])
minutes=round(seconds/60)
except:
seconds=None
if not seconds:
logging.error("Too many requests to BF api. Try again later")
self.cbpi.notify("Error", "Too many requests to BF api. Try again later", NotificationType.ERROR)
else:
logging.error(f"Too many requests to BF api. Try in {minutes} minutes again.")
self.cbpi.notify("Error", f"Too many requests to BF api. Try in {minutes} minutes again.", NotificationType.ERROR)
repeat = False
logging.error(r.headers['Retry-After'])
else:
bf_recipe_list = await r.json()
await bf_session.close()
except Exception as e:
logging.error(e)
repeat = False
try:
if bf_recipe_list:
for row in bf_recipe_list:
recipe_id = row['_id']
name = row['name']
element = {'value': recipe_id, 'label': name}
result.append(element)
else:
repeat = False
except Exception as e:
logging.error(e)
try:
if len(bf_recipe_list) != limit:
repeat = False
else:
parameters={"limit": limit, 'start_after': recipe_id}
except Exception as e:
logging.error(e)

try:
newlist = sorted(result, key=lambda d: d['label'])
listlength=len(newlist)
max=math.floor(listlength/length)
sortlist=[]
for i in range(0 , max+1):
sortlist.append({ 'value': i*length, 'label': i*length })
return newlist, sortlist, length
except:
logging.error("Return empty BF recipe list")
sortlist=[{ 'value': 0, 'label': '0' }]
return result, sortlist, length


def get_creation_path(self):
creation_path = self.cbpi.config.get("RECIPE_CREATION_PATH", "upload")
Expand Down Expand Up @@ -738,7 +778,7 @@ async def bf_recipe_creation(self, Recipe_ID):

brewfather = True
result=[]
self.bf_url="https://api.brewfather.app/v1/recipes/" + Recipe_ID
self.bf_url="https://api.brewfather.app/v2/recipes/" + Recipe_ID
brewfather_user_id = self.cbpi.config.get("brewfather_user_id", None)
if brewfather_user_id == "" or brewfather_user_id is None:
brewfather = False
Expand Down Expand Up @@ -775,6 +815,21 @@ async def bf_recipe_creation(self, Recipe_ID):
except:
miscs = None

try:
fermentation_steps=bf_recipe['fermentation']['steps']
except:
fermentation_steps=None

if fermentation_steps is not None:
try:
step=fermentation_steps[0]
self.fermentation_step_temp=int(step['stepTemp'])
except:
self.fermentation_step_temp=None

if self.fermentation_step_temp is not None and self.TEMP_UNIT != "C":
self.fermentation_step_temp = round((9.0 / 5.0 * float(self.fermentation_step_temp)+ 32))

FirstWort = self.getFirstWort(hops, "bf")

await self.create_recipe(RecipeName)
Expand Down Expand Up @@ -1012,8 +1067,9 @@ async def create_Whirlpool_Cooldown(self, time : str = "15"):
cooldown_sensor = self.cbpi.config.get("steps_cooldown_sensor", None)
if cooldown_sensor is None or cooldown_sensor == '':
cooldown_sensor = self.boilkettle.sensor # fall back to boilkettle sensor if no other sensor is specified
step_timer = ""
step_temp = int(self.CoolDownTemp)
step_timer = ""

step_temp = int(self.CoolDownTemp) if (self.fermentation_step_temp is None or self.fermentation_step_temp <= int(self.CoolDownTemp)) else self.fermentation_step_temp
step_string = { "name": "Cooldown",
"props": {
"Kettle": self.boilid,
Expand Down
36 changes: 34 additions & 2 deletions cbpi/extension/ConfigUpdate/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from cbpi.api import *
from cbpi.api.config import ConfigType
from cbpi.api.base import CBPiBase
import glob
import glob, yaml
from cbpi import __version__

logger = logging.getLogger(__name__)
Expand All @@ -19,6 +19,12 @@ def __init__(self,cbpi):
self.cbpi = cbpi
self._task = asyncio.create_task(self.run())

def append_to_yaml(self, file_path, data_to_append):

with open(file_path[0], 'a+') as file:
file.seek(0)
yaml.dump(data_to_append, file, default_flow_style=False)


async def run(self):
logging.info("Check Config for required changes")
Expand Down Expand Up @@ -61,12 +67,13 @@ async def run(self):
AddMashIn = self.cbpi.config.get("AddMashInStep", None)
bfuserid = self.cbpi.config.get("brewfather_user_id", None)
bfapikey = self.cbpi.config.get("brewfather_api_key", None)
bflistlength = self.cbpi.config.get("brewfather_list_length", None)
RecipeCreationPath = self.cbpi.config.get("RECIPE_CREATION_PATH", None)
BoilKettle = self.cbpi.config.get("BoilKettle", None)
CONFIG_STATUS = self.cbpi.config.get("CONFIG_STATUS", None)
self.version=__version__
current_grid = self.cbpi.config.get("current_grid", None)

mqtt_offset=self.cbpi.static_config.get("mqtt_offset", None)

if boil_temp is None:
logger.info("INIT Boil Temp Setting")
Expand Down Expand Up @@ -244,6 +251,21 @@ async def run(self):
await self.cbpi.config.add("brewfather_api_key", "", type=ConfigType.STRING, description="Brewfather API Key", source="craftbeerpi")
except:
logger.warning('Unable to update config')

## Check if Brewfather API Key is in config

if bflistlength is None:
logger.info("INIT Brewfather Recipe List Length")
try:
await self.cbpi.config.add("brewfather_list_length", 50, type=ConfigType.SELECT, description="Brewfather Recipe List length",
source="craftbeerpi",
options= [{"label": "5", "value": 5},
{"label": "10", "value": 10},
{"label": "25", "value": 25},
{"label": "50", "value": 50},
{"label": "100", "value": 100}])
except:
logger.warning('Unable to update config')

## Check if Brewfather API Key is in config

Expand Down Expand Up @@ -542,6 +564,16 @@ async def run(self):
except Exception as e:
logging.error(e)

if mqtt_offset is None:
logging.info("INIT MQTT Offset in static config")
try:
static_config_file=glob.glob(self.cbpi.config_folder.get_file_path('config.yaml'))
data_to_append = {'mqtt_offset': False}
self.append_to_yaml(static_config_file, data_to_append)
pass
except Exception as e:
logging.error(e)
logging.warning('Unable to update database')

## Check if influxdbname is in config
if CONFIG_STATUS is None or CONFIG_STATUS != self.version:
Expand Down
2 changes: 1 addition & 1 deletion cbpi/extension/mashstep/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -536,7 +536,7 @@ async def run(self):
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, 2))
cooldown_model = np.polynomial.polynomial.Polynomial.fit(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"))
Expand Down
Loading

0 comments on commit 8b42600

Please sign in to comment.