If you’ve ever needed to quickly change an entire strategy’s worth of PAC Control tags back and forth between specific pre-set values, this post is for you!
This flow takes tag “recipes” as comma-separated value (CSV) files, breaks the files down, and then uses that data to set any number of PAC Control tags that you need – all triggered by input from groov View:
With this flow you can make as many recipe files as you need, and simply set the file name (#1-6 in this case) using groov View to immediately have those values applied to your PAC Control tags.
These files take the format “
type,tagName,value” on each new line. The type must be int32, int64, float, or string exactly (no capital letters or spaces), followed by the PAC Control tag name, and finally the value the tag should be set to.Here’s a complete
recipe-#.csv example:
int32,count,122
float,pi,3.14159
string,MyString,testing
int32,pause,500
int64,Opto,22
Which applies to the values in PAC Control right away:

In order for this to work with groov View you can simply have a groov View tag set by a series of command buttons that will update the value based on the recipe you select:

Finally you will need to load each of the recipe-#.csv files into the unsecured file area of your groov EPIC so that Node-RED can access them. You can either create these files directly in Node-RED or just drop them in the file area via groov Manage.
Here is the example CSV file to get you started: recipe-5.zip (237 Bytes),
and here is the flow import code for you to try it yourself:
[{"id":"5bfc7774.a81ca8","type":"switch","z":"72ff86de.983b78","name":"type?","property":"payload.type","propertyType":"msg","rules":[{"t":"eq","v":"int32","vt":"str"},{"t":"eq","v":"int64","vt":"str"},{"t":"eq","v":"float","vt":"str"},{"t":"eq","v":"string","vt":"str"},{"t":"else"}],"checkall":"true","repair":false,"outputs":5,"x":690,"y":1340,"wires":[["fec057cc.6174b8"],["76c7bc62.4dbc44"],["a9e16c44.23a67"],["4821b52e.c5f3ac"],["2d9e3199.8f91ce"]]},{"id":"30e8b89e.6374f8","type":"function","z":"72ff86de.983b78","name":"type,tag,value","func":"var write = {}; // write object to be sent out\ndata = msg.payload; // make a copy of msg.payload\ntype = data.indexOf(','); // find the commas in \"type,tag,value\"\ntag = data.indexOf(',', type+1); // offset by 1 to skip the first comma\n\nwrite.type = data.substring(0,type); // first field is the data type\nwrite.tagName = data.substring(type+1,tag); // second field is the tag name\nwrite.value = data.substring(tag+1,data.length); // final field is the write value\n\nreturn { payload : write }; // now we have payload.tagName and payload.value for the PAC node","outputs":1,"noerr":0,"x":500,"y":1360,"wires":[["5bfc7774.a81ca8"]]},{"id":"fec057cc.6174b8","type":"pac-write","z":"72ff86de.983b78","device":"1b17b31a.79d5ad","dataType":"int32-variable","tagName":"","tableStartIndex":"","value":"payload.value","valueType":"msg","name":"int32","x":890,"y":1260,"wires":[[]]},{"id":"76c7bc62.4dbc44","type":"pac-write","z":"72ff86de.983b78","device":"1b17b31a.79d5ad","dataType":"int64-variable","tagName":"","tableStartIndex":"","value":"payload.value","valueType":"msg","name":"int64","x":890,"y":1300,"wires":[[]]},{"id":"a9e16c44.23a67","type":"pac-write","z":"72ff86de.983b78","device":"1b17b31a.79d5ad","dataType":"float-variable","tagName":"","tableStartIndex":"","value":"payload.value","valueType":"msg","name":"float","x":890,"y":1340,"wires":[[]]},{"id":"4821b52e.c5f3ac","type":"pac-write","z":"72ff86de.983b78","device":"1b17b31a.79d5ad","dataType":"string-variable","tagName":"","tableStartIndex":"","value":"payload.value","valueType":"msg","name":"string","x":890,"y":1380,"wires":[[]]},{"id":"2d9e3199.8f91ce","type":"debug","z":"72ff86de.983b78","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":890,"y":1420,"wires":[]},{"id":"af341aeb.561788","type":"file in","z":"72ff86de.983b78","name":"recipe-#.csv","filename":"","format":"lines","chunk":false,"sendError":false,"encoding":"none","x":330,"y":1360,"wires":[["30e8b89e.6374f8"]]},{"id":"5da1a2b6.3b040c","type":"change","z":"72ff86de.983b78","name":"set filename","rules":[{"t":"set","p":"filename","pt":"msg","to":"\"/home/dev/unsecured/recipe-\" & msg.payload & \".csv\"","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":170,"y":1360,"wires":[["af341aeb.561788"]]},{"id":"d2473d07.00bdb","type":"rbe","z":"72ff86de.983b78","name":"","func":"rbe","gap":"","start":"","inout":"out","property":"payload","x":460,"y":1300,"wires":[["5da1a2b6.3b040c"]]},{"id":"e9b45fcf.fc045","type":"groov-read-ds","z":"72ff86de.983b78","dataStore":"18a28a95.517b05","tagName":"recipe","tableStartIndex":"","tableLength":"","value":"","valueType":"msg.payload","topic":"","topicType":"none","name":"recipe #","x":320,"y":1300,"wires":[["d2473d07.00bdb"]]},{"id":"d116b38b.8801a","type":"inject","z":"72ff86de.983b78","name":"","topic":"","payload":"","payloadType":"date","repeat":"1","crontab":"","once":true,"onceDelay":0.1,"x":170,"y":1300,"wires":[["e9b45fcf.fc045"]]},{"id":"1b17b31a.79d5ad","type":"pac-device","z":0,"address":"localhost","protocol":"https"},{"id":"18a28a95.517b05","type":"groov-data-store","z":0,"project":"6f94d393.9ebf4c","dsName":"NodeRED"},{"id":"6f94d393.9ebf4c","type":"groov-project","z":0,"address":"localhost"}]
Please comment below if you have any questions or specific use-cases for this code, and feel free to modify and reuse it however you need.
Happy coding!

