Been using brewblox for some time now. So far it’s been working quite good. The only thing I’m missing is the ability to easily make automated temperature steps for mashing.
Is this still in alpha stage? Any ETA on a stable release? How do I set his up?
There are currently two options: our own automation service, and an integration with Node-RED, both very much in alpha.
We’ll go into more detail during the next release, but we are ending development of our own automation service in favour of integration with Node-RED and/or other low-code platforms.
Our conclusion was that automation functionality is both doable and desirable, but that a custom editor UI is simply not feasible - we estimate the total required effort to be somewhere in the vicinity of “all other Brewblox software combined”.
The good news is that we can now give more priority to development of the Node-RED integration.
The current state of the integration is that block state and change commands are available and documented. To manipulate them you’ll need to inspect / change JS/JSON objects. Node-RED itself implements the timers and start buttons required for mash automation.
If this is not an insurmountable barrier, you can add a service with brewblox-ctl add-node-red. I can make some time to help out with setup.
Are you planning to implement Node-RED somehow into the brewblox UI similar to the alpha automation service you were developing? I’ve been messing around with the automation and was pretty impressed with the integration. I just added the Node-RED service and checked out the 443/node-red page but hope I don’t have to switch between that and the main brewblox ui page during a brew. I’m new to Node-RED and not so much of a programmer, so not really sure how it and brewblox will interface together. Sorry if I’m jumping the gun on upcoming release info.
Yes. We want to avoid UI switches during everyday use (brewing, fermentation). The idea is to use Node-RED to create and edit configuration, and then use the Brewblox integration to start/stop and monitor whatever is happening in Node-RED.
The integration includes:
Brewblox nodes in Node-RED for manipulating blocks
Dashboard widgets to control and monitor Node-RED
Quickstart wizards to generate configuration presets
Just a quick suggestion, based on the extra options and quirks that node-red brings to the table.
How hard would it be for me (knowing some basic programming) to rewrite the Blocks | Brewblox widget/block/module to implement a simple auto-temperature step based on the following:
Waits till PID >= 30° (or close to, lets say 0.5 margin)
Starts timer
Timer goal reached
Sets PID to 40°
Waits till PID >= 40° (0.5 margin)
Starts timer
Timer goal reached
Sets PID to 50°
Waits till PID >= 50° (0.5 margin)
…
So basicly, instead of setting a time, setting a temp value based on a sensor and duration.
Add a basic start/pause/stop to it, this would safe me some timers, user errors and watching my brew.
I guess this function would be a more than welcome addition to brewblox?
The Setpoint Profile block is implemented in the Spark firmware.
Implementation of a target+timer based profile in firmware is on the backlog, but falls below the Spark 4 in priority. We may get around to building it in a service or Node-RED as a temporary / experimental solution.
Development-wise, it’s simpler and less risky to add new features to the UI or the Spark service than it is to change the firmware. Resource-wise, firmware-based features are more efficient and reliable (no network).
Contributions are always very welcome, but firmware changes would not be the easiest point to start from.
First off, thanks for the quick replies on a sunday night.
Any ETA on the adding it to the firmware side? The only other option for me right now is to have a look at implementing this in the UI side I guess? Haven’t had any problems with the brewblox system crashing… so I guess this would be a good way to do it?
I really can’t say. Firmware is Elco’s domain, so firmware and hardware share a dev pipeline. Right now the new board is top priority, and I wouldn’t be surprised if it has some post-release teething issues.
You can’t reliably run independent timers in the UI, because code execution stops when you close the browser.
If you prefer a code-based approach, then a separate service would be a decent option. We have a boilerplate repo for getting up and running. If you prefer a more barebones approach, we also have tutorials for scheduling jobs and interacting with the MQTT eventbus.
Architecture-wise you’re looking at:
get step config from somewhere (REST, MQTT, file, process arguments)
this includes: temperatures, durations, related blocks
get start trigger (or start immediately)
subscribe to spark state events to check actual temp
save a value with “temp target achieved at”
write update to setpoint block when timer expires
If you prefer starting it from the commandline, then the barebones approach may be simpler. If you’d rather have an integration with the UI, then you’ll probably want to use the service boilerplate, and we can set up some UI widget for control/feedback.
Anyone think they can help point me in the right direction on how to change the block states in Node-RED? So far I have the node-red service running and can pull the spark state and block state easily enough, but can’t figure out how to inject changes back into brewblox. The “check block value” and “change block” nodes are where I’m getting lost. Thanks in advance!
I’m working on a short guide for the current implementation (in retrospect, this may have been better done before the release), but there are two ways to save the changed block:
You can use the REST API.
Spark services are accessible as http://{SERVICE_ID} in node-red.
Visit https://{IP_ADDRESS}/{SERVICE_ID}/api/doc in your browser for endpoint documentation.
You can publish changes to the eventbus.
All Spark services listen to the same topic. The serviceId in the block is checked.
We identified a set of nodes that are generic enough to share. You can import them, and then use link in / link out nodes to connect all your custom flows.
Got in touch with Thomas from Brewfather and see how we can have things integrated between Brewfather and Brewblox. From what I understood he is interested. He suggested to first start with the REST API they provide, grab recipe and have automation service operational and then get back to him to see how we could setup hooks to update Brewfather. Sounds like a plan.
Yesterday I started diving into service creation using the boilerplate. Looks like I am ready to start some code now.
Several questions though to sync with current state on your side folks:
has someone already implemented a brewfather REST client within a service or a barebone python script?
the way Nodered integration is planned (didn’t do the update and tested yet) seems like the work to be done is to :
query brewfather to get mash steps JSON array
translate batch recipe into NodeRed flow (using nodered service?) including periodic status report back to brewfather and command hooks for brewfather to force flow progress or update flow
It would work (you can set up http endpoints in node-red itself), but then you have to expose and secure the endpoint.
You’d also have to implement either an authentication mechanism, or some sort of manual review/confirmation to avoid exposing hardware control to a public endpoint.
I was thinking of using exposed brewblox services and route to this feature eventually. So that we benefit directly from security from the whole system. Publicly exposing endpoints from a Nodered http endpoint seems like a bad idea, I agree.
Wouldn’t all endpoint-based solutions suffer from the same problem, regardless of what service provides the listener?
If configuration data is submitted to a public API, there always needs to be some kind of client verification. You could add JWT/bearer tokens to the payload, but this would require support on the Brewfather side.
fiddling around with node-red integration got me thinking further of the approach. This post might get long so bear with me.
For me there are two ways of working Brewfather automation. WAY 1
One way is to say if we want to achieve automation we can do it in a very generic way using node-red. This means you can setup a flow which sends MQTT message to set blocks values at the right moment and listen for blocks to drive the logic. Basically this means:
I load a recipe (ie mash steps) in the nodered context,
loop/wait for a trigger to start mash
send MQTT to set MLT block temperature setpoint
listen MQTT to get a specific block value (for instance MLT sensor temp value)
when reached start timer
when timer is at the end, process with mash step 2 and so on
this will leave people with maybe ready made subflows to query Brewfather API and extract useful payload to have mash steps and then have another ready made subflow that conducts the automated steps mentioned before.
This means we could simply do almost everything in node-red and I ‘just’ contribute a set of nodered JSON flows and eventually create some UI widget to query recipes from brewfather, select the recipe to launch and start/stop the nodered automation flow.
WAY2
have a code approach and do all things above, straight in code, packed in a service. This basically means that automation logic will be specific to brewfather integration and tightly coupled. IMHO this second approach is cleaner, more robust and less error prone but it comes with the drawback that things achieved in this service for achieving automation won’t be generic. Or we could split this in two parts: one automation service with a predefined logic waiting for mash steps and timers and a second service achieving the third party specific communication.
additional note: for WAY1 I discovered we could even have the UI to fetch recipes and interact with brewfather directly from a nodered dashboard. I did a quick test and it works.
For this kind of functionality, the whiteboard / pen and paper design stage is about 90% of the work, regardless of implementation.
A block for bare-bones mash steps (set temp, reach temp, wait time) is pretty high on the backlog. This means some sort of split between direct step control and the other functionality is probably a good idea, as the former is likely to be made redundant.
A valid strategy may be to start with a dedicated service, and then iteratively extract the parts that can be made generic.
We also do have a Slack channel we use for more granular discussions. If you want I can send you an invite for that.