From 8d7ab238debb8daee28ca1b738cdd56cc78fcfe9 Mon Sep 17 00:00:00 2001 From: Jim Bennett Date: Sat, 19 Jun 2021 11:19:54 -0700 Subject: [PATCH] Fixing some code samples that were wrong --- .../README.md | 34 +++++++------- .../code-gps-decode/pi/gps-sensor/app.py | 18 ++------ .../virtual-device/gps-sensor/app.py | 14 +----- .../code-gps/pi/gps-sensor/app.py | 4 +- .../code-gps/virtual-device/gps-sensor/app.py | 4 +- .../1-location-tracking/pi-gps-sensor.md | 8 ++-- .../single-board-computer-gps-decode.md | 2 +- .../virtual-device-gps-sensor.md | 8 ++-- .../code/pi/gps-sensor/app.py | 45 ++++++++++--------- .../code/virtual-device/gps-sensor/app.py | 43 +++++++++--------- .../4-multiple-language-support/README.md | 4 +- 11 files changed, 86 insertions(+), 98 deletions(-) diff --git a/2-farm/lessons/5-migrate-application-to-the-cloud/README.md b/2-farm/lessons/5-migrate-application-to-the-cloud/README.md index 5fcbacba..82365812 100644 --- a/2-farm/lessons/5-migrate-application-to-the-cloud/README.md +++ b/2-farm/lessons/5-migrate-application-to-the-cloud/README.md @@ -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*. diff --git a/3-transport/lessons/1-location-tracking/code-gps-decode/pi/gps-sensor/app.py b/3-transport/lessons/1-location-tracking/code-gps-decode/pi/gps-sensor/app.py index 3aad9865..a5de9192 100644 --- a/3-transport/lessons/1-location-tracking/code-gps-decode/pi/gps-sensor/app.py +++ b/3-transport/lessons/1-location-tracking/code-gps-decode/pi/gps-sensor/app.py @@ -2,21 +2,12 @@ import time import serial import pynmea2 import json -from azure.iot.device import IoTHubDeviceClient, Message - -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) diff --git a/3-transport/lessons/1-location-tracking/code-gps-decode/virtual-device/gps-sensor/app.py b/3-transport/lessons/1-location-tracking/code-gps-decode/virtual-device/gps-sensor/app.py index 0383f8fd..2b819a56 100644 --- a/3-transport/lessons/1-location-tracking/code-gps-decode/virtual-device/gps-sensor/app.py +++ b/3-transport/lessons/1-location-tracking/code-gps-decode/virtual-device/gps-sensor/app.py @@ -5,18 +5,11 @@ import time import counterfit_shims_serial import pynmea2 import json -from azure.iot.device import IoTHubDeviceClient, Message 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) \ No newline at end of file + time.sleep(1) \ No newline at end of file diff --git a/3-transport/lessons/1-location-tracking/code-gps/pi/gps-sensor/app.py b/3-transport/lessons/1-location-tracking/code-gps/pi/gps-sensor/app.py index 8a282ee1..0dfad1e9 100644 --- a/3-transport/lessons/1-location-tracking/code-gps/pi/gps-sensor/app.py +++ b/3-transport/lessons/1-location-tracking/code-gps/pi/gps-sensor/app.py @@ -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) diff --git a/3-transport/lessons/1-location-tracking/code-gps/virtual-device/gps-sensor/app.py b/3-transport/lessons/1-location-tracking/code-gps/virtual-device/gps-sensor/app.py index 7dd2a965..811ffded 100644 --- a/3-transport/lessons/1-location-tracking/code-gps/virtual-device/gps-sensor/app.py +++ b/3-transport/lessons/1-location-tracking/code-gps/virtual-device/gps-sensor/app.py @@ -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) \ No newline at end of file diff --git a/3-transport/lessons/1-location-tracking/pi-gps-sensor.md b/3-transport/lessons/1-location-tracking/pi-gps-sensor.md index 8cf30733..01148da1 100644 --- a/3-transport/lessons/1-location-tracking/pi-gps-sensor.md +++ b/3-transport/lessons/1-location-tracking/pi-gps-sensor.md @@ -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. diff --git a/3-transport/lessons/1-location-tracking/single-board-computer-gps-decode.md b/3-transport/lessons/1-location-tracking/single-board-computer-gps-decode.md index bf7bc26f..39954623 100644 --- a/3-transport/lessons/1-location-tracking/single-board-computer-gps-decode.md +++ b/3-transport/lessons/1-location-tracking/single-board-computer-gps-decode.md @@ -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) diff --git a/3-transport/lessons/1-location-tracking/virtual-device-gps-sensor.md b/3-transport/lessons/1-location-tracking/virtual-device-gps-sensor.md index e47a455f..a524c7b5 100644 --- a/3-transport/lessons/1-location-tracking/virtual-device-gps-sensor.md +++ b/3-transport/lessons/1-location-tracking/virtual-device-gps-sensor.md @@ -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. diff --git a/3-transport/lessons/2-store-location-data/code/pi/gps-sensor/app.py b/3-transport/lessons/2-store-location-data/code/pi/gps-sensor/app.py index a0b5c0cf..3364f6b4 100644 --- a/3-transport/lessons/2-store-location-data/code/pi/gps-sensor/app.py +++ b/3-transport/lessons/2-store-location-data/code/pi/gps-sensor/app.py @@ -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 = '' -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) \ No newline at end of file + time.sleep(60) diff --git a/3-transport/lessons/2-store-location-data/code/virtual-device/gps-sensor/app.py b/3-transport/lessons/2-store-location-data/code/virtual-device/gps-sensor/app.py index aa211db1..0383f8fd 100644 --- a/3-transport/lessons/2-store-location-data/code/virtual-device/gps-sensor/app.py +++ b/3-transport/lessons/2-store-location-data/code/virtual-device/gps-sensor/app.py @@ -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 = '' -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) \ No newline at end of file + time.sleep(60) \ No newline at end of file diff --git a/6-consumer/lessons/4-multiple-language-support/README.md b/6-consumer/lessons/4-multiple-language-support/README.md index d92c80d7..71542a9a 100644 --- a/6-consumer/lessons/4-multiple-language-support/README.md +++ b/6-consumer/lessons/4-multiple-language-support/README.md @@ -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