mirror of
https://github.com/PiBrewing/craftbeerpi4.git
synced 2024-11-28 17:54:15 +01:00
Update upload_controller.py
merge of rutines for upload / recipe creation
This commit is contained in:
parent
cd21688563
commit
b6a430ada1
1 changed files with 355 additions and 450 deletions
|
@ -104,7 +104,6 @@ class UploadController:
|
||||||
|
|
||||||
async def FileUpload(self, data):
|
async def FileUpload(self, data):
|
||||||
fileData = data['File']
|
fileData = data['File']
|
||||||
logging.info(fileData)
|
|
||||||
filename = fileData.filename
|
filename = fileData.filename
|
||||||
recipe_file = fileData.file
|
recipe_file = fileData.file
|
||||||
content_type = fileData.content_type
|
content_type = fileData.content_type
|
||||||
|
@ -141,260 +140,159 @@ class UploadController:
|
||||||
self.cbpi.notify("Error", "Wrong content type. Upload failed", NotificationType.ERROR)
|
self.cbpi.notify("Error", "Wrong content type. Upload failed", NotificationType.ERROR)
|
||||||
|
|
||||||
async def kbh_recipe_creation(self, Recipe_ID):
|
async def kbh_recipe_creation(self, Recipe_ID):
|
||||||
self.kettle = None
|
config = self.get_config_values()
|
||||||
|
if self.kettle is not None:
|
||||||
#Define MashSteps
|
|
||||||
self.mashin = self.cbpi.config.get("steps_mashin", "MashInStep")
|
|
||||||
self.mash = self.cbpi.config.get("steps_mash", "MashStep")
|
|
||||||
self.mashout = self.cbpi.config.get("steps_mashout", None) # Currently used only for the Braumeister
|
|
||||||
self.boil = self.cbpi.config.get("steps_boil", "BoilStep")
|
|
||||||
self.whirlpool="Waitstep"
|
|
||||||
self.cooldown = self.cbpi.config.get("steps_cooldown", "WaitStep")
|
|
||||||
|
|
||||||
#get default boil temp from settings
|
|
||||||
self.BoilTemp = self.cbpi.config.get("steps_boil_temp", 98)
|
|
||||||
|
|
||||||
#get default cooldown temp alarm setting
|
|
||||||
self.CoolDownTemp = self.cbpi.config.get("steps_cooldown_temp", 25)
|
|
||||||
|
|
||||||
#get server port from settings and define url for api calls -> adding steps
|
|
||||||
self.port = str(self.cbpi.static_config.get('port',8000))
|
|
||||||
self.url="http://127.0.0.1:" + self.port + "/step2/"
|
|
||||||
|
|
||||||
|
|
||||||
# get default Kettle from Settings
|
|
||||||
self.id = self.cbpi.config.get('MASH_TUN', None)
|
|
||||||
try:
|
|
||||||
self.kettle = self.cbpi.kettle.find_by_id(self.id)
|
|
||||||
except:
|
|
||||||
self.cbpi.notify('Recipe Upload', 'No default Kettle defined. Please specify default Kettle in settings', NotificationType.ERROR)
|
|
||||||
if self.id is not None or self.id != '':
|
|
||||||
# load beerxml file located in upload folder
|
# load beerxml file located in upload folder
|
||||||
self.path = os.path.join(".", 'config', "upload", "kbh.db")
|
self.path = os.path.join(".", 'config', "upload", "kbh.db")
|
||||||
if os.path.exists(self.path) is False:
|
if os.path.exists(self.path) is False:
|
||||||
self.cbpi.notify("File Not Found", "Please upload a kbh V2 databsel file", NotificationType.ERROR)
|
self.cbpi.notify("File Not Found", "Please upload a kbh V2 databsel file", NotificationType.ERROR)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
# Get Recipe Nmae
|
||||||
conn = sqlite3.connect(self.path)
|
conn = sqlite3.connect(self.path)
|
||||||
c = conn.cursor()
|
c = conn.cursor()
|
||||||
c.execute('SELECT Sudname FROM Sud WHERE ID = ?', (Recipe_ID,))
|
c.execute('SELECT Sudname FROM Sud WHERE ID = ?', (Recipe_ID,))
|
||||||
row = c.fetchone()
|
row = c.fetchone()
|
||||||
name = row[0]
|
name = row[0]
|
||||||
|
|
||||||
# Create recipe in recipe Book with name of first recipe in xml file
|
# get MashIn Temp
|
||||||
self.recipeID = await self.cbpi.recipe.create(name)
|
mashin_temp = None
|
||||||
|
|
||||||
# send recipe to mash profile
|
|
||||||
await self.cbpi.recipe.brew(self.recipeID)
|
|
||||||
|
|
||||||
# remove empty recipe from recipe book
|
|
||||||
await self.cbpi.recipe.remove(self.recipeID)
|
|
||||||
|
|
||||||
#MashIn Step
|
|
||||||
c.execute('SELECT Temp FROM Rasten WHERE Typ = 0 AND SudID = ?', (Recipe_ID,))
|
c.execute('SELECT Temp FROM Rasten WHERE Typ = 0 AND SudID = ?', (Recipe_ID,))
|
||||||
row = c.fetchone()
|
row = c.fetchone()
|
||||||
|
try:
|
||||||
|
if self.cbpi.config.get("TEMP_UNIT", "C") == "C":
|
||||||
|
mashin_temp = str(int(row[0]))
|
||||||
|
else:
|
||||||
|
mashin_temp = str(round(9.0 / 5.0 * int(row[0]) + 32))
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
step_kettle = self.id
|
# get the hop addition times
|
||||||
step_name = "MashIn"
|
c.execute('SELECT Zeit FROM Hopfengaben WHERE Vorderwuerze = 0 AND SudID = ?', (Recipe_ID,))
|
||||||
step_timer = "0"
|
hops = c.fetchall()
|
||||||
step_temp = str(int(row[0]))
|
|
||||||
sensor = self.kettle.sensor
|
|
||||||
step_type = self.mashin if self.mashin != "" else "MashInStep"
|
|
||||||
AutoMode = "Yes" if step_type == "MashInStep" else "No"
|
|
||||||
Notification = "Target temperature reached. Please add malt."
|
|
||||||
await self.create_step(step_type, step_name, step_kettle, step_timer, step_temp, AutoMode, sensor, Notification)
|
|
||||||
|
|
||||||
for row in c.execute('SELECT Name, Temp, Dauer FROM Rasten WHERE Typ <> 0 AND SudID = ?', (Recipe_ID,)):
|
# get the misc addition times
|
||||||
step_name = str(row[0])
|
c.execute('SELECT Zugabedauer FROM WeitereZutatenGaben WHERE Zeitpunkt = 1 AND SudID = ?', (Recipe_ID,))
|
||||||
step_temp = str(int(row[1]))
|
miscs = c.fetchall()
|
||||||
step_timer = str(int(row[2]))
|
|
||||||
step_type = self.mash if self.mash != "" else "MashStep"
|
|
||||||
AutoMode = "Yes" if step_type == "MashStep" else "No"
|
|
||||||
await self.create_step(step_type, step_name, step_kettle, step_timer, step_temp, AutoMode, sensor)
|
|
||||||
|
|
||||||
# MashOut -> Notification step that sends notification and waits for user input to move to next step (AutoNext=No)
|
|
||||||
if self.mashout == "NotificationStep":
|
|
||||||
step_kettle = self.id
|
|
||||||
step_type = self.mashout
|
|
||||||
step_name = "Lautering"
|
|
||||||
step_timer = ""
|
|
||||||
step_temp = ""
|
|
||||||
AutoMode = ""
|
|
||||||
sensor = ""
|
|
||||||
Notification = "Mash Process completed. Please start lautering and press next to start boil."
|
|
||||||
AutoNext = "No"
|
|
||||||
await self.create_step(step_type, step_name, step_kettle, step_timer, step_temp, AutoMode, sensor, Notification, AutoNext)
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
c.execute('SELECT Zeit FROM Hopfengaben WHERE Vorderwuerze = 1 AND SudID = ?', (Recipe_ID,))
|
||||||
|
FW_Hops = c.fetchall()
|
||||||
|
FirstWort = self.getFirstWort(FW_Hops,"kbh")
|
||||||
|
except:
|
||||||
|
FirstWort = "No"
|
||||||
|
|
||||||
c.execute('SELECT Kochdauer FROM Sud WHERE ID = ?', (Recipe_ID,))
|
c.execute('SELECT Kochdauer FROM Sud WHERE ID = ?', (Recipe_ID,))
|
||||||
row = c.fetchone()
|
row = c.fetchone()
|
||||||
step_time = str(int(row[0]))
|
BoilTime = str(int(row[0]))
|
||||||
|
|
||||||
logging.info("Boil Time: {}".format(step_time))
|
|
||||||
|
|
||||||
FirstWortFlag = self.getFirstWortKBH(Recipe_ID)
|
|
||||||
|
|
||||||
logging.info(FirstWortFlag)
|
await self.create_recipe(name)
|
||||||
|
|
||||||
BoilTimeAlerts = self.getBoilAlertsKBH(Recipe_ID)
|
if mashin_temp is not None:
|
||||||
|
step_type = self.mashin if self.mashin != "" else "MashInStep"
|
||||||
|
step_string = { "name": "MashIn",
|
||||||
|
"props": {
|
||||||
|
"AutoMode": "Yes" if step_type == "MashInStep" else "No",
|
||||||
|
"Kettle": self.id,
|
||||||
|
"Sensor": self.kettle.sensor,
|
||||||
|
"Temp": mashin_temp,
|
||||||
|
"Timer": "0",
|
||||||
|
"Notification": "Target temperature reached. Please add malt."
|
||||||
|
},
|
||||||
|
"status_text": "",
|
||||||
|
"status": "I",
|
||||||
|
"type": step_type
|
||||||
|
}
|
||||||
|
await self.create_step(step_string)
|
||||||
|
|
||||||
logging.info(BoilTimeAlerts)
|
for row in c.execute('SELECT Name, Temp, Dauer FROM Rasten WHERE Typ <> 0 AND SudID = ?', (Recipe_ID,)):
|
||||||
|
step_type = self.mash if self.mash != "" else "MashStep"
|
||||||
|
step_string = { "name": str(row[0]),
|
||||||
|
"props": {
|
||||||
|
"AutoMode": "Yes" if step_type == "MashStep" else "No",
|
||||||
|
"Kettle": self.id,
|
||||||
|
"Sensor": self.kettle.sensor,
|
||||||
|
"Temp": str(int(row[1])) if self.TEMP_UNIT == "C" else str(round(9.0 / 5.0 * int(row[1]) + 32)),
|
||||||
|
"Timer": str(int(row[2]))
|
||||||
|
},
|
||||||
|
"status_text": "",
|
||||||
|
"status": "I",
|
||||||
|
"type": step_type
|
||||||
|
}
|
||||||
|
await self.create_step(step_string)
|
||||||
|
|
||||||
step_kettle = self.id
|
# MashOut -> Notification step that sends notification and waits for user input to move to next step (AutoNext=No)
|
||||||
|
if self.mashout == "NotificationStep":
|
||||||
|
step_string = { "name": "Lautering",
|
||||||
|
"props": {
|
||||||
|
"AutoNext": "No",
|
||||||
|
"Kettle": self.id,
|
||||||
|
"Notification": "Mash Process completed. Please start lautering and press next to start boil."
|
||||||
|
|
||||||
|
},
|
||||||
|
"status_text": "",
|
||||||
|
"status": "I",
|
||||||
|
"type": self.mashout
|
||||||
|
}
|
||||||
|
await self.create_step(step_string)
|
||||||
|
|
||||||
|
|
||||||
|
Hops = self.getBoilAlerts(hops, miscs, "kbh")
|
||||||
step_type = self.boil if self.boil != "" else "BoilStep"
|
step_type = self.boil if self.boil != "" else "BoilStep"
|
||||||
step_name = "Boil Step"
|
step_string = { "name": "Boil Step",
|
||||||
step_temp = int(self.BoilTemp)
|
"props": {
|
||||||
AutoMode = "Yes" if step_type == "BoilStep" else "No"
|
"AutoMode": "Yes" if step_type == "BoilStep" else "No",
|
||||||
sensor = self.kettle.sensor
|
"Kettle": self.id,
|
||||||
Notification = ""
|
"Sensor": self.kettle.sensor,
|
||||||
AutoNext = ""
|
"Temp": int(self.BoilTemp),
|
||||||
LidAlert = "Yes"
|
"Timer": BoilTime,
|
||||||
FirstWort = 'Yes' if FirstWortFlag == True else 'No'
|
"First_Wort": FirstWort,
|
||||||
Hop1 = str(int(BoilTimeAlerts[0])) if len(BoilTimeAlerts) >= 1 else None
|
"LidAlert": "Yes",
|
||||||
Hop2 = str(int(BoilTimeAlerts[1])) if len(BoilTimeAlerts) >= 2 else None
|
"Hop_1": Hops[0],
|
||||||
Hop3 = str(int(BoilTimeAlerts[2])) if len(BoilTimeAlerts) >= 3 else None
|
"Hop_2": Hops[1],
|
||||||
Hop4 = str(int(BoilTimeAlerts[3])) if len(BoilTimeAlerts) >= 4 else None
|
"Hop_3": Hops[2],
|
||||||
Hop5 = str(int(BoilTimeAlerts[4])) if len(BoilTimeAlerts) >= 5 else None
|
"Hop_4": Hops[3],
|
||||||
Hop6 = str(int(BoilTimeAlerts[5])) if len(BoilTimeAlerts) >= 6 else None
|
"Hop_5": Hops[4],
|
||||||
|
"Hop_6": Hops[5]
|
||||||
|
},
|
||||||
|
"status_text": "",
|
||||||
|
"status": "I",
|
||||||
|
"type": step_type
|
||||||
|
}
|
||||||
|
|
||||||
|
await self.create_step(step_string)
|
||||||
|
|
||||||
|
await self.create_Whirlpool_Cooldown()
|
||||||
|
|
||||||
await self.create_step(step_type, step_name, step_kettle, step_time, step_temp, AutoMode, sensor, Notification, AutoNext, LidAlert, FirstWort, Hop1, Hop2, Hop3, Hop4, Hop5, Hop6)
|
self.cbpi.notify('KBH Recipe created', name, NotificationType.INFO)
|
||||||
|
|
||||||
# Add Waitstep as Whirlpool
|
|
||||||
if self.cooldown != "WaiStep" and self.cooldown !="":
|
|
||||||
step_type = "WaitStep"
|
|
||||||
step_name = "Whirlpool"
|
|
||||||
cooldown_sensor = ""
|
|
||||||
step_timer = "15"
|
|
||||||
step_temp = ""
|
|
||||||
AutoMode = ""
|
|
||||||
|
|
||||||
await self.create_step(step_type, step_name, step_kettle, step_timer, step_temp, AutoMode, cooldown_sensor)
|
|
||||||
|
|
||||||
# CoolDown step is sending a notification when cooldowntemp is reached
|
|
||||||
step_type = self.cooldown if self.cooldown != "" else "WaitStep"
|
|
||||||
step_name = "CoolDown"
|
|
||||||
cooldown_sensor = ""
|
|
||||||
step_timer = "15"
|
|
||||||
step_temp = ""
|
|
||||||
AutoMode = ""
|
|
||||||
if step_type == "CooldownStep":
|
|
||||||
cooldown_sensor = self.cbpi.config.get("steps_cooldown_sensor", None)
|
|
||||||
if cooldown_sensor is None or cooldown_sensor == '':
|
|
||||||
cooldown_sensor = self.kettle.sensor # fall back to kettle sensor if no other sensor is specified
|
|
||||||
step_kettle = self.id
|
|
||||||
step_timer = ""
|
|
||||||
step_temp = int(self.CoolDownTemp)
|
|
||||||
|
|
||||||
await self.create_step(step_type, step_name, step_kettle, step_timer, step_temp, AutoMode, cooldown_sensor)
|
|
||||||
|
|
||||||
except:
|
except:
|
||||||
|
self.cbpi.notify('KBH Recipe creation failure', name, NotificationType.ERROR)
|
||||||
pass
|
pass
|
||||||
|
else:
|
||||||
self.cbpi.notify('KBH Recipe created', name, NotificationType.INFO)
|
self.cbpi.notify('Recipe Upload', 'No default Kettle defined. Please specify default Kettle in settings', NotificationType.ERROR)
|
||||||
|
|
||||||
def getFirstWortKBH(self, id):
|
|
||||||
alert = False
|
|
||||||
try:
|
|
||||||
conn = sqlite3.connect(self.path)
|
|
||||||
c = conn.cursor()
|
|
||||||
c.execute('SELECT Zeit FROM Hopfengaben WHERE Vorderwuerze = 1 AND SudID = ?', (id,))
|
|
||||||
row = c.fetchall()
|
|
||||||
if len(row) != 0:
|
|
||||||
alert = True
|
|
||||||
except Exception as e:
|
|
||||||
self.cbpi.notify("Failed to create Recipe", e.message, NotificationType.ERROR)
|
|
||||||
return ('', 500)
|
|
||||||
finally:
|
|
||||||
if conn:
|
|
||||||
conn.close()
|
|
||||||
|
|
||||||
return alert
|
|
||||||
|
|
||||||
|
|
||||||
def getBoilAlertsKBH(self, id):
|
|
||||||
alerts = []
|
|
||||||
try:
|
|
||||||
conn = sqlite3.connect(self.path)
|
|
||||||
c = conn.cursor()
|
|
||||||
# get the hop addition times
|
|
||||||
c.execute('SELECT Zeit FROM Hopfengaben WHERE Vorderwuerze = 0 AND SudID = ?', (id,))
|
|
||||||
rows = c.fetchall()
|
|
||||||
|
|
||||||
for row in rows:
|
|
||||||
alerts.append(float(row[0]))
|
|
||||||
|
|
||||||
# get any misc additions if available
|
|
||||||
c.execute('SELECT Zugabedauer FROM WeitereZutatenGaben WHERE Zeitpunkt = 1 AND SudID = ?', (id,))
|
|
||||||
rows = c.fetchall()
|
|
||||||
|
|
||||||
for row in rows:
|
|
||||||
alerts.append(float(row[0]))
|
|
||||||
|
|
||||||
## Dedupe and order the additions by their time, to prevent multiple alerts at the same time
|
|
||||||
alerts = sorted(list(set(alerts)))
|
|
||||||
|
|
||||||
## CBP should have these additions in reverse
|
|
||||||
alerts.reverse()
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
self.cbpi.notify("Failed to create Recipe", e.message, NotificationType.ERROR)
|
|
||||||
return ('', 500)
|
|
||||||
finally:
|
|
||||||
if conn:
|
|
||||||
conn.close()
|
|
||||||
|
|
||||||
return alerts
|
|
||||||
|
|
||||||
async def xml_recipe_creation(self, Recipe_ID):
|
async def xml_recipe_creation(self, Recipe_ID):
|
||||||
self.kettle = None
|
config = self.get_config_values()
|
||||||
|
|
||||||
#Define MashSteps
|
if self.kettle is not None:
|
||||||
self.mashin = self.cbpi.config.get("steps_mashin", "MashStep")
|
|
||||||
self.mash = self.cbpi.config.get("steps_mash", "MashStep")
|
|
||||||
self.mashout = self.cbpi.config.get("steps_mashout", None) # Currently used only for the Braumeister
|
|
||||||
self.boil = self.cbpi.config.get("steps_boil", "BoilStep")
|
|
||||||
self.cooldown = self.cbpi.config.get("steps_cooldown", "WaitStep")
|
|
||||||
|
|
||||||
#get default boil temp from settings
|
|
||||||
self.BoilTemp = self.cbpi.config.get("steps_boil_temp", 98)
|
|
||||||
|
|
||||||
#get default cooldown temp alarm setting
|
|
||||||
self.CoolDownTemp = self.cbpi.config.get("steps_cooldown_temp", 25)
|
|
||||||
|
|
||||||
#get server port from settings and define url for api calls -> adding steps
|
|
||||||
self.port = str(self.cbpi.static_config.get('port',8000))
|
|
||||||
self.url="http://127.0.0.1:" + self.port + "/step2/"
|
|
||||||
|
|
||||||
|
|
||||||
# get default Kettle from Settings
|
|
||||||
self.id = self.cbpi.config.get('MASH_TUN', None)
|
|
||||||
try:
|
|
||||||
self.kettle = self.cbpi.kettle.find_by_id(self.id)
|
|
||||||
except:
|
|
||||||
self.cbpi.notify('Recipe Upload', 'No default Kettle defined. Please specify default Kettle in settings', NotificationType.ERROR)
|
|
||||||
if self.id is not None or self.id != '':
|
|
||||||
# load beerxml file located in upload folder
|
# load beerxml file located in upload folder
|
||||||
self.path = os.path.join(".", 'config', "upload", "beer.xml")
|
self.path = os.path.join(".", 'config', "upload", "beer.xml")
|
||||||
if os.path.exists(self.path) is False:
|
if os.path.exists(self.path) is False:
|
||||||
self.cbpi.notify("File Not Found", "Please upload a Beer.xml File", NotificationType.ERROR)
|
self.cbpi.notify("File Not Found", "Please upload a Beer.xml File", NotificationType.ERROR)
|
||||||
|
|
||||||
|
|
||||||
e = xml.etree.ElementTree.parse(self.path).getroot()
|
e = xml.etree.ElementTree.parse(self.path).getroot()
|
||||||
|
recipe = e.find('./RECIPE[%s]' % (str(Recipe_ID)))
|
||||||
|
hops = recipe.findall('./HOPS/HOP')
|
||||||
|
miscs = recipe.findall('MISCS/MISC[USE="Boil"]')
|
||||||
|
name = e.find('./RECIPE[%s]/NAME' % (str(Recipe_ID))).text
|
||||||
|
boil_time = float(e.find('./RECIPE[%s]/BOIL_TIME' % (str(Recipe_ID))).text)
|
||||||
|
FirstWort= self.getFirstWort(hops, "xml")
|
||||||
|
|
||||||
result = []
|
await self.create_recipe(name)
|
||||||
for idx, val in enumerate(e.findall('RECIPE')):
|
|
||||||
result.append(val.find("NAME").text)
|
|
||||||
|
|
||||||
# Create recipe in recipe Book with name of first recipe in xml file
|
|
||||||
self.recipeID = await self.cbpi.recipe.create(self.getRecipeName(Recipe_ID))
|
|
||||||
|
|
||||||
# send recipe to mash profile
|
|
||||||
await self.cbpi.recipe.brew(self.recipeID)
|
|
||||||
|
|
||||||
# remove empty recipe from recipe book
|
|
||||||
await self.cbpi.recipe.remove(self.recipeID)
|
|
||||||
|
|
||||||
# Mash Steps -> first step is different as it heats up to defined temp and stops with notification to add malt
|
# Mash Steps -> first step is different as it heats up to defined temp and stops with notification to add malt
|
||||||
# AutoMode is yes to start and stop automatic mode or each step
|
# AutoMode is yes to start and stop automatic mode or each step
|
||||||
MashIn_Flag = True
|
MashIn_Flag = True
|
||||||
|
@ -406,135 +304,82 @@ class UploadController:
|
||||||
sensor = self.kettle.sensor
|
sensor = self.kettle.sensor
|
||||||
if MashIn_Flag == True and row.get("timer") == 0:
|
if MashIn_Flag == True and row.get("timer") == 0:
|
||||||
step_type = self.mashin if self.mashin != "" else "MashInStep"
|
step_type = self.mashin if self.mashin != "" else "MashInStep"
|
||||||
AutoMode = "Yes" if step_type == "MashInStep" else "No"
|
|
||||||
Notification = "Target temperature reached. Please add malt."
|
Notification = "Target temperature reached. Please add malt."
|
||||||
MashIn_Flag = False
|
MashIn_Flag = False
|
||||||
else:
|
else:
|
||||||
step_type = self.mash if self.mash != "" else "MashStep"
|
step_type = self.mash if self.mash != "" else "MashStep"
|
||||||
AutoMode = "Yes" if step_type == "MashStep" else "No"
|
|
||||||
Notification = ""
|
Notification = ""
|
||||||
|
|
||||||
await self.create_step(step_type, step_name, step_kettle, step_timer, step_temp, AutoMode, sensor, Notification)
|
step_string = { "name": step_name,
|
||||||
|
"props": {
|
||||||
|
"AutoMode": "Yes" if step_type == "MashInStep" else "No",
|
||||||
|
"Kettle": self.id,
|
||||||
|
"Sensor": self.kettle.sensor,
|
||||||
|
"Temp": step_temp,
|
||||||
|
"Timer": step_timer,
|
||||||
|
"Notification": Notification
|
||||||
|
},
|
||||||
|
"status_text": "",
|
||||||
|
"status": "I",
|
||||||
|
"type": step_type
|
||||||
|
}
|
||||||
|
|
||||||
|
await self.create_step(step_string)
|
||||||
|
|
||||||
# MashOut -> Simple step that sends notification and waits for user input to move to next step (AutoNext=No)
|
# MashOut -> Simple step that sends notification and waits for user input to move to next step (AutoNext=No)
|
||||||
if self.mashout == "NotificationStep":
|
if self.mashout == "NotificationStep":
|
||||||
step_kettle = self.id
|
step_string = { "name": "Lautering",
|
||||||
step_type = self.mashout
|
"props": {
|
||||||
step_name = "Lautering"
|
"AutoNext": "No",
|
||||||
step_timer = ""
|
"Kettle": self.id,
|
||||||
step_temp = ""
|
"Notification": "Mash Process completed. Please start lautering and press next to start boil."
|
||||||
AutoMode = ""
|
},
|
||||||
sensor = ""
|
"status_text": "",
|
||||||
Notification = "Mash Process completed. Please start lautering and press next to start boil."
|
"status": "I",
|
||||||
AutoNext = "No"
|
"type": self.mashout
|
||||||
await self.create_step(step_type, step_name, step_kettle, step_timer, step_temp, AutoMode, sensor, Notification, AutoNext)
|
}
|
||||||
|
await self.create_step(step_string)
|
||||||
|
|
||||||
# Boil step including hop alarms and alarm for first wort hops -> Automode is set tu yes
|
# Boil step including hop alarms and alarm for first wort hops -> Automode is set tu yes
|
||||||
FirstWortFlag = len(str(self.getFirstWortAlert(Recipe_ID)))
|
Hops = self.getBoilAlerts(hops, miscs, "xml")
|
||||||
self.BoilTimeAlerts = self.getBoilAlerts(Recipe_ID)
|
|
||||||
|
|
||||||
step_kettle = self.id
|
step_kettle = self.id
|
||||||
step_time = str(int(self.getBoilTime(Recipe_ID)))
|
|
||||||
step_type = self.boil if self.boil != "" else "BoilStep"
|
step_type = self.boil if self.boil != "" else "BoilStep"
|
||||||
step_name = "Boil Step"
|
step_time = str(int(boil_time))
|
||||||
step_temp = self.BoilTemp
|
step_temp = self.BoilTemp
|
||||||
AutoMode = "Yes" if step_type == "BoilStep" else "No"
|
|
||||||
sensor = self.kettle.sensor
|
sensor = self.kettle.sensor
|
||||||
Notification = ""
|
|
||||||
AutoNext = ""
|
|
||||||
LidAlert = "Yes"
|
LidAlert = "Yes"
|
||||||
FirstWort = 'Yes' if FirstWortFlag != 0 else 'No'
|
|
||||||
Hop1 = str(int(self.BoilTimeAlerts[0])) if len(self.BoilTimeAlerts) >= 1 else None
|
step_string = { "name": "Boil Step",
|
||||||
Hop2 = str(int(self.BoilTimeAlerts[1])) if len(self.BoilTimeAlerts) >= 2 else None
|
"props": {
|
||||||
Hop3 = str(int(self.BoilTimeAlerts[2])) if len(self.BoilTimeAlerts) >= 3 else None
|
"AutoMode": "Yes" if step_type == "BoilStep" else "No",
|
||||||
Hop4 = str(int(self.BoilTimeAlerts[3])) if len(self.BoilTimeAlerts) >= 4 else None
|
"Kettle": step_kettle,
|
||||||
Hop5 = str(int(self.BoilTimeAlerts[4])) if len(self.BoilTimeAlerts) >= 5 else None
|
"Sensor": sensor,
|
||||||
Hop6 = str(int(self.BoilTimeAlerts[5])) if len(self.BoilTimeAlerts) >= 6 else None
|
"Temp": step_temp,
|
||||||
|
"Timer": step_time,
|
||||||
|
"First_Wort": FirstWort,
|
||||||
|
"LidAlert": LidAlert,
|
||||||
|
"Hop_1": Hops[0],
|
||||||
|
"Hop_2": Hops[1],
|
||||||
|
"Hop_3": Hops[2],
|
||||||
|
"Hop_4": Hops[3],
|
||||||
|
"Hop_5": Hops[4],
|
||||||
|
"Hop_6": Hops[5]
|
||||||
|
},
|
||||||
|
"status_text": "",
|
||||||
|
"status": "I",
|
||||||
|
"type": step_type
|
||||||
|
}
|
||||||
|
|
||||||
|
await self.create_step(step_string)
|
||||||
|
|
||||||
|
await self.create_Whirlpool_Cooldown()
|
||||||
|
|
||||||
|
self.cbpi.notify('BeerXML Recipe created ', name, NotificationType.INFO)
|
||||||
|
else:
|
||||||
|
self.cbpi.notify('Recipe Upload', 'No default Kettle defined. Please specify default Kettle in settings', NotificationType.ERROR)
|
||||||
|
|
||||||
|
|
||||||
await self.create_step(step_type, step_name, step_kettle, step_time, step_temp, AutoMode, sensor, Notification, AutoNext, LidAlert, FirstWort, Hop1, Hop2, Hop3, Hop4, Hop5, Hop6)
|
# XML functions to retrieve xml repice parameters (if multiple recipes are stored in one xml file, id could be used)
|
||||||
|
|
||||||
# Add Waitstep as Whirlpool
|
|
||||||
if self.cooldown != "WaiStep" and self.cooldown !="":
|
|
||||||
step_type = "WaitStep"
|
|
||||||
step_name = "Whirlpool"
|
|
||||||
cooldown_sensor = ""
|
|
||||||
step_timer = "15"
|
|
||||||
step_temp = ""
|
|
||||||
AutoMode = ""
|
|
||||||
|
|
||||||
await self.create_step(step_type, step_name, step_kettle, step_timer, step_temp, AutoMode, cooldown_sensor)
|
|
||||||
|
|
||||||
# CoolDown step is sending a notification when cooldowntemp is reached
|
|
||||||
step_type = self.cooldown if self.cooldown != "" else "WaitStep"
|
|
||||||
step_name = "CoolDown"
|
|
||||||
cooldown_sensor = ""
|
|
||||||
step_timer = "15"
|
|
||||||
step_temp = ""
|
|
||||||
AutoMode = ""
|
|
||||||
if step_type == "CooldownStep":
|
|
||||||
cooldown_sensor = self.cbpi.config.get("steps_cooldown_sensor", None)
|
|
||||||
if cooldown_sensor is None or cooldown_sensor == '':
|
|
||||||
cooldown_sensor = self.kettle.sensor # fall back to kettle sensor if no other sensor is specified
|
|
||||||
step_kettle = self.id
|
|
||||||
step_timer = ""
|
|
||||||
step_temp = self.CoolDownTemp
|
|
||||||
|
|
||||||
await self.create_step(step_type, step_name, step_kettle, step_timer, step_temp, AutoMode, cooldown_sensor)
|
|
||||||
|
|
||||||
self.cbpi.notify('BeerXML Recipe created ', result, NotificationType.INFO)
|
|
||||||
|
|
||||||
# XML functions to retrieve xml repice parameters (if multiple recipes are stored in one xml file, id could be used)
|
|
||||||
|
|
||||||
def getRecipeName(self, id):
|
|
||||||
e = xml.etree.ElementTree.parse(self.path).getroot()
|
|
||||||
return e.find('./RECIPE[%s]/NAME' % (str(id))).text
|
|
||||||
|
|
||||||
def getBoilTime(self, id):
|
|
||||||
e = xml.etree.ElementTree.parse(self.path).getroot()
|
|
||||||
return float(e.find('./RECIPE[%s]/BOIL_TIME' % (str(id))).text)
|
|
||||||
|
|
||||||
def getBoilAlerts(self, id):
|
|
||||||
e = xml.etree.ElementTree.parse(self.path).getroot()
|
|
||||||
|
|
||||||
recipe = e.find('./RECIPE[%s]' % (str(id)))
|
|
||||||
alerts = []
|
|
||||||
for e in recipe.findall('./HOPS/HOP'):
|
|
||||||
use = e.find('USE').text
|
|
||||||
## Hops which are not used in the boil step should not cause alerts
|
|
||||||
if use != 'Aroma' and use != 'Boil':
|
|
||||||
continue
|
|
||||||
|
|
||||||
alerts.append(float(e.find('TIME').text))
|
|
||||||
## There might also be miscelaneous additions during boild time
|
|
||||||
for e in recipe.findall('MISCS/MISC[USE="Boil"]'):
|
|
||||||
alerts.append(float(e.find('TIME').text))
|
|
||||||
|
|
||||||
## Dedupe and order the additions by their time, to prevent multiple alerts at the same time
|
|
||||||
alerts = sorted(list(set(alerts)))
|
|
||||||
## CBP should have these additions in reverse
|
|
||||||
alerts.reverse()
|
|
||||||
|
|
||||||
return alerts
|
|
||||||
|
|
||||||
def getFirstWortAlert(self, id):
|
|
||||||
e = xml.etree.ElementTree.parse(self.path).getroot()
|
|
||||||
recipe = e.find('./RECIPE[%s]' % (str(id)))
|
|
||||||
alerts = []
|
|
||||||
for e in recipe.findall('./HOPS/HOP'):
|
|
||||||
use = e.find('USE').text
|
|
||||||
## Hops which are not used in the boil step should not cause alerts
|
|
||||||
if use != 'First Wort':
|
|
||||||
continue
|
|
||||||
|
|
||||||
alerts.append(float(e.find('TIME').text))
|
|
||||||
|
|
||||||
## Dedupe and order the additions by their time, to prevent multiple alerts at the same time
|
|
||||||
alerts = sorted(list(set(alerts)))
|
|
||||||
## CBP should have these additions in reverse
|
|
||||||
alerts.reverse()
|
|
||||||
|
|
||||||
return alerts
|
|
||||||
|
|
||||||
def getSteps(self, id):
|
def getSteps(self, id):
|
||||||
e = xml.etree.ElementTree.parse(self.path).getroot()
|
e = xml.etree.ElementTree.parse(self.path).getroot()
|
||||||
|
@ -549,34 +394,9 @@ class UploadController:
|
||||||
return steps
|
return steps
|
||||||
|
|
||||||
async def bf_recipe_creation(self, Recipe_ID):
|
async def bf_recipe_creation(self, Recipe_ID):
|
||||||
self.kettle = None
|
config = self.get_config_values()
|
||||||
|
|
||||||
#Define MashSteps
|
if self.kettle is not None:
|
||||||
self.mashin = self.cbpi.config.get("steps_mashin", "MashStep")
|
|
||||||
self.mash = self.cbpi.config.get("steps_mash", "MashStep")
|
|
||||||
self.mashout = self.cbpi.config.get("steps_mashout", None) # Currently used only for the Braumeister
|
|
||||||
self.boil = self.cbpi.config.get("steps_boil", "BoilStep")
|
|
||||||
self.cooldown = self.cbpi.config.get("steps_cooldown", "WaitStep")
|
|
||||||
|
|
||||||
#get default boil temp from settings
|
|
||||||
self.BoilTemp = self.cbpi.config.get("steps_boil_temp", 98)
|
|
||||||
|
|
||||||
#get default cooldown temp alarm setting
|
|
||||||
self.CoolDownTemp = self.cbpi.config.get("steps_cooldown_temp", 25)
|
|
||||||
|
|
||||||
#get server port from settings and define url for api calls -> adding steps
|
|
||||||
self.port = str(self.cbpi.static_config.get('port',8000))
|
|
||||||
self.url="http://127.0.0.1:" + self.port + "/step2/"
|
|
||||||
|
|
||||||
self.TEMP_UNIT=self.cbpi.config.get("TEMP_UNIT", "C")
|
|
||||||
|
|
||||||
# get default Kettle from Settings
|
|
||||||
self.id = self.cbpi.config.get('MASH_TUN', None)
|
|
||||||
try:
|
|
||||||
self.kettle = self.cbpi.kettle.find_by_id(self.id)
|
|
||||||
except:
|
|
||||||
self.cbpi.notify('Recipe Upload', 'No default Kettle defined. Please specify default Kettle in settings', NotificationType.ERROR)
|
|
||||||
if self.id is not None or self.id != '':
|
|
||||||
|
|
||||||
brewfather = True
|
brewfather = True
|
||||||
result=[]
|
result=[]
|
||||||
|
@ -609,19 +429,9 @@ class UploadController:
|
||||||
except:
|
except:
|
||||||
miscs = None
|
miscs = None
|
||||||
|
|
||||||
FirstWort = "No"
|
FirstWort = self.getFirstWort(hops, "bf")
|
||||||
for hop in hops:
|
|
||||||
if hop['use'] == "First Wort":
|
|
||||||
FirstWort="Yes"
|
|
||||||
|
|
||||||
# Create recipe in recipe Book with name of first recipe in xml file
|
await self.create_recipe(RecipeName)
|
||||||
self.recipeID = await self.cbpi.recipe.create(RecipeName)
|
|
||||||
|
|
||||||
# send recipe to mash profile
|
|
||||||
await self.cbpi.recipe.brew(self.recipeID)
|
|
||||||
|
|
||||||
# remove empty recipe from recipe book
|
|
||||||
await self.cbpi.recipe.remove(self.recipeID)
|
|
||||||
|
|
||||||
# Mash Steps -> first step is different as it heats up to defined temp and stops with notification to add malt
|
# Mash Steps -> first step is different as it heats up to defined temp and stops with notification to add malt
|
||||||
# AutoMode is yes to start and stop automatic mode or each step
|
# AutoMode is yes to start and stop automatic mode or each step
|
||||||
|
@ -646,126 +456,221 @@ class UploadController:
|
||||||
step_type = self.mash if self.mash != "" else "MashStep"
|
step_type = self.mash if self.mash != "" else "MashStep"
|
||||||
AutoMode = "Yes" if step_type == "MashStep" else "No"
|
AutoMode = "Yes" if step_type == "MashStep" else "No"
|
||||||
Notification = ""
|
Notification = ""
|
||||||
await self.create_step(step_type, step_name, step_kettle, step_timer, step_temp, AutoMode, sensor, Notification)
|
|
||||||
|
step_string = { "name": step_name,
|
||||||
|
"props": {
|
||||||
|
"AutoMode": "Yes" if step_type == "MashInStep" else "No",
|
||||||
|
"Kettle": self.id,
|
||||||
|
"Sensor": self.kettle.sensor,
|
||||||
|
"Temp": step_temp,
|
||||||
|
"Timer": step_timer,
|
||||||
|
"Notification": Notification
|
||||||
|
},
|
||||||
|
"status_text": "",
|
||||||
|
"status": "I",
|
||||||
|
"type": step_type
|
||||||
|
}
|
||||||
|
|
||||||
|
await self.create_step(step_string)
|
||||||
|
|
||||||
# MashOut -> Simple step that sends notification and waits for user input to move to next step (AutoNext=No)
|
# MashOut -> Simple step that sends notification and waits for user input to move to next step (AutoNext=No)
|
||||||
|
|
||||||
if self.mashout == "NotificationStep":
|
if self.mashout == "NotificationStep":
|
||||||
step_kettle = self.id
|
step_string = { "name": "Lautering",
|
||||||
step_type = self.mashout
|
"props": {
|
||||||
step_name = "Lautering"
|
"AutoNext": "No",
|
||||||
step_timer = ""
|
"Kettle": self.id,
|
||||||
step_temp = ""
|
"Notification": "Mash Process completed. Please start lautering and press next to start boil."
|
||||||
AutoMode = ""
|
},
|
||||||
sensor = ""
|
"status_text": "",
|
||||||
Notification = "Mash Process completed. Please start lautering and press next to start boil."
|
"status": "I",
|
||||||
AutoNext = "No"
|
"type": self.mashout
|
||||||
await self.create_step(step_type, step_name, step_kettle, step_timer, step_temp, AutoMode, sensor, Notification, AutoNext)
|
}
|
||||||
|
await self.create_step(step_string)
|
||||||
|
|
||||||
# Boil step including hop alarms and alarm for first wort hops -> Automode is set tu yes
|
# Boil step including hop alarms and alarm for first wort hops -> Automode is set tu yes
|
||||||
self.BoilTimeAlerts = self.getBoilAlertsBF(hops,miscs)
|
Hops = self.getBoilAlerts(hops , miscs, "bf")
|
||||||
|
|
||||||
step_kettle = self.id
|
step_kettle = self.id
|
||||||
step_time = str(int(BoilTime))
|
step_time = str(int(BoilTime))
|
||||||
step_type = self.boil if self.boil != "" else "BoilStep"
|
step_type = self.boil if self.boil != "" else "BoilStep"
|
||||||
step_name = "Boil Step"
|
|
||||||
step_temp = self.BoilTemp
|
step_temp = self.BoilTemp
|
||||||
AutoMode = "Yes" if step_type == "BoilStep" else "No"
|
|
||||||
sensor = self.kettle.sensor
|
sensor = self.kettle.sensor
|
||||||
Notification = ""
|
|
||||||
AutoNext = ""
|
|
||||||
LidAlert = "Yes"
|
LidAlert = "Yes"
|
||||||
Hop1 = str(int(self.BoilTimeAlerts[0])) if len(self.BoilTimeAlerts) >= 1 else None
|
|
||||||
Hop2 = str(int(self.BoilTimeAlerts[1])) if len(self.BoilTimeAlerts) >= 2 else None
|
|
||||||
Hop3 = str(int(self.BoilTimeAlerts[2])) if len(self.BoilTimeAlerts) >= 3 else None
|
|
||||||
Hop4 = str(int(self.BoilTimeAlerts[3])) if len(self.BoilTimeAlerts) >= 4 else None
|
|
||||||
Hop5 = str(int(self.BoilTimeAlerts[4])) if len(self.BoilTimeAlerts) >= 5 else None
|
|
||||||
Hop6 = str(int(self.BoilTimeAlerts[5])) if len(self.BoilTimeAlerts) >= 6 else None
|
|
||||||
|
|
||||||
|
step_string = { "name": "Boil Step",
|
||||||
|
"props": {
|
||||||
|
"AutoMode": "Yes" if step_type == "BoilStep" else "No",
|
||||||
|
"Kettle": step_kettle,
|
||||||
|
"Sensor": sensor,
|
||||||
|
"Temp": step_temp,
|
||||||
|
"Timer": step_time,
|
||||||
|
"First_Wort": FirstWort,
|
||||||
|
"LidAlert": LidAlert,
|
||||||
|
"Hop_1": Hops[0],
|
||||||
|
"Hop_2": Hops[1],
|
||||||
|
"Hop_3": Hops[2],
|
||||||
|
"Hop_4": Hops[3],
|
||||||
|
"Hop_5": Hops[4],
|
||||||
|
"Hop_6": Hops[5]
|
||||||
|
},
|
||||||
|
"status_text": "",
|
||||||
|
"status": "I",
|
||||||
|
"type": step_type
|
||||||
|
}
|
||||||
|
|
||||||
await self.create_step(step_type, step_name, step_kettle, step_time, step_temp, AutoMode, sensor, Notification, AutoNext, LidAlert, FirstWort, Hop1, Hop2, Hop3, Hop4, Hop5, Hop6)
|
await self.create_step(step_string)
|
||||||
|
|
||||||
|
await self.create_Whirlpool_Cooldown()
|
||||||
# Add Waitstep as Whirlpool
|
|
||||||
if self.cooldown != "WaiStep" and self.cooldown !="":
|
|
||||||
step_type = "WaitStep"
|
|
||||||
step_name = "Whirlpool"
|
|
||||||
cooldown_sensor = ""
|
|
||||||
step_timer = "15"
|
|
||||||
step_temp = ""
|
|
||||||
AutoMode = ""
|
|
||||||
|
|
||||||
await self.create_step(step_type, step_name, step_kettle, step_timer, step_temp, AutoMode, cooldown_sensor)
|
|
||||||
|
|
||||||
# CoolDown step is sending a notification when cooldowntemp is reached
|
|
||||||
step_type = self.cooldown if self.cooldown != "" else "WaitStep"
|
|
||||||
step_name = "CoolDown"
|
|
||||||
cooldown_sensor = ""
|
|
||||||
step_timer = "15"
|
|
||||||
step_temp = ""
|
|
||||||
AutoMode = ""
|
|
||||||
if step_type == "CooldownStep":
|
|
||||||
cooldown_sensor = self.cbpi.config.get("steps_cooldown_sensor", None)
|
|
||||||
if cooldown_sensor is None or cooldown_sensor == '':
|
|
||||||
cooldown_sensor = self.kettle.sensor # fall back to kettle sensor if no other sensor is specified
|
|
||||||
step_kettle = self.id
|
|
||||||
step_timer = ""
|
|
||||||
step_temp = self.CoolDownTemp
|
|
||||||
|
|
||||||
await self.create_step(step_type, step_name, step_kettle, step_timer, step_temp, AutoMode, cooldown_sensor)
|
|
||||||
|
|
||||||
self.cbpi.notify('Brewfather App Recipe created: ', RecipeName, NotificationType.INFO)
|
self.cbpi.notify('Brewfather App Recipe created: ', RecipeName, NotificationType.INFO)
|
||||||
|
else:
|
||||||
|
self.cbpi.notify('Recipe Upload', 'No default Kettle defined. Please specify default Kettle in settings', NotificationType.ERROR)
|
||||||
|
|
||||||
|
def getBoilAlerts(self, hops, miscs, recipe_type):
|
||||||
def getBoilAlertsBF(self, hops, miscs):
|
|
||||||
alerts = []
|
alerts = []
|
||||||
for hop in hops:
|
for hop in hops:
|
||||||
use = hop['use']
|
if recipe_type == "xml":
|
||||||
## Hops which are not used in the boil step should not cause alerts
|
use = hop.find('USE').text
|
||||||
if use != 'Aroma' and use != 'Boil':
|
## Hops which are not used in the boil step should not cause alerts
|
||||||
continue
|
|
||||||
|
|
||||||
alerts.append(float(hop['time']))
|
|
||||||
#There might also be miscelaneous additions during boild time
|
|
||||||
if miscs is not None:
|
|
||||||
for misc in miscs:
|
|
||||||
use = misc['use']
|
|
||||||
if use != 'Aroma' and use != 'Boil':
|
if use != 'Aroma' and use != 'Boil':
|
||||||
continue
|
continue
|
||||||
|
alerts.append(float(hop.find('TIME').text))
|
||||||
alerts.append(float(misc['time']))
|
elif recipe_type == "bf":
|
||||||
|
use = hop['use']
|
||||||
|
if use != 'Aroma' and use != 'Boil':
|
||||||
|
continue
|
||||||
|
alerts.append(float(hop['time']))
|
||||||
|
elif recipe_type == "kbh":
|
||||||
|
alerts.append(float(hop[0]))
|
||||||
|
## There might also be miscelaneous additions during boild time
|
||||||
|
if miscs is not None:
|
||||||
|
for misc in miscs:
|
||||||
|
if recipe_type == "xml":
|
||||||
|
alerts.append(float(misc.find('TIME').text))
|
||||||
|
elif recipe_type == "bf":
|
||||||
|
use = misc['use']
|
||||||
|
if use != 'Aroma' and use != 'Boil':
|
||||||
|
continue
|
||||||
|
alerts.append(float(misc['time']))
|
||||||
|
elif recipe_type == "kbh":
|
||||||
|
alerts.append(float(misc[0]))
|
||||||
## Dedupe and order the additions by their time, to prevent multiple alerts at the same time
|
## Dedupe and order the additions by their time, to prevent multiple alerts at the same time
|
||||||
alerts = sorted(list(set(alerts)))
|
alerts = sorted(list(set(alerts)))
|
||||||
## CBP should have these additions in reverse
|
## CBP should have these additions in reverse
|
||||||
alerts.reverse()
|
alerts.reverse()
|
||||||
|
hop_alerts = []
|
||||||
|
for i in range(0,6):
|
||||||
|
try:
|
||||||
|
hop_alerts.append(str(int(alerts[i])))
|
||||||
|
except:
|
||||||
|
hop_alerts.append(None)
|
||||||
|
return hop_alerts
|
||||||
|
|
||||||
return alerts
|
def getFirstWort(self, hops, recipe_type):
|
||||||
|
alert = "No"
|
||||||
|
if recipe_type == "kbh":
|
||||||
|
if len(hops) != 0:
|
||||||
|
alert = "Yes"
|
||||||
|
elif recipe_type == "xml":
|
||||||
|
for hop in hops:
|
||||||
|
use = hop.find('USE').text
|
||||||
|
## Hops which are not used in the boil step should not cause alerts
|
||||||
|
if use != 'First Wort':
|
||||||
|
continue
|
||||||
|
alert = "Yes"
|
||||||
|
elif recipe_type == "bf":
|
||||||
|
for hop in hops:
|
||||||
|
if hop['use'] == "First Wort":
|
||||||
|
alert="Yes"
|
||||||
|
return alert
|
||||||
|
|
||||||
|
async def create_Whirlpool_Cooldown(self):
|
||||||
# function to create json to be send to api to add a step to the current mash profile. Currently all properties are send to each step which does not cuase an issue
|
# Add Waitstep as Whirlpool
|
||||||
async def create_step(self, type, name, kettle, timer, temp, AutoMode, sensor, Notification = "", AutoNext = "", LidAlert = "", FirstWort = "", Hop1 = "", Hop2 = "", Hop3 = "", Hop4 = "", Hop5 = "", Hop6=""):
|
if self.cooldown != "WaiStep" and self.cooldown !="":
|
||||||
step_string = { "name": name,
|
step_string = { "name": "Whirlpool",
|
||||||
"props": {
|
"props": {
|
||||||
"AutoMode": AutoMode,
|
"Kettle": self.id,
|
||||||
"Kettle": kettle,
|
"Timer": "15"
|
||||||
"Sensor": sensor,
|
|
||||||
"Temp": temp,
|
|
||||||
"Timer": timer,
|
|
||||||
"Notification": Notification,
|
|
||||||
"AutoNext": AutoNext,
|
|
||||||
"First_Wort": FirstWort,
|
|
||||||
"LidAlert": LidAlert,
|
|
||||||
"Hop_1": Hop1,
|
|
||||||
"Hop_2": Hop2,
|
|
||||||
"Hop_3": Hop3,
|
|
||||||
"Hop_4": Hop4,
|
|
||||||
"Hop_5": Hop5,
|
|
||||||
"Hop_6": Hop6
|
|
||||||
},
|
},
|
||||||
"status_text": "",
|
"status_text": "",
|
||||||
"status": "I",
|
"status": "I",
|
||||||
"type": type
|
"type": "WaitStep"
|
||||||
}
|
}
|
||||||
|
await self.create_step(step_string)
|
||||||
|
|
||||||
|
# CoolDown step is sending a notification when cooldowntemp is reached
|
||||||
|
step_type = self.cooldown if self.cooldown != "" else "WaitStep"
|
||||||
|
step_name = "CoolDown"
|
||||||
|
cooldown_sensor = ""
|
||||||
|
step_temp = ""
|
||||||
|
step_timer = "15"
|
||||||
|
if step_type == "CooldownStep":
|
||||||
|
cooldown_sensor = self.cbpi.config.get("steps_cooldown_sensor", None)
|
||||||
|
if cooldown_sensor is None or cooldown_sensor == '':
|
||||||
|
cooldown_sensor = self.kettle.sensor # fall back to kettle sensor if no other sensor is specified
|
||||||
|
step_timer = ""
|
||||||
|
step_temp = int(self.CoolDownTemp)
|
||||||
|
step_string = { "name": "Cooldown",
|
||||||
|
"props": {
|
||||||
|
"Kettle": self.id,
|
||||||
|
"Timer": step_timer,
|
||||||
|
"Temp": step_temp,
|
||||||
|
"Sensor": cooldown_sensor
|
||||||
|
},
|
||||||
|
"status_text": "",
|
||||||
|
"status": "I",
|
||||||
|
"type": step_type
|
||||||
|
}
|
||||||
|
await self.create_step(step_string)
|
||||||
|
|
||||||
|
def get_config_values(self):
|
||||||
|
self.kettle = None
|
||||||
|
#Define MashSteps
|
||||||
|
self.TEMP_UNIT = self.cbpi.config.get("TEMP_UNIT", "C")
|
||||||
|
self.mashin = self.cbpi.config.get("steps_mashin", "MashInStep")
|
||||||
|
self.mash = self.cbpi.config.get("steps_mash", "MashStep")
|
||||||
|
self.mashout = self.cbpi.config.get("steps_mashout", None) # Currently used only for the Braumeister
|
||||||
|
self.boil = self.cbpi.config.get("steps_boil", "BoilStep")
|
||||||
|
self.whirlpool="Waitstep"
|
||||||
|
self.cooldown = self.cbpi.config.get("steps_cooldown", "WaitStep")
|
||||||
|
#get default boil temp from settings
|
||||||
|
self.BoilTemp = self.cbpi.config.get("steps_boil_temp", 98)
|
||||||
|
#get default cooldown temp alarm setting
|
||||||
|
self.CoolDownTemp = self.cbpi.config.get("steps_cooldown_temp", 25)
|
||||||
|
# get default Kettle from Settings
|
||||||
|
self.id = self.cbpi.config.get('MASH_TUN', None)
|
||||||
|
try:
|
||||||
|
self.kettle = self.cbpi.kettle.find_by_id(self.id)
|
||||||
|
except:
|
||||||
|
self.cbpi.notify('Recipe Upload', 'No default Kettle defined. Please specify default Kettle in settings', NotificationType.ERROR)
|
||||||
|
config_values = { "kettle": self.kettle,
|
||||||
|
"kettle_id": str(self.id),
|
||||||
|
"mashin": str(self.mashin),
|
||||||
|
"mash": str(self.mash),
|
||||||
|
"mashout": str(self.mashout),
|
||||||
|
"boil": str(self.boil),
|
||||||
|
"whirlpool": str(self.whirlpool),
|
||||||
|
"cooldown": str(self.cooldown),
|
||||||
|
"boiltemp": str(self.BoilTemp),
|
||||||
|
"cooldowntemp": str(self.CoolDownTemp),
|
||||||
|
"temp_unit": str(self.TEMP_UNIT)
|
||||||
|
}
|
||||||
|
return config_values
|
||||||
|
|
||||||
|
async def create_recipe(self, name):
|
||||||
|
# Create recipe in recipe Book with name of first recipe in xml file
|
||||||
|
self.recipeID = await self.cbpi.recipe.create(name)
|
||||||
|
# send recipe to mash profile
|
||||||
|
await self.cbpi.recipe.brew(self.recipeID)
|
||||||
|
# remove empty recipe from recipe book
|
||||||
|
await self.cbpi.recipe.remove(self.recipeID)
|
||||||
|
|
||||||
|
# function to create json to be send to api to add a step to the current mash profile. Currently all properties are send to each step which does not cuase an issue
|
||||||
|
async def create_step(self, step_string):
|
||||||
|
#get server port from settings and define url for api calls -> adding steps
|
||||||
|
self.port = str(self.cbpi.static_config.get('port',8000))
|
||||||
|
self.url="http://127.0.0.1:" + self.port + "/step2/"
|
||||||
# convert step:string to json required for api call.
|
# convert step:string to json required for api call.
|
||||||
step = json.dumps(step_string)
|
step = json.dumps(step_string)
|
||||||
headers={'Content-Type': 'application/json', 'Accept': 'application/json'}
|
headers={'Content-Type': 'application/json', 'Accept': 'application/json'}
|
||||||
|
|
Loading…
Reference in a new issue