I think this is the most simple way to do it. It’s not the way I would have done it perhaps, but it’s crude and simple There’s no problem after swapping tracks or devices either.
I’ve structured it in a way that should, hopefully, be easy to reuse.
function add_device_notifier(track, device_idx, banger_func)
local device = track:device(device_idx)
local notifier_func = function(event)
if event.type == "remove" then
local exists = false
for idx, obj in ipairs(track.devices) do
exists = exists or rawequal(obj, device)
if not exists then
local was_removed_func = function()
print("the device was removed")
local track_obj = renoise.song().selected_track
local device_index = 2
add_device_notifier(track_obj, device_index, was_removed_func)
EDIT: I forgot that you may want it to react to the track being removed as well, but maybe you’ll manage to add this on your own. Just use a similar approach for tracks and renoise.Song.tracks_observable.