Having been trying to make sense of the broadcast packets from the heaters and controllers for a few days it became apparent that I wasn't making much progress. Some small pieces made sense and seemed to point to a structure, but there just wasn't enough to progress my understanding.
Firmware?
When I opened the controller to find the RF chip being used, I noticed a series of 6 through hole pads, marked as X1. Conventionally the X prefix suggests a socket.

There were 6 pins, the 3rd from the top appears to be GND if we assume a ground plane has been used. Given the STMicroelectronics SPIRIT1 being used, would they have also used an STM32? It would have obvious benefits from a development standpoint.
SWD?
The Nucleo development board that I have has an attached ST-LINK with a 6 pin header, labelled CN4.

Pin #3 is GND so this looks like a possible match?
After downloading the ST-LINK software and fashioning a cable to connect the CN4 header to X1 on the PCB it was time to power up the PCB and see what I got.
Bytes
Sure enough, as soon as the controller was powered up and I clicked the connect button in the software, I had access. The flash contents appeared. What I don't know is which of the STM32 family of chips the controller uses as it's hidden beneath the soldered on LCD screen. I can't simply look at the chip for inspiration and the ST-LINK software didn't offer any suggestions.
Before copying the data I experimented with the length to read until I had all the available data included. With that settled I downloaded to a file.
$ hd dump.bin | more
00000000 00 40 00 20 5d f5 00 08 cd f5 00 08 cf f5 00 08 |.@. ]...........|
00000010 d5 f5 00 08 db f5 00 08 e1 f5 00 08 00 00 00 00 |................|
00000020 00 00 00 00 00 00 00 00 00 00 00 00 e7 f5 00 08 |................|
00000030 e9 f5 00 08 00 00 00 00 eb f5 00 08 ed f5 00 08 |................|
00000040 a5 f5 00 08 a5 f5 00 08 a5 f5 00 08 a5 f6 00 08 |................|
00000050 a5 f5 00 08 15 f6 00 08 a5 f5 00 08 29 f6 00 08 |............)...|
00000060 a5 f5 00 08 a5 f5 00 08 51 f6 00 08 a5 f5 00 08 |........Q.......|
00000070 a5 f5 00 08 a5 f5 00 08 a5 f5 00 08 a5 f5 00 08 |................|
00000080 a5 f5 00 08 a5 f5 00 08 19 f6 00 08 a5 f5 00 08 |................|
00000090 a5 f5 00 08 a5 f5 00 08 a5 f5 00 08 5f f6 00 08 |............_...|
000000a0 a5 f5 00 08 a5 f5 00 08 a5 f5 00 08 a5 f5 00 08 |................|
000000b0 a5 f5 00 08 b5 f6 00 08 c9 f6 00 08 a5 f5 00 08 |................|
000000c0 a5 f5 00 08 a5 f5 00 08 a5 f5 00 08 95 f6 00 08 |................|
000000d0 a5 f5 00 08 a5 f5 00 08 a5 f5 00 08 a5 f5 00 08 |................|
000000e0 83 f6 00 08 a5 f5 00 08 a5 f5 00 08 a5 f5 00 08 |................|
000000f0 a5 f5 00 08 00 00 00 00 00 00 00 00 a5 f5 00 08 |................|
00000100 00 00 00 00 00 00 00 00 a5 f5 00 08 a5 f5 00 08 |................|
% file ./dump.bin
./dump.bin: data
Not much help. Maybe binwalk can help?
% binwalk ./dump.bin
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
117308 0x1CA3C PEM RSA private key
117372 0x1CA7C PEM DSA private key
117552 0x1CB30 PEM EC private key
117616 0x1CB70 PEM certificate
119580 0x1D31C AES S-Box
119836 0x1D41C AES Inverse S-Box
122248 0x1DD88 SHA256 hash constants, little endian
This looks more promising. Maybe looking at the strings will reveal more?

-----BEGIN DH PARAMETERS-----MBYCEQC80RK35an+lEkPBY+TKIDzAgEC-----END DH PARAMETERS-----
However they all appear to be empty except for the DH parameter value. They are possibly just standard additions from the STM framework? While looking at the strings output I did find this,
..\\src\\Hal\\src\\HAL_CubeMx.c
which appears to confirm that they used the STM framework to write the firmware.
Can it be disassembled?
% binwalk -Y ./dump.bin
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
226 0xE2 ARM executable code, 16-bit (Thumb), little endian, at least 1587 valid instructions
Running the command again with verbose output gives a lot more detail.
% binwalk -Y -v ./dump.bin
Scan Time: 2023-02-17 12:34:23
Target File: dump.bin
MD5 Checksum: da346f005d15ba3cf4769877e8f2e92e
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
226 0xE2 ARM executable code, 16-bit (Thumb), little endian, at least 1587 valid instructions
226 0xE2 lsrs r0, r0, #0x20
228 0xE4 sub.w r8, r5, #0x800000
232 0xE8 sub.w r8, r5, #0x800000
236 0xEC sub.w r8, r5, #0x800000
240 0xF0 sub.w r8, r5, #0x800000
244 0xF4 movs r0, r0
246 0xF6 movs r0, r0
248 0xF8 movs r0, r0
250 0xFA movs r0, r0
252 0xFC sub.w r8, r5, #0x800000
Now What?
Several articles I have read suggested using IDA to decompile the file contents, but as I'm not planning on using it for more than this project the price is far too high. I did find Binary Ninja which has proven useful and managed to extract the compiler code.

I'm not convinced that the extractions are correct but have very little experience of such things. The controller has been available for a number of years, so it could be that the firmware is similarly older than the tools have been assuming?
Think I need to try and identify the chip I am working with and then track down the datasheet for it. This should help me dump the entrire flash contents and also find the SPI memory addresses that I imagine it uses for communicating with the SPIRIT1.
If anyone with more experince of doing this sort of reverse engineering has any thoughts, I'd be grateful to hear them!