USB File Management with groov View and Node-RED

To allow file management outside of the groov Manage interface I’ve put together this groov View page and Node-RED flow. I am using this to move files between local, on-board storage and an attached USB drive, as well as safely unmounting, all from just one page on my groov EPIC. There is NO use of groov Manage required after the initial setup; the only requirement is access to a groov View page!

Note: The “unmount” functionality is now officially supported through the Manage API, and functions essentially the same as it did in prior versions of EPIC firmware (pre-3.0). However, if you are using this project with multiple USB drives inserted, please post in the thread below as you will need to make some modifications to the Node-RED flow and groov View page.

With that out of the way, if you want to try this out yourself, go ahead download the zipped groov View page and Node-RED flow attached to this post and follow these steps to import and configure everything:

  1. Enable USB automount if you haven’t already.
    In groov Manage select System, Settings, and then USB. Enable the USB and Automount options.

  2. Next you will need to add the following tags to either an existing Data Store or a new one (I call my Data Store for this project simply “nodered”).
    There are four booleans, two boolean tables copyLOCAL and copyUSB with length 5, and two string tables filesLOCAL and filesUSB also with length 5:
    With these buttons and tables you can display any number of files by “scrolling” through the file lists – you’re not limited to just five!

  3. Import the groov View page through groov Build to get the required page and gadgets (consider backing up your current project first).
    Once the page is imported, assign each tag to their respective gadget. You will only need to do this once, but be sure to get each one right:

  4. Import the Node-RED flow – it should look like this:

  5. Get an API key for the unmount command: Go to groov Manage and copy the API key for a user with groov Manage permissions. (If you have not set up your groov View in Node-RED yet, I suggest choosing a user that also has groov View permissions.)

  6. Double click on the “set headers” function node at the top of the imported flow. Change the value of “host” to your local devices hostname, and paste the API key exactly as copied from your groov Manage user account page for the “apiKey” value. Click Done to save the changes.

  7. Next, double click any groov Node to configure the connection to your new project. Select the pencil icon next to the Data Store “nodered” (or whatever you called yours if you made a different one, just make sure the spelling exactly matches what you have in groov Build).

  8. If you already have your localhost groov Project configured in Node-RED, you can use that.
    If you don’t, click the pencil icon next to Groov Project (add new groov-project), leave the groov Address as localhost and paste the API key you copied earlier as long as it has groov View permissions.

  9. Click “Update” and then “Done” to save this configuration. All the groov nodes are now using this API key, so you don’t need to make any other changes.

  10. Deploy the flow and go back to groov View, it’s ready to go!

How to use the page:

  • First you will need to insert your USB drive and click Refresh to see the file lists.
  • Use the arrows to move through the file lists, by default it will jump 5 items at a time like going through pages. If you prefer line-by-line “scrolling”, go into Node-RED and inject 1 into flow.scroll_offset. You do not need to redeploy for the change to take effect.
  • To move a file from local storage (/home/dev/unsecured) click the “>” button gadget to the left of the file name that you want to move. The button will light up and then go dark after the move command is complete, but you will need to click refresh to see a file move to the other list.
  • Similarly, to move a file from USB storage (/run/media/sdb1), just click the “<” button to the right of the file name listed under USB files, and refresh to confirm that it has moved.
  • Once you’re happy with where all the files are, click unmount in the top right and wait a moment after the unmount light turns back to green, just to make sure it has time to finish.
  • BEFORE you pull out the USB drive, try to refresh the list first. If all the file names disappear, you’re good to go ahead and remove the drive. If the files are still listed, the drive is probably still busy, so double check any apps that might be using it, and try again.

Final note: If you unmount and then decide that you want to see the files on your drive again, you MUST physically disconnect your USB media and plug it in again. The unmount button has a confirmation lock on it to avoid doing this accidentally, but do keep this limitation in mind.

As always, feel free to dive into the groov View page and function blocks to modify them for your needs, and please share any successes (or failures) in the thread below. Happy coding!



A like for the crazy amount of work this must have been.

1 Like

Wow, Awesome. Thanks Ben & son, I will try this out. Just a warning, I am new to Node-Red, so I may have some questions along the way.
Thanks Again

1 Like

Okay, first question. Node-Red. I’m running v1.0.3 and it doesn’t seem to the the Opto groov nodes (groov-read-ds & groov-write-ds). Do I need to re-import them, I thought I had done this before I downloaded EPIC v2.0.1-b.84. I can do this if needed.

Thanks Dave

The nodes are not carried over between firmware updates, so yes, if you don’t have those nodes any more, install them using the usual Node-RED manage palette menu option.

Yep How long does it take for Node-Red to install the Groov nodes? It went through the install process, now the Node-Red palette and screen is faded. If I click to close Node-Red, it says ‘Leave Site Changes you made may not be saved’? Do I need to wait till the screen returns to being functional?

It takes around 1-2 minutes tops. (Unless you are on a really slow network).

Just accept the warning, losing your changes is not a big deal, you can just import the flow again…
You need to be sure those groov view nodes are installed before you go any further.

1 Like

Yep, I have the nodes installed. I import the flow, but if I close Node Red and come back in, the inserted flow is gone. There has to be a way to ‘save’ it. In the real world, if your application uses various flows, how do the flows continue to run? Does Node-Red stay on/active all the time? My Node-Red in Groov Manage always shows it as ‘running’. I’ll peruse the Node Red forum and maybe what Terry’s video’s, maybe I can glean some info from there. The User Manual doesn’t say much about this.


@DWatts before you close the Node-RED tab make sure you hit “deploy” in the top right-hand corner: the blue dots marking the newly imported nodes will disappear to confirm that those nodes are live and actually running.

After that, the flow should persist and keep running in the background.

Okay, got it, done. Question: Restoring you provided project (*.tar.gz) ‘Restore Project’ in View, what is the username/password. Mine do not work, nor does leaving them blank. I was thinking this may clear up the Node Red node ‘Configuration Errors’ on nodes: ‘unmount’, ‘refresh’, ‘scroll up’, ‘down’, ‘mv local -> usb’, ‘mv usb -> local’


Thanks for the reminder – just added that detail to the main post!
Username is “opto” and password is just “opto22

Thanks, It still shows ‘Configuration Errors’ (see attached photo)


@DWatts Can you please double check the groov project configuration to make sure the ‘nodered’ Data Store is configured with the ‘localhost’ groov Project? Sometimes I accidentally make multiple configurations and only one of them works.


There should only be one localhost project – if there are duplicates, just remove them and start fresh:


Then confirm your API key (it will be unique to your user, it should not be the same as mine)


Let me know if all of that looks right on your end and still doesn’t work after redeploying the flow, there are a few other things we can double check.

Okay, It seems to work now. One thing I noticed after I power cycled the Epic setup, it created a new API key, I guess I’ll have to remember that in the future. And the ‘Unmount’ feature works as well. I will modify the ‘Unsecured’ area lookup, I made a \Data folder where we will store all the data files. Kinda keeps the ‘Unsecured’ area a bit cleaner and that’s the structure we currently use. I have some ideas for possible future enhancements, but let me play with this awhile.
Excellent work,
Thanks, Dave (if I have other ideas, should I post them as before, or email them directly to you)

1 Like

Glad to hear you are up and running!
And a great idea with the data folder for organization; to access any subfolders you should only have to add /Data to the path in the “list LOCAL files” switch node and the return strings in both “create move command” function blocks.

Regarding your API key, it should be exactly the same between power cycles. It will change if you delete the key or the user, or if you do a factory reset, but it should be persistent otherwise. If you are getting an entirely new key every power cycle I would strongly recommend reaching out to Opto support to figure out what’s going on there.

Finally, if you have any ideas or modifications please post them here! That way others can make use of them as well :slight_smile:

I’ll try checking the API key again, I will power down everything again and see what happens.

Yes, I got it to read the \Data folder, although it was empty. I’m in the process of working on copying some files from a USB into the \Data folder to get a ‘real feel’ setup. I found the path of the USB (/dev/sdb1), they created a mount point in the \media folder so I could mount the USB and view its contents, thus can copy the files. Always something to learn

I ‘sorta’ got it back working. I found out that the API keys I thought was being recreated was that I have (4 Accounts) API keys; Opto (Sys-Wide Admin), NodeRed (Sys-Wide Admin), Falex…Admin (Sys-Wide Admin), Falex…Groov (kisok). So I picked Falex…Admin. I copied some files into the \Unsecured\Data folder to practice on. Now when I select to copy a file from the USB or Local, in Node-Red I get an ‘error:1’ under the ‘exec’ node(s). (see attached photo) I cannot find an explanation of the error. I’m sure its something simple. Selecting ‘Restart Flows’ clears the error, but still doesn’t copy the file.
Thanks Dave

To get more details from the error just wire a new debug node into the second (middle) output of the exec node. That should display any specific error that comes back in the debug pane:

Could you also paste your modified code from the “create move command” function node? The path there must be exact otherwise it will not work – I suspect the sub-folder is causing the error.

Terry, Attached are a photo of the ‘error:1’ message, also the code from the ‘create move command’ from the ‘local to usb’ string. I see where I need to add the \Data into the code, but after I did this and accept changes with the ‘Done’ button. I can’t seem to clear the ‘blue’ dot in the upper right corner of the node I modified. I’ve tried all the 'deploys, even ‘Restart Flows’, they still hang around. Sorry for the 20 questions, just trying to learn a bit of Node-Red.

Thanks, Dave

Local to USB
offset = flow.get(‘scroll_offset’)||5;
// scroll 5 items for every arrow click (5 = page-style scrolling, 1 = item-style scrolling)
// NOTE: IF YOU CHANGE OFFSET - also change it in the “display LOCAL” and “display USB” function nodes
myFiles = flow.get(‘myLocalFiles’)||[]; // get the list of LOCAL filenames so we know what to copy
if(myFiles.length < 1) return null; // the file list must exist and be non-empty
// loop through all the buttons:
for(i = 0; i < msg.payload.length; i++) {
if(msg.payload[i]) { // if this button is on:
scroll = flow.get(‘scroll’); // get the current scroll level
thisFile = (myFiles[i + scroll*offset]) ? myFiles[i + scroll*offset] : “”; // if this file exists
// mv /home/dev/unsecured/<usb_file> /run/media/sdb1 move from unsecured LOCAL storage --> USB
if(thisFile.length > 0) return { ‘myIndex’ : i, ‘payload’ : “mv /home/dev/unsecured/” + thisFile + " /run/media/sdb1" };
return null; // no file found

Terry, I found that I needed to ADD the \Data to the ‘create move command’ nodes. I also saw in one of your videos that simply clicking the ‘Deploy’ and not using the dropdown selections “saved” removed the blue dots. It know works.
I’ll be in touch with some possible mod’s after I ‘play’ with this setup for awhile

Thanks, Dave

1 Like