Creating a Media Daemon for SUSI Smart Speaker

Creating a Media Daemon for SUSI Smart Speaker

A daemon in reference of operating systems is a computer program that runs as a background process rather than under direct control of the user. Various daemons are being used in SUSI smart speaker.

The following features have been created

  • Update Daemon
  • Media Discovery Daemon
  • Factory Reset Daemon

In this blog, we’ll be discussing the implementation of the Media Discovery Daemon

Media Discovery Daemon:

The SUSI Smart speaker will have an essential feature which will allow the Users to play music from their USB devices. Hence , a media daemon will be running which will detect a USB connection and then scan it’s contents checking for all the mp3 files and then create custom SUSI skills to allow SUSI Smart Speaker to play music from your USB device.


The Media Daemon was implemented in the following steps

1.UDEV Rules

We had to figure out a way to run our daemon as soon as the user inserted the USB storage and stop the daemon as soon as the USB storage was removed


So, we used UDEV rules to trigger the Media Daemon.


ACTION==“add”, KERNEL==“sd?”, SUBSYSTEM==“block”, ENV{ID_BUS}==“usb”, RUN=“/home/pi/SUSI.AI/susi_linux/media_daemon/”ACTION==“remove, KERNEL==“sd?”, SUBSYSTEM==“block”, ENV{ID_BUS}==“usb”, RUN=“/home/pi/SUSI.AI/susi_linux/media_daemon/”

The Udev rules trigger a script called ‘’  on USB detection and a script called ‘’ on USB removal.

2. Custom Skill Creation

As the USB connection is now detected ,a script is triggered which checks the presence of a  local SUSI server in the repo. If a local server instance is detected,a python script is triggered which parses through the USB mount point and checks for the list of mp3 files present in the storage device and then create a custom skill file in the local server instance.


media_daemon_folder = os.path.dirname(os.path.abspath(__file__))
base_folder = os.path.dirname(media_daemon_folder)
server_skill_folder = os.path.join(base_folder, ‘susi_server/susi_server/data/generic_skills/media_discovery’)
server_settings_folder = os.path.join(base_folder, ‘susi_server/susi_server/data/settings’)

def make_skill(): # pylint-enable
   name_of_usb = get_mount_points()
   x = name_of_usb[0]
   USB = name_of_usb[0]
   mp3_files = glob(“*.mp3”)
   f = open( media_daemon_folder +‘/custom_skill.txt’,‘w’)
   music_path = list()
   for mp in mp3_files:
       music_path.append(“{}”.format(USB[1]) + “/{}”.format(mp))

   song_list = ” “.join(music_path)
   skills = [‘play audio’,‘!console:Playing audio from your usb device’,‘{“actions”:[‘,‘{“type”:”audio_play”, “identifier_type”:”url”, “identifier”:”file://’+str(song_list) +‘”}’,‘]}’,‘eol’]
   for skill in skills:
       f.write(skill + ‘\n’)
   shutil.move( media_daemon_folder + ‘custom_skill.txt’, server_skill_folder)
   f2 = open(server_settings_folder + ‘’,‘a’)
   f2.write(‘local.mode = true’)

def get_usb_devices():
   sdb_devices = map(os.path.realpath, glob(‘/sys/block/sd*’))
   usb_devices = (dev for dev in sdb_devices
       if ‘usb’ in dev.split(‘/’)[5])
   return dict((os.path.basename(dev), dev) for dev in usb_devices)

def get_mount_points(devices=None):
   devices = devices or get_usb_devices() # if devices are None: get_usb_devices
   output = check_output([‘mount’]).splitlines() #nosec #pylint-disable type: ignore
   output = [tmp.decode(‘UTF-8’) for tmp in output ] # pytlint-enable
   def is_usb(path):
       return any(dev in path for dev in devices)
   usb_info = (line for line in output if is_usb(line.split()[0]))
   return [(info.split()[0], info.split()[2]) for info in usb_info] 


Now a custom skill file will be created in the local server instance by the name of `custom_skill.txt` and the user can play audio from USB by speaking the command ‘play audio’


3. Preparing for the Next USB insertion

Now if the User wants to update his/her music library or wants to use another USB storage device. The USB will be removed and hence the custom skill file is also deleted from the script ‘’ which is triggered via the UDEV rules

#! /bin/bash

SCRIPT_PATH=$(realpath $0)

cd $DIR_PATH/../susi_server/susi_server/data/generic_skills/media_discovery/

sudo rm custom_skill.txt  


This is how the Media Discovery Daemon works in SUSI Smart Speaker




gsoc, gsoc’18 , fossasia,, smart speaker, media daemon, susi skills

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.