Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Brewing stuff

  • Loading branch information...
commit e135035d504845bd490db521a5224b351285953c 1 parent 3ea2109
@cjohansen authored
Showing with 135 additions and 0 deletions.
  1. +135 −0 brew.el
View
135 brew.el
@@ -0,0 +1,135 @@
+(require 'dash)
+
+(defun kg-lbs (kg)
+ (/ kg 0.45359237))
+
+(defun l-gal (l)
+ (/ l 3.78541178))
+
+(defun lbs-kg (lbs)
+ (* lbs 0.45359237))
+
+(defun gal-l (gal)
+ (* gal 3.78541178))
+
+(defun strike-water-temp (ratio infusion-temp grain-temp)
+ "Calculate the strike water temperature given the
+ liters water/kilograms grain ratio, the desired infusion
+ temperature and the grain temperature"
+ (+ (* (/ 0.41 ratio) (- infusion-temp grain-temp)) infusion-temp))
+
+(defun infusion-volume (infusion-temp mash-temp grain-weight water-volume addition-temp)
+ "Calculate the amount of water at temperature ADDITION-TEMP
+ necessary to add to a mash of GRAIN-WIGHT (kg) and WATER-VOLUME (l)
+ currently at MASH-TEMP (C) in order to bring it up to INFUSION-TEMP (C)"
+ (/ (* (- infusion-temp mash-temp) (+ (* 0.41 grain-weight) water-volume)) (- addition-temp infusion-temp)))
+
+(defun infusion-volume-boil (infusion-temp mash-temp grain-weight water-volume)
+ "Calculate the amount of boiling water necessary to add to a
+ mash of GRAIN-WAIGHT (kg) and WATER-VOLUME (l) currently at
+ MASH-TEMP (C) in order to bring it up to INFUSION-TEMP (C)"
+ (infusion-volume infusion-temp mash-temp grain-weight water-volume 100))
+
+(defun gravity-points (gravity)
+ "Given a GRAVITY like 1.050, get the number of 'gravity points'
+ (e.g. 50)"
+ (* 1000 (- gravity 1)))
+
+(defun wort-gravity (vol weight ppg)
+ "Given WEIGHT (lbs) amount of fermentable with gravity points PPG,
+ calculate the specific gravity in a wort of VOL gallons"
+ (+ 1 (/ (* (/ weight vol) ppg) 1000.0)))
+
+(defun wort-gravity-metric (vol weight ppg)
+ "Given WEIGHT (kg) amount of fermentable with gravity points PPG,
+ calculate the specific gravity in a wort of VOL liters"
+ (wort-gravity (l-gal vol) (kg-lbs weight) ppg))
+
+(defun extract-weight-for-og (vol og ppg)
+ "Calculate the amount of extract with PPG ppg (gravity points per
+ lb per gallon) needed for VOL gallons of wort at original gravity OG"
+ (let ((points (* (gravity-points og) vol)))
+ (/ points ppg)))
+
+(defun dme-amount-for-og (vol og)
+ "Given the wort volume VOL in gallons, and an original gravity OG,
+ calculate the necessary amount of DME in lbs"
+ (extract-weight-for-og vol og 42))
+
+(defun lme-amount-for-og (vol og)
+ "Given the wort volume VOL in gallons, and an original gravity OG,
+ calculate the necessary amount of LME in lbs"
+ (extract-weight-for-og vol og 36))
+
+(defun extract-kg-for-og (vol og ppg)
+ "Calculate the weight in kg of extract to reach the desired OG in
+ a wort of VOL litres."
+ (lbs-kg (extract-weight-for-og (l-gal vol) og ppg)))
+
+(defun dme-kg-for-og (vol og)
+ (extract-kg-for-og vol og 42))
+
+(defun lme-kg-for-og (vol og)
+ (extract-kg-for-og vol og 36))
+
+(defun abv (og fg)
+ (* (- og fg) 131.25))
+
+(defvar sucrose-ppg 46)
+
+(defun extraction-efficiency (grain-weight wort-volume gravity)
+ (/ (* (gravity-points gravity) wort-volume) grain-weight))
+
+(defun mash-efficiency (grain-weight wort-volume gravity fgdb)
+ (/ (extraction-efficiency grain-weight wort-volume gravity) (* fgdb sucrose-ppg)))
+
+(defun extraction-efficiency-metric (grain-weight wort-volume gravity)
+ (extraction-efficiency (kg-lbs grain-weight) (l-gal wort-volume) gravity))
+
+(defun mash-efficiency-metric (grain-weight wort-volume gravity fgdb)
+ (mash-efficiency (kg-lbs grain-weight) (l-gal wort-volume) gravity fgdb))
+
+(defun required-grain-weights (wort-volume gravity grains)
+ "Calculates required weight of individual grains based on a list
+ of grains where each item is a list of the grain's percentage in
+ the recipe, its fgdb, and expected efficiency, e.g.:
+ ((0.1 0.7 0.75) ;; CaraPils
+ (0.1 0.75 0.75) ;; Light Crystal 10L
+ (0.8 0.8 0.75) ;; Two-row lager malt
+ )"
+ (let ((points (* (gravity-points gravity) wort-volume)))
+ (-map (lambda (grain)
+ (/ (* points (car grain))
+ (* (car (cdr grain)) (car (cddr grain)) sucrose-ppg))) grains)))
+
+(defun required-grain-weights-metric (wort-volume gravity grains)
+ (-map 'lbs-kg (required-grain-weights (l-gal wort-volume) gravity grains)))
+
+;; (required-grain-weights 5 1.050 '((0.74 0.78 0.75) (0.26 0.75 0.75)))
+;; (required-grain-weights-metric 18.92 1.050 '((0.74 0.78 0.75) (0.26 0.75 0.75)))
+
+(defun boil-cold (temp volume cold-temp)
+ "To create VOLUME liters of TEMP C water, use this many liters
+ of boiling water, and this many liters of cold water"
+ (let ((boiling (/ (- (* temp volume) cold-temp) 100)))
+ (list (cons (- volume boiling) cold-temp) (cons boiling 100))))
+
+(defun wort-points (gravity volume)
+ (* (gravity-points gravity) volume))
+
+(defun wort-points-metric (gravity volume)
+ (wort-points gravity (l-gal volume)))
+
+(defun wort-volume-at-gravity (gravity volume desired-gravity)
+ (/ (wort-points gravity volume) (gravity-points desired-gravity)))
+
+(defun mash-schedule (grain-weight grain-temp start-ratio steps)
+ (let ((strike-temp (strike-water-temp start-ratio (car steps) grain-temp))
+ (mash-temp (car steps))
+ (water-volume (* grain-weight start-ratio)))
+ (-flatten (cons (boil-cold strike-temp water-volume 10.4) (-map (lambda (infusion-temp)
+ (cons (infusion-volume-boil infusion-temp mash-temp grain-weight water-volume) 100)) (cdr steps))))))
+
+(defun final-mash-volume (grain-weight grain-temp start-ratio steps)
+ (-reduce-from (lambda (sum pair) (+ sum (car pair)))
+ 0 (mash-schedule grain-weight grain-temp start-ratio steps)))
Please sign in to comment.
Something went wrong with that request. Please try again.