Dropbox folder sync

I've just had a look at your flow, and it seems that you've deleted some necessary code from the 'Generate commands' node which I've re-added, and the path formats were not correct.

So with the flow corrected, firstly I've added the path for a temporary directory (to hold the archive before sending it to dropbox) on line 3 of the 'Generate commands' node;
var path = '/home/pi/tempDir/'; TAKE NOTE - the trailing slash /
This can be any path on your system, and doesn't need to be created first - the flow will create it.

On my pi, I've created a folder which contains a number of files which I want to back up;

/home/pi/testDir
         ├── test1.txt
         ├── test2.txt
         └── test3.txt

.and added the path /home/pi/testDir to line 27 of the 'Generate commands' node.
Again, this can be a directory path of your choice.

Finally, I updated the 2 paths in the 'Read filenames' with the new tempDir path.

Running the flow, results in this msg being injected into the dropbox node - which is the path for the archive file to be uploaded to dropbox.
drop
...and the Thu_testDir.tar.gz file being successfully uploaded to Dropbox.

Anyway, here is the flow which I used in the above example;

[{"id":"1b89f49d.7bc87b","type":"comment","z":"9616f62.4426f08","name":"Nightly Backups","info":"","x":123,"y":100,"wires":[]},{"id":"2c3308c.d13c2f8","type":"inject","z":"9616f62.4426f08","name":"Start backup","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"00 03 * * *","once":false,"onceDelay":"","x":130,"y":150,"wires":[["51aee723.e82988"]]},{"id":"5d361489.9c825c","type":"function","z":"9616f62.4426f08","name":"Triggered queue","func":"// if queue doesn't exist, create it\ncontext.queue = context.queue || [];\ncontext.busy = context.busy || false;\n\n// if the msg is a trigger one release next message\nif (msg.hasOwnProperty(\"trigger\")) {\n    if (context.queue.length > 0) {\n        var m = context.queue.shift();\n        return {payload:m};\n    }\n    else {\n        context.busy = false;\n      //  node.send({payload:\"result\"});\n      var msg2 = { payload:\"OK\" };\n    }\n}\nelse {\n    if (context.busy) {\n        // if busy add to queue\n        context.queue.push(msg.payload);\n    }\n    else {\n        // otherwise we are empty so just pass through and set busy flag\n        context.busy = true;\n        return msg;\n    }\n}\n\nreturn [null,msg2];","outputs":"2","noerr":0,"x":300,"y":240,"wires":[["683cd42.833362c"],["c6b1a676.bfd758"]]},{"id":"fb715149.0d43f","type":"function","z":"9616f62.4426f08","name":"set trigger","func":"// handle the return from the exec in here \n// if all is good then set msg.trigger property to exist\nmsg.trigger = 1;\nreturn msg;","outputs":1,"noerr":0,"x":590,"y":150,"wires":[["5d361489.9c825c"]]},{"id":"683cd42.833362c","type":"exec","z":"9616f62.4426f08","command":"","addpay":true,"append":"","useSpawn":"false","timer":"","oldrc":false,"name":"Execute commands","x":530,"y":230,"wires":[["fb715149.0d43f"],[],["15110d05.06fe83"]]},{"id":"c6b1a676.bfd758","type":"function","z":"9616f62.4426f08","name":"Read filenames","func":"var path = ('/home/pi/tempDir/');\nvar fs = (global.get('fse'));\n\nfs.readdirSync(path).forEach(file => {\n  node.send({localFilename: \"/home/pi/tempDir/\"+(file)});\n});\nreturn null;","outputs":1,"noerr":0,"x":310,"y":300,"wires":[["798ff79f.0715d8"]]},{"id":"51aee723.e82988","type":"function","z":"9616f62.4426f08","name":"Generate commands","func":"//--Edit these to your own installation\n//Don't change these!\nvar path = '/home/pi/tempDir/';\n\n//Generate days to add to archive title\nvar d = new Date();\nvar day = new Array(7);\nday[0]=  \"Sun\";\nday[1] = \"Mon\";\nday[2] = \"Tue\";\nday[3] = \"Wed\";\nday[4] = \"Thu\";\nday[5] = \"Fri\";\nday[6] = \"Sat\";\n\n//Create directory structure\nvar m1={payload: \"rm -rf \"+[path]};\nvar m2={payload: \"mkdir \"+[path]};\n\n// ************************************************************************* //\n// *** The below commands will archive the entire node-red user directory,\n// *** emoncms data directories & mysql. To add further commands, use the\n// *** same format, and add the corresponding msg id to the 'return' statement.\n// ************************************************************************* //\n//---Log Filer---//\n  //Create ~/testDir archive\n  var m4={payload: \"tar -czvf \"+[path]+(day[d.getDay()])+\"_testDir\"+\".tar.gz /home/pi/testDir\"};\n\n// Output the commands for execution\nreturn [ [ m1, m2, m4, ] ];","outputs":"1","noerr":0,"x":334,"y":150,"wires":[["5d361489.9c825c"]]},{"id":"15110d05.06fe83","type":"function","z":"9616f62.4426f08","name":"Report any errors","func":"var code = (msg.payload.code);\nif ([code] != \"0\") {\nmsg.payload = (msg.payload.message);\nmsg.topic = \"Raspberry backup process failed\";\nreturn msg;\n}\nelse {\nreturn null;\n}","outputs":1,"noerr":0,"x":300,"y":350,"wires":[["9d4138d9.e0f328"]]},{"id":"e1e0dd4a.dc498","type":"comment","z":"9616f62.4426f08","name":"README (select & view in info panel!)","info":"**REQUIREMENTS**  \nRequires the library fs-extra installing & enabling\nglobally in settngs.js  \n(used in `Read Filenames` function node)\n\nTO INSTALL FS-EXTRA  \n```\ncd ./node-red  \nnpm install --save fs-extra\n```\nTO MAKE FS-EXTRA GLOBAL  \nAdd `fse:require('fs-extra')` to the\n`functionGlobalContext` section in NR settings.js file.\n\n**CONFIGURATION**  \nEdit the `Generate commands` function node with \nyour own;  \n- Emoncms data directory path\n- Emoncms MYSQL username (default = emoncms)\n- Emoncms MYSQL password  \n\nSetup the `dropbox` node, (details in the node info)  \nAlso edit the `Start backup` inject node with your preferred time to run.  \nIf you want to be alerted about archive problems or failures, you can use the `Report any errors` node output to dispatch the message via Pushover, email, twitter or whatever.","x":379,"y":99,"wires":[]},{"id":"9d4138d9.e0f328","type":"debug","z":"9616f62.4426f08","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":600,"y":350,"wires":[]},{"id":"798ff79f.0715d8","type":"debug","z":"9616f62.4426f08","name":"Replace with dropbox node","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":600,"y":300,"wires":[]}]

Thanks again for the thorough reply.
I am not actually trying to make backups in tar.gz format, but just to upload the files in the directory, but this is a minor issue.
Even so, I am still getting the error
" 3/1/2019 13.25.49node: Read filenamesfunction : (error)

"TypeError: Cannot read property 'readdirSync' of undefined""
after having created the testdir and a text file. This is all the output I am getting, and none of the nodes are reporting errors as such - just the above message.

That means your fs variable is undefined in this piece of code --

So either you modified the wrong settings.js file (and the functionGlobalContext is not being set), or you don't have the fs-extra module installed in the right place... as mentioned in the docs:

Modules loaded from your settings file must be installed in the same directory as the settings file. For most users that will be the default user directory - ~/.node-red

Although, in that case, I would expect the require to fail and put something in the console log.

Aren't there already nodes set up to watch for changes to directory contents, and send a msg with the filename? Seems like that would be a lot simpler than writing it all inside a function node, especially one that needs to require other modules... Or if you don't need to know immediately when a new file is ready to be backed up, have any of the scheduler nodes just read the directory and output a list of all the files in it, and copy each to dropbox (either using a dropbox node, or even an exec node to run the system "copy" command).

The reason for creating an archive including the day of the week, eg Thu_testDir.tar.gz was that over a week, you would have 7 individually named archives uploaded to Dropbox, so that in the event of an issue, you could quickly select any day of the previous week to restore. However, even with a free dropbox account, you can still use 'dropbox version history' to grab previous versions of the archives for 30 days anyway.

I'm aware that you are running this on Yocto, so can't really help resolve the issue that you are having with fs, but if you are struggling, as Steve @shrickus has said, replace the 'Read filenames' node with a another node, such as node-red-contrib-readdir which performs the same function (and wasn't available when I orginally wrote this flow)

Example;

  1. Add the node-red-contrib-readdir node to your palette
  2. Import the attached example
[{"id":"9d4138d9.e0f328","type":"debug","z":"9616f62.4426f08","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":660,"y":270,"wires":[]},{"id":"f3305303.2cef1","type":"dropbox out","z":"9616f62.4426f08","dropbox":"","filename":"","localFilename":"","name":"","x":670,"y":310,"wires":[]},{"id":"17c6814c.2616bf","type":"readdir","z":"9616f62.4426f08","name":"","dir":"/home/pi/tempDir","as":"multi","recursive":false,"outproperty":"localFilename","x":500,"y":270,"wires":[["9d4138d9.e0f328","f3305303.2cef1"]]},{"id":"27e94630.4b432a","type":"comment","z":"9616f62.4426f08","name":"Nightly Backups","info":"","x":130,"y":100,"wires":[]},{"id":"6983a73d.4b2648","type":"inject","z":"9616f62.4426f08","name":"Start backup","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"00 03 * * *","once":false,"onceDelay":"","x":137,"y":150,"wires":[["e659a63c.7f82d8"]]},{"id":"bfa79f9b.32b4c","type":"function","z":"9616f62.4426f08","name":"Triggered queue","func":"// if queue doesn't exist, create it\ncontext.queue = context.queue || [];\ncontext.busy = context.busy || false;\n\n// if the msg is a trigger one release next message\nif (msg.hasOwnProperty(\"trigger\")) {\n    if (context.queue.length > 0) {\n        var m = context.queue.shift();\n        return {payload:m};\n    }\n    else {\n        context.busy = false;\n      //  node.send({payload:\"result\"});\n      var msg2 = { payload:\"OK\" };\n    }\n}\nelse {\n    if (context.busy) {\n        // if busy add to queue\n        context.queue.push(msg.payload);\n    }\n    else {\n        // otherwise we are empty so just pass through and set busy flag\n        context.busy = true;\n        return msg;\n    }\n}\n\nreturn [null,msg2];","outputs":"2","noerr":0,"x":260,"y":220,"wires":[["73977470.eecd0c"],["17c6814c.2616bf"]]},{"id":"f401fc44.575db","type":"function","z":"9616f62.4426f08","name":"set trigger","func":"// handle the return from the exec in here \n// if all is good then set msg.trigger property to exist\nmsg.trigger = 1;\nreturn msg;","outputs":1,"noerr":0,"x":597,"y":150,"wires":[["bfa79f9b.32b4c"]]},{"id":"73977470.eecd0c","type":"exec","z":"9616f62.4426f08","command":"","addpay":true,"append":"","useSpawn":"false","timer":"","oldrc":false,"name":"Execute commands","x":530,"y":220,"wires":[["f401fc44.575db"],[],["4c26b243.ba9e5c"]]},{"id":"e659a63c.7f82d8","type":"function","z":"9616f62.4426f08","name":"Generate commands","func":"//--Edit these to your own installation\n//Don't change these!\nvar path = '/home/pi/tempDir/';\n\n//Generate days to add to archive title\nvar d = new Date();\nvar day = new Array(7);\nday[0]=  \"Sun\";\nday[1] = \"Mon\";\nday[2] = \"Tue\";\nday[3] = \"Wed\";\nday[4] = \"Thu\";\nday[5] = \"Fri\";\nday[6] = \"Sat\";\n\n//Create directory structure\nvar m1={payload: \"rm -rf \"+[path]};\nvar m2={payload: \"mkdir \"+[path]};\n\n// ************************************************************************* //\n// *** The below commands will archive the entire node-red user directory,\n// *** emoncms data directories & mysql. To add further commands, use the\n// *** same format, and add the corresponding msg id to the 'return' statement.\n// ************************************************************************* //\n//---Log Filer---//\n  //Create ~/testDir archive\n  var m4={payload: \"tar -czvf \"+[path]+(day[d.getDay()])+\"_testDir\"+\".tar.gz /home/pi/testDir\"};\n\n// Output the commands for execution\nreturn [ [ m1, m2, m4, ] ];","outputs":"1","noerr":0,"x":341,"y":150,"wires":[["bfa79f9b.32b4c"]]},{"id":"4c26b243.ba9e5c","type":"function","z":"9616f62.4426f08","name":"Report any errors","func":"var code = (msg.payload.code);\nif ([code] != \"0\") {\nmsg.payload = (msg.payload.message);\nmsg.topic = \"Raspberry backup process failed\";\nreturn msg;\n}\nelse {\nreturn null;\n}","outputs":1,"noerr":0,"x":740,"y":220,"wires":[[]]},{"id":"39494f27.32d39","type":"comment","z":"9616f62.4426f08","name":"README (select & view in info panel!)","info":"**REQUIREMENTS**  \nRequires the library fs-extra installing & enabling\nglobally in settngs.js  \n(used in `Read Filenames` function node)\n\nTO INSTALL FS-EXTRA  \n```\ncd ./node-red  \nnpm install --save fs-extra\n```\nTO MAKE FS-EXTRA GLOBAL  \nAdd `fse:require('fs-extra')` to the\n`functionGlobalContext` section in NR settings.js file.\n\n**CONFIGURATION**  \nEdit the `Generate commands` function node with \nyour own;  \n- Emoncms data directory path\n- Emoncms MYSQL username (default = emoncms)\n- Emoncms MYSQL password  \n\nSetup the `dropbox` node, (details in the node info)  \nAlso edit the `Start backup` inject node with your preferred time to run.  \nIf you want to be alerted about archive problems or failures, you can use the `Report any errors` node output to dispatch the message via Pushover, email, twitter or whatever.","x":386,"y":99,"wires":[]}]

I appreciate your answers, and I have tried implementing your suggestions.
It seemed like fs-extra was not working correctly, because it was installed in the wrong directory. My bad.
@Paul-Reed, your last example works as intended, but there is only one thing I need to change:
Instead of making the .tar.gz file backup of something, I need it to just copy all the files in the following folder to Dropbox:
/home/root/nylog
I have tried adding the following line to "Generate commands":
var m5={payload: "cp /home/root/* /home/pi/testDir"};
but to no avail.
What I am going to/trying to do is make it check for files in the folder, upload the ones it finds, and then (in a separate string) check Dropbox for new files, and then delete local files in the folder, if they have the same names. That way, only succesfully uploaded files will be deleted locally (and thus removed from the "queue"). Along with this, I also store the files in another directory permanently, so I always have a backup.
I have attempted just using "readdir" separately, and even though it actually does the job with finding the files and uploading them to Dropbox, the content of the files is replaced with what seems to be the Unix timestamp, which I guess it is getting from the initiating pushbutton's timestamp. If only it could just ignore this and instead read the files (with their actual content) and upload them without altering them, everything would be fine. Needless to say, I am bit confused.

That's good news, at least you've got a working flow now to modify it's functionality to your preference.

I haven't explored uploading individual files, as I prefer a compressed archive, so can't really help with the points that you've raised.

Alright, so now I have actually made it work - sort of. There seems to be an issue with Dropbox not being too happy about having too many write operations. It is repeatedly reporting this error message:
" 7/1/2019 11.46.12node: upload til Dropbox
msg : string[108]
"{"error_summary": "too_many_write_operations/.", "error": {"reason": {".tag": "too_many_write_operations"}}}""
In reality, what this means is that I have a bunch of files in the local directory that are not uploaded because the input files are generated too often and the Dropbox node can't keep up with it and "get rid" of the files quickly enough. I was certain I had gotten rid of the problem with a message queuing node, but having 100+ files in the local storage folder at the moment and not being able to connect to Node-RED in my browser, I am quite sure that my hardware is part of the problem.