You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
98 lines
4.2 KiB
98 lines
4.2 KiB
3 years ago
|
# Set a timer - Virtual IoT Hardware and Raspberry Pi
|
||
|
|
||
|
In this part of the lesson, you will set a timer on your virtual IoT device or Raspberry Pi based off a command from the IoT Hub.
|
||
|
|
||
|
## Set a timer
|
||
|
|
||
|
The command sent from the serverless function contains the time for the timer in seconds as the payload. This time can be used to set a timer.
|
||
|
|
||
|
Timers can be set using the Python `threading.Timer` class. This class takes a delay time and a function, and after the delay time, the function is executed.
|
||
|
|
||
|
### Task - set a timer
|
||
|
|
||
|
1. Open the `smart-timer` project in VS Code, and ensure the virtual environment is loaded in the terminal if you are using a virtual IoT device.
|
||
|
|
||
|
1. Add the following import statement at the top of the file to import the threading Python library:
|
||
|
|
||
|
```python
|
||
|
import threading
|
||
|
```
|
||
|
|
||
|
1. Above the `handle_method_request` function that handles the method request, add a function to speak a response. Fow now this will just write to the console, but later in this lesson this will speak the text.
|
||
|
|
||
|
```python
|
||
|
def say(text):
|
||
|
print(text)
|
||
|
```
|
||
|
|
||
|
1. Below this add a function that will be called by a timer to announce that the timer is complete:
|
||
|
|
||
|
```python
|
||
|
def announce_timer(minutes, seconds):
|
||
|
announcement = 'Times up on your '
|
||
|
if minutes > 0:
|
||
|
announcement += f'{minutes} minute'
|
||
|
if seconds > 0:
|
||
|
announcement += f'{seconds} second'
|
||
|
announcement += ' timer.'
|
||
|
say(announcement)
|
||
|
```
|
||
|
|
||
|
This function takes the number of minutes and seconds for the timer, and builds a sentence to say that the timer is complete. It will check the number of minutes and seconds, and only include each time unit if it has a number. For example, if the number of minutes is 0 then only seconds are included in the message. This sentence is then sent to the `say` function.
|
||
|
|
||
|
1. Below this, add the following `create_timer` function to create a timer:
|
||
|
|
||
|
```python
|
||
|
def create_timer(seconds):
|
||
|
minutes, seconds = divmod(seconds, 60)
|
||
|
threading.Timer(seconds, announce_timer, args=[minutes, seconds]).start()
|
||
|
```
|
||
|
|
||
|
This function takes the total number of seconds for the timer that will be sent in the command, and converts this to minutes and seconds. It then creates and starts a timer object using the total number of seconds, passing in the `announce_timer` function and a list containing the minutes and seconds. When the timer elapses, it will call the `announce_timer` function, and pass the contents of this list as the parameters - so the first item in the list gets passes as the `minutes` parameter, and the second item as the `seconds` parameter.
|
||
|
|
||
|
1. To the end of the `create_timer` function, add some code to build a message to be spoken to the user to announce that the timer is starting:
|
||
|
|
||
|
```python
|
||
|
announcement = ''
|
||
|
if minutes > 0:
|
||
|
announcement += f'{minutes} minute'
|
||
|
if seconds > 0:
|
||
|
announcement += f'{seconds} second'
|
||
|
announcement += ' timer started.'
|
||
|
say(announcement)
|
||
|
```
|
||
|
|
||
|
Again, this only includes the time unit that has a value. This sentence is then sent to the `say` function.
|
||
|
|
||
|
1. At the start of the `handle_method_request` function, add the following code to check that the `set-timer` direct method was requested:
|
||
|
|
||
|
```python
|
||
|
if request.name == 'set-timer':
|
||
|
```
|
||
|
|
||
|
1. Inside this `if` statement, extract the timer time in seconds from the payload and use this to create a timer:
|
||
|
|
||
|
```python
|
||
|
payload = json.loads(request.payload)
|
||
|
seconds = payload['seconds']
|
||
|
if seconds > 0:
|
||
|
create_timer(payload['seconds'])
|
||
|
```
|
||
|
|
||
|
The timer is only created if the number of seconds is greater than 0
|
||
|
|
||
|
1. Run the app, and ensure the function app is also running. Set some timers, and the output will show the timer being set, and then will show when it elapses:
|
||
|
|
||
|
```output
|
||
|
pi@raspberrypi:~/smart-timer $ python3 app.py
|
||
|
Connecting
|
||
|
Connected
|
||
|
Set a one minute 4 second timer.
|
||
|
1 minute, 4 second timer started
|
||
|
Times up on your 1 minute, 4 second timer
|
||
|
```
|
||
|
|
||
|
> 💁 You can find this code in the [code-timer/pi](code-timer/pi) or [code-timer/virtual-iot-device](code-timer/virtual-iot-device) folder.
|
||
|
|
||
|
😀 Your timer program was a success!
|