Skip to content

collection of simple utilities for use across the mycroft ecosystem

Notifications You must be signed in to change notification settings

msgpo/jarbas_utils

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Jarbas - utils

collection of simple utilities for use across the mycroft ecosystem

Install

stable version on pip 0.4.1

pip install jarbas_utils

dev version

pip install git+https://github.com/OpenJarbas/jarbas_utils

Usage

Messagebus

The main way to interact with a mycroft instance is using the messagebus

WARNING: the mycroft bus is unencrypted, be sure to secure your communications in some way before you start poking firewall ports open

Listening

Listening for events is super easy, here is a small program counting number of spoken utterances

from jarbas_utils.messagebus import listen_for_message
from jarbas_utils.log import LOG
from jarbas_utils import wait_for_exit_signal

spoken = 0


def handle_speak(message):
    global spoken
    spoken += 1
    LOG.info("Mycroft spoke {n} sentences since start".format(n=spoken))


bus = listen_for_message("speak", handle_speak)
wait_for_exit_signal()  # wait for ctrl+c

# cleanup is a good practice! 
bus.remove_all_listeners("speak")
bus.close()

Sending

Triggering events in mycroft is also trivial

from jarbas_utils.messagebus import send_message
from jarbas_utils.log import LOG
from jarbas_utils import create_daemon, wait_for_exit_signal
import random
from time import sleep


def alert():
    LOG.info("Alerting user of some event using Mycroft")
    send_message("speak", {"utterance": "Alert! something happened"})


def did_something_happen():
    while True:
        if random.choice([True, False]):
            alert()
        sleep(10)


create_daemon(did_something_happen) # check for something in background
wait_for_exit_signal()  # wait for ctrl+c

Remote Websocket

You can also connect to a remote messagebus, here is a live translator using language utils

from jarbas_utils.messagebus import get_mycroft_bus, listen_for_message
from jarbas_utils import wait_for_exit_signal
from jarbas_utils.lang.translate import say_in_language


bus_ip = "0.0.0.0"  # enter a remote ip here, remember bus is unencrypted! careful with opening firewalls
bus = get_mycroft_bus(host=bus_ip)


TARGET_LANG = "pt"


def translate(message):
    utterance = message.data["utterance"]
    say_in_language(utterance, lang=TARGET_LANG)


listen_for_message("speak", translate, bus=bus)

wait_for_exit_signal()  # wait for ctrl+c

bus.remove_all_listeners("speak")
bus.close()

Advanced Usage

Providing services over the messagebus

from jarbas_utils.messagebus import BusFeedProvider, Message
from datetime import datetime


class ClockService(BusFeedProvider):
    def __init__(self, name="clock_transmitter", bus=None):
        trigger_message  = Message("time.request")
        super().__init__(trigger_message, name, bus)
        self.set_data_gatherer(self.handle_get_time)
        
    def handle_get_time(self, message):
        self.update({"date": datetime.now()})
        
        
clock_service = ClockService()

Querying services over the messagebus

from jarbas_utils.messagebus import BusFeedConsumer, Message

class Clock(BusFeedConsumer):
    def __init__(self, name="clock_receiver", timeout=3, bus=None):
        request_message = Message("time.request")
        super().__init__(request_message, name, timeout, bus)

clock = Clock()
date = clock.request()["date"]

Enclosures

If you are making a system enclosure you will likely need to handle system actions

System actions

from jarbas_utils.system import system_reboot, system_shutdown, ssh_enable, ssh_disable
from jarbas_utils.log import LOG
from jarbas_utils.messagebus import get_mycroft_bus, Message


class MyEnclosureClass:

    def __init__(self):
        LOG.info('Setting up client to connect to a local mycroft instance')
        self.bus = get_mycroft_bus()
        self.bus.on("system.reboot", self.handle_reboot)
        
    def speak(self, utterance):
        LOG.info('Sending speak message...')
        self.bus.emit(Message('speak', data={'utterance': utterance}))
        
    def handle_reboot(self, message):
        self.speak("rebooting")
        system_reboot()
        
        

Configuration

utils are provided to manipulate the user config

NOTE: this assumes you are running this code on the same machine as mycroft, it manipulates files directly in your system

from jarbas_utils.configuration import read_mycroft_config

config = read_mycroft_config()
stt = config["stt"]["module"]

individual configs can also be manipulated

from jarbas_utils.configuration import MycroftUserConfig, MycroftSystemConfig, MycroftDefaultConfig
from jarbas_utils.log import LOG

config = MycroftUserConfig()
config["lang"] = "pt"
config["tts"] = {"module": "google"}
config.store()

config = MycroftSystemConfig(allow_overwrite=True)
config["enclosure"] = {"platform": "respeaker"}
config.store()

config = MycroftDefaultConfig()
config.set_mycroft_root("~/PycharmProjects/mycroft-core")  # not needed for mark1/mark2/picroft
lang = config["lang"]
try:
    config["lang"] = "pt"
except PermissionError:
    LOG.error("config is read only")

you can also use the LocalConf class with your own path for other use cases

from jarbas_utils.configuration import LocalConf

MY_CONFIG = "~/.projectX/projectX.conf"

class MyConfig(LocalConf):
    def __init__(self):
        super().__init__(MY_CONFIG)
        
config = MyConfig()
if not config.get("lang"):
    config["lang"] = "pt"
    config.store() # now changes are saved

config.merge({mycroft_ip: "http://somedomain.net"})
config.reload() # now changes are gone
Wake words

when defining pocketsphinx wake words you often need to know the phonemes

from jarbas_utils.configuration import update_mycroft_config
from jarbas_utils.lang.phonemes import get_phonemes


def create_wakeword(word, sensitivity):
    # sensitivity is a bitch to do automatically
    # IDEA make some web ui or whatever to tweak it experimentally
    phonemes = get_phonemes(word)
    config = {
        "listener": {
            "wake_word": word
          },
          word: {
            "andromeda": {
              "module": "pocketsphinx",
              "phonemes": phonemes,
              "sample_rate": 16000,
              "threshold": sensitivity,
              "lang": "en-us"
            }
          }
    }
    update_mycroft_config(config)
    
create_wakeword("andromeda", "1e-25")
        

Here is some sample output from get_phonemes

hey mycroft HH EY1 . M Y K R OW F T
hey chatterbox HH EY1 . CH AE T EH R B OW K S
alexa AH0 L EH1 K S AH0

Sound

Volume control is also a common thing you need to handle

from jarbas_utils.sound.alsa import AlsaControl
#from jarbas_utils.sound.pulse import PulseAudio
from jarbas_utils.log import LOG
from jarbas_utils.messagebus import get_mycroft_bus, Message


class MyPretendEnclosure:

    def __init__(self):
        LOG.info('Setting up client to connect to a local mycroft instance')
        self.bus = get_mycroft_bus()
        # None of these are mycroft signals, but you get the point
        self.bus.on("set.volume", self.handle_set_volume)
        self.bus.on("speak.volume", self.handle_speak_volume)
        self.bus.on("mute.volume", self.handle_mute_volume)
        self.bus.on("unmute.volume", self.handle_unmute_volume)
        
        self.alsa = AlsaControl()
        # self.pulse = PulseAudio()
        
    def speak(self, utterance):
        self.bus.emit(Message('speak', data={'utterance': utterance}))
        
    def handle_speak_volume(self, message):
        volume = self.alsa.get_volume()
        self.speak(volume)
        
    def handle_mute_volume(self, message):
        if not self.alsa.is_muted():
            self.alsa.mute()
        
    def handle_unmute_volume(self, message):
        if self.alsa.is_muted():
            self.alsa.unmute()
        
    def handle_set_volume(self, message):
        volume = message.data.get("volume", 50)
        assert 0 <= volume <= 100
        self.alsa.set_volume(volume)

About

collection of simple utilities for use across the mycroft ecosystem

Resources

Stars

Watchers

Forks

Sponsor this project

Packages

No packages published

Languages