Best approach to use node flows to generate structured XML

730 views
Skip to first unread message

perdomo-0a

unread,
Dec 9, 2016, 11:53:16 AM12/9/16
to Node-RED
Hi,

i am fairly new to node-red and i am looking for some advice of the experienced user group here.

What i am trying to do
I would like to use node-red as the UI to generate config files for a software. So instead of hacking in XML i would like to create flows that in the end generate the XML. Plenty of googling and scrolling through user groups and the flow directories didn't really help out to get a picture what could be an approach.

Currently i thought about creating custom nodes per XML section that can be configured in node red. The parameters are stored in the javascript object and i would send this through the json node and finally the xml2js node to create my configuration.

Questions
  1. Better ideas on how to do such a thing: reusing node-red as a UI for creating structuured config as a result?
  2. How can i create xml with attributes in the xml node, what type of object or input must be passed to the node that it creates an attribute?
  3. Is there a documentation somewhere describing each node in details, especially the JSON and XML nodes, smth like a reference.
  4. Is there a good node i could start with for holding the properties that i could you as a base before running it through the conversions? Like the input node which seemed to be to limited

Config XML

This is how my XML should look like, as you can see i am very dependent on attributes. I got different objects: sensors having evaluation rules (could be two nodes wired together) and rules consisting of a trigger and a condition.



<sensor_configuration>
   
<sensors>
       
<sensor sensor_id="cloud_connected">
           
<sensor_class>unknown</sensor_class>
       
</sensor>
       
<sensor sensor_id="Vibration_Alarm">
           
<sensor_class>boolean</sensor_class>
           
<unit/>
           
<state_evaluation_expressions>
               
<state_evaluation_expression>
                   
<expression>value</expression>
                   
<true severity="200">Vibration alert</true>
                   
<false severity="0">OK</false>
               
</state_evaluation_expression>
           
</state_evaluation_expressions>
       
</sensor>
       
<sensor sensor_id="Ventilator">
           
<sensor_class>boolean</sensor_class>
           
<unit/>
           
<state_evaluation_expressions>
               
<state_evaluation_expression>
                   
<expression>value</expression>
                   
<true severity="100">ON</true>
                   
<false severity="0">OFF</false>
               
</state_evaluation_expression>
           
</state_evaluation_expressions>
           
<sensor_gateway sensor_gateway_id="gw_X20DO6639_coils_2">
               
<demux>
                   
<keys>
                       
<key>24</key>
                   
</keys>
               
</demux>
           
</sensor_gateway>
       
</sensor>
   
</sensors>
   
<ac_rules>
       
<rule rule_id="Raise_cumulative_alarm">
           
<triggers>
               
<trigger sensor_id="Temp_Alarm" trigger_topic="calibrated_result" value_name="temp_alarm" value_type="boolean"/>
               
<trigger sensor_id="Door_Alarm" trigger_topic="calibrated_result" value_name="door_alarm" value_type="boolean"/>
               
<trigger sensor_id="Vibration_Alarm" trigger_topic="calibrated_result" value_name="vibration_alarm" value_type="boolean"/>
           
</triggers>
           
<conditions>
               
<condition expr="door_alarm or temp_alarm or vibration_alarm">
                   
<true>
                       
<result_list>
                           
<result result_value="True" sensor_id="Alarm" value_type="boolean"/>
                       
</result_list>
                   
</true>
               
</condition>
           
</conditions>
       
</rule>
   
</ac_rules>
</sensor_configuration>



I hope i have been comprehensible enough even though i am fairly unsure if this all makes sense or node-red might be the wrong vehicle for it.

Thanks in advance,
Regards

perdomo-0a

unread,
Dec 9, 2016, 12:04:41 PM12/9/16
to Node-RED
I quickly creatd a non-functional flow that would show what i am intending to do.

[{"id":"bb92a879.13de68","type":"tab","label":"sensor config flow to XML"},{"id":"d1268305.9a67f8","type":"inject","z":"bb92a879.13de68","name":"","topic":"","payload":"Vibration Sensor","payloadType":"str","repeat":"","crontab":"","once":false,"x":283.5,"y":207,"wires":[["62974f13.593028","80689a73.f16e68","54c1cbed.110444"]]},{"id":"62974f13.593028","type":"function","z":"bb92a879.13de68","name":"state_evaluation","func":"\nreturn msg;","outputs":1,"noerr":0,"x":503.5,"y":89,"wires":[[]]},{"id":"80689a73.f16e68","type":"function","z":"bb92a879.13de68","name":"ac_rule","func":"\nreturn msg;","outputs":1,"noerr":0,"x":494.5,"y":148,"wires":[[]]},{"id":"b41d7492.b846e8","type":"inject","z":"bb92a879.13de68","name":"","topic":"","payload":"Temperature Sensor","payloadType":"str","repeat":"","crontab":"","once":false,"x":267,"y":319,"wires":[["54c1cbed.110444"]]},{"id":"34015175.ec001e","type":"inject","z":"bb92a879.13de68","name":"","topic":"","payload":"Door Alarm","payloadType":"str","repeat":"","crontab":"","once":false,"x":282,"y":263,"wires":[["54c1cbed.110444"]]},{"id":"54c1cbed.110444","type":"function","z":"bb92a879.13de68","name":"Condition","func":"\nreturn msg;","outputs":1,"noerr":0,"x":550.5,"y":486,"wires":[["d85ba25a.603d7"]]},{"id":"d85ba25a.603d7","type":"function","z":"bb92a879.13de68","name":"Raise Alarm","func":"\nreturn msg;","outputs":1,"noerr":0,"x":779.5,"y":485,"wires":[[]]},{"id":"7eef4ddb.95b72c","type":"inject","z":"bb92a879.13de68","name":"","topic":"","payload":"My Flow","payloadType":"flow","repeat":"","crontab":"","once":false,"x":252.5,"y":605,"wires":[["541a7079.153b2"]]},{"id":"541a7079.153b2","type":"json","z":"bb92a879.13de68","name":"","x":481.5,"y":604,"wires":[["c7b07b60.c915a"]]},{"id":"c7b07b60.c915a","type":"xml","z":"bb92a879.13de68","name":"","attr":"","chr":"","x":736.5,"y":604,"wires":[[]]},{"id":"37e285bb.a87d92","type":"comment","z":"bb92a879.13de68","name":"Sensor Config Flow","info":"the above represents the sensor configuration. I would then like to export this flow and run it through the below flow that creates json out of the JS objects and finally XMl via xml2json?","x":304.5,"y":152,"wires":[]},{"id":"bc992d63.e949d8","type":"comment","z":"bb92a879.13de68","name":"Create XML from input flow above through xml2json","info":"","x":363.5,"y":564,"wires":[]}]

Julian Knight

unread,
Dec 10, 2016, 4:32:28 AM12/10/16
to Node-RED
A good place to start would be to take your example XML and feed it into Node-RED and through an XML node which will convert it to JSON. Since JSON is easily handled in JavaScript you should then find it easier to work out how to manipulate it. Once you have a flow that works for you, you can run the JSON through the XML node again and it should produce the output you want that you can then save with a file out node.

Julian Knight

unread,
Dec 10, 2016, 4:35:07 AM12/10/16
to Node-RED
For some reason, I can't import this flow. I don't get an error but I don't get a flow either.

perdomo-0a

unread,
Dec 14, 2016, 7:09:29 AM12/14/16
to Node-RED
Thanks for your reply Julian. I exported the flow again and this should be importable for you.

[
   
{
       
"id": "4ec80b49.c05b24",

       
"type": "tab",
       
"label": "sensor config flow to XML"
   
},
   
{

       
"id": "c0242e33.b9e918",
       
"type": "inject",
       
"z": "4ec80b49.c05b24",

       
"name": "",
       
"topic": "",
       
"payload": "Vibration Sensor",
       
"payloadType": "str",
       
"repeat": "",
       
"crontab": "",
       
"once": false,
       
"x": 283.5,
       
"y": 207,
       
"wires": [
           
[

               
"482c456c.68bd04",
               
"ac65a476.016c9",
               
"4cf9bc41.620c14"
           
]
       
]
   
},
   
{
       
"id": "482c456c.68bd04",
       
"type": "function",
       
"z": "4ec80b49.c05b24",

       
"name": "state_evaluation",
       
"func": "\nreturn msg;",
       
"outputs": 1,
       
"noerr": 0,
       
"x": 503.5,
       
"y": 89,
       
"wires": [
           
[]
       
]
   
},
   
{

       
"id": "ac65a476.016c9",
       
"type": "function",
       
"z": "4ec80b49.c05b24",

       
"name": "ac_rule",
       
"func": "\nreturn msg;",
       
"outputs": 1,
       
"noerr": 0,
       
"x": 494.5,
       
"y": 148,
       
"wires": [
           
[]
       
]
   
},
   
{

       
"id": "1e126b77.18cd1d",
       
"type": "inject",
       
"z": "4ec80b49.c05b24",

       
"name": "",
       
"topic": "",
       
"payload": "Temperature Sensor",
       
"payloadType": "str",
       
"repeat": "",
       
"crontab": "",
       
"once": false,
       
"x": 267,
       
"y": 319,
       
"wires": [
           
[

               
"4cf9bc41.620c14"
           
]
       
]
   
},
   
{
       
"id": "ad73cedb.a51cd8",
       
"type": "inject",
       
"z": "4ec80b49.c05b24",

       
"name": "",
       
"topic": "",
       
"payload": "Door Alarm",
       
"payloadType": "str",
       
"repeat": "",
       
"crontab": "",
       
"once": false,
       
"x": 282,
       
"y": 263,
       
"wires": [
           
[

               
"4cf9bc41.620c14"
           
]
       
]
   
},
   
{
       
"id": "4cf9bc41.620c14",
       
"type": "function",
       
"z": "4ec80b49.c05b24",

       
"name": "Condition",
       
"func": "\nreturn msg;",
       
"outputs": 1,
       
"noerr": 0,
       
"x": 550.5,
       
"y": 486,
       
"wires": [
           
[

               
"d00307ba.aa3898"
           
]
       
]
   
},
   
{
       
"id": "d00307ba.aa3898",
       
"type": "function",
       
"z": "4ec80b49.c05b24",

       
"name": "Raise Alarm",
       
"func": "\nreturn msg;",
       
"outputs": 1,
       
"noerr": 0,
       
"x": 779.5,
       
"y": 485,
       
"wires": [
           
[]
       
]
   
},
   
{

       
"id": "64dea5af.c86b34",
       
"type": "inject",
       
"z": "4ec80b49.c05b24",

       
"name": "",
       
"topic": "",
       
"payload": "My Flow",
       
"payloadType": "flow",
       
"repeat": "",
       
"crontab": "",
       
"once": false,
       
"x": 252.5,
       
"y": 605,
       
"wires": [
           
[

               
"f1ecfa72.21fda8"
           
]
       
]
   
},
   
{
       
"id": "f1ecfa72.21fda8",
       
"type": "json",
       
"z": "4ec80b49.c05b24",

       
"name": "",
       
"x": 481.5,
       
"y": 604,
       
"wires": [
           
[

               
"b547c7a7.690c"
           
]
       
]
   
},
   
{
       
"id": "b547c7a7.690c",
       
"type": "xml",
       
"z": "4ec80b49.c05b24",

       
"name": "",
       
"attr": "",
       
"chr": "",
       
"x": 736.5,
       
"y": 604,
       
"wires": [
           
[]
       
]
   
},
   
{

       
"id": "b70a08b.bc4fb78",
       
"type": "comment",
       
"z": "4ec80b49.c05b24",

       
"name": "Sensor Config Flow",
       
"info": "the above represents the sensor configuration. I would then like to export this flow and run it through the below flow that creates json out of the JS objects and finally XMl via xml2json?",
       
"x": 304.5,
       
"y": 152,
       
"wires": []
   
},
   
{

       
"id": "8b425a7d.a29128",
       
"type": "comment",
       
"z": "4ec80b49.c05b24",

       
"name": "Create XML from input flow above through xml2json",
       
"info": "",
       
"x": 363.5,
       
"y": 564,
       
"wires": []
   
}
]

Julian Knight

unread,
Dec 14, 2016, 3:21:51 PM12/14/16
to Node-RED
Urm, that's weird! It still doesn't import properly, never seen this before. NR knows that something has changed so offers me the commit button but nothing appears in the UI and I get no errors in the browser nor the NR consoles.

Perhaps someone else can try?

Nicholas O'Leary

unread,
Dec 14, 2016, 3:56:48 PM12/14/16
to Node-RED Mailing List
It imports fine - as it includes a tab node, the nodes end up on that new tab, not the current one.

I'm struggling to understand the concept here. Is the top flow meant to generate some XML? Or is it meant to be a structural representation of some xml that your second flow parses out to some form?

Nick



--
http://nodered.org
 
Join us on Slack to continue the conversation: http://nodered.org/slack
---
You received this message because you are subscribed to the Google Groups "Node-RED" group.
To unsubscribe from this group and stop receiving emails from it, send an email to node-red+unsubscribe@googlegroups.com.
To post to this group, send email to node...@googlegroups.com.
Visit this group at https://groups.google.com/group/node-red.
To view this discussion on the web, visit https://groups.google.com/d/msgid/node-red/96cb9f4f-4fe8-4512-aa0c-be07773c8fc0%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Julian Knight

unread,
Dec 14, 2016, 6:23:24 PM12/14/16
to Node-RED
Ah, I thought I'd checked that.

Kratediggah

unread,
Dec 16, 2016, 4:42:09 PM12/16/16
to Node-RED Mailing List
Thanks for importing it. Yes its like a pseudo flow. The top represents the structure that should become an xml in the end and the botton represents the conversion flow. I am lacking the node red skill here and am searching for feedback what would be a good approach to generate out of flows an xml close to our todays xml file. I thought about creating special nodes, connecting these and using the final js object to throw it into the conversion flow if that makes sense.

You received this message because you are subscribed to a topic in the Google Groups "Node-RED" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/node-red/ghet3XMxyf4/unsubscribe.
To unsubscribe from this group and all its topics, send an email to node-red+u...@googlegroups.com.

To post to this group, send email to node...@googlegroups.com.
Visit this group at https://groups.google.com/group/node-red.
Reply all
Reply to author
Forward
0 new messages