Add Reboot and Shutdown Routes to your Pi Web Server


Description

This project continues to build on our Basic Web Server project. In the last post we added the ability to Pass Parameters to our HTML.

It can be useful to provide the ability to either Reboot or Shutdown your Pi through a web interface, especially if you’re running in a headless configuration with no monitor, mouse or keyboard attached. This project will provide you with the steps to add reboot and shutdown routes to your Pi Web Server that we created previously.

Parameters

This is some information about this project and the conditions under which it was done. If you try to replicate it in the future and it doesn’t work, you can evaluate these parameters to see if any changes between these and your configuration might have impacted your results. An example might be changes to future versions of Python or Flask.

  • Date: July 17, 2021
  • Skill: Beginner
  • Raspberry Pi Model(s): Zero-W, 3B+, 4B
  • OS: Raspberry Pi OS version 10 (Buster)
  • Python Version: 3.7.3
  • Flask Version: 1.0.2

Steps

  1. Let’s start by opening up our web server app (sample.py) in , Geany, Thonny or your favorite Python editor.
  1. Now add the following changes to your code:
from flask import Flask, render_template
from datetime import datetime
import io
import os

START_DATE = datetime.now().strftime('%m/%d/%y %I:%M:%S %p')

app = Flask(__name__)

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/healthcheck')
def healthcheck():
    curDateTime = datetime.now().strftime('%m/%d/%y %-I:%M:%S %p')

    # Report available disk space
    stat = os.statvfs('/home/pi')
    gbFree = '%0.2f GB' % (stat.f_bfree*stat.f_bsize/1024/1024/1024)

    # Report CPU Temp
    try:
        tFile = open('/sys/class/thermal/thermal_zone0/temp')
        temp = float(tFile.read())
        tempC = '%0.1f C' % (temp/1000)
        tempF = '%0.1f F' % ((temp/1000) * 1.8 + 32)
    except:
        tempC = 'ERR'
        tempF = 'ERR'

    tFile.close()

    return render_template('health.html', curDate=curDateTime, startDate=START_DATE, gbFree=gbFree, tempC=tempC, tempF=tempF)

@app.route('/reboot')
def reboot():
    ret = os.system('sudo reboot')
    return 'Rebooting'

@app.route('/shutdown')
def shutdown():
    ret = os.system('sudo shutdown -h now')
    return 'Shutting down'

if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0', port=5000)

You can see that these are pretty simple routes and you are probably already familiar with the commands. We are simply exposing them through a web interface so we don’t have to SSH or VNC in to the Pi to execute the commands. Also note that even though the routes have a return statement, which is required for each route, that code will never execute because of the OS commands above them. Once you execute the route in the browser, it will immediately lose the connection to the server.

  1. Next, open index.html and make the following changes to add the links to the new routes for convenient access.
<!DOCTYPE html>
<html>

<head>
  <style>
    body {
      background-color: lightblue;
      color: blue;
    }
  </style>
</head>

<body>
  <h1>My Webserver!</h1>
  <p><a href='/healthcheck'>Health Check</a></p>
  <p><a href='/reboot'>Reboot</a></p>
  <p><a href='/shutdown'>Shutdown</a></p>
</body>
</html>
  1. Reload in your browser and you should now have the following:

Summary

This was a pretty simple project but I have found it very useful, especially if I want to shut the Pi down but don’t want to SSH or VNC into it to do it, and you certainly don’t want to just pull the plug while it’s running. I have found the Reboot path less valuable, because I mostly want to use that when I’ve lost connection with the Pi, but of course you can’t execute the reboot route if you can’t talk to the server. In a future project, I’ll show you how to implement some self-monitoring and automatically reboot if the network connection is lost for a certain amount of time. Of course this is only useful if you also have the server configured to automatically start at boot, which I will cover in the next project.

Learn More

Raspberry Pi / Raspberry Pi OS

Python / HTML / CSS

Flask

Leave a Comment

Your email address will not be published. Required fields are marked *