You can do it today with a flow, I did something similar for a boiler with a load forecast.
Have the Pi send the model output as telemetry of the furnace device: {"pred_load_c": 41.0, "pred_conf": 0.83}. In the device’s root flow (or a profile root for the furnace profile), after Save telemetry, add a Script block that computes the offset and a Send command block that sends it. The Script block:
const p = msg.payload;
if (p.pred_load_c === undefined) return null;
const w = Math.min(Math.max((p.pred_conf - 0.5) / 0.4, 0), 1); // 0 below 0.5, 1 above 0.9
const deficit = 850 - p.pred_load_c; // target minus load temp
msg.payload = { offset_c: Math.round(Math.min(deficit * 0.02 * w, 15) * 10) / 10 };
return msg;
Then Send command with a catalog command like furnace.set_ff_offset and params msg.payload. The command goes to the message’s device, which is the furnace’s Pi.
Keep the clamp (15 °C here) and let the Pi refuse anything outside its own limits. For kstewart’s worry: the PID stays on the Pi or the controller; the cloud only suggests an offset, and the Pi should drop it back to 0 after a few minutes without a fresh one.
Mind the plan: each Script block in a deployed flow counts toward your Script blocks limit, and a deploy with a script asks you to type the flow’s name.

