Basic plugin doesnt start up using Socket communication

Hi,

I try to build a very basic plugin. It should “just” show the payload of a mqtt message to the user. I think the easiest would be to use a Toast Message.

BTW: When creating a new plugin, it uses the “example plugin” out of the volumio-plugin-source repo. I just wonder why on some functions, like onVolumioStart, a selicolon is missing. Also the Volumio documentation point to the old Volumio2 plugin " ATTENTION: The first step is cloning the volumio-plugins repository, just head there and click “fork” on top right corner"

The coder behind the volumio-mqtt script extended his work so it should emit the message:
volumio-mqtt/ at feature/callMethod · richiewebgate/volumio-mqtt · GitHub → file server.js line 72++

When i start the script and send a message to “volumio-server/set/callMethod 22” it seems to me like that part is ok

DEBUG=socket.io* node server.js

socket.io-client:manager writing packet {“type”:2,“data”:[“callMethod”,22],“options”:{“compress”:true},“nsp”:“/”} +17s
socket.io-parser encoding packet {“type”:2,“data”:[“callMethod”,22],“options”:{“compress”:true},“nsp”:“/”} +17s
socket.io-parser encoded {“type”:2,“data”:[“callMethod”,22],“options”:{“compress”:true},“nsp”:“/”} as 2[“callMethod”,22] +0ms
[7/1/2023, 10:23:42 AM] 22

Now I created a custom plugin where i tried to listen to that message. But, when enabling the line socket.on(‘callMethod’, function (data) { self.submitMyMessage(data); }); doesnt load. When disabling that line the plugin start up an print the message “plugin started”

I expected that when i send the mqtt message, I would receive the message “function called”

‘use strict’;

//const NodeMonkey = require(“node-monkey”)
//NodeMonkey()

var libQ = require(‘kew’);
var fs=require(‘fs-extra’);
var config = new (require(‘v-conf’))();
var exec = require(‘child_process’).exec;
var execSync = require(‘child_process’).execSync;

module.exports = notifyuser;
function notifyuser(context) {
var self = this;

this.context = context;
this.commandRouter = this.context.coreCommand;
this.logger = this.context.logger;
this.configManager = this.context.configManager;

};

notifyuser.prototype.onVolumioStart = function()
{
var self = this;
var configFile=this.commandRouter.pluginManager.getConfigurationFile(this.context,‘config.json’);
this.config = new (require(‘v-conf’))();
this.config.loadFile(configFile);

return libQ.resolve();

};

notifyuser.prototype.onStart = function() {
var self = this;
var defer=libQ.defer();

self.commandRouter.pushToastMessage('success', "Yes", "plugin started");

// socket.on(‘callMethod’, function (data) { self.submitMyMessage(data); });

defer.resolve();

return defer.promise;

};

notifyuser.prototype.submitMyMessage = function (data) {
var self = this;

self.commandRouter.pushToastMessage(‘success’, “Yes”, “function called”);
return libQ.resolve();

};

notifyuser.prototype.onStop = function() {
var self = this;
var defer=libQ.defer();

// Once the Plugin has successfull stopped resolve the promise
defer.resolve();

return libQ.resolve();

};

notifyuser.prototype.onRestart = function() {
var self = this;
// Optional, use if you need it
};

// Configuration Methods -----------------------------------------------------------------------------

notifyuser.prototype.getUIConfig = function() {
var defer = libQ.defer();
var self = this;

var lang_code = this.commandRouter.sharedVars.get('language_code');


self.commandRouter.i18nJson(__dirname+'/i18n/strings_'+lang_code+'.json',
    __dirname+'/i18n/strings_en.json',
    __dirname + '/UIConfig.json')
    .then(function(uiconf)
    {


        defer.resolve(uiconf);
    })
    .fail(function()
    {
        defer.reject(new Error());
    });

return defer.promise;

};

notifyuser.prototype.getConfigurationFiles = function() {
return [‘config.json’];
}

notifyuser.prototype.setUIConfig = function(data) {
var self = this;
//Perform your installation tasks here
};

notifyuser.prototype.getConf = function(varName) {
var self = this;
//Perform your installation tasks here
};

notifyuser.prototype.setConf = function(varName, varValue) {
var self = this;
//Perform your installation tasks here
};

Thanks for letting us know about the reference to volumio2 in the documentation. However, you are looking at the wrong one.

The new documentation is at:

Where did you find the link for the documentation?

As per your plugin, solution is easy:

  • Before listening to events, you need to start the socket connection.

To do so, add on the onStart:

var socket = io.connect('http://localhost:3000');

Hi,

and thanks for your reply. Just searched for “write volumio plugin” using google whichs links me to

Ok, without the proper connection it cant work.

'use strict';

var libQ = require(‘kew’);
var fs=require(‘fs-extra’);
var config = new (require(‘v-conf’))();
var exec = require(‘child_process’).exec;
var execSync = require(‘child_process’).execSync;
var io = require(‘socket.io-client’);
var socket = io.connect(‘http://localhost:3000’);

Had to install sudo npm install socket.io-client

The mqtt script itself connects also to

let socket = io.connect(config.volumio_host);

with
“volumio_host”: ‘http://localhost:3000
it seems to handle the mqtt message as I get the console output with this part:

socket.emit(‘callMethod’, JSON.parse(msg));
if (config.debugme) printLog(msg);

Here is the current code with a lot of debug messages. But none of them appear

notifyuser.prototype.onStart = function() {
var self = this;
var defer=libQ.defer();
var socket = io.connect(‘http://localhost:3000’);
self.commandRouter.pushToastMessage(‘success’, “Yes”, “plugin started”);
socket.on(‘callMethod’, function (data)
{
// doesnt seem to jump into this
self.logger.info(“notifyuser callMethod”);
self.submitMyMessage(data);
});

    self.logger.info("notifyuser Plugin started");
    defer.resolve();
return defer.promise;

};

notifyuser.prototype.submitMyMessage = function (data) {
var self = this;
self.logger.info(“notifyuser function called”);
self.commandRouter.pushToastMessage(‘success’, “Yes”, “function called”);
return libQ.resolve();

};

Finally:

my script which emits data

socket.emit('callMethod',  {endpoint:'user_interface/notifyuser',method:'submitMyMessage',data:msg});

index.js

var io = require('socket.io-client');
var socket = io.connect('http://localhost:3000');
....
notifyuser.prototype.submitMyMessage = function (data) {
        var self = this;
        self.logger.info("notifyuser function called");
        self.commandRouter.pushToastMessage('success', "Yes", data);
return libQ.resolve();
};
...
notifyuser.prototype.onStart = function() {
    var self = this;
        var defer=libQ.defer();
        self.commandRouter.pushToastMessage('success', "Yes", "plugin started");
        defer.resolve();
    return defer.promise;
};

Now i can send a mqtt message and the text will be displayed for a few seconds.

Is there any way to place some icon or whatever on top of everything? So, instead of showing a short message, the message is persitent (e.g. top right corner)?