MessageBus

A Message Bus is mechanism for independent systems to communicate with each other using a set of _messages_ for common commands or notifiers. In the Mycroft ecosystem, the Messagebus is a websocket.

What is a Message Bus?

A Message Bus is mechanism for independent systems to communicate with each other using a set of messages for common commands or notifiers. In the Mycroft ecosystem, the Messagebus is a websocket and the messages contain a message type with an optional JSON data packet. Some messages trigger actions and have side effects; some are simple notifiers of actions that either have occurred or are about to occur. The Messagebus connects the mycroft-core processes and the Skills, and can also be joined by outside systems such as the CLI.

The common messages are listed below. Messages can be sent from the producers listed below and acted upon by Skills or other consumers within mycroft-core. The producers and consumers list below is not exhaustive and some messages might be generated or handled by other processes or advanced Skills.

The base MycroftSkill API handles most of the Messagebus usage automatically. For example, the mycroft.stop message is caught by the skill framework, invoking an overridden MycroftSkills.stop() method within a Skill. Similarly, the MycroftSkill.speak() and MycroftSkill.speak_dialog() methods generate speak messages to be conveyed to the text-to-speech (TTS) and audio systems.

You will really only need to know about the Mycroft Messagebus if you are developing advanced Skills. The MycroftSkill.add_event() method allows you to attach a handler which will be triggered when the message is seen on the Messagebus.

NOTE: We can only currently assist you in writing Skills in Python, so if you choose to write Skills in another programming language, we may not be able to provide assistance - but we don't want to stop you doing awesome things!

Mycroft Messagebus messages

message type

data

Emitted By (Producer)

Handled By (Consumer)

Meaning

speak

{"utterance": "words to be spoken", "lang": "en-us"}

Request to speak utterance

mycroft.internet.connected

Internet connection is now available (only generated on initial connection)

mycroft.stop

Stop command (e.g. button pressed)

mycroft.paired

Pairing has completed

open

messagebusclientws.py

System UI is ready

complete_intent_failure

Intent processing failed

recognizer_loop:sleep

Go into 'sleep' mode. Everything except "Hey Mycroft, wake up" will be ignored.

recognizer_loop:wake_up

Come out of 'sleep' mode.

mycroft.awoken

Has come out of sleep mode

recognizer_loop:wakeword

{"utterance": "wakeword heard", "session": session_id}

client/speech/main.py

Wake Word was heard

recognizer_loop:record_begin

client/speech/main.py

Recording has started

recognizer_loop:record_end

client/speech/main.py

Recording has ended

recognizer_loop:utterance

{"utterances": [text], "lang": self.stt.lang, "session": session_id}

client/speech/main.py

recognizer_loop:audio_output_start

audio/speech.py

Text output (TTS) has begun

recognizer_loop:audio_output_end

audio/speech.py

Text output (TTS) has ended

enclosure.notify.no_internet

audio/speech.py

Detetected a connection error during STT

mycroft.mic.mute

client/speech/main.py

Turn off the mic (no wakeword or STT processing)

mycroft.mic.unmute

client/speech/main.py

Turn on the mic (enable wakeword and STT processing)

mycroft.mic.listen

Begin recording for STT processing

mycroft.audio.service.play

skills/audioservice.py

audio/main.py

Start playback of tracklist

mycroft.audio.service.stop

skills/audioservice.py

audio/main.py

Stop playback

mycroft.audio.service.pause

skills/audioservice.py

audio/main.py

Pause playback (if supported)

mycroft.audio.service.resume

skills/audioservice.py

audio/main.py

Resume playback (if supported by backend)

mycroft.audio.service.track_info

skills/audioservice.py

audio/main.py

Request track info from audio service

mycroft.audio.service.track_info_reply

audio/main.py

skills/audioservice.py

Reply to track info request

mycroft.audio.service.next

skills/audioservice.py

audio/main.py

Skip to next track

mycroft.audio.service.prev

skills/audioservice.py

audio/main.py

Skip to previous track

mycroft.volume.increase

{"play_sound": true}

client/enclosure/init.py

Volume Skill

Enclosure Volume up

mycroft.volume.decrease

{"play_sound": true}

client/enclosure/init.py

Volume Skill

Enclosure Volume down

mycroft.volume.mute

{"speak_message": true}

Volume Skill

Enclosure Volume muted

mycroft.volume.unmute

{"speak_message": true}

Volume Skill

Enclosure Volume unmuted

mycroft.skill.handler.start

{"handler": class/function name}

mycroft.skill.handler.complete

mycroft.skill.disable_intent

{"intent_name": "name"}

mycroft/skills/core.py

Disable intent

mycroft.skill.enable_intent

{"intent_name": "name"}

mycroft/skills/core.py

Enable disabled intent

mycroft.skills.loaded

{"id": SKILL ID, "name": SKILL NAME, "folder": FOLDER, "modified": MODIFIED}

skills/main.py

mycroft/skills/intent_service.py

A skill has been loaded

mycroft.skills.loading_failure

{"id": SKILL ID, "folder": SKILL FOLDER}

skills/main.py

mycroft.skills.shutdown

{"id": SKILL ID, "folder": SKILL FOLDER}

skills/main.py

mycroft.skills.list

{"skills": [...] }

skills/main.py

List of loaded skills (response to 'skillmanager.list')

mycroft.skills.initialized

mycroft/skills/main.py

Upon startup, all skills have been loaded

mycroft.skills.settings.update

Configuration Skill

mycroft/skills/settings.py

Pull new skill settings from the server

msm.updating

msm.sh

skills/main.py

MSM install has begun

msm.installing

msm.sh

skills/main.py

MSM update has begun

msm.install.succeeded

{ "skill" : name }

msm.sh

skills/main.py

MSM install succeeded for given skill

msm.install.failed

{ "skill" : name, "error" : code }

msm.sh

skills/main.py

MSM install failed for given skill

msm.installed

msm.sh

skills/main.py

MSM install is complete

msm.updated

msm.sh

skills/main.py

MSM update is complete

msm.removing

msm.sh

skills/main.py

MSM remove has begun

msm.remove.succeeded

{ "skill" : name }

msm.sh

skills/main.py

MSM remove succeeded for given skill

msm.remove.failed

{ "skill" : name, "error" : code }

msm.sh

skills/main.py

MSM remove failed for given skill

msm.removed

msm.sh

skills/main.py

MSM remove is complete

skillmanager.update

skills/main.py

Request immediate update of all skills

skillmanager.list

CLI (client/text/main.py)

skills/main.py

Request a response with 'mycroft.skills.list'

System administrative actions

system.wifi.setup / mycroft.wifi.start

mycroft-wifi-setup: mycroft_admin_service.py

Kick off a a wifi-setup session

system.wifi.reset / mycroft.wifi.reset

mycroft-wifi-setup: mycroft_admin_service.py

Clear the saved wifi settings

system.ntp.sync

mycroft-wifi-setup: mycroft_admin_service.py

Force the system clock to synchronize with NTP servers

system.ssh.enable / mycroft.enable.ssh

mycroft-wifi-setup: mycroft_admin_service.py

Configure system to allow SSH connections

system.ssh.disable / mycroft.disable.ssh

mycroft-wifi-setup: mycroft_admin_service.py

Configure system to block SSH connections

system.reboot

mycroft-wifi-setup: mycroft_admin_service.py

Force a Linux reboot

system.shutdown

mycroft-wifi-setup: mycroft_admin_service.py

Force a Linux shutdown

system.update

mycroft-wifi-setup: mycroft_admin_service.py

Force an apt-get update on mycroft-mark-1 or mycroft-picroft package (as appropriate)

Guidelines for Mycroft Messagebus usage

Private messages can be placed on the Messagebus following these naming conventions: subsystem.message or skill.skillname.message

  • Messages MUST use verbs for requests - such as;

    • mic.mute

    • mic.unmute

    • skill.mycrofttimer.cancel.all

  • Messages MUST use the future tense for pre-action notifications - such as;

    • mic.muting

    • mic.unmuting

  • Messages MUST use the past tense for post-action notifications - such as;

    • mic.muted

    • mic.unmuted

    • skill.mycrofttimer.expired

Command line invocation syntax

python3 -m mycroft.messagebus.send xxx.yyy.zzz

or

python3 -m mycroft.messagebus.send xxx.yyy.zzz '{"name": "value"}'

Connecting message handlers within a MycroftSkill

...
def initialize(self):
self.add_event('recognizer_loop:record_begin',
self.handle_listener_started)
self.add_event('recognizer_loop:record_end',
self.handle_listener_ended)
def handle_listener_started(self, message):
# code to excecute when active listening begins...
def handle_listener_ended(self, message):
# code to excecute when active listening begins...
...

Generating messages within a MycroftSkill

...
def some_method(self):
self.emitter.emit(Message("recognizer_loop:utterance",
{'utterances': ["inject a user utterance"],
'lang': 'en-us'}))
...

Connecting to the Mycroft Messagebus in Python

Here is an example Python script to connect to the messagebus:

#! /usr/bin/env python3
import sys
from websocket import create_connection
uri = 'ws://' + sys.argv[1] + ':8181/core'
ws = create_connection(uri)
print("Sending " + sys.argv[2] + " to " + uri + "...")
if len(sys.argv) >= 4:
data = sys.argv[3]
else:
data = "{}"
message = '{"type": "' + sys.argv[2] + '", "data": ' + data +'}'
result = ws.send(message)
print("Receiving..." )
result = ws.recv()
print("Received '%s'" % result)
ws.close()

Unfortunately, we cannot provide support or examples for other languages.

If you have further questions, then the best place to ask them is our Community Forum or in the ~dev Channel on Mycroft Chat.