In looking through the docs and the example virtual thermostat source I cannot find any explanation about what the difference is for heatingSetpoint vs thermostatSetpoint for the Thermostat capability, can anyone shed some light on this topic?
Typically, thermostats or at least their drivers track heatingSetpoint and coolingSetpoint separately, then the thermostatSetpoint attribute will show whichever setpoint is the one that actually matters at the moment based on the current thermostatMode (or the last one that did matter if it's off).
Here are the current states from an actual thermostat I have as one example:
And I believe some thermostats will use the two hearing and cooling set points when in auto mode, if they have one. Along with some king of buffer, potentially.