1
1
mirror of https://github.com/OpenVoiceOS/OpenVoiceOS synced 2025-04-24 07:17:21 +02:00

MycroftOS: Mycroft A.I. service package

- Systemd support for Mycroft A.I.
- Remove old init.d system files
- Update start/stop-mycroft.sh files
This commit is contained in:
Peter Steenbergen 2019-02-04 12:55:48 +01:00
parent f0711f0972
commit 032566548a
10 changed files with 157 additions and 113 deletions

View File

@ -1,3 +1,6 @@
menu "Mycroft A.I. Personal Assistant"
source "$BR2_EXTERNAL_MYCROFTOS_PATH/package/python-mycroft/Config.in"
source "$BR2_EXTERNAL_MYCROFTOS_PATH/package/mycroft-service/Config.in"
menu "Additional drivers, libraries and/or applications" menu "Additional drivers, libraries and/or applications"
source "$BR2_EXTERNAL_MYCROFTOS_PATH/package/fann/Config.in" source "$BR2_EXTERNAL_MYCROFTOS_PATH/package/fann/Config.in"
source "$BR2_EXTERNAL_MYCROFTOS_PATH/package/respeaker/Config.in" source "$BR2_EXTERNAL_MYCROFTOS_PATH/package/respeaker/Config.in"
@ -28,7 +31,6 @@ menu "Additional external python modules"
source "$BR2_EXTERNAL_MYCROFTOS_PATH/package/python-monotonic/Config.in" source "$BR2_EXTERNAL_MYCROFTOS_PATH/package/python-monotonic/Config.in"
source "$BR2_EXTERNAL_MYCROFTOS_PATH/package/python-msk/Config.in" source "$BR2_EXTERNAL_MYCROFTOS_PATH/package/python-msk/Config.in"
source "$BR2_EXTERNAL_MYCROFTOS_PATH/package/python-msm/Config.in" source "$BR2_EXTERNAL_MYCROFTOS_PATH/package/python-msm/Config.in"
source "$BR2_EXTERNAL_MYCROFTOS_PATH/package/python-mycroft/Config.in"
source "$BR2_EXTERNAL_MYCROFTOS_PATH/package/python-oauth2client/Config.in" source "$BR2_EXTERNAL_MYCROFTOS_PATH/package/python-oauth2client/Config.in"
source "$BR2_EXTERNAL_MYCROFTOS_PATH/package/python-olefile/Config.in" source "$BR2_EXTERNAL_MYCROFTOS_PATH/package/python-olefile/Config.in"
source "$BR2_EXTERNAL_MYCROFTOS_PATH/package/python-padaos/Config.in" source "$BR2_EXTERNAL_MYCROFTOS_PATH/package/python-padaos/Config.in"
@ -54,3 +56,4 @@ menu "Additional external python modules"
source "$BR2_EXTERNAL_MYCROFTOS_PATH/package/python-xmlrunner/Config.in" source "$BR2_EXTERNAL_MYCROFTOS_PATH/package/python-xmlrunner/Config.in"
source "$BR2_EXTERNAL_MYCROFTOS_PATH/package/python-xxhash/Config.in" source "$BR2_EXTERNAL_MYCROFTOS_PATH/package/python-xxhash/Config.in"
endmenu endmenu
endmenu

View File

@ -184,6 +184,8 @@ BR2_PACKAGE_HOST_PYTHON_CYTHON=y
BR2_PACKAGE_HOST_PYTHON_LXML=y BR2_PACKAGE_HOST_PYTHON_LXML=y
BR2_PACKAGE_HOST_PYTHON_SIX=y BR2_PACKAGE_HOST_PYTHON_SIX=y
BR2_PACKAGE_HOST_PYTHON_XLRD=y BR2_PACKAGE_HOST_PYTHON_XLRD=y
BR2_PACKAGE_PYTHON_MYCROFT=y
BR2_PACKAGE_MYCROFT_SERVICE=y
BR2_PACKAGE_FANN=y BR2_PACKAGE_FANN=y
BR2_PACKAGE_RESPEAKER=y BR2_PACKAGE_RESPEAKER=y
BR2_PACKAGE_PYTHON_ADAPT_PARSER=y BR2_PACKAGE_PYTHON_ADAPT_PARSER=y
@ -198,7 +200,6 @@ BR2_PACKAGE_PYTHON_GTTS=y
BR2_PACKAGE_PYTHON_HUMANHASH3=y BR2_PACKAGE_PYTHON_HUMANHASH3=y
BR2_PACKAGE_PYTHON_INFLECTION=y BR2_PACKAGE_PYTHON_INFLECTION=y
BR2_PACKAGE_PYTHON_MSK=y BR2_PACKAGE_PYTHON_MSK=y
BR2_PACKAGE_PYTHON_MYCROFT=y
BR2_PACKAGE_PYTHON_OAUTH2CLIENT=y BR2_PACKAGE_PYTHON_OAUTH2CLIENT=y
BR2_PACKAGE_PYTHON_OLEFILE=y BR2_PACKAGE_PYTHON_OLEFILE=y
BR2_PACKAGE_PYTHON_PADATIOUS=y BR2_PACKAGE_PYTHON_PADATIOUS=y

View File

@ -0,0 +1,6 @@
config BR2_PACKAGE_MYCROFT_SERVICE
bool "mycroft-service"
help
Start the Mycroft A.I. software as service.
https://mycroft.ai/

View File

@ -0,0 +1,27 @@
################################################################################
#
# mycroft-service
#
################################################################################
MYCROFT_SERVICE_VERSION = 0.1.0
MYCROFT_SERVICE_SITE = $(BR2_EXTERNAL_MYCROFTOS_PATH)/package/mycroft-service
MYCROFT_SERVICE_SITE_METHOD = local
MYCROFT_SERVICE_LICENSE = Apache License 2.0
MYCROFT_SERVICE_LICENSE_FILES = LICENSE
define MYCROFT_SERVICE_USERS
mycroft -1 mycroft -1 mycroft /home/mycroft /bin/bash audio,pulse,pulse-access
endef
define MYCROFT_SERVICE_INSTALL_TARGET_CMDS
$(INSTALL) -m 0755 $(@D)/start-mycroft.sh $(TARGET_DIR)/usr/bin/
$(INSTALL) -m 0755 $(@D)/stop-mycroft.sh $(TARGET_DIR)/usr/bin/
$(INSTALL) -D -m 644 $(@D)/mycroft.service \
$(TARGET_DIR)/usr/lib/systemd/system/mycroft.service
mkdir -p $(TARGET_DIR)/etc/systemd/system/multi-user.target.wants
ln -fs ../../../../usr/lib/systemd/system/mycroft.service \
$(TARGET_DIR)/etc/systemd/system/multi-user.target.wants/mycroft.service
endef
$(eval $(generic-package))

View File

@ -0,0 +1,15 @@
[Unit]
Description=Mycroft AI
After=pulseaudio.service
[Service]
User=mycroft
WorkingDirectory=/home/mycroft
ExecStart=start-mycroft.sh all
ExecStop=stop-mycroft.sh all
Type=forking
Restart=always
RestartSec=3
[Install]
WantedBy=multi-user.target

View File

@ -23,31 +23,34 @@ DIR="$( pwd )"
function help() { function help() {
echo "${script}: Mycroft command/service launcher" echo "${script}: Mycroft command/service launcher"
echo "usage: ${script} [command] [params]" echo "usage: ${script} [COMMAND] [restart] [params]"
echo echo
echo "Services:" echo "Services COMMANDs:"
echo " all runs core services: bus, audio, skills, voice" echo " all runs core services: bus, audio, skills, voice"
echo " debug runs core services, then starts the CLI" echo " debug runs core services, then starts the CLI"
echo
echo "Services:"
echo " audio the audio playback service" echo " audio the audio playback service"
echo " bus the messagebus service" echo " bus the messagebus service"
echo " skills the skill service" echo " skills the skill service"
echo " voice voice capture service" echo " voice voice capture service"
# echo " wifi wifi setup service"
echo " enclosure mark_1 enclosure service" echo " enclosure mark_1 enclosure service"
echo echo
echo "Tools:" echo "Tool COMMANDs:"
echo " cli the Command Line Interface" echo " cli the Command Line Interface"
echo " unittest run mycroft-core unit tests (requires pytest)" echo " unittest run mycroft-core unit tests (requires pytest)"
echo " skillstest run the skill autotests for all skills (requires pytest)" echo " skillstest run the skill autotests for all skills (requires pytest)"
echo echo
echo "Utils:" echo "Util COMMANDs:"
echo " audiotest attempt simple audio validation" echo " audiotest attempt simple audio validation"
echo " audioaccuracytest more complex audio validation" echo " audioaccuracytest more complex audio validation"
echo " sdkdoc generate sdk documentation" echo " sdkdoc generate sdk documentation"
echo echo
echo "Options:"
echo " restart (optional) Force the service to restart if running"
echo
echo "Examples:" echo "Examples:"
echo " ${script} all" echo " ${script} all"
echo " ${script} all restart"
echo " ${script} cli" echo " ${script} cli"
echo " ${script} unittest" echo " ${script} unittest"
@ -72,7 +75,32 @@ function name-to-script-path() {
esac esac
} }
first_time=true
# set the right locale / language settings
export LC_ALL=en_US.UTF-8
export LANG=en_US.UTF-8
export LANGUAGE=en_US.UTF-8
function init-once() {
if ($first_time) ; then
echo "Initializing..."
# Check if Mycroft log folders are present and if not
# create those logging folders
if [[ ! -w /var/log/mycroft/ ]] ; then
# Creating needed folders
printf "Creating /var/log/mycroft/ directory"
if [[ ! -d /var/log/mycroft/ ]] ; then
mkdir /var/log/mycroft/
fi
fi
first_time=false
fi
}
function launch-process() { function launch-process() {
init-once
name-to-script-path ${1} name-to-script-path ${1}
# Launch process in foreground # Launch process in foreground
@ -80,12 +108,28 @@ function launch-process() {
python3 -m ${_module} $_params python3 -m ${_module} $_params
} }
function require-process() {
# Launch process if not found
name-to-script-path ${1}
if ! pgrep -f "python3 -m ${_module}" > /dev/null ; then
# Start required process
launch-background ${1}
fi
}
function launch-background() { function launch-background() {
init-once
# Check if given module is running and start (or restart if running) # Check if given module is running and start (or restart if running)
name-to-script-path ${1} name-to-script-path ${1}
if pgrep -f "python3 -m ${_module}" > /dev/null ; then if pgrep -f "python3 -m ${_module}" > /dev/null ; then
if ($_force_restart) ; then
echo "Restarting: ${1}" echo "Restarting: ${1}"
"${DIR}/stop-mycroft.sh" ${1} "${DIR}/stop-mycroft.sh" ${1}
else
# Already running, no need to restart
return
fi
else else
echo "Starting background service $1" echo "Starting background service $1"
fi fi
@ -107,25 +151,27 @@ function launch-all() {
launch-background skills launch-background skills
launch-background audio launch-background audio
launch-background voice launch-background voice
# Determine platform type
if [[ -r /etc/mycroft/mycroft.conf ]] ; then
mycroft_platform=$( jq -r ".enclosure.platform" < /etc/mycroft/mycroft.conf )
if [[ $mycroft_platform = "mycroft_mark_1" ]] ; then
# running on a Mark 1, start enclosure service
launch-background enclosure launch-background enclosure
fi
fi
} }
_opt=$1 _opt=$1
_force_restart=false
shift shift
if [[ "${1}" == "restart" ]] || [[ "${_opt}" == "restart" ]] ; then
_force_restart=true
if [[ "${_opt}" == "restart" ]] ; then
# Support "start-mycroft.sh restart all" as well as "start-mycroft.sh all restart"
_opt=$1
fi
shift
fi
_params=$@ _params=$@
case ${_opt} in case ${_opt} in
"all") "all")
launch-all launch-all
;; ;;
"bus") "bus")
launch-background ${_opt} launch-background ${_opt}
;; ;;
@ -138,24 +184,51 @@ case ${_opt} in
"voice") "voice")
launch-background ${_opt} launch-background ${_opt}
;; ;;
"debug") "debug")
launch-all launch-all
launch-process cli launch-process cli
;; ;;
"cli") "cli")
require-process bus
require-process skills
launch-process ${_opt} launch-process ${_opt}
;; ;;
# TODO: Restore support for Wifi Setup on a Picroft, etc.
# "wifi")
# launch-background ${_opt}
# ;;
"unittest")
source-venv
pytest test/unittests/ --cov=mycroft "$@"
;;
"singleunittest")
source-venv
pytest "$@"
;;
"skillstest")
source-venv
pytest test/integrationtests/skills/discover_tests.py "$@"
;;
"audiotest") "audiotest")
launch-process ${_opt} launch-process ${_opt}
;; ;;
"audioaccuracytest") "audioaccuracytest")
launch-process ${_opt} launch-process ${_opt}
;; ;;
"sdkdoc")
source-venv
cd doc
make ${opt}
cd ..
;;
"enclosure") "enclosure")
launch-background ${_opt} launch-background ${_opt}
;; ;;
*) *)
help help
;; ;;
esac esac

View File

@ -31,7 +31,7 @@ function help() {
echo " audio stop the audio playback service" echo " audio stop the audio playback service"
echo " skills stop the skill service" echo " skills stop the skill service"
echo " voice stop voice capture service" echo " voice stop voice capture service"
echo " enclosure stop mark_1 enclosure service" echo " enclosure stop enclosure (hardware/gui interface) service"
echo echo
echo "Examples:" echo "Examples:"
echo " ${script}" echo " ${script}"
@ -50,8 +50,9 @@ function process-running() {
function end-process() { function end-process() {
if process-running $1 ; then if process-running $1 ; then
echo -n "Stopping $1..." # Find the process by name, only returning the oldest if it has children
pid=$( pgrep -f "python3 -m mycroft.*${1}" ) pid=$( pgrep -o -f "python3 -m mycroft.*${1}" )
echo -n "Stopping $1 (${pid})..."
kill -SIGINT ${pid} kill -SIGINT ${pid}
# Wait up to 5 seconds (50 * 0.1) for process to stop # Wait up to 5 seconds (50 * 0.1) for process to stop
@ -67,7 +68,8 @@ function end-process() {
if process-running $1 ; then if process-running $1 ; then
echo "failed to stop." echo "failed to stop."
echo -n " Killing $1..." pid=$( pgrep -o -f "python3 -m mycroft.*${1}" )
echo -n " Killing $1 (${pid})..."
kill -9 ${pid} kill -9 ${pid}
echo "killed." echo "killed."
result=120 result=120
@ -80,8 +82,10 @@ function end-process() {
fi fi
} }
result=0 # default, no change result=0 # default, no change
OPT=$1 OPT=$1
shift shift
@ -94,15 +98,7 @@ case ${OPT} in
end-process skills end-process skills
end-process audio end-process audio
end-process speech end-process speech
# determine platform type
if [[ -r /etc/mycroft/mycroft.conf ]] ; then
mycroft_platform=$( jq -r ".enclosure.platform" < /etc/mycroft/mycroft.conf )
if [[ $mycroft_platform == "mycroft_mark_1" ]] ; then
# running on a Mark 1, stop enclosure service
end-process enclosure end-process enclosure
fi
fi
;; ;;
"bus") "bus")
end-process messagebus.service end-process messagebus.service
@ -119,6 +115,7 @@ case ${OPT} in
"enclosure") "enclosure")
end-process enclosure end-process enclosure
;; ;;
*) *)
help help
;; ;;

View File

@ -7,6 +7,6 @@
PYTHON_MYCROFT_VERSION = v18.8.12 PYTHON_MYCROFT_VERSION = v18.8.12
PYTHON_MYCROFT_SITE = $(call github,MycroftAI,mycroft-core,release/$(PYTHON_MYCROFT_VERSION)) PYTHON_MYCROFT_SITE = $(call github,MycroftAI,mycroft-core,release/$(PYTHON_MYCROFT_VERSION))
PYTHON_MYCROFT_SETUP_TYPE = setuptools PYTHON_MYCROFT_SETUP_TYPE = setuptools
PYTHON_MYCROFT_LICENSE_FILES = PYTHON_MYCROFT_LICENSE_FILES = LICENSE
$(eval $(python-package)) $(eval $(python-package))

View File

@ -1,41 +0,0 @@
#!/bin/sh
#
# Prepare Mycroft software stack.
#
start() {
# set the right locale / language settings
export LC_ALL=en_US.UTF-8
export LANG=en_US.UTF-8
export LANGUAGE=en_US.UTF-8
# Check if Mycroft log folders are present and if not
# create those logging folders
if [[ ! -w /var/log/mycroft/ ]] ; then
# Creating needed folders
printf "Creating /var/log/mycroft/ directory"
if [[ ! -d /var/log/mycroft/ ]] ; then
mkdir /var/log/mycroft/
fi
fi
# Check if /.mycroft exist already and if not
# create a symbolic link to /root/.mycroft
if [[ ! -w /.mycroft/ ]] ; then
# Creating .mycroft symlink
printf "Creating /.mycroft/ symlink"
if [[ ! -d /.mycroft/ ]] ; then
ln -s /root/.mycroft /.mycroft
fi
fi
}
case "$1" in
start)
start
;;
*)
echo "Usage: $0 {start}"
exit 1
esac
exit $?

View File

@ -1,37 +0,0 @@
#!/bin/sh
#
# Starts Mycroft services.
#
start() {
printf "Starting Mycroft services: "
umask 077
bash /usr/bin/start-mycroft.sh all
echo "OK"
}
stop() {
printf "Stopping Mycroft services: "
bash /usr/bin/stop-mycroft.sh all
echo "OK"
}
restart() {
stop
start
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart|reload)
restart
;;
*)
echo "Usage: $0 {start|stop|restart}"
exit 1
esac
exit $?