Mycroft AI
  • Documentation
  • About Mycroft AI
    • Why use Mycroft AI?
    • Glossary of terms
    • Contributing
    • FAQ
  • Using Mycroft AI
    • Get Mycroft
      • Mark II
        • Mark II Dev Kit
      • Mark 1
      • Picroft
      • Linux
      • Mac OS and Windows with VirtualBox
      • Docker
      • Android
    • Pairing Your Device
    • Basic Commands
    • Installing New Skills
    • Customizations
      • Configuration Manager
      • mycroft.conf
      • Languages
        • Français (French)
        • Deutsch (German)
      • Using a Custom Wake Word
      • Speech-To-Text
      • Text-To-Speech
    • Troubleshooting
      • General Troubleshooting
      • Audio Troubleshooting
      • Wake Word Troubleshooting
      • Log Files
      • Support Skill
      • Getting more support
  • Skill Development
    • Voice User Interface Design Guidelines
      • What can a Skill do?
      • Design Process
      • Voice Assistant Personas
      • Interactions
        • Intents
        • Statements and Prompts
        • Confirmations
      • Conversations
      • Error Handling
      • Example Interaction Script
      • Prototyping
      • Design to Development
    • Development Setup
      • Python Resources
      • Your First Skill
    • Skill Structure
      • Lifecycle Methods
      • Logging
      • Skill Settings
      • Dependencies
        • Manifest.yml
        • Requirements files
      • Filesystem access
      • Skill API
    • Integration Tests
      • Test Steps
      • Scenario Outlines
      • Test Runner
      • Reviewing the Report
      • Adding Custom Steps
      • Old Test System
    • User interaction
      • Intents
        • Padatious Intents
        • Adapt Intents
      • Statements
      • Prompts
      • Parsing Utterances
      • Confirmations
      • Conversational Context
      • Converse
    • Displaying information
      • GUI Framework
      • Show Simple Content
      • Mycroft-GUI on a PC
      • Mark 1 Display
    • Advanced Skill Types
      • Fallback Skill
      • Common Play Framework
      • Common Query Framework
      • Common IoT Framework
    • Mycroft Skills Manager
      • Troubleshooting
    • Marketplace Submission
      • Skills Acceptance Process
        • Information Review Template
        • Code Review Template
        • Functional Review Template
        • Combined Template
      • Skill README.md
    • FAQ
  • Mycroft Technologies
    • Technology Overview
    • Roadmap
    • Mycroft Core
      • MessageBus
      • Message Types
      • Services
        • Enclosure
        • Voice Service
        • Audio Service
        • Skills Service
      • Plugins
        • Audioservice Plugins
        • STT Plugins
        • TTS Plugins
        • Wake Word Plugins
      • Testing
      • Legacy Repo
    • Adapt
      • Adapt Examples
      • Adapt Tutorial
    • Lingua Franca
    • Mimic TTS
      • Mimic 3
      • Mimic 2
      • Mimic 1
      • Mimic Recording Studio
    • Mycroft GUI
      • Remote STT and TTS
    • Mycroft Skills Kit
    • Mycroft Skills Manager
    • Padatious
    • Precise
    • Platforms
Powered by GitBook
On this page
  • Introduction
  • Basing your Skill on the CommonPlaySkill class instead of MycroftSkill
  • CPS_match_query_phrase
  • CPS_start
  • Example implementation of CommonPlaySkill
  • Technical Documentation
  • Where to go for more assistance

Was this helpful?

  1. Skill Development
  2. Advanced Skill Types

Common Play Framework

To support a range of Skills that can "play" things, each Common Play Skill must return a confidence score to indicate their ability to successfully complete the users request.

Introduction

Over time, many Skills are likely to use similar keywords - called Intents - to triggers actions. One of the most frequently used keywords is play. This means that several Skills can all use the word play in their Intents - causing something called an intent collision - where Mycroft doesn't know which Skill to invoke because there are so many to choose from.

The Common Play Framework solves this problem by allowing Mycroft to infer a confidence score from an Intent which uses the play keyword. The confidence score is designed so that there is a much higher probability of the right Skill being invoked to handle an Intent which has the keyword play in it.

To take advantage of the Common Play Framework, your Skill needs to be written in a specific way - outlined below:

Basing your Skill on the CommonPlaySkill class instead of MycroftSkill

To interface with the playback control the Skill will be based on the CommonPlaySkill class instead of the normal MycroftSkill. Your Skill also needs to implement two methods, CPS_match_query_phrase and CPS_start.

The setup looks like this:

from mycroft.skills.common_play_skill import CommonPlaySkill, CPSMatchLevel


class TutorialSkill(CommonPlaySkill):
    def CPS_match_query_phrase(self, phrase):
        """ This method responds wether the skill can play the input phrase.

            The method is invoked by the PlayBackControlSkill.

            Returns: tuple (matched phrase(str),
                            match level(CPSMatchLevel),
                            optional data(dict))
                     or None if no match was found.
        """
        return None

    def CPS_start(self, phrase, data):
        """ Starts playback.

            Called by the playback control skill to start playback if the
            skill is selected (has the best match level)
        """
        pass


def create_skill():
    return TutorialSkill()

CPS_match_query_phrase

The argument phrase is sent from the PlaybackControlSkill, and is the entire phrase said by the user with the play keyword stripped out. So if the user says

"Play something by Professor Elemental"

the phrase argument will contain

"something by Professor Elemental"

Using this phrase the Skill Author should now determine if the Skill can play this phrase and return the matched phrase and the confidence level. The confidence level is reported using the CPSMatchLevel enum type.

Possible values are:

  • CPSMatchLevel.EXACT (The input matches exact)

  • CPSMatchLevel.MULTI_KEY (The input contains multiple matches such as Artist and Album title)

  • CPSMatchLevel.TITLE (The phrase contains a matching title)

  • CPSMatchLevel.ARTIST (The phrase contains a matching artist)

  • CPSMatchLevel.CATEGORY (The phrase contains a category supported by the skill, Rock, bitpop, Podcast etc.)

  • CPSMatchLevel.GENERIC (Generic match, maybe contains the skill title but no media match)

where CPSMatchLevel.EXACT is the greatest confidence and the CPSMatchLevel.GENERIC is lowest.

Example:

        return (matched_phrase, CPSMatchLevel.TITLE)

The method can also return data that will be needed when starting the playback. This is very useful if the skill can play a variety of things of various types. The data is added as a third element in the return tuple and has to be a simple python dict.

Example:

        data = {
            "track": "my_music.mp3"
        }
        return (matched_phrase, CPSMatchLevel.TITLE, data)

The data is then passed to the CPS_start() method as an argument.

CPS_start

CPS_start simply starts the playback using the data and/or the phrase to determine what to play.

For convenience the self.audioservice object can be used to start playback or queue up tracks.

Example implementation of CommonPlaySkill

Let's fill in the blanks in the the above base and create a Skill to play the best (according to yours truly, @forslund) Commodore 64 remixes!

We add a nice safe data structure to the Skill file:

track_dict = {
    'bomb jack': 'http://remix.kwed.org/files/RKOfiles/Chronblom%20-%20Bomb%20Jack%20subtune%206%20(violin%20version).mp3',
    'druid': 'http://remix.kwed.org/files/RKOfiles/Revel%20Craft%20-%20Druid.mp3',
    'crazy comets':  'http://remix.kwed.org/files/RKOfiles/Makke%20-%20Crazy%20Comets%20(Komet%20Non-Stop).mp3',
    'boulder dash': 'http://remix.kwed.org/files/RKOfiles/Mahoney%20-%20BoulderDash%20(Commodore%2069%20mix).mp3',
    'garfield': 'http://remix.kwed.org/files/RKOfiles/Reyn%20Ouwehand%20-%20Garfield.mp3'
}

To match from this list the match_one function in mycroft.util.parse can be used to fuzzy match one of the elements in the dict.

First we add the import at the top of the file:

from mycroft.util.parse import match_one

then we update the CPS_match_query_phrase method to use it to select the best match. This fuzzy matching system will match strings that are close to one of the keys in the above dict. This means phrases like "play crazy comet" will be matched with a fairly high confidence despite not being the exact string in the dictionary.

    def CPS_match_query_phrase(self, phrase):
        """ This method responds wether the skill can play the input phrase.

            The method is invoked by the PlayBackControlSkill.

            Returns: tuple (matched phrase(str),
                            match level(CPSMatchLevel),
                            optional data(dict))
                     or None if no match was found.
        """
        # Get match and confidence
        match, confidence = match_one(phrase, track_dict)
        # If the confidence is high enough return a match
        if confidence > 0.5:
            return (match, CPSMatchLevel.TITLE, {"track": match})
        # Otherwise return None
        else:
            return None

This will include the url of the selected file as "track" in the data received by the CPS_start method.

Which simply becomes

    def CPS_start(self, phrase, data):
        """ Starts playback.

            Called by the playback control skill to start playback if the
            skill is selected (has the best match level)
        """
        # Retrieve the track url from the data
        url = data['track']
        self.audioservice.play(url)  # Send url to audioservice to start playback

Technical Documentation

Where to go for more assistance

PreviousFallback SkillNextCommon Query Framework

Last updated 5 years ago

Was this helpful?

The complete source code can be found

More information on the Common Play Framework can be found in the .

Join us in the or join us in the .

here
Mycroft Technical Documentation
Skills Mycroft Chat room
Mycroft Forum