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/autostart.sh”ACTION==“remove, KERNEL==“sd?”, SUBSYSTEM==“block”, ENV{ID_BUS}==“usb”, RUN=“/home/pi/SUSI.AI/susi_linux/media_daemon/autostop.sh” |
The Udev rules trigger a script called ‘autostart.sh’ on USB detection and a script called ‘autostop.sh’ 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() print(type(name_of_usb)) print(name_of_usb[0]) x = name_of_usb[0] os.chdir(‘{}’.format(x[1])) 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’) f.close() shutil.move( media_daemon_folder + ‘custom_skill.txt’, server_skill_folder) f2 = open(server_settings_folder + ‘customized_config.properties’,‘a’) f2.write(‘local.mode = true’) f2.close() 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 ‘autstop.sh’ which is triggered via the UDEV rules
#! /bin/bash SCRIPT_PATH=$(realpath $0) DIR_PATH=$(dirname $SCRIPT_PATH) 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
References
- https://github.com/fossasia/susi_linux
- https://linuxconfig.org/tutorial-on-how-to-write-basic-udev-rules-in-linux
- https://github.com/fossasia/susi_skill_cms
Tags
gsoc, gsoc’18 , fossasia, susi.ai, smart speaker, media daemon, susi skills