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
This commit is contained in:
Родитель
fa3d078b7c
Коммит
b9f2d93a3f
|
@ -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 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. 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. 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
|
||||
|
||||
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 pynmea2
|
||||
import json
|
||||
from azure.iot.device import IoTHubDeviceClient, Message
|
||||
|
||||
connection_string = '<connection_string>'
|
||||
|
||||
serial = serial.Serial('/dev/ttyAMA0', 9600, timeout=1)
|
||||
serial.reset_input_buffer()
|
||||
serial.flush()
|
||||
|
||||
device_client = IoTHubDeviceClient.create_from_connection_string(connection_string)
|
||||
|
||||
print('Connecting')
|
||||
device_client.connect()
|
||||
print('Connected')
|
||||
|
||||
def printGPSData(line):
|
||||
def print_gps_data(line):
|
||||
msg = pynmea2.parse(line)
|
||||
if msg.sentence_type == 'GGA':
|
||||
lat = pynmea2.dm_to_sd(msg.lat)
|
||||
|
@ -28,16 +19,13 @@ def printGPSData(line):
|
|||
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)
|
||||
print(f'{lat},{lon} - from {msg.num_sats} satellites')
|
||||
|
||||
while True:
|
||||
line = serial.readline().decode('utf-8')
|
||||
|
||||
while len(line) > 0:
|
||||
printGPSData(line)
|
||||
print_gps_data(line)
|
||||
line = serial.readline().decode('utf-8')
|
||||
|
||||
time.sleep(1)
|
||||
|
|
|
@ -5,18 +5,11 @@ import time
|
|||
import counterfit_shims_serial
|
||||
import pynmea2
|
||||
import json
|
||||
from azure.iot.device import IoTHubDeviceClient, Message
|
||||
|
||||
connection_string = '<connection_string>'
|
||||
|
||||
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):
|
||||
msg = pynmea2.parse(line)
|
||||
if msg.sentence_type == 'GGA':
|
||||
|
@ -29,10 +22,7 @@ def send_gps_data(line):
|
|||
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)
|
||||
print(f'{lat},{lon} - from {msg.num_sats} satellites')
|
||||
|
||||
while True:
|
||||
line = serial.readline().decode('utf-8')
|
||||
|
@ -41,4 +31,4 @@ while True:
|
|||
send_gps_data(line)
|
||||
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.flush()
|
||||
|
||||
def printGPSData():
|
||||
def print_gps_data():
|
||||
print(line.rstrip())
|
||||
|
||||
while True:
|
||||
line = serial.readline().decode('utf-8')
|
||||
|
||||
while len(line) > 0:
|
||||
printGPSData()
|
||||
print_gps_data()
|
||||
line = serial.readline().decode('utf-8')
|
||||
|
||||
time.sleep(1)
|
||||
|
|
|
@ -6,14 +6,14 @@ import counterfit_shims_serial
|
|||
|
||||
serial = counterfit_shims_serial.Serial('/dev/ttyAMA0')
|
||||
|
||||
def printGPSData(line):
|
||||
def print_gps_data(line):
|
||||
print(line.rstrip())
|
||||
|
||||
while True:
|
||||
line = serial.readline().decode('utf-8')
|
||||
|
||||
while len(line) > 0:
|
||||
printGPSData(line)
|
||||
print_gps_data(line)
|
||||
line = serial.readline().decode('utf-8')
|
||||
|
||||
time.sleep(1)
|
|
@ -118,14 +118,14 @@ Program the device.
|
|||
serial.reset_input_buffer()
|
||||
serial.flush()
|
||||
|
||||
def printGPSData(line):
|
||||
def print_gps_data(line):
|
||||
print(line.rstrip())
|
||||
|
||||
while True:
|
||||
line = serial.readline().decode('utf-8')
|
||||
|
||||
while len(line) > 0:
|
||||
printGPSData(line)
|
||||
print_gps_data(line)
|
||||
line = serial.readline().decode('utf-8')
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ Program the device to decode the GPS data.
|
|||
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
|
||||
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:
|
||||
|
||||
```python
|
||||
def printGPSData(line):
|
||||
def print_gps_data(line):
|
||||
print(line.rstrip())
|
||||
|
||||
while True:
|
||||
line = serial.readline().decode('utf-8')
|
||||
|
||||
while len(line) > 0:
|
||||
printGPSData(line)
|
||||
print_gps_data(line)
|
||||
line = serial.readline().decode('utf-8')
|
||||
|
||||
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.
|
||||
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
import time
|
||||
from grove.adc import ADC
|
||||
from grove.grove_relay import GroveRelay
|
||||
import serial
|
||||
import pynmea2
|
||||
import json
|
||||
from azure.iot.device import IoTHubDeviceClient, Message, MethodResponse
|
||||
from azure.iot.device import IoTHubDeviceClient, Message
|
||||
|
||||
connection_string = '<connection_string>'
|
||||
|
||||
adc = ADC()
|
||||
relay = GroveRelay(5)
|
||||
serial = serial.Serial('/dev/ttyAMA0', 9600, timeout=1)
|
||||
serial.reset_input_buffer()
|
||||
serial.flush()
|
||||
|
||||
device_client = IoTHubDeviceClient.create_from_connection_string(connection_string)
|
||||
|
||||
|
@ -15,24 +16,28 @@ print('Connecting')
|
|||
device_client.connect()
|
||||
print('Connected')
|
||||
|
||||
def handle_method_request(request):
|
||||
print("Direct method received - ", request.name)
|
||||
|
||||
if request.name == "relay_on":
|
||||
relay.on()
|
||||
elif request.name == "relay_off":
|
||||
relay.off()
|
||||
def print_gps_data(line):
|
||||
msg = pynmea2.parse(line)
|
||||
if msg.sentence_type == 'GGA':
|
||||
lat = pynmea2.dm_to_sd(msg.lat)
|
||||
lon = pynmea2.dm_to_sd(msg.lon)
|
||||
|
||||
method_response = MethodResponse.create_from_method_request(request, 200)
|
||||
device_client.send_method_response(method_response)
|
||||
if msg.lat_dir == 'S':
|
||||
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:
|
||||
soil_moisture = adc.read(0)
|
||||
print("Soil moisture:", soil_moisture)
|
||||
line = serial.readline().decode('utf-8')
|
||||
|
||||
message = Message(json.dumps({ 'soil_moisture': soil_moisture }))
|
||||
device_client.send_message(message)
|
||||
while len(line) > 0:
|
||||
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)
|
||||
|
||||
import time
|
||||
from counterfit_shims_grove.adc import ADC
|
||||
from counterfit_shims_grove.grove_relay import GroveRelay
|
||||
import counterfit_shims_serial
|
||||
import pynmea2
|
||||
import json
|
||||
from azure.iot.device import IoTHubDeviceClient, Message, MethodResponse
|
||||
from azure.iot.device import IoTHubDeviceClient, Message
|
||||
|
||||
connection_string = '<connection_string>'
|
||||
|
||||
adc = ADC()
|
||||
relay = GroveRelay(5)
|
||||
serial = counterfit_shims_serial.Serial('/dev/ttyAMA0')
|
||||
|
||||
device_client = IoTHubDeviceClient.create_from_connection_string(connection_string)
|
||||
|
||||
|
@ -18,24 +17,28 @@ print('Connecting')
|
|||
device_client.connect()
|
||||
print('Connected')
|
||||
|
||||
def handle_method_request(request):
|
||||
print("Direct method received - ", request.name)
|
||||
|
||||
if request.name == "relay_on":
|
||||
relay.on()
|
||||
elif request.name == "relay_off":
|
||||
relay.off()
|
||||
def send_gps_data(line):
|
||||
msg = pynmea2.parse(line)
|
||||
if msg.sentence_type == 'GGA':
|
||||
lat = pynmea2.dm_to_sd(msg.lat)
|
||||
lon = pynmea2.dm_to_sd(msg.lon)
|
||||
|
||||
method_response = MethodResponse.create_from_method_request(request, 200)
|
||||
device_client.send_method_response(method_response)
|
||||
if msg.lat_dir == 'S':
|
||||
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:
|
||||
soil_moisture = adc.read(0)
|
||||
print("Soil moisture:", soil_moisture)
|
||||
line = serial.readline().decode('utf-8')
|
||||
|
||||
message = Message(json.dumps({ 'soil_moisture': soil_moisture }))
|
||||
device_client.send_message(message)
|
||||
while len(line) > 0:
|
||||
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
|
||||
|
||||
![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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
**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).
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
||||
* [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/)
|
||||
* Microphone and speaker:
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче