Close

Starting NixieBot on bootup

A project log for NixieBot

A neon faced, twitter connected, clock, social monitor and picture server

robin-bussellRobin Bussell 10/19/2016 at 21:560 Comments

One of those jobs that I have been meaning to get around to for ages is that of making sure that the NixieBot code would automatically be run whenever the pi was booted. Recently a couple of weekend power cuts that left the bot down for a few hours until I noticed its absence prompted me to get this task done.

First off, in normal operation nixiebot.py is run from a screen session. Screen is a text based window manager that allows command line processes to be run up, dismissed from view and then reattached to later to see what's going on or to interact with them. it's very handy indeed for a machine that has no keyboard or monitor that is only ever connected to by ssh session over the network. With screen you can start a process and terminate the terminal session without also terminating the process you ran from that session. Then later you can log back in and reattach to see what's going on with the process. It's a really handy utility that gets used in my day job all the time. So any script that aims to start nixiebot should start it in a screen session so that I can interact with it later if I want to change the clock routine's behavior.

To keep things neat we first need a script that will run up nixiebot, here it is:

#! /bin/bash
cd /home/pi/nixiebot
python3 nixiebot.py

Pretty straightforward, this script is what will be run in the screen session. I saved it as a file named startNixieBot.sh, put a copy in /usr/bin so that it is in the path and made it executable with:

chmod +x /usr/bin/startNixieBot.sh
so it can be invoked just by typing startNixieBot.sh from any directory.

The command to start up a screen session (named nixiebotScrn to identify it among any other screen sessions that might be running) and run the nixiebot code in it is this:

screen -S nixiebotScrn  -d -m startNixieBot.sh


So that deals with starting the code, what about stopping it? If you are at the console of nixiebot and type a 'q' then hit enter it will wrap up things nicely, terminating the connections to twitter's API in a polite fashion and closing down all the threads properly (more on those threads in a later log). So, rather than just killing the process, it would be good to send a 'q<cr>' sequence to nixiebot whenever the pi is being shut down.

Luckily screen has a way of doing this with the -X stuff command, here's how to stop the nixiebot that was started by the above command:

screen -S nixiebotScrn -p 0 -X stuff "q$(printf \\r)"

Notice the use of -S nixiebotScrn again so that the key gets sent to the right session. The rather abstract looking "q$(printf \\r)" is just shell script-ese for "q then the return key". I got this handy tip from this question on stackexchange. Stackexhange nearly always delivers the goods if you have a unix scripting question!

Having worked out the commands for startting and stopping a background nixiebot process from the command line, the next task is making sure that these commands get run on startup and shutdown.

There are a few ways of ensuring that a process runs on bootup with linux systems, the best way (IMHO) is to write a proper init script. If you go looking in /etc/init.d you'll find a whole bunch of scripts that deal with starting and stopping the various services that might be running on that machine. There are some nice refinements that distro builders have worked out over the years to make sure that services only get started when any other services that they depend on are ready and so on.

A little light googling produced a nice template script from here , all I had to do was edit the lines that actually did the work of starting and stopping the script plus change the descriptions in the header section.

#! /bin/sh
# /etc/init.d/nixiebot

### BEGIN INIT INFO
# Provides:          nixiebot
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Simple script to start nixiebot process at boot
# Description:       A simple script from www.stuffaboutcode.com which will start / stop a program a boot / shutdown.
### END INIT INFO

# If you want a command to always run, put it here

# Carry out specific functions when asked to by the system
case "$1" in
  start)
    echo "Starting nixiebot"
    # run application you want to start
    /usr/bin/screen -S nixiebotScrn  -d -m  startNixieBot.sh
    ;;
  stop)
    echo "Stopping nixiebot"
    # kill application you want to stop
    /usr/bin/screen -S nixiebotScrn -p 0 -X stuff "q$(printf \\r)"
    ;;
  *)
    echo "Usage: /etc/init.d/nixiebot {start|stop}"
    exit 1
    ;;
esac

exit 0

Nearly there! Once this file was created as /etc/init.d/nixiebot then made executable with :

chmod +x /etc/init.d/nixiebot
all that remains was to tell the init system on raspbian to run the file on startup with this command:
update-rc.d nixiebot defaults
And that's it, rebooting now runs nixibot up and shutdown terminates it properly (you can run into problems with twitter's API connection and rate limiting if you just crash out the code without terminating connections properly).

Discussions