187 lines
6.6 KiB
Python
187 lines
6.6 KiB
Python
# Copyright 2016 Mycroft AI, Inc.
|
|
#
|
|
# This file is part of Mycroft Core.
|
|
#
|
|
# Mycroft Core is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# Mycroft Core is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with Mycroft Core. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
from mycroft.messagebus.message import Message
|
|
from mycroft.util.log import getLogger
|
|
|
|
__author__ = 'jdorleans'
|
|
|
|
LOGGER = getLogger(__name__)
|
|
|
|
|
|
class EnclosureAPI:
|
|
"""
|
|
This API is intended to be used to interface with the hardware
|
|
that is running Mycroft. It exposes all possible commands which
|
|
can be sent to a Mycroft enclosure implementation.
|
|
|
|
Different enclosure implementations may implement this differently
|
|
and/or may ignore certain API calls completely. For example,
|
|
the eyes_color() API might be ignore on a Mycroft that uses simple
|
|
LEDs which only turn on/off, or not at all on an implementation
|
|
where there is no face at all.
|
|
"""
|
|
|
|
def __init__(self, ws):
|
|
self.ws = ws
|
|
|
|
def reset(self):
|
|
"""The enclosure should restore itself to a started state.
|
|
Typically this would be represented by the eyes being 'open'
|
|
and the mouth reset to its default (smile or blank).
|
|
"""
|
|
self.ws.emit(Message("enclosure.reset"))
|
|
|
|
def system_reset(self):
|
|
"""The enclosure hardware should reset any CPUs, etc."""
|
|
self.ws.emit(Message("enclosure.system.reset"))
|
|
|
|
def system_mute(self):
|
|
"""Turn off the system microphone (not listening for wakeword)."""
|
|
self.ws.emit(Message("enclosure.system.mute"))
|
|
|
|
def system_unmute(self):
|
|
"""Turn the system microphone on (listening for wakeword)."""
|
|
self.ws.emit(Message("enclosure.system.unmute"))
|
|
|
|
def system_blink(self, times):
|
|
"""The 'eyes' should blink the given number of times.
|
|
Args:
|
|
times (int): number of times to blink
|
|
"""
|
|
self.ws.emit(Message("enclosure.system.blink", {'times': times}))
|
|
|
|
def eyes_on(self):
|
|
"""Illuminate or show the eyes."""
|
|
self.ws.emit(Message("enclosure.eyes.on"))
|
|
|
|
def eyes_off(self):
|
|
"""Turn off or hide the eyes."""
|
|
self.ws.emit(Message("enclosure.eyes.off"))
|
|
|
|
def eyes_blink(self, side):
|
|
"""Make the eyes blink
|
|
Args:
|
|
side (str): 'r', 'l', or 'b' for 'right', 'left' or 'both'
|
|
"""
|
|
self.ws.emit(Message("enclosure.eyes.blink", {'side': side}))
|
|
|
|
def eyes_narrow(self):
|
|
"""Make the eyes look narrow, like a squint"""
|
|
self.ws.emit(Message("enclosure.eyes.narrow"))
|
|
|
|
def eyes_look(self, side):
|
|
"""Make the eyes look to the given side
|
|
Args:
|
|
side (str): 'r' for right
|
|
'l' for left
|
|
'u' for up
|
|
'd' for down
|
|
'c' for crossed
|
|
"""
|
|
self.ws.emit(Message("enclosure.eyes.look", {'side': side}))
|
|
|
|
def eyes_color(self, r=255, g=255, b=255):
|
|
"""Change the eye color to the given RGB color
|
|
Args:
|
|
r (int): 0-255, red value
|
|
g (int): 0-255, green value
|
|
b (int): 0-255, blue value
|
|
"""
|
|
self.ws.emit(Message("enclosure.eyes.color",
|
|
{'r': r, 'g': g, 'b': b}))
|
|
|
|
def eyes_brightness(self, level=30):
|
|
"""Set the brightness of the eyes in the display.
|
|
Args:
|
|
level (int): 1-30, bigger numbers being brighter
|
|
"""
|
|
self.ws.emit(Message("enclosure.eyes.level", {'level': level}))
|
|
|
|
def eyes_reset(self):
|
|
"""Restore the eyes to their default (ready) state."""
|
|
self.ws.emit(Message("enclosure.eyes.reset"))
|
|
|
|
def eyes_timed_spin(self, length):
|
|
"""Make the eyes 'roll' for the given time.
|
|
Args:
|
|
length (int): duration in milliseconds of roll, None = forever
|
|
"""
|
|
self.ws.emit(Message("enclosure.eyes.timedspin",
|
|
{'length': length}))
|
|
|
|
def eyes_volume(self, volume):
|
|
"""Indicate the volume using the eyes
|
|
Args:
|
|
volume (int): 0 to 11
|
|
"""
|
|
self.ws.emit(Message("enclosure.eyes.volume", {'volume': volume}))
|
|
|
|
def mouth_reset(self):
|
|
"""Restore the mouth display to normal (blank)"""
|
|
self.ws.emit(Message("enclosure.mouth.reset"))
|
|
|
|
def mouth_talk(self):
|
|
"""Show a generic 'talking' animation for non-synched speech"""
|
|
self.ws.emit(Message("enclosure.mouth.talk"))
|
|
|
|
def mouth_think(self):
|
|
"""Show a 'thinking' image or animation"""
|
|
self.ws.emit(Message("enclosure.mouth.think"))
|
|
|
|
def mouth_listen(self):
|
|
"""Show a 'thinking' image or animation"""
|
|
self.ws.emit(Message("enclosure.mouth.listen"))
|
|
|
|
def mouth_smile(self):
|
|
"""Show a 'smile' image or animation"""
|
|
self.ws.emit(Message("enclosure.mouth.smile"))
|
|
|
|
def mouth_viseme(self, code):
|
|
"""Display a viseme mouth shape for synched speech
|
|
Args:
|
|
code (int): 0 = shape for sounds like 'y' or 'aa'
|
|
1 = shape for sounds like 'aw'
|
|
2 = shape for sounds like 'uh' or 'r'
|
|
3 = shape for sounds like 'th' or 'sh'
|
|
4 = neutral shape for no sound
|
|
5 = shape for sounds like 'f' or 'v'
|
|
6 = shape for sounds like 'oy' or 'ao'
|
|
"""
|
|
self.ws.emit(Message("enclosure.mouth.viseme", {'code': code}))
|
|
|
|
def mouth_text(self, text=""):
|
|
"""Display text (scrolling as needed)
|
|
Args:
|
|
text (str): text string to display
|
|
"""
|
|
self.ws.emit(Message("enclosure.mouth.text", {'text': text}))
|
|
|
|
def weather_display(self, img_code, temp):
|
|
"""Show a weather icon (deprecated)"""
|
|
self.ws.emit(Message("enclosure.weather.display",
|
|
{'img_code': img_code, 'temp': temp}))
|
|
|
|
def activate_mouth_events(self):
|
|
"""Enable movement of the mouth with speech"""
|
|
self.ws.emit(Message('enclosure.mouth.events.activate'))
|
|
|
|
def deactivate_mouth_events(self):
|
|
"""Disable movement of the mouth with speech"""
|
|
self.ws.emit(Message('enclosure.mouth.events.deactivate'))
|