MagicMirror² v2.5.0 is available! For more information about this release, check out this topic.

Building my first module, using MMM-API



  • Hi,

    I’m trying to build my first module for MagicMirror, the plan is to build a PiggyBank.
    Basically this would consist on a PiggyBank image that would be visible according to the percentage of money you have related to the target e.g. if we have 30% left to the target the bottom 70% of the image will be visible and 30% of the image will be hidden.

    The target and the amount of money saved will be stored in a JSON file. According to what i’ve seen the code that handles the store/retrieve of data should be placed in node_helper.js.

    .
    ├── CHANGELOG.md
    ├── Gruntfile.js
    ├── LICENSE.txt
    ├── MMM-PiggyBank.css
    ├── MMM-PiggyBank.js
    ├── node_helper.js
    ├── package.json
    ├── README.md
    └── translations
        ├── en.json
        └── es.json
    

    The module MMM-Api would be used to change the target or the amount of money saved.

    Now my question, in the MMM-Api documention the target is an ACTION in the module. My question here is where do i define the ACTION? Could you kindly show me a mockup/skeloton of and ACTION?

    MAGIG_MIRROR_IP:PORT/api/v1/modules/MODULE_NAME/ACTION?payload1key=payload1value&payload2key=payload2value
    

    An ACTION is just the name of a function inside MODULE_NAME.js e.g. processData?

    processData: function(data) {
    

    Please bear in mind that I’m new to MagicMirror and to nodejs as well.
    I took the chance to look at Head first developing MM module for extreme beginners and MagicMirror2 Module Development Documentation but failed to understand how the ACTION should be defined.

    Thanks in advance,
    Edgar Santos


  • Module Developer

    @ptcrusher
    As I read the document of MMM-API, ACTION would be the name of notification of target module. (It’s obvious whether notification could be case-insensitive.)
    By example,
    MMM-Glance module works with notification GLANCE_ON, Thus MMM-API doc says

    curl -X POST 'http://localhost:3001/api/v1/modules/mmm-glance/glance_on?name=news&time=1000'
    

    will activate MMM-Glance. This curl execution will be equivalent with the notification GLANCE_ON with payload value {name:"news", time:1000}.



  • @sean Got it! Thanks



  • @Sean Did some progress on the module. I removed the dependency on MMM-API since we can define extra routes in node_helper.js.

    Now i have a doubt. Should i keep the values that i wish to retrieve in a variable and use the socketNotificationSend/socketNotificationReceived logic or… should i call the extra-routes from my module (MMM-PiggyBank.js) pretending that i’m accessing an external API?

    Could you kindly tell me which is the recommended approach?

    extraRoutes: function() {
                    var self = this;
                    this.expressApp.get("/MMM-PiggyBank/WITHDRAW", function(req, res) {
                            self.withdrawCash().then((rsp) => res.status(rsp.status).send(rsp.response));
                    });
                    this.expressApp.post("/MMM-PiggyBank/CASH_IN", function(req, res) {
                            self.updateCash(req.query.target,req.query.current).then((rsp) => res.status(rsp.status).send(rsp.response));
                    });
            },
    
           updateCash: async function(target,current) {
                    var self = this;
                    try {
                            await self.checkExistance(self.fullyQualFileName());
                            var oldcontent = await readFile(self.fullyQualFileName());
                            var contentcandidate = await self.valChanges(target, current, JSON.parse(oldcontent));
                            var newcontent = await writeFile(self.fullyQualFileName(), JSON.stringify(contentcandidate));
                            return self.buildSuccessRsp("Successfully saved!");
                    }
                    catch(err) {
                            return self.buildErrRsp(err);
                    }
            },
    
            withdrawCash: async function() {
                    var self = this;
                    try {
                            await self.checkExistance(self.fullyQualFileName());
                            var oldcontent = await readFile(self.fullyQualFileName());
                            return self.buildSuccessRsp(JSON.parse(oldcontent));
                    }
                    catch(err) {
                            return self.buildErrRsp(err);
                    }
            },
    

  • Module Developer

    @ptcrusher
    I think, there might be no silver bullet or Deus Ex Machina about that kinds of question. I believe anything be good if you can handle it.