Open Source Brewery Controller.
HTML C++ C CSS PHP Lua
Switch branches/tags
Nothing to show
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
docs
lib
src
test_code
.cproject
.gitignore
.project
AUTHORS
COPYING
ChangeLog
INSTALL
Makefile.am
Makefile.old
NEWS
README
autogen.sh
bt.php
building.txt
configure.in

README

Unfortunately this software should be considered ABANDONED. I will leave it here for anyone who may find it useful, either as a starting point for something else or just to see how poor my C++ skills are.

I am however working on re-implementing this in Python, with an associated mobile app for controlling the brewery, fermenters, and also kegerator (with display).
The whole project is at https://github.com/vortexau/OpenBrew-Py.git

Basically I reimplemented all my thoughts and ideas in Python so I could learn that language (I know I know! I rubbished it below! Let's just say I've learned it has its place, and it's for things like this! My thoughts on Perl haven't changed though. Sorry.). And I wanted to learn Cordova development, so that's why I used that for the mobile app.

---

OpenBrew. Software for Linux and UNIX-like OS for controlling a Brewery.

I've designed and written this software to suit /my/ brewery, however I aim to keep it extensible enough for modifications to suit larger breweries and installations. As it's a 'home' brewery, I have no desire to implement real-time 'stuff'. If the OS takes a second to respond to a temp or to enable a pump, well it won't be the end of the world. Deal with it :)

My Brewery:

Control Hardware & Software:
SBC which controls the brewery: BeagleBone board; ARM CPU.
30a @ 250v Mechanical Relay Board, 8 relays: http://www.ereshop.com/shop/i2c-bus-heavy-current-relay-12v-pcf8574-p-771.html
Software is all C/C++.
Trying to keep it as free as possible, avoiding BOOST if I can (though that may be foolish).
PID Temperature control (yet to be implemented)
NO PYTHON! Rant: Python isn't much better than Perl in my eyes, and Perl is not much better than having your legs cut off to prevent your arms from getting sunburn. Doesn't make sense, does it. Neither does Perl. Disclaimer: I have been paid to be a Perl developer in a past life, so these comments are from someone who knows the language!

HLT:
 * 2400watt element for heating water
 * 'little brown pump' for recirculating water in the HLT while heating.
 * 48L 'wide' Stainless pot. Side draining. (70L stainless pot when main kettle is upgraded.)
 * 30a @ 250v Mechanical Relay for Element control.
 * 30a @ 250v Mechanical Relay for Recirc pump control.
 * Water temp sensor in side of vessel, thermowell with DS18B20 Sensor
 
Mash Tun.
 * 60L Square Esky (Building 70L Stainless mashtun currently)
 * Recirculation via March Pump
 * RIMS tube with 2400watt element
 * 30a @ 250v Mechanical Relay for Element control.
 * Thermowell in side of mashtun (DS18B20 Sensor inside Thermowell)
 * Thermowell in RIMS tube after element
 
Kettle
 * 70L Kettle (planning upgrade to 98L kettle)
 * Whirlpool fitting
 * Pickup at base of kettle
 
Chiller
 * Twin plate chillers
 * Pre-chiller to chill water going to second chiller
 * Temp sensors on wort ingress and egress

---------------

Processes for the software to control.

Timer for HLT Fill and Heating.
- Plug the brewery panel in, enable 'Standby Mode'. When going to Standby mode, the software will perform an NTPDate update of the system clock to ensure it's accurate. 
- Standby mode, allow the user to either fill the HLT manually, or to auto-fill (such as via RO or 'normal' water filters) at X time.
- Choose "Ready Target" time, say 7am - this will allow the system to auto-fill at 5am, heat water to either set point (say 75c) via PID, and HOLD at temp. 
- Option of heat to a boil, hold boil for 15 minutes, then allow to cool, and then hold at X temp via PID, ready to use for mash-in.
- When heater is active, enable 'little brown pump' to circulate the HLT water content to avoid stratification of the water temps. Possibly disable this at temps above 80c, as IIRC it's not rated above that.
- Flow Meter on auto-fill in-line after solenoid controlled valve for HLT fill. Alarm if filling does not create flow.

Mash tun
- Flow meter
- Alarm if flow drops too low
- Kill heating element if flow drops too low.
- Only enable Heating element if pump is on.
- Step mashing as defined in the recipe file.
- Starting the mash profile may require a user to say 'ok' as hoses and valves may need to be manually setup.

Kettle
- Brew Timer support in the GUI, alarm according to the recipe for various items (hop additions, flame out etc).
- Automate whirlpool control - At flame out, enable pump for X amount of time, count down timer for X time to allow trub cone to form.

---------------


program structure basic ideas.

classes:

vessel
 - abstract addStep(Step step);
 - int maxVolume // volume in mL, null means has no volume
 
 - liquortun (extend vessel)
 - mashtun (extend vessel)
 - kettletun (extend vessel)

// 0 HLT_AUTO_FILL
// 1 HLT_BOIL
// 2 HLT_HOLD 
// 3 HLT_

// 10 MASH_IN 
// 11 MASH_BETA_GLUCAN
// 12 MASH_PROTEIN
// 13 MASH_BETA_AMYLASE
// 14 MASH_ALPHA_AMYLASE
// 15 MASH_REST
// 16 MASH_VORLAUF
// 19 MASH_OUT

// 20 MASH_BATCH_DRAIN
// 21 MASH_BATCH_SPARGE
// 22 MASH_FLY_SPARGE


// 30 BOIL_STEP
// 31 BOIL_ADDITION
// 39 BOIL_FLAMEOUT

// 40 WHIRLPOOL_START
// 41 WHIRLPOOL_RUN
// 42 WHIRLPOOL_REST
// 49 WHIRLPOOL_END

// 51 CHILLER_START
// 52 CHILLER_RUN
// 59 CHILLER_END

Step Abstract
 - private stepOrder;
 - private stepTemp;
 - private stepStartTime;
 - private stepRunTime; // seconds.
 - private stepType; 
 - private stepRecirc = T/F;


mashInStep extends Step

betaGlucanStep extends Step
  - stepOrder ??
  - stepTemp 43.0;
  - stepTime 900 (15 mins).
  - stepType = MASH_BETA_GLUCAN

proteinStep extends Step

betaAmylaseStep extends Step

alphaAmylaseStep extends Step

mashOutStep extends Step

---------

load a batch, (parse beerxml file?)
batch always has:
    HLT
    MLT
    KETTLE
    
each vessel comprises a number of steps.
a step needs to be able to do many things:
    - enable/disable pump(s)
    - enable/disable heating element(s)
    - run for a certain amount of time.
    
Perhaps a method written to do the action execution could be passed a step object one at a time to perform actions as needed.
    - watch temps
    - enable/disable pumps based on flow
    - enable/disable elements based on flow
    - enable/disable alarms based on flow

// ----

Create UDEV rules for sensors, pumps and relays: http://www.reactivated.net/writing_udev_rules.html
can have paths such as /dev/pump1 /dev/pump2 possibly even for OneWire sensors also, say /dev/hlt_temp1 /dev/hlt_temp2 etc.


-- parsing beerxml file

-- Steps to Generate

Xpath for various variables:
//recipes/recipe/mash/sparge_temp.child_value()

Mash Profile Name
pugi::xml_node mash_name = doc.child("RECIPES").child("RECIPE").child("MASH").child("NAME");
cout << "recipe name: #" << mash_name.child_value() << "# " << endl; // get sparge temp.

Sparge Temp:
pugi::xml_node sparge_temp = doc.child("RECIPES").child("RECIPE").child("MASH").child("SPARGE_TEMP");
cout << "recipe name: #" << sparge_temp.child_value() << "# " << endl; // get sparge temp.

//recipes/recipe/mash/mash_steps/ path to all mash steps

//recipes/recipe/mash/mash_steps/mash_step[i]/
//recipes/recipe/mash/mash_steps/mash_step[i]/name
//recipes/recipe/mash/mash_steps/mash_step[i]/type
//recipes/recipe/mash/mash_steps/mash_step[i]/infuse_amount (water to add)
//recipes/recipe/mash/mash_steps/mash_step[i]/step_time - length of step in minutes
//recipes/recipe/mash/mash_steps/mash_step[i]/step_temp - temperature to maintain during step
//recipes/recipe/mash/mash_steps/mash_step[i]/ramp_time - time to take to raise temp
//recipes/recipe/mash/mash_steps/mash_step[i]/end_temp  - temp to be at the end of the step
//recipes/recipe/mash/mash_steps/mash_step[i]/infuse_temp