BSB-LAN: Message Queuing and Error Handling
Description:
Due to the fact, the BSB-LAN Adapter is based on a light weight Arduino or ESP micro controller, it's only possible to process requests serially. If the controller is busy with a longer running request all follwing requests will fail with ECONNREFUSED error as long as the former request is running. This simple message queuing flow will concentrate all requests to BSB-LAN adapter one by one and only opens it's gate, when BSB-LAN Adapter is responsible again. It also loops failed requests (only due to ECONNREFUSED failed) with short delay until it succeeds.
Dependencies:
- https://flows.nodered.org/node/node-red-contrib-simple-message-queue
- https://flows.nodered.org/node/node-red-contrib-bsb-lan
Usage:
Use Input/Output-LinkNodes to interact with queue. Be sure that every request to BSB-LAN Adapter passing through this queue. If there are more instances of bsb-lan nodes are active it's possible that they interfere each other. Which ends up in errors.
For GET requests with expected result set, use msg.topic property to refer correct return msg in superordinated flow which is using BSB-LAN queue.
See example flow.
Pic:
[{"id":"4290c4a6.90df7c","type":"switch","z":"15be78c0.6761c7","name":"get-Return GetDiagData","property":"topic","propertyType":"msg","rules":[{"t":"eq","v":"GetDiagData","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":680,"y":80,"wires":[["c8eb0126.5b7e4","b13971dd.ff407"]]},{"id":"c8eb0126.5b7e4","type":"function","z":"15be78c0.6761c7","name":"Format BSB Data","func":"\nfunction makeFloat ($value) {\n $myRet = parseFloat($value)\n if (isNaN($myRet)) {\n return 0\n } else {\n return $myRet\n }\n}\n\n\nvar $myRet = {\n TWWNennSoll:makeFloat(msg.payload['1610'].value),\n TWWKesselAnforderung:makeFloat(msg.payload['1859'].value),\n Mischerüberhöhung:makeFloat(msg.payload['2130'].value),\n ErzeugersperreSD:makeFloat(msg.payload['4721'].value),\n dTPuffer2HK:makeFloat(msg.payload['4722'].value),\n Kesseltemp:makeFloat(msg.payload['8310'].value),\n KesselSoll:makeFloat(msg.payload['8311'].value),\n WPFanRPM:makeFloat(msg.payload['8323'].value),\n WPBetriebstunden:makeFloat(msg.payload['8330'].value),\n WPStartcounter:makeFloat(msg.payload['8331'].value),\n// WPBetriebstunden2:makeFloat(msg.payload['8336'].value),\n// WPTempRücklauf:makeFloat(msg.payload['8410'].value),\n// WPTempVorlauf:makeFloat(msg.payload['8412'].value),\n TempAußen:makeFloat(msg.payload['8700'].value),\n TempAußenGedämpft:makeFloat(msg.payload['8703'].value),\n TempAußenGemischt:makeFloat(msg.payload['8704'].value),\n HKPumpeQ2:makeFloat(msg.payload['8730'].value),\n// HKMischerAufY1:makeFloat(msg.payload['8731'].value),\n// HKMischerZuY2:makeFloat(msg.payload['8732'].value),\n TempRaum:makeFloat(msg.payload['8740'].value),\n TempRaumSoll:makeFloat(msg.payload['8741'].value),\n// TempRaumModell:makeFloat(msg.payload['8742'].value),\n TempVorlauf:makeFloat(msg.payload['8743'].value),\n TempVorlaufSollHeizen:makeFloat(msg.payload['8744'].value),\n// StatusRaumThermostat:makeFloat(msg.payload['8749'].value),\n// ModulationPumpePerc:makeFloat(msg.payload['8750'].value),\n TempVorlaufSollKühlen:makeFloat(msg.payload['8756'].value),\n TempTrinkwasser:makeFloat(msg.payload['8830'].value),\n TempTrinkwasserSoll:makeFloat(msg.payload['8831'].value),\n TempTrinkwasserZirkulation:makeFloat(msg.payload['8835'].value),\n TempSchienenVorlaufSoll:makeFloat(msg.payload['8951'].value),\n TempPuffer1:makeFloat(msg.payload['8980'].value),\n TempPuffer1Soll:makeFloat(msg.payload['8981'].value),\n TempPuffer2:makeFloat(msg.payload['8983'].value),\n BetriebsartHK:makeFloat(msg.payload['700'].value),\n BetriebsartKK:makeFloat(msg.payload['901'].value),\n BetriebsartTWW:makeFloat(msg.payload['1680'].value),\n LowerLimitVorlaufK:makeFloat(msg.payload['923'].value),\n TWWUmwälzpumpe:makeFloat(msg.payload['9055'].value)\n }\n//global.set(\"heizungDiag\",$myRet)\nmsg.payload = $myRet\nvar msgHK = {\n payload:$myRet.BetriebsartHK\n}\nvar msgKK = {\n payload:$myRet.BetriebsartKK\n}\n\nvar msgTWW = {\n payload:$myRet.BetriebsartTWW\n}\nreturn [msg,msgHK,msgKK,msgTWW];","outputs":4,"noerr":0,"initialize":"","finalize":"","x":910,"y":80,"wires":[["7bb7915d.8e349","fb3db173.65b1a"],["f856855.f4f4e78"],["c3207e78.be025"],["d76b1998.86cee8"]]},{"id":"fb3db173.65b1a","type":"change","z":"15be78c0.6761c7","name":"save Global","rules":[{"t":"set","p":"payload.timestamp","pt":"msg","to":"","tot":"date"},{"t":"set","p":"heizungDiag","pt":"global","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":1110,"y":60,"wires":[[]]},{"id":"b13971dd.ff407","type":"function","z":"15be78c0.6761c7","name":"Send GetStatus","func":"msg = {\n requesttype:'GET',\n parameters:[8000,8003,8004,8005,8010,8022],\n topic:'GetStatus'\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":640,"y":120,"wires":[["dce72868.1308f8"]]},{"id":"dce72868.1308f8","type":"link out","z":"15be78c0.6761c7","name":"","links":["7d5ab016.e2f37","970e948.ef26368"],"x":755,"y":120,"wires":[]},{"id":"950ef20b.df682","type":"link in","z":"15be78c0.6761c7","name":"","links":["afaaf839.c5e558","5ee06e0d.4522d"],"x":575,"y":160,"wires":[["89c5edc.dc5c81"]]},{"id":"89c5edc.dc5c81","type":"switch","z":"15be78c0.6761c7","name":"get-Return GetStatus","property":"topic","propertyType":"msg","rules":[{"t":"eq","v":"GetStatus","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":750,"y":160,"wires":[["f6cd7a1e.8e31d8"]]},{"id":"f6cd7a1e.8e31d8","type":"function","z":"15be78c0.6761c7","name":"Format BSB Data","func":"\nfunction makeFloat ($value) {\n $myRet = parseFloat($value)\n if (isNaN($myRet)) {\n return 0\n } else {\n return $myRet\n }\n}\n\n\nvar $myRet = {\n Heizkreis:makeFloat(msg.payload['8000'].value),\n Trinkwasser:makeFloat(msg.payload['8003'].value),\n Kühlkreis:makeFloat(msg.payload['8004'].value),\n Kessel:makeFloat(msg.payload['8005'].value),\n Pufferspeicher:makeFloat(msg.payload['8010'].value),\n Zusatzerzeuger:makeFloat(msg.payload['8022'].value)\n}\n\nmsg.payload = $myRet\n\n\n/*\nvar msgHK = {\n payload:$myRet.BetriebsartHK\n}\nvar msgKK = {\n payload:$myRet.BetriebsartKK\n}\n\nvar msgTWW = {\n payload:$myRet.BetriebsartTWW\n}\nreturn [msg,msgHK,msgKK,msgTWW];\n*/\n\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","x":970,"y":160,"wires":[["7b0213a8.869c1c","5db00cbe.d105a4"]]},{"id":"5db00cbe.d105a4","type":"change","z":"15be78c0.6761c7","name":"save Global","rules":[{"t":"set","p":"payload.timestamp","pt":"msg","to":"","tot":"date"},{"t":"set","p":"heizungStatus","pt":"global","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":1210,"y":280,"wires":[[]]},{"id":"38684a0b.cdb516","type":"link in","z":"15be78c0.6761c7","name":"","links":["afaaf839.c5e558","5ee06e0d.4522d"],"x":495,"y":80,"wires":[["4290c4a6.90df7c"]]},{"id":"d6bd9f7c.f0d72","type":"link out","z":"15be78c0.6761c7","name":"","links":["7d5ab016.e2f37","970e948.ef26368"],"x":435,"y":80,"wires":[]},{"id":"c9229821.a71818","type":"function","z":"15be78c0.6761c7","name":"Send GetDiagData","func":"msg = {\n requesttype:'GET',\n parameters:[\n 700,\n 901,\n 923,\n 1610,\n 1680,\n 1859,\n 2130,\n 4721,\n 4722,\n 8099,\n 8310,\n 8311,\n 8323,\n 8325,\n 8330,\n 8331,\n// 8336,\n 8427,\n 8429,\n 8700,\n 8703,\n 8704,\n 8730,\n// 8731,\n// 8732,\n 8740,\n 8741,\n// 8742,\n 8743,\n 8744,\n 8756,\n 8830,\n 8831,\n 8835,\n 8951,\n 8980,\n 8981,\n 8983,\n 9055\n ],\n topic:'GetDiagData'\n}\nreturn msg;\n\n ","outputs":1,"noerr":0,"initialize":"","finalize":"","x":310,"y":80,"wires":[["d6bd9f7c.f0d72"]]},{"id":"dca61b4b.be0808","type":"inject","z":"15be78c0.6761c7","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"60","crontab":"","once":true,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":130,"y":80,"wires":[["c9229821.a71818"]]},{"id":"7cc65782.277db8","type":"group","z":"15be78c0.6761c7","name":"BSB-LAN Qeueu","style":{"stroke":"#92d04f","fill":"#000000","label":true,"color":"#ffC000"},"nodes":["f0b30f62.4555b","fb4e5d33.2fdf1","51c2aab5.2e3794","970e948.ef26368","5ee06e0d.4522d","70398e4f.e20c2","ed9bfc23.6bae2","3f9a84bc.e027cc","73ba2589.1a1c6c","dc233730.f03548","2deb638d.408ffc","6068c523.e16a1c","660c553a.eb6bac","5187cd7d.e443a4","8c3a5b08.fdc8e8","75677129.1f68c","7def0aad.237744","f025e6ba.817128","8cf696ba.b9eca8"],"x":1594,"y":119,"w":1572,"h":262},{"id":"f0b30f62.4555b","type":"bsb-lan","z":"15be78c0.6761c7","g":"7cc65782.277db8","device":"481b0fd8.623ad","name":"","requesttype":"GET","parameters":[],"value":"","x":2200,"y":200,"wires":[["73ba2589.1a1c6c"]]},{"id":"fb4e5d33.2fdf1","type":"simple-queue","z":"15be78c0.6761c7","g":"7cc65782.277db8","name":"Main Queue","firstMessageBypass":true,"bypassInterval":"5000","x":2010,"y":220,"wires":[["f0b30f62.4555b"]]},{"id":"51c2aab5.2e3794","type":"change","z":"15be78c0.6761c7","g":"7cc65782.277db8","name":"Q-fetch next","rules":[{"t":"set","p":"trigger","pt":"msg","to":"1","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":2610,"y":300,"wires":[["8cf696ba.b9eca8"]]},{"id":"970e948.ef26368","type":"link in","z":"15be78c0.6761c7","g":"7cc65782.277db8","name":"BSB-Queue-In","links":["1dd5b473.2618bc","27181e76.5c9182","2a2e02c.53d7dfe","2aae39ae.cc62a6","30ef0364.476acc","55b44b3.bbf48b4","582d9c1f.e361a4","70398e4f.e20c2","72a7a085.84515","85cf098a.dcc328","89360262.1341a","b1329576.3189a8","b307a7c8.941e48","c33f4b71.516468","d20b1fe8.d5f4a","d6bd9f7c.f0d72","d7ff6d47.ad70a","dce72868.1308f8","de99bc94.df97f","e64be30d.36346"],"x":1700,"y":200,"wires":[["660c553a.eb6bac"]],"l":true},{"id":"5ee06e0d.4522d","type":"link out","z":"15be78c0.6761c7","g":"7cc65782.277db8","name":"BSB-Queue-Out","links":["35ea5b32.3e0604","38684a0b.cdb516","48f79ae9.005264","4ad8e98c.18b448","4ebc41bf.41d3b","7116a081.3b8f7","8a23770b.7183b8","8f3fdff6.0dad5","950ef20b.df682","9ff20b9e.8bdf28","b786402a.41f0f","d0f43ee3.124d8","d2ee17a4.be03e8","f4e792be.4d4d2","fd8cf64f.dcff88"],"x":3060,"y":200,"wires":[],"l":true},{"id":"70398e4f.e20c2","type":"link out","z":"15be78c0.6761c7","g":"7cc65782.277db8","name":"BSB-Queue-FetchNext","links":["970e948.ef26368"],"x":2895,"y":300,"wires":[]},{"id":"ed9bfc23.6bae2","type":"catch","z":"15be78c0.6761c7","g":"7cc65782.277db8","name":"","scope":null,"uncaught":false,"x":1840,"y":280,"wires":[["3f9a84bc.e027cc"]]},{"id":"3f9a84bc.e027cc","type":"link out","z":"15be78c0.6761c7","g":"7cc65782.277db8","name":"","links":["d82e8291.44e8"],"x":1955,"y":280,"wires":[]},{"id":"73ba2589.1a1c6c","type":"switch","z":"15be78c0.6761c7","g":"7cc65782.277db8","name":"OK?","property":"payload","propertyType":"msg","rules":[{"t":"cont","v":"ECONNREFUSED","vt":"str"},{"t":"else"}],"checkall":"false","repair":false,"outputs":2,"x":2370,"y":240,"wires":[["dc233730.f03548"],["5ee06e0d.4522d","f025e6ba.817128","8c3a5b08.fdc8e8"]],"outputLabels":["goto Retry","Request OK"]},{"id":"dc233730.f03548","type":"change","z":"15be78c0.6761c7","g":"7cc65782.277db8","name":"Retry ring buffer","rules":[{"t":"delete","p":"payload","pt":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":2560,"y":160,"wires":[["2deb638d.408ffc"]]},{"id":"2deb638d.408ffc","type":"link out","z":"15be78c0.6761c7","g":"7cc65782.277db8","name":"","links":["6068c523.e16a1c"],"x":2855,"y":160,"wires":[]},{"id":"6068c523.e16a1c","type":"link in","z":"15be78c0.6761c7","g":"7cc65782.277db8","name":"","links":["2deb638d.408ffc"],"x":1875,"y":160,"wires":[["5187cd7d.e443a4"]]},{"id":"660c553a.eb6bac","type":"delay","z":"15be78c0.6761c7","g":"7cc65782.277db8","name":"","pauseType":"random","timeout":"50","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"10","randomLast":"20","randomUnits":"milliseconds","drop":false,"x":1875,"y":200,"wires":[["fb4e5d33.2fdf1"]],"l":false},{"id":"5187cd7d.e443a4","type":"simple-queue","z":"15be78c0.6761c7","g":"7cc65782.277db8","name":"Retry Queue","firstMessageBypass":true,"bypassInterval":"5000","x":2010,"y":160,"wires":[["f0b30f62.4555b"]],"icon":"font-awesome/fa-recycle"},{"id":"8c3a5b08.fdc8e8","type":"debug","z":"15be78c0.6761c7","g":"7cc65782.277db8","name":"recent","active":false,"tosidebar":false,"console":false,"tostatus":true,"complete":"topic","targetType":"msg","statusVal":"topic","statusType":"auto","x":2530,"y":340,"wires":[]},{"id":"75677129.1f68c","type":"status","z":"15be78c0.6761c7","g":"7cc65782.277db8","name":"","scope":["5187cd7d.e443a4"],"x":2060,"y":340,"wires":[["7def0aad.237744"]]},{"id":"7def0aad.237744","type":"function","z":"15be78c0.6761c7","g":"7cc65782.277db8","name":"set-BSBRetryEmpty","func":"function makeInt ($value) {\n $myRet = parseInt($value)\n if (isNaN($myRet)) {\n return 0\n } else {\n return $myRet\n }\n}\n\nif (makeInt(msg.status.text > 0)) {\n flow.set('BSBRetryEmpty', false)\n} else {\n flow.set('BSBRetryEmpty', true)\n}\n\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":2240,"y":340,"wires":[[]]},{"id":"f025e6ba.817128","type":"delay","z":"15be78c0.6761c7","g":"7cc65782.277db8","name":"","pauseType":"delay","timeout":"10","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":2495,"y":300,"wires":[["51c2aab5.2e3794"]],"l":false},{"id":"8cf696ba.b9eca8","type":"switch","z":"15be78c0.6761c7","g":"7cc65782.277db8","name":"Retry Empty?","property":"BSBRetryEmpty","propertyType":"flow","rules":[{"t":"false"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":2780,"y":300,"wires":[["2deb638d.408ffc"],["70398e4f.e20c2"]]},{"id":"481b0fd8.623ad","type":"bsb-lan-device","host":"bsb-lan.fritz.box","port":"80"}]