Giter VIP home page Giter VIP logo

boozer's Introduction

boozer - Kegerator Monitoring Platform

 ____   ___   ___ __________ ____
| __ ) / _ \ / _ \__  / ____|  _ \
|  _ \| | | | | | |/ /|  _| | |_) |
| |_) | |_| | |_| / /_| |___|  _ <
|____/ \___/ \___/____|_____|_| \_\


+---------------+--------------+--------+
|      File     |   Filepath   | Exists |
+---------------+--------------+--------+
|    Database   | ./db.sqlite  |  True  |
| Configuration | ./config.ini |  True  |
+---------------+--------------+--------+
+-------------+---------+
|   Feature   |  Status |
+-------------+---------+
|   Twitter   | enabled |
|     Mqtt    | enabled |
| Temperature | enabled |
|    Slack    | enabled |
|  Scrollphat | enabled |
+-------------+---------+
+-----+------------+--------------------+----------+------------------+
| Tap |    Beer    | Capacity (Gallons) | GPIO Pin | Volume Remaining |
+-----+------------+--------------------+----------+------------------+
|  1  | Test Batch |         5          |    13    |      83.149      |
|  2  | Custom IPA |         5          |    14    |      100.00      |
|  3  | Coors      |         5          |    15    |      100.00      |
|  4  | Seltzer    |         5          |    16    |      0.00        |
+-----+------------+--------------------+----------+------------------+
+----------+-----------+
|   Key    |   Value   |
+----------+-----------+
| influxdb |  enabled  |
| database |   boozer  |
|   host   | texas.lol |
|   port   |   31132   |
| username |    None   |
| password |    None   |
+----------+-----------+
+------------+------------+
|  MQTT-Key  | MQTT-Value |
+------------+------------+
|   broker   | texas.lol  |
|    port    |   31353    |
| Connected? | Connected  |
+------------+------------+
+-------------+-------------+
|    Sensor   | Temperature |
+-------------+-------------+
| temperature |   38.175ยฐ   |
+-------------+-------------+
2019-05-30 10:55:23,545 flowmeter    INFO     Boozer Intialized! Waiting for pours. Drink up, be merry!
2019-05-30 10:56:25,554 influxdb_client INFO     Influx update pushed. temperature = 37.6134

What is boozer

Kegerator monitoring/volume tracking platform writting in Python.

  • Track the remaining beer volume of your kegs! Flow sensors keep a running log of your remaining beer volume, using SQLITE.
  • Slack & Twitter functionality. Sharing is caring.
  • Temperature Monitoring via ds18b20 GPIO sensor or sensors2json microservice/REST
  • IoT functionality with MQTT/Mosquito and InfluxDB.

Support update:

Boozer is now longer in active development but can be used as the basis of new development projects.

Version 2

  • Complete rewrite
  • 1-10 flowsensors are now supported
  • Custom keg sizes are now supported (5gal, 10gal, etc)
  • You can now push metrics directly to InfluxDB and MQTT
  • Enhanced UI with configurable verbosity. No more guessing your configuration.
  • Temperature sensing can now be done via a GPIO sensor or via a REST call.
  • Keg volumes can now be reset without the toolkit
  • New docker image. bgulla/boozer->boozerbar/boozer
  • New plug-in supported architecture.
  • There are breaking changes. Be sure to convert your configuration to match the new schema.

Supported Notification Platforms

Boozer can tweet out whenever a new pour event is detected. The following notification platforms are supported:

  • Slack (webhook) Slack
  • Twitter (oauth)
  • Untappd Auto-Posting. (I broke this, hoping to fix it soon)

Supported Monitoring Platforms

  • InfluxDB
  • MQTT/Mosquitto

Hardware

The following hardware was used in the inital build of boozer but not necessarily required.

Pouring in motion Breadboard

Running in Docker

Simplify deployment with Docker. Instructions for installing docker on RaspberryPi's here. Works in Kubernetes, if you're into the whole distributed computing thing. This assumes you have a beginner-level knowledge of Docker.

docker run --rm  -d --name="boozer" \
    --privileged \
    -v </path/to/config.ini>:/boozer/config.ini \
    -v </path/to/db.sqlite>:/boozer/db.sqlite \
    -t boozerbar/boozer

Home-Assistant

boozer in home-assistant

Add the following to your configuration.yaml file.

mqtt:
  broker: <mqtt_host>
  port: <mqtt_port>
sensor:
  - platform: mqtt
    state_topic: "bar/tap1/value"
    name: "Boozer Tap1"
  - platform: mqtt
    state_topic: "bar/tap1/beverage"
    name: "Boozer Tap1 beverage"
  - platform: mqtt
    state_topic: "bar/tap2/value"
    name: "Boozer Tap2"
  - platform: mqtt
    state_topic: "bar/tap2/beverage"
    name: "Boozer Tap2 beverage"
  - platform: mqtt
    state_topic: "bar/tap3/value"
    name: "Boozer Tap3"
  - platform: mqtt
    state_topic: "bar/tap3/beverage"
    name: "Boozer Tap3 beverage"
  - platform: mqtt
    state_topic: "bar/tap4/value"
    name: "Boozer Tap4"
  - platform: mqtt
    state_topic: "bar/tap4/beverage"
    name: "Boozer Tap4 beverage"

Configuration Sample

[Boozer]
minimum_pour_vol: 0.075 # Used for testing
logging_level: INFO

[Taps]
tap1_gpio_pin: 13
tap1_beer_name: Test Batch
tap1_gallon_capacity: 5
tap2_gpio_pin: 14
tap2_beer_name: Manor Hill Friends Dont Shake Hands
tap2_gallon_capacity: 5
tap3_gpio_pin: 15
tap3_beer_name: Banquet Beer
tap3_gallon_capacity: 5
tap4_gpio_pin: 16
tap4_beer_name: Seltzer
tap4_gallon_capacity: 5

[Slack]
enabled:True
webhookurl: https://hooks.slack.com/services/<redacted>

[Temperature]
enabled: True
sensor_protocol: ds18b20
#sensor_url: http://10.0.1.48:8888/chillerf
#endpoint: http://10.0.1.48:8888/chillerf

[Twitter]
enabled: True
consumer_key="redacted"
consumer_secret="redacted"
access_token="1549176829-redacted"
access_token_secret="redacted"

[Mqtt]
enabled: True
broker: mqtthost.lol
port: 31353
#username: foo
#password: bar


[Logging]
file: /tmp/beer.log

[Scrollphat]
enabled: True

[Influxdb]
enabled: True
host=influxhost.lol
port=8086

Toolkit

๐Ÿบ  pi@bar[/opt/boozer] >docker exec -ti boozer python /boozer/toolkit.py -h
usage: toolkit.py [-h] [--reset-tap RESET_TAP_ID] [--printval] [--temp]
                  [--mqtt]

Example with long option names

optional arguments:
  -h, --help            show this help message and exit
  --reset-tap RESET_TAP_ID, -t RESET_TAP_ID
                        Reset the database value for a tap
  --printval, -p        print all tap volumes
  --temp                print the temperature values
  --mqtt, -m            update the tap values in mqtt broker
  --scrollphat, -s      Test the functionality of the SCROLLPHAT display.

Print Remaining Keg Volumes

๐Ÿบ  pi@bar[/opt/boozer] > docker exec -it boozer python /boozer/toolkit.py --printval
Loaded config...
        Database file:  /boozer/db.sqlite
----------------------------------------------------
        Tap 1 | 100.0 remaining
        Tap 2 | 100.0 remaining
        Tap 3 | 100.0 remaining
        Tap 4 | 100.0 remaining

Force-Update MQTT Broker

๐Ÿบ  pi@bar[/opt/boozer] > docker exec -it boozer python /boozer/toolkit.py --mqtt
Loaded config...
        Database file:  /boozer/db.sqlite
----------------------------------------------------
[MQTT] updated tap 1
[MQTT] updated tap 2
[MQTT] updated tap 3
[MQTT] updated tap 4

Reseting Taps

The time will come to change out your kegs and rather than editing sqlite directly, use the toolkit script to reset your keg volume available to 100%.

๐Ÿบ  pi@bar[/opt/boozer] >docker exec -ti boozer python /boozer/toolkit.py --reset-tap 1
Loaded config...
	Database file:	/boozer/db.sqlite
----------------------------------------------------
current [Tap 1 ] 0.00 remaining
Are you sure that you reset tapid: 1 (y/n): y
Record: Tap 1 Volume 0
Reset Tap  1
updated! [Tap 1 ] 1.0 remaining

protip: another way to reset the tap val to 100% without the toolkit is to add tap1_reset_database:True to the taps configuration. NOTE: you will need to remove the line after starting boozer or your tap value will reset every time boozer is restarted.

Displaying Stats in Grafana

With a little help from Telegraf (or directly with v2) and the Mqtt message broker, bar stats are viewable in real time with Grafana.

Grafana is awesome

Build Pictures

Photos of the bar making process are available here.

FAQs

Most of your questions can probably be answered in the reddit post or the Hackaday feature.

Press:

Updates

  • 5-30-2019: v2 is live
  • 5-22-2018: Temperature sensors are now optional.
  • 7-1-2018: Toolkit functionality finally documented. Reset tap db values and more.
  • 3-2019: new docker image (boozerbar/boozer). new console logging. more flexible config.

The Bar That Started It All

boozer's People

Contributors

bgulla avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

boozer's Issues

No image after running docker command

copied both config.ini and db.sqlite to /opt/boozer

ran as

sudo docker run --rm  -d --name="boozer" \
    --privileged \
    -v /config.ini:/boozer/config.ini \
    -v /db.sqlite:/boozer/db.sqlite \
    -t bgulla/boozer

now when i do sudo docker ps, nothing is showing, no image for bgulla/boozer :(

Make the number of taps dynamic

As of right now, boozer expects 4 taps to be present. I need to make it where it iterates the entries in the config file and dynamically builds the expected tap structure.

level of effort: low.

Only able to work with 4 taps

Hello,
There seems to be something missing to add more than 4 taps. I tried to modify the beer_db.py to add it there but I still get the following error:
2020-04-12 20:16:07,530 root INFO Tap 1: Setting capacity to 5
2020-04-12 20:16:07,537 bar_mqtt INFO mqtt topic updated: topic: bar/tap1/value | value: 100.0
2020-04-12 20:16:07,542 bar_mqtt INFO mqtt topic updated: topic: bar/tap1/beverage | value: Cidre
2020-04-12 20:16:07,544 root INFO Tap 2: Setting capacity to 5
2020-04-12 20:16:07,550 bar_mqtt INFO mqtt topic updated: topic: bar/tap2/value | value: 100.0
2020-04-12 20:16:07,556 bar_mqtt INFO mqtt topic updated: topic: bar/tap2/beverage | value: Blanche
2020-04-12 20:16:07,558 root INFO Tap 3: Setting capacity to 5
2020-04-12 20:16:07,563 bar_mqtt INFO mqtt topic updated: topic: bar/tap3/value | value: 100.0
2020-04-12 20:16:07,569 bar_mqtt INFO mqtt topic updated: topic: bar/tap3/beverage | value: Erable
2020-04-12 20:16:07,571 root INFO Tap 4: Setting capacity to 5
2020-04-12 20:16:07,577 bar_mqtt INFO mqtt topic updated: topic: bar/tap4/value | value: 99.015
2020-04-12 20:16:07,582 bar_mqtt INFO mqtt topic updated: topic: bar/tap4/beverage | value: NEIPA
2020-04-12 20:16:07,584 root INFO Tap 5: Setting capacity to 5
Traceback (most recent call last):
File "boozer.py", line 525, in
main()
File "boozer.py", line 520, in main
boozer = Boozer()
File "boozer.py", line 259, in init
self.update_mqtt(tap, beverage_name=new_tap.get_beverage_name())
File "boozer.py", line 286, in update_mqtt
percent = self.db.get_percentage100(tap_id)
File "/boozer/beer_db.py", line 61, in get_percentage100
return self.get_percentage(tap_id) * 100
File "/boozer/beer_db.py", line 50, in get_percentage
volume_expelled = self.get_tap(tap_id)
File "/boozer/beer_db.py", line 111, in get_tap
return volume
UnboundLocalError: local variable 'volume' referenced before assignment

Pour Event always for tap4 even when using other flow meter

Hello,
I have kept (and reverted to default configuration) to 4 taps. Each pour is detected to be coming from tap 4. I know that I used the right GPIO (as now that I reverted to default configuration and files the 5 taps is not triggering the counter anymore). So there seems to be something in the flow_meter.py.

Anyone can help me?
Thanks!
Fred
2020-04-13 13:22:23,885 flowmeter INFO --- REGISTERING-FULL-POUR 0.848888888889 vs 0.075
2020-04-13 13:22:23,888 flowmeter INFO POUR this pour was 0.0 pints (thisPour=0.0 vs totalPour=0.848888888889
Record: Tap 4 Volume 9.144 Percentage: 77.14
2020-04-13 13:22:23,926 flowmeter INFO Database updated: 4 1.794.
2020-04-13 13:22:23,937 bar_mqtt INFO mqtt topic updated: topic: bar/tap4/value | value: 77.14
2020-04-13 13:22:23,945 bar_mqtt INFO mqtt topic updated: topic: bar/tap4/beverage | value: NEIPA
2020-04-13 13:22:23,948 flowmeter INFO Pour processing complete. Reseting pour of tap 4 amount to 0.0
2020-04-13 13:23:13,071 influxdb_client INFO Influx update pushed. temperature = 73.7366
2020-04-13 13:24:14,910 influxdb_client INFO Influx update pushed. temperature = 73.625
2020-04-13 13:25:16,750 influxdb_client INFO Influx update pushed. temperature = 73.625

Alway registering from last tap in the array

Hello,

I have re-installed everything and still each time last tap is registering the pour. So it will always come from tap 5 as I have 5 taps.

I have modified the code as I am not good with python and objects. So it's a bit ugly but it works for 5 taps. So there's something with the GPIO.add_event_detect that refers always to the last object initialized. I tried both in the docker container and running it from the PI outside the docker container.

There is still little things with the toolkit with hardcoded number of tap to 4 but that's an easy fix.

I replaced this:

for tap in self.taps: # setup all the taps. add event triggers to the opening of the taps.

GPIO.add_event_detect(tap.get_pin(), GPIO.RISING, callback=lambda *a: self.register_tap(tap), bouncetime=20)

By this for 5 taps. But it's not really clean and I do not know how to fix previous function.
tap=self.taps[0]
GPIO.add_event_detect(tap.get_pin(), GPIO.RISING, callback=lambda a: self.register_tap(self.taps[0]), bouncetime=20)
tap=self.taps[1]
GPIO.add_event_detect(tap.get_pin(), GPIO.RISING, callback=lambda a: self.register_tap(self.taps[1]), bouncetime=20)
tap=self.taps[2]
GPIO.add_event_detect(tap.get_pin(), GPIO.RISING, callback=lambda a: self.register_tap(self.taps[2]), bouncetime=20)
tap=self.taps[3]
GPIO.add_event_detect(tap.get_pin(), GPIO.RISING, callback=lambda a: self.register_tap(self.taps[3]), bouncetime=20)
tap=self.taps[4]
GPIO.add_event_detect(tap.get_pin(), GPIO.RISING, callback=lambda a: self.register_tap(self.taps[4]), bouncetime=20)

Config for flow meter calibration per tap

Hello,
Nice work! It would be really nice to have a configuration variable for the calibration per tap. For now I modified the number of pulses according to my flow meter but it would be nice to have it in the configuration file and per tap to support different flow meter and to calibrate them individually.
Thanks!
Fred

Config option for metric/imperial

Would it be possible to add a option to the config.ini to select either imperial or metric units. I'd rather have it in celcius and maybe liters for volume.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.