Create GOM XML transfer file from CSV files

This flow will create XML files in GOM Inspect Exchange Format from CSV input files.

alt tag

CSV node can be substituted for any source that can provide an array of JavaScript objects with structure defined in mapping node (database, streaming source, etc.).

Generated XML is conforming to the 2019.1 version of the open data format.

Configuration

There are only two nodes you need to modify:

  • Start node - enter the path to directory with CSV files.
  • Mapping template - You need to specify how columns in your CSV map to GOM elements, i.e., x field will map to CSV column called “coord-x.”

See our blog post for details.

Testing

You can use following CSV file to test the flow. Generated XML was tested on GOM Inspect 2019 and 2020.

Released under MIT License

Copyright (c) 2020 Kenso Software, LLC

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

[{"id":"f7dd5695.c01598","type":"tab","label":"Create GOM XML from CSV","disabled":false,"info":"Generate GOM Inspect XML from any CSV file. Visit https://blog.kensobi.com/ for details."},{"id":"1b562d91.3c71f2","type":"csv","z":"f7dd5695.c01598","name":"Parse CSV","sep":",","hdrin":true,"hdrout":"none","multi":"mult","ret":"\\n","temp":"","skip":"0","strings":true,"include_empty_strings":"","include_null_values":"","x":410,"y":180,"wires":[["8e65dad6.c56f98"]]},{"id":"279275b9.82370a","type":"template","z":"f7dd5695.c01598","name":"Point nominal","field":"payload.nominal","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"{{#isValid}}\n        <point id=\"{{elementId}}0\" name=\"{{name}}\">\n            <actual>{{elementId}}</actual>\n            <state>ok</state>\n            <geometry>\n                <pos x=\"{{x}}\" y=\"{{y}}\" z=\"{{z}}\"></pos>\n            </geometry>\n            <result>\n                <x checked=\"1\">\n                    <tolerance lower_limit=\"{{x_lower}}\" upper_limit=\"{{x_upper}}\"></tolerance>\n                    <nominal_scalar value=\"{{x}}\"></nominal_scalar>\n                </x>\n                <y checked=\"1\">\n                    <tolerance lower_limit=\"{{y_lower}}\" upper_limit=\"{{y_upper}}\"></tolerance>\n                    <nominal_scalar value=\"{{y}}\"></nominal_scalar>\n                </y>\n                <z checked=\"1\">\n                    <tolerance lower_limit=\"{{z_lower}}\" upper_limit=\"{{z_upper}}\"></tolerance>\n                    <nominal_scalar value=\"{{z}}\"></nominal_scalar>\n                </z>\n              </result>\n        </point>\n{{/isValid}}","output":"str","x":840,"y":260,"wires":[["c68c47a0.751e98"]]},{"id":"1e4f4efe.b471f1","type":"inject","z":"f7dd5695.c01598","name":"Start","props":[{"p":"dirPath","v":"/filedrop","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":130,"y":120,"wires":[["64d8b16.886585"]]},{"id":"d5695b04.0654c8","type":"file in","z":"f7dd5695.c01598","name":"Read file","filename":"","format":"utf8","chunk":false,"sendError":false,"encoding":"utf8","x":260,"y":180,"wires":[["1b562d91.3c71f2"]]},{"id":"2bae1ead.b9bae2","type":"switch","z":"f7dd5695.c01598","name":"","property":"type","propertyType":"msg","rules":[{"t":"eq","v":"","vt":"str"},{"t":"eq","v":"$trim($lookup(mapping.typeValueMap, \"point\"))","vt":"jsonata"},{"t":"eq","v":"$trim($lookup(mapping.typeValueMap, \"line\"))","vt":"jsonata"},{"t":"eq","v":"$trim($lookup(mapping.typeValueMap, \"circle\"))","vt":"jsonata"},{"t":"eq","v":"$trim($lookup(mapping.typeValueMap, \"plane\"))","vt":"jsonata"},{"t":"eq","v":"$trim($lookup(mapping.typeValueMap, \"ellipse\"))","vt":"jsonata"},{"t":"eq","v":"$trim($lookup(mapping.typeValueMap, \"slotted_hole\"))","vt":"jsonata"},{"t":"eq","v":"$trim($lookup(mapping.typeValueMap, \"rectangular_hole\"))","vt":"jsonata"},{"t":"eq","v":"$trim($lookup(mapping.typeValueMap, \"sphere\"))","vt":"jsonata"},{"t":"eq","v":"$trim($lookup(mapping.typeValueMap, \"cylinder\"))","vt":"jsonata"},{"t":"eq","v":"$trim($lookup(mapping.typeValueMap, \"cone\"))","vt":"jsonata"},{"t":"eq","v":"$trim($lookup(mapping.typeValueMap, \"polygon_hole\"))","vt":"jsonata"},{"t":"else"}],"checkall":"true","repair":false,"outputs":13,"x":370,"y":440,"wires":[[],["e9ee423a.1d424"],["aaad5d23.1aba6"],["b3c448c1.039078"],["40c4aac2.219344"],["93522995.db5938"],["bdb2504c.00e47"],["9dc86af7.5cff28"],["9a8acae.3fa1838"],["a8825505.fe89f8"],["153b0dac.70c4c2"],["3481aa97.f1ab66"],["be5a4fc2.acc38"]]},{"id":"bb1a43c8.8430a","type":"template","z":"f7dd5695.c01598","name":"Circle nominal","field":"payload.nominal","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"{{#isValid}}\n        <circle id=\"{{elementId}}0\" name=\"{{name}}\">\n            <actual>{{elementId}}</actual>\n            <state>ok</state>\n            <geometry>\n                <pos x=\"{{x}}\" y=\"{{y}}\" z=\"{{z}}\"></pos>\n                <radius>{{radius}}</radius>\n            </geometry>\n            <result>\n                <diameter checked=\"1\">\n                  <tolerance lower_limit=\"{{diameter_lower}}\" upper_limit=\"{{diameter_upper}}\"></tolerance>\n                  <nominal_scalar value=\"{{diameter}}\"></nominal_scalar>\n                </diameter>\n                \n                <x checked=\"1\">\n                    <tolerance lower_limit=\"{{x_lower}}\" upper_limit=\"{{x_upper}}\"></tolerance>\n                    <nominal_scalar value=\"{{x}}\"></nominal_scalar>\n                </x>\n                <y checked=\"1\">\n                    <tolerance lower_limit=\"{{y_lower}}\" upper_limit=\"{{y_upper}}\"></tolerance>\n                    <nominal_scalar value=\"{{y}}\"></nominal_scalar>\n                </y>\n                <z checked=\"1\">\n                    <tolerance lower_limit=\"{{z_lower}}\" upper_limit=\"{{z_upper}}\"></tolerance>\n                    <nominal_scalar value=\"{{z}}\"></nominal_scalar>\n                </z>\n              </result>\n        </circle>\n{{/isValid}}","output":"str","x":840,"y":340,"wires":[["c68c47a0.751e98"]]},{"id":"39667f17.e7d8f","type":"split","z":"f7dd5695.c01598","name":"Split by line","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":150,"y":360,"wires":[["f7d28600.84dae8"]]},{"id":"c68c47a0.751e98","type":"join","z":"f7dd5695.c01598","name":"","mode":"auto","build":"string","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":false,"timeout":"","count":"","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":1130,"y":420,"wires":[["1b978377.8469dd"]]},{"id":"8e65dad6.c56f98","type":"template","z":"f7dd5695.c01598","name":"Mapping template","field":"mapping","fieldType":"msg","format":"json","syntax":"mustache","template":"{\n    \"name\": \"name\",\n    \"x\": \"coord-x\",\n    \"y\": \"coord-y\",\n    \"z\": \"coord-z\",\n    \"x2\": \"coord-x2\",\n    \"y2\": \"coord-y2\",\n    \"z2\": \"coord-z2\",\n    \"x3\": \"coord-x3\",\n    \"y3\": \"coord-y3\",\n    \"z3\": \"coord-z3\",\n    \"normal_x\": \"normal-x\",\n    \"normal_y\": \"normal-y\",\n    \"normal_z\": \"normal-z\",\n    \"dir_x\": \"dir-x\",\n    \"dir_y\": \"dir-y\",\n    \"dir_z\": \"dir-z\",\n    \"radius\": \"radius\",\n    \"radius2\": \"radius2\",\n    \"edge_radius\": \"edge-radius\",\n    \"num_points\": \"num-points\",\n    \"angle\": \"angle\",\n    \"distance\": \"distance\",\n    \"length\": \"length\",\n    \"width\": \"width\",\n    \"height\": \"height\",\n    \"orientation\": \"orientation\",\n    \"type\": \"type\",\n    \"typeValueMap\": {\n        \"point\": \"point\",\n        \"line\": \"line\",\n        \"plane\": \"plane\",\n        \"circle\": \"circle\",\n        \"ellipse\": \"ellipse\",\n        \"slotted_hole\": \"slotted hole\",\n        \"rectangular_hole\": \"rectangular hole\",\n        \"sphere\": \"sphere\",\n        \"cylinder\": \"cylinder\",\n        \"cone\": \"cone\",\n        \"polygon_hole\": \"polygon hole\"\n    },\n    \"x_lower\": \"tol-x-lower\",\n    \"x_upper\": \"tol-x-upper\",\n    \"y_lower\": \"tol-y-lower\",\n    \"y_upper\": \"tol-y-upper\",\n    \"z_lower\": \"tol-z-lower\",\n    \"z_upper\": \"tol-z-upper\",\n    \"diameter_lower\": \"tol-diameter-lower\",\n    \"diameter_upper\": \"tol-diameter-upper\",\n    \"length_lower\": \"tol-length-lower\",\n    \"length_upper\": \"tol-length-upper\",\n    \"width_lower\": \"tol-width-lower\",\n    \"width_upper\": \"tol-width-upper\"\n}","output":"json","x":590,"y":180,"wires":[["39667f17.e7d8f"]]},{"id":"e9ee423a.1d424","type":"template","z":"f7dd5695.c01598","name":"Point actual","field":"payload.measured","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"{{#isValid}}\n        <point id=\"{{elementId}}\" name=\"{{name}}\">\n            <state>ok</state>\n            <geometry>\n                <pos x=\"{{x}}\" y=\"{{y}}\" z=\"{{z}}\"></pos>\n            </geometry>\n            <result></result>\n        </point>\n{{/isValid}}","output":"str","x":590,"y":260,"wires":[["279275b9.82370a"]]},{"id":"b3c448c1.039078","type":"template","z":"f7dd5695.c01598","name":"Circle actual","field":"payload.measured","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"{{#isValid}}\n        <circle id=\"{{elementId}}\" name=\"{{name}}\">\n              <state>ok</state>\n              <geometry>\n                <pos x=\"{{x}}\" y=\"{{y}}\" z=\"{{z}}\"></pos>\n                <radius>{{radius}}</radius>\n              </geometry>\n              <result></result>\n        </circle>\n{{/isValid}}","output":"str","x":590,"y":340,"wires":[["bb1a43c8.8430a"]]},{"id":"aaad5d23.1aba6","type":"template","z":"f7dd5695.c01598","name":"Line actual","field":"payload.measured","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"{{#isValid}}\n        <line id=\"{{elementId}}\" name=\"{{name}}\">\n            <state>ok</state>\n            <geometry>\n                \t<pos1 x=\"{{x}}\" y=\"{{y}}\" z=\"{{z}}\"></pos1>\n                \t<pos2 x=\"{{x2}}\" y=\"{{y2}}\" z=\"{{z2}}\"></pos2>\n                \t<dir x=\"{{dir_x}}\" y=\"{{dir_y}}\" z=\"{{dir_z}}\"></dir>\n            </geometry>\n        </line>\n{{/isValid}}","output":"str","x":590,"y":300,"wires":[["6f398baa.36eef4"]]},{"id":"6f398baa.36eef4","type":"template","z":"f7dd5695.c01598","name":"Line nominal","field":"payload.nominal","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"{{#isValid}}\n        <line id=\"{{elementId}}0\" name=\"{{name}}\">\n            <actual>{{elementId}}</actual>\n            <state>ok</state>\n            <geometry>\n                \t<pos1 x=\"{{x}}\" y=\"{{y}}\" z=\"{{z}}\"></pos1>\n                \t<pos2 x=\"{{x2}}\" y=\"{{y2}}\" z=\"{{z2}}\"></pos2>\n                \t<dir x=\"{{dir_x}}\" y=\"{{dir_y}}\" z=\"{{dir_z}}\"></dir>\n            </geometry>\n            <result></result>\n        </line>\n{{/isValid}}","output":"str","x":830,"y":300,"wires":[["c68c47a0.751e98"]]},{"id":"1b978377.8469dd","type":"template","z":"f7dd5695.c01598","name":"Create GOM XML","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<gom>\n    <header>\n        <version>2019.1</version>\n        <length_unit>mm</length_unit>\n        <angle_unit>deg</angle_unit>\n    </header>\n    <nominal>\n{{#payload}}{{{nominal}}}{{/payload}}\n    </nominal>\n    <measured>\n{{#payload}}{{{measured}}}{{/payload}}\n    </measured>\n</gom>\n","output":"str","x":1310,"y":420,"wires":[["4aee38d3.c6c228"]]},{"id":"48b211f0.ee47f","type":"file","z":"f7dd5695.c01598","name":"Save GOM XML","filename":"","appendNewline":false,"createDir":true,"overwriteFile":"true","encoding":"utf8","x":1300,"y":580,"wires":[[]]},{"id":"be5a4fc2.acc38","type":"template","z":"f7dd5695.c01598","name":"Bad values","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"","output":"str","x":590,"y":700,"wires":[["c68c47a0.751e98"]]},{"id":"f7d28600.84dae8","type":"change","z":"f7dd5695.c01598","name":"Map columns","rules":[{"t":"set","p":"name","pt":"msg","to":"$trim($lookup(payload, mapping.name))\t","tot":"jsonata"},{"t":"set","p":"x","pt":"msg","to":"$lookup(payload, mapping.x)","tot":"jsonata"},{"t":"set","p":"y","pt":"msg","to":"$lookup(payload, mapping.y)","tot":"jsonata"},{"t":"set","p":"z","pt":"msg","to":"$lookup(payload, mapping.z)","tot":"jsonata"},{"t":"set","p":"type","pt":"msg","to":"$trim($lookup(payload, mapping.type))","tot":"jsonata"},{"t":"set","p":"elementId","pt":"msg","to":"$substring($string($random()), 2, 10)","tot":"jsonata"},{"t":"set","p":"isValid","pt":"msg","to":"($boolean(x) or x=0) and ($boolean(y) or y=0) and ($boolean(z) or z=0) and $boolean(name)","tot":"jsonata"},{"t":"set","p":"radius","pt":"msg","to":"$lookup(payload, mapping.radius)","tot":"jsonata"},{"t":"set","p":"dir_x","pt":"msg","to":"$lookup(payload, mapping.dir_x)","tot":"jsonata"},{"t":"set","p":"dir_y","pt":"msg","to":"$lookup(payload, mapping.dir_y)","tot":"jsonata"},{"t":"set","p":"dir_z","pt":"msg","to":"$lookup(payload, mapping.dir_z)","tot":"jsonata"},{"t":"set","p":"x2","pt":"msg","to":"$lookup(payload, mapping.x2)","tot":"jsonata"},{"t":"set","p":"y2","pt":"msg","to":"$lookup(payload, mapping.y2)","tot":"jsonata"},{"t":"set","p":"z2","pt":"msg","to":"$lookup(payload, mapping.z2)","tot":"jsonata"},{"t":"set","p":"x_lower","pt":"msg","to":"$lookup(payload, mapping.x_lower)","tot":"jsonata"},{"t":"set","p":"x_upper","pt":"msg","to":"$lookup(payload, mapping.x_upper)","tot":"jsonata"},{"t":"set","p":"y_lower","pt":"msg","to":"$lookup(payload, mapping.y_lower)","tot":"jsonata"},{"t":"set","p":"y_upper","pt":"msg","to":"$lookup(payload, mapping.y_upper)","tot":"jsonata"},{"t":"set","p":"z_lower","pt":"msg","to":"$lookup(payload, mapping.z_lower)","tot":"jsonata"},{"t":"set","p":"z_upper","pt":"msg","to":"$lookup(payload, mapping.z_upper)","tot":"jsonata"},{"t":"set","p":"diameter_lower","pt":"msg","to":"$lookup(payload, mapping.diameter_lower)","tot":"jsonata"},{"t":"set","p":"diameter_upper","pt":"msg","to":"$lookup(payload, mapping.diameter_upper)","tot":"jsonata"},{"t":"set","p":"diameter","pt":"msg","to":"radius * 2","tot":"jsonata"},{"t":"set","p":"height","pt":"msg","to":"$lookup(payload, mapping.height)","tot":"jsonata"},{"t":"set","p":"width","pt":"msg","to":"$lookup(payload, mapping.width)","tot":"jsonata"},{"t":"set","p":"orientation","pt":"msg","to":"$lookup(payload, mapping.orientation)","tot":"jsonata"},{"t":"set","p":"length","pt":"msg","to":"$lookup(payload, mapping.length)","tot":"jsonata"},{"t":"set","p":"distance","pt":"msg","to":"$lookup(payload, mapping.distance)","tot":"jsonata"},{"t":"set","p":"normal_x","pt":"msg","to":"$lookup(payload, mapping.normal_x)","tot":"jsonata"},{"t":"set","p":"normal_y","pt":"msg","to":"$lookup(payload, mapping.normal_y)","tot":"jsonata"},{"t":"set","p":"normal_z","pt":"msg","to":"$lookup(payload, mapping.normal_z)","tot":"jsonata"},{"t":"set","p":"radius2","pt":"msg","to":"$lookup(payload, mapping.radius2)","tot":"jsonata"},{"t":"set","p":"x3","pt":"msg","to":"$lookup(payload, mapping.x3)","tot":"jsonata"},{"t":"set","p":"y3","pt":"msg","to":"$lookup(payload, mapping.y3)","tot":"jsonata"},{"t":"set","p":"z3","pt":"msg","to":"$lookup(payload, mapping.z3)","tot":"jsonata"},{"t":"set","p":"width_lower","pt":"msg","to":"$lookup(payload, mapping.width_lower)","tot":"jsonata"},{"t":"set","p":"width_upper","pt":"msg","to":"$lookup(payload, mapping.width_upper)","tot":"jsonata"},{"t":"set","p":"length_lower","pt":"msg","to":"$lookup(payload, mapping.length_lower)","tot":"jsonata"},{"t":"set","p":"length_upper","pt":"msg","to":"$lookup(payload, mapping.length_upper)","tot":"jsonata"},{"t":"set","p":"edge_radius","pt":"msg","to":"$lookup(payload, mapping.edge_radius)","tot":"jsonata"},{"t":"set","p":"angle","pt":"msg","to":"$lookup(payload, mapping.angle)","tot":"jsonata"},{"t":"set","p":"num_points","pt":"msg","to":"$lookup(payload, mapping.num_points)","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":150,"y":440,"wires":[["c89b1cf3.8ed8b"]]},{"id":"40c4aac2.219344","type":"template","z":"f7dd5695.c01598","name":"Plane actual","field":"payload.measured","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"{{#isValid}}\n        <plane id=\"{{elementId}}\" name=\"{{name}}\">\n            <state>ok</state>\n            <geometry>\n                <normal x=\"{{normal_x}}\" y=\"{{normal_y}}\" z=\"{{normal_z}}\"></normal>\n                <pos x=\"{{x}}\" y=\"{{y}}\" z=\"{{z}}\"></pos>\n                <length>{{length}}</length>\n                <width>{{width}}</width>\n                <orientation>{{orientation}}</orientation>\n            </geometry>\n            <result></result>\n        </plane>\n{{/isValid}}","output":"str","x":590,"y":380,"wires":[["c68f496b.f085a8"]]},{"id":"c68f496b.f085a8","type":"template","z":"f7dd5695.c01598","name":"Plane nominal","field":"payload.nominal","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"{{#isValid}}\n        <plane id=\"{{elementId}}0\" name=\"{{name}}\">\n            <actual>{{elementId}}</actual>\n            <state>ok</state>\n            <geometry>\n                <normal x=\"{{normal_x}}\" y=\"{{normal_y}}\" z=\"{{normal_z}}\"></normal>\n                <pos x=\"{{x}}\" y=\"{{y}}\" z=\"{{z}}\"></pos>\n                <length>{{length}}</length>\n                <width>{{width}}</width>\n                <orientation>{{orientation}}</orientation>\n            </geometry>\n            <result></result>\n        </plane>\n{{/isValid}}","output":"str","x":840,"y":380,"wires":[["c68c47a0.751e98"]]},{"id":"93522995.db5938","type":"template","z":"f7dd5695.c01598","name":"Ellipse actual","field":"payload.measured","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"{{#isValid}}\n        <ellipse id=\"{{elementId}}\" name=\"{{name}}\">\n            <state>ok</state>\n            <geometry>\n                    <pos x=\"{{x}}\" y=\"{{y}}\" z=\"{{z}}\"></pos>\n                \t<pos1 x=\"{{x2}}\" y=\"{{y2}}\" z=\"{{z2}}\"></pos1>\n                \t<pos2 x=\"{{x3}}\" y=\"{{y3}}\" z=\"{{z3}}\"></pos2>\n                \t<dir x=\"{{dir_x}}\" y=\"{{dir_y}}\" z=\"{{dir_z}}\"></dir>\n                \t<normal x=\"{{normal_x}}\" y=\"{{normal_y}}\" z=\"{{normal_z}}\"></normal>\n                    <inner_radius>{{radius}}</inner_radius>\n                    <outer_radius>{{radius2}}</outer_radius>\n            </geometry>\n        </ellipse>\n{{/isValid}}","output":"str","x":590,"y":420,"wires":[["fcaa700d.390ac"]]},{"id":"fcaa700d.390ac","type":"template","z":"f7dd5695.c01598","name":"Ellipse nominal","field":"payload.nominal","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"{{#isValid}}\n        <ellipse id=\"{{elementId}}0\" name=\"{{name}}\">\n            <actual>{{elementId}}</actual>\n            <state>ok</state>\n            <geometry>\n                <pos x=\"{{x}}\" y=\"{{y}}\" z=\"{{z}}\"></pos>\n                <pos1 x=\"{{x2}}\" y=\"{{y2}}\" z=\"{{z2}}\"></pos1>\n                <pos2 x=\"{{x3}}\" y=\"{{y3}}\" z=\"{{z3}}\"></pos2>\n                <dir x=\"{{dir_x}}\" y=\"{{dir_y}}\" z=\"{{dir_z}}\"></dir>\n                <normal x=\"{{normal_x}}\" y=\"{{normal_y}}\" z=\"{{normal_z}}\"></normal>\n                <inner_radius>{{radius}}</inner_radius>\n                <outer_radius>{{radius2}}</outer_radius>\n            </geometry>\n            <result></result>\n        </ellipse>\n{{/isValid}}","output":"str","x":840,"y":420,"wires":[["c68c47a0.751e98"]]},{"id":"bdb2504c.00e47","type":"template","z":"f7dd5695.c01598","name":"Slotted Hole actual","field":"payload.measured","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"{{#isValid}}\n        <slotted_hole id=\"{{elementId}}\" name=\"{{name}}\">\n            <state>ok</state>\n            <geometry>\n                <pos x=\"{{x}}\" y=\"{{y}}\" z=\"{{z}}\"></pos>\n                <dir x=\"{{dir_x}}\" y=\"{{dir_y}}\" z=\"{{dir_z}}\"></dir>\n                <normal x=\"{{normal_x}}\" y=\"{{normal_y}}\" z=\"{{normal_z}}\"></normal>\n                <length>{{length}}</length>\n                <width>{{width}}</width>\n            </geometry>\n        </slotted_hole>\n{{/isValid}}","output":"str","x":610,"y":460,"wires":[["caa5473f.1bfc08"]]},{"id":"caa5473f.1bfc08","type":"template","z":"f7dd5695.c01598","name":"Slotted Hole nominal","field":"payload.nominal","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"{{#isValid}}\n        <slotted_hole id=\"{{elementId}}0\" name=\"{{name}}\">\n            <actual>{{elementId}}</actual>\n            <state>ok</state>\n            <geometry>\n                <pos x=\"{{x}}\" y=\"{{y}}\" z=\"{{z}}\"></pos>\n                <dir x=\"{{dir_x}}\" y=\"{{dir_y}}\" z=\"{{dir_z}}\"></dir>\n                <normal x=\"{{normal_x}}\" y=\"{{normal_y}}\" z=\"{{normal_z}}\"></normal>\n                <length>{{length}}</length>\n                <width>{{width}}</width>\n            </geometry>\n            <result>\n                {{#width}}\n                <width checked=\"1\">\n                  <tolerance lower_limit=\"{{width_lower}}\" upper_limit=\"{{width_upper}}\"></tolerance>\n                  <nominal_scalar value=\"{{width}}\"></nominal_scalar>\n                </width>\n                {{/width}}\n                <x checked=\"1\">\n                    <tolerance lower_limit=\"{{x_lower}}\" upper_limit=\"{{x_upper}}\"></tolerance>\n                    <nominal_scalar value=\"{{x}}\"></nominal_scalar>\n                </x>\n                <y checked=\"1\">\n                    <tolerance lower_limit=\"{{y_lower}}\" upper_limit=\"{{y_upper}}\"></tolerance>\n                    <nominal_scalar value=\"{{y}}\"></nominal_scalar>\n                </y>\n                <z checked=\"1\">\n                    <tolerance lower_limit=\"{{z_lower}}\" upper_limit=\"{{z_upper}}\"></tolerance>\n                    <nominal_scalar value=\"{{z}}\"></nominal_scalar>\n                </z>\n              </result>\n        </slotted_hole>\n{{/isValid}}","output":"str","x":860,"y":460,"wires":[["c68c47a0.751e98"]]},{"id":"c89b1cf3.8ed8b","type":"change","z":"f7dd5695.c01598","name":"Set defaults","rules":[{"t":"set","p":"x_lower","pt":"msg","to":"$exists(x_lower) ? x_lower : -1","tot":"jsonata"},{"t":"set","p":"x_upper","pt":"msg","to":"$exists(x_upper) ? x_upper: 1","tot":"jsonata"},{"t":"set","p":"y_lower","pt":"msg","to":"$exists(y_lower) ? y_lower : -1","tot":"jsonata"},{"t":"set","p":"y_upper","pt":"msg","to":"$exists(y_upper) ? y_upper: 1","tot":"jsonata"},{"t":"set","p":"z_lower","pt":"msg","to":"$exists(z_lower) ? z_lower : -1","tot":"jsonata"},{"t":"set","p":"z_upper","pt":"msg","to":"$exists(z_upper) ? z_upper: 1","tot":"jsonata"},{"t":"set","p":"width_lower","pt":"msg","to":"$exists(width_lower) ? width_lower: -1","tot":"jsonata"},{"t":"set","p":"width_upper","pt":"msg","to":"$exists(width_upper) ? width_upper: 1","tot":"jsonata"},{"t":"set","p":"normal_x","pt":"msg","to":"$exists(normal_x) ? normal_x: 1","tot":"jsonata"},{"t":"set","p":"normal_y","pt":"msg","to":"$exists(normal_y) ? normal_y: 0","tot":"jsonata"},{"t":"set","p":"normal_z","pt":"msg","to":"$exists(normal_z) ? normal_z: 0","tot":"jsonata"},{"t":"set","p":"edge_radius","pt":"msg","to":"$exists(edge_radius) ? edge_radius: 0","tot":"jsonata"},{"t":"set","p":"diameter_lower","pt":"msg","to":"$exists(diameter_lower) ? diameter_lower: -1","tot":"jsonata"},{"t":"set","p":"diameter_upper","pt":"msg","to":"$exists(diameter_upper) ? diameter_upper: 1","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":150,"y":520,"wires":[["2bae1ead.b9bae2"]]},{"id":"9dc86af7.5cff28","type":"template","z":"f7dd5695.c01598","name":"Rectangular Hole actual","field":"payload.measured","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"{{#isValid}}\n        <rectangular_hole id=\"{{elementId}}\" name=\"{{name}}\">\n            <state>ok</state>\n            <geometry>\n                <pos x=\"{{x}}\" y=\"{{y}}\" z=\"{{z}}\"></pos>\n                <dir x=\"{{dir_x}}\" y=\"{{dir_y}}\" z=\"{{dir_z}}\"></dir>\n                <normal x=\"{{normal_x}}\" y=\"{{normal_y}}\" z=\"{{normal_z}}\"></normal>\n                <length>{{length}}</length>\n                <width>{{width}}</width>\n                <edge_radius>{{edge_radius}}</edge_radius>\n            </geometry>\n        </rectangular_hole>\n{{/isValid}}","output":"str","x":630,"y":500,"wires":[["b7d71c64.53edb"]]},{"id":"b7d71c64.53edb","type":"template","z":"f7dd5695.c01598","name":"Rectangular Hole nominal","field":"payload.nominal","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"{{#isValid}}\n        <rectangular_hole id=\"{{elementId}}0\" name=\"{{name}}\">\n            <actual>{{elementId}}</actual>\n            <state>ok</state>\n            <geometry>\n                <pos x=\"{{x}}\" y=\"{{y}}\" z=\"{{z}}\"></pos>\n                <dir x=\"{{dir_x}}\" y=\"{{dir_y}}\" z=\"{{dir_z}}\"></dir>\n                <normal x=\"{{normal_x}}\" y=\"{{normal_y}}\" z=\"{{normal_z}}\"></normal>\n                <length>{{length}}</length>\n                <width>{{width}}</width>\n                <edge_radius>{{edge_radius}}</edge_radius>\n            </geometry>\n            <result>\n                {{#width}}\n                <width checked=\"1\">\n                  <tolerance lower_limit=\"{{width_lower}}\" upper_limit=\"{{width_upper}}\"></tolerance>\n                  <nominal_scalar value=\"{{width}}\"></nominal_scalar>\n                </width>\n                {{/width}}\n                <x checked=\"1\">\n                    <tolerance lower_limit=\"{{x_lower}}\" upper_limit=\"{{x_upper}}\"></tolerance>\n                    <nominal_scalar value=\"{{x}}\"></nominal_scalar>\n                </x>\n                <y checked=\"1\">\n                    <tolerance lower_limit=\"{{y_lower}}\" upper_limit=\"{{y_upper}}\"></tolerance>\n                    <nominal_scalar value=\"{{y}}\"></nominal_scalar>\n                </y>\n                <z checked=\"1\">\n                    <tolerance lower_limit=\"{{z_lower}}\" upper_limit=\"{{z_upper}}\"></tolerance>\n                    <nominal_scalar value=\"{{z}}\"></nominal_scalar>\n                </z>\n              </result>\n        </rectangular_hole>\n{{/isValid}}","output":"str","x":870,"y":500,"wires":[["c68c47a0.751e98"]]},{"id":"9a8acae.3fa1838","type":"template","z":"f7dd5695.c01598","name":"Sphere actual","field":"payload.measured","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"{{#isValid}}\n        <sphere id=\"{{elementId}}\" name=\"{{name}}\">\n              <state>ok</state>\n              <geometry>\n                <pos x=\"{{x}}\" y=\"{{y}}\" z=\"{{z}}\"></pos>\n                <radius>{{radius}}</radius>\n              </geometry>\n              <result></result>\n        </sphere>\n{{/isValid}}","output":"str","x":600,"y":540,"wires":[["7c9ad7db.813728"]]},{"id":"7c9ad7db.813728","type":"template","z":"f7dd5695.c01598","name":"Sphere nominal","field":"payload.nominal","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"{{#isValid}}\n        <sphere id=\"{{elementId}}0\" name=\"{{name}}\">\n            <actual>{{elementId}}</actual>\n            <state>ok</state>\n            <geometry>\n                <pos x=\"{{x}}\" y=\"{{y}}\" z=\"{{z}}\"></pos>\n                <radius>{{radius}}</radius>\n            </geometry>\n            <result>\n                <diameter checked=\"1\">\n                  <tolerance lower_limit=\"{{diameter_lower}}\" upper_limit=\"{{diameter_upper}}\"></tolerance>\n                  <nominal_scalar value=\"{{diameter}}\"></nominal_scalar>\n                </diameter>\n                \n                <x checked=\"1\">\n                    <tolerance lower_limit=\"{{x_lower}}\" upper_limit=\"{{x_upper}}\"></tolerance>\n                    <nominal_scalar value=\"{{x}}\"></nominal_scalar>\n                </x>\n                <y checked=\"1\">\n                    <tolerance lower_limit=\"{{y_lower}}\" upper_limit=\"{{y_upper}}\"></tolerance>\n                    <nominal_scalar value=\"{{y}}\"></nominal_scalar>\n                </y>\n                <z checked=\"1\">\n                    <tolerance lower_limit=\"{{z_lower}}\" upper_limit=\"{{z_upper}}\"></tolerance>\n                    <nominal_scalar value=\"{{z}}\"></nominal_scalar>\n                </z>\n              </result>\n        </sphere>\n{{/isValid}}","output":"str","x":840,"y":540,"wires":[["c68c47a0.751e98"]]},{"id":"a8825505.fe89f8","type":"template","z":"f7dd5695.c01598","name":"Cylinder actual","field":"payload.measured","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"{{#isValid}}\n        <cylinder id=\"{{elementId}}\" name=\"{{name}}\">\n            <state>ok</state>\n            <geometry>\n                \t<pos1 x=\"{{x}}\" y=\"{{y}}\" z=\"{{z}}\"></pos1>\n                \t<pos2 x=\"{{x2}}\" y=\"{{y2}}\" z=\"{{z2}}\"></pos2>\n                \t<dir x=\"{{dir_x}}\" y=\"{{dir_y}}\" z=\"{{dir_z}}\"></dir>\n                \t<radius>{{radius}}</radius>\n                \t<length>{{length}}</length>\n            </geometry>\n        </cylinder >\n{{/isValid}}","output":"str","x":600,"y":580,"wires":[["5025f50e.8d431c"]]},{"id":"5025f50e.8d431c","type":"template","z":"f7dd5695.c01598","name":"Cylinder nominal","field":"payload.nominal","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"{{#isValid}}\n        <cylinder id=\"{{elementId}}0\" name=\"{{name}}\">\n            <actual>{{elementId}}</actual>\n            <state>ok</state>\n            <geometry>\n                \t<pos1 x=\"{{x}}\" y=\"{{y}}\" z=\"{{z}}\"></pos1>\n                \t<pos2 x=\"{{x2}}\" y=\"{{y2}}\" z=\"{{z2}}\"></pos2>\n                \t<dir x=\"{{dir_x}}\" y=\"{{dir_y}}\" z=\"{{dir_z}}\"></dir>\n                \t<radius>{{radius}}</radius>\n                \t<length>{{length}}</length>\n            </geometry>\n            <result>\n                <diameter checked=\"1\">\n                  <tolerance lower_limit=\"{{diameter_lower}}\" upper_limit=\"{{diameter_upper}}\"></tolerance>\n                  <nominal_scalar value=\"{{diameter}}\"></nominal_scalar>\n                </diameter>\n              </result>\n        </cylinder>\n{{/isValid}}","output":"str","x":850,"y":580,"wires":[["c68c47a0.751e98"]]},{"id":"153b0dac.70c4c2","type":"template","z":"f7dd5695.c01598","name":"Cone actual","field":"payload.measured","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"{{#isValid}}\n        <cone id=\"{{elementId}}\" name=\"{{name}}\">\n            <state>ok</state>\n            <geometry>\n                \t<pos1 x=\"{{x}}\" y=\"{{y}}\" z=\"{{z}}\"></pos1>\n                \t<pos2 x=\"{{x2}}\" y=\"{{y2}}\" z=\"{{z2}}\"></pos2>\n                \t<dir x=\"{{dir_x}}\" y=\"{{dir_y}}\" z=\"{{dir_z}}\"></dir>\n                \t<radius1>{{radius}}</radius1>\n                \t<radius2>{{radius2}}</radius2>\n                \t<angle>{{angle}}</angle>\n            </geometry>\n        </cone >\n{{/isValid}}","output":"str","x":590,"y":620,"wires":[["6f9c9236.9581fc"]]},{"id":"6f9c9236.9581fc","type":"template","z":"f7dd5695.c01598","name":"Cone nominal","field":"payload.nominal","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"{{#isValid}}\n        <cone id=\"{{elementId}}0\" name=\"{{name}}\">\n            <actual>{{elementId}}</actual>\n            <state>ok</state>\n            <geometry>\n                \t<pos1 x=\"{{x}}\" y=\"{{y}}\" z=\"{{z}}\"></pos1>\n                \t<pos2 x=\"{{x2}}\" y=\"{{y2}}\" z=\"{{z2}}\"></pos2>\n                \t<dir x=\"{{dir_x}}\" y=\"{{dir_y}}\" z=\"{{dir_z}}\"></dir>\n                \t<radius1>{{radius}}</radius1>\n                \t<radius2>{{radius2}}</radius2>\n                \t<angle>{{angle}}</angle>\n            </geometry>\n            <result></result>\n        </cone>\n{{/isValid}}","output":"str","x":840,"y":620,"wires":[["c68c47a0.751e98"]]},{"id":"3481aa97.f1ab66","type":"template","z":"f7dd5695.c01598","name":"Polygon Hole actual","field":"payload.measured","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"{{#isValid}}\n        <polygon_hole id=\"{{elementId}}\" name=\"{{name}}\">\n            <state>ok</state>\n            <geometry>\n                <pos x=\"{{x}}\" y=\"{{y}}\" z=\"{{z}}\"></pos>\n                <dir x=\"{{dir_x}}\" y=\"{{dir_y}}\" z=\"{{dir_z}}\"></dir>\n                <normal x=\"{{normal_x}}\" y=\"{{normal_y}}\" z=\"{{normal_z}}\"></normal>\n                <num_points>{{num_points}}</num_points>\n                <inner_radius>{{radius}}</inner_radius>\n            </geometry>\n        </polygon_hole>\n{{/isValid}}","output":"str","x":620,"y":660,"wires":[["81822ed3.55f2"]]},{"id":"81822ed3.55f2","type":"template","z":"f7dd5695.c01598","name":"Polygon Hole nominal","field":"payload.nominal","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"{{#isValid}}\n        <polygon_hole id=\"{{elementId}}0\" name=\"{{name}}\">\n            <actual>{{elementId}}</actual>\n            <state>ok</state>\n            <geometry>\n                <pos x=\"{{x}}\" y=\"{{y}}\" z=\"{{z}}\"></pos>\n                <dir x=\"{{dir_x}}\" y=\"{{dir_y}}\" z=\"{{dir_z}}\"></dir>\n                <normal x=\"{{normal_x}}\" y=\"{{normal_y}}\" z=\"{{normal_z}}\"></normal>\n                <num_points>{{num_points}}</num_points>\n                <inner_radius>{{radius}}</inner_radius>\n            </geometry>\n            <result>\n                <x checked=\"1\">\n                    <tolerance lower_limit=\"{{x_lower}}\" upper_limit=\"{{x_upper}}\"></tolerance>\n                    <nominal_scalar value=\"{{x}}\"></nominal_scalar>\n                </x>\n                <y checked=\"1\">\n                    <tolerance lower_limit=\"{{y_lower}}\" upper_limit=\"{{y_upper}}\"></tolerance>\n                    <nominal_scalar value=\"{{y}}\"></nominal_scalar>\n                </y>\n                <z checked=\"1\">\n                    <tolerance lower_limit=\"{{z_lower}}\" upper_limit=\"{{z_upper}}\"></tolerance>\n                    <nominal_scalar value=\"{{z}}\"></nominal_scalar>\n                </z>\n              </result>\n        </polygon_hole>\n{{/isValid}}","output":"str","x":860,"y":660,"wires":[["c68c47a0.751e98"]]},{"id":"64d8b16.886585","type":"fs-ops-dir","z":"f7dd5695.c01598","name":"List CSV files in dir","path":"dirPath","pathType":"msg","filter":"*.csv","filterType":"str","dir":"payload","dirType":"msg","x":290,"y":120,"wires":[["f13ce5e1.c1b1e8"]]},{"id":"f13ce5e1.c1b1e8","type":"split","z":"f7dd5695.c01598","name":"Split files","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":460,"y":120,"wires":[["cecf1bbc.577608"]]},{"id":"cecf1bbc.577608","type":"change","z":"f7dd5695.c01598","name":"Set part settings","rules":[{"t":"set","p":"filename","pt":"msg","to":"$join([dirPath,payload], '/')\t","tot":"jsonata"},{"t":"delete","p":"parts","pt":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":620,"y":120,"wires":[["d5695b04.0654c8"]]},{"id":"4aee38d3.c6c228","type":"change","z":"f7dd5695.c01598","name":"XML file name","rules":[{"t":"set","p":"filename","pt":"msg","to":"$replace(filename, '.csv', '.xml')","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":1310,"y":500,"wires":[["48b211f0.ee47f"]]}]

Flow Info

Created 3 years, 6 months ago
Rating: 4 1

Owner

Actions

Rate:

Node Types

Core
  • change (x4)
  • csv (x1)
  • file (x1)
  • file in (x1)
  • inject (x1)
  • join (x1)
  • split (x2)
  • switch (x1)
  • template (x25)
Other
  • fs-ops-dir (x1)
  • tab (x1)

Tags

  • GOM
  • XML
  • measurement
  • CSV
  • metrology
  • import
  • inspection
  • characteristic
  • feature
  • part
Copy this flow JSON to your clipboard and then import into Node-RED using the Import From > Clipboard (Ctrl-I) menu option