Fixing some code and adding names (#110)

* Adding content

* Update en.json

* Update README.md

* Update TRANSLATIONS.md

* Adding lesson tempolates

* Fixing code files with each others code in

* Update README.md

* Adding lesson 16

* Adding virtual camera

* Adding Wio Terminal camera capture

* Adding wio terminal code

* Adding SBC classification to lesson 16

* Adding challenge, review and assignment

* Adding images and using new Azure icons

* Update README.md

* Update iot-reference-architecture.png

* Adding structure for JulyOT links

* Removing icons

* Sketchnotes!

* Create lesson-1.png

* Starting on lesson 18

* Updated sketch

* Adding virtual distance sensor

* Adding Wio Terminal image classification

* Update README.md

* Adding structure for project 6 and wio terminal distance sensor

* Adding some of the smart timer stuff

* Updating sketchnotes

* Adding virtual device speech to text

* Adding chapter 21

* Language tweaks

* Lesson 22 stuff

* Update en.json

* Bumping seeed libraries

* Adding functions lab to lesson 22

* Almost done with LUIS

* Update README.md

* Reverting sunlight sensor change

Fixes #88

* Structure

* Adding speech to text lab for Pi

* Adding virtual device text to speech lab

* Finishing lesson 23

* Clarifying privacy

Fixes #99

* Update README.md

* Update hardware.md

* Update README.md

* Fixing some code samples that were wrong
pull/116/head
Jim Bennett 3 years ago committed by GitHub
parent fa3d078b7c
commit b9f2d93a3f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -192,6 +192,23 @@ The Azure Functions CLI can be used to create a new Functions app.
> ⚠️ If you get a firewall notification, grant access as the `func` application needs to be able to read and write to your network. > ⚠️ If you get a firewall notification, grant access as the `func` application needs to be able to read and write to your network.
> ⚠️ If you are using macOS, there may be warnings in the output:
>
> ```output
> (.venv) ➜ soil-moisture-trigger func start
> Found Python version 3.9.1 (python3).
>
> Azure Functions Core Tools
> Core Tools Version: 3.0.3442 Commit hash: 6bfab24b2743f8421475d996402c398d2fe4a9e0 (64-bit)
> Function Runtime Version: 3.0.15417.0
>
> [2021-06-16T08:18:28.315Z] Cannot create directory for shared memory usage: /dev/shm/AzureFunctions
> [2021-06-16T08:18:28.316Z] System.IO.FileSystem: Access to the path '/dev/shm/AzureFunctions' is denied. Operation not permitted.
> [2021-06-16T08:18:30.361Z] No job functions found.
> ```
>
> You can ignore these as long as the Functions app starts correctly and lists the running functions. As mentioned in [this question on the Microsoft Docs Q&A](https://docs.microsoft.com/answers/questions/396617/azure-functions-core-tools-error-osx-devshmazurefu.html?WT.mc_id=academic-17441-jabenn) it can be ignored.
1. Stop the Functions app by pressing `ctrl+c`. 1. Stop the Functions app by pressing `ctrl+c`.
1. Open the current folder in VS Code, either by opening VS Code, then opening this folder, or by running the following: 1. Open the current folder in VS Code, either by opening VS Code, then opening this folder, or by running the following:
@ -213,23 +230,6 @@ The Azure Functions CLI can be used to create a new Functions app.
1. Make sure the Python virtual environment is running in the VS Code terminal. Terminate it and restart it if necessary. 1. Make sure the Python virtual environment is running in the VS Code terminal. Terminate it and restart it if necessary.
1. There may be warnings in the output:
```output
(.venv) ➜ soil-moisture-trigger func start
Found Python version 3.9.1 (python3).
Azure Functions Core Tools
Core Tools Version: 3.0.3442 Commit hash: 6bfab24b2743f8421475d996402c398d2fe4a9e0 (64-bit)
Function Runtime Version: 3.0.15417.0
[2021-06-16T08:18:28.315Z] Cannot create directory for shared memory usage: /dev/shm/AzureFunctions
[2021-06-16T08:18:28.316Z] System.IO.FileSystem: Access to the path '/dev/shm/AzureFunctions' is denied. Operation not permitted.
[2021-06-16T08:18:30.361Z] No job functions found.
```
but don't worry about them as long as the Functions app starts correctly and lists the running functions. As mentioned in this question on the [Docs Q&A](https://docs.microsoft.com/answers/questions/396617/azure-functions-core-tools-error-osx-devshmazurefu.html?WT.mc_id=academic-17441-jabenn) it can be ignored.
## Create an IoT Hub event trigger ## Create an IoT Hub event trigger
The Functions app is the shell of your serverless code. To respond to IoT hub events, you can add an IoT Hub trigger to this app. This trigger needs to connect to the stream of messages that are sent to the IoT Hub and respond to them. To get this stream of messages, your trigger needs to connect to the IoT Hubs *event hub compatible endpoint*. The Functions app is the shell of your serverless code. To respond to IoT hub events, you can add an IoT Hub trigger to this app. This trigger needs to connect to the stream of messages that are sent to the IoT Hub and respond to them. To get this stream of messages, your trigger needs to connect to the IoT Hubs *event hub compatible endpoint*.

@ -2,21 +2,12 @@ import time
import serial import serial
import pynmea2 import pynmea2
import json import json
from azure.iot.device import IoTHubDeviceClient, Message
connection_string = '<connection_string>'
serial = serial.Serial('/dev/ttyAMA0', 9600, timeout=1) serial = serial.Serial('/dev/ttyAMA0', 9600, timeout=1)
serial.reset_input_buffer() serial.reset_input_buffer()
serial.flush() serial.flush()
device_client = IoTHubDeviceClient.create_from_connection_string(connection_string) def print_gps_data(line):
print('Connecting')
device_client.connect()
print('Connected')
def printGPSData(line):
msg = pynmea2.parse(line) msg = pynmea2.parse(line)
if msg.sentence_type == 'GGA': if msg.sentence_type == 'GGA':
lat = pynmea2.dm_to_sd(msg.lat) lat = pynmea2.dm_to_sd(msg.lat)
@ -28,16 +19,13 @@ def printGPSData(line):
if msg.lon_dir == 'W': if msg.lon_dir == 'W':
lon = lon * -1 lon = lon * -1
message_json = { "gps" : { "lat":lat, "lon":lon } } print(f'{lat},{lon} - from {msg.num_sats} satellites')
print("Sending telemetry", message_json)
message = Message(json.dumps(message_json))
device_client.send_message(message)
while True: while True:
line = serial.readline().decode('utf-8') line = serial.readline().decode('utf-8')
while len(line) > 0: while len(line) > 0:
printGPSData(line) print_gps_data(line)
line = serial.readline().decode('utf-8') line = serial.readline().decode('utf-8')
time.sleep(1) time.sleep(1)

@ -5,18 +5,11 @@ import time
import counterfit_shims_serial import counterfit_shims_serial
import pynmea2 import pynmea2
import json import json
from azure.iot.device import IoTHubDeviceClient, Message
connection_string = '<connection_string>' connection_string = '<connection_string>'
serial = counterfit_shims_serial.Serial('/dev/ttyAMA0') serial = counterfit_shims_serial.Serial('/dev/ttyAMA0')
device_client = IoTHubDeviceClient.create_from_connection_string(connection_string)
print('Connecting')
device_client.connect()
print('Connected')
def send_gps_data(line): def send_gps_data(line):
msg = pynmea2.parse(line) msg = pynmea2.parse(line)
if msg.sentence_type == 'GGA': if msg.sentence_type == 'GGA':
@ -29,10 +22,7 @@ def send_gps_data(line):
if msg.lon_dir == 'W': if msg.lon_dir == 'W':
lon = lon * -1 lon = lon * -1
message_json = { "gps" : { "lat":lat, "lon":lon } } print(f'{lat},{lon} - from {msg.num_sats} satellites')
print("Sending telemetry", message_json)
message = Message(json.dumps(message_json))
device_client.send_message(message)
while True: while True:
line = serial.readline().decode('utf-8') line = serial.readline().decode('utf-8')
@ -41,4 +31,4 @@ while True:
send_gps_data(line) send_gps_data(line)
line = serial.readline().decode('utf-8') line = serial.readline().decode('utf-8')
time.sleep(60) time.sleep(1)

@ -5,14 +5,14 @@ serial = serial.Serial('/dev/ttyAMA0', 9600, timeout=1)
serial.reset_input_buffer() serial.reset_input_buffer()
serial.flush() serial.flush()
def printGPSData(): def print_gps_data():
print(line.rstrip()) print(line.rstrip())
while True: while True:
line = serial.readline().decode('utf-8') line = serial.readline().decode('utf-8')
while len(line) > 0: while len(line) > 0:
printGPSData() print_gps_data()
line = serial.readline().decode('utf-8') line = serial.readline().decode('utf-8')
time.sleep(1) time.sleep(1)

@ -6,14 +6,14 @@ import counterfit_shims_serial
serial = counterfit_shims_serial.Serial('/dev/ttyAMA0') serial = counterfit_shims_serial.Serial('/dev/ttyAMA0')
def printGPSData(line): def print_gps_data(line):
print(line.rstrip()) print(line.rstrip())
while True: while True:
line = serial.readline().decode('utf-8') line = serial.readline().decode('utf-8')
while len(line) > 0: while len(line) > 0:
printGPSData(line) print_gps_data(line)
line = serial.readline().decode('utf-8') line = serial.readline().decode('utf-8')
time.sleep(1) time.sleep(1)

@ -118,14 +118,14 @@ Program the device.
serial.reset_input_buffer() serial.reset_input_buffer()
serial.flush() serial.flush()
def printGPSData(line): def print_gps_data(line):
print(line.rstrip()) print(line.rstrip())
while True: while True:
line = serial.readline().decode('utf-8') line = serial.readline().decode('utf-8')
while len(line) > 0: while len(line) > 0:
printGPSData(line) print_gps_data(line)
line = serial.readline().decode('utf-8') line = serial.readline().decode('utf-8')
time.sleep(1) time.sleep(1)
@ -133,9 +133,9 @@ Program the device.
This code imports the `serial` module from the `pyserial` Pip package. It then connects to the `/dev/ttyAMA0` serial port - this is the address of the serial port that the Grove Pi Base Hat uses for its UART port. It then clears any existing data from this serial connection. This code imports the `serial` module from the `pyserial` Pip package. It then connects to the `/dev/ttyAMA0` serial port - this is the address of the serial port that the Grove Pi Base Hat uses for its UART port. It then clears any existing data from this serial connection.
Next a function called `printGPSData` is defined that prints out the line passed to it to the console. Next a function called `print_gps_data` is defined that prints out the line passed to it to the console.
Next the code loops forever, reading as many lines of text as it can from the serial port in each loop. It calls the `printGPSData` function for each line. Next the code loops forever, reading as many lines of text as it can from the serial port in each loop. It calls the `print_gps_data` function for each line.
After all the data has been read, the loop sleeps for 1 second, then tries again. After all the data has been read, the loop sleeps for 1 second, then tries again.

@ -24,7 +24,7 @@ Program the device to decode the GPS data.
import pynmea2 import pynmea2
``` ```
1. Replace the contents of the `printGPSData` function with the following: 1. Replace the contents of the `print_gps_data` function with the following:
```python ```python
msg = pynmea2.parse(line) msg = pynmea2.parse(line)

@ -77,22 +77,22 @@ Program the GPS sensor app.
1. Add the following code below this to read from the serial port and print the values to the console: 1. Add the following code below this to read from the serial port and print the values to the console:
```python ```python
def printGPSData(line): def print_gps_data(line):
print(line.rstrip()) print(line.rstrip())
while True: while True:
line = serial.readline().decode('utf-8') line = serial.readline().decode('utf-8')
while len(line) > 0: while len(line) > 0:
printGPSData(line) print_gps_data(line)
line = serial.readline().decode('utf-8') line = serial.readline().decode('utf-8')
time.sleep(1) time.sleep(1)
``` ```
A function called `printGPSData` is defined that prints out the line passed to it to the console. A function called `print_gps_data` is defined that prints out the line passed to it to the console.
Next the code loops forever, reading as many lines of text as it can from the serial port in each loop. It calls the `printGPSData` function for each line. Next the code loops forever, reading as many lines of text as it can from the serial port in each loop. It calls the `print_gps_data` function for each line.
After all the data has been read, the loop sleeps for 1 second, then tries again. After all the data has been read, the loop sleeps for 1 second, then tries again.

@ -1,13 +1,14 @@
import time import time
from grove.adc import ADC import serial
from grove.grove_relay import GroveRelay import pynmea2
import json import json
from azure.iot.device import IoTHubDeviceClient, Message, MethodResponse from azure.iot.device import IoTHubDeviceClient, Message
connection_string = '<connection_string>' connection_string = '<connection_string>'
adc = ADC() serial = serial.Serial('/dev/ttyAMA0', 9600, timeout=1)
relay = GroveRelay(5) serial.reset_input_buffer()
serial.flush()
device_client = IoTHubDeviceClient.create_from_connection_string(connection_string) device_client = IoTHubDeviceClient.create_from_connection_string(connection_string)
@ -15,24 +16,28 @@ print('Connecting')
device_client.connect() device_client.connect()
print('Connected') print('Connected')
def handle_method_request(request): def print_gps_data(line):
print("Direct method received - ", request.name) msg = pynmea2.parse(line)
if msg.sentence_type == 'GGA':
if request.name == "relay_on": lat = pynmea2.dm_to_sd(msg.lat)
relay.on() lon = pynmea2.dm_to_sd(msg.lon)
elif request.name == "relay_off":
relay.off()
method_response = MethodResponse.create_from_method_request(request, 200) if msg.lat_dir == 'S':
device_client.send_method_response(method_response) lat = lat * -1
device_client.on_method_request_received = handle_method_request if msg.lon_dir == 'W':
lon = lon * -1
message_json = { "gps" : { "lat":lat, "lon":lon } }
print("Sending telemetry", message_json)
message = Message(json.dumps(message_json))
device_client.send_message(message)
while True: while True:
soil_moisture = adc.read(0) line = serial.readline().decode('utf-8')
print("Soil moisture:", soil_moisture)
message = Message(json.dumps({ 'soil_moisture': soil_moisture })) while len(line) > 0:
device_client.send_message(message) print_gps_data(line)
line = serial.readline().decode('utf-8')
time.sleep(10) time.sleep(60)

@ -2,15 +2,14 @@ from counterfit_connection import CounterFitConnection
CounterFitConnection.init('127.0.0.1', 5000) CounterFitConnection.init('127.0.0.1', 5000)
import time import time
from counterfit_shims_grove.adc import ADC import counterfit_shims_serial
from counterfit_shims_grove.grove_relay import GroveRelay import pynmea2
import json import json
from azure.iot.device import IoTHubDeviceClient, Message, MethodResponse from azure.iot.device import IoTHubDeviceClient, Message
connection_string = '<connection_string>' connection_string = '<connection_string>'
adc = ADC() serial = counterfit_shims_serial.Serial('/dev/ttyAMA0')
relay = GroveRelay(5)
device_client = IoTHubDeviceClient.create_from_connection_string(connection_string) device_client = IoTHubDeviceClient.create_from_connection_string(connection_string)
@ -18,24 +17,28 @@ print('Connecting')
device_client.connect() device_client.connect()
print('Connected') print('Connected')
def handle_method_request(request): def send_gps_data(line):
print("Direct method received - ", request.name) msg = pynmea2.parse(line)
if msg.sentence_type == 'GGA':
if request.name == "relay_on": lat = pynmea2.dm_to_sd(msg.lat)
relay.on() lon = pynmea2.dm_to_sd(msg.lon)
elif request.name == "relay_off":
relay.off()
method_response = MethodResponse.create_from_method_request(request, 200) if msg.lat_dir == 'S':
device_client.send_method_response(method_response) lat = lat * -1
device_client.on_method_request_received = handle_method_request if msg.lon_dir == 'W':
lon = lon * -1
message_json = { "gps" : { "lat":lat, "lon":lon } }
print("Sending telemetry", message_json)
message = Message(json.dumps(message_json))
device_client.send_message(message)
while True: while True:
soil_moisture = adc.read(0) line = serial.readline().decode('utf-8')
print("Soil moisture:", soil_moisture)
message = Message(json.dumps({ 'soil_moisture': soil_moisture })) while len(line) > 0:
device_client.send_message(message) send_gps_data(line)
line = serial.readline().decode('utf-8')
time.sleep(10) time.sleep(60)

@ -2,7 +2,9 @@
Add a sketchnote if possible/appropriate Add a sketchnote if possible/appropriate
![Embed a video here if available](video-url) This video gives an overview of the Azure speech services, covering speech to text and text to speech from earlier lessons, as well as translating speech, a topic covered in this lesson:
[![Recognizing speech with a few lines of Python from Microsoft Build 2020](https://img.youtube.com/vi/h6xbpMPSGEA/0.jpg)](https://www.youtube.com/watch?v=h6xbpMPSGEA)
## Pre-lecture quiz ## Pre-lecture quiz

@ -20,9 +20,9 @@ The projects cover the journey of food from farm to table. This includes farming
![A road map for the course showing 24 lessons covering intro, farming, transport, processing, retail and cooking](sketchnotes/Roadmap.png) ![A road map for the course showing 24 lessons covering intro, farming, transport, processing, retail and cooking](sketchnotes/Roadmap.png)
**Hearty thanks to our authors [Jen Fox](https://github.com/jenfoxbot), [Jen Looper](https://github.com/jlooper), [Jim Bennett](https://github.com/jimbobbennett), and our sketchnote artist [Nitya Narasimhan](https://github.com/nitya)** **Hearty thanks to our authors [Jen Fox](https://github.com/jenfoxbot), [Jen Looper](https://github.com/jlooper), [Jim Bennett](https://github.com/jimbobbennett), and our sketchnote artist [Nitya Narasimhan](https://github.com/nitya).**
**Thanks as well to our team of [Microsoft Learn Student Ambassadors](https://studentambassadors.microsoft.com?WT.mc_id=academic-17441-jabenn) who have been reviewing and translating this curriculum - [Manvi Jha](https://github.com/Severus-Matthew), [Mireille Tan](https://www.linkedin.com/in/mireille-tan-a4834819a/), [Mohammad Iftekher (Iftu) Ebne Jalal](https://github.com/Iftu119), [Priyanshu Srivastav](https://www.linkedin.com/in/priyanshu-srivastav-b067241ba), and [Zina Kamel](https://www.linkedin.com/in/zina-kamel/)** **Thanks as well to our team of [Microsoft Learn Student Ambassadors](https://studentambassadors.microsoft.com?WT.mc_id=academic-17441-jabenn) who have been reviewing and translating this curriculum - [Bhavesh Suneja](https://github.com/EliteWarrior315), [Lateefah Bello](https://www.linkedin.com/in/lateefah-bello/), [Manvi Jha](https://github.com/Severus-Matthew), [Mireille Tan](https://www.linkedin.com/in/mireille-tan-a4834819a/), [Mohammad Iftekher (Iftu) Ebne Jalal](https://github.com/Iftu119), [Priyanshu Srivastav](https://www.linkedin.com/in/priyanshu-srivastav-b067241ba), and [Zina Kamel](https://www.linkedin.com/in/zina-kamel/).**
> **Teachers**, we have [included some suggestions](for-teachers.md) on how to use this curriculum. If you would like to create your own lessons, we have also included a [lesson template](lesson-template/README.md). > **Teachers**, we have [included some suggestions](for-teachers.md) on how to use this curriculum. If you would like to create your own lessons, we have also included a [lesson template](lesson-template/README.md).

@ -46,7 +46,7 @@ All the device code for Raspberry Pi is in Python. To complete all the assignmen
These are specific to using the Raspberry Pi, and are not relevant to using the Arduino device. These are specific to using the Raspberry Pi, and are not relevant to using the Arduino device.
* [Grove Pi base hat](https://wiki.seeedstudio.com/Grove_Base_Hat_for_Raspberry_Pi) * [Grove Pi base hat](https://www.seeedstudio.com/Grove-Base-Hat-for-Raspberry-Pi.html)
* [Raspberry Pi Camera module](https://www.raspberrypi.org/products/camera-module-v2/) * [Raspberry Pi Camera module](https://www.raspberrypi.org/products/camera-module-v2/)
* Microphone and speaker: * Microphone and speaker:

Loading…
Cancel
Save