A quick blog post about how I managed my music via Kalliope :)
The basic idea is simple: I want to ask Kalliope to play music for me, and manage spotify playlist/search and radio
To do this, I need: - Kalliope installed - Kalliope MPD module installed - Mopidy server (to act like a MPD server and manage spotify and radio source)
I wanted to have a simple flow:
Me: "I want to listen to music"
Kalliope: "Of course, what do you want to listen to?"
Me:
Option 1:
Me: "My favorite spotify playlist"
Kalliope: "Ok, starting your favorite playlist"
Option 2:
Me: "spotify playlist <Name Of a playlist>"
Kalliope: "Ok, launching <Name of a playlist>"
Option 3:
Me: "I want to listen to the radio"
Kalliope: Which radio sir?
Me: "<radio name>"
Kalliope: "launching radio <radio name>"
Option 4:
Me: "music from <artist name>"
Kalliope: "searching for music of <artist name>"
Option 5:
Me: "I'll try some fashion music"
Kalliope: "Starting some fashion music"
Installation
Kalliope
First, install Kalliope. For this, follow the documentation. Once it’s done and working, install the MPD neuron as indicated on the README.
We’ll get to the brain configuration in the next step.
Mopidy server
Then, you need to install mopidy. Either on the same device as Kalliope or on another one. For this, same as above, follow the documentation :)
If you have the same use cases as me, and want to plug spotify and the radio, you will also need to install mopidy-spotify, tunein, and spotify_tunigo and of corse the core mpd backend.
Mon fichier de conf .config/mopidy/mopidy.conf
pour exemple:
[mpd]
enabled = true
hostname = 127.0.0.1
port = 8080
password = MyPassword
max_connections = 10
connection_timeout = 60
zeroconf = Mopidy MPD server on $hostname
command_blacklist = listall,listallinfo
default_playlist_scheme = m3u
[core]
cache_dir = $XDG_CACHE_DIR/mopidy
config_dir = $XDG_CONFIG_DIR/mopidy
data_dir = $XDG_DATA_DIR/mopidy
max_tracklist_length = 10000
restore_state = false
[logging]
color = true
console_format = %(levelname)-8s %(message)s
debug_format = %(levelname)-8s %(asctime)s [%(process)d:%(threadName)s] %(name)s\n %(message)s
debug_file = mopidy.log
config_file =
[spotify]
username = MyLogin
password = MyPassword
enabled = true
bitrate = 320
timeout = 100
client_id = MyClientId
client_secret = MyClientSecret
[spotify_tunigo]
enabled: true
[tunein]
timeout = 5000
PS: You need to adapt the hostname if your mopidy server is not installed on the same machine as Kalliope!, see mopidy hostname configuration here.
Configuring the brain
The first question
Let’s create a new brain file called mpd.yml
in your brains directory,
and configure the first step of the flow:
- name: "ask-and-play-music"
signals:
- order: "I want to listen to music"
neurons:
- say:
message: "Of course, what do you want to listen to?"
- neurotransmitter:
from_answer_link:
- synapse: "play-favorite-spotify-playlist"
answers:
- "My favorite spotify playlist"
- synapse: "play-asked-spotify-playlist"
answers:
- "spotify playlist {{query}}"
- synapse: "play-fashion-music"
answers:
- "I'll try some fashion music"
- synapse: "play-asked-radio"
answers:
- "I want to listen to the radio"
- synapse: "play-asked-music"
answers:
- "search for {{query}}"
default: "didnt-understand"
So here we have the first step for our full flow. Kalliope is asking what kind of music I want to listen to, and depending on my answer, different synapse will be triggered.
Now I need to define the actions for each of these choices.
Managing options and anwsers
Playing my favorite playlist
That’s easy, just like said in the doc of the neuron:
- name: "play-favorite-spotify-playlist"
signals:
- order: "start my favorite spotify playlist"
neurons:
- kalliopempd:
mpd_action: "playlist"
mpd_url: "{{mpd_url}}"
mpd_port: "{{mpd_port}}"
mpd_password: "{{mpd_password}}"
mpd_random: "1"
mpd_volume: "50"
query: "{{favorite_playlist_name}}"
- say:
message: "Ok, starting your favorite playlist"
I could give a “no_order” but I might want to fire this playlist directly so I gave a correct order.
Please note that I’m using the brackets because I’m using the variables capability of kalliope
Playing a playlist
- name: "play-asked-spotify-playlist"
signals:
- order: "start playlist {{query}}"
neurons:
- kalliopempd:
mpd_action: "playlist"
mpd_url: "{{mpd_url}}"
mpd_port: "{{mpd_port}}"
mpd_password: "{{mpd_password}}"
mpd_random: "1"
mpd_volume: "50"
query: "{{query}}"
- say:
message: "Ok, starting the playlist {{query}}"
Asking and playing a radio
First, lets configure kalliope so it ask which radio I want to listen to:
- name: "play-asked-radio"
signals:
- order: "I want to listen to the radio"
neurons:
- say:
message: "Which radio sir?"
- neurotransmitter:
from_answer_link:
- synapse: "play-radio"
answers:
- "{{query}}"
default: "didnt-understand"
Then, create the brain that will actually start the radio:
- name: "play-radio"
signals:
- order: "play-radio-no-order"
neurons:
- kalliopempd:
mpd_action: "search"
mpd_url: "{{mpd_url}}"
mpd_port: "{{mpd_port}}"
mpd_password: "{{mpd_password}}"
mpd_random: "0"
query: "{{query}}"
- say:
message: "Launching radio {{query}}"
Please note that I’m using the brackets because I’m using the variables capability of kalliope
Asking and playing any music
Same as the favorite playlist:
- name: "play-asked-music"
signals:
- order: "search music {{query}}"
neurons:
- kalliopempd:
mpd_action: "search"
mpd_url: "{{mpd_url}}"
mpd_port: "{{mpd_port}}"
mpd_password: "{{mpd_password}}"
mpd_random: "0"
query: "{{query}}"
- say:
message: "Launching some music of {{query}}"
Please note that I’m using the brackets because I’m using the variables capability of kalliope
Didn’t understand synapse
This is just to let me know if something went wrong and Kalliope didn’t understand:
- name: "didnt-understand"
signals:
- order: "didnt-understand"
neurons:
- say:
message: "I'm terribly sorry sir, but something went wrong…"
Don’t forget to add your new brain file in the brain.yml via an include and your variable in a loaded file :)
The full brain file:
- name: "ask-and-play-music"
signals:
- order: "I want to listen to music"
neurons:
- say:
message: "Of course, what do you want to listen to?"
- neurotransmitter:
from_answer_link:
- synapse: "play-favorite-spotify-playlist"
answers:
- "My favorite spotify playlist"
- synapse: "play-asked-spotify-playlist"
answers:
- "spotify playlist {{query}}"
- synapse: "play-fashion-music"
answers:
- "I'll try some fashion music"
- synapse: "play-asked-radio"
answers:
- "I want to listen to the radio"
- synapse: "play-asked-music"
answers:
- "search for {{query}}"
default: "didnt-understand"
- name: "play-favorite-spotify-playlist"
signals:
- order: "start my favorite spotify playlist"
neurons:
- kalliopempd:
mpd_action: "playlist"
mpd_url: "{{mpd_url}}"
mpd_port: "{{mpd_port}}"
mpd_password: "{{mpd_password}}"
mpd_random: "1"
mpd_volume: "50"
query: "{{favorite_playlist_name}}"
- say:
message: "Ok, starting your favorite playlist"
- name: "play-asked-spotify-playlist"
signals:
- order: "start playlist {{query}}"
neurons:
- kalliopempd:
mpd_action: "playlist"
mpd_url: "{{mpd_url}}"
mpd_port: "{{mpd_port}}"
mpd_password: "{{mpd_password}}"
mpd_random: "1"
mpd_volume: "50"
query: "{{query}}"
- say:
message: "Ok, starting the playlist {{query}}"
- name: "play-asked-radio"
signals:
- order: "I want to listen to the radio"
neurons:
- say:
message: "Which radio sir?"
- neurotransmitter:
from_answer_link:
- synapse: "play-radio"
answers:
- "{{query}}"
default: "didnt-understand"
- name: "play-radio"
signals:
- order: "play-radio-no-order"
neurons:
- kalliopempd:
mpd_action: "search"
mpd_url: "{{mpd_url}}"
mpd_port: "{{mpd_port}}"
mpd_password: "{{mpd_password}}"
mpd_random: "0"
query: "{{query}}"
- say:
message: "Launching radio {{query}}"
- name: "play-asked-music"
signals:
- order: "search music {{query}}"
neurons:
- kalliopempd:
mpd_action: "search"
mpd_url: "{{mpd_url}}"
mpd_port: "{{mpd_port}}"
mpd_password: "{{mpd_password}}"
mpd_random: "0"
query: "{{query}}"
- say:
message: "Launching some music of {{query}}"
- name: "didnt-understand"
signals:
- order: "didnt-understand"
neurons:
- say:
message: "I'm terribly sorry sir, but something went wrong…"
Kalliope reminder with snooze kalliopereminder
Quick blog post to talk about how I setup Kalliope to remind me stuff, but with a snooze feature.
The default setup of the neurotimer let you ask Kalliope to remind you stuff after some time (minutes or hours).
I really like it because I have a poor short term memory, so when I have something to do in 30min, I use the kalliope neurotimer module to help me remember… But sometime, I want Kalliope to remind me again after 5 min because I didn’t have the time to do at the time Kalliope reminded me.
Let’s take a real life use case:
Let’s say I am in a game (starcraft2 fan here ^^) and someone is calling
me. When in a game, I can’t (don’t want to) pick up the phone, but I
want to remember to call back the person. For this I’m using the
neurotimer to do so, with a sentence like
"Remind me in XX minutes to YYY"
.
This is the default setup explained in the neurotimer README file here.
But that is not enough for me, because I may be still in game when being reminded by Kalliope, so I want to have the ability to tell kalliope to remind me again in X minutes, without re-asking the full order like before.
The workflow I want:
Me: "Kalliope… remind me in 10 minutes to call back dad"
Kalliope: "I'll remind you in 10 minutes to call back dad"
[… 10minutes later …]
Kalliope: "You asked me to remind you call back dad"
Kalliope: "Do you want me to remind you again?"
option1: (I want another reminder)
Me: "Yes"
Kalliope: "When?"
Me: "In 5 minutes"
[… 5 minutes later …]
Kalliope: "You asked me to remind you to call back dad"
*Option: Again, I'm in a sort of a loop here, so as long as I say "yes", it will remind me again until I say no (or anything other than yes).*
Option2:
Me: "No"
Kalliope: "Ok, I won't remind you again."
So how does it work? I’m using the Neurotimer module, with the Neurotransmitter and the Kalliope memory to do so.
It does bring a limitation though, as you can’t have multi reminder with “snooze” as the memory will only remember the last one.
My configuration to do so is the following:
Brain file:
{% raw %}
---
- name: "reminder-synapse"
signals:
- order: "remind me to {{ remember }} in {{ time }} minutes"
neurons:
- neurotimer:
minutes: "{{ time }}"
synapse: "reminder-todo"
forwarded_parameters:
remember: "{{ remember }}"
kalliope_memory:
reminder_2: "{{ remember }}"
- say:
message:
- "Ok sir, reminder setup"
- name: "reminder-todo"
signals:
- order: "reminder_todo_no_order"
neurons:
- say:
message:
- "Sir, you asked me to remind you to {{ remember }}"
- say:
message: "Do you want me to remind you again ?"
- neurotransmitter:
from_answer_link:
- synapse: "reminder2"
answers:
- "oui"
- synapse: "no-response"
answers:
- "non"
default: "no-response"
- name: "reminder2"
signals:
- order: "reminder2-no-order"
neurons:
- say:
message: "When do I have to remind you to {{ kalliope_memory['reminder_2'] }} ?"
- neurotransmitter:
from_answer_link:
- synapse: "reminder-via-memory"
answers:
- "in {{time}} minutes"
- synapse: "reminder-via-memory"
answers:
- "dans {{time}} minutes"
default: "no-response"
- name: "reminder-via-memory"
signals:
- order: "reminder-via-memory-no-order"
neurons:
- neurotimer:
minutes: "{{ time }}"
synapse: "reminder-todo"
forwarded_parameters:
remember: "{{ kalliope_memory['reminder_2'] }}"
- say:
message:
- "Ok, I'll remind you in {{time}} minutes to {{ kalliope_memory['reminder_2'] }}"
{% endraw %}
Nota: The “no-response” is a default synapse I created that simply answer “ok sir” or something like this :).
And voilà :)