Trigger on USB Drive Insertion - Raspberry Pi

Hey friends! I'm working on a Node-RED Pi Zero project and am looking for a way to monitor when a USB drive is plugged in. The aim is to auto-copy a bunch of files when a drive is inserted then unmount the drive. Copying and unmounting are relatively easy, but I'm having a tough time finding a way to have the OS notify Node-RED that a drive has been inserted/mounted.

The only thing I can think of right now is to have Node-RED constantly pinging the mount point to see if something is there and continue on if if finds a drive. While not resource-intensive it seems a bit wasteful and inefficient. But maybe this is the best way to go?

I'm not great at this stuff and could use a pointer or two! Thanks!

Maybe some kind of Python script running in the background on the PI - GitHub - (I haven't tried that particular script).

You can then modify it using the PiGPIO library to set one of the pins to high or low when it detects a USB event.

Node Red has node-red-node-pi-gpio which can then monitor the state of the pins and you can trigger an action off that.

I think periodically checking sounds a reasonable way to tackle the issue if a drive is always mounted the same way each time

Or run that script using the node-red-node-daemon node - which will then provide an output of whatever the script reports which you can then use to trigger whatever is required.

1 Like

There is also a javascript possible way even though it's not perfect

  1. Install this package:
    https://www.npmjs.com/package/usb-detection
sudo npm install usb-detection

  1. Edit your NR settings.js and add the line with the usbDetect:
    functionGlobalContext: {
	//tellduslive:require('telldus-live'),
        //noble:require('noble'),
        SunCalc:require('suncalc'),
        usbDetect:require('usb-detection'),

  1. Restart NR

  2. Import the flow below, click ONCE only on "Start usb monitoring"

[{"id":"7b3a1756.5c8518","type":"function","z":"60f50465.20a53c","name":"","func":"var usbDetect = global.get('usbDetect');\n\nif(msg.payload){\n    usbDetect.startMonitoring();\n    node.warn('started usb monitoring');\n    \n    usbDetect.on('add', function(device) {\n        device.state = \"connected\";\n        node.send(device);\n    });\n    \n    usbDetect.on('remove', function(device) {\n        device.state = \"removed\";\n        node.send(device);\n    });\n}\n\nif(!msg.payload){\n    usbDetect.stopMonitoring();\n    node.warn('stopped usb monitoring');\n}\n\n","outputs":1,"noerr":0,"x":1020,"y":130,"wires":[["b7c8d674.1671c8"]]},{"id":"b7c8d674.1671c8","type":"debug","z":"60f50465.20a53c","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":1200,"y":130,"wires":[]},{"id":"a3913d80.f3765","type":"inject","z":"60f50465.20a53c","name":"Start usb monitoring","topic":"","payload":"true","payloadType":"bool","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":780,"y":130,"wires":[["7b3a1756.5c8518"]]},{"id":"523afc6c.afbbb4","type":"inject","z":"60f50465.20a53c","name":"Stop usb monitoring","topic":"","payload":"false","payloadType":"bool","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":780,"y":230,"wires":[["7b3a1756.5c8518"]]}]

  1. Remove & then connect a usb device and check the result in the debug window. I tested with a usb memory stick and a usb camera, I received a notification for both. In the function node I have added the property state so that you easily can identify if the device was "connected" or "removed"

PLEASE note that you can only start the monitoring once. If you change the code in the function node after the monitoring has started, you may have to reboot the Pi before those changes works. Read more here why: https://github.com/MadLittleMods/node-usb-detection/issues/53

3 Likes

Wrapping that up looks like a great "my first contrib node" project for someone !

1 Like

Not sure about the JS tooling. However, the "normal" way to do something on usb drive attachment is to configure udev to detect when the device comes active and then run a shell script.

Since a shell script could update a file, output to a UNIX pipe or even call an HTTP endpoint, there would seem to be lots of ways to efficiently do something useful in Node-RED.

https://www.thegeekdiary.com/how-to-run-a-script-when-usb-devices-is-attached-or-removed-using-udev/

1 Like

Found a simple Node-RED solution! Thanks for all the suggestions. Here's a pretty simple "in-house" solution for this case (or any Linux implementation):

Using the [watch] object you can easily monitor the /dev/disk/by-uuid/ directory which changes when a drive is plugged in or removed. [watch] can then trigger anything down the flow. You can watch any of the /dev/disk/ sub-directories but the bonus of /by-uuid is that the [watch] object kicks out msg.file as the uuid of the inserted drive, which can then be used to map the mount point, trigger the transfer, and then unmount the drive. Still need to make it so the flow it only executes on drive insertion but I think I can work that out.

I'm still tweaking the final result and will post the solution here when I get closer. Thanks again for all the suggestions! Cheers!

4 Likes

Hi @jeff8houses are you still using this flow? If so, would you share it?

You can use UDEV rules to run a script when a USB device is inserted.

linux - Using udev rules to run a script on USB insertion - Super User

Just get the script to notify Node-RED (e.g. using curl to trigger a Node-RED http endpoint).

I will indeed post the flow! It's on the pi (shame on me for not backing it up elsewhere) so I need to go dig it up. I'll post it here in a bit!

Thanks im looking forward to it :slight_smile: