Raspberry Pi Activation Script

#!/usr/bin/env bash
# the preceding line instructs this script to run using the bash interpreter

# main function definition
perform_install()
{
  # echo: output a message to the screen
  echo 'Starting activation process...'

  # install nodejs (javascript runtime without a web browser)
  install_nodejs

  # install npm (node.js package manager)
  install_npm

  # install n (node.js version management)
  install_n

  # install nodejs 6.14.4
  install_nodejs_6_14_4

  # install ws node.js library
  install_ws

  # install rpio node.js library
  install_rpio

  # install pm2 to run the limitos javascript process via node
  install_pm2

  # download the limitos.js file
  download_limitos_js

  # start the limitos.js process
  start_limitos_js

  # output the registration information
  echo "Register this device within 5 minutes at https://limitos.com/register"
  echo "Registration code: $registration_auth_token"
}

# function to install nodejs
function install_nodejs()
{
  # check if nodejs is installed
  # command -v: outputs location of specified program, wc -l: count line numbers
  nodejs_installed=$(command -v nodejs | wc -l)

  # if nodejs is not installed (command location line count is zero)
  if [ $nodejs_installed -eq 0 ]
    # then execute the commands below
    then

      # output activation message
      echo 'node.js not found, installing...'

      # install version 6 of nodejs, and log output
      sudo curl -sL https://deb.nodesource.com/setup_6.x | sudo bash - &> 'limitos_install.log'

      # install nodejs, and log output
      sudo apt-get install -y nodejs &> 'limitos_install.log'

  # end the if statement
  fi

}

# function to install npm
function install_npm()
{
  # check if npm is installed
  npm_installed=$(command -v npm | wc -l)

  # if npm is not installed
  if [ $npm_installed -eq 0 ]
    # then execute the commands below
    then

      # output activation message
      echo 'npm not found, installing...'

      # install npm, and log output
      sudo apt-get install npm -y &> 'limitos_install.log'

  # end the if statement
  fi

}

# function to install n version management
function install_n()
{
  # check if n is installed
  # npm list --depth=0: show top-level node.js modules
  # 2> /dev/null: ignore npm list error output
  n_installed=$(npm list --depth=0 2> /dev/null | grep " n@" | wc -l)

  # if n is not installed
  if [ $n_installed -eq 0 ]
    # then execute the commands below
    then

      # output activation message
      echo 'n not found, installing...'

      # install n globally, and log output
      sudo npm install n -g &> 'limitos_install.log'

  # end the if statement
  fi

}


# function to install node.js version 6.14.4 (for compatibility with necessary libraries)
function install_nodejs_6_14_4()
{
    # output activation message
    echo 'installing node.js v6.14.4...'

    # install nodejs v6.14.4, and log output
    sudo n install 6.14.4 &> 'limitos_install.log'

}

# function to install node.js websocket libary (ws)
function install_ws()
{
  # check if ws is installed
  # npm list --depth=0: show top-level node.js modules
  # 2> /dev/null: ignore npm list error output
  ws_installed=$(npm list --depth=0 2> /dev/null | grep " ws@6.2.1" | wc -l)

  # if ws is not installed
  if [ $ws_installed -eq 0 ]
    # then execute the commands below
    then

      # output activation message
      echo 'ws not found, installing...'

      # install ws, and log output
      sudo npm install ws@6.2.1 &> 'limitos_install.log'

  # end the if statement
  fi

}

# function to install node.js gpio library for the raspberry pi (rpio)
function install_rpio()
{
  # check if rpio is installed
  # npm list --depth=0: show top-level node.js modules
  # 2> /dev/null: ignore npm list error output
  rpio_installed=$(npm list --depth=0 2> /dev/null | grep " rpio@" | wc -l)

  # if rpio is not installed
  if [ $rpio_installed -eq 0 ]
    # then execute the commands below
    then

      # output activation message
      echo 'rpio not found, installing...'

      # install rpio, and log output
      sudo npm install rpio &> 'limitos_install.log'

  # end the if statement
  fi

}

# function to install pm2
function install_pm2()
{
  # check if pm2 is installed
  pm2_installed=$(command -v pm2 | wc -l)

  # if pm2 is not installed
  if [ $pm2_installed -eq 0 ]
    # then execute the commands below
    then

      # output activation message
      echo 'pm2 not found, installing...'

      # install pm2
      sudo npm install pm2@2.9.3 -g &> 'limitos_install.log'

  # end the if statement
  fi

}

# function to download limitos.js
function download_limitos_js()
{
  # create a new device and save the auth_token as device_json
  # curl: request a remote url, -s: silent, -S: show errors, -L: follow redirects, -X POST: use a HTTP POST request
  device_json=$(curl -sSL -X POST https://limitos.com/api/v1/devices)

  # get the device id from the JSON
  # grep: search, -P: use Perl regular expressions, -o: only output the match, '"id":(\d*)': look for "id":(digits)
  # awk: pattern manipulation, -F':': separate by ':', print $2: print the second match
  device_id=$(echo $device_json | grep -Po '"id":(\d*)' | awk -F':' '{print $2}')

  # get the auth token from the JSON
  # '"auth_token":.*?[^\\]"': look for "auth_token":"xxxxxx", tr -d '"': delete quotes
  device_auth_token=$(echo $device_json | grep -Po '"auth_token":.*?[^\\]"' | awk -F':' '{print $2}' | tr -d '"')

  # get a new registration code (using the device auth_token)
  registration_json=$(curl -sSL --data "auth_token=$device_auth_token" https://limitos.com/api/v1/devices/$device_id/registrations)

  # get the auth token from the JSON
  registration_auth_token=$(echo $registration_json | grep -Po '"auth_token":.*?[^\\]"' | awk -F':' '{print $2}' | tr -d '"')

  # retrieve the nodejs script and save it as limitos.js
  curl -sS --data "auth_token=$device_auth_token" https://limitos.com/api/v1/devices/$device_id/nodejs_script > limitos_unverified.js

  # if the file is valid
  if node --check limitos_unverified.js
    # then execute the commands below
    then

      # move the file
      mv limitos_unverified.js limitos.js

  # end the if statement
  fi
}

# function to start the limitos.js process
function start_limitos_js()
{
  # output message
  echo 'starting limitos.js process...'

  # stop any previously running limitos.js processes
  sudo pm2 stop limitos.js &> 'limitos_install.log'

  # start the limitos.js node script, -s: silent mode
  sudo pm2 -s start limitos.js

  # save the current limitos.js process
  sudo pm2 -s save

  # start pm2 when server is started, and log output
  sudo pm2 startup &> 'limitos_install.log'
}

# run the main function
perform_install