Skip to content

Commit

Permalink
feat: implement initial brew steps window
Browse files Browse the repository at this point in the history
  • Loading branch information
NoxHarmonium committed Sep 2, 2021
1 parent 685bf06 commit 0b45d3a
Show file tree
Hide file tree
Showing 30 changed files with 1,157 additions and 110 deletions.
6 changes: 4 additions & 2 deletions .vscode/c_cpp_properties.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@
"${myDefaultIncludePath}"
],
"defines": [
"TARGET_OS_MAC"
"TARGET_OS_MAC",
"OLDROUTINENAMES"
],
"forcedInclude": [
"${workspaceFolder}/include/MacIncludes.h"
"${workspaceFolder}/include/MacIncludes.h",
"${workspaceFolder}/include/CIncludes/Carbon.h"
],
"cStandard": "c89"
}
Expand Down
4 changes: 3 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@
"stdio.h": "c",
"textutils.h": "c",
"quickdraw.h": "c",
"mbserial.h": "c"
"mbserial.h": "c",
"controldefinitions.h": "c",
"mbutil.h": "c"
},
"c-cpp-flylint.clang.enable": false,
"c-cpp-flylint.flexelint.enable": false,
Expand Down
2 changes: 1 addition & 1 deletion Images/basilisk_ii_prefs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ displaycolordepth 0
disk ./system710-macbrew-dev-with-code.image
extfs /
screen win/512/384
seriala /dev/pts/3
seriala /dev/pts/4
serialb /dev/ttyS1
udptunnel false
udpport 6066
Expand Down
12 changes: 11 additions & 1 deletion macbrew-proxy/resources/sample_recipe.xml
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,16 @@ Also trying some Mandarina Bravaria this time and Eclipse (HPA-016) which appare
<TIME>0</TIME>
<FORM>Pellet</FORM>
</HOP>
<HOP>
<NAME>Warrior</NAME>
<VERSION>1</VERSION>
<ALPHA>11.75</ALPHA>
<AMOUNT>0.001</AMOUNT>
<USE>Boil</USE>
<USER_HOP_USE>Boil</USER_HOP_USE>
<TIME>10</TIME>
<FORM>Pellet</FORM>
</HOP>
<HOP>
<NAME>Amarillo (8.6 AA)</NAME>
<VERSION>1</VERSION>
Expand Down Expand Up @@ -358,4 +368,4 @@ Also trying some Mandarina Bravaria this time and Eclipse (HPA-016) which appare
<COLOR_MAX>10</COLOR_MAX>
</STYLE>
</RECIPE>
</RECIPES>
</RECIPES>
6 changes: 3 additions & 3 deletions macbrew-proxy/resources/sample_session.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
{
"id": "363597",
"loginid": "217955",
"recipeid": "1072961",
"recipeid": "123456",
"folder_id": null,
"brewstepprofileid": "1",
"phase": "All Gone",
Expand Down Expand Up @@ -69,7 +69,7 @@
"updated": "2020-12-02T10:29:45+00:00"
},
"recipe": {
"id": "1072961",
"id": "123456",
"recipetoken": "5fa1c626d6cc4",
"brewer_author_id": "217955",
"title": "Forresty Fruit",
Expand Down Expand Up @@ -161,4 +161,4 @@
}
}
]
}
}
224 changes: 224 additions & 0 deletions macbrew-proxy/src/commands/list_steps.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
use crate::commands::command::{prepare_response, Command};
use crate::data::brewers_friend::bf_data_manager::BfDataManager;
use crate::data::macbrew::recipes::Recipe;
use crate::data::macbrew::steps::{
BrewSessionStep, BOIL_PHASE, CHILL_PHASE, CLEANUP_PHASE, MASH_PHASE, PREPARE_PHASE,
};
use crate::error::Error::InvalidCommandInput;
use crate::error::Result;
use async_trait::async_trait;
use std::marker::PhantomData;
use std::str::FromStr;

// TODO: Work out why rustc thinks T is unused. Is PhantomData needed? Can I restructure this?
// Clue: https://github.com/rust-lang/rust/issues/23246
pub struct ListStepsCommand<DataManager: BfDataManager>(PhantomData<DataManager>);

#[async_trait]
impl<DataManager: BfDataManager + 'static> Command<DataManager> for ListStepsCommand<DataManager> {
async fn handle(rid: &str, args: &[&str]) -> Result<Vec<u8>> {
// TODO: This is extremely rough and just a MVP implmentation to start working on the Mac UI
// It will be cleaned up soon
match args {
[session_id] => {
let session = DataManager::session(session_id).await?;
let beer_xml_recipe = DataManager::recipe(&session.recipeid).await?;
let recipe = Recipe::from_beer_xml(&beer_xml_recipe);

let initial_steps = vec![
BrewSessionStep {
description: "Check ingredients (hops/yeast etc.) and reset equipment"
.to_string(),
time: -1,
phase: PREPARE_PHASE,
},
BrewSessionStep {
description: "Prepare strike water (add salt/acid)".to_string(),
time: -1,
phase: PREPARE_PHASE,
},
];

let mash_hops = recipe
.hops
.iter()
.filter(|h| h.hop_use == "Mash")
.collect::<Vec<_>>();

let mash_hop_steps: Vec<BrewSessionStep> = if mash_hops.is_empty() {
vec![]
} else {
mash_hops
.iter()
.map(|s| {
// TODO: Clean up this mess
let coerced_time = i16::from_str(&s.time).unwrap_or(0);
BrewSessionStep {
description: format!(
"Add {:?}g of {:?} hops to mash at minute {:?}",
s.amount, s.name, s.time,
),
time: coerced_time,
phase: MASH_PHASE,
}
})
.collect()
};

let mash_steps = recipe
.mash
.mash_steps
.iter()
.map(|s| {
// TODO: Clean up this mess
let time: String = s.step_time.clone().unwrap_or_else(|| "".to_string());
let coerced_time = i16::from_str(&time).unwrap_or(0);
BrewSessionStep {
description: format!(
"Heat {:?} water to {:?} degrees",
s.mash_step_type,
s.step_temp.clone().unwrap_or_else(|| "unknown".to_string())
),
time: coerced_time,
phase: MASH_PHASE,
}
})
.collect::<Vec<BrewSessionStep>>();

let preboil_steps = vec![
BrewSessionStep {
description: "Take gravity sample and record pre-boil volume".to_string(),
time: -1,
phase: MASH_PHASE,
},
BrewSessionStep {
description: "Bring to a boil".to_string(),
time: -1,
phase: MASH_PHASE,
},
];

let boil_hops = recipe
.hops
.iter()
.filter(|h| h.hop_use == "Boil")
.collect::<Vec<_>>();

let boil_hop_steps: Vec<BrewSessionStep> = if boil_hops.is_empty() {
vec![]
} else {
boil_hops
.iter()
.map(|s| {
// TODO: Clean up this mess
let coerced_time = i16::from_str(&s.time).unwrap_or(0);
BrewSessionStep {
description: format!(
"Add {:?}g of {:?} hops to boil at minute {:?}",
s.amount, s.name, s.time,
),
time: coerced_time,
phase: BOIL_PHASE,
}
})
.collect()
};

let postboil_steps = vec![
BrewSessionStep {
description: "Turn off kettle".to_string(),
time: i16::from_str(&recipe.boil_time).unwrap_or(0),
phase: BOIL_PHASE,
},
BrewSessionStep {
description: "Start chilling wort".to_string(),
time: -1,
phase: BOIL_PHASE,
},
];

let whirlpool_hops = recipe
.hops
.iter()
.filter(|h| {
// TODO: Maybe move some of this coersion to where the XML recipe is convered to rust objects
h.hop_use == "Aroma"
&& h.user_hop_use.clone().unwrap_or_else(|| "".to_string())
== "Whirlpool"
})
.collect::<Vec<_>>();

let whirlpool_hop_steps: Vec<BrewSessionStep> = if whirlpool_hops.is_empty() {
vec![]
} else {
whirlpool_hops
.iter()
.map(|s|
BrewSessionStep {
description: format!(
"When temp is {:?} degrees, add {:?}g of {:?} hops to whirlpool for {:?} minutes",
s.hop_temp, s.amount, s.name, s.time
),
time: -1,
phase: CHILL_PHASE,
}
)
.collect()
};

let chill_steps = vec![
BrewSessionStep {
description: format!("Cool wort down to {:?}", recipe.primary_temp),
time: -1,
phase: CHILL_PHASE,
},
BrewSessionStep {
description: "Take gravity reading".to_string(),
time: -1,
phase: CHILL_PHASE,
},
BrewSessionStep {
description: "Transfer to fermentor".to_string(),
time: -1,
phase: CHILL_PHASE,
},
BrewSessionStep {
description: "Pitch yeast".to_string(),
time: -1,
phase: CHILL_PHASE,
},
];

let cleanup_steps = vec![
BrewSessionStep {
description: "Set fermentation chamber temp".to_string(),
time: -1,
phase: CLEANUP_PHASE,
},
BrewSessionStep {
description: "Cleanup equipment".to_string(),
time: -1,
phase: CLEANUP_PHASE,
},
];

let all_steps: Vec<BrewSessionStep> = [
initial_steps,
mash_hop_steps,
mash_steps,
preboil_steps,
boil_hop_steps,
postboil_steps,
whirlpool_hop_steps,
chill_steps,
cleanup_steps,
]
.concat();
prepare_response(rid, true, &all_steps)
}
[_args @ ..] => Err(InvalidCommandInput {
message: String::from("Expected single parameter (Session ID)"),
}),
}
}
}
1 change: 1 addition & 0 deletions macbrew-proxy/src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ pub mod get_fermentation;
pub mod get_recipes;
pub mod get_sessions;
pub mod list_sessions;
pub mod list_steps;
pub mod ping;
25 changes: 24 additions & 1 deletion macbrew-proxy/src/data/brewers_friend/recipes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,29 @@ pub struct BeerXmlYeasts {
pub YEAST: Vec<BeerXmlYeast>,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
#[allow(non_snake_case)]
pub struct BeerXmlMashStep {
pub NAME: String,
pub TYPE: String,
pub STEP_TIME: Option<String>,
pub INFUSE_AMOUNT: Option<String>,
pub STEP_TEMP: Option<String>,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
#[allow(non_snake_case)]
pub struct BeerXmlMashSteps {
pub MASH_STEP: Vec<BeerXmlMashStep>,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
#[allow(non_snake_case)]
pub struct BeerXmlMash {
pub GRAIN_TEMP: String,
pub MASH_STEPS: BeerXmlMashSteps,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
#[allow(non_snake_case)]
pub struct BeerXmlRecipe {
Expand All @@ -110,7 +133,7 @@ pub struct BeerXmlRecipe {
//pub MISCS: TODO
pub YEASTS: BeerXmlYeasts,
//pub WATERS: TODO
//pub MASH: TODO
pub MASH: BeerXmlMash,
pub NOTES: Option<String>,
pub TASTE_NOTES: Option<String>,
pub TASTE_RATING: Option<String>,
Expand Down
1 change: 1 addition & 0 deletions macbrew-proxy/src/data/macbrew/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ pub mod fermentation;
pub mod recipes;
pub mod sessions;
pub mod shared;
pub mod steps;
Loading

0 comments on commit 0b45d3a

Please sign in to comment.