This project started as a testing suite for my brewing device software, especially Gravitymon. I needed a way to collect and analyse the data for further improving the software. It has since been extended to be used as my fermentation tracking software as a complement to Brewfather which I use for recepie design and tracking what beer I have.
This is a short list of features that has been implemented into the Brewlogger software
- Keeping a registry of devices, currently supports: GravityMon, KegMon, GravityMon Gateway, ChamberController
- Keeping track of batches that contains Gravity data.
- Visualing data collected from GravityMon (Gravity, Angle, Battery, Temperature, RSSI) and ChamberController (Frige Temperature)
- Analysing, Visulizing and Creating gravity formulas for GravityMon
- Importing data from Brewfather and connect that to batches
- Controlling ChamberController according to scheule from Brewfather
- Importing data via HTTP or Bluetooth
- Collecting logs from devices (using websocket interface)
- Collect tap information from KegMon
- Taplist for showing whats serving and what is available
- Fermentation prediction engine
There are a few public endpoints in brewlogger for receving data.
- http://your-ip/gravity (Used for sending gravity data)
- http://your-ip/pressure (Used for sending pressure data)
- http://your-ip/post (Used for sending both pressure and gravity data)
- Keeping track of batches that contain pressure data (PressureMon)
-
1.1.0 Support for new chamber control, disabled brewfather and AI for predicting when brew is finished
-
Improved unit test coverage especially for the UI that lacked automated tests
-
Added Machine Learning algorithm to estimate when brew is finished, shown on dashboard when enough data has been collected
-
Added fg/og fields to the batch including fetching from brewfather
-
Added editor for fermentation steps, which now also enables target via beer or fridge control.
-
Requires chamber controller version 0.8 since older versions lack the remote control API
-
Fixed issue that batch view could not be opened when brewfather keys are missing, now it will handle that gracefully
-
Fixed some minor bugs
-
-
1.0.0 Refactoring to support new devices
- Changed the batch API to only return the batches (not all the data)
- Fixed issue with NGNIX that added compression when payload was large which cause fetch errors in UI
- Refactored all API's to support null values when there is no data for better consistency
- Added the latest data points to the home view to a better overview.
- Update ble scanning code to support latest products
- Added more system events to the system log for helping out with issue tracking
- Added log for all recevied data on /public endpoints
- Set retention to 90 days for system log and received.
- Documeneted code and marked all paramters with type
- Fixed all lint recommendations (10/10)
- Increased test coverage where possible (+90%)
-
0.9.0 Updated with new features
- Feature: Added support for pressuremon and new post format
- Updated web flasher
- Various updates to UI to improve usability
- Made size of logfiles collected configurable
- Added log/ble collecting status via redis cache
- Upgraded to postgres17 (first create backup and then upgrade with fresh volume + restore)
- Update to python3.13
- Update to redis8
-
0.8.0 Updated with new features
- Feature: Refactored user interface to avoid data fetching, this will also allow for multiple devices interacting with the API's and data updated in background.
- Feature: Added support for pour data from Kegmon as well as fetching batches from Brewlogger (a must if pour storing is used)
- Feature: Added sorting of lists in UI to easier find what you are looking for.
- Bug: Caching of data from brewfather was invalidated to quickly
- Feature: Adding option to disable individual pour records
- Bug: Fixed problem with not beeing able to create a batch without connected gravity device.
- Feature: Refactor mDNS repeater to use AVAHI driver instead. mDNS container will now scan and store results in the Redis Cache.
- Bug: Not able to store changes when a record has just been created.
- Feature: Adding log collection and presentation using websocket interface
- Feature: Supporting Chamber Controller project and fermentation profiles from brewfather
-
0.7.0 First stable testing version
Installation requires a docker runtime (or k8s) where a stack can be deployed (a stack is a set of docker containers). I personally use portainer which is an excellent management software for containers.
It consists of the following containers.
- brewlogger-web; Web interface and webserver as the main entry point to the stack and uses the Server API's
- brewlogger-api; Server with the API's for the web interface
- brewlogger-cache; Redis cache for temporary data storage
- brewlogger-db; Postgres Database for persistent storage
- brewlogger-mdns [Optional]; Scans for mDNS devices on the local network and stores these in the Redis Cache for consumption by the API. If not deployed discovery of brewing devices will not work. This container will need to run on the host networks and will update the cache via the web/api server.
- brewlogger-ble [Optional]; BLE scanner that forwards data to the Server API's. If not deployed BLE data from GravityMon will not be captured. An option is to use GravityMon-Gatway instead.
- brewlogger-pgadmin [Optional]; Postgres Admin application. Only needed if you want to interact directly with the postgres application
- brewlogger-log [Optional]; Used for collecting logs from devices
services:
brew_web:
image: mpse2/brewlogger-web
hostname: brew_web
restart: always
environment:
- API_KEY=[your API key for securing access to brew_api]
- API_HOST=brew_api
networks:
- brew_net
ports:
- 80:80
depends_on:
- brew_api
brew_api:
image: mpse2/brewlogger-api
hostname: brew_api
restart: always
networks:
- brew_net
environment:
- API_KEY=[your API key for securing access to brew_api]
- DATABASE_URL=postgresql://[postgres user]:[postgres password]@brew_db:5432/app
- REDIS_HOST=brew_cache
- BREWFATHER_API_KEY=[your brewfather API key]
- BREWFATHER_USER_KEY=[your brewfather USER key]
volumes:
- log:/app/log
depends_on:
- brew_db
- brew_cache
brew_log:
image: mpse2/brewlogger-log
hostname: brew_log
restart: always
environment:
- API_HOST=brew_api
- API_KEY=[your API key for securing access to brew_api]
- MAX_FILE_SIZE=[optional max size of logfiles]
- REDIS_HOST=brew_cache
volumes:
- log:/app/log
networks:
- brew_net
depends_on:
- brew_api
brew_cache:
image: redis:7
hostname: brew_cache
restart: always
networks:
- brew_net
brew_db:
image: postgres:14
hostname: brew_db
restart: always
networks:
- brew_net
volumes:
- pg-data:/var/lib/postgresql/data/pgdata
environment:
- PGDATA=/var/lib/postgresql/data/pgdata
- POSTGRES_SERVER=brew_db
- POSTGRES_USER=[postgres user]
- POSTGRES_PASSWORD=[postgres password]
- POSTGRES_DB=app
brew_pgadmin:
image: dpage/pgadmin4
hostname: brew_pgadmin
restart: always
networks:
- brew_net
environment:
- PGADMIN_DEFAULT_EMAIL=[email for admin login]
- PGADMIN_DEFAULT_PASSWORD=[password for admin login]
ports:
- 5050:80
volumes:
- pgadmin-data:/var/lib/pgadmin
brew_mdns:
image: mpse2/brewlogger-mdns
hostname: brew_mdns
container_name: mdns
restart: always
network_mode: host
privileged: true
environment:
- WEB_HOST=[your published url]
- API_KEY=[your API key for securing access to brew_api]
volumes:
- /var/run/dbus:/var/run/dbus
- /var/run/avahi-daemon/socket:/var/run/avahi-daemon/socket
brew_ble:
image: mpse2/brewlogger-ble
hostname: brew_ble
networks:
- brew_net
restart: always
privileged: true
environment:
- API_HOST=brew_api
- MIN_INTERVAL=[Minimum time in seconds between sending data to API, ie. 300]
- REDIS_HOST=brew_cache
volumes:
- /dev:/dev
- /var/run/dbus:/var/run/dbus
networks:
brew_net:
volumes:
pg-data:
pgadmin-data:
logs:
When posting data from Gravitymon use the following URL's which points to the same API.
- http://[hostname or ip]/ispindel
- http://[hostname or ip]/gravity