mirror of
https://github.com/PiBrewing/craftbeerpi4.git
synced 2024-11-25 16:38:36 +01:00
Merge pull request #35 from avollkopf/development
Merge update from Development Branch
This commit is contained in:
commit
4f82dc85b3
7 changed files with 353 additions and 20 deletions
|
@ -1,2 +1 @@
|
||||||
__version__ = "4.0.1.2"
|
__version__ = "4.0.1.7"
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ from cbpi.utils.utils import load_config
|
||||||
from zipfile import ZipFile
|
from zipfile import ZipFile
|
||||||
from cbpi.craftbeerpi import CraftBeerPi
|
from cbpi.craftbeerpi import CraftBeerPi
|
||||||
import os
|
import os
|
||||||
|
import platform
|
||||||
import pathlib
|
import pathlib
|
||||||
import shutil
|
import shutil
|
||||||
import yaml
|
import yaml
|
||||||
|
@ -152,12 +153,17 @@ def check_for_setup():
|
||||||
if zip_content == True:
|
if zip_content == True:
|
||||||
print("Found correct content. Starting Restore process")
|
print("Found correct content. Starting Restore process")
|
||||||
output_path = pathlib.Path(os.path.join(".", 'config'))
|
output_path = pathlib.Path(os.path.join(".", 'config'))
|
||||||
|
system = platform.system()
|
||||||
|
print(system)
|
||||||
|
if system != "Windows":
|
||||||
owner = output_path.owner()
|
owner = output_path.owner()
|
||||||
group = output_path.group()
|
group = output_path.group()
|
||||||
print("Removing old config folder")
|
print("Removing old config folder")
|
||||||
shutil.rmtree(output_path, ignore_errors=True)
|
shutil.rmtree(output_path, ignore_errors=True)
|
||||||
print("Extracting zip file to config folder")
|
print("Extracting zip file to config folder")
|
||||||
zip.extractall(output_path)
|
zip.extractall(output_path)
|
||||||
|
zip.close()
|
||||||
|
if system != "Windows":
|
||||||
print("Changing owner and group of config folder recursively to {}:{}".format(owner,group))
|
print("Changing owner and group of config folder recursively to {}:{}".format(owner,group))
|
||||||
recursive_chown(output_path, owner, group)
|
recursive_chown(output_path, owner, group)
|
||||||
print("Removing backup file")
|
print("Removing backup file")
|
||||||
|
|
|
@ -59,6 +59,16 @@ class UploadController:
|
||||||
except:
|
except:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
async def get_json_recipes(self):
|
||||||
|
try:
|
||||||
|
path = os.path.join(".", 'config', "upload", "mmum.json")
|
||||||
|
e = json.load(open(path))
|
||||||
|
result =[]
|
||||||
|
result.append({'value': str(1), 'label': e['Name']})
|
||||||
|
return result
|
||||||
|
except:
|
||||||
|
return []
|
||||||
|
|
||||||
async def get_brewfather_recipes(self,offset=0):
|
async def get_brewfather_recipes(self,offset=0):
|
||||||
brewfather = True
|
brewfather = True
|
||||||
result=[]
|
result=[]
|
||||||
|
@ -123,6 +133,20 @@ class UploadController:
|
||||||
self.cbpi.notify("Error" "XML Recipe upload failed: {}".format(e), NotificationType.ERROR)
|
self.cbpi.notify("Error" "XML Recipe upload failed: {}".format(e), NotificationType.ERROR)
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
elif content_type == 'application/json':
|
||||||
|
try:
|
||||||
|
mmum_json = recipe_file.read().decode('utf-8','replace')
|
||||||
|
if recipe_file and self.allowed_file(filename, 'json'):
|
||||||
|
self.path = os.path.join(".", 'config', "upload", "mmum.json")
|
||||||
|
|
||||||
|
f = open(self.path, "w")
|
||||||
|
f.write(mmum_json)
|
||||||
|
f.close()
|
||||||
|
self.cbpi.notify("Success", "JSON Recipe {} has been uploaded".format(filename), NotificationType.SUCCESS)
|
||||||
|
except Exception as e:
|
||||||
|
self.cbpi.notify("Error" "JSON Recipe upload failed: {}".format(e), NotificationType.ERROR)
|
||||||
|
pass
|
||||||
|
|
||||||
elif content_type == 'application/octet-stream':
|
elif content_type == 'application/octet-stream':
|
||||||
try:
|
try:
|
||||||
content = recipe_file.read()
|
content = recipe_file.read()
|
||||||
|
@ -293,6 +317,235 @@ class UploadController:
|
||||||
else:
|
else:
|
||||||
self.cbpi.notify('Recipe Upload', 'No default Kettle defined. Please specify default Kettle in settings', NotificationType.ERROR)
|
self.cbpi.notify('Recipe Upload', 'No default Kettle defined. Please specify default Kettle in settings', NotificationType.ERROR)
|
||||||
|
|
||||||
|
def findMax(self, string):
|
||||||
|
self.path = os.path.join(".", 'config', "upload", "mmum.json")
|
||||||
|
e = json.load(open(self.path))
|
||||||
|
for idx in range(1,20):
|
||||||
|
search_string = string.replace("%%",str(idx))
|
||||||
|
i = idx
|
||||||
|
if search_string not in e:
|
||||||
|
break
|
||||||
|
return i
|
||||||
|
|
||||||
|
def getJsonMashin(self, id):
|
||||||
|
self.path = os.path.join(".", 'config', "upload", "mmum.json")
|
||||||
|
e = json.load(open(self.path))
|
||||||
|
return float(e['Infusion_Einmaischtemperatur'])
|
||||||
|
|
||||||
|
async def json_recipe_creation(self, Recipe_ID):
|
||||||
|
config = self.get_config_values()
|
||||||
|
|
||||||
|
if self.kettle is not None:
|
||||||
|
# load mmum-json file located in upload folder
|
||||||
|
self.path = os.path.join(".", 'config', "upload", "mmum.json")
|
||||||
|
if os.path.exists(self.path) is False:
|
||||||
|
self.cbpi.notify("File Not Found", "Please upload a MMuM-JSON File", NotificationType.ERROR)
|
||||||
|
|
||||||
|
e = json.load(open(self.path))
|
||||||
|
name = e['Name']
|
||||||
|
boil_time = float(e['Kochzeit_Wuerze'])
|
||||||
|
|
||||||
|
await self.create_recipe(name)
|
||||||
|
|
||||||
|
|
||||||
|
hops = []
|
||||||
|
for idx in range(1,self.findMax("Hopfen_%%_Kochzeit")):
|
||||||
|
hops_name = "%sg %s %s%% alpha" % (e["Hopfen_{}_Menge".format(idx)],e["Hopfen_{}_Sorte".format(idx)],e["Hopfen_{}_alpha".format(idx)])
|
||||||
|
if e["Hopfen_{}_Kochzeit".format(idx)].isnumeric():
|
||||||
|
if boil_time is not e["Hopfen_{}_Kochzeit".format(idx)].isnumeric():
|
||||||
|
alert = float(e["Hopfen_{}_Kochzeit".format(idx)])
|
||||||
|
elif e["Hopfen_{}_Kochzeit".format(idx)] == "Whirlpool":
|
||||||
|
alert = float(1)
|
||||||
|
else:
|
||||||
|
self.api.notify(headline="No Number at Hoptime", message="Please change json-File at Hopfen_{}_Kochzeit".format(idx), type="danger")
|
||||||
|
alert = float(1)
|
||||||
|
hops.append({"name":hops_name,"time":alert})
|
||||||
|
|
||||||
|
|
||||||
|
firstHops=[]
|
||||||
|
for idx in range(1,self.findMax("Hopfen_VWH_%%_Sorte")):
|
||||||
|
firstHops_name = "%sg %s %s%% alpha" % (e["Hopfen_VWH_{}_Menge".format(idx)],e["Hopfen_VWH_{}_Sorte".format(idx)],e["Hopfen_VWH_{}_alpha".format(idx)])
|
||||||
|
|
||||||
|
firstHops.append({"name":firstHops_name})
|
||||||
|
|
||||||
|
|
||||||
|
FirstWort= self.getFirstWort(firstHops, "json")
|
||||||
|
|
||||||
|
miscs = []
|
||||||
|
for idx in range(1,self.findMax("WeitereZutat_Wuerze_%%_Kochzeit")):
|
||||||
|
miscs_name = "%s%s %s" % (e["WeitereZutat_Wuerze_{}_Menge".format(idx)],e["WeitereZutat_Wuerze_{}_Einheit".format(idx)],e["WeitereZutat_Wuerze_{}_Name".format(idx)])
|
||||||
|
if e["WeitereZutat_Wuerze_{}_Kochzeit".format(idx)].isnumeric():
|
||||||
|
alert = float(e["WeitereZutat_Wuerze_{}_Kochzeit".format(idx)])
|
||||||
|
elif e["WeitereZutat_Wuerze_{}_Kochzeit".format(idx)] == "Whirlpool":
|
||||||
|
alert = float(1)
|
||||||
|
else:
|
||||||
|
self.api.notify(headline="No Number at Hoptime", message="Please change json-File at WeitereZutat_Wuerze_{}_Kochzeit".format(idx), type="danger")
|
||||||
|
alert = float(1)
|
||||||
|
miscs.append({"name":miscs_name,"time":alert})
|
||||||
|
|
||||||
|
|
||||||
|
# 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
|
||||||
|
MashIn_Flag = True
|
||||||
|
step_kettle = self.id
|
||||||
|
last_step_temp = 0
|
||||||
|
logging.info(step_kettle) ###################################################
|
||||||
|
for row in self.getSteps(Recipe_ID, "json"):
|
||||||
|
step_name = str(row.get("name"))
|
||||||
|
step_timer = str(int(row.get("timer")))
|
||||||
|
step_temp = str(int(row.get("temp")))
|
||||||
|
last_step_temp = step_temp
|
||||||
|
sensor = self.kettle.sensor
|
||||||
|
if MashIn_Flag == True:
|
||||||
|
if row.get("timer") == 0:
|
||||||
|
step_type = self.mashin if self.mashin != "" else "MashInStep"
|
||||||
|
Notification = "Target temperature reached. Please add malt."
|
||||||
|
MashIn_Flag = False
|
||||||
|
if step_name is None or step_name == "":
|
||||||
|
step_name = "MashIn"
|
||||||
|
elif self.addmashin == "Yes":
|
||||||
|
step_type = self.mashin if self.mashin != "" else "MashInStep"
|
||||||
|
Notification = "Target temperature reached. Please add malt."
|
||||||
|
MashIn_Flag = False
|
||||||
|
step_string = { "name": "MashIn",
|
||||||
|
"props": {
|
||||||
|
"AutoMode": self.AutoMode,
|
||||||
|
"Kettle": self.id,
|
||||||
|
"Sensor": self.kettle.sensor,
|
||||||
|
"Temp": self.getJsonMashin(Recipe_ID),
|
||||||
|
"Timer": 0,
|
||||||
|
"Notification": Notification
|
||||||
|
},
|
||||||
|
"status_text": "",
|
||||||
|
"status": "I",
|
||||||
|
"type": step_type
|
||||||
|
}
|
||||||
|
await self.create_step(step_string)
|
||||||
|
logging.info(step_kettle) ###################################################
|
||||||
|
|
||||||
|
step_type = self.mash if self.mash != "" else "MashStep"
|
||||||
|
Notification = ""
|
||||||
|
else:
|
||||||
|
step_type = self.mash if self.mash != "" else "MashStep"
|
||||||
|
Notification = ""
|
||||||
|
|
||||||
|
else:
|
||||||
|
step_type = self.mash if self.mash != "" else "MashStep"
|
||||||
|
Notification = ""
|
||||||
|
|
||||||
|
step_string = { "name": step_name,
|
||||||
|
"props": {
|
||||||
|
"AutoMode": self.AutoMode,
|
||||||
|
"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 -> mashStep to reach mashout-temp for 1 min
|
||||||
|
if last_step_temp != e["Abmaischtemperatur"]:
|
||||||
|
step_string = { "name": "MashOut",
|
||||||
|
"props": {
|
||||||
|
"AutoMode": self.AutoMode,
|
||||||
|
"Kettle": self.id,
|
||||||
|
"Sensor": self.kettle.sensor,
|
||||||
|
"Temp": e["Abmaischtemperatur"],
|
||||||
|
"Timer": 1,
|
||||||
|
"Notification": ""
|
||||||
|
},
|
||||||
|
"status_text": "",
|
||||||
|
"status": "I",
|
||||||
|
"type": "MashStep"
|
||||||
|
}
|
||||||
|
|
||||||
|
await self.create_step(step_string)
|
||||||
|
# Lautering -> Simple 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)
|
||||||
|
|
||||||
|
# Measure Original Gravity -> Simple step that sends notification
|
||||||
|
step_string = { "name": "Measure Original Gravity",
|
||||||
|
"props": {
|
||||||
|
"AutoNext": "No",
|
||||||
|
"Kettle": self.id,
|
||||||
|
"Notification": "What is the original gravity of the beer wort?"
|
||||||
|
},
|
||||||
|
"status_text": "",
|
||||||
|
"status": "I",
|
||||||
|
"type": "NotificationStep"
|
||||||
|
}
|
||||||
|
await self.create_step(step_string)
|
||||||
|
|
||||||
|
# Boil step including hop alarms and alarm for first wort hops -> Automode is set tu yes
|
||||||
|
Hops = self.getBoilAlerts(hops, miscs, "json")
|
||||||
|
step_kettle = self.boilid
|
||||||
|
step_type = self.boil if self.boil != "" else "BoilStep"
|
||||||
|
step_time = str(int(boil_time))
|
||||||
|
step_temp = self.BoilTemp
|
||||||
|
sensor = self.boilkettle.sensor
|
||||||
|
LidAlert = "Yes"
|
||||||
|
|
||||||
|
logging.info(step_temp) ###################################################
|
||||||
|
|
||||||
|
step_string = { "name": "Boil Step",
|
||||||
|
"props": {
|
||||||
|
"AutoMode": self.AutoMode,
|
||||||
|
"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_string)
|
||||||
|
|
||||||
|
# Measure Original Gravity -> Simple step that sends notification
|
||||||
|
step_string = { "name": "Measure Original Gravity",
|
||||||
|
"props": {
|
||||||
|
"AutoNext": "No",
|
||||||
|
"Kettle": self.id,
|
||||||
|
"Notification": "What is the original gravity of the beer wort?"
|
||||||
|
},
|
||||||
|
"status_text": "",
|
||||||
|
"status": "I",
|
||||||
|
"type": "NotificationStep"
|
||||||
|
}
|
||||||
|
await self.create_step(step_string)
|
||||||
|
|
||||||
|
await self.create_Whirlpool_Cooldown()
|
||||||
|
|
||||||
|
self.cbpi.notify('MMuM-JSON Recipe created ', name, NotificationType.INFO)
|
||||||
|
else:
|
||||||
|
self.cbpi.notify('Recipe Upload', 'No default Kettle defined. Please specify default Kettle in settings', NotificationType.ERROR)
|
||||||
|
|
||||||
|
|
||||||
async def xml_recipe_creation(self, Recipe_ID):
|
async def xml_recipe_creation(self, Recipe_ID):
|
||||||
config = self.get_config_values()
|
config = self.get_config_values()
|
||||||
|
|
||||||
|
@ -316,7 +569,7 @@ class UploadController:
|
||||||
# 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
|
||||||
step_kettle = self.id
|
step_kettle = self.id
|
||||||
for row in self.getSteps(Recipe_ID):
|
for row in self.getSteps(Recipe_ID, "xml"):
|
||||||
step_name = str(row.get("name"))
|
step_name = str(row.get("name"))
|
||||||
step_timer = str(int(row.get("timer")))
|
step_timer = str(int(row.get("timer")))
|
||||||
step_temp = str(int(row.get("temp")))
|
step_temp = str(int(row.get("temp")))
|
||||||
|
@ -428,15 +681,26 @@ class UploadController:
|
||||||
|
|
||||||
# XML functions to retrieve xml repice parameters (if multiple recipes are stored in one xml file, id could be used)
|
# XML functions to retrieve xml repice parameters (if multiple recipes are stored in one xml file, id could be used)
|
||||||
|
|
||||||
def getSteps(self, id):
|
def getSteps(self, id, recipe_type):
|
||||||
e = xml.etree.ElementTree.parse(self.path).getroot()
|
|
||||||
steps = []
|
steps = []
|
||||||
|
if recipe_type == "xml":
|
||||||
|
e = xml.etree.ElementTree.parse(self.path).getroot()
|
||||||
for e in e.findall('./RECIPE[%s]/MASH/MASH_STEPS/MASH_STEP' % (str(id))):
|
for e in e.findall('./RECIPE[%s]/MASH/MASH_STEPS/MASH_STEP' % (str(id))):
|
||||||
if self.cbpi.config.get("TEMP_UNIT", "C") == "C":
|
if self.cbpi.config.get("TEMP_UNIT", "C") == "C":
|
||||||
temp = float(e.find("STEP_TEMP").text)
|
temp = float(e.find("STEP_TEMP").text)
|
||||||
else:
|
else:
|
||||||
temp = round(9.0 / 5.0 * float(e.find("STEP_TEMP").text) + 32, 2)
|
temp = round(9.0 / 5.0 * float(e.find("STEP_TEMP").text) + 32, 2)
|
||||||
steps.append({"name": e.find("NAME").text, "temp": temp, "timer": float(e.find("STEP_TIME").text)})
|
steps.append({"name": e.find("NAME").text, "temp": temp, "timer": float(e.find("STEP_TIME").text)})
|
||||||
|
elif recipe_type == "json":
|
||||||
|
self.path = os.path.join(".", 'config', "upload", "mmum.json")
|
||||||
|
e = json.load(open(self.path))
|
||||||
|
for idx in range(1,self.findMax("Infusion_Rastzeit%%")):
|
||||||
|
if self.cbpi.config.get("TEMP_UNIT", "C") == "C":
|
||||||
|
temp = float(e["Infusion_Rasttemperatur{}".format(idx)])
|
||||||
|
else:
|
||||||
|
temp = round(9.0 / 5.0 * float(e["Infusion_Rasttemperatur{}".format(idx)]) + 32, 2)
|
||||||
|
|
||||||
|
steps.append({"name": "Rast {}".format(idx), "temp": temp, "timer": float(e["Infusion_Rastzeit{}".format(idx)])})
|
||||||
|
|
||||||
return steps
|
return steps
|
||||||
|
|
||||||
|
@ -632,6 +896,9 @@ class UploadController:
|
||||||
alerts.append(float(hop['time']))
|
alerts.append(float(hop['time']))
|
||||||
elif recipe_type == "kbh":
|
elif recipe_type == "kbh":
|
||||||
alerts.append(float(hop[0]))
|
alerts.append(float(hop[0]))
|
||||||
|
elif recipe_type == "json":
|
||||||
|
alerts.append(float(hop['time']))
|
||||||
|
|
||||||
## There might also be miscelaneous additions during boild time
|
## There might also be miscelaneous additions during boild time
|
||||||
if miscs is not None:
|
if miscs is not None:
|
||||||
for misc in miscs:
|
for misc in miscs:
|
||||||
|
@ -644,6 +911,8 @@ class UploadController:
|
||||||
alerts.append(float(misc['time']))
|
alerts.append(float(misc['time']))
|
||||||
elif recipe_type == "kbh":
|
elif recipe_type == "kbh":
|
||||||
alerts.append(float(misc[0]))
|
alerts.append(float(misc[0]))
|
||||||
|
elif recipe_type == "json":
|
||||||
|
alerts.append(float(misc['time']))
|
||||||
## 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
|
||||||
|
@ -672,6 +941,9 @@ class UploadController:
|
||||||
for hop in hops:
|
for hop in hops:
|
||||||
if hop['use'] == "First Wort":
|
if hop['use'] == "First Wort":
|
||||||
alert="Yes"
|
alert="Yes"
|
||||||
|
elif recipe_type == "json":
|
||||||
|
for hop in hops:
|
||||||
|
alert="Yes"
|
||||||
return alert
|
return alert
|
||||||
|
|
||||||
async def create_Whirlpool_Cooldown(self):
|
async def create_Whirlpool_Cooldown(self):
|
||||||
|
@ -705,7 +977,8 @@ class UploadController:
|
||||||
"Kettle": self.boilid,
|
"Kettle": self.boilid,
|
||||||
"Timer": step_timer,
|
"Timer": step_timer,
|
||||||
"Temp": step_temp,
|
"Temp": step_temp,
|
||||||
"Sensor": cooldown_sensor
|
"Sensor": cooldown_sensor,
|
||||||
|
"Actor": self.CoolDownActor
|
||||||
},
|
},
|
||||||
"status_text": "",
|
"status_text": "",
|
||||||
"status": "I",
|
"status": "I",
|
||||||
|
@ -729,6 +1002,7 @@ class UploadController:
|
||||||
self.BoilTemp = self.cbpi.config.get("steps_boil_temp", 98)
|
self.BoilTemp = self.cbpi.config.get("steps_boil_temp", 98)
|
||||||
#get default cooldown temp alarm setting
|
#get default cooldown temp alarm setting
|
||||||
self.CoolDownTemp = self.cbpi.config.get("steps_cooldown_temp", 25)
|
self.CoolDownTemp = self.cbpi.config.get("steps_cooldown_temp", 25)
|
||||||
|
self.CoolDownActor = self.cbpi.config.get("steps_cooldown_actor", None)
|
||||||
# get default Kettle from Settings
|
# get default Kettle from Settings
|
||||||
self.id = self.cbpi.config.get('MASH_TUN', None)
|
self.id = self.cbpi.config.get('MASH_TUN', None)
|
||||||
self.boilid = self.cbpi.config.get('BoilKettle', None)
|
self.boilid = self.cbpi.config.get('BoilKettle', None)
|
||||||
|
@ -758,6 +1032,7 @@ class UploadController:
|
||||||
"cooldown": str(self.cooldown),
|
"cooldown": str(self.cooldown),
|
||||||
"boiltemp": str(self.BoilTemp),
|
"boiltemp": str(self.BoilTemp),
|
||||||
"cooldowntemp": str(self.CoolDownTemp),
|
"cooldowntemp": str(self.CoolDownTemp),
|
||||||
|
"cooldownactor": self.CoolDownActor,
|
||||||
"temp_unit": str(self.TEMP_UNIT),
|
"temp_unit": str(self.TEMP_UNIT),
|
||||||
"AutoMode": str(self.AutoMode)
|
"AutoMode": str(self.AutoMode)
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ class ConfigUpdate(CBPiExtension):
|
||||||
default_cool_temp = 20 if TEMP_UNIT == "C" else 68
|
default_cool_temp = 20 if TEMP_UNIT == "C" else 68
|
||||||
boil_temp = self.cbpi.config.get("steps_boil_temp", None)
|
boil_temp = self.cbpi.config.get("steps_boil_temp", None)
|
||||||
cooldown_sensor = self.cbpi.config.get("steps_cooldown_sensor", None)
|
cooldown_sensor = self.cbpi.config.get("steps_cooldown_sensor", None)
|
||||||
|
cooldown_actor = self.cbpi.config.get("steps_cooldown_actor", None)
|
||||||
cooldown_temp = self.cbpi.config.get("steps_cooldown_temp", None)
|
cooldown_temp = self.cbpi.config.get("steps_cooldown_temp", None)
|
||||||
mashin_step = self.cbpi.config.get("steps_mashin", None)
|
mashin_step = self.cbpi.config.get("steps_mashin", None)
|
||||||
mash_step = self.cbpi.config.get("steps_mash", None)
|
mash_step = self.cbpi.config.get("steps_mash", None)
|
||||||
|
@ -60,6 +61,13 @@ class ConfigUpdate(CBPiExtension):
|
||||||
except:
|
except:
|
||||||
logger.warning('Unable to update database')
|
logger.warning('Unable to update database')
|
||||||
|
|
||||||
|
if cooldown_actor is None:
|
||||||
|
logger.info("INIT Cooldown Actor Setting")
|
||||||
|
try:
|
||||||
|
await self.cbpi.config.add("steps_cooldown_actor", "", ConfigType.ACTOR, "Actor to trigger cooldown water on and off (default: None)")
|
||||||
|
except:
|
||||||
|
logger.warning('Unable to update database')
|
||||||
|
|
||||||
if cooldown_temp is None:
|
if cooldown_temp is None:
|
||||||
logger.info("INIT Cooldown Temp Setting")
|
logger.info("INIT Cooldown Temp Setting")
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -41,7 +41,7 @@ class ReadThread (threading.Thread):
|
||||||
try:
|
try:
|
||||||
if self.sensor_name is None:
|
if self.sensor_name is None:
|
||||||
return
|
return
|
||||||
with open('/sys/bus/w1/devices/w1_bus_master1/%s/w1_slave' % self.sensor_name, 'r') as content_file:
|
with open('/sys/bus/w1/devices/%s/w1_slave' % self.sensor_name, 'r') as content_file:
|
||||||
content = content_file.read()
|
content = content_file.read()
|
||||||
if (content.split('\n')[0].split(' ')[11] == "YES"):
|
if (content.split('\n')[0].split(' ')[11] == "YES"):
|
||||||
temp = float(content.split("=")[-1]) / 1000 # temp in Celcius
|
temp = float(content.split("=")[-1]) / 1000 # temp in Celcius
|
||||||
|
|
|
@ -101,6 +101,47 @@ class UploadHttpEndpoints():
|
||||||
await self.controller.xml_recipe_creation(xml_id['id'])
|
await self.controller.xml_recipe_creation(xml_id['id'])
|
||||||
return web.Response(status=200)
|
return web.Response(status=200)
|
||||||
|
|
||||||
|
@request_mapping(path='/json', method="GET", auth_required=False)
|
||||||
|
async def get_json_list(self, request):
|
||||||
|
"""
|
||||||
|
|
||||||
|
---
|
||||||
|
description: Get recipe list from json file
|
||||||
|
tags:
|
||||||
|
- Upload
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: successful operation
|
||||||
|
"""
|
||||||
|
|
||||||
|
json_list = await self.controller.get_json_recipes()
|
||||||
|
|
||||||
|
return web.json_response(json_list)
|
||||||
|
|
||||||
|
@request_mapping(path='/json', method="POST", auth_required=False)
|
||||||
|
async def create_json_recipe(self, request):
|
||||||
|
"""
|
||||||
|
|
||||||
|
---
|
||||||
|
description: Create recipe from json file with selected id
|
||||||
|
tags:
|
||||||
|
- Upload
|
||||||
|
parameters:
|
||||||
|
- name: "id"
|
||||||
|
in: "body"
|
||||||
|
description: "Recipe ID: {'id': ID}"
|
||||||
|
required: true
|
||||||
|
type: "string"
|
||||||
|
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: successful operation
|
||||||
|
"""
|
||||||
|
|
||||||
|
json_id = await request.json()
|
||||||
|
await self.controller.json_recipe_creation(json_id['id'])
|
||||||
|
return web.Response(status=200)
|
||||||
|
|
||||||
@request_mapping(path='/bf/{offset}/', method="POST", auth_required=False)
|
@request_mapping(path='/bf/{offset}/', method="POST", auth_required=False)
|
||||||
async def get_bf_list(self, request):
|
async def get_bf_list(self, request):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -32,7 +32,11 @@ class CBPiWebSocket:
|
||||||
self.logger.debug("broadcast to ws clients. Data: %s" % data)
|
self.logger.debug("broadcast to ws clients. Data: %s" % data)
|
||||||
for ws in self._clients:
|
for ws in self._clients:
|
||||||
async def send_data(ws, data):
|
async def send_data(ws, data):
|
||||||
|
try:
|
||||||
await ws.send_json(data=data, dumps=json_dumps)
|
await ws.send_json(data=data, dumps=json_dumps)
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.error("Error with client %s: %s" % (ws, str(e)))
|
||||||
|
|
||||||
self.cbpi.app.loop.create_task(send_data(ws, data))
|
self.cbpi.app.loop.create_task(send_data(ws, data))
|
||||||
|
|
||||||
async def websocket_handler(self, request):
|
async def websocket_handler(self, request):
|
||||||
|
|
Loading…
Reference in a new issue