Building the web dashboard

The first step is creating the html template for the dashboard. Our dashboard is going to enable controlling four appliances, that is, turn them on or off:

  1. In our dashboard, we need an htmltable where each row on the table represents a device, as follows:
       <table> 
<tr>
<td>
<input type="checkbox" name="relay"
value="relay_0">Motor</input> </br>
</td>
<td>
<input type="radio" name="state_0" value="On">On
</input>
<input type="radio" name="state_0" value="Off"
checked="checked">Off</input>
</td>
</table>
  1. In the preceding code snippet, each device state is encapsulated in a data cell <td>, each device is represented by a checkbox, and the device state is represented by an on/off radio button. For example, a motor is represented as follows:
       <td> 
<input type="checkbox" name="relay"
value="relay_0">Motor</input> </br>
</td>
<td>
<input type="radio" name="state_0" value="On">On
</input>
<input type="radio" name="state_0" value="Off"
checked="checked">Off</input>
</td>

On the dashboard, this would be represented as follows:

Device represented by a checkbox and radio button
  1. The table is encapsulated in an html form:
       <form action="/energize" method="POST"> 
<table>
.
.
.
</table>
</form>
  1. The device states are submitted to the flask server when the user hits the energize button:
       <input type="submit" value="Energize" class="button">
Energize button
  1. On the server side, we need to set up the GPIO pins used to control the relays:
       NUM_APPLIANCES = 4 

relay_index = [2, 3, 4, 14]
  1. The list relay_index represents the GPIO pins being used to control the relays.
  2. Before starting the server, we need to create an OutputDevice object (from the gpiozero module) for all the devices:
       for i in range(NUM_APPLIANCES): 
devices.append(OutputDevice(relay_index[i],
active_high=False))
  1. The OutputDevice object meant for each device/relay is initialized and added to the devices list.
  2. When the form is submitted (by hitting the energize button), the POST request is handled by the energize() method.
  3. We are controlling four devices that are represented by relay_x, and their corresponding states are represented by state_x, that is, On or Off. The default state is Off.
  4. When a form is submitted by the user, we determine if the POST request contains information related to each device. If a specific device needs to be turned on/off, we call the on()/off() method of that device's object:
       relays = request.form.getlist("relay") 
for idx in range(0, NUM_APPLIANCES):
device_name = "relay_" + str(idx)
if device_name in relays:
device_state = "state_" + str(idx)
state = request.form.get(device_state)
print(state)
if state == "On":
print(state)
devices[idx].on()
elif state == "Off":
print(state)
devices[idx].off()
  1. In the preceding code snippet, we fetch information related to all relays as a list:
       relays = request.form.getlist("relay")
  1. In the form, each device is represented by a value relay_x (relay_0 through relay_3). A for loop is used to determine a specific relay is turned on/off. The state of each device is represented by the value state_x where x corresponds to the device (from 0 through 3).
  2. The GPIO pins used in this example are connected to the relay board pins, IN1 through IN4. The relay board is powered by the Raspberry Pi's GPIO power supply. Alternatively, you may power it using an external power supply. (You still need to connect the ground pin of the Raspberry Pi Zero to the relay board.)
  3. The earlier-mentioned dashboard is available along with this chapter under the subfolder flask_framework_appliance (including the flask server, html files, and so on.). In the following snapshot, the Motor and Tank Light 2 are checked and set to On. In the picturehere, the first and the third relay are energized.
Turning on Motor and Tank Light 2
Relays 1 and 3 energized

Exercise for the reader:

In this section, we made use of a POST request to control devices. How would you make use of a GET request to display room temperature from a temperature sensor?

Project ideas/enhancements: