BrewBlox Tilt Service

Disclaimer: what you are proposing has significant reliability issues. Any network calls in the input/process/output loop are points of failure. So far the Tilt’s bluetooth connection has proven especially fickle.
That said, we also recommend doing whatever you like in your own code =)

Your proposal requires both a backend service, and a UI plugin.

The service would be responsible for reading the Tilt, and writing to the Spark service. (Anything that must continue happening when you close the UI). You can also split reading/writing between @j616s service, and yours.

The UI plugin can be used to configure your service.

The service can register REST endpoints that are reachable from both the UI, and other backend services. You make them accessible from the UI by declaring a PathPrefix label in your docker-compose.yml so the Traefik service can forward http requests.

You can also send block updates to the REST API of the Spark service. To view the spec for the Spark API, go to https://<pi_address>/spark-one/api/doc.

This same endpoint is reachable from your service as http://spark-one:5000/spark-one/api/doc.

The client code for the Spark can be found here:

To consume data from your service in your UI plugin, you have three options:

  • publish data to the eventbus, and view in graph/metrics widgets.
    • this is useful for values, less so for configuration, and useless for strings.
  • poll the backend service every few seconds / manually.
    • simple, but clunky.
  • implement an SSE endpoint in your service endpoint.
    • nicer than polling, but more complicated.

Personally I’d first build a polling version, and maybe switch to SSE somewhere down the line.

The block you’re interested in would be https://github.com/BrewBlox/brewblox-ui/blob/develop/src/plugins/spark/features/TempSensorMock/types.ts.

A typical update is to read the block, set the data/value property, and write the changed block.

I’d heavily advise against using the Tilt’s temp to drive ferm schedules. In my experience, the Tilt is nowhere near reliable enough. I still think triggering progression through steps based on SG is useful as long as there’s a method of triggering manually as backup. After all, some method of measuring SG is better than no method. But the wired sensors are far better at the job of reading temp.

1 Like

I second the opinion against using the Tilt temperature or SG as input to fermentation control, for these reasons at minimum:

  1. Tilt temperature readings lack the necessary scale. Tilt’s temp accuracy is quoted as +/- 1 degrees F, and I’m not sure of its resolution (how many digits to the right of the decimal), but your Tilt might be reporting 73F when the true temp is 1+ degrees from that.
  2. you can’t control where the Tilt floats. In my case (stainless conical) there is an appreciable temp diff between the liquid right next to the wall of the fermenter vs. in the middle of it, especially during a ramp up or down. And in reality it’s the temp at the midpoint of the liquid, well below the surface, that I’m interested in which is why I depend on a OneWire sensor in a thermowell.
  3. the Tilt doesn’t always freely float. I’ve had dry hop bags cause it to read values 10 or more gravity points above or below what a hydrometer sample tells me. And there is ongoing debate about how much impact there is on a Tilt from the krausen and other stuff also floating at the top of a fermentation.
  4. similar to the above point, during active fermentation the Tilt shows a lot of fluctuation in its SG readings (due to CO2 bubbles and other floaties?). If you’re dependent on SG for process control, and readings are fluctuating right on the edge of some control point, your process could fluctuate as well if you don’t smooth out the noise (like the ‘D’ in a PID algorithm).
1 Like

@j616s

Havin an issue where data is not being shown on the tilt service.

tilt_1 | 2020-02-14T12:35:27.504683562Z 2020/02/14 12:35:27 ERROR brewblox_tilt Error when publishing data ConnectionRefusedError(111, "Connect call failed ('172.17.0.1', 5672)")

https://termbin.com/0hst

Any suggestions

Initial errors seem normal: it complains until the eventbus is done starting up. Does it also not send data after that?

Yep and the errors keep on going.

Its the same on my setup as well as the one I posted earlier. I’ll post new logs from each of them so you can see.

https://termbin.com/yp93
and
https://termbin.com/aw4e

Oh, I think I get it. Tilt is running host mode, and need an eventbus port published. That’s an edit in a file we just reset.

Try adding the docker-compose.override.yml file, with content:

services:
  eventbus:
    ports:
      - "5672:5672"

have added file with the contents

but still same error:

https://termbin.com/t5212

Could you please run docker-compose config? That should show if it correctly interpreted the override.

After that, you can also fix it by setting the ports config entry in docker-compose.shared.yml

This will break next update, unless you update with --no-copy-config

Edit: the best solution is to edit docker-compose.yml, and add the following entry under services:
(indented two spaces)

  eventbus: { ports: ["5672:5672"] }
1 Like

So looks like its not being interpreted correctly.

Output of docker-compose config.

I’ll add it to the other file. and let you know.

  datastore:
    image: treehouses/couchdb:2.3.1
    labels:
      traefik.frontend.rule: 'PathPrefixStrip: /datastore'
      traefik.port: '5984'
    restart: unless-stopped
    volumes:
    - /home/pi/brewblox/couchdb:/opt/couchdb/data:rw
  emitter:
    image: brewblox/brewblox-emitter:rpi-edge
    labels:
      traefik.frontend.rule: 'PathPrefix: /emitter'
      traefik.port: '5000'
    restart: unless-stopped
  eventbus:
    image: arm32v6/rabbitmq:alpine
    restart: unless-stopped
  history:
    image: brewblox/brewblox-history:rpi-edge
    labels:
      traefik.frontend.rule: 'PathPrefix: /history'
      traefik.port: '5000'
    restart: unless-stopped
  influx:
    environment:
      INFLUXDB_DATA_INDEX_VERSION: tsi1
      INFLUXDB_DATA_WAL_FSYNC_DELAY: 1s
      INFLUXDB_HTTP_LOG_ENABLED: "false"
      INFLUXDB_LOGGING_LEVEL: warn
    image: influxdb
    restart: unless-stopped
    volumes:
    - /home/pi/brewblox/influxdb:/var/lib/influxdb:rw
  mdns:
    command: --port=5000
    image: brewblox/brewblox-mdns:rpi-edge
    network_mode: host
    restart: unless-stopped
  spark-one:
    command: '--name=spark-one --mdns-port=5000

      '
    depends_on:
    - datastore
    - eventbus
    image: brewblox/brewblox-devcon-spark:rpi-edge
    labels:
      traefik.frontend.rule: 'PathPrefix: /spark-one'
      traefik.port: '5000'
    privileged: true
    restart: unless-stopped
  tilt:
    command: -p 5001 --eventbus-host=172.17.0.1
    depends_on:
    - history
    image: j616s/brewblox-tilt:rpi-latest
    network_mode: host
    privileged: true
    restart: unless-stopped
    volumes:
    - /home/pi/brewblox/tilt:/share:rw
  traefik:
    command: '-c /dev/null --docker  --docker.domain=brewblox.local --entrypoints=''name:http
      Address::80 Redirect.EntryPoint:https'' --entrypoints=''name:https Address::443
      TLS:config/brewblox.crt,config/brewblox.key'' --defaultentrypoints="http,https"

      '
    image: traefik:v1.7
    ports:
    - 80:80/tcp
    - 443:443/tcp
    restart: unless-stopped
    volumes:
    - /home/pi/brewblox/traefik:/config:rw
    - /var/run/docker.sock:/var/run/docker.sock:rw
  ui:
    image: brewblox/brewblox-ui:rpi-edge
    labels:
      traefik.frontend.rule: Path:/, /ui, /ui/{sub:(.*)?}
      traefik.port: '80'
    restart: unless-stopped
version: '3.0'

Ok so worked in the other file. However I cannot check any of the items in the list, including the Spark-one items. As you can see they have all unticked themselves.

We pushed a fix for that a few hours ago. Run docker-compose pull to get it.

Thanks Bob, That’s working now.

Great support as usual.

Since the last brewblox update I am having issues with my tilt. According to the Logs the tilt is found but the data cannot be published for some reason. Anybody an idea why?

Scroll up a bit for the answer =)

The solution for now is to edit docker-compose.shared.yml and add the “ports” entry to the eventbus. See https://github.com/j616/brewblox-tilt#or-deploy-the-tilt-service-on-the-brewblox-stack for more info.

Edit: the best solution is to edit docker-compose.yml, and add the following entry under services:
(indented two spaces)

  eventbus: { ports: ["5672:5672"] }

Oh haha I didn’t see that post. It worked, Thanks!

OK, so I tried to get this working again, but it does not seem to be working again for me. I did a clean configuration of Brewblox, got the Tilt service set up, it was working for a short period, then stopped again.

Just ran update again today to make sure everything up to date.

Tilt not logging - and when i go to try to add metrics, the Tilt is not showing as available to select - only the Spark. I tried the steps Bob pointed to in order to install on the stack (I had previously just used the install script for Tilt).

Logs are here: https://termbin.com/2prqr

Running docker logs brewblox_tilt_1 just gives a series of repeated messages like this:

2020/03/09 16:56:47 INFO     brewblox_service.service        Creating [tilt] application
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "/usr/local/lib/python3.7/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/usr/local/lib/python3.7/site-packages/brewblox_tilt/__main__.py", line 28, in <module>
    main()
  File "/usr/local/lib/python3.7/site-packages/brewblox_tilt/__main__.py", line 18, in main
    tiltScanner.setup(app)
  File "/usr/local/lib/python3.7/site-packages/brewblox_tilt/tiltScanner.py", line 39, in setup
    features.add(app, TiltScanner(app))
  File "/usr/local/lib/python3.7/site-packages/brewblox_tilt/tiltScanner.py", line 238, in __init__
    self.messageHandler = MessageHandler()
  File "/usr/local/lib/python3.7/site-packages/brewblox_tilt/tiltScanner.py", line 120, in __init__
    self.sgCal = Calibrator(SG_CAL_FILE_PATH)
  File "/usr/local/lib/python3.7/site-packages/brewblox_tilt/tiltScanner.py", line 46, in __init__
    self.loadFile(file)
  File "/usr/local/lib/python3.7/site-packages/brewblox_tilt/tiltScanner.py", line 63, in loadFile
    uncal = float(line[1].strip())
IndexError: list index out of range

I have a tilt/SGCal.csv file with the following contents:

black, 1.002, 1.000
black, 1.089, 1.095
black, 1.073, 1.077
black, 1.063, 1.066
black, 1.047, 1.053
black, 1.036, 1.043
black, 1.029, 1.034
red, 0.997, 1.000
red, 1.098, 1.095
red, 1.071, 1.077
red, 1.059, 1.066
red, 1.047, 1.053
red, 1.037, 1.042
red, 1.027, 1.034

Any ideas what I am doing wrong?

Thanks,
Jerry

This could be caused by an empty line at the end of your calibration CSV file (or anywhere in the file)

Well, thanks for that. There was a blank line after the entries. This has been removed and this is working now!

A bit strange that this would cause the BrewBlox from reading values from the Tilt. I will monitor and see how it goes.

This fixed the same issue for me thanks @Bob_Steers