Brewblox / Automation

Yes sure thing. Much easier.

I started playing around with node-red for automation in recent days after I stumbled upon this thread here.
I already managed to read out the MQTT messages from the brewblox service but for changing something in brewblox, I could use a little push in the right direction.
I had a look at Bob’s brewblox-reusable-flows.json as well as at the brewblox blocks in the brewblox/node-red container. But I still have no clue on how I actually have to compose the JSON-message to let’s say raise the target temperatur of a setpoint or to toggle a pump…

Has anybody some examples to share on that topic?

Thanks and kind regards

For this, it’s useful to know how specific blocks look like. Block data documentation can be found at Block data types | Brewblox

To set block fields to a constant value, add the following nodes:

  • Inject
  • Link out

In the Inject node, set msg.payload to be a JSON object:

    "serviceId": "spark-sim",
    "id": "HERMS BK Setpoint",
    "data": {
        "settingEnabled": true,
        "storedSetting": {
            "__bloxtype": "Quantity",
            "unit": "degC",
            "value": 60

Connect the Inject node to the Link out node, and link the Link out node to Patch block from the reusable flows.

Node-Red export:

[{"id":"60493c07.00cc94","type":"tab","label":"Flow 1","disabled":false,"info":""},{"id":"f7426d32056d54ab","type":"inject","z":"60493c07.00cc94","name":"Enable setpoint","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"serviceId\":\"spark-sim\",\"id\":\"HERMS BK Setpoint\",\"data\":{\"settingEnabled\":true,\"storedSetting\":{\"__bloxtype\":\"Quantity\",\"unit\":\"degC\",\"value\":60}}}","payloadType":"json","x":670,"y":240,"wires":[["576812e87f548bfe"]]},{"id":"576812e87f548bfe","type":"link out","z":"60493c07.00cc94","name":"","links":["64059918.357d18"],"x":835,"y":240,"wires":[]}]

If you need to make a change based on the current block state (eg. toggle enabled), you need to read the block, edit it, and write the changes.
This can be done by getting it from the cache, or explicitly reading it. The second is somewhat simpler, so we’ll use that as example.

Add the following nodes:

  • Inject
  • HTTP request
  • Function
  • Link out

The Inject node sets the payload for the HTTP request node:

    "serviceId": "spark-sim",
    "id": "HERMS BK Setpoint"

The HTTP request node sends a POST request to http://spark-sim:5000/spark-sim/blocks/read (the internal address for the service), and parses the response as JSON.

The Function node edits msg.payload to whatever you want it to be.
In this example, we just toggle the settingEnabled field.

const data =;
data.settingEnabled = !data.settingEnabled;
return msg;

The Function node should be connected to the Link out node to send the block update back to the service.
Because this is a full block (and not just the fields we want changed), we can link the Link out node to Write block from the reusable flows.

Node-Red export:

[{"id":"f3401d5ed8270c60","type":"tab","label":"Flow 2","disabled":false,"info":""},{"id":"3d5f64d9f6660893","type":"inject","z":"f3401d5ed8270c60","name":"trigger","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"serviceId\":\"spark-sim\",\"id\":\"HERMS BK Setpoint\"}","payloadType":"json","x":250,"y":300,"wires":[["557afd7a17edd99f"]]},{"id":"557afd7a17edd99f","type":"http request","z":"f3401d5ed8270c60","name":"read block","method":"POST","ret":"obj","paytoqs":"ignore","url":"http://spark-sim:5000/spark-sim/blocks/read","tls":"","persist":false,"proxy":"","authType":"","x":450,"y":300,"wires":[["993a09efe400adc2"]]},{"id":"993a09efe400adc2","type":"function","z":"f3401d5ed8270c60","name":"toggle settingEnabled","func":"const data =;\ndata.settingEnabled = !data.settingEnabled;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":680,"y":300,"wires":[["5716b0175b483043"]]},{"id":"5716b0175b483043","type":"link out","z":"f3401d5ed8270c60","name":"","links":["a7877bde.d857f8"],"x":855,"y":300,"wires":[]}]

Thanks, Bob, exactly what I needed… I will give it a try…

Hi everybody,

I’m listening in here since I’m looking into node red automation of BrewBlox as well.

Could any of you post a full export of your node-red flows here as a starting point for us newcomers? I know they won’t work out of context when I import them. But they provide context and a starting point ubtil we have a basic getting started guide.

I’m also curious to know how you’ve setup the step automation in node red in practicality - there are as far as I am aware many ways to do that in node red.

Best regards & thanks in advance,
// Troels :slight_smile:

Hi , im trying to publish some values from a pressure sensor via node red to Brewblox . I have already test your Injection node for change temperature values and its work fine . But now i want to publish a realtime value witch change constantly . Can you please help me with a example .

Thanks Andi

What is the additional step that’s causing problems? Reading the sensor?

Reading the Sensor is no Problem , but i want to publish the Sensor value to Brewblox to show it graphically , like its done whit Tilt hygrometer. I need to know how the JSON object have to look like and which node a have to add to have a constantly changing value.

If you want to track the values in a graph or metrics widget, then the relevant documentation is Publishing history data | Brewblox.

Node-wise, I’d use a function node to transform data, then a MQTT out node to publish to brewcast/history/my-sensor-name.
The chain would be inject (repeated) → read sensor → transform → MQTT out.

Looking forward to use the new “Sequence block”.

Any news on when this release will be rolled out? Or is it safe to upgrade right now?

The release date is “any moment now”. All features are present, and we ran verification tests yesterday.

This yielded two bugs:

  • Under specific circumstances, fast PWM in channel 2 would be slaved to fast PWM in channel 1.
  • The mutex would ignore the (deprecated) default lock out time, but not the per-constraint lockout.

We’re fixing these, will shake the changes some more, and if no more bugs fall out, push the release live.


Is there any new guide on how to use node red?

What kind of guide would you be looking for? Installation, basic use, recipes?

With the introduction of the patch endpoint in the spark service API, there’s little added value to the dedicated brewblox plugin. Node-red is still useful, but you can interact with the REST/MQTT API using the default nodes.

Yeah looking to do some automation like temperature alarms and change setpoint temperature of the controller, so we better interact with REST/MQTT?

I’ll make a note to write a tutorial for how to interact with the system using node-red. I can probably squeeze that in while preparing the upcoming release.

The short version:

  • To update spark block settings (setpoints etc), you can use the Spark service REST API.
  • To listen for block changes, you can subscribe to the periodic (5s) broadcast of Spark service state. This is a JSON object that includes generic service state and all blocks.
  • You can find the documentation for the service state broadcast at Spark service state | Brewblox
  • The service API endpoints documented using Swagger. To access it, navigate to {address}/{service name}/api/doc. Some more context is provided at Spark blocks API | Brewblox
  • You can find the data types for individual blocks at Block data types | Brewblox.

A quick example of a function node that gets the value of a specific sensor from brewcast/state messages:

1 Like

Thanks a lot looking forward your guide!, maybe with some practical examples we can start experimenting. Can I also interact with the Tilt?

Yes. The Tilt service publishes data to brewcast/state/tilt/{color}/{mac} for each connected Tilt device. It looks like the type documentation for it is unfinished, but the typing for the JSON object is:

export interface TiltStateEvent {
  key: string; // Service ID
  type: 'Tilt.state';
  timestamp: number; // ms date
  color: string;
  mac: string;
  name: string;
  data: {
    'temperature[degF]': number;
    'temperature[degC]': number;
    specificGravity: number;
    'rssi[dBm]': number;
    'plato[degP]': number;

    // Present if calibration values are provided
    'uncalibratedTemperature[degF]'?: number;
    'uncalibratedTemperature[degC]'?: number;
    uncalibratedSpecificGravity?: number;
    'uncalibratedPlato[degP]'?: number;
1 Like

Thanks looking this up.

I added the tutorials. They’ll be pushed to with the next release, but they’re already available for preview at:

1 Like