The registered intents are now stored in a list. When a detach_skill message is received the list is checked for matching intents and the intents are removed
The CommonPlaySkill base class provides an easy base class for any
skill wishing to use the "Common Play" framework. This allows multiple
skills to jointly handle requests such as "play Janet Joplin",
"play my Sled Zepplin playlist", "play NPS news" or "play Strump's
speech to the UN". Previously the "wildcard" intents needed to handle
this were basically impossible -- only one skill got a shot at handling
the request. Now several skills to search their service to see if they
have anything that can service the request. The service with which
reports the highest confidence gets invoked.
The CommonPlaySkill makes it easy to implement this. Simply derive a
skill from CommonPlaySkill (instead of MycroftSkill) and override
the two required methods CPS__match_query_phrase() and CPS__start().
The skill can then use self.CPS__play(url) to begin playback, or invoke
a unique player to interact with a custom service.
This makes a cross context call be treated as one level when calculating the probability. this makes previous contexes not be completely invalidated when a cross context call is sent.
* Add protection for naive skill authors
It is fairly common for new skill authors to attempt actions in the __init__()
method which are not legal yet, as the Skill has not been fully connected to
the Mycroft system. This adds an @property protection layer for the two most common
issues:
* Accessing MycroftSkill.bus
* Accessing MycroftSkill.enclosure
Now those are properties instead of variables and provide appropriate warnings
when used before they exist.
Also enhancing the handling of error logs in the CLI to highlight problems such
as this:
* Color "- ERROR -" log messages in red
* Retaining leading characters from log messages, improving readability in formatted messages
This eliminates a lot of the noise in the log files. Later I'll add features in the CLI to
assist watching the messagebus messages rather than writing them all to logs.
Also corrected some language and formatting in settings.py docstrings.
* Add "wait" option to MycroftSkill.speak() and speak_dialog()
The new "wait" option will cause the speak function to block until all
of the given dialog has been spoken by Mycroft. This means:
self.speak("Hello world", wait=True)
is now equivalent to:
self.speak("Hello world")
wait_while_speaking()
* Add ability to schedule event in seconds
The MycroftSkill.schedule_event() method now accepts an integer in addition to
a datetime for the 'when' parameter. The integer represents the number of
seconds in the future to fire off the event. E.g.
```python
self.schedule_event(some_handler, 7)
```
Will invoke some_handler() seven seconds from now.
Also unified language used in event docstrings.
Switch to an OrderedDict() for translate_namedvalues(), maintaining the
sequence of values defined in the original "list.value" file. This is
useful in circumstances where there are multiple values, but the order
of listing indicates some sort of preference.
This is used in the Alarm skill to allow synonyms like "weekdays"/"weekday",
"Mondays/Monday", but the first value is used when building the status string.
For example "You have an alarm for 8am on Mondays". Generically, this lets
translators consistently provide preferred names for values by adjusting the
order.
Adapt doesn't populate the entry from the one_of correctly from context. To work around the issue intent structure is scanned for empty keys and tries to populate them from entities in __tags__
* Add repeat option to audioservice
The audioservice.play() method now accepts a repeat parameter. If this
parameter is True the playlist passed to the audio service will be
repeated.
* Add repeat support to vlc
* Add the repeat parameter to all services
Not functional but playback will work at least. Hacktoberfest?
* Add cleanup if the skill loading fails
If a skill throws an exception in initialize the registered handlers
need to be removed. To cleanup this the skill shutdown procedure is
run.
* Don't try converse method on non-loaded skills
Checks if a valid skill instance is present before calling the converse method
to filter out skills that wasn't loaded.
* Mark unloaded skills as inactive in CLI
The recent changes to support the 'locale' directory were incorrectly
joining the os.walk() path and filename, resulting in double-directories,
like "./vocab/en-us/./vocab/en-us/Something.voc"
This is a step towards abstracting the idea of an Enclosure which ties Mycroft to the hardware that is running Mycroft.
- Move the enclosure API to mycroft.enclosure.api (previously was mycroft.client.enclosure.api)
- Move display_manager out of enclosure client to mycroft.enclosure.display_manager
- Merge EnclosureWeather into EnclosureMouth
- Wrap display manager in a class
* Add MycroftSkill.find_resource() that locates a localization resource file
from either under the old vocab/regex/dialog folder, or under any folder in
the new 'locale' folder. The locale folder unifies the three different
folders and allows arbitrary subfolders underneath it.
* MycroftSkill.speak_dialog() will now speak the entry name if no dialog file
is found. Periods are replaced with spaces, so
```self.speak_dialog("this.is.a.test.")``` would return "this is a test" if
no file named this.is.a.test.dialog is found.
* Remove MycroftSkills.vocab_dir value
* Minor edits to several docstrings
The method first tries to use the skill vocab directory and then tries
the mycroft/res/text... directory.
After the vocab is loaded from file once it's stored in a cache
dictionary and further uses of the method won't hit the disk.
Example:
if self.voc_match(utt, "Yes):
...
The initial implementation of web settings returned values as
strings all the time, even Boolean and numeric values. This
required unnecessarily complicated code, such as:
```python
if setting["show_time"] == "true":
# do whatever...
```
Now a value defined in metadata as a "checkbox" gets cast to a boolean,
and values defined in metadata as a "number" is typecast to int or
float, as appropriate. This allows cleaner code such as:
```python
if setting["show_time"]:
# do whatever...
```
NOTE: This can be a breaking change, verify you skill which uses 'checkbox'
webUI types handles this correctly for 18.08.
The list holding the names of scheduled events was being populated with decorated names,
but other code assumed it held the "friendly" name. Corrected this assumption.
Several locations also removed list entries while iterating on the same list, resulting
in entries being skipped and left un-deleted. This left behind phantom scheduled events
when skills were reloaded, goofing up many schedules after the reload.