Difference between revisions of "Controlling Belimo Valves"

From Open Source Controls Wiki
Jump to navigation Jump to search
 
(50 intermediate revisions by the same user not shown)
Line 1: Line 1:
[[File:PIC EU SR24A-MOD 4C-product.jpg|right]]
[[File:Nrmodbusb.png|right|977px]]
Belimo valves are one of the most recognised and widely used makes of valve in the HVAC industry.
Belimo valves are one of the most recognised and widely used makes of valve in the HVAC industry.  


The libraries on this page provide the tools to control and monitor valves<br>using the MQTT open controls protocol and Node-RED.
[[Category:Functions]]
[[Category:Functions]]
The libraries on this page provide the tools to control and monitor valves using the MQTT open controls protocol and Node-RED.


* [https://www.belimo.com/ch/en_GB/ Belimo Website]
<br>
 
== Documents ==
 
*[https://www.belimo.com/ch/en_GB/ Belimo Website]
*[https://www.belimo.com/ch/shop/en_GB/Actuators/Valve-Actuators/SR24A-MOD/p?code=SR24A-MOD SR24A-MOD product page and instructions]
*[https://www.belimo.com/ch/shop/en_GB/Actuators/Valve-Actuators/SR24A-MOD/p?code=SR24A-MOD SR24A-MOD product page and instructions]
* [https://www.belimo.com/mam/europe/technical-documentation/system_integration/belimo_Modbus-Register_AirWater_V3_04_en-gb.pdf Belimo Modbus information]
* [https://www.belimo.com/mam/europe/technical-documentation/system_integration/belimo_Modbus-Register_AirWater_V3_04_en-gb.pdf Belimo Modbus information]


== Autowiring==
# Drag parts onto page
# Wire terminals together either manually, or by pressing Autowire
# Position parts neatly
# Reroute messy wires<br />
[[File:Concons1.png|frameless|100px|right]]
<iframe key="wiki" align="right" width="90%" height="1000" level="" path="/gojs/samples/wiring6.html?id=wiring1&palette=wiringPalette1" />


<pre id="wiringPalette1" style="display:none">
[
{"key":"node","name":"Automation Hat","color":"#1a613d","image":"/images/thumb/1/13/BAH1c.png/800px-BAH1c.png","leftArray":[{"portId":"left0","portColor":"#000000"},{"portId":"left1","portColor":"#ffff00"},{"portId":"left2","portColor":"#000000"},{"portId":"left3","portColor":"#ffff00"},{"portId":"left4","portColor":"#000000"},{"portId":"left5","portColor":"#ffff00"},{"portId":"left6","portColor":"#000000"},{"portId":"left7","portColor":"#ffff00"},{"portId":"left8","portColor":"#000000"},{"portId":"left9","portColor":"#ffff00"},{"portId":"left10","portColor":"#000000"},{"portId":"left11","portColor":"#ffff00"},{"portId":"left12","portColor":"#000000"},{"portId":"left13","portColor":"#ffff00"},{"portId":"left14","portColor":"#000000"},{"portId":"left15","portColor":"#ffff00"}],"topArray":[{"portColor":"#ffffff","portId":"top0"},{"portId":"top1","portColor":"#ffc900"},{"portId":"top2","portColor":"#ffc900"},{"portId":"top3","portColor":"#ffc900"},{"portId":"top4","portColor":"#ffc900"},{"portId":"top5","portColor":"#ffffff"},{"portId":"top6","portColor":"#ffffff"},{"portId":"top7","portColor":"#ffffff"},{"portId":"top8","portColor":"#ffffff"},{"portId":"top9","portColor":"#ffffff"},{"portId":"top10","portColor":"#ffffff"},{"portId":"top11","portColor":"#ffffff"},{"portId":"top12","portColor":"#ffffff"},{"portId":"top13","portColor":"#ffffff"},{"portId":"top14","portColor":"#ffffff"},{"portId":"top15","portColor":"#ffffff"},{"portId":"top16","portColor":"#ffffff"},{"portId":"top17","portColor":"#ffffff"},{"portId":"top18","portColor":"#ffffff"},{"portId":"top19","portColor":"#ffffff"},{"portId":"top20","portColor":"#ff0000"},{"portId":"top21","portColor":"#000001"}],"bottomArray":[{"portColor":"#888888","portId":"bottom0"},{"portId":"bottom1","portColor":"#888889"},{"portId":"bottom2","portColor":"#888890"},{"portId":"bottom11","portColor":"#888891"},{"portId":"bottom12","portColor":"#ffffff"},{"portId":"bottom13","portColor":"#ffffff"},{"portId":"bottom14","portColor":"#ffffff"},{"portId":"bottom15","portColor":"#ffffff"},{"portId":"bottom16","portColor":"#ffffff"},{"portId":"bottom17","portColor":"#ffffff"},{"portId":"bottom18","portColor":"#ff0000"},{"portId":"bottom19","portColor":"#ff0000"},{"portId":"bottom20","portColor":"#ff0000"},{"portId":"bottom21","portColor":"#ff0000"}],"rightArray":[{"portId":"right8","portColor":"#8827e7"},{"portId":"right9","portColor":"#000000"},{"portId":"right10","portColor":"#8827e7"},{"portId":"right11","portColor":"#000000"},{"portId":"right12","portColor":"#8827e7"},{"portId":"right13","portColor":"#000000"},{"portId":"right14","portColor":"#8827e7"},{"portId":"right15","portColor":"#000000"},{"portId":"right0","portColor":"#f6beb6"},{"portId":"right1","portColor":"#000001"},{"portId":"right2","portColor":"#f6beb6"},{"portId":"right3","portColor":"#000001"},{"portId":"right4","portColor":"#f6beb6"},{"portId":"right5","portColor":"#000001"},{"portId":"right6","portColor":"#f6beb6"},{"portId":"right7","portColor":"#000001"}],"textColor":"#efebeb","notes":"","size":"287 160"},
{"name":"Pulsed Flow Sensor","color":"#dbf6cb","pulsesPerLitre":"520","leftArray":[],"rightArray":[{"portId":"right1","portColor":"#ffc900"},{"portId":"right2","portColor":"#000000"},{"portId":"right0","portColor":"#00ffff","signalTypes":["#00ffff","#ffff00"]}],"topArray":[],"bottomArray":[],"key":"FS","size":"82.107421875 53"},
{"name":"Timeclock","color":"#dbf6cb","leftArray":[],"rightArray":[{"portId":"right0","portColor":"#000000"},{"portId":"right1","portColor":"#00ffff","signalTypes":["#00ffff","#ffff00"]}],"topArray":[],"bottomArray":[],"key":"timer","size":"78.78515625 47"},
{"name":"Room Thermostat","color":"#dbf6cb","leftArray":[],"rightArray":[{"portId":"right0","portColor":"#000000"},{"portId":"right1","portColor":"#00ffff","signalTypes":["#00ffff","#ffff00"]}],"topArray":[],"bottomArray":[],"key":"roomstat","size":"78.78515625 47"},
{"name":"Switch","color":"#dbf6cb","leftArray":[{"portId":"left0","portColor":"#00ffff","signalTypes":["#00ffff","#ffff00"]},{"portId":"left1","portColor":"#000000"}],"rightArray":[],"topArray":[],"bottomArray":[],"key":"switch","size":"69 47"},
{"name":"Pressure + Temp Sensor","range":"6 bar","color":"#dbf6cb","leftArray":[],"rightArray":[{"portId":"right1","portColor":"#ffc900"},{"portId":"right2","portColor":"#000000"},{"portId":"right0","portColor":"#8827e7","signalTypes":["#ffff00"]},{"portId":"right3","portColor":"#8827e7","signalTypes":["#ffff00"]}],"topArray":[],"bottomArray":[],"key":"RPS","size":"88 55"},
{"name":"DP + Temp Sensor","range":"300 kPa","color":"#dbf6cb","leftArray":[],"rightArray":[{"portId":"right1","portColor":"#ffc900"},{"portId":"right2","portColor":"#000000"},{"portId":"right0","portColor":"#8827e7","signalTypes":["#ffff00"]},{"portId":"right3","portColor":"#8827e7","signalTypes":["#ffff00"]}],"topArray":[],"bottomArray":[],"key":"DPS","size":"88 55"},
{"name":"Flow + Temp Sensor","range":"4-30 lpm","color":"#dbf6cb","leftArray":[],"rightArray":[{"portId":"right1","portColor":"#ffc900"},{"portId":"right2","portColor":"#000000"},{"portId":"right0","portColor":"#8827e7","signalTypes":["#ffff00"]},{"portId":"right3","portColor":"#8827e7","signalTypes":["#ffff00"]}],"topArray":[],"bottomArray":[],"key":"VFS","size":"88 55"},
{"name":"24v Power","color":"#dbf6cb","leftArray":[{"portId":"left0","portColor":"#ff0000"},{"portId":"left2","portColor":"#000001"}],"rightArray":[],"topArray":[],"bottomArray":[],"key":"24VDC","size":"90 50"},
{"name":"NTC10K","color":"#dbf6cb","leftArray":[],"rightArray":[{"portId":"right0","portColor":"#000000"},{"portId":"right1","portColor":"#00ff00","signalTypes":["#00ff00","#ffff00"]}],"topArray":[],"bottomArray":[],"key":"ntc","size":"58 40"},
{"name":"Modbus Master","color":"#dbf6cb","leftArray":[{"portId":"left0","portColor":"#888891"},{"portId":"left1","portColor":"#888890"}],"rightArray":[],"topArray":[],"bottomArray":[],"key":"modbus1","size":"67 54"},
{"name":"Control Valve (Modbus)","color":"#ff9900","leftArray":[],"rightArray":[],"topArray":[{"portId":"top0","portColor":"#888888"},{"portId":"top1","portColor":"#888889"},{"portId":"top2","portColor":"#ff0000"},{"portId":"top3","portColor":"#000000","signalTypes":["#000001","#000000"]}],"bottomArray":[],"key":"valve","size":"96 59"},
{"name":"Control Valve (0-10V)","color":"#ff9900","leftArray":[],"rightArray":[],"topArray":[{"portId":"top0","portColor":"#8827e7","signalTypes":["#ffff00","#e988e3"]},{"portId":"top1","portColor":"#e988e3","signalTypes":["#8827e7"]},{"portId":"top2","portColor":"#ff0000"},{"portId":"top3","portColor":"#000000"}],"bottomArray":[],"key":"valve","size":"96 59"},
{"name":"Control Valve (Hybrid)","color":"#ff9900","leftArray":[],"rightArray":[],"topArray":[{"portId":"top0","portColor":"#888888"},{"portId":"top1","portColor":"#888889"},{"portId":"top2","portColor":"#8827e7","signalTypes":["#ffff00","#e988e3"]},{"portId":"top3","portColor":"#e988e3","signalTypes":["#8827e7"]},{"portId":"top4","portColor":"#ff0000"},{"portId":"top5","portColor":"#000000","signalTypes":["#000000","#000001"]}],"bottomArray":[],"key":"valve","size":"96 59"},
{"name":"Pump (0-10V)","color":"#dbf6cb","leftArray":[],"rightArray":[],"topArray":[{"portId":"top0","portColor":"#8827e7","signalTypes":["#ffff00","#e988e3"]},{"portId":"top1","portColor":"#e988e3","signalTypes":["#8827e7"]},{"portId":"top2","portColor":"#000000"}],"bottomArray":[],"key":"pump","size":"57.3212890625 52"},{"name":"Sticky Note","color":"#ffffff00","background":"/images/thumb/3/3f/Sticky.png/597px-Sticky.png","leftArray":[],"rightArray":[],"topArray":[],"bottomArray":[],"key":"note","size":"150 150"}
]
</pre>
<pre id="wiring1" style="display:none">
{ "class": "GraphLinksModel",
  "copiesArrays": true,
  "copiesArrayObjects": true,
  "linkFromPortIdProperty": "fromPort",
  "linkToPortIdProperty": "toPort",
  "nodeDataArray": [
{"key":"MQTT","name":"mqtt.heatweb.co.uk","color":"#ffffff","image":"/images/5/5f/Cloud1.png","leftArray":[],"topArray":[],"bottomArray":[{"portId":"bottom0","portColor":"#ffffff"}],"rightArray":[],"textColor":"#000000","notes":"","size":"201 80","loc":"70.8125 -87.25"},
{"key":"node","name":"Automation Hat","color":"#1a613d","image":"/images/thumb/1/13/BAH1c.png/800px-BAH1c.png","leftArray":[{"portId":"left0","portColor":"#000000"},{"portId":"left1","portColor":"#ffff00"},{"portId":"left2","portColor":"#000000"},{"portId":"left3","portColor":"#ffff00"},{"portId":"left4","portColor":"#000000"},{"portId":"left5","portColor":"#ffff00"},{"portId":"left6","portColor":"#000000"},{"portId":"left7","portColor":"#ffff00"},{"portId":"left8","portColor":"#000000"},{"portId":"left9","portColor":"#ffff00"},{"portId":"left10","portColor":"#000000"},{"portId":"left11","portColor":"#ffff00"},{"portId":"left12","portColor":"#000000"},{"portId":"left13","portColor":"#ffff00"},{"portId":"left14","portColor":"#000000"},{"portId":"left15","portColor":"#ffff00"}],"topArray":[{"portColor":"#ffffff","portId":"top0"},{"portId":"top1","portColor":"#ffc900"},{"portId":"top2","portColor":"#ffc900"},{"portId":"top3","portColor":"#ffc900"},{"portId":"top4","portColor":"#ffc900"},{"portId":"top5","portColor":"#ffffff"},{"portId":"top6","portColor":"#ffffff"},{"portId":"top7","portColor":"#ffffff"},{"portId":"top8","portColor":"#ffffff"},{"portId":"top9","portColor":"#ffffff"},{"portId":"top10","portColor":"#ffffff"},{"portId":"top11","portColor":"#ffffff"},{"portId":"top12","portColor":"#ffffff"},{"portId":"top13","portColor":"#ffffff"},{"portId":"top14","portColor":"#ffffff"},{"portId":"top15","portColor":"#ffffff"},{"portId":"top16","portColor":"#ffffff"},{"portId":"top17","portColor":"#ffffff"},{"portId":"top18","portColor":"#ffffff"},{"portId":"top19","portColor":"#ffffff"},{"portId":"top20","portColor":"#ff0000"},{"portId":"top21","portColor":"#000001"}],"bottomArray":[{"portColor":"#888888","portId":"bottom0"},{"portId":"bottom1","portColor":"#888889"},{"portId":"bottom2","portColor":"#888890"},{"portId":"bottom11","portColor":"#888891"},{"portId":"bottom12","portColor":"#ffffff"},{"portId":"bottom13","portColor":"#ffffff"},{"portId":"bottom14","portColor":"#ffffff"},{"portId":"bottom15","portColor":"#ffffff"},{"portId":"bottom16","portColor":"#ffffff"},{"portId":"bottom17","portColor":"#ffffff"},{"portId":"bottom18","portColor":"#ff0000"},{"portId":"bottom19","portColor":"#ff0000"},{"portId":"bottom20","portColor":"#ff0000"},{"portId":"bottom21","portColor":"#ff0000"}],"rightArray":[{"portId":"right8","portColor":"#8827e7"},{"portId":"right9","portColor":"#000000"},{"portId":"right10","portColor":"#8827e7"},{"portId":"right11","portColor":"#000000"},{"portId":"right12","portColor":"#8827e7"},{"portId":"right13","portColor":"#000000"},{"portId":"right14","portColor":"#8827e7"},{"portId":"right15","portColor":"#000000"},{"portId":"right0","portColor":"#f6beb6"},{"portId":"right1","portColor":"#000001"},{"portId":"right2","portColor":"#f6beb6"},{"portId":"right3","portColor":"#000001"},{"portId":"right4","portColor":"#f6beb6"},{"portId":"right5","portColor":"#000001"},{"portId":"right6","portColor":"#f6beb6"},{"portId":"right7","portColor":"#000001"}],"textColor":"#efebeb","notes":"","size":"287 160","loc":"-45.84375 177.125"},
{"name":"24v Power","color":"#dbf6cb","leftArray":[{"portId":"left0","portColor":"#ff0000"},{"portId":"left2","portColor":"#000001"}],"rightArray":[],"topArray":[],"bottomArray":[],"key":"24VDC","size":"90 50","loc":"246.15625 41.125"},
{"name":"NTC10K","color":"#dbf6cb","leftArray":[],"rightArray":[{"portId":"right0","portColor":"#000000"},{"portId":"right1","portColor":"#00ff00","signalTypes":["#00ff00","#ffff00"]}],"topArray":[],"bottomArray":[],"key":"ntc","size":"58 40","loc":"-550.84375 31.15625"},
{"name":"NTC10K","color":"#dbf6cb","leftArray":[],"rightArray":[{"portId":"right0","portColor":"#000000"},{"portId":"right1","portColor":"#00ff00","signalTypes":["#00ff00","#ffff00"]}],"topArray":[],"bottomArray":[],"key":"ntc2","size":"58 40","loc":"-548.84375 85.15625"},
{"name":"DP + Temp Sensor","range":"300 kPa","color":"#dbf6cb","leftArray":[],"rightArray":[{"portId":"right2","portColor":"#000000"},{"portId":"right3","portColor":"#8827e7","signalTypes":["#ffff00"]},{"portId":"right0","portColor":"#8827e7","signalTypes":["#ffff00"]},{"portId":"right1","portColor":"#ffc900"}],"topArray":[],"bottomArray":[],"key":"DPS","size":"88 55","loc":"-557.84375 209.15625"},
{"name":"Control Valve (Hybrid)","color":"#ff9900","leftArray":[],"rightArray":[],"topArray":[{"portId":"top0","portColor":"#888888"},{"portId":"top1","portColor":"#888889"},{"portId":"top2","portColor":"#8827e7","signalTypes":["#ffff00","#e988e3"]},{"portId":"top3","portColor":"#e988e3","signalTypes":["#8827e7"]},{"portId":"top4","portColor":"#ff0000"},{"portId":"top5","portColor":"#000000","signalTypes":["#000000","#000001"]}],"bottomArray":[],"key":"valve3","size":"96 59","loc":"-48.6875 437.859375"}
],
  "linkDataArray": [
{"from":"24VDC","to":"node","fromPort":"left0","toPort":"top20","points":[193.15625,36.125,175.15625,36.125,49.15625,36.125,49.15625,53.625,49.15625,71.125,49.15625,89.125]},
{"from":"24VDC","to":"node","fromPort":"left2","toPort":"top21","points":[193.15625,46.125,183.15625,46.125,59.15625,46.125,59.15625,62.625,59.15625,79.125,59.15625,89.125]},
{"from":"MQTT","to":"node","fromPort":"bottom0","toPort":"top16","points":[70.8125,-39.25,70.8125,-25.25,70.8125,-11.0625,9.15625,-11.0625,9.15625,39.125,9.15625,89.125]},
{"from":"ntc","to":"node","fromPort":"right1","toPort":"left1","points":[-512.84375,36.15625,-502.84375,36.15625,-345.59375,36.15625,-345.59375,112.125,-220.34375,112.125,-198.34375,112.125]},
{"from":"ntc","to":"node","fromPort":"right0","toPort":"left0","points":[-512.84375,26.15625,-494.84375,26.15625,-337.59375,26.15625,-337.59375,102.125,-212.34375,102.125,-198.34375,102.125]},
{"from":"ntc2","to":"node","fromPort":"right1","toPort":"left3","points":[-510.84375,90.15625,-500.84375,90.15625,-364.84375,90.15625,-364.84375,132.125,-236.34375,132.125,-198.34375,132.125]},
{"from":"ntc2","to":"node","fromPort":"right0","toPort":"left2","points":[-510.84375,80.15625,-492.84375,80.15625,-356.84375,80.15625,-356.84375,122.125,-228.34375,122.125,-198.34375,122.125]},
{"from":"DPS","to":"node","fromPort":"right3","toPort":"left5","points":[-504.84375,204.15625,-482.84375,204.15625,-369.59375,204.15625,-369.59375,152.125,-288.34375,152.125,-198.34375,152.125]},
{"from":"DPS","to":"node","fromPort":"right0","toPort":"left7","points":[-504.84375,214.15625,-474.84375,214.15625,-357.59375,214.15625,-357.59375,172.125,-272.34375,172.125,-198.34375,172.125]},
{"from":"node","to":"DPS","fromPort":"left4","toPort":"right2","points":[-198.34375,142.125,-296.34375,142.125,-380.84375,142.125,-380.84375,194.15625,-490.84375,194.15625,-504.84375,194.15625]},
{"from":"DPS","to":"node","fromPort":"right1","toPort":"top1","points":[-504.84375,224.15625,-466.84375,224.15625,-320.59375,224.15625,-320.59375,66.125,-140.84375,66.125,-140.84375,88.125]},
{"from":"valve3","to":"node","fromPort":"top3","toPort":"right14","points":[-43.6875,399.359375,-43.6875,373.359375,-43.6875,339.7421875,188.65625,339.7421875,188.65625,162.125,106.65625,162.125]},
{"from":"valve3","to":"node","fromPort":"top2","toPort":"left9","points":[-53.6875,399.359375,-53.6875,369.359375,-53.6875,337.7421875,-256.34375,337.7421875,-256.34375,192.125,-198.34375,192.125]},
{"from":"valve3","to":"node","fromPort":"top1","toPort":"bottom1","points":[-63.6875,399.359375,-63.6875,377.359375,-63.6875,377.359375,-100.84375,377.359375,-100.84375,372.125,-100.84375,266.125]},
{"from":"valve3","to":"node","fromPort":"top0","toPort":"bottom0","points":[-73.6875,399.359375,-73.6875,385.359375,-73.6875,385.359375,-110.84375,385.359375,-110.84375,380.125,-110.84375,266.125]},
{"from":"valve3","to":"node","fromPort":"top5","toPort":"right15","points":[-23.6875,399.359375,-23.6875,389.359375,-23.6875,347.7421875,180.65625,347.7421875,180.65625,172.125,106.65625,172.125]},
{"from":"valve3","to":"node","fromPort":"top4","toPort":"bottom18","points":[-33.6875,399.359375,-33.6875,381.359375,-33.6875,280.15625,-10.84375,280.15625,-10.84375,360.125,-10.84375,266.125]}
]}
</pre>


== Modbus Registers ==
== Modbus Registers ==
Line 23: Line 93:
[[File:Belimo modbus2.png|535x535px]]
[[File:Belimo modbus2.png|535x535px]]


== Connecting via FTDI Cable ==
=== JSON Description ===
FTDI -> Actuator
<pre>
[
    {
        "register": "1",
        "reading": "dat.setpoint",
        "multiplier": "100",
        "datatype": "int16"
    },
    {
        "register": "2",
        "reading": "dat.overrideControl",
        "multiplier": "1",
        "datatype": "int16",
        "values": {
            "0": "none",
            "1": "open",
            "2": "close",
            "3": "min",
            "4": "mid",
            "5": "max"
        }
    },
    {
        "register": "3",
        "reading": "dat.command",
        "multiplier": "1",
        "datatype": "int16"
    },
    {
        "register": "4",
        "reading": "dat.actuatorType",
        "multiplier": "1",
        "datatype": "int16",
        "values": {
            "0": "Actuator Not Connected",
            "1": "Air / Water",
            "2": "VAV / EPIV",
            "3": "Fire",
            "4": "Energy Valve",
            "5": "6way EPIV"
        }
    },
    {
        "register": "5",
        "reading": "dat.relativePosition",
        "multiplier": "100",
        "datatype": "int16",
        "units": "%"
    },
    {
        "register": "6",
        "reading": "dat.absolutePosition",
        "multiplier": "1",
        "datatype": "int16",
        "units": "mm"
    },
    {
        "register": "6",
        "reading": "dat.sensorValue1",
        "multiplier": "1",
        "datatype": "int16"
    },
    {
        "register": "13",
        "reading": "dat.setpointAnalogue",
        "multiplier": "100",
        "datatype": "int16",
        "units": "%"
    },
    {
        "register": "100",
        "reading": "settings.busTermination",
        "multiplier": "1",
        "datatype": "int16",
        "values": {
            "0": "inactive",
            "1": "active"
        }
    },
    {
        "register": "101",
        "reading": "stat.seriesNumberPart1",
        "multiplier": "1",
        "datatype": "int16"
    },
    {
        "register": "102",
        "reading": "stat.seriesNumberPart2",
        "multiplier": "1",
        "datatype": "int16"
    },
    {
        "register": "103",
        "reading": "stat.seriesNumberPart3",
        "multiplier": "1",
        "datatype": "int16"
    },
    {
        "register": "104",
        "reading": "stat.firmwareVirsion",
        "multiplier": "1",
        "datatype": "int16"
    },
    {
        "register": "106",
        "reading": "settings.min",
        "multiplier": "100",
        "datatype": "int16",
        "units": "%"
    },
    {
        "register": "107",
        "reading": "settings.max",
        "multiplier": "100",
        "datatype": "int16",
        "units": "%"
    },
    {
        "register": "108",
        "reading": "settings.sensorType1",
        "multiplier": "1",
        "datatype": "int16",
        "values": {
            "0": "None",
            "1": "Active / Hybrid",
            "2": "Passive_1K",
            "3": "Passive_20K",
            "4": "Switch",
            "5": "PT1000_C",
            "6": "NI1000_C",
            "7": "NTC10K_C",
            "8": "PT1000_F",
            "9": "NI1000_F",
            "10": "NTC10K_F"
        }
    },
    {
        "register": "109",
        "reading": "settings.busFailPosition",
        "multiplier": "1",
        "datatype": "int16",
        "values": {
            "0": "None / Last setpoint",
            "1": "Fast close",
            "2": "Fast open",
            "3": "Mid position"
        }
    },
    {
        "register": "110",
        "reading": "settings.watchdogTimeout",
        "multiplier": "1",
        "datatype": "int16",
        "units": "s"
    }
]
</pre>


Orange -> Grey
<br>


Yellow -> Pink
== Control Modes ==
Modbus register 119 is used to set the control mode:  0: Analog 1: Modbus (see example commands).


Black  -> Not Connected
=== Modbus Control ===
The valve setpoint is controlled through register 1.
 
=== Analogue Control ===
The valve setpoint is controlled through the analogue input connection using a 2-10v signal.
 
=== Analogue Hybrid Mode ===
Refers to analogue control with Modbus connected for additional functions.
 
<br>
 
== Wiring ==
 
=== Actuator Wiring ===
[[File:R24amod.png|frameless|551x551px]]
 
 
=== Controller Wiring Modbus Only ===
[[File:Seqbel2.png|frameless|647x647px]]
 
 
=== Controller Wiring Modbus and Analogue ===
[[File:Seqbel1.png|frameless|688x688px]]
 
 
 
=== Connecting via FTDI Cable ===
[[File:Ftdicable.jpg|right|frameless|195x195px]]
A USB-FTDI RS485 cable can be used to connect to the actuator Modbus from a system with USB ports.
 
FTDI -> Actuator
Orange -> Grey [7]
Yellow -> Pink [6]
Black  -> Not Connected
 
* https://uk.farnell.com/ftdi/usb-rs485-we-1800-bt/cable-usb-rs485-serial-converter/dp/1740357
 
== Serial Settings ==
[[File:Belmodser.png]]
 
The serial port is setup for a Raspberry Pi's UART (on the header) for use with the [[Heatweb BEMS Hat|'''Heatweb BEMS Hat''']].  This may need changing in the serial settings to ttyUSB0 if using an FTDI cable, or a COM port if on a PC.


== Example Commands ==
== Example Commands ==
Line 46: Line 313:
  dec: [ 1, 3, 0, 12, 0, 1, 68, 9 ]
  dec: [ 1, 3, 0, 12, 0, 1, 68, 9 ]
When reading the analogue setpoint, note that analogue values less than 2v will result in unreadable values (65030+).  The valve will still be closed.
When reading the analogue setpoint, note that analogue values less than 2v will result in unreadable values (65030+).  The valve will still be closed.
=== Set to Modbus Control ===
dec: [ 1, 6, 0, 118, 0, 1, 169, 208 ]
=== Set to Analogue Control ===
dec:  [ 1, 6, 0, 118, 0, 0, 104, 16 ]


=== Open Valve 100% ===
=== Open Valve 100% ===
Line 53: Line 326:


  dec: [ 1, 6, 0, 0, 0, 0, 137, 202 ]
  dec: [ 1, 6, 0, 0, 0, 0, 137, 202 ]
== Quick Start & Testing ==
For very simple control or setup, Modbus messages can be directly injected to the serial connection as a buffer, including the CRC.
For example, to fully open the valve to 100% setpoint, the inject node would be setup as follows.
[[File:Injectbuffer.png]]
[[File:Injectbufferset.png]]
Import this example into Node-RED using the JSON below.  You can add further inject nodes from examples above.
<pre>
[{"id":"748c3615.f4aed8","type":"serial out","z":"9f18bf08.c2a65","name":"","serial":"b8be9e6d.b7861","x":2010,"y":200,"wires":[]},{"id":"973c444f7e178e38","type":"inject","z":"9f18bf08.c2a65","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"[1,6,0,0,39,16,147,246]","payloadType":"bin","x":1850,"y":200,"wires":[["748c3615.f4aed8"]]},{"id":"b8be9e6d.b7861","type":"serial-port","serialport":"/dev/ttyAMA0","serialbaud":"38400","databits":"8","parity":"none","stopbits":"2","waitfor":"","dtr":"none","rts":"none","cts":"none","dsr":"none","newline":"50","bin":"bin","out":"time","addchar":"","responsetimeout":"10000"}]
</pre>
This method is rarely used as it requires one to generate CRC codes in advance.


== CRC Calculation ==
== CRC Calculation ==
A Cyclic Redundancy Check is a value at the end of a Modbus message that is calculated from the message and can be used to check that received message is uncorrupted.
A Cyclic Redundancy Check is a value at the end of a Modbus message that is calculated from the message and can be used to check that received message is uncorrupted.


The following function takes a buffer as an input.  For example, n the Close Valve example above, the input is [ 1, 6, 0, 0, 0, 0 ] and the calculated crc value is [137, 202 ].  
The following function takes a buffer as an input.  For example, in the Close Valve example above, the input is [ 1, 6, 0, 0, 0, 0 ] and the calculated crc value is [137, 202 ].  
  function crc16(buffer) {
  function crc16(buffer) {
   
   
Line 81: Line 372:
  }
  }


== FC3 Read Register Function ==
== FC3 Read and FC6 Write Register Functions ==
The following function can be used to read values using FC3 command.
The following function can be used to read values using FC3 command, and to write values using FC£ command, using pure JavaScript.


It takes an input msg as follows:
It takes an input msg as follows:


  msg.fc = 6;
  msg.payload = { fc:3, address:1, register:1, rlength:1 };   // Read FC3
  msg.address = 1;
 
msg.register = 1;
  msg.payload = { fc:6, address:1, register:1, rlength:1, targetv:5000 };   // Write FC6
msg.rlength = 1;
msg.targetv = 5000;


  var address = msg.payload.address || msg.address ||8;
  var address = msg.payload.address || msg.address ||8;
  var fc = msg.payload.fc || msg.fc ;
  var fc = msg.payload.fc || msg.fc || 3;
  var register = msg.payload.register || msg.register || 1;
  var register = msg.payload.register || msg.register || 1;
var rlength = msg.payload.rlength || msg.rlength || 1;
var targetv = msg.targetv;
 
register = register - 1;  // offset
   
   
register = register - 1;
var rlength = msg.payload.rlength || msg.rlength || 1;
  var r1 = Math.floor(register / 256);
  var r1 = Math.floor(register / 256);
  var r2 = register % 256;
  var r2 = register % 256;
   
   
var targetv = msg.targetv; //999;
   
   
if (fc != 3 && fc != 6) { return null; }
  if (fc == 3) {  // Read FC3
  if (fc == 3) {   
      
      
     var tosend = String.fromCharCode(devAddress) + String.fromCharCode(3);
     var tosend = String.fromCharCode(devAddress) + String.fromCharCode(3);
Line 114: Line 400:
      
      
     var crcString = crc16(Buffer.from(tosend, 'ascii'));
     var crcString = crc16(Buffer.from(tosend, 'ascii'));
     tosend += String.fromCharCode(parseInt(crcString.substr(2,2),16)) + String.fromCharCode(parseInt(crcString.substr(0,2),16)) ;
     tosend += String.fromCharCode(parseInt(crcString.substr(2,2),16)) + String.fromCharCode(parseInt(crcString.substr(0,2),16));   
    msg.payload  = Buffer.from(tosend, 'ascii');   
   
    return msg;
} else if (fc == 6 ) {    // Write FC6
    tosend = String.fromCharCode(address) + String.fromCharCode(6);   
    tosend += String.fromCharCode(r1) + String.fromCharCode(r2);
      
      
    targetv = parseInt(targetv);
    var hexStringValue  = "0000" + targetv.toString(16);
    hexStringValue = hexStringValue.substr(-4);       
    tosend += String.fromCharCode(parseInt(hexStringValue.substr(0,2),16)) + String.fromCharCode(parseInt(hexStringValue.substr(2,2),16));
       
    crcString = crc16(Buffer.from(tosend, 'ascii')); 
    tosend += String.fromCharCode(parseInt(crcString.substr(2,2),16)) + String.fromCharCode(parseInt(crcString.substr(0,2),16));         
     msg.payload  = Buffer.from(tosend, 'ascii');     
     msg.payload  = Buffer.from(tosend, 'ascii');     
      
      
     return msg;
     return msg;
   
   
  }
  } else  { return null; }
 
== Node-RED Flow ==
The following Node-RED flow is a working example of controlling a Belimo valve.


== Analogue Control ==
The serial port is setup for a Raspberry Pi's UART (on the header) for use with the [[Heatweb BEMS Hat|'''Heatweb BEMS Hat''']].  This may need changing in the serial settings to ttyUSB0 if using an FTDI cable, or a COM port if on a PC.<pre>
[{"id":"b2d492ed.c4def","type":"subflow","name":"rbe 3min","info":"","category":"","in":[{"x":80,"y":160,"wires":[{"id":"ee023f13.5958c"}]}],"out":[{"x":460,"y":160,"wires":[{"id":"61b66a77.aec334","port":0}]}],"env":[]},{"id":"61b66a77.aec334","type":"switch","z":"b2d492ed.c4def","name":"","property":"reset","propertyType":"msg","rules":[{"t":"null"}],"checkall":"false","repair":false,"outputs":1,"x":330,"y":160,"wires":[[]]},{"id":"23f9ad60.8b4b82","type":"change","z":"b2d492ed.c4def","name":"","rules":[{"t":"set","p":"reset","pt":"msg","to":"1","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":220,"y":120,"wires":[["ee023f13.5958c"]]},{"id":"44580c0c.eb7c04","type":"inject","z":"b2d492ed.c4def","name":"","repeat":"180","crontab":"","once":false,"onceDelay":"60","topic":"","payload":"","payloadType":"date","x":210,"y":80,"wires":[["23f9ad60.8b4b82"]]},{"id":"ee023f13.5958c","type":"rbe","z":"b2d492ed.c4def","name":"","func":"rbe","gap":"","start":"","inout":"out","property":"payload","x":200,"y":160,"wires":[["61b66a77.aec334"]]},{"id":"9f18bf08.c2a65","type":"tab","label":"Belimo Modbus","disabled":false,"info":"https://www.binaryconvert.com/convert_signed_int.html?hexadecimal=000019FD"},{"id":"19182344.741c9d","type":"function","z":"9f18bf08.c2a65","name":"","func":"//if(Buffer.from(msg.payload, 'ascii')[1]!==3) { return null; }\n\nfunction hex2bin(hex){\n    return (\"00000000\" + (parseInt(hex)).toString(2)).substr(-8);\n}\n\nfunction dec2bin(dec){\n  return (dec >>> 0).toString(2);\n}\n\nvar msg2 = { \"payload\": Buffer.from(msg.payload, 'ascii') };\n\nmsg.address = msg.payload[0];\n//msg.register = (256 * msg.payload[2]) + msg.payload[3];\nmsg.register = flow.get(\"curreg\");\n\n\nminfo = flow.get(\"registers.r\" + msg.register) || null;\ndinfo = flow.get(\"devices.\" + msg.address) || null;\n\nif (!minfo) { return null; }\nif (!dinfo) { return null; }  \n\nif (minfo.datatype==\"bits\") {\n    \n    var oot = {};\n    var bits = minfo.items.split(\",\");\n    var bc=15;\n    for (var bit in bits) {\n    \n        var item = {};\n        item.payload = (256 * msg.payload[3]) + msg.payload[4];        \n        item.payload =  (\"00000000000000000\" + dec2bin(item.payload)).substr(-16);\n        item.payload =  item.payload.substr(bc,1);\n        \n        item.topic = dinfo.device + \"/\" + bits[bit].replace(\".\",\"/\");\n        \n        if (minfo[\"units\"]) { item.units = minfo[\"units\"]; }\n        item.title = (bits[bit].split(\".\")[1]?  bits[bit].split(\".\")[1]:bits[bit]) + \" [Modbus \" + msg.register + \", bit \" + bit + \"]\"; \n\n        if (minfo[\"title\"]) { item.title = minfo[\"title\"] + \", \" + item.title; }\n\n        if (minfo[\"values\"]) {\n            \n            if (minfo[\"values\"][15-bc]) {\n                if (minfo[\"values\"][15-bc][\"\" + item.payload]) { item.payload = minfo[\"values\"][15-bc][\"\" + item.payload]; }\n            }\n        }\n\n\n        \n        oot[item.topic] = item;\n        \n        bc=bc-1;\n\n    }\n    msg.payload = oot;\n    \n    return [null,msg];\n    \n    \n} else {\n    \n  \n          \n    msg.payload = (256 * msg.payload[3]) + msg.payload[4];        \n    msg.payload =  msg.payload / parseFloat(minfo[\"multiplier\"] || 1);\n\n    msg.topic = dinfo.device + \"/\" + minfo[\"reading\"].replace(\".\",\"/\");\n\n\n    if (minfo[\"values\"]) {\n        \n        if (minfo[\"values\"]==\"alarmCodes\") { \n            \n            var ac = flow.get(\"alarmCodes\");\n            if (ac[\"\" + msg.payload]) { msg.payload = ac[\"\" + msg.payload]; }\n        }\n        \n        else if (minfo[\"values\"][\"\" + msg.payload]) { msg.payload = minfo[\"values\"][\"\" + msg.payload]; }\n    }\n\n    if (minfo[\"units\"]) { msg.units = minfo[\"units\"]; }\n    //if (minfo[\"title\"]) { msg.title = minfo[\"title\"]; }\n    \n    \n    if (minfo[\"title\"]) { msg.title = minfo[\"title\"] + \" [Modbus \" + msg.register + \"]\"; }\n    else  { msg.title = (minfo[\"reading\"].split(\".\")[1]?  minfo[\"reading\"].split(\".\")[1] : minfo[\"reading\"]) + \" [Modbus \" + msg.register + \"]\"; }\n\n    return [msg,null];\n    \n}\n\n","outputs":2,"noerr":0,"x":850,"y":760,"wires":[["dc3ca7c5.e94698","86708b96.ef5ad8","5e07fd48.7736c4"],["3e19cbf3.6791d4","5ab178a1.1cde28","86708b96.ef5ad8"]]},{"id":"dc3ca7c5.e94698","type":"debug","z":"9f18bf08.c2a65","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1070,"y":640,"wires":[]},{"id":"2f4d21d5.a442be","type":"function","z":"9f18bf08.c2a65","name":"Modbus","func":"// http://www.simplymodbus.ca/FC03.htm\n//11 03 006B 0003 7687\n// 11 03 06 AE41 5652 4340 49AD\n\n// uses address 17 as default.\n\n//var offs = 0;\n//if  (msg.payload[0] === 0) { offs = 1; }\nif (!msg.payload) { msg.payload={}; }\n\nvar address = msg.payload.address || msg.address ||8;\nvar fc = msg.payload.fc || msg.fc ;\nvar register = msg.payload.register || msg.register || 1;\nflow.set(\"curreg\", register);\nflow.set(\"fc\", fc);\n\nregister = register - 1;\n\nvar rlength = msg.payload.rlength || msg.rlength || 1;\n\nvar r1 = Math.floor(register / 256);\nvar r2 = register % 256;\n\n\n\n\nvar targetv = msg.targetv; //999;\n\n\nif (fc != 3 && fc != 6) { return null; }\n\nflow.set(\"modbusIn\",\"\");\n\n//targetv = global.get(\"modbus.\"+register+\".value\") || 0;\n\n//targetv = parseInt(global.get(\"modbus.\"+register+\".multiply\") || 1) * targetv;\n\n\nfunction crc16(buffer) {\n    var crc = 0xFFFF;\n    var odd;\n\n    for (var i = 0; i < buffer.length; i++) {\n        crc = crc ^ buffer[i];\n\n        for (var j = 0; j < 8; j++) {\n            odd = crc & 0x0001;\n            crc = crc >> 1;\n            if (odd) {\n                crc = crc ^ 0xA001;\n            }\n        }\n    }\n\n    crc  = \"0000\" + crc.toString(16);\n    crc = crc.substr(-4);\n\n    return crc;\n}\n\nvar tosend = \"\";\nvar crcString =\"\";\nvar msg2={};\n \nif (fc == 3) {  // read\n\n    \n    tosend = String.fromCharCode(address) + String.fromCharCode(3);\n    tosend += String.fromCharCode(r1) + String.fromCharCode(r2);\n    tosend += String.fromCharCode(0) + String.fromCharCode(rlength);\n    \n    crcString = crc16(Buffer.from(tosend, 'ascii'));\n    tosend += String.fromCharCode(parseInt(crcString.substr(2,2),16)) + String.fromCharCode(parseInt(crcString.substr(0,2),16)) ;\n    \n    msg.payload  = Buffer.from(tosend, 'ascii');\n    \n    tosend = \"-\" + tosend;\n    \n    msg2.payload  = Buffer.from(tosend, 'ascii');\n    \n    \n    return [msg,msg2];\n\n} else if (fc == 6 ) {    // write\n\n\n    tosend = String.fromCharCode(address) + String.fromCharCode(6);\n    \n    tosend += String.fromCharCode(r1) + String.fromCharCode(r2);\n    \n    targetv = parseInt(targetv) ;\n    var hexStringValue  = \"0000\" + targetv.toString(16);\n    hexStringValue = hexStringValue.substr(-4);\n    \n    \n    tosend += String.fromCharCode(parseInt(hexStringValue.substr(0,2),16)) + String.fromCharCode(parseInt(hexStringValue.substr(2,2),16)) ;\n    \n    \n    msg.payload  = Buffer.from(tosend, 'ascii');\n    \n    crcString = crc16(msg.payload);\n  \n    tosend += String.fromCharCode(parseInt(crcString.substr(2,2),16)) + String.fromCharCode(parseInt(crcString.substr(0,2),16)) ;\n  \n      \n    msg.payload  = Buffer.from(tosend, 'ascii');\n    tosend = \"-\" + tosend;\n    msg2.payload  = Buffer.from(tosend, 'ascii');\n    \n    \n    return [msg,msg2];\n\n} \n\n\n","outputs":"2","noerr":0,"initialize":"","finalize":"","libs":[],"x":1000,"y":380,"wires":[["e0f88c79.9f4af","7cf5ec60.b4aa74","748c3615.f4aed8"],[]]},{"id":"5175b544.b7200c","type":"serial in","z":"9f18bf08.c2a65","name":"","serial":"b8be9e6d.b7861","x":650,"y":760,"wires":[["38612c3b.f919e4","19182344.741c9d"]]},{"id":"748c3615.f4aed8","type":"serial out","z":"9f18bf08.c2a65","name":"","serial":"b8be9e6d.b7861","x":1210,"y":380,"wires":[]},{"id":"38612c3b.f919e4","type":"debug","z":"9f18bf08.c2a65","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":730,"y":680,"wires":[]},{"id":"7cf5ec60.b4aa74","type":"debug","z":"9f18bf08.c2a65","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1210,"y":340,"wires":[]},{"id":"6cfb0711.4da528","type":"inject","z":"9f18bf08.c2a65","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"300","crontab":"","once":true,"onceDelay":"20","topic":"","payload":"registers","payloadType":"flow","x":160,"y":240,"wires":[["329d854f.d78aca"]]},{"id":"329d854f.d78aca","type":"function","z":"9f18bf08.c2a65","name":"","func":"\nvar oot = [];\n\nfor (var r in flow.get(\"registers\")) {\n    for (var d in flow.get(\"devices\")) {\n    \n    \n        var item = {};\n        item.fc = 3;\n        item.address = flow.get(\"devices.\"+d+\".address\");\n        item.register = flow.get(\"registers.\"+r+\".register\");\n        item.rlength = 1;\n\n        oot.push(item);\n        \n    }\n    \n}\n\nmsg.payload = oot;\n\nflow.set(\"msglist\",[]);\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":340,"y":240,"wires":[["d3419296.35733"]]},{"id":"bef71e0f.deefb","type":"split","z":"9f18bf08.c2a65","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":570,"y":300,"wires":[["17020088.5d3acf"]]},{"id":"2a6e4f4c.deb5d","type":"debug","z":"9f18bf08.c2a65","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":630,"y":200,"wires":[]},{"id":"ed2532f3.8b2eb","type":"link out","z":"9f18bf08.c2a65","name":"","links":["72fc070f.39dd8"],"x":1495,"y":680,"wires":[]},{"id":"3e19cbf3.6791d4","type":"split","z":"9f18bf08.c2a65","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"topic","x":1050,"y":840,"wires":[["72c274fa.6b8f9c"]]},{"id":"349371d0.2b2f3e","type":"debug","z":"9f18bf08.c2a65","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1370,"y":840,"wires":[]},{"id":"5ab178a1.1cde28","type":"debug","z":"9f18bf08.c2a65","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1070,"y":800,"wires":[]},{"id":"203b17cc.280718","type":"debug","z":"9f18bf08.c2a65","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1510,"y":780,"wires":[]},{"id":"44a3fc4e.eb1fe4","type":"function","z":"9f18bf08.c2a65","name":"1 - 119 - Analogue Control","func":"\nmsg.fc = 6;\nmsg.address = 1;\nmsg.register = 119;\nmsg.rlength = 1;\n\nflow.set(\"multiply\", 1);\nflow.set(\"rtopic\", \"test\");\n\n\nmsg.targetv = 0;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":370,"y":640,"wires":[["33ad8fe7.e6b4"]]},{"id":"cb15d2ed.3f48d","type":"inject","z":"9f18bf08.c2a65","name":"","repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":160,"y":640,"wires":[["44a3fc4e.eb1fe4"]]},{"id":"14e7567b.06d12a","type":"function","z":"9f18bf08.c2a65","name":"1- 1 - Setpoint 0%","func":"\nmsg.fc = 6;\nmsg.address = 1;\nmsg.register = 1;\nmsg.rlength = 1;\n\nflow.set(\"multiply\", 1);\nflow.set(\"rtopic\", \"test\");\n\n\nmsg.targetv = 0;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":390,"y":500,"wires":[["33ad8fe7.e6b4"]]},{"id":"78197e95.d9a76","type":"inject","z":"9f18bf08.c2a65","name":"","props":[{"p":"payload","v":"","vt":"date"},{"p":"topic","v":"","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":160,"y":500,"wires":[["14e7567b.06d12a"]]},{"id":"10d76ef9.420971","type":"function","z":"9f18bf08.c2a65","name":"Read Key Registers","func":"\n\nvar oot = [];\n\n    for (var d in flow.get(\"devices\")) {\n    \n    \n        var item = {};\n        item.fc = 3;\n        item.address = flow.get(\"devices.\"+d+\".address\");\n        item.register = 5;\n        item.rlength = 1;\n\n        oot.push(item);\n        \n        \n        item = {};\n        item.fc = 3;\n        item.address = flow.get(\"devices.\"+d+\".address\");\n        item.register = 6;\n        item.rlength = 1;\n\n        oot.push(item);\n        \n  \n        \n    }\n    \n\n\nmsg.payload = oot;\n\n\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":380,"y":300,"wires":[["bef71e0f.deefb"]]},{"id":"446f5a59.fe8d44","type":"inject","z":"9f18bf08.c2a65","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"10","crontab":"","once":false,"onceDelay":0.1,"topic":"","payloadType":"date","x":170,"y":300,"wires":[["10d76ef9.420971"]]},{"id":"17020088.5d3acf","type":"function","z":"9f18bf08.c2a65","name":"SHIFT","func":"\nvar msglist=flow.get(\"msglist\") || [];\n\n//if (msglist.length> 100) { msglist = []; }\n    \nif (msg.payload == \"next\") { \n    \n    if (!msglist[0]) { return null; }\n    \n    if (flow.get(\"modbusIn\")===\"\") { return null; }\n    \n    msg = msglist[0];\n    msglist.shift();\n    flow.set(\"msglist\",msglist);\n    return msg;\n}\n\nelse {  \n    \n    msglist.push(msg); \n    flow.set(\"msglist\",msglist);\n    return null;\n    \n}\n\n\n\n\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":830,"y":380,"wires":[["2f4d21d5.a442be"]]},{"id":"5a484812.f02ea8","type":"inject","z":"9f18bf08.c2a65","name":"","props":[{"p":"payload","v":"next","vt":"str"},{"p":"topic","v":"","vt":"string"}],"repeat":"1","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"next","payloadType":"str","x":610,"y":400,"wires":[["17020088.5d3acf"]]},{"id":"86708b96.ef5ad8","type":"link out","z":"9f18bf08.c2a65","name":"","links":["c4e46a82.1c9e7","7518a87f.5d7068"],"x":1015,"y":760,"wires":[]},{"id":"e0f88c79.9f4af","type":"trigger","z":"9f18bf08.c2a65","name":"","op1":"reading","op2":"done","op1type":"str","op2type":"str","duration":"1","extend":true,"units":"s","reset":"","bytopic":"all","outputs":1,"x":1200,"y":460,"wires":[["aa894598.5858c8"]]},{"id":"aa894598.5858c8","type":"change","z":"9f18bf08.c2a65","name":"","rules":[{"t":"set","p":"modbusIn","pt":"flow","to":"xxx","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1370,"y":460,"wires":[[]]},{"id":"7518a87f.5d7068","type":"link in","z":"9f18bf08.c2a65","name":"","links":["86708b96.ef5ad8"],"x":595,"y":460,"wires":[["e857ae6f.a401"]]},{"id":"e857ae6f.a401","type":"change","z":"9f18bf08.c2a65","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"next","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":720,"y":460,"wires":[["17020088.5d3acf"]]},{"id":"c8c036ab.563c08","type":"inject","z":"9f18bf08.c2a65","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"10","crontab":"","once":true,"onceDelay":0.1,"topic":"","payloadType":"date","x":1010,"y":460,"wires":[["e0f88c79.9f4af"]]},{"id":"85deb34b.0c993","type":"link in","z":"9f18bf08.c2a65","name":"","links":["c330631c.9a504","2db0089.690c2f8","be5ca099.80857","5dbf074d.dd7078","315cd92.2bca026"],"x":635,"y":360,"wires":[["17020088.5d3acf"]]},{"id":"c330631c.9a504","type":"link out","z":"9f18bf08.c2a65","name":"","links":["85deb34b.0c993","479e65f4.abc6cc"],"x":815,"y":560,"wires":[]},{"id":"72c274fa.6b8f9c","type":"function","z":"9f18bf08.c2a65","name":"","func":"msg= msg.payload;\nreturn msg;","outputs":1,"noerr":0,"x":1190,"y":840,"wires":[["349371d0.2b2f3e","e14c6575.623d68"]]},{"id":"e14c6575.623d68","type":"subflow:b2d492ed.c4def","z":"9f18bf08.c2a65","name":"","x":1280,"y":760,"wires":[["ed2532f3.8b2eb","203b17cc.280718"]]},{"id":"89b77ab4.3c2838","type":"function","z":"9f18bf08.c2a65","name":"1 - 1 - Setpoint 50%","func":"\nmsg.fc = 6;\nmsg.address = 1;\nmsg.register = 1;\nmsg.rlength = 1;\n\nflow.set(\"multiply\", 1);\nflow.set(\"rtopic\", \"test\");\n\n\nmsg.targetv = 5000;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":380,"y":540,"wires":[["33ad8fe7.e6b4"]]},{"id":"4997a59c.4f2acc","type":"inject","z":"9f18bf08.c2a65","name":"","repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":160,"y":540,"wires":[["89b77ab4.3c2838"]]},{"id":"33ad8fe7.e6b4","type":"change","z":"9f18bf08.c2a65","name":"","rules":[{"t":"delete","p":"msglist","pt":"flow"}],"action":"","property":"","from":"","to":"","reg":false,"x":650,"y":560,"wires":[["c330631c.9a504"]]},{"id":"a66bfaa4.b844c8","type":"function","z":"9f18bf08.c2a65","name":"1 - 1 - Setpoint 100%","func":"\nmsg.fc = 6;\nmsg.address = 1;\nmsg.register = 1;\nmsg.rlength = 1;\n\nflow.set(\"multiply\", 1);\nflow.set(\"rtopic\", \"test\");\n\n\nmsg.targetv = 10000;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":380,"y":580,"wires":[["33ad8fe7.e6b4"]]},{"id":"b646f6a1.46b738","type":"inject","z":"9f18bf08.c2a65","name":"","repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":160,"y":580,"wires":[["a66bfaa4.b844c8"]]},{"id":"2e03727d.2ee90e","type":"delay","z":"9f18bf08.c2a65","name":"","pauseType":"rate","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":630,"y":240,"wires":[["17020088.5d3acf"]]},{"id":"d3419296.35733","type":"split","z":"9f18bf08.c2a65","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":470,"y":240,"wires":[["2e03727d.2ee90e","2a6e4f4c.deb5d"]]},{"id":"655578e3.f19378","type":"change","z":"9f18bf08.c2a65","name":"","rules":[{"t":"set","p":"points","pt":"msg","to":"5000","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1260,"y":720,"wires":[["ed2532f3.8b2eb"]]},{"id":"5e07fd48.7736c4","type":"switch","z":"9f18bf08.c2a65","name":"","property":"topic","propertyType":"msg","rules":[{"t":"cont","v":"AlarmCode","vt":"str"},{"t":"cont","v":"WarningCode","vt":"str"},{"t":"cont","v":"Position","vt":"str"},{"t":"else"}],"checkall":"true","repair":false,"outputs":4,"x":1050,"y":700,"wires":[["68ad79cd.24fde8","ed2532f3.8b2eb"],["ed2532f3.8b2eb"],["655578e3.f19378"],["e14c6575.623d68"]]},{"id":"6933c8e2.e56078","type":"inject","z":"9f18bf08.c2a65","name":"REGISTERS","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":true,"onceDelay":"10","topic":"","payload":"[{\"register\":\"1\",\"reading\":\"dat.setpoint\",\"multiplier\":\"100\",\"datatype\":\"int16\"},{\"register\":\"2\",\"reading\":\"dat.overrideControl\",\"multiplier\":\"1\",\"datatype\":\"int16\",\"values\":{\"0\":\"none\",\"1\":\"open\",\"2\":\"close\",\"3\":\"min\",\"4\":\"mid\",\"5\":\"max\"}},{\"register\":\"3\",\"reading\":\"dat.command\",\"multiplier\":\"1\",\"datatype\":\"int16\"},{\"register\":\"4\",\"reading\":\"dat.actuatorType\",\"multiplier\":\"1\",\"datatype\":\"int16\",\"values\":{\"0\":\"Actuator Not Connected\",\"1\":\"Air / Water\",\"2\":\"VAV / EPIV\",\"3\":\"Fire\",\"4\":\"Energy Valve\",\"5\":\"6way EPIV\"}},{\"register\":\"5\",\"reading\":\"dat.relativePosition\",\"multiplier\":\"100\",\"datatype\":\"int16\",\"units\":\"%\"},{\"register\":\"6\",\"reading\":\"dat.absolutePosition\",\"multiplier\":\"1\",\"datatype\":\"int16\",\"units\":\"mm\"},{\"register\":\"6\",\"reading\":\"dat.sensorValue1\",\"multiplier\":\"1\",\"datatype\":\"int16\"},{\"register\":\"13\",\"reading\":\"dat.setpointAnalogue\",\"multiplier\":\"100\",\"datatype\":\"int16\",\"units\":\"%\"},{\"register\":\"100\",\"reading\":\"settings.busTermination\",\"multiplier\":\"1\",\"datatype\":\"int16\",\"values\":{\"0\":\"inactive\",\"1\":\"active\"}},{\"register\":\"101\",\"reading\":\"stat.seriesNumberPart1\",\"multiplier\":\"1\",\"datatype\":\"int16\"},{\"register\":\"102\",\"reading\":\"stat.seriesNumberPart2\",\"multiplier\":\"1\",\"datatype\":\"int16\"},{\"register\":\"103\",\"reading\":\"stat.seriesNumberPart3\",\"multiplier\":\"1\",\"datatype\":\"int16\"},{\"register\":\"104\",\"reading\":\"stat.firmwareVirsion\",\"multiplier\":\"1\",\"datatype\":\"int16\"},{\"register\":\"106\",\"reading\":\"settings.min\",\"multiplier\":\"100\",\"datatype\":\"int16\",\"units\":\"%\"},{\"register\":\"107\",\"reading\":\"settings.max\",\"multiplier\":\"100\",\"datatype\":\"int16\",\"units\":\"%\"},{\"register\":\"108\",\"reading\":\"settings.sensorType1\",\"multiplier\":\"1\",\"datatype\":\"int16\",\"values\":{\"0\":\"None\",\"1\":\"Active / Hybrid\",\"2\":\"Passive_1K\",\"3\":\"Passive_20K\",\"4\":\"Switch\",\"5\":\"PT1000_C\",\"6\":\"NI1000_C\",\"7\":\"NTC10K_C\",\"8\":\"PT1000_F\",\"9\":\"NI1000_F\",\"10\":\"NTC10K_F\"}},{\"register\":\"109\",\"reading\":\"settings.busFailPosition\",\"multiplier\":\"1\",\"datatype\":\"int16\",\"values\":{\"0\":\"None / Last setpoint\",\"1\":\"Fast close\",\"2\":\"Fast open\",\"3\":\"Mid position\"}},{\"register\":\"110\",\"reading\":\"settings.watchdogTimeout\",\"multiplier\":\"1\",\"datatype\":\"int16\",\"units\":\"s\"}]","payloadType":"json","x":150,"y":80,"wires":[["95c42acc.304aa8"]]},{"id":"95c42acc.304aa8","type":"split","z":"9f18bf08.c2a65","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":310,"y":80,"wires":[["29e989ab.124226"]]},{"id":"29e989ab.124226","type":"function","z":"9f18bf08.c2a65","name":"Store Registers","func":"\nvar rin = msg.payload;\nif (rin.register<1) { return null; } \n\n\nvar v = global.get(\"readings.\" + rin.reading + \".value\") || 0\nrin[\"value\"] = v;\n\n\n\nflow.set(\"registers.r\" + rin.register, rin);\n\nmsg.payload = flow.get(\"registers\") ;\n    \nreturn msg;\n\n\n\n\n\n","outputs":1,"noerr":0,"x":480,"y":80,"wires":[[]]},{"id":"6d5c01a3.769db","type":"inject","z":"9f18bf08.c2a65","name":"DEVICES","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":true,"onceDelay":"10","topic":"","payload":"[{\"address\":\"1\",\"device\":\"valveSR1\"}]","payloadType":"json","x":140,"y":140,"wires":[["d0c0d129.1a35f"]]},{"id":"d0c0d129.1a35f","type":"split","z":"9f18bf08.c2a65","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":310,"y":140,"wires":[["47f84ff5.818ab"]]},{"id":"47f84ff5.818ab","type":"function","z":"9f18bf08.c2a65","name":"Store Devices","func":"\nvar rin = msg.payload;\nif (rin.address<1) { return null; } \n\n\nflow.set(\"devices.\" + rin.address, rin);\n\n\n    \nreturn msg;\n\n\n\n\n\n","outputs":1,"noerr":0,"x":480,"y":140,"wires":[[]]},{"id":"b7ec2cb5.c3f62","type":"link in","z":"9f18bf08.c2a65","name":"","links":["1f335ee0.7b9a41","b09805d5.754898"],"x":195,"y":440,"wires":[["728528de.3f5da8"]]},{"id":"68ad79cd.24fde8","type":"function","z":"9f18bf08.c2a65","name":"","func":"msg.topic = msg.topic.replace(\"/stat/\",\"/alarm/\");\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1280,"y":660,"wires":[["ed2532f3.8b2eb"]]},{"id":"728528de.3f5da8","type":"delay","z":"9f18bf08.c2a65","name":"","pauseType":"rate","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"2","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":400,"y":440,"wires":[["33ad8fe7.e6b4"]]},{"id":"52cda5dc3e02a412","type":"function","z":"9f18bf08.c2a65","name":"1 - 119 - Modbus Control","func":"\nmsg.fc = 6;\nmsg.address = 1;\nmsg.register = 119;\nmsg.rlength = 1;\n\nflow.set(\"multiply\", 1);\nflow.set(\"rtopic\", \"test\");\n\n\nmsg.targetv = 1;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":370,"y":680,"wires":[["33ad8fe7.e6b4"]]},{"id":"45607cf72a252634","type":"inject","z":"9f18bf08.c2a65","name":"","repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":160,"y":680,"wires":[["52cda5dc3e02a412"]]},{"id":"b8be9e6d.b7861","type":"serial-port","serialport":"/dev/ttyAMA0","serialbaud":"38400","databits":"8","parity":"none","stopbits":"2","waitfor":"","dtr":"none","rts":"none","cts":"none","dsr":"none","newline":"50","bin":"bin","out":"time","addchar":"","responsetimeout":"10000"}]
</pre>

Latest revision as of 19:00, 21 June 2022

Nrmodbusb.png

Belimo valves are one of the most recognised and widely used makes of valve in the HVAC industry.

The libraries on this page provide the tools to control and monitor valves
using the MQTT open controls protocol and Node-RED.


Documents

Autowiring

  1. Drag parts onto page
  2. Wire terminals together either manually, or by pressing Autowire
  3. Position parts neatly
  4. Reroute messy wires
Concons1.png



Modbus Registers

Note that the register number is one more than address.

Operation Registers

Belimo modbus1.png

Service Registers

Belimo modbus2.png

JSON Description

[
    {
        "register": "1",
        "reading": "dat.setpoint",
        "multiplier": "100",
        "datatype": "int16"
    },
    {
        "register": "2",
        "reading": "dat.overrideControl",
        "multiplier": "1",
        "datatype": "int16",
        "values": {
            "0": "none",
            "1": "open",
            "2": "close",
            "3": "min",
            "4": "mid",
            "5": "max"
        }
    },
    {
        "register": "3",
        "reading": "dat.command",
        "multiplier": "1",
        "datatype": "int16"
    },
    {
        "register": "4",
        "reading": "dat.actuatorType",
        "multiplier": "1",
        "datatype": "int16",
        "values": {
            "0": "Actuator Not Connected",
            "1": "Air / Water",
            "2": "VAV / EPIV",
            "3": "Fire",
            "4": "Energy Valve",
            "5": "6way EPIV"
        }
    },
    {
        "register": "5",
        "reading": "dat.relativePosition",
        "multiplier": "100",
        "datatype": "int16",
        "units": "%"
    },
    {
        "register": "6",
        "reading": "dat.absolutePosition",
        "multiplier": "1",
        "datatype": "int16",
        "units": "mm"
    },
    {
        "register": "6",
        "reading": "dat.sensorValue1",
        "multiplier": "1",
        "datatype": "int16"
    },
    {
        "register": "13",
        "reading": "dat.setpointAnalogue",
        "multiplier": "100",
        "datatype": "int16",
        "units": "%"
    },
    {
        "register": "100",
        "reading": "settings.busTermination",
        "multiplier": "1",
        "datatype": "int16",
        "values": {
            "0": "inactive",
            "1": "active"
        }
    },
    {
        "register": "101",
        "reading": "stat.seriesNumberPart1",
        "multiplier": "1",
        "datatype": "int16"
    },
    {
        "register": "102",
        "reading": "stat.seriesNumberPart2",
        "multiplier": "1",
        "datatype": "int16"
    },
    {
        "register": "103",
        "reading": "stat.seriesNumberPart3",
        "multiplier": "1",
        "datatype": "int16"
    },
    {
        "register": "104",
        "reading": "stat.firmwareVirsion",
        "multiplier": "1",
        "datatype": "int16"
    },
    {
        "register": "106",
        "reading": "settings.min",
        "multiplier": "100",
        "datatype": "int16",
        "units": "%"
    },
    {
        "register": "107",
        "reading": "settings.max",
        "multiplier": "100",
        "datatype": "int16",
        "units": "%"
    },
    {
        "register": "108",
        "reading": "settings.sensorType1",
        "multiplier": "1",
        "datatype": "int16",
        "values": {
            "0": "None",
            "1": "Active / Hybrid",
            "2": "Passive_1K",
            "3": "Passive_20K",
            "4": "Switch",
            "5": "PT1000_C",
            "6": "NI1000_C",
            "7": "NTC10K_C",
            "8": "PT1000_F",
            "9": "NI1000_F",
            "10": "NTC10K_F"
        }
    },
    {
        "register": "109",
        "reading": "settings.busFailPosition",
        "multiplier": "1",
        "datatype": "int16",
        "values": {
            "0": "None / Last setpoint",
            "1": "Fast close",
            "2": "Fast open",
            "3": "Mid position"
        }
    },
    {
        "register": "110",
        "reading": "settings.watchdogTimeout",
        "multiplier": "1",
        "datatype": "int16",
        "units": "s"
    }
]


Control Modes

Modbus register 119 is used to set the control mode: 0: Analog 1: Modbus (see example commands).

Modbus Control

The valve setpoint is controlled through register 1.

Analogue Control

The valve setpoint is controlled through the analogue input connection using a 2-10v signal.

Analogue Hybrid Mode

Refers to analogue control with Modbus connected for additional functions.


Wiring

Actuator Wiring

R24amod.png


Controller Wiring Modbus Only

Seqbel2.png


Controller Wiring Modbus and Analogue

Seqbel1.png


Connecting via FTDI Cable

Ftdicable.jpg

A USB-FTDI RS485 cable can be used to connect to the actuator Modbus from a system with USB ports.

FTDI -> Actuator
Orange -> Grey [7]
Yellow -> Pink [6]
Black  -> Not Connected

Serial Settings

Belmodser.png

The serial port is setup for a Raspberry Pi's UART (on the header) for use with the Heatweb BEMS Hat. This may need changing in the serial settings to ttyUSB0 if using an FTDI cable, or a COM port if on a PC.

Example Commands

Read Modbus Setpoint

As an example, to read the Setpoint requires sending to the device (1 default) a FC3 read command (3) calling for register 1 (0 0), requesting a single value (0 1), ending with the CRC (Cyclic Redundancy Check).

In modbus the following characters would be sent to the valve over RS485 (shown in decimal and hex):

dec: [ 1, 3, 0, 0, 0, 1, 132, 10 ]  hex: [0x01, 0x03, 0x00, 0x00, 0x00, 0x01, 0x84, 0x0a]

Read Analogue Setpoint

The analogue setpoint register (13) is different from the Modbus setpoint (1). Register 119 (Sepoint Selection) choses which is valid.

dec: [ 1, 3, 0, 12, 0, 1, 68, 9 ]

When reading the analogue setpoint, note that analogue values less than 2v will result in unreadable values (65030+). The valve will still be closed.

Set to Modbus Control

dec: [ 1, 6, 0, 118, 0, 1, 169, 208 ]

Set to Analogue Control

dec:  [ 1, 6, 0, 118, 0, 0, 104, 16 ]

Open Valve 100%

dec: [ 1, 6, 0, 0, 39, 16, 147, 246 ]

Close Valve

dec: [ 1, 6, 0, 0, 0, 0, 137, 202 ]

Quick Start & Testing

For very simple control or setup, Modbus messages can be directly injected to the serial connection as a buffer, including the CRC.

For example, to fully open the valve to 100% setpoint, the inject node would be setup as follows.

Injectbuffer.png

Injectbufferset.png


Import this example into Node-RED using the JSON below. You can add further inject nodes from examples above.

[{"id":"748c3615.f4aed8","type":"serial out","z":"9f18bf08.c2a65","name":"","serial":"b8be9e6d.b7861","x":2010,"y":200,"wires":[]},{"id":"973c444f7e178e38","type":"inject","z":"9f18bf08.c2a65","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"[1,6,0,0,39,16,147,246]","payloadType":"bin","x":1850,"y":200,"wires":[["748c3615.f4aed8"]]},{"id":"b8be9e6d.b7861","type":"serial-port","serialport":"/dev/ttyAMA0","serialbaud":"38400","databits":"8","parity":"none","stopbits":"2","waitfor":"","dtr":"none","rts":"none","cts":"none","dsr":"none","newline":"50","bin":"bin","out":"time","addchar":"","responsetimeout":"10000"}]

This method is rarely used as it requires one to generate CRC codes in advance.

CRC Calculation

A Cyclic Redundancy Check is a value at the end of a Modbus message that is calculated from the message and can be used to check that received message is uncorrupted.

The following function takes a buffer as an input. For example, in the Close Valve example above, the input is [ 1, 6, 0, 0, 0, 0 ] and the calculated crc value is [137, 202 ].

function crc16(buffer) {

    var crc = 0xFFFF;
    var odd;

    for (var i = 0; i < buffer.length; i++) {
        crc = crc ^ buffer[i];

        for (var j = 0; j < 8; j++) {
            odd = crc & 0x0001;
            crc = crc >> 1;
            if (odd) {
                crc = crc ^ 0xA001;
            }
        }
    }

    crc  = "0000" + crc.toString(16);
    crc = crc.substr(-4);

    return crc;
}

FC3 Read and FC6 Write Register Functions

The following function can be used to read values using FC3 command, and to write values using FC£ command, using pure JavaScript.

It takes an input msg as follows:

msg.payload = { fc:3, address:1, register:1, rlength:1 };   // Read FC3
msg.payload = { fc:6, address:1, register:1, rlength:1, targetv:5000 };   // Write FC6
var address = msg.payload.address || msg.address ||8;
var fc = msg.payload.fc || msg.fc || 3;
var register = msg.payload.register || msg.register || 1;
var rlength = msg.payload.rlength || msg.rlength || 1;
var targetv = msg.targetv; 
 
register = register - 1;  // offset 

var r1 = Math.floor(register / 256);
var r2 = register % 256;


if (fc == 3) {   // Read FC3
    
    var tosend = String.fromCharCode(devAddress) + String.fromCharCode(3);
    tosend += String.fromCharCode(r1) + String.fromCharCode(r2);
    tosend += String.fromCharCode(0) + String.fromCharCode(rlength);
    
    var crcString = crc16(Buffer.from(tosend, 'ascii'));
    tosend += String.fromCharCode(parseInt(crcString.substr(2,2),16)) + String.fromCharCode(parseInt(crcString.substr(0,2),16));    
    msg.payload  = Buffer.from(tosend, 'ascii');    
    
    return msg;


} else if (fc == 6 ) {     // Write FC6


    tosend = String.fromCharCode(address) + String.fromCharCode(6);    
    tosend += String.fromCharCode(r1) + String.fromCharCode(r2);
    
    targetv = parseInt(targetv);
    var hexStringValue  = "0000" + targetv.toString(16);
    hexStringValue = hexStringValue.substr(-4);        
    tosend += String.fromCharCode(parseInt(hexStringValue.substr(0,2),16)) + String.fromCharCode(parseInt(hexStringValue.substr(2,2),16));
        
    crcString = crc16(Buffer.from(tosend, 'ascii'));   
    tosend += String.fromCharCode(parseInt(crcString.substr(2,2),16)) + String.fromCharCode(parseInt(crcString.substr(0,2),16));          
    msg.payload  = Buffer.from(tosend, 'ascii');    
    
    return msg;


} else  { return null; }

Node-RED Flow

The following Node-RED flow is a working example of controlling a Belimo valve.

The serial port is setup for a Raspberry Pi's UART (on the header) for use with the Heatweb BEMS Hat. This may need changing in the serial settings to ttyUSB0 if using an FTDI cable, or a COM port if on a PC.

[{"id":"b2d492ed.c4def","type":"subflow","name":"rbe 3min","info":"","category":"","in":[{"x":80,"y":160,"wires":[{"id":"ee023f13.5958c"}]}],"out":[{"x":460,"y":160,"wires":[{"id":"61b66a77.aec334","port":0}]}],"env":[]},{"id":"61b66a77.aec334","type":"switch","z":"b2d492ed.c4def","name":"","property":"reset","propertyType":"msg","rules":[{"t":"null"}],"checkall":"false","repair":false,"outputs":1,"x":330,"y":160,"wires":[[]]},{"id":"23f9ad60.8b4b82","type":"change","z":"b2d492ed.c4def","name":"","rules":[{"t":"set","p":"reset","pt":"msg","to":"1","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":220,"y":120,"wires":[["ee023f13.5958c"]]},{"id":"44580c0c.eb7c04","type":"inject","z":"b2d492ed.c4def","name":"","repeat":"180","crontab":"","once":false,"onceDelay":"60","topic":"","payload":"","payloadType":"date","x":210,"y":80,"wires":[["23f9ad60.8b4b82"]]},{"id":"ee023f13.5958c","type":"rbe","z":"b2d492ed.c4def","name":"","func":"rbe","gap":"","start":"","inout":"out","property":"payload","x":200,"y":160,"wires":[["61b66a77.aec334"]]},{"id":"9f18bf08.c2a65","type":"tab","label":"Belimo Modbus","disabled":false,"info":"https://www.binaryconvert.com/convert_signed_int.html?hexadecimal=000019FD"},{"id":"19182344.741c9d","type":"function","z":"9f18bf08.c2a65","name":"","func":"//if(Buffer.from(msg.payload, 'ascii')[1]!==3) { return null; }\n\nfunction hex2bin(hex){\n    return (\"00000000\" + (parseInt(hex)).toString(2)).substr(-8);\n}\n\nfunction dec2bin(dec){\n  return (dec >>> 0).toString(2);\n}\n\nvar msg2 = { \"payload\": Buffer.from(msg.payload, 'ascii') };\n\nmsg.address = msg.payload[0];\n//msg.register = (256 * msg.payload[2]) + msg.payload[3];\nmsg.register = flow.get(\"curreg\");\n\n\nminfo = flow.get(\"registers.r\" + msg.register) || null;\ndinfo = flow.get(\"devices.\" + msg.address) || null;\n\nif (!minfo) { return null; }\nif (!dinfo) { return null; }  \n\nif (minfo.datatype==\"bits\") {\n    \n    var oot = {};\n    var bits = minfo.items.split(\",\");\n    var bc=15;\n    for (var bit in bits) {\n    \n        var item = {};\n        item.payload = (256 * msg.payload[3]) + msg.payload[4];        \n        item.payload =   (\"00000000000000000\" + dec2bin(item.payload)).substr(-16);\n        item.payload =  item.payload.substr(bc,1);\n        \n        item.topic = dinfo.device + \"/\" + bits[bit].replace(\".\",\"/\");\n        \n        if (minfo[\"units\"]) { item.units = minfo[\"units\"]; }\n        item.title = (bits[bit].split(\".\")[1]?  bits[bit].split(\".\")[1]:bits[bit]) + \" [Modbus \" + msg.register + \", bit \" + bit + \"]\"; \n\n        if (minfo[\"title\"]) { item.title = minfo[\"title\"] + \", \" + item.title; }\n\n        if (minfo[\"values\"]) {\n            \n            if (minfo[\"values\"][15-bc]) {\n                if (minfo[\"values\"][15-bc][\"\" + item.payload]) { item.payload = minfo[\"values\"][15-bc][\"\" + item.payload]; }\n            }\n        }\n\n\n        \n        oot[item.topic] = item;\n        \n        bc=bc-1;\n\n    }\n    msg.payload = oot;\n    \n    return [null,msg];\n    \n    \n} else {\n    \n   \n           \n    msg.payload = (256 * msg.payload[3]) + msg.payload[4];        \n    msg.payload =  msg.payload / parseFloat(minfo[\"multiplier\"] || 1);\n\n    msg.topic = dinfo.device + \"/\" + minfo[\"reading\"].replace(\".\",\"/\");\n\n\n    if (minfo[\"values\"]) {\n        \n        if (minfo[\"values\"]==\"alarmCodes\") { \n            \n            var ac = flow.get(\"alarmCodes\");\n            if (ac[\"\" + msg.payload]) { msg.payload = ac[\"\" + msg.payload]; }\n        }\n        \n        else if (minfo[\"values\"][\"\" + msg.payload]) { msg.payload = minfo[\"values\"][\"\" + msg.payload]; }\n    }\n\n    if (minfo[\"units\"]) { msg.units = minfo[\"units\"]; }\n    //if (minfo[\"title\"]) { msg.title = minfo[\"title\"]; }\n    \n    \n    if (minfo[\"title\"]) { msg.title = minfo[\"title\"] + \" [Modbus \" + msg.register + \"]\"; }\n    else  { msg.title = (minfo[\"reading\"].split(\".\")[1]?  minfo[\"reading\"].split(\".\")[1] : minfo[\"reading\"]) + \" [Modbus \" + msg.register + \"]\"; }\n\n    return [msg,null];\n    \n}\n\n","outputs":2,"noerr":0,"x":850,"y":760,"wires":[["dc3ca7c5.e94698","86708b96.ef5ad8","5e07fd48.7736c4"],["3e19cbf3.6791d4","5ab178a1.1cde28","86708b96.ef5ad8"]]},{"id":"dc3ca7c5.e94698","type":"debug","z":"9f18bf08.c2a65","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1070,"y":640,"wires":[]},{"id":"2f4d21d5.a442be","type":"function","z":"9f18bf08.c2a65","name":"Modbus","func":"// http://www.simplymodbus.ca/FC03.htm\n//11 03 006B 0003 7687\n// 11 03 06 AE41 5652 4340 49AD\n\n// uses address 17 as default.\n\n//var offs = 0;\n//if  (msg.payload[0] === 0) { offs = 1; }\nif (!msg.payload) { msg.payload={}; }\n\nvar address = msg.payload.address || msg.address ||8;\nvar fc = msg.payload.fc || msg.fc ;\nvar register = msg.payload.register || msg.register || 1;\nflow.set(\"curreg\", register);\nflow.set(\"fc\", fc);\n\nregister = register - 1;\n\nvar rlength = msg.payload.rlength || msg.rlength || 1;\n\nvar r1 = Math.floor(register / 256);\nvar r2 = register % 256;\n\n\n\n\nvar targetv = msg.targetv; //999;\n\n\nif (fc != 3 && fc != 6) { return null; }\n\nflow.set(\"modbusIn\",\"\");\n\n//targetv = global.get(\"modbus.\"+register+\".value\") || 0;\n\n//targetv = parseInt(global.get(\"modbus.\"+register+\".multiply\") || 1) * targetv;\n\n\nfunction crc16(buffer) {\n    var crc = 0xFFFF;\n    var odd;\n\n    for (var i = 0; i < buffer.length; i++) {\n        crc = crc ^ buffer[i];\n\n        for (var j = 0; j < 8; j++) {\n            odd = crc & 0x0001;\n            crc = crc >> 1;\n            if (odd) {\n                crc = crc ^ 0xA001;\n            }\n        }\n    }\n\n    crc  = \"0000\" + crc.toString(16);\n    crc = crc.substr(-4);\n\n    return crc;\n}\n\nvar tosend = \"\";\nvar crcString =\"\";\nvar msg2={};\n \nif (fc == 3) {   // read\n\n    \n    tosend = String.fromCharCode(address) + String.fromCharCode(3);\n    tosend += String.fromCharCode(r1) + String.fromCharCode(r2);\n    tosend += String.fromCharCode(0) + String.fromCharCode(rlength);\n    \n    crcString = crc16(Buffer.from(tosend, 'ascii'));\n    tosend += String.fromCharCode(parseInt(crcString.substr(2,2),16)) + String.fromCharCode(parseInt(crcString.substr(0,2),16)) ;\n    \n    msg.payload  = Buffer.from(tosend, 'ascii');\n    \n    tosend = \"-\" + tosend;\n    \n    msg2.payload  = Buffer.from(tosend, 'ascii');\n    \n    \n    return [msg,msg2];\n\n} else if (fc == 6 ) {    // write\n\n\n    tosend = String.fromCharCode(address) + String.fromCharCode(6);\n    \n    tosend += String.fromCharCode(r1) + String.fromCharCode(r2);\n    \n    targetv = parseInt(targetv) ;\n    var hexStringValue  = \"0000\" + targetv.toString(16);\n    hexStringValue = hexStringValue.substr(-4);\n    \n    \n    tosend += String.fromCharCode(parseInt(hexStringValue.substr(0,2),16)) + String.fromCharCode(parseInt(hexStringValue.substr(2,2),16)) ;\n    \n    \n    msg.payload  = Buffer.from(tosend, 'ascii');\n    \n    crcString = crc16(msg.payload);\n   \n    tosend += String.fromCharCode(parseInt(crcString.substr(2,2),16)) + String.fromCharCode(parseInt(crcString.substr(0,2),16)) ;\n   \n       \n    msg.payload  = Buffer.from(tosend, 'ascii');\n    tosend = \"-\" + tosend;\n    msg2.payload  = Buffer.from(tosend, 'ascii');\n    \n    \n    return [msg,msg2];\n\n} \n\n\n","outputs":"2","noerr":0,"initialize":"","finalize":"","libs":[],"x":1000,"y":380,"wires":[["e0f88c79.9f4af","7cf5ec60.b4aa74","748c3615.f4aed8"],[]]},{"id":"5175b544.b7200c","type":"serial in","z":"9f18bf08.c2a65","name":"","serial":"b8be9e6d.b7861","x":650,"y":760,"wires":[["38612c3b.f919e4","19182344.741c9d"]]},{"id":"748c3615.f4aed8","type":"serial out","z":"9f18bf08.c2a65","name":"","serial":"b8be9e6d.b7861","x":1210,"y":380,"wires":[]},{"id":"38612c3b.f919e4","type":"debug","z":"9f18bf08.c2a65","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":730,"y":680,"wires":[]},{"id":"7cf5ec60.b4aa74","type":"debug","z":"9f18bf08.c2a65","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1210,"y":340,"wires":[]},{"id":"6cfb0711.4da528","type":"inject","z":"9f18bf08.c2a65","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"300","crontab":"","once":true,"onceDelay":"20","topic":"","payload":"registers","payloadType":"flow","x":160,"y":240,"wires":[["329d854f.d78aca"]]},{"id":"329d854f.d78aca","type":"function","z":"9f18bf08.c2a65","name":"","func":"\nvar oot = [];\n\nfor (var r in flow.get(\"registers\")) {\n    for (var d in flow.get(\"devices\")) {\n    \n    \n        var item = {};\n        item.fc = 3;\n        item.address = flow.get(\"devices.\"+d+\".address\");\n        item.register = flow.get(\"registers.\"+r+\".register\");\n        item.rlength = 1;\n\n        oot.push(item);\n        \n    }\n    \n}\n\nmsg.payload = oot;\n\nflow.set(\"msglist\",[]);\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":340,"y":240,"wires":[["d3419296.35733"]]},{"id":"bef71e0f.deefb","type":"split","z":"9f18bf08.c2a65","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":570,"y":300,"wires":[["17020088.5d3acf"]]},{"id":"2a6e4f4c.deb5d","type":"debug","z":"9f18bf08.c2a65","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":630,"y":200,"wires":[]},{"id":"ed2532f3.8b2eb","type":"link out","z":"9f18bf08.c2a65","name":"","links":["72fc070f.39dd8"],"x":1495,"y":680,"wires":[]},{"id":"3e19cbf3.6791d4","type":"split","z":"9f18bf08.c2a65","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"topic","x":1050,"y":840,"wires":[["72c274fa.6b8f9c"]]},{"id":"349371d0.2b2f3e","type":"debug","z":"9f18bf08.c2a65","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1370,"y":840,"wires":[]},{"id":"5ab178a1.1cde28","type":"debug","z":"9f18bf08.c2a65","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1070,"y":800,"wires":[]},{"id":"203b17cc.280718","type":"debug","z":"9f18bf08.c2a65","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1510,"y":780,"wires":[]},{"id":"44a3fc4e.eb1fe4","type":"function","z":"9f18bf08.c2a65","name":"1 - 119 - Analogue Control","func":"\nmsg.fc = 6;\nmsg.address = 1;\nmsg.register = 119;\nmsg.rlength = 1;\n\nflow.set(\"multiply\", 1);\nflow.set(\"rtopic\", \"test\");\n\n\nmsg.targetv = 0;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":370,"y":640,"wires":[["33ad8fe7.e6b4"]]},{"id":"cb15d2ed.3f48d","type":"inject","z":"9f18bf08.c2a65","name":"","repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":160,"y":640,"wires":[["44a3fc4e.eb1fe4"]]},{"id":"14e7567b.06d12a","type":"function","z":"9f18bf08.c2a65","name":"1- 1 - Setpoint 0%","func":"\nmsg.fc = 6;\nmsg.address = 1;\nmsg.register = 1;\nmsg.rlength = 1;\n\nflow.set(\"multiply\", 1);\nflow.set(\"rtopic\", \"test\");\n\n\nmsg.targetv = 0;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":390,"y":500,"wires":[["33ad8fe7.e6b4"]]},{"id":"78197e95.d9a76","type":"inject","z":"9f18bf08.c2a65","name":"","props":[{"p":"payload","v":"","vt":"date"},{"p":"topic","v":"","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":160,"y":500,"wires":[["14e7567b.06d12a"]]},{"id":"10d76ef9.420971","type":"function","z":"9f18bf08.c2a65","name":"Read Key Registers","func":"\n\nvar oot = [];\n\n    for (var d in flow.get(\"devices\")) {\n    \n    \n        var item = {};\n        item.fc = 3;\n        item.address = flow.get(\"devices.\"+d+\".address\");\n        item.register = 5;\n        item.rlength = 1;\n\n        oot.push(item);\n        \n        \n        item = {};\n        item.fc = 3;\n        item.address = flow.get(\"devices.\"+d+\".address\");\n        item.register = 6;\n        item.rlength = 1;\n\n        oot.push(item);\n        \n   \n        \n    }\n    \n\n\nmsg.payload = oot;\n\n\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":380,"y":300,"wires":[["bef71e0f.deefb"]]},{"id":"446f5a59.fe8d44","type":"inject","z":"9f18bf08.c2a65","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"10","crontab":"","once":false,"onceDelay":0.1,"topic":"","payloadType":"date","x":170,"y":300,"wires":[["10d76ef9.420971"]]},{"id":"17020088.5d3acf","type":"function","z":"9f18bf08.c2a65","name":"SHIFT","func":"\nvar msglist=flow.get(\"msglist\") || [];\n\n//if (msglist.length> 100) { msglist = []; }\n    \nif (msg.payload == \"next\") { \n    \n    if (!msglist[0]) { return null; }\n    \n    if (flow.get(\"modbusIn\")===\"\") { return null; }\n    \n    msg = msglist[0];\n    msglist.shift();\n    flow.set(\"msglist\",msglist);\n    return msg;\n}\n\nelse {   \n    \n    msglist.push(msg); \n    flow.set(\"msglist\",msglist);\n    return null;\n    \n}\n\n\n\n\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":830,"y":380,"wires":[["2f4d21d5.a442be"]]},{"id":"5a484812.f02ea8","type":"inject","z":"9f18bf08.c2a65","name":"","props":[{"p":"payload","v":"next","vt":"str"},{"p":"topic","v":"","vt":"string"}],"repeat":"1","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"next","payloadType":"str","x":610,"y":400,"wires":[["17020088.5d3acf"]]},{"id":"86708b96.ef5ad8","type":"link out","z":"9f18bf08.c2a65","name":"","links":["c4e46a82.1c9e7","7518a87f.5d7068"],"x":1015,"y":760,"wires":[]},{"id":"e0f88c79.9f4af","type":"trigger","z":"9f18bf08.c2a65","name":"","op1":"reading","op2":"done","op1type":"str","op2type":"str","duration":"1","extend":true,"units":"s","reset":"","bytopic":"all","outputs":1,"x":1200,"y":460,"wires":[["aa894598.5858c8"]]},{"id":"aa894598.5858c8","type":"change","z":"9f18bf08.c2a65","name":"","rules":[{"t":"set","p":"modbusIn","pt":"flow","to":"xxx","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1370,"y":460,"wires":[[]]},{"id":"7518a87f.5d7068","type":"link in","z":"9f18bf08.c2a65","name":"","links":["86708b96.ef5ad8"],"x":595,"y":460,"wires":[["e857ae6f.a401"]]},{"id":"e857ae6f.a401","type":"change","z":"9f18bf08.c2a65","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"next","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":720,"y":460,"wires":[["17020088.5d3acf"]]},{"id":"c8c036ab.563c08","type":"inject","z":"9f18bf08.c2a65","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"10","crontab":"","once":true,"onceDelay":0.1,"topic":"","payloadType":"date","x":1010,"y":460,"wires":[["e0f88c79.9f4af"]]},{"id":"85deb34b.0c993","type":"link in","z":"9f18bf08.c2a65","name":"","links":["c330631c.9a504","2db0089.690c2f8","be5ca099.80857","5dbf074d.dd7078","315cd92.2bca026"],"x":635,"y":360,"wires":[["17020088.5d3acf"]]},{"id":"c330631c.9a504","type":"link out","z":"9f18bf08.c2a65","name":"","links":["85deb34b.0c993","479e65f4.abc6cc"],"x":815,"y":560,"wires":[]},{"id":"72c274fa.6b8f9c","type":"function","z":"9f18bf08.c2a65","name":"","func":"msg= msg.payload;\nreturn msg;","outputs":1,"noerr":0,"x":1190,"y":840,"wires":[["349371d0.2b2f3e","e14c6575.623d68"]]},{"id":"e14c6575.623d68","type":"subflow:b2d492ed.c4def","z":"9f18bf08.c2a65","name":"","x":1280,"y":760,"wires":[["ed2532f3.8b2eb","203b17cc.280718"]]},{"id":"89b77ab4.3c2838","type":"function","z":"9f18bf08.c2a65","name":"1 - 1 - Setpoint 50%","func":"\nmsg.fc = 6;\nmsg.address = 1;\nmsg.register = 1;\nmsg.rlength = 1;\n\nflow.set(\"multiply\", 1);\nflow.set(\"rtopic\", \"test\");\n\n\nmsg.targetv = 5000;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":380,"y":540,"wires":[["33ad8fe7.e6b4"]]},{"id":"4997a59c.4f2acc","type":"inject","z":"9f18bf08.c2a65","name":"","repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":160,"y":540,"wires":[["89b77ab4.3c2838"]]},{"id":"33ad8fe7.e6b4","type":"change","z":"9f18bf08.c2a65","name":"","rules":[{"t":"delete","p":"msglist","pt":"flow"}],"action":"","property":"","from":"","to":"","reg":false,"x":650,"y":560,"wires":[["c330631c.9a504"]]},{"id":"a66bfaa4.b844c8","type":"function","z":"9f18bf08.c2a65","name":"1 - 1 - Setpoint 100%","func":"\nmsg.fc = 6;\nmsg.address = 1;\nmsg.register = 1;\nmsg.rlength = 1;\n\nflow.set(\"multiply\", 1);\nflow.set(\"rtopic\", \"test\");\n\n\nmsg.targetv = 10000;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":380,"y":580,"wires":[["33ad8fe7.e6b4"]]},{"id":"b646f6a1.46b738","type":"inject","z":"9f18bf08.c2a65","name":"","repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":160,"y":580,"wires":[["a66bfaa4.b844c8"]]},{"id":"2e03727d.2ee90e","type":"delay","z":"9f18bf08.c2a65","name":"","pauseType":"rate","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":630,"y":240,"wires":[["17020088.5d3acf"]]},{"id":"d3419296.35733","type":"split","z":"9f18bf08.c2a65","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":470,"y":240,"wires":[["2e03727d.2ee90e","2a6e4f4c.deb5d"]]},{"id":"655578e3.f19378","type":"change","z":"9f18bf08.c2a65","name":"","rules":[{"t":"set","p":"points","pt":"msg","to":"5000","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1260,"y":720,"wires":[["ed2532f3.8b2eb"]]},{"id":"5e07fd48.7736c4","type":"switch","z":"9f18bf08.c2a65","name":"","property":"topic","propertyType":"msg","rules":[{"t":"cont","v":"AlarmCode","vt":"str"},{"t":"cont","v":"WarningCode","vt":"str"},{"t":"cont","v":"Position","vt":"str"},{"t":"else"}],"checkall":"true","repair":false,"outputs":4,"x":1050,"y":700,"wires":[["68ad79cd.24fde8","ed2532f3.8b2eb"],["ed2532f3.8b2eb"],["655578e3.f19378"],["e14c6575.623d68"]]},{"id":"6933c8e2.e56078","type":"inject","z":"9f18bf08.c2a65","name":"REGISTERS","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":true,"onceDelay":"10","topic":"","payload":"[{\"register\":\"1\",\"reading\":\"dat.setpoint\",\"multiplier\":\"100\",\"datatype\":\"int16\"},{\"register\":\"2\",\"reading\":\"dat.overrideControl\",\"multiplier\":\"1\",\"datatype\":\"int16\",\"values\":{\"0\":\"none\",\"1\":\"open\",\"2\":\"close\",\"3\":\"min\",\"4\":\"mid\",\"5\":\"max\"}},{\"register\":\"3\",\"reading\":\"dat.command\",\"multiplier\":\"1\",\"datatype\":\"int16\"},{\"register\":\"4\",\"reading\":\"dat.actuatorType\",\"multiplier\":\"1\",\"datatype\":\"int16\",\"values\":{\"0\":\"Actuator Not Connected\",\"1\":\"Air / Water\",\"2\":\"VAV / EPIV\",\"3\":\"Fire\",\"4\":\"Energy Valve\",\"5\":\"6way EPIV\"}},{\"register\":\"5\",\"reading\":\"dat.relativePosition\",\"multiplier\":\"100\",\"datatype\":\"int16\",\"units\":\"%\"},{\"register\":\"6\",\"reading\":\"dat.absolutePosition\",\"multiplier\":\"1\",\"datatype\":\"int16\",\"units\":\"mm\"},{\"register\":\"6\",\"reading\":\"dat.sensorValue1\",\"multiplier\":\"1\",\"datatype\":\"int16\"},{\"register\":\"13\",\"reading\":\"dat.setpointAnalogue\",\"multiplier\":\"100\",\"datatype\":\"int16\",\"units\":\"%\"},{\"register\":\"100\",\"reading\":\"settings.busTermination\",\"multiplier\":\"1\",\"datatype\":\"int16\",\"values\":{\"0\":\"inactive\",\"1\":\"active\"}},{\"register\":\"101\",\"reading\":\"stat.seriesNumberPart1\",\"multiplier\":\"1\",\"datatype\":\"int16\"},{\"register\":\"102\",\"reading\":\"stat.seriesNumberPart2\",\"multiplier\":\"1\",\"datatype\":\"int16\"},{\"register\":\"103\",\"reading\":\"stat.seriesNumberPart3\",\"multiplier\":\"1\",\"datatype\":\"int16\"},{\"register\":\"104\",\"reading\":\"stat.firmwareVirsion\",\"multiplier\":\"1\",\"datatype\":\"int16\"},{\"register\":\"106\",\"reading\":\"settings.min\",\"multiplier\":\"100\",\"datatype\":\"int16\",\"units\":\"%\"},{\"register\":\"107\",\"reading\":\"settings.max\",\"multiplier\":\"100\",\"datatype\":\"int16\",\"units\":\"%\"},{\"register\":\"108\",\"reading\":\"settings.sensorType1\",\"multiplier\":\"1\",\"datatype\":\"int16\",\"values\":{\"0\":\"None\",\"1\":\"Active / Hybrid\",\"2\":\"Passive_1K\",\"3\":\"Passive_20K\",\"4\":\"Switch\",\"5\":\"PT1000_C\",\"6\":\"NI1000_C\",\"7\":\"NTC10K_C\",\"8\":\"PT1000_F\",\"9\":\"NI1000_F\",\"10\":\"NTC10K_F\"}},{\"register\":\"109\",\"reading\":\"settings.busFailPosition\",\"multiplier\":\"1\",\"datatype\":\"int16\",\"values\":{\"0\":\"None / Last setpoint\",\"1\":\"Fast close\",\"2\":\"Fast open\",\"3\":\"Mid position\"}},{\"register\":\"110\",\"reading\":\"settings.watchdogTimeout\",\"multiplier\":\"1\",\"datatype\":\"int16\",\"units\":\"s\"}]","payloadType":"json","x":150,"y":80,"wires":[["95c42acc.304aa8"]]},{"id":"95c42acc.304aa8","type":"split","z":"9f18bf08.c2a65","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":310,"y":80,"wires":[["29e989ab.124226"]]},{"id":"29e989ab.124226","type":"function","z":"9f18bf08.c2a65","name":"Store Registers","func":"\nvar rin = msg.payload;\nif (rin.register<1) { return null; } \n\n\nvar v = global.get(\"readings.\" + rin.reading + \".value\") || 0\nrin[\"value\"] = v;\n\n\n\nflow.set(\"registers.r\" + rin.register, rin);\n\nmsg.payload = flow.get(\"registers\") ;\n    \nreturn msg;\n\n\n\n\n\n","outputs":1,"noerr":0,"x":480,"y":80,"wires":[[]]},{"id":"6d5c01a3.769db","type":"inject","z":"9f18bf08.c2a65","name":"DEVICES","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":true,"onceDelay":"10","topic":"","payload":"[{\"address\":\"1\",\"device\":\"valveSR1\"}]","payloadType":"json","x":140,"y":140,"wires":[["d0c0d129.1a35f"]]},{"id":"d0c0d129.1a35f","type":"split","z":"9f18bf08.c2a65","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":310,"y":140,"wires":[["47f84ff5.818ab"]]},{"id":"47f84ff5.818ab","type":"function","z":"9f18bf08.c2a65","name":"Store Devices","func":"\nvar rin = msg.payload;\nif (rin.address<1) { return null; } \n\n\nflow.set(\"devices.\" + rin.address, rin);\n\n\n    \nreturn msg;\n\n\n\n\n\n","outputs":1,"noerr":0,"x":480,"y":140,"wires":[[]]},{"id":"b7ec2cb5.c3f62","type":"link in","z":"9f18bf08.c2a65","name":"","links":["1f335ee0.7b9a41","b09805d5.754898"],"x":195,"y":440,"wires":[["728528de.3f5da8"]]},{"id":"68ad79cd.24fde8","type":"function","z":"9f18bf08.c2a65","name":"","func":"msg.topic = msg.topic.replace(\"/stat/\",\"/alarm/\");\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1280,"y":660,"wires":[["ed2532f3.8b2eb"]]},{"id":"728528de.3f5da8","type":"delay","z":"9f18bf08.c2a65","name":"","pauseType":"rate","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"2","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":400,"y":440,"wires":[["33ad8fe7.e6b4"]]},{"id":"52cda5dc3e02a412","type":"function","z":"9f18bf08.c2a65","name":"1 - 119 - Modbus Control","func":"\nmsg.fc = 6;\nmsg.address = 1;\nmsg.register = 119;\nmsg.rlength = 1;\n\nflow.set(\"multiply\", 1);\nflow.set(\"rtopic\", \"test\");\n\n\nmsg.targetv = 1;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":370,"y":680,"wires":[["33ad8fe7.e6b4"]]},{"id":"45607cf72a252634","type":"inject","z":"9f18bf08.c2a65","name":"","repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":160,"y":680,"wires":[["52cda5dc3e02a412"]]},{"id":"b8be9e6d.b7861","type":"serial-port","serialport":"/dev/ttyAMA0","serialbaud":"38400","databits":"8","parity":"none","stopbits":"2","waitfor":"","dtr":"none","rts":"none","cts":"none","dsr":"none","newline":"50","bin":"bin","out":"time","addchar":"","responsetimeout":"10000"}]