Skip to content
This repository has been archived by the owner on Feb 8, 2019. It is now read-only.

How to Add new Commands and Actions #64

Open
Adsouza98 opened this issue May 3, 2018 · 11 comments
Open

How to Add new Commands and Actions #64

Adsouza98 opened this issue May 3, 2018 · 11 comments
Labels
enhancement feature request Request a new feature that is not already there

Comments

@Adsouza98
Copy link

Hey, I was wondering where the getCommands function and Action function are suppose to be declared.

Are they suppose to be declared inside the MMM-Assistant module for the config.js or in a separate file?

Also I was hoping someone can show me a simple example of how to create the function call to another module. (Example: change the text of hello world).

Just installed Magic Mirror last week and this is my first Github question, so sorry if formatting is horrendous.

{
	module: "helloworld",
	position: "bottom_bar",
	config: {
            text: "Hello world!"
	}
},
{
        module: 'MMM-Assistant',
        position: 'bottom_left',
	config: {			
	    TestFunc: function() {
                //Change Text of Hello World!
            },
	    getCommands: function(commander) {
  	        commander.add({
    		     command: 'Test',
    		     callback: 'TestFunc'
  	        })
	    },
            //Rest of standard MMM-Assistant config
         }
}
@drftg
Copy link

drftg commented May 3, 2018

You might want to take a look at my fork https://github.com/drftg/MMM-Assistant as I have already extended this module a bit to be able to send Notifications to other modules in the form

{
  notification: "SHOW_ALERT", // any notification can be sent to other modules
  parameter:  {type: "notification", title: "Important message!", message: "we are awake"}
}

but this only works via a snowboy hot word

@E3V3A E3V3A added enhancement feature request Request a new feature that is not already there labels May 3, 2018
@Adsouza98
Copy link
Author

I have a few questions:

  1. Do all new commands only need to be defined EXCLUSIVELY in the config file.

    • All other files can be left as default and no external libraries are required.
  2. How do you reference other modules.

    • In your config file you use the notification: "Command"
      • I assume this is to label the code block as a command.
    • The "parameter:"
      • I assume is then used as the "hot keywords ref" but there is no ref to how the command knows how to turn the screen on/off. What I mean by that is that there is no ref to the SCREEN func. So how does the code block know to ref that func
  3. What is the purpose of the module map if it's never called or used. Or is it used and I'm just not following it correctly.

  4. Can you explain this syntax of in terms of other modules

    • notification: "SHOW_ALERT", // any notification can be sent to other modules
      parameter: {type: "notification", title: "Important message!", message: "we are awake"}

    • What I don't understand but assume
      notification: "SHOW_ALERT" -> Don't understand
      type -> command
      title -> name of module
      message-> command of what to change in the module

This is your config file....

snowboy: {
// major change: every model now starts a list of commands so no more "hotword" parameter
models: [
    {
        file: "resources/hello.pmdl", // This file defines your MM wake word. (See doc note$
        sensitivity: 0.5,
        commands: [
            {
                notification: "COMMAND",
                parameter: "show overview"
            },
            {
                notification: "COMMAND",
                parameter: "turn the screen on"
             },
         ]
     },
     {
          file: "resources/u-models/smart_mirror.umdl", // This file defines your MM wake word. (See doc notes.)
          sensitivity: 0.5,
          commands: [
              {
                  notification: "COMMAND",
                  parameter: "turn the screen on"
               },
               {notification: "MIRROR"}  // old hotword
           ] 
       },
       {
           file: "resources/u-models/snowboy.umdl",
           sensitivity: 0.5,
           confirm: "resources/u-hmm-2.wav",
           commands: [  // turn the screen on before calling Google Assistant
               {
                   notification: "COMMAND", 
                   parameter: "turn the screen on" 
               },
               {notification: "ASSISTANT"},
	    ]
        },
        {
            file: "resources/u-models/alexa.umdl",
            sensitivity: 0.5,
            commands: [
                {
                    notification: "PLAY", 
                    parameter: "resources/snowboy.wav" 
                },
                {
                    notification: "COMMAND",
                    parameter: "hide all modules" // any spoken command can be sent as text (see translation/??.json for commands)
                 },
                 {
                     notification: "COMMAND", 
                     parameter: "show module time" // even module name mapping works (see modulemap below)
                 },
                 {
                      notification: "COMMAND", 
                      parameter: "turn the screen on" 
                  },
                  {
                      notification: "SHOW_ALERT", // any notification can be sent to other modules
                      parameter:  {type: "notification", title: "Important message!", message: "we are awake"}
                  }
              ],
          }
      ]
},
screen: {
    on: "vcgencmd display_power 1",
    off: "vcgencmd display_power 0",
    timeoff: 120 // seconds before screen is turned off
},
modulemap: [ // this table matches spoken module names to their real name
     ["time", "clock"],
     ["assistant", "MMM-Assistant"],
     ["overview", ["clock", "currentweather"]]
],

@E3V3A
Copy link
Collaborator

E3V3A commented May 3, 2018

@Adsouza98

This particular module does not have native support for added hot words in the way (we) would like. We are currently investigating how to make this more easy. For such an implementation I suggest to rather use MMM-voice which has this more clearly implemented.

The problem is that we would like to be able to use Alexa, GA and MM control separately, but still in an easy way. @drftg has made some improvements and additions, but ultimately we will make a future release that better implement this.

@Adsouza98
Copy link
Author

Adsouza98 commented May 3, 2018

@E3V3A

Okay, so if I'm understanding this correctly this module does not have the ability yet to have hot words like "Smart mirror next page" which intern will alter the MMM-Carousel module to go to the next page? It just has the ability to call GA, Alexa, and MM standard voice commands?

@drftg
Copy link

drftg commented May 3, 2018

@Adsouza98 Just a quick response.

You can use a hot word for MMM-Carousel like this

        {
            file: "resources/smart_mirror_next_page.pmdl", // this is your specific snowboy hot word
            commands: [
                  {
                      notification: "KEYPRESS", // this notification will be sent to all other modules
                      parameter:  {KeyName: "KEY_RIGHT"} // this parameter is sent as payload
                  }
              ],
          }

@Adsouza98
Copy link
Author

Adsouza98 commented May 4, 2018

When I use just that code you provided it reads my hot word but doesn't perform the action of simulating the right arrow key being pressed. Then gets stuck with a red recording icon.

I've tried both KEYPRESSED and KEY_PRESSED

my config:

snowboy: {
    models: [
    {
         file: "resources/u-models/smart_mirror.umdl",
         sensitivity: 0.5,
         hotwords : "MIRROR"    // Default model: "MIRROR". (This is not the wake word!)
    },
    {
         file: "resources/u-models/snowboy.umdl",
         sensitivity: 0.5,
	 hotwords : "ASSISTANT"    // Default model: "ASSISTANT". (This is not the wake word!)
    },
    {
         file: "resources/next_page.pmdl", // this is your specific snowboy hot word
	 commands: [
	     {
                 notification: "KEYPRESSED", // this notification will be sent to all other modules
		 parameter:  {KeyName: "KEY_RIGHT"} // this parameter is sent as payload
	     }
         ],
     },
}

@E3V3A
Copy link
Collaborator

E3V3A commented May 4, 2018

Come on guys, you're making me cry! 😭
Don't use a new hotword for every spoken command you need. That is what the MM control is used for!
One wake word for MM, then tell it what you want to do.

@drftg
Copy link

drftg commented May 4, 2018

@Adsouza98 Sorry for the confusion. That config only works on my fork, not the original one.

@E3V3A Sorry for making you cry. But sometimes that is exactly what I want; one hotword for one specific action. I agree that a "next page" hotword is not the best option but I myself am very happy with using a single hot word just to wake up the screen.

@drftg
Copy link

drftg commented May 4, 2018

@Adsouza98 Some explanation for the longer question you asked above.

  1. Do all new commands only need to be defined EXCLUSIVELY in the config file.

Due to how MMM-Assistent was originally designed the commands defined by MMM-Assistant can only be reached by spoken word. The phrases are defined in translations/en.json etcetera.

For example the line "CMD_HIDE_MODULE" : "hide module :module", defines that a spoken command like "hide module clock" gets translated via "CMD_HIDE_MODULE" to an internal function cmd_asstnt_hide_module in MMM-Assistant.js that hides the module given as parameter in this case "clock". Unfortunately "CMD_HIDE_MODULE" is not exposed so it can not be activated by a notification from other modules.
If you want to extend the functionality of MMM-Assistant you have to define a function in MMM-Assistant.js and define the utterance in translations/??.json. But of course you can also choose to use a different sentence for existing commands by changing them in the json files. I extended the functionality by adding some commands to handle the screen and handling pages.

To make commands available with using just a hot word I extended the config so the commands are sent as notifications. Some are handled by MMM-Assistant itself like

ASSISTANT activates Google Assistant
MIRROR activates command mode (it start listening for commands)
COMMAND sends a string as if it was spoken in command mode but without actually activating it
PLAY plays the file specified as a confirmation sound of the hot word

and all others are sent to the rest of MagicMirror. So <ANYTHING ELSE> is sent as a notification to all modules of MM

  1. How do you reference other modules.

This is the case described as <ANYTHING ELSE>. See 4.

  1. What is the purpose of the module map if it's never called or used. Or is it used and I'm just not following it correctly.

The modulemap was introduced because I found that the STT (Speech to text) engine did not always understand me correctly when pronouncing module names but also because module names are sometimes unpronounceable. Besides mapping the words that are "understood" in command mode to actual modules I also extended the functionality by mapping that to a set of modules. This makes it possible to actually define named pages. That, for me, makes modules like MMM-pages and MMM-Carousel obsolete. Now I can just ask my mirror to "show weather" and it will hide all modules except the ones I specified in modulemap after "weather". Also, although @E3V3A does not like that, you can use a specific hot word and send a {notification: "COMMAND", parameter: "show weather"}

  1. Can you explain this syntax of in terms of other modules

If you define the module "alert" in your config, it will handle the notification "SHOW_ALERT". I gave the example below to show how that works.

{notification: "SHOW_ALERT", parameter: {type: "notification", title: "Important message!", message: "we are awake"}}

where

Notification: "SHOW_ALERT" // This is sent as notification to MM 
type: // is the type of notification to show and is specific for the module `alert`
title: // you can define a title for this notification
message: // and this is the actual notification to show

@Adsouza98
Copy link
Author

@drftg Honestly all I want is to be able to say "smart mirror next page" or "next page" which then sends a notification to the MMM-Carousel module (or all modules) simulating a right key press and vice-versa with previous page 😭.

The MMM-Voice/MMM-Lucy module does offer page views this but it's supper laggy on my PI 3. The MMM-Assistant voice recognition works simultaneously with my voice which is why I want to use this module.

How would I accomplish this with the standard eouia Assistant module?

Sorry for so many questions, and taking up your time.

@E3V3A
Copy link
Collaborator

E3V3A commented May 5, 2018

@Adsouza98

all I want is to be able to say "smart mirror next page" or "next page"

Then just follow @drftg fork.

The reason this module has not yet implemented it that way, is because we want to also be able to control both the MM and/or the module using other methods, such as ultrasound , PIR, GPIO buttons etc. The programming would quickly get out of control and very disorderly, and would agian make also this module laggy! So we solve one problem at the time and compartmentalize the development. You user scenario is definitely important, and is why I labelled this issue as it is.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement feature request Request a new feature that is not already there
Projects
None yet
Development

No branches or pull requests

3 participants