So ... finally here you are.
- the data structure is defined by the topics: nameInStore.object[s].property seperated by dots.
-
nameInStore will be used as
global.get("nameInStore","file")
You have to edit this in ALL function nodes if you have a different store provider. -
object[s] the object in witch the
list[]
should be stored -
property name of the property or keyword to trigger a function (
uiDropdown, uiAdd, uiDelete
). The propertyname
must be provided to store the name of a configuration.
- make sure that is unchecked for ALL ui_Nodes EXCEPT the dropdown list
- all ui_Nodes must provide the topic described above. You can use the most resend ui_List , this should have the possibility to enter a topic.
- edit the addNew function node and add your default values
- edit the switch node to match your topics in the ui_Nodes
- all single msg.payload input / output can be wired directly between the switch node and the save Data function node
- for other nodes you have to add special nodes like the save List function node in the second example
- last but not least enter the initial topic in the inject node
And this is the result in your store:
Version with switches:
[{"id":"e73adecd.24ffa","type":"ui_text_input","z":"897fdb2a.109f68","name":"name","label":"","tooltip":"","group":"d11141a.b59afc","order":5,"width":6,"height":1,"passthru":false,"mode":"text","delay":"0","topic":"mySettings.heating.test.name","x":590,"y":280,"wires":[["1ff3f5ad.ab0eca"]]},{"id":"74ea0435.e9838c","type":"ui_button","z":"897fdb2a.109f68","name":"uiDelete","group":"d11141a.b59afc","order":3,"width":1,"height":1,"passthru":false,"label":"","tooltip":"","color":"","bgcolor":"","icon":"delete","payload":"Do you really like to delete this entry?","payloadType":"str","topic":"mySettings.heating.test.uiDelete","x":600,"y":220,"wires":[["843a51.ab4095b"]]},{"id":"372cbb4a.c123c4","type":"function","z":"897fdb2a.109f68","name":"delete period","func":"node.status({});\nvar currentObject= global.get(msg.topic.slice(0,msg.topic.indexOf('.')),\"file\");\nif (!currentObject) return;\nvar currentProperty=currentObject.getEntry(msg.topic);\nif (!currentProperty) {\n node.status({fill:\"red\",shape:\"dot\",text: msg.topic+\" not found\"});\n return;\n}\nvar name=currentProperty.name;\n\ntry {\n if (currentObject.deleteEntry(msg.topic)) {\n node.status({fill:\"green\",shape:\"dot\",text:name+\" deleted\"});\n } else {\n node.status({fill:\"green\",shape:\"dot\",text:name+\" NOT deleted\"});\n }\n return msg;\n} catch (err) {\n node.status({fill:\"red\",shape:\"dot\",text:\"ups, something gone wrong.\"});\n console.log(err);\n} ","outputs":1,"noerr":0,"x":890,"y":220,"wires":[["d3df79d6.ec2598"]]},{"id":"bd2033fe.103aa","type":"ui_date_picker","z":"897fdb2a.109f68","name":"start","label":"","group":"d11141a.b59afc","order":7,"width":6,"height":1,"passthru":false,"topic":"mySettings.heating.test.start","x":590,"y":320,"wires":[["1ff3f5ad.ab0eca"]]},{"id":"4dbfe990.188838","type":"ui_date_picker","z":"897fdb2a.109f68","name":"end","label":"","group":"d11141a.b59afc","order":9,"width":6,"height":1,"passthru":false,"topic":"mySettings.heating.test.end","x":590,"y":360,"wires":[["1ff3f5ad.ab0eca"]]},{"id":"3159de8.1169f22","type":"ui_text","z":"897fdb2a.109f68","group":"d11141a.b59afc","order":4,"width":2,"height":1,"name":"Name:","label":"Name:","format":"{{msg.payload}}","layout":"row-spread","x":110,"y":280,"wires":[]},{"id":"5073b43e.635a4c","type":"ui_text","z":"897fdb2a.109f68","group":"d11141a.b59afc","order":6,"width":2,"height":1,"name":"Start:","label":"Begin:","format":"{{msg.payload}}","layout":"row-spread","x":110,"y":340,"wires":[]},{"id":"fd9ab15d.fbc79","type":"ui_text","z":"897fdb2a.109f68","group":"d11141a.b59afc","order":8,"width":2,"height":1,"name":"End:","label":"End:","format":"{{msg.payload}}","layout":"row-spread","x":110,"y":400,"wires":[]},{"id":"d793942.135c968","type":"ui_dropdown","z":"897fdb2a.109f68","name":"uiDropdown","label":"","tooltip":"","place":"select period","group":"d11141a.b59afc","order":1,"width":6,"height":1,"passthru":true,"options":[],"payload":"","topic":"mySettings.heating.test.uiDropdown","x":610,"y":100,"wires":[["7dbcf8cd.631618"]]},{"id":"79445713.d60a98","type":"function","z":"897fdb2a.109f68","name":"update","func":"var msgDropdown={};\nvar msgName={};\nvar msgList={};\nvar msgParameter=[];\n\nvar topicParts=msg.topic.split('.');\nvar currentObject= global.get(topicParts[0],\"file\");\nif (!currentObject) return;\nvar keyword = topicParts.pop();\nvar propertyTopic = msg.topic.slice(0,msg.topic.lastIndexOf('.'));\nvar currentProperty=currentObject.getObject(msg.topic);\nif (!currentProperty) {\n node.status({fill:\"red\",shape:\"dot\",text:\"msg.topic='object.property' expected\"});\n return;\n}\n\nmsgDropdown.topic=msg.topic;\n\ntry {\n // fill an array for all parameters in list if exiting\n if (currentProperty.list) { \n for (var item in currentProperty.list[currentProperty.uiPointer]) {\n if (!item.startsWith('ui')) \n msgParameter.push({\"payload\":currentProperty.list[currentProperty.uiPointer][item], \"topic\": propertyTopic+'.'+item});\n }\n } \n switch (keyword) {\n case \"uiDropdown\":\n node.status({fill:\"green\",shape:\"dot\",text:\"Dropdown updated!\"});\n return [null,msgParameter]; // update all parameters\n case \"uiAdd\":\n msgDropdown.payload=currentProperty.uiPointer;\n node.status({fill:\"green\",shape:\"dot\",text:\"new entry nr=\"+currentProperty.uiPointer});\n return [msgDropdown,null]; // update only dropdown, parametes will follw next call\n case \"uiDelete\":\n msgDropdown.payload=\"init\";\n node.status({fill:\"green\",shape:\"dot\",text:\"entry deleted\"});\n return [msgDropdown,null]; // update only dropdown, parametes will follw next call\n case \"name\":\n msgDropdown.payload=currentProperty.uiPointer;\n node.status({fill:\"green\",shape:\"dot\",text:\"entry renamed!\"});\n return [msgDropdown,null]; // update only dropdown\n }\n \n node.status({fill:\"gray\",shape:\"dot\",text:msg.topic+\"=\"+msg.payload});\n return null;\n} catch (err) {\n node.status({fill:\"red\",shape:\"dot\",text:\"ups, somthing gone wrong. (\"+keyword+\")\"});\n console.log(err);\n} ","outputs":2,"noerr":0,"x":190,"y":200,"wires":[["f022e935.c6ab48"],["7c078fcf.9a8e9"]]},{"id":"b51dc782.8c09d8","type":"link out","z":"897fdb2a.109f68","name":"updatePeriod","links":["bc9c5ee1.ceb48"],"x":995,"y":280,"wires":[]},{"id":"bc9c5ee1.ceb48","type":"link in","z":"897fdb2a.109f68","name":"updatePeriod","links":["b51dc782.8c09d8","750a4ef9.a29c9","480be8a7.ca3858","d3df79d6.ec2598","54d64382.c8d62c"],"x":95,"y":200,"wires":[["79445713.d60a98"]]},{"id":"750a4ef9.a29c9","type":"link out","z":"897fdb2a.109f68","name":"updatePeriod","links":["bc9c5ee1.ceb48"],"x":995,"y":100,"wires":[]},{"id":"1ff3f5ad.ab0eca","type":"function","z":"897fdb2a.109f68","name":"save Data","func":"node.status({});\nvar currentObject= global.get(msg.topic.slice(0,msg.topic.indexOf('.')),\"file\");\nif (!currentObject) return;\nvar currentProperty=currentObject.getEntry(msg.topic);\nif (!currentProperty) {\n node.status({fill:\"red\",shape:\"dot\",text: msg.topic+\" not found\"});\n return;\n}\nvar propertyName=msg.topic.slice(msg.topic.lastIndexOf('.')+1);\n\ntry {\n // make shure your topic is set correctly in your ui nodes(s): objectName.propertyName\n currentProperty[propertyName]=msg.payload;\n\n node.status({fill:\"green\",shape:\"dot\",text:propertyName+\"=\"+msg.payload+\"!\"});\n return msg;\n} catch (err) {\n node.status({fill:\"red\",shape:\"dot\",text:\"ups, somthing gone wrong.\"});\n console.log(err);\n} ","outputs":1,"noerr":0,"x":880,"y":280,"wires":[["b51dc782.8c09d8"]],"icon":"font-awesome/fa-database"},{"id":"f022e935.c6ab48","type":"function","z":"897fdb2a.109f68","name":"fill dropdown","func":"var topicParts=msg.topic.split('.');\nvar currentObject= global.get(topicParts[0],\"file\");\nif (!currentObject) return;\nvar keyword = topicParts.pop();\nvar currentProperty=currentObject.getObject(msg.topic);\nif (!currentProperty) {\n node.status({fill:\"red\",shape:\"dot\",text:\"msg.topic='object.property' expected\"});\n return;\n}\n\n//try {\n console.log(currentProperty.list!==undefined)\n if (currentProperty.list!==undefined) {\n msg.options=[];\n var listEntry={};\n currentProperty.list.forEach(function(item,index){\n listEntry={};\n listEntry[item.name]=String(index);\n msg.options.push(listEntry);\n })\n msg.options.sort();\n \n if (!currentProperty.list[currentProperty.uiPointer]) {\n if (currentProperty.list.length>0){\n currentProperty.uiPointer=0; // reset to first\n msg.payload=currentProperty.uiPointer;\n } else { // no list existing\n delete msg.payload;\n }\n } else msg.payload=currentProperty.uiPointer;\n \n node.status({fill:\"green\",shape:\"dot\",text:\"done!\"});\n } else {\n node.status({fill:\"yellow\",shape:\"dot\",text:\"object.list empty\"});\n }\n return msg;\n\n/*} catch (err) {\n node.status({fill:\"yellow\",shape:\"dot\",text:\"No list entry\"});\n return msg;\n} */","outputs":1,"noerr":0,"x":410,"y":100,"wires":[["d793942.135c968"]]},{"id":"5ecf0362.de014c","type":"inject","z":"897fdb2a.109f68","name":"initalize","topic":"mySettings.heating.test.null","payload":"uiInit","payloadType":"str","repeat":"","crontab":"","once":true,"onceDelay":0.1,"x":100,"y":100,"wires":[["b984a3e8.bf33"]]},{"id":"7dbcf8cd.631618","type":"function","z":"897fdb2a.109f68","name":"set editPeriod","func":"var topicParts=msg.topic.split('.');\nvar currentObject= global.get(topicParts[0],\"file\");\nif (!currentObject) return;\nvar currentProperty=currentObject.getObject(msg.topic);\nif (!currentProperty) {\n node.status({fill:\"red\",shape:\"dot\",text:\"msg.topic='object.property' expected\"});\n return;\n}\n\ntry {\n currentProperty.uiPointer=Number(msg.payload);\n node.status({fill:\"green\",shape:\"dot\",text:msg.payload+\"!\"});\n return msg;\n} catch (err) {\n node.status({fill:\"red\",shape:\"dot\",text:\"ups, somthing gone wrong.\"});\n console.log(err);\n} ","outputs":1,"noerr":0,"x":840,"y":100,"wires":[["750a4ef9.a29c9"]]},{"id":"d3df79d6.ec2598","type":"link out","z":"897fdb2a.109f68","name":"updatePeriod","links":["bc9c5ee1.ceb48"],"x":995,"y":220,"wires":[]},{"id":"5a8215ea.6905cc","type":"ui_button","z":"897fdb2a.109f68","name":"uiAdd","group":"d11141a.b59afc","order":2,"width":1,"height":1,"passthru":false,"label":"","tooltip":"","color":"","bgcolor":"","icon":"playlist_add","payload":"unnamed","payloadType":"str","topic":"mySettings.heating.test.uiAdd","x":590,"y":160,"wires":[["cf5aca8c.406948"]]},{"id":"cf5aca8c.406948","type":"function","z":"897fdb2a.109f68","name":"add new","func":"node.status({});\nvar currentObject= global.get(msg.topic.slice(0,msg.topic.indexOf('.')),\"file\");\nif (!currentObject) return;\nvar currentProperty=currentObject.newObject(msg.topic);\nif (!currentProperty) {\n node.status({fill:\"red\",shape:\"dot\",text: msg.topic+\" not created\"});\n return;\n}\n\n// move Pointer to new entry\ncurrentProperty.uiPointer=currentProperty.list.length-1\nvar newItem = currentProperty.list[currentProperty.uiPointer];\n\n// initialize property object\nnewItem.name=msg.payload;\n\n//---------------------------------------------------------------\n// fill in defaults here! \n//---------------------------------------------------------------\nnewItem.start=new Date();\nnewItem.end=new Date();\nnewItem.monday=false;\nnewItem.tuesday=false;\nnewItem.wednesday=false;\nnewItem.thursday=false;\nnewItem.friday=false;\nnewItem.saturday=false;\nnewItem.sunday=false;\n\n\n// send output\nnode.status({fill:\"green\",shape:\"dot\",text:msg.payload+\" saved\"});\nreturn msg;","outputs":1,"noerr":0,"x":880,"y":160,"wires":[["54d64382.c8d62c"]],"icon":"node-red/file.png"},{"id":"54d64382.c8d62c","type":"link out","z":"897fdb2a.109f68","name":"updatePeriod","links":["bc9c5ee1.ceb48"],"x":995,"y":160,"wires":[]},{"id":"7c078fcf.9a8e9","type":"switch","z":"897fdb2a.109f68","name":"topic","property":"topic","propertyType":"msg","rules":[{"t":"eq","v":"mySettings.heating.test.name","vt":"str"},{"t":"eq","v":"mySettings.heating.test.start","vt":"str"},{"t":"eq","v":"mySettings.heating.test.end","vt":"str"},{"t":"eq","v":"mySettings.heating.test.monday","vt":"str"},{"t":"eq","v":"mySettings.heating.test.tuesday","vt":"str"},{"t":"eq","v":"mySettings.heating.test.wednesday","vt":"str"},{"t":"eq","v":"mySettings.heating.test.thursday","vt":"str"},{"t":"eq","v":"mySettings.heating.test.friday","vt":"str"},{"t":"eq","v":"mySettings.heating.test.saturday","vt":"str"},{"t":"eq","v":"mySettings.heating.test.sunday","vt":"str"}],"checkall":"true","repair":false,"outputs":10,"x":370,"y":340,"wires":[["e73adecd.24ffa"],["bd2033fe.103aa"],["4dbfe990.188838"],["61878250.8fc43c"],["2148eae6.2c8076"],["9572f07e.81162"],["9b06565e.dd2798"],["515536be.f1d9c8"],["4d24d50f.a27ccc"],["4ba796b0.614ec8"]]},{"id":"843a51.ab4095b","type":"ui_toast","z":"897fdb2a.109f68","position":"dialog","displayTime":"3","highlight":"","sendall":false,"outputs":1,"ok":"OK","cancel":"","topic":"","name":"Delete?","x":740,"y":220,"wires":[["372cbb4a.c123c4"]]},{"id":"b984a3e8.bf33","type":"function","z":"897fdb2a.109f68","name":"initialize","func":"if (!msg.payload) return;\n\nvar topicParts=\"\";\n\ntry {\n topicParts=msg.topic.split('.');\n} catch (err) {\n node.status({fill:\"red\",shape:\"dot\",text:\"msg.topic='object.property' expected\"});\n}\nvar keyword = topicParts.pop();\n\nif (topicParts.length<3) {\n node.status({fill:\"red\",shape:\"dot\",text:\"msg.topic='object.property' expected\"});\n return;\n}\n\n\n// get or initalize root for global store\nvar currentObject= global.get(topicParts[0],\"file\");\nif (!currentObject) {\n currentObject={};\n global.set(topicParts[0],currentObject,\"file\")\n}\n\n// function to create object for specific topic\ncurrentObject.newObject = function(topic) {\n var topicParts = topic.split('.');\n var keyword=topicParts.pop();\n if (keyword!='uiAdd') return Null\n if (topicParts.length<2) return null;\n var objectPtr=global.get(topicParts[0],\"file\");\n for (var i=1; i<topicParts.length; i++) {\n if (!objectPtr[topicParts[i]]) return null; // object not found\n objectPtr=objectPtr[topicParts[i]];\n }\n if (!objectPtr.list) objectPtr.list=[]; // initialize list if not existing\n objectPtr.list.push({}); // add new object into list\n return objectPtr;\n};\n\n// function to get object for specific topic\ncurrentObject.getObject = function(topic) {\n var topicParts = topic.split('.');\n if (topicParts.length<2) return null;\n var objectPtr=global.get(topicParts[0],\"file\");\n for (var i=1; i<topicParts.length-1; i++) { // ignore the last identifier\n if (!objectPtr[topicParts[i]]) return null; // object not found\n objectPtr=objectPtr[topicParts[i]];\n } \n return objectPtr;\n};\n\n// function to get object for current entry out of list\ncurrentObject.getEntry = function(topic) {\n objectPtr=this.getObject(topic);\n if (objectPtr.uiPointer<objectPtr.list.length){\n return objectPtr.list[objectPtr.uiPointer];\n }\n return null;\n};\n\n// function to delete current entry out of list\ncurrentObject.deleteEntry = function(topic) {\n objectPtr=this.getObject(topic);\n if (objectPtr.uiPointer<objectPtr.list.length){\n var returnObj= objectPtr.list.splice(objectPtr.uiPointer,1);\n if (returnObj) objectPtr.uiPointer=0;\n return returnObj;\n }\n return null;\n};\n\n// (re)build Object Tree\nvar objectRoot= currentObject;\nfor (i=1; i<topicParts.length; i++) {\n if (!currentObject[topicParts[i]]) currentObject[topicParts[i]]={};\n currentObject=currentObject[topicParts[i]];\n}\nif (currentObject.uiPointer===undefined) currentObject.uiPointer=0;\nnode.status({fill:\"green\",shape:\"dot\",text:\"done!\"});\nreturn msg;\n","outputs":1,"noerr":0,"x":240,"y":100,"wires":[["f022e935.c6ab48"]]},{"id":"61878250.8fc43c","type":"ui_switch","z":"897fdb2a.109f68","name":"","label":"Monday","tooltip":"","group":"d11141a.b59afc","order":10,"width":0,"height":0,"passthru":true,"decouple":"false","topic":"mySettings.heating.test.monday","style":"","onvalue":"true","onvalueType":"bool","onicon":"","oncolor":"","offvalue":"false","offvalueType":"bool","officon":"","offcolor":"","x":600,"y":400,"wires":[["1ff3f5ad.ab0eca"]]},{"id":"2148eae6.2c8076","type":"ui_switch","z":"897fdb2a.109f68","name":"","label":"Tuesday","tooltip":"","group":"d11141a.b59afc","order":11,"width":0,"height":0,"passthru":true,"decouple":"false","topic":"mySettings.heating.test.tuesday","style":"","onvalue":"true","onvalueType":"bool","onicon":"","oncolor":"","offvalue":"false","offvalueType":"bool","officon":"","offcolor":"","x":600,"y":460,"wires":[["1ff3f5ad.ab0eca"]]},{"id":"9572f07e.81162","type":"ui_switch","z":"897fdb2a.109f68","name":"","label":"Wednesday","tooltip":"","group":"d11141a.b59afc","order":12,"width":0,"height":0,"passthru":true,"decouple":"false","topic":"mySettings.heating.test.wednesday","style":"","onvalue":"true","onvalueType":"bool","onicon":"","oncolor":"","offvalue":"false","offvalueType":"bool","officon":"","offcolor":"","x":610,"y":520,"wires":[["1ff3f5ad.ab0eca"]]},{"id":"9b06565e.dd2798","type":"ui_switch","z":"897fdb2a.109f68","name":"","label":"Thursday","tooltip":"","group":"d11141a.b59afc","order":13,"width":0,"height":0,"passthru":true,"decouple":"false","topic":"mySettings.heating.test.thursday","style":"","onvalue":"true","onvalueType":"bool","onicon":"","oncolor":"","offvalue":"false","offvalueType":"bool","officon":"","offcolor":"","x":600,"y":580,"wires":[["1ff3f5ad.ab0eca"]]},{"id":"515536be.f1d9c8","type":"ui_switch","z":"897fdb2a.109f68","name":"","label":"Friday","tooltip":"","group":"d11141a.b59afc","order":14,"width":0,"height":0,"passthru":true,"decouple":"false","topic":"mySettings.heating.test.friday","style":"","onvalue":"true","onvalueType":"bool","onicon":"","oncolor":"","offvalue":"false","offvalueType":"bool","officon":"","offcolor":"","x":590,"y":640,"wires":[["1ff3f5ad.ab0eca"]]},{"id":"4d24d50f.a27ccc","type":"ui_switch","z":"897fdb2a.109f68","name":"","label":"Saturday","tooltip":"","group":"d11141a.b59afc","order":15,"width":0,"height":0,"passthru":true,"decouple":"false","topic":"mySettings.heating.test.saturday","style":"","onvalue":"true","onvalueType":"bool","onicon":"","oncolor":"","offvalue":"false","offvalueType":"bool","officon":"","offcolor":"","x":600,"y":700,"wires":[["1ff3f5ad.ab0eca"]]},{"id":"4ba796b0.614ec8","type":"ui_switch","z":"897fdb2a.109f68","name":"","label":"Sunday","tooltip":"","group":"d11141a.b59afc","order":16,"width":0,"height":0,"passthru":true,"decouple":"false","topic":"mySettings.heating.test.sunday","style":"","onvalue":"true","onvalueType":"bool","onicon":"","oncolor":"","offvalue":"false","offvalueType":"bool","officon":"","offcolor":"","x":600,"y":760,"wires":[["1ff3f5ad.ab0eca"]]},{"id":"d11141a.b59afc","type":"ui_group","z":"","name":"Test Period","tab":"450f9708.9afe08","disp":true,"width":"8","collapse":false},{"id":"450f9708.9afe08","type":"ui_tab","z":"","name":"ui_Test","icon":"dashboard","disabled":false,"hidden":false}]
ui_list version in next post