I tried switching off the pushState listener in the onStop function as you suggested.
But the listener is still triggered multiple times.
If I account for this repeat triggers in code, my plugin works as expected.
Thanks.
NOTE: I am currently on Volumio 4 for Raspberry Pi and have the following plugins installed - Auto Volume (my plugin), System Information, Now Playing, Touch Display
I am developing a plugin to control the volume of each song being played.
For that I need to limit the range of values for a config to be below volumio’s “Max Volume Level” setting (Playback Options → Volume Options → Max Volume Level).
How do I query this value from within my plugin’s code and set my UIconfig range accordingly?
Thanks to everyone active in the volumio community.
Query the Max Volume Level setting from your plugin code:
var maxVolume = this.commandRouter.executeOnPlugin('audio_interface', 'alsa_controller', 'getConfigParam', 'volumemax');
The setting is stored as ‘volumemax’ in the alsa_controller plugin configuration file at:
/data/configuration/audio_interface/alsa_controller/config.json
To dynamically set your UIConfig element range in getUIConfig(), modify the element’s max attribute before resolving:
The issue is listener accumulation. Each time onStart runs, you add another socket.on listener without removing previous ones. After plugin restarts or multiple starts, you end up with duplicate listeners all firing on the same event.
Fix: Remove the listener in onStop.
AutoVol.prototype.onStart = function() {
const self = this;
const defer = libQ.defer();
self.astart = Date.now();
// Store reference to the bound function for later removal
self.pushStateHandler = function(state) {
self.statusChanged(state);
};
socket.emit("getState", "");
socket.on("pushState", self.pushStateHandler);
defer.resolve();
return defer.promise;
};
AutoVol.prototype.onStop = function() {
const self = this;
const defer = libQ.defer();
// Remove the listener
socket.off("pushState", self.pushStateHandler);
defer.resolve();
return defer.promise;
};
Key points:
Store the handler function reference in self.pushStateHandler
Use socket.off() in onStop to remove that specific listener
This prevents listener accumulation across plugin restarts
Alternative: Use socket.once() if you only need the state once, but for continuous monitoring you need the on/off pattern shown above.
One request: please consolidate your plugin development questions into a single thread - something like “Learning Plugin Development” or similar. It keeps related discussion together and helps others learning the same things find the answers more easily.