User-configurable behavior: settings + settingsmeta + live reload¶
In a nutshell
You build an OVOSSkill that reacts immediately to a changed setting, using settings_change_callback alongside a settingsmeta.yaml field declaration.
When you'd want this: a skill has a behavior the user should be able to tune, such as a unit system, a greeting name, or an API key, and it should react immediately when that value changes, whether the change came from a config file edit or a remote settings backend.
from ovos_workshop.skills import OVOSSkill
from ovos_workshop.decorators import intent_handler
class GreeterSkill(OVOSSkill):
def initialize(self):
self.settings_change_callback = self.on_settings_changed
self._apply_settings()
def _apply_settings(self):
self.greeting_name = self.settings.get("name", "friend")
self.use_title_case = self.settings.get("shout", False)
def on_settings_changed(self):
# called whenever settings.json changes on disk, or a remote
# settings backend pushes an update for this skill
self._apply_settings()
self.log.info(f"settings updated, now greeting as {self.greeting_name}")
@intent_handler("greet.intent")
def handle_greet(self, message):
name = self.greeting_name.upper() if self.use_title_case else self.greeting_name
self.speak_dialog("greeting", {"name": name})
settingsmeta.yaml (the optional form shown by web/companion-app settings UIs):
skillMetadata:
sections:
- name: "Greeter"
fields:
- name: "name"
type: "text"
label: "What should I call you?"
value: "friend"
- name: "shout"
type: "checkbox"
label: "SHOUT the greeting"
value: false
Moving parts¶
self.settings_change_callbackis a plain attribute you assign a callable to (there is no decorator for it). The base class checksif self.settings_change_callback is not Noneboth on a local file-watcher change and on a remotemycroft.skills.settings.changedpush, and calls it with no arguments either way. See Skill Settings for the two trigger paths.- Read settings defensively with
.get(key, default). A fresh install has an emptysettings.jsonuntilsettingsmeta.yamldefaults are applied by a settings UI, or you seedself.settingsyourself ininitialize(). settingsmeta.yaml/.jsonis descriptive only. It drives a UI for editing settings, and does not itself create or validate keys. See Skill Settings Meta for the full field-type table and where the file must live.
Read next: Skill Cookbook Related: Skill Settings · Skill Settings Meta · A skill with a settings UI