Here is a flow that you can use for heat/cool control with node-red-contrib-pid. Instructions on configuring it are in the Function node.
[{"id":"d06813fe.a657d","type":"inject","z":"9b808c99.ccb9c","name":"","repeat":"","crontab":"","once":false,"topic":"","payload":"0.25","payloadType":"num","x":135,"y":97,"wires":[["5685aea6.42f268"]]},{"id":"aef6c072.927a7","type":"inject","z":"9b808c99.ccb9c","name":"","repeat":"","crontab":"","once":false,"topic":"","payload":"0.5","payloadType":"num","x":136.5,"y":132,"wires":[["5685aea6.42f268"]]},{"id":"e09ee366.fdac08","type":"inject","z":"9b808c99.ccb9c","name":"","repeat":"","crontab":"","once":false,"topic":"","payload":"0.75","payloadType":"num","x":137.5,"y":169,"wires":[["5685aea6.42f268"]]},{"id":"7a93c7f8.a116e","type":"inject","z":"9b808c99.ccb9c","name":"","repeat":"","crontab":"","once":false,"topic":"","payload":"0.0","payloadType":"num","x":134.5,"y":61,"wires":[["5685aea6.42f268"]]},{"id":"d48c3837.cad168","type":"inject","z":"9b808c99.ccb9c","name":"","repeat":"","crontab":"","once":false,"topic":"","payload":"1.0","payloadType":"num","x":137.5,"y":206,"wires":[["5685aea6.42f268"]]},{"id":"5685aea6.42f268","type":"function","z":"9b808c99.ccb9c","name":"Split Heat/Cool","func":"/* A function designed to be used with node-red-contrib-pid in applications where both\n * heating and cooling are available to control the system.\n * The node is given a power value in msg.payload in the range 0 to 1, such as is produced by \n * node-red-contrib-pid and splits this into a heat power (o/p 1) and cool power (o/p 2) where\n * each is in the range 0 to 1. These can then be fed directly into an output device, if this\n * is continuously variable, or they may be passed to node-red-contrib-timeprop nodes to generate\n * time proportioned on/off outputs.\n * There are two particular issues to be dealt with in a heat/cool application. Firstly is the fact\n * that the cooling device may be more or less powerful than the heating device. It is necessary\n * therefore to be able to adjust the gain of the system separately for heating and cooling. Secondly\n * is the highly non-linear response of some devices, notably refrigerant systems, that can have a\n * large effect initially, then this tails off. To compensate for this it is useful to have an \n * overlap range where both heat and cool are slightly on.\n *\n * To allow for these requirements two variables can be set below. The value of the power input value\n * where the heating starts to come on is determined by the variable heatMin. Above this value the\n * heating will rise till it is fully on with an input of 1.\n * The cooling is fully on when value of the power input is 0, and falls till the cooling is fully\n * off at an input of coolMin.\n *\n * If the heating and cooling systems are of similar power then set heatMin and coolMin both to 0.5\n * in which case input values of 0.5 to 1.0 will map to heating outputs of 0.0 to 1.0,\n * and 0.5 down to 0.0 will map to cooling 0.0 to 1.0.\n * If, for example, the cooling system is more powerful than heating then they can both be set\n * to something like 0.7 which increases the gain in the heating region and reduces it\n * in the cooling region, to compensate for the different powers in the heating/cooling systems.\n * If some overlap is desired (so that both heat and cool are on slightly near the crossover\n * point) then overlap the two settings so that, for example, heatMin might be 0.45 and coolMin\n * might be 0.55\n */\n\n// set these as described above\nvar heatMin = 0.5; // the value of input corresponding to 0 heat o/p\nvar coolMin = 0.5; // the value of input corresponding to 0 cool o/p\n \nvar power = msg.payload;\nvar heat = (power - heatMin)/(1 - heatMin);\n// limit to range 0 to 1\nheat = Math.min(Math.max(heat, 0), 1);\nvar cool = (coolMin - power) / coolMin;\n// limit to range 0 to 1\ncool = Math.min(Math.max(cool, 0), 1);\nreturn [{payload: heat}, {payload: cool}];\n","outputs":"2","noerr":0,"x":400,"y":250,"wires":[["2b64cd9e.3e398a"],["268a1179.f064f6"]]},{"id":"268a1179.f064f6","type":"debug","z":"9b808c99.ccb9c","name":"Cool","active":true,"console":"false","complete":"payload","x":604.5,"y":264,"wires":[]},{"id":"2b64cd9e.3e398a","type":"debug","z":"9b808c99.ccb9c","name":"Heat","active":true,"console":"false","complete":"payload","x":604,"y":220,"wires":[]},{"id":"bef43ce5.5970c","type":"comment","z":"9b808c99.ccb9c","name":"Feed node-red-contrib-pid in here","info":"","x":169,"y":273,"wires":[]},{"id":"4263d000.5c697","type":"comment","z":"9b808c99.ccb9c","name":"To heater","info":"","x":580,"y":185,"wires":[]},{"id":"18516842.115a1","type":"comment","z":"9b808c99.ccb9c","name":"To Cooler","info":"","x":579,"y":302,"wires":[]}]