Skip to content

Commit

Permalink
Merge pull request #10 from bossjones/feature-emit-cmd-signal
Browse files Browse the repository at this point in the history
Feature: emit cmd signal
  • Loading branch information
bossjones authored Jul 6, 2016
2 parents 7a10d58 + e5edac3 commit 4ed9d74
Show file tree
Hide file tree
Showing 4 changed files with 315 additions and 23 deletions.
226 changes: 226 additions & 0 deletions generator_commands.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,226 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from __future__ import with_statement
from __future__ import division

import sys
import os

os.environ[
"GST_DEBUG_DUMP_DOT_DIR"] = "/home/pi/dev/bossjones-github/scarlett-dbus-poc/_debug"
os.putenv('GST_DEBUG_DUMP_DIR_DIR',
'/home/pi/dev/bossjones-github/scarlett-dbus-poc/_debug')

import pprint
pp = pprint.PrettyPrinter(indent=4)

from IPython.core.debugger import Tracer
from IPython.core import ultratb

sys.excepthook = ultratb.FormattedTB(mode='Verbose',
color_scheme='Linux',
call_pdb=True,
ostream=sys.__stdout__)
import logging
logger = logging.getLogger('scarlettlogger')

import generator_utils
from generator_utils import trace, abort_on_exception

import time
import datetime

CMD_MASTER_LIST_HEX = {
"frizzytv": {
"up": "1,77E1D009,32",
"down": "1,77E1B009,32",
"left": "1,77E11009,32",
"right": "1,77E1E009,32",
"menu": "1,77E1BA09,32",
"pause": "1,77E12009,32",
"play": "1,77E17A09,32",
"circle button": "1,77E1BA09,32" # this too 77E12009
},
"appletv": {
"up": "1,77E1D030,32",
"down": "1,77E1B030,32",
"left": "1,77E11030,32",
"right": "1,77E1E030,32",
"menu": "1,77E14030,32",
"pause": "1,77E17A30,32",
"play": "1,77E17A30,32",
"circle button": "1,77E1BA30,32"
},
"toshiba": {
"channel up": "1,2FDD827,32",
"channel down": "1,2FDF807,32",
"volume up": "1,2FD58A7,32",
"volume down": "1,2FD7887,32",
"mute": "1,2FD08F7,32",
"recall": "1,2FD38C7,32",
"input": "1,2FDF00F,32",
"select up": "1,2FD41BE,32",
"select down": "1,2FDC13E,32",
"select left": "1,2FDB847,32",
"select right": "1,2FD9867,32",
"select enter": "1,2FD916E,32",
"one": "1,2FD807F,32",
"two": "1,2FD40BF,32",
"three": "1,2FDC03F,32",
"four": "1,2FD20DF,32",
"five": "1,2FDA05F,32",
"six": "1,2FD609F,32",
"seven": "1,2FDE01F,32",
"eight": "1,2FD10EF,32",
"nine": "1,2FD906F,32",
"zero": "1,2FD00FF,32",
"power": "1,2FD48B7,32"
}
}

SPOTIFY_CMDS = {
"SPOTIFY PLAY": "play music",
"SPOTIFY PAUSE": "pause music",
"SPOTIFY SKIP": "skip track",
"SPOTIFY SKIP FORWARD": "track back",
"SPOTIFY SKIP BACK": "track forward",
}

LIGHT_CMDS = {
"TURN ON THE LIGHTS": "hue lights on",
"TURN ON LIGHTS": "hue lights on",
"LIGHTS ON": "hue lights on",
"TURN OFF THE LIGHTS": "hue lights off",
"TURN OFF LIGHTS": "hue lights off",
"LIGHTS OFF": "hue lights off",
"TURN LIGHTS RED": "hue lights all red",
"LIGHTS RED": "hue lights all red",
"CHANGE LIGHTS RED": "hue lights all red",
"TURN LIGHTS GREEN": "hue lights all green",
"LIGHTS GREEN": "hue lights all green",
"CHANGE LIGHTS GREEN": "hue lights all green",
"TURN LIGHTS WHITE": "hue lights all white",
"LIGHTS WHITE": "hue lights all white",
"CHANGE LIGHTS WHITE": "hue lights all white",

# TODO: CHANGE THIS BULLSHIT TO USE PROPER PYTHON MODULE
"TURN LIGHTS BRIGHTER": "echo '{\"bri\": 240}' | hue lights 3 state",
"LIGHTS BRIGHTER": "echo '{\"bri\": 240}' | hue lights 3 state",
"TURN LIGHTS DARKER": "echo '{\"bri\": 100}' | hue lights 3 state",
"LIGHTS DARKER": "echo '{\"bri\": 100}' | hue lights 3 state",
"SEXY TIME": "hue lights colorloop",
"GET LIGHT NAMES": "get light names",
}

TIME_CMDS = {
"WHAT TIME IS IT": "what time is it",
"TIME IS IT": "what time is it",
"TIME IT IS": "what time is it"
}

TV_CMDS = {
"CHANNEL UP": "channel up",
"CHANNEL DOWN": "channel down",
"TURN TO MTV": "turn to mtv",
"TURN TO BET": "turn to bet",
"TURN TO HBO": "turn to hbo",
"SWITCH TO APPLE TV": "switch to apple tv",
"SWITCH TO PLAY STATION": "switch to play station",
"SWTICH TO REGULAR TV": "switch to regular tv",
"APPLE TV UP": CMD_MASTER_LIST_HEX["appletv"]["up"].lower(),
"APPLE TV CHANNEL UP": CMD_MASTER_LIST_HEX["appletv"]["up"].lower(),
"APPLE TV DOWN": CMD_MASTER_LIST_HEX["appletv"]["down"].lower(),
"APPLE TV CHANNEL DOWN": CMD_MASTER_LIST_HEX["appletv"]["down"].lower(),
"APPLE TV LEFT": CMD_MASTER_LIST_HEX["appletv"]["left"].lower(),
"APPLE TV CHANNEL LEFT": CMD_MASTER_LIST_HEX["appletv"]["left"].lower(),
"APPLE TV RIGHT": CMD_MASTER_LIST_HEX["appletv"]["right"].lower(),
"APPLE TV CHANNEL RIGHT": CMD_MASTER_LIST_HEX["appletv"]["right"].lower(),
"APPLE TV PAUSE": CMD_MASTER_LIST_HEX["appletv"]["pause"].lower(),
"APPLE TV PLAY": CMD_MASTER_LIST_HEX["appletv"]["play"].lower(),
"APPLE TV MENU": CMD_MASTER_LIST_HEX["appletv"]["menu"].lower(),
"APPLE TV MENU BUTTON": CMD_MASTER_LIST_HEX["appletv"]["menu"].lower(),
"APPLE TV ENTER": CMD_MASTER_LIST_HEX["appletv"]["circle button"].lower(),
"APPLE TV ENTER BUTTON": CMD_MASTER_LIST_HEX["appletv"]["circle button"].lower()
}

GENERAL_CMDS = {
"CANCEL": "cancel",
}

FORECAST_CMDS = {
"WHAT IS THE FORECAST": "weather",
"WHAT IS THE TEMPATURE": "weather",
"WHAT IS CURRENT TEMPATURE": "weather",
"WHATS THE WEATHER": "weather",
"WHATS TODAYS WEATHER": "weather",
"WHATS THE TEMPATURE": "weather",
}

NO_OP = '__SCARLETT_NO_OP__'

######################################################################################################################
# NOTE: In the future time will be its own plugin class etc, for now we're just going to add arbitrary functions here:
######################################################################################################################
######################################################################################################################


class TimeCommand(object):

@staticmethod
def get_current_time():
now = datetime.datetime.now()
return now.strftime("It is now, %I:%M %p")

@staticmethod
def get_current_date():
now = datetime.datetime.now()
return now.strftime("Today's date is, %A, %B %d, %Y")

######################################################################################################################
######################################################################################################################


class Command(object):

@staticmethod
def check_cmd(command_tuple=None):
logger.error("Value of command_tuple: {}".format(command_tuple))

if isinstance(command_tuple, tuple):
logger.info("Valid command_tuple: {}".format(command_tuple))
else:
logger.error("INValid command_tuple: {}".format(command_tuple))
return NO_OP

msg, scarlett_sound, command = command_tuple

if command in SPOTIFY_CMDS.keys():
logger.debug("** received {}, sending 'spotify {}'".format(command, SPOTIFY_CMDS[command]))
elif command in LIGHT_CMDS.keys():
logger.debug("** received {}, sending 'light {}'".format(command, LIGHT_CMDS[command]))
# try:
# logger.debug("trying light chit")
# self.get_hue = scarlett.connect_hue(self.voice, self.brain)
# return self.get_hue.get_light_names()
# # REFACTOR ### light_play(LIGHT_CMDS[command])
# except Exception as e:
# logger.debug("light exception b. \nCMD: {} \nException: {}" %(command, e))
# # REFACTOR ### general_play("cancel")
elif command in TIME_CMDS.keys():
logger.debug("** received {}, sending 'time {}'".format(command, TIME_CMDS[command]))
return TimeCommand.get_current_time()
# try:
# from scarlett.features.time import FeatureTime
# self.get_time = FeatureTime(self.voice, self.brain)
# return self.get_time.time_play()
# except Exception as e:
# logger.debug(
# "time exception b. \nCMD: {} \nException: {}" %
# (command, e))
elif command in GENERAL_CMDS.keys():
logger.debug("** received {}, sending 'general command: {}'".format(command, GENERAL_CMDS[command]))
elif command in FORECAST_CMDS.keys():
logger.debug("** received {}, sending 'forecast command: {}'".format(command, FORECAST_CMDS[command]))
elif command in TV_CMDS.keys():
logger.debug("** received {}, sending 'tv command: {}'".format(command, TV_CMDS[command]))
9 changes: 8 additions & 1 deletion generator_listener.py
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ def scarlett_reset_listen(self):
self.failed = 0
self.kw_found = 0

def cancel_listening(self):
def cancel_listening(self, *args, **kwargs):
logger.debug("Inside cancel_listening function")
self.scarlett_reset_listen()
logger.debug("self.failed = %i" % (self.failed))
Expand Down Expand Up @@ -502,6 +502,13 @@ def _connect_to_dbus(self):
self.dbus_proxy.emitConnectedToListener('ScarlettListener')
sleep(2)
logger.info('_connect_to_dbus')
ss_cancel_signal = self.bus.subscribe(sender=None,
iface="org.scarlett.Listener",
signal="ListenerCancelSignal",
object="/org/scarlett/Listener",
arg0=None,
flags=0,
signal_fired=self.cancel_listening)

# NOTE: This function generates the dot file, checks that graphviz in installed and
# then finally generates a png file, which it then displays
Expand Down
21 changes: 12 additions & 9 deletions generator_speaker.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
class ScarlettSpeaker(object):
"""Scarlett Speaker Class."""

def __init__(self, text_to_speak="", wavpath=""):
def __init__(self, text_to_speak="", wavpath="", skip_player=False):
"""ScarlettSpeaker object. Anything defined here belongs to the INSTANCE of the class."""
self._wavefile = []
self._pitch = 75
Expand All @@ -60,6 +60,8 @@ def __init__(self, text_to_speak="", wavpath=""):
"-w", self._wavpath, "-v%s" % self._voice,
". %s ." % self._text]

self.path = None

# Write espeak data
with generator_utils.time_logger('Espeak Subprocess To File'):
self.running = True
Expand All @@ -70,14 +72,15 @@ def __init__(self, text_to_speak="", wavpath=""):
print "Did is run successfully? {}".format(self.res)

# Have Gstreamer play it
for path in self._wavefile:
path = os.path.abspath(os.path.expanduser(path))
with generator_player.ScarlettPlayer(path) as f:
print(f.channels)
print(f.samplerate)
print(f.duration)
for s in f:
pass
if skip_player != True:
for path in self._wavefile:
path = os.path.abspath(os.path.expanduser(path))
with generator_player.ScarlettPlayer(path) as f:
print(f.channels)
print(f.samplerate)
print(f.duration)
for s in f:
pass

# Cleanup.
def close(self, force=False):
Expand Down
82 changes: 69 additions & 13 deletions generator_tasker.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
from generator_utils import trace, abort_on_exception, _IdleObject
import generator_player
import generator_speaker
import generator_commands

import logging
logger = logging.getLogger('scarlettlogger')
Expand Down Expand Up @@ -353,6 +354,51 @@ def command_cb(*args, **kwargs):
# iface='org.scarlett.Listener',
# signal='CommandRecognizedSignal',
# params=GLib.Variant('(sss)', (' ScarlettListener caugh...ommand match', 'pi-response', 'what time is it')))

# NOTE: THIS IS WHAT FIXED THE GENERATOR NONSENSE
# source: https://www.python.org/dev/peps/pep-0343/
def player_generator_func():
for path in wavefile:
path = os.path.abspath(os.path.expanduser(path))
yield True
print("for path in wavefile")
p = generator_player.ScarlettPlayer(path, False)
while True:
try:
yield p.next()
finally:
time.sleep(p.duration)
p.close(force=True)
yield False

def run_player(function):
gen = function()
GObject.idle_add(lambda: next(gen, False), priority=GLib.PRIORITY_HIGH)


def speaker_generator_func():
for scarlett_text in tts_list:
yield True
print("scarlett_text in tts_list")
_wavepath = "/home/pi/dev/bossjones-github/scarlett-dbus-poc/espeak_tmp.wav"
s = generator_speaker.ScarlettSpeaker(text_to_speak=scarlett_text,
wavpath=_wavepath,
skip_player=True)
p = generator_player.ScarlettPlayer(_wavepath, False)
logger.error("Duration: p.duration: {}".format(p.duration))
while True:
try:
yield p.next()
finally:
time.sleep(p.duration)
p.close(force=True)
s.close(force=True)
yield False

def run_speaker(function):
gen = function()
GObject.idle_add(lambda: next(gen, False), priority=GLib.PRIORITY_HIGH)

for i, v in enumerate(args):
if SCARLETT_DEBUG:
logger.debug("Type v: {}".format(type(v)))
Expand All @@ -366,19 +412,29 @@ def command_cb(*args, **kwargs):
logger.warning(
" scarlett_sound: {}".format(scarlett_sound))
logger.warning(" command: {}".format(command))
command_run = True
if command_run:
tts_list = SpeakerType.speaker_to_array(
'Hello sir. How are you doing this afternoon? I am full lee function nall, andd red ee for your commands')
logger.info('BEGIN PLAYING INTRO')
for scarlett_text in tts_list:
with generator_utils.time_logger('Scarlett Speaks'):
generator_speaker.ScarlettSpeaker(text_to_speak=scarlett_text,
wavpath="/home/pi/dev/bossjones-github/scarlett-dbus-poc/espeak_tmp.wav")
logger.info('FINISHED PLAYING INTRO')
tts_list = None
command_run = False
return True

# 1. play sound first
wavefile = SoundType.get_path(scarlett_sound)
run_player_result = run_player(player_generator_func)

# 2. Perform command
command_run_results = generator_commands.Command.check_cmd(command_tuple=v)

# 3. Verify it is not a command NO_OP
if command_run_results == '__SCARLETT_NO_OP__':
logger.error("__SCARLETT_NO_OP__")
return False

# 4. Scarlett Speaks
tts_list = SpeakerType.speaker_to_array(command_run_results)
run_speaker_result = run_speaker(speaker_generator_func)

# 5. Emit signal to reset keyword match ( need to implement this )
bus = SessionBus()
ss = bus.get("org.scarlett", object_path='/org/scarlett/Listener') # NOQA
time.sleep(1)
ss.emitListenerCancelSignal()
# 6. Finished call back
else:
logger.debug("THIS IS NOT A GLib.Variant: {} - TYPE {}".format(v, type(v)))

Expand Down

0 comments on commit 4ed9d74

Please sign in to comment.