diff --git a/translated_images/pt-BR/.co-op-translator.json b/translated_images/pt-BR/.co-op-translator.json new file mode 100644 index 000000000..66884bbf3 --- /dev/null +++ b/translated_images/pt-BR/.co-op-translator.json @@ -0,0 +1,2198 @@ +{ + "IMG_5305.aa291c8812a9f1e5.webp": { + "original_hash": "fc0711c2be2774ab6089d59dc597260b", + "translation_date": "2026-01-16T12:24:58+00:00", + "source_file": "5-retail/lessons/1-train-stock-detector/images/testing/IMG_5305.png", + "language_code": "pt-BR" + }, + "IMG_5306.d575b9ab7025877b.webp": { + "original_hash": "4e37695a9ad976c862b785afb2bb7c2e", + "translation_date": "2026-01-16T12:24:36+00:00", + "source_file": "5-retail/lessons/1-train-stock-detector/images/testing/IMG_5306.png", + "language_code": "pt-BR" + }, + "IMG_5307.f9c9b8361a8aa734.webp": { + "original_hash": "cab390c38e0b27852ef90122d6dc4a8a", + "translation_date": "2026-01-16T12:26:06+00:00", + "source_file": "5-retail/lessons/1-train-stock-detector/images/training/IMG_5307.png", + "language_code": "pt-BR" + }, + "IMG_5308.cbd6ed7007e69060.webp": { + "original_hash": "0ba29462f9494cbdec73138d13555eeb", + "translation_date": "2026-01-16T12:29:16+00:00", + "source_file": "5-retail/lessons/1-train-stock-detector/images/training/IMG_5308.png", + "language_code": "pt-BR" + }, + "IMG_5309.23fbc3b6667bfb64.webp": { + "original_hash": "489a940aac2fae4a3a1e497781cba5a8", + "translation_date": "2026-01-16T12:26:12+00:00", + "source_file": "5-retail/lessons/1-train-stock-detector/images/training/IMG_5309.png", + "language_code": "pt-BR" + }, + "IMG_5310.0ee0eb2fbc1c2d0e.webp": { + "original_hash": "44821d181f6a6dfc59fce6430ea543c3", + "translation_date": "2026-01-16T12:28:36+00:00", + "source_file": "5-retail/lessons/1-train-stock-detector/images/training/IMG_5310.png", + "language_code": "pt-BR" + }, + "IMG_5311.8c90da6446c2d8c2.webp": { + "original_hash": "68d840516ae36a03715a432e9dac3856", + "translation_date": "2026-01-16T12:27:25+00:00", + "source_file": "5-retail/lessons/1-train-stock-detector/images/training/IMG_5311.png", + "language_code": "pt-BR" + }, + "IMG_5312.a45550ddd8ce8e65.webp": { + "original_hash": "254b4fd54e9fe80a51a191ce9f654c85", + "translation_date": "2026-01-16T12:25:46+00:00", + "source_file": "5-retail/lessons/1-train-stock-detector/images/training/IMG_5312.png", + "language_code": "pt-BR" + }, + "IMG_5313.ed1b45211271dbd2.webp": { + "original_hash": "86bea69b269add926a2da7a91bd68191", + "translation_date": "2026-01-16T12:25:49+00:00", + "source_file": "5-retail/lessons/1-train-stock-detector/images/training/IMG_5313.png", + "language_code": "pt-BR" + }, + "IMG_5314.c2203206a05a74b5.webp": { + "original_hash": "168cc384e8f57b7bdd2469769fddced6", + "translation_date": "2026-01-16T12:27:43+00:00", + "source_file": "5-retail/lessons/1-train-stock-detector/images/training/IMG_5314.png", + "language_code": "pt-BR" + }, + "IMG_5315.f698228e0e031bd4.webp": { + "original_hash": "4975f6e8e46204674362e3686f994433", + "translation_date": "2026-01-16T12:28:32+00:00", + "source_file": "5-retail/lessons/1-train-stock-detector/images/training/IMG_5315.png", + "language_code": "pt-BR" + }, + "IMG_5316.29dc70d802ce8349.webp": { + "original_hash": "ba7dbbd6975e2bd39c4b37e1a12867da", + "translation_date": "2026-01-16T12:25:16+00:00", + "source_file": "5-retail/lessons/1-train-stock-detector/images/training/IMG_5316.png", + "language_code": "pt-BR" + }, + "IMG_5317.ed81e4c1ca5046dc.webp": { + "original_hash": "1418135512d05bb5a5e8295c3ca27e4e", + "translation_date": "2026-01-16T12:26:26+00:00", + "source_file": "5-retail/lessons/1-train-stock-detector/images/training/IMG_5317.png", + "language_code": "pt-BR" + }, + "IMG_5318.15dfffeb7f47abf7.webp": { + "original_hash": "6d55d50694cfb9d88f84167f245a5d51", + "translation_date": "2026-01-16T12:25:40+00:00", + "source_file": "5-retail/lessons/1-train-stock-detector/images/training/IMG_5318.png", + "language_code": "pt-BR" + }, + "IMG_5319.b549b1fff0dcf143.webp": { + "original_hash": "cd73355ae901d57470404f12f3e14d8f", + "translation_date": "2026-01-16T12:28:19+00:00", + "source_file": "5-retail/lessons/1-train-stock-detector/images/training/IMG_5319.png", + "language_code": "pt-BR" + }, + "IMG_5320.8268d3f61972f348.webp": { + "original_hash": "a6db3613b3615430929eec1d26541f23", + "translation_date": "2026-01-16T12:28:00+00:00", + "source_file": "5-retail/lessons/1-train-stock-detector/images/training/IMG_5320.png", + "language_code": "pt-BR" + }, + "IMG_5321.b207cf143a59458d.webp": { + "original_hash": "d5626c8d5686c0fb0b71774b18b5799e", + "translation_date": "2026-01-16T12:24:53+00:00", + "source_file": "5-retail/lessons/1-train-stock-detector/images/testing/IMG_5321.png", + "language_code": "pt-BR" + }, + "IMG_5322.974809b9461a9e20.webp": { + "original_hash": "12e8057af8ca375668ac69dd83d3df9e", + "translation_date": "2026-01-16T12:28:27+00:00", + "source_file": "5-retail/lessons/1-train-stock-detector/images/training/IMG_5322.png", + "language_code": "pt-BR" + }, + "IMG_5323.4939fa17958f291b.webp": { + "original_hash": "e7b6ccd025636efe16234fde1583ac2f", + "translation_date": "2026-01-16T12:28:51+00:00", + "source_file": "5-retail/lessons/1-train-stock-detector/images/training/IMG_5323.png", + "language_code": "pt-BR" + }, + "IMG_5324.0afbc6f0caceb1a3.webp": { + "original_hash": "2d32f160ad94adf82b14722b5a4750de", + "translation_date": "2026-01-16T12:26:20+00:00", + "source_file": "5-retail/lessons/1-train-stock-detector/images/training/IMG_5324.png", + "language_code": "pt-BR" + }, + "IMG_5325.9e9d9e9b85a10b06.webp": { + "original_hash": "797e68cbe795ca2b3bcefb017cde1e88", + "translation_date": "2026-01-16T12:27:38+00:00", + "source_file": "5-retail/lessons/1-train-stock-detector/images/training/IMG_5325.png", + "language_code": "pt-BR" + }, + "IMG_5326.35bbc9e054c704d0.webp": { + "original_hash": "34cd6fb13bd85e2bc35a2113b89aecd1", + "translation_date": "2026-01-16T12:26:01+00:00", + "source_file": "5-retail/lessons/1-train-stock-detector/images/training/IMG_5326.png", + "language_code": "pt-BR" + }, + "IMG_5327.804b63a605b5a77a.webp": { + "original_hash": "7f20dfc038fa8b756cf381c0d13cc764", + "translation_date": "2026-01-16T12:26:59+00:00", + "source_file": "5-retail/lessons/1-train-stock-detector/images/training/IMG_5327.png", + "language_code": "pt-BR" + }, + "IMG_5328.925a9da23d96759f.webp": { + "original_hash": "d2038a13e44588a9bfbf8901b11d00e2", + "translation_date": "2026-01-16T12:25:35+00:00", + "source_file": "5-retail/lessons/1-train-stock-detector/images/training/IMG_5328.png", + "language_code": "pt-BR" + }, + "IMG_5329.27da5fcbc3336773.webp": { + "original_hash": "fd75c4e9e16aeb231b2f10c94d10d608", + "translation_date": "2026-01-16T12:28:44+00:00", + "source_file": "5-retail/lessons/1-train-stock-detector/images/training/IMG_5329.png", + "language_code": "pt-BR" + }, + "IMG_5330.3db3d5ea01c8cca2.webp": { + "original_hash": "148147aa52a66e9d9e77c17a4b6fb50b", + "translation_date": "2026-01-16T12:27:20+00:00", + "source_file": "5-retail/lessons/1-train-stock-detector/images/training/IMG_5330.png", + "language_code": "pt-BR" + }, + "IMG_5331.181987d3d094472f.webp": { + "original_hash": "2272482bed9dbf36b7798a41324d008f", + "translation_date": "2026-01-16T12:28:58+00:00", + "source_file": "5-retail/lessons/1-train-stock-detector/images/training/IMG_5331.png", + "language_code": "pt-BR" + }, + "IMG_5332.4beed56eaa5158e3.webp": { + "original_hash": "445a83687357d2bf3749e23583768407", + "translation_date": "2026-01-16T12:29:06+00:00", + "source_file": "5-retail/lessons/1-train-stock-detector/images/training/IMG_5332.png", + "language_code": "pt-BR" + }, + "IMG_5333.53c3364c2ee0e7bb.webp": { + "original_hash": "018ac6ada7c30b62d168689b8865c5cd", + "translation_date": "2026-01-16T12:28:08+00:00", + "source_file": "5-retail/lessons/1-train-stock-detector/images/training/IMG_5333.png", + "language_code": "pt-BR" + }, + "IMG_5334.979472e433948c10.webp": { + "original_hash": "13d55902d7f4025e4c0b4ec92d7e5c38", + "translation_date": "2026-01-16T12:27:49+00:00", + "source_file": "5-retail/lessons/1-train-stock-detector/images/training/IMG_5334.png", + "language_code": "pt-BR" + }, + "IMG_5335.9f5bfba69a8d5a90.webp": { + "original_hash": "d896d7a763d29c0da589c8dbc77c9ed3", + "translation_date": "2026-01-16T12:26:45+00:00", + "source_file": "5-retail/lessons/1-train-stock-detector/images/training/IMG_5335.png", + "language_code": "pt-BR" + }, + "IMG_5336.1b46586fdec95767.webp": { + "original_hash": "e40e7f6dcb13a7f78508a3751ce2f071", + "translation_date": "2026-01-16T12:26:32+00:00", + "source_file": "5-retail/lessons/1-train-stock-detector/images/training/IMG_5336.png", + "language_code": "pt-BR" + }, + "IMG_5337.91c82be4d37029b0.webp": { + "original_hash": "17697be963b005f6961b32d72072d6af", + "translation_date": "2026-01-16T12:26:39+00:00", + "source_file": "5-retail/lessons/1-train-stock-detector/images/training/IMG_5337.png", + "language_code": "pt-BR" + }, + "IMG_5338.9ab356541448923b.webp": { + "original_hash": "c6112e9cf630cc63b828dcbdde845de3", + "translation_date": "2026-01-16T12:29:11+00:00", + "source_file": "5-retail/lessons/1-train-stock-detector/images/training/IMG_5338.png", + "language_code": "pt-BR" + }, + "IMG_5340.8440651b3ce1dd35.webp": { + "original_hash": "24b34e210b680dcdd7f84c7b819e5af2", + "translation_date": "2026-01-16T12:25:27+00:00", + "source_file": "5-retail/lessons/1-train-stock-detector/images/training/IMG_5340.png", + "language_code": "pt-BR" + }, + "IMG_5341.a1aa041c42dbc534.webp": { + "original_hash": "a5bce966ff8f378c7ac2c3ae3263f629", + "translation_date": "2026-01-16T12:27:11+00:00", + "source_file": "5-retail/lessons/1-train-stock-detector/images/training/IMG_5341.png", + "language_code": "pt-BR" + }, + "IMG_5342.9f3b93d9fab90d3b.webp": { + "original_hash": "5d05e1e08f6e5aaf21891368d22fcfb5", + "translation_date": "2026-01-16T12:26:51+00:00", + "source_file": "5-retail/lessons/1-train-stock-detector/images/training/IMG_5342.png", + "language_code": "pt-BR" + }, + "IMG_5343.fa30105d3c10cad2.webp": { + "original_hash": "a41290e37e030928a002529f04f9387f", + "translation_date": "2026-01-16T12:24:44+00:00", + "source_file": "5-retail/lessons/1-train-stock-detector/images/testing/IMG_5343.png", + "language_code": "pt-BR" + }, + "IMG_5344.acfcd61ee5281321.webp": { + "original_hash": "a376d539df9a174bfdaadbab9dbc1cfd", + "translation_date": "2026-01-16T12:27:04+00:00", + "source_file": "5-retail/lessons/1-train-stock-detector/images/training/IMG_5344.png", + "language_code": "pt-BR" + }, + "IMG_5345.3d305ee2bb4ee804.webp": { + "original_hash": "a511a224fa17db01684e0e63921ff020", + "translation_date": "2026-01-16T12:25:02+00:00", + "source_file": "5-retail/lessons/1-train-stock-detector/images/training/IMG_5345.png", + "language_code": "pt-BR" + }, + "IMG_5346.281dcc267f69c70b.webp": { + "original_hash": "4772f5cabda119b12f676ad35147320e", + "translation_date": "2026-01-16T12:28:13+00:00", + "source_file": "5-retail/lessons/1-train-stock-detector/images/training/IMG_5346.png", + "language_code": "pt-BR" + }, + "IMG_5347.48a4a981e76910ae.webp": { + "original_hash": "7b0d15e3f5e8ec289aff74d74a6dbf6e", + "translation_date": "2026-01-16T12:25:54+00:00", + "source_file": "5-retail/lessons/1-train-stock-detector/images/training/IMG_5347.png", + "language_code": "pt-BR" + }, + "IMG_5348.3961d3b444537c13.webp": { + "original_hash": "312f940de37e3d8b548a5ff7e0ef59ce", + "translation_date": "2026-01-16T12:27:30+00:00", + "source_file": "5-retail/lessons/1-train-stock-detector/images/training/IMG_5348.png", + "language_code": "pt-BR" + }, + "IMG_5349.1f0ec7fbf8807b3b.webp": { + "original_hash": "d12db74e18cfb01344a6f47e93341d6e", + "translation_date": "2026-01-16T12:25:06+00:00", + "source_file": "5-retail/lessons/1-train-stock-detector/images/training/IMG_5349.png", + "language_code": "pt-BR" + }, + "Roadmap.bb1dec285dda0eda.webp": { + "original_hash": "c49112726cdadd69ca0ec203a13e4689", + "translation_date": "2026-01-16T12:13:54+00:00", + "source_file": "sketchnotes/Roadmap.jpg", + "language_code": "pt-BR" + }, + "amqp.804bd4fce8330157.webp": { + "original_hash": "692b3edd9d3704d946d527027dd7c551", + "translation_date": "2026-01-16T12:06:43+00:00", + "source_file": "images/amqp.png", + "language_code": "pt-BR" + }, + "analog-sensor-voltage.3b6f315392247399.webp": { + "original_hash": "04c17740d5a42b6ee113d71605d6a0a8", + "translation_date": "2026-01-16T12:01:47+00:00", + "source_file": "images/analog-sensor-voltage.png", + "language_code": "pt-BR" + }, + "arducam-wio-terminal-connections.a4d5a4049bdb5ab8.webp": { + "original_hash": "01f69e3dc5f29479230a13a7c0f0efe0", + "translation_date": "2026-01-16T12:06:40+00:00", + "source_file": "images/arducam-wio-terminal-connections.png", + "language_code": "pt-BR" + }, + "arducam.20e4e4cbb2682965.webp": { + "original_hash": "f17393656663c080b68a3ed2b41c0fc2", + "translation_date": "2026-01-16T12:05:46+00:00", + "source_file": "images/arducam.png", + "language_code": "pt-BR" + }, + "arduino-sketch.79590cb837ff7a7c.webp": { + "original_hash": "a1ff6ddb0db8a676992dd9f958c6a5af", + "translation_date": "2026-01-16T12:05:55+00:00", + "source_file": "images/arduino-sketch.png", + "language_code": "pt-BR" + }, + "assignment-1-flow.7552a51acb1a5ec8.webp": { + "original_hash": "b3991eeb7b7d7ab00b21d1b95cbbd2c1", + "translation_date": "2026-01-16T11:57:14+00:00", + "source_file": "images/assignment-1-flow.png", + "language_code": "pt-BR" + }, + "assignment-1-internet-flow.3256feab5f052fd2.webp": { + "original_hash": "46d80a9e43b81a385c223c1fc12f39c6", + "translation_date": "2026-01-16T11:50:27+00:00", + "source_file": "images/assignment-1-internet-flow.png", + "language_code": "pt-BR" + }, + "azure-container-registry-logo.09494206991d4b29.webp": { + "original_hash": "adbc9655bf044bdf906e0f58fb36fbe1", + "translation_date": "2026-01-16T11:55:45+00:00", + "source_file": "images/azure-container-registry-logo.png", + "language_code": "pt-BR" + }, + "azure-functions-logo.1cfc8e3204c9c44a.webp": { + "original_hash": "7e62e90fe4cbd4f81b7db92c1f52933a", + "translation_date": "2026-01-16T12:03:28+00:00", + "source_file": "images/azure-functions-logo.png", + "language_code": "pt-BR" + }, + "azure-iot-edge-logo.c1c076749b5cba2e.webp": { + "original_hash": "bda41e5883dffedc3baf5efd20f09b49", + "translation_date": "2026-01-16T12:05:52+00:00", + "source_file": "images/azure-iot-edge-logo.png", + "language_code": "pt-BR" + }, + "azure-iot-hub-logo.28a19de76d0a1932.webp": { + "original_hash": "25526337ac38c5da2187ec953308a1a0", + "translation_date": "2026-01-16T12:04:28+00:00", + "source_file": "images/azure-iot-hub-logo.png", + "language_code": "pt-BR" + }, + "azure-maps-logo.35d01dcfbd81fe61.webp": { + "original_hash": "0b44d4f0596a033eb687e0a23d231428", + "translation_date": "2026-01-16T11:46:19+00:00", + "source_file": "images/azure-maps-logo.png", + "language_code": "pt-BR" + }, + "azure-region-existing.73f704604f2aa6cb.webp": { + "original_hash": "663095f6754e78da000aecf8b255f56a", + "translation_date": "2026-01-16T11:57:57+00:00", + "source_file": "images/azure-region-existing.png", + "language_code": "pt-BR" + }, + "azure-region-planned-expansion.a5074a1e8af74f15.webp": { + "original_hash": "e7b04b7641a855f6ab0461b9814c5bfa", + "translation_date": "2026-01-16T12:02:17+00:00", + "source_file": "images/azure-region-planned-expansion.png", + "language_code": "pt-BR" + }, + "azure-speech-logo.a1f08c4befb0159f.webp": { + "original_hash": "c0515d2fc1d34b7de4da2ae6f6af07e6", + "translation_date": "2026-01-16T11:57:39+00:00", + "source_file": "images/azure-speech-logo.png", + "language_code": "pt-BR" + }, + "azure-storage-logo.605c0f602c640d48.webp": { + "original_hash": "1b40b8e787f4058533cbfe7371dc400c", + "translation_date": "2026-01-16T11:53:52+00:00", + "source_file": "images/azure-storage-logo.png", + "language_code": "pt-BR" + }, + "azure-translator-logo.c6ed3a4a433edfd2.webp": { + "original_hash": "e6f188b64083c3f1814719c5b31a2128", + "translation_date": "2026-01-16T11:55:03+00:00", + "source_file": "images/azure-translator-logo.png", + "language_code": "pt-BR" + }, + "banana-arducam.be1b32d4267a8194.webp": { + "original_hash": "ab405c9f67c6a168e156dd3de2e4c9be", + "translation_date": "2026-01-16T12:06:15+00:00", + "source_file": "images/banana-arducam.jpg", + "language_code": "pt-BR" + }, + "banana-picture-compare.174df164dc326a42.webp": { + "original_hash": "1c539ac9dde011622cb841c9d1ac7991", + "translation_date": "2026-01-16T11:57:00+00:00", + "source_file": "images/banana-picture-compare.png", + "language_code": "pt-BR" + }, + "banana-ripe-1.6ed72365ffc92300.webp": { + "original_hash": "b669c7b079f11e40ccf403bca27420a6", + "translation_date": "2026-01-16T12:29:18+00:00", + "source_file": "4-manufacturing/lessons/1-train-fruit-detector/images/testing/ripe/banana-ripe-1.png", + "language_code": "pt-BR" + }, + "banana-ripe-1.780e9be3a60d8879.webp": { + "original_hash": "e1657ae830ee7346983e1ca04f185e0e", + "translation_date": "2026-01-16T12:29:38+00:00", + "source_file": "4-manufacturing/lessons/1-train-fruit-detector/images/training/ripe/banana-ripe-1.png", + "language_code": "pt-BR" + }, + "banana-ripe-10.c3d98eb280e7464f.webp": { + "original_hash": "1fd32bdc31ba975c91484494cc3ef395", + "translation_date": "2026-01-16T12:29:39+00:00", + "source_file": "4-manufacturing/lessons/1-train-fruit-detector/images/training/ripe/banana-ripe-10.png", + "language_code": "pt-BR" + }, + "banana-ripe-11.3d932f292b95b9a2.webp": { + "original_hash": "10d419a7eb4916eb20ab86a2d5704359", + "translation_date": "2026-01-16T12:29:21+00:00", + "source_file": "4-manufacturing/lessons/1-train-fruit-detector/images/training/ripe/banana-ripe-11.png", + "language_code": "pt-BR" + }, + "banana-ripe-12.9f87e663b9da6c85.webp": { + "original_hash": "8e8d0158457b243d442b06713947d089", + "translation_date": "2026-01-16T12:29:35+00:00", + "source_file": "4-manufacturing/lessons/1-train-fruit-detector/images/training/ripe/banana-ripe-12.png", + "language_code": "pt-BR" + }, + "banana-ripe-13.b7402e05160f4543.webp": { + "original_hash": "9f3ebf2203aaa657357ba262990bbb21", + "translation_date": "2026-01-16T12:29:25+00:00", + "source_file": "4-manufacturing/lessons/1-train-fruit-detector/images/training/ripe/banana-ripe-13.png", + "language_code": "pt-BR" + }, + "banana-ripe-14.85cf309aa702cfa8.webp": { + "original_hash": "c45e36f248a3dace32791bfca32d6aed", + "translation_date": "2026-01-16T12:29:33+00:00", + "source_file": "4-manufacturing/lessons/1-train-fruit-detector/images/training/ripe/banana-ripe-14.png", + "language_code": "pt-BR" + }, + "banana-ripe-15.933412eb14a3f8e4.webp": { + "original_hash": "efaa40a12e710aa6bbb1a1d0bb2052a4", + "translation_date": "2026-01-16T12:29:34+00:00", + "source_file": "4-manufacturing/lessons/1-train-fruit-detector/images/training/ripe/banana-ripe-15.png", + "language_code": "pt-BR" + }, + "banana-ripe-16.781a68a01401f89e.webp": { + "original_hash": "29f95cc922f22691d9804dae4672b387", + "translation_date": "2026-01-16T12:29:28+00:00", + "source_file": "4-manufacturing/lessons/1-train-fruit-detector/images/training/ripe/banana-ripe-16.png", + "language_code": "pt-BR" + }, + "banana-ripe-17.f8e2853a40d3ac45.webp": { + "original_hash": "8f0a9f7b93505876f7bd290b3679099d", + "translation_date": "2026-01-16T12:29:31+00:00", + "source_file": "4-manufacturing/lessons/1-train-fruit-detector/images/training/ripe/banana-ripe-17.png", + "language_code": "pt-BR" + }, + "banana-ripe-18.3d05f5f78ecf6f0d.webp": { + "original_hash": "cae1792a648b1486d2e3590866d11980", + "translation_date": "2026-01-16T12:29:30+00:00", + "source_file": "4-manufacturing/lessons/1-train-fruit-detector/images/training/ripe/banana-ripe-18.png", + "language_code": "pt-BR" + }, + "banana-ripe-19.ac3b0fc6cf6fdfd5.webp": { + "original_hash": "2390f2cc5023984a9682ec5f96f2bd6e", + "translation_date": "2026-01-16T12:29:36+00:00", + "source_file": "4-manufacturing/lessons/1-train-fruit-detector/images/training/ripe/banana-ripe-19.png", + "language_code": "pt-BR" + }, + "banana-ripe-2.8ab96da692df69f1.webp": { + "original_hash": "ae966eeff29fbf1a867a864baa149780", + "translation_date": "2026-01-16T12:29:17+00:00", + "source_file": "4-manufacturing/lessons/1-train-fruit-detector/images/testing/ripe/banana-ripe-2.png", + "language_code": "pt-BR" + }, + "banana-ripe-2.96ddc53114c5f020.webp": { + "original_hash": "c7c3b976043accf6fff757e50afed132", + "translation_date": "2026-01-16T12:29:24+00:00", + "source_file": "4-manufacturing/lessons/1-train-fruit-detector/images/training/ripe/banana-ripe-2.png", + "language_code": "pt-BR" + }, + "banana-ripe-20.a4d0ad33a7e6f037.webp": { + "original_hash": "aa2539f64cd978be437a294ef56b38ec", + "translation_date": "2026-01-16T12:29:28+00:00", + "source_file": "4-manufacturing/lessons/1-train-fruit-detector/images/training/ripe/banana-ripe-20.png", + "language_code": "pt-BR" + }, + "banana-ripe-21.07e03d64f265d55d.webp": { + "original_hash": "2c1528b1de4d0572dd8e3813ec38a591", + "translation_date": "2026-01-16T12:29:22+00:00", + "source_file": "4-manufacturing/lessons/1-train-fruit-detector/images/training/ripe/banana-ripe-21.png", + "language_code": "pt-BR" + }, + "banana-ripe-22.a63c05aeb7f866fc.webp": { + "original_hash": "1b4c8cac0fb4d88e2fac6e10a401b567", + "translation_date": "2026-01-16T12:29:39+00:00", + "source_file": "4-manufacturing/lessons/1-train-fruit-detector/images/training/ripe/banana-ripe-22.png", + "language_code": "pt-BR" + }, + "banana-ripe-23.6f3364afcab19e57.webp": { + "original_hash": "28dcfffcd92c957991aca002f7afb9f5", + "translation_date": "2026-01-16T12:29:34+00:00", + "source_file": "4-manufacturing/lessons/1-train-fruit-detector/images/training/ripe/banana-ripe-23.png", + "language_code": "pt-BR" + }, + "banana-ripe-24.ff2c02cc80a9c430.webp": { + "original_hash": "cffff187f53978527516f37fbdb528b6", + "translation_date": "2026-01-16T12:29:37+00:00", + "source_file": "4-manufacturing/lessons/1-train-fruit-detector/images/training/ripe/banana-ripe-24.png", + "language_code": "pt-BR" + }, + "banana-ripe-25.65ce63418cdc4de2.webp": { + "original_hash": "773b4a997e31a2a512b75f51941d594d", + "translation_date": "2026-01-16T12:29:26+00:00", + "source_file": "4-manufacturing/lessons/1-train-fruit-detector/images/training/ripe/banana-ripe-25.png", + "language_code": "pt-BR" + }, + "banana-ripe-3.4fae05a0a1d2b5f0.webp": { + "original_hash": "4810eae16d8cd35405bd23a7630d4c1c", + "translation_date": "2026-01-16T12:29:32+00:00", + "source_file": "4-manufacturing/lessons/1-train-fruit-detector/images/training/ripe/banana-ripe-3.png", + "language_code": "pt-BR" + }, + "banana-ripe-5.c762086879ccec4c.webp": { + "original_hash": "b70a07b7c7fe7a6e38624ecf409ecb39", + "translation_date": "2026-01-16T12:29:21+00:00", + "source_file": "4-manufacturing/lessons/1-train-fruit-detector/images/training/ripe/banana-ripe-5.png", + "language_code": "pt-BR" + }, + "banana-ripe-6.5131bcbf492980cb.webp": { + "original_hash": "54da747610520d477d2ce3ab576ac125", + "translation_date": "2026-01-16T12:29:23+00:00", + "source_file": "4-manufacturing/lessons/1-train-fruit-detector/images/training/ripe/banana-ripe-6.png", + "language_code": "pt-BR" + }, + "banana-ripe-7.5fc18dfe7b7ae9dc.webp": { + "original_hash": "ab45157090d3fb253fc262e1ac44cd36", + "translation_date": "2026-01-16T12:29:40+00:00", + "source_file": "4-manufacturing/lessons/1-train-fruit-detector/images/training/ripe/banana-ripe-7.png", + "language_code": "pt-BR" + }, + "banana-ripe-8.dba1d33bd34d4830.webp": { + "original_hash": "12afa64eebbc95b9536e6f3bbccdb345", + "translation_date": "2026-01-16T12:29:27+00:00", + "source_file": "4-manufacturing/lessons/1-train-fruit-detector/images/training/ripe/banana-ripe-8.png", + "language_code": "pt-BR" + }, + "banana-ripe-9.32f91462c8b0e2d3.webp": { + "original_hash": "a380e69917059d3401d09c9e00e289f6", + "translation_date": "2026-01-16T12:29:29+00:00", + "source_file": "4-manufacturing/lessons/1-train-fruit-detector/images/training/ripe/banana-ripe-9.png", + "language_code": "pt-BR" + }, + "banana-training-images.530eb203346d73bc.webp": { + "original_hash": "c93a7b2b58562500f7eaf9385e7c0d58", + "translation_date": "2026-01-16T11:54:04+00:00", + "source_file": "images/banana-training-images.png", + "language_code": "pt-BR" + }, + "banana-unripe-1.910c8606a300fa20.webp": { + "original_hash": "6d91493fcc6ed717266d0a58ed4ba97d", + "translation_date": "2026-01-16T12:30:00+00:00", + "source_file": "4-manufacturing/lessons/1-train-fruit-detector/images/training/unripe/banana-unripe-1.png", + "language_code": "pt-BR" + }, + "banana-unripe-1.b2c7051d9c8a4e61.webp": { + "original_hash": "a4cc0cccd0bd9e129367a314c3d97e3a", + "translation_date": "2026-01-16T12:29:20+00:00", + "source_file": "4-manufacturing/lessons/1-train-fruit-detector/images/testing/unripe/banana-unripe-1.png", + "language_code": "pt-BR" + }, + "banana-unripe-10.38dab0db918a2487.webp": { + "original_hash": "3fbe312ca683ffb4130c21bb5f8faf67", + "translation_date": "2026-01-16T12:29:45+00:00", + "source_file": "4-manufacturing/lessons/1-train-fruit-detector/images/training/unripe/banana-unripe-10.png", + "language_code": "pt-BR" + }, + "banana-unripe-11.ec8d0eefe63e10b9.webp": { + "original_hash": "fafe54a9660b5ea8811d8df8dfe375ad", + "translation_date": "2026-01-16T12:30:04+00:00", + "source_file": "4-manufacturing/lessons/1-train-fruit-detector/images/training/unripe/banana-unripe-11.png", + "language_code": "pt-BR" + }, + "banana-unripe-12.b95a088ccae935db.webp": { + "original_hash": "26ff82ce86b8b10f54fc97c7227aa131", + "translation_date": "2026-01-16T12:29:53+00:00", + "source_file": "4-manufacturing/lessons/1-train-fruit-detector/images/training/unripe/banana-unripe-12.png", + "language_code": "pt-BR" + }, + "banana-unripe-13.37e5a7cac5aa0920.webp": { + "original_hash": "ad62ee1af2830d972b9d933e94c8f592", + "translation_date": "2026-01-16T12:29:50+00:00", + "source_file": "4-manufacturing/lessons/1-train-fruit-detector/images/training/unripe/banana-unripe-13.png", + "language_code": "pt-BR" + }, + "banana-unripe-14.d19ddd6bbf63a259.webp": { + "original_hash": "df691d75f8bdf20269d642704fa81233", + "translation_date": "2026-01-16T12:29:58+00:00", + "source_file": "4-manufacturing/lessons/1-train-fruit-detector/images/training/unripe/banana-unripe-14.png", + "language_code": "pt-BR" + }, + "banana-unripe-15.274e48544326077a.webp": { + "original_hash": "1bf43279e1d99527a05e3fd05b6ac035", + "translation_date": "2026-01-16T12:30:01+00:00", + "source_file": "4-manufacturing/lessons/1-train-fruit-detector/images/training/unripe/banana-unripe-15.png", + "language_code": "pt-BR" + }, + "banana-unripe-16.bd058f64bd7ec014.webp": { + "original_hash": "a57dba0a4221e68a916b8d6b39ee88b3", + "translation_date": "2026-01-16T12:29:42+00:00", + "source_file": "4-manufacturing/lessons/1-train-fruit-detector/images/training/unripe/banana-unripe-16.png", + "language_code": "pt-BR" + }, + "banana-unripe-17.408382d679bfa079.webp": { + "original_hash": "9b487f26ef0c7cfb561c472902c5d96b", + "translation_date": "2026-01-16T12:29:55+00:00", + "source_file": "4-manufacturing/lessons/1-train-fruit-detector/images/training/unripe/banana-unripe-17.png", + "language_code": "pt-BR" + }, + "banana-unripe-18.39c0eb79d7b3b9ba.webp": { + "original_hash": "5e5522a34ce418404df666003c42058e", + "translation_date": "2026-01-16T12:29:51+00:00", + "source_file": "4-manufacturing/lessons/1-train-fruit-detector/images/training/unripe/banana-unripe-18.png", + "language_code": "pt-BR" + }, + "banana-unripe-19.e61e6d7efaf2d8c8.webp": { + "original_hash": "9412ba91c9eca98b84c86de22b51631f", + "translation_date": "2026-01-16T12:29:54+00:00", + "source_file": "4-manufacturing/lessons/1-train-fruit-detector/images/training/unripe/banana-unripe-19.png", + "language_code": "pt-BR" + }, + "banana-unripe-2.43a73b544521afc7.webp": { + "original_hash": "191f77cd53ad268a98fc833365c67fc5", + "translation_date": "2026-01-16T12:29:19+00:00", + "source_file": "4-manufacturing/lessons/1-train-fruit-detector/images/testing/unripe/banana-unripe-2.png", + "language_code": "pt-BR" + }, + "banana-unripe-2.9591d1a6aa27deeb.webp": { + "original_hash": "b414558382a2640d15611bd29ed8f5f0", + "translation_date": "2026-01-16T12:29:52+00:00", + "source_file": "4-manufacturing/lessons/1-train-fruit-detector/images/training/unripe/banana-unripe-2.png", + "language_code": "pt-BR" + }, + "banana-unripe-20.85b7a74eaab5634e.webp": { + "original_hash": "cf0067ebc713ffa4be85f95463639d68", + "translation_date": "2026-01-16T12:29:49+00:00", + "source_file": "4-manufacturing/lessons/1-train-fruit-detector/images/training/unripe/banana-unripe-20.png", + "language_code": "pt-BR" + }, + "banana-unripe-21.ccc1333439b344bc.webp": { + "original_hash": "6ee44eae72d211d164828835be1dd7c5", + "translation_date": "2026-01-16T12:29:56+00:00", + "source_file": "4-manufacturing/lessons/1-train-fruit-detector/images/training/unripe/banana-unripe-21.png", + "language_code": "pt-BR" + }, + "banana-unripe-22.27dff4b438163080.webp": { + "original_hash": "a9a930c9ba5f72daa2205105248afd86", + "translation_date": "2026-01-16T12:29:48+00:00", + "source_file": "4-manufacturing/lessons/1-train-fruit-detector/images/training/unripe/banana-unripe-22.png", + "language_code": "pt-BR" + }, + "banana-unripe-23.c4c9067f23370e90.webp": { + "original_hash": "141fdca6d816f53efd73fe0ae59d0a43", + "translation_date": "2026-01-16T12:29:41+00:00", + "source_file": "4-manufacturing/lessons/1-train-fruit-detector/images/training/unripe/banana-unripe-23.png", + "language_code": "pt-BR" + }, + "banana-unripe-24.6f0b781c309da62f.webp": { + "original_hash": "c36781ac98c350de305cc9864e4e4b67", + "translation_date": "2026-01-16T12:30:03+00:00", + "source_file": "4-manufacturing/lessons/1-train-fruit-detector/images/training/unripe/banana-unripe-24.png", + "language_code": "pt-BR" + }, + "banana-unripe-25.21d553d84880ac4f.webp": { + "original_hash": "534e54b877de9b3bc7c5e67e6fb426b5", + "translation_date": "2026-01-16T12:29:59+00:00", + "source_file": "4-manufacturing/lessons/1-train-fruit-detector/images/training/unripe/banana-unripe-25.png", + "language_code": "pt-BR" + }, + "banana-unripe-26.823c48b61feb1d5c.webp": { + "original_hash": "f541d556eff5be42991bba984ca305f9", + "translation_date": "2026-01-16T12:30:03+00:00", + "source_file": "4-manufacturing/lessons/1-train-fruit-detector/images/training/unripe/banana-unripe-26.png", + "language_code": "pt-BR" + }, + "banana-unripe-27.f98fd272deeb02d9.webp": { + "original_hash": "32ffe72a780f2ae97ac1b189d0fb9a44", + "translation_date": "2026-01-16T12:29:44+00:00", + "source_file": "4-manufacturing/lessons/1-train-fruit-detector/images/training/unripe/banana-unripe-27.png", + "language_code": "pt-BR" + }, + "banana-unripe-28.5331ba409ce41c07.webp": { + "original_hash": "75f6d0f1ad3d2ca875d31421b8f35deb", + "translation_date": "2026-01-16T12:29:47+00:00", + "source_file": "4-manufacturing/lessons/1-train-fruit-detector/images/training/unripe/banana-unripe-28.png", + "language_code": "pt-BR" + }, + "banana-unripe-29.84e126f389bf627e.webp": { + "original_hash": "fad512ccb4e4129d91a10b915bc55829", + "translation_date": "2026-01-16T12:29:57+00:00", + "source_file": "4-manufacturing/lessons/1-train-fruit-detector/images/training/unripe/banana-unripe-29.png", + "language_code": "pt-BR" + }, + "banana-unripe-3.896df8fb2c3b8f51.webp": { + "original_hash": "16d53ba9a1f72a431e04901214d53f2e", + "translation_date": "2026-01-16T12:29:49+00:00", + "source_file": "4-manufacturing/lessons/1-train-fruit-detector/images/training/unripe/banana-unripe-3.png", + "language_code": "pt-BR" + }, + "banana-unripe-4.483e740d6fd7b5a6.webp": { + "original_hash": "e0ff72cd82b8c7c4595e1beec806b8cb", + "translation_date": "2026-01-16T12:29:45+00:00", + "source_file": "4-manufacturing/lessons/1-train-fruit-detector/images/training/unripe/banana-unripe-4.png", + "language_code": "pt-BR" + }, + "banana-unripe-5.e9923cf1ffcfc1c9.webp": { + "original_hash": "c46c19087503e1173c9c214750b06c8f", + "translation_date": "2026-01-16T12:29:58+00:00", + "source_file": "4-manufacturing/lessons/1-train-fruit-detector/images/training/unripe/banana-unripe-5.png", + "language_code": "pt-BR" + }, + "banana-unripe-6.e3a73307558caecc.webp": { + "original_hash": "29d58bf3f0290ac98d5c748f467ab900", + "translation_date": "2026-01-16T12:29:43+00:00", + "source_file": "4-manufacturing/lessons/1-train-fruit-detector/images/training/unripe/banana-unripe-6.png", + "language_code": "pt-BR" + }, + "banana-unripe-7.634ca89acc17d68f.webp": { + "original_hash": "90677247facc68c33c17c37f03d6531d", + "translation_date": "2026-01-16T12:29:46+00:00", + "source_file": "4-manufacturing/lessons/1-train-fruit-detector/images/training/unripe/banana-unripe-7.png", + "language_code": "pt-BR" + }, + "banana-unripe-8.75720b4cdebac8c3.webp": { + "original_hash": "b2c3f312e05c258ea969ea1510c9e8d7", + "translation_date": "2026-01-16T12:29:54+00:00", + "source_file": "4-manufacturing/lessons/1-train-fruit-detector/images/training/unripe/banana-unripe-8.png", + "language_code": "pt-BR" + }, + "banana-unripe-9.e8076983351d2f54.webp": { + "original_hash": "93eac8be89da4c1db40c38166f18d515", + "translation_date": "2026-01-16T12:30:02+00:00", + "source_file": "4-manufacturing/lessons/1-train-fruit-detector/images/training/unripe/banana-unripe-9.png", + "language_code": "pt-BR" + }, + "banana-unripe-quick-test-prediction.dae9b5e1c4ef7c64.webp": { + "original_hash": "7351b0cf725cfdc62e6b44d3c25ece0b", + "translation_date": "2026-01-16T11:59:05+00:00", + "source_file": "images/banana-unripe-quick-test-prediction.png", + "language_code": "pt-BR" + }, + "bananas-ripe-vs-unripe-predictions.8d0e2034014aa50e.webp": { + "original_hash": "43cbf29c310e7358f9ac1baa54fcf34f", + "translation_date": "2026-01-16T12:05:50+00:00", + "source_file": "images/bananas-ripe-vs-unripe-predictions.png", + "language_code": "pt-BR" + }, + "basic-thermostat.a923217fd1f37e5a.webp": { + "original_hash": "50447b3cb751fb0fe9d4d79b89e2b923", + "translation_date": "2026-01-16T12:03:35+00:00", + "source_file": "images/basic-thermostat.png", + "language_code": "pt-BR" + }, + "bing-translate.348aa796d6efe2a9.webp": { + "original_hash": "357040ee1345ab2473e9b5284f85e81b", + "translation_date": "2026-01-16T11:46:28+00:00", + "source_file": "images/bing-translate.png", + "language_code": "pt-BR" + }, + "bounding-box.1420a7ea0d3d15f7.webp": { + "original_hash": "6e8d5968c9badbf125027b02a8f5cacd", + "translation_date": "2026-01-16T12:05:36+00:00", + "source_file": "images/bounding-box.png", + "language_code": "pt-BR" + }, + "bricked-car.dc38f8efadc6c59d.webp": { + "original_hash": "67716470d43e5717406c6ef7ce6f51e4", + "translation_date": "2026-01-16T12:02:47+00:00", + "source_file": "images/bricked-car.png", + "language_code": "pt-BR" + }, + "button-with-digital.3749edea8eb885af.webp": { + "original_hash": "c71d7fe1263b112c755f3d0442406df8", + "translation_date": "2026-01-16T11:54:03+00:00", + "source_file": "images/button-with-digital.png", + "language_code": "pt-BR" + }, + "button.eadb560b77ac45e5.webp": { + "original_hash": "85b6123798803252b7f30ffce7dc58c8", + "translation_date": "2026-01-16T11:46:12+00:00", + "source_file": "images/button.png", + "language_code": "pt-BR" + }, + "chart-soil-moisture-relay.fbb391236d34a64d.webp": { + "original_hash": "2528b9288bbb1201b87058b75d516b0a", + "translation_date": "2026-01-16T11:47:18+00:00", + "source_file": "images/chart-soil-moisture-relay.png", + "language_code": "pt-BR" + }, + "chart-soil-moisture.fd6d9d0cdc0b5f75.webp": { + "original_hash": "7dfa7af1913187ec9700073ccfac2d7e", + "translation_date": "2026-01-16T11:54:48+00:00", + "source_file": "images/chart-soil-moisture.png", + "language_code": "pt-BR" + }, + "child-watering-garden.9a5d3f1bfe6d0d8d.webp": { + "original_hash": "c547237141a5201756db33e5e977a363", + "translation_date": "2026-01-16T11:48:32+00:00", + "source_file": "images/child-watering-garden.jpg", + "language_code": "pt-BR" + }, + "cloud-with-edge.1e26462c62c126fe.webp": { + "original_hash": "5f1262d7eaa6699d85c7b7c89ed6eeb0", + "translation_date": "2026-01-16T11:47:59+00:00", + "source_file": "images/cloud-with-edge.png", + "language_code": "pt-BR" + }, + "cloud-without-edge.b4da641f6022c95e.webp": { + "original_hash": "7788335416c9ad8abd402188a02680b2", + "translation_date": "2026-01-16T11:56:32+00:00", + "source_file": "images/cloud-without-edge.png", + "language_code": "pt-BR" + }, + "cmos-sensor.75f9cd74decb1371.webp": { + "original_hash": "955bcd3e34765f989cd7c0df5909560d", + "translation_date": "2026-01-16T12:04:23+00:00", + "source_file": "images/cmos-sensor.png", + "language_code": "pt-BR" + }, + "commands.d6c06bbbb3a02cce.webp": { + "original_hash": "8390a0fb6de9ed7ea485aa8b7885d107", + "translation_date": "2026-01-16T12:07:30+00:00", + "source_file": "images/commands.png", + "language_code": "pt-BR" + }, + "condenser-mic.6f6ed5b76ca19e0e.webp": { + "original_hash": "b1b138069d34d7c5c124b0d8e69a8089", + "translation_date": "2026-01-16T11:58:31+00:00", + "source_file": "images/condenser-mic.jpg", + "language_code": "pt-BR" + }, + "consumer-groups.a3262e26fc27ba20.webp": { + "original_hash": "052b922d0ba2c50c83132074572c68e3", + "translation_date": "2026-01-16T11:59:39+00:00", + "source_file": "images/consumer-groups.png", + "language_code": "pt-BR" + }, + "container-edge-flow.c246050dd60ceefd.webp": { + "original_hash": "82e97f8c96fa7aa5acddb9e2bace544b", + "translation_date": "2026-01-16T11:56:55+00:00", + "source_file": "images/container-edge-flow.png", + "language_code": "pt-BR" + }, + "container-web-browser.4ee81dd4f0d8838c.webp": { + "original_hash": "ed428a4061a9c8a7bd3b46eb92709603", + "translation_date": "2026-01-16T11:53:40+00:00", + "source_file": "images/container-web-browser.png", + "language_code": "pt-BR" + }, + "counterfit-camera-options.eb3bd5150a8e7dff.webp": { + "original_hash": "bad454364357d90492676e610b7bfaaf", + "translation_date": "2026-01-16T12:00:19+00:00", + "source_file": "images/counterfit-camera-options.png", + "language_code": "pt-BR" + }, + "counterfit-camera.001ec52194c8ee5d.webp": { + "original_hash": "ce27314b8b055207bd6d020cd0f16403", + "translation_date": "2026-01-16T11:57:37+00:00", + "source_file": "images/counterfit-camera.png", + "language_code": "pt-BR" + }, + "counterfit-connected.ed30b46d8f79b092.webp": { + "original_hash": "9deaaeb5131e9a263fbbecb01f7997f6", + "translation_date": "2026-01-16T12:01:37+00:00", + "source_file": "images/counterfit-connected.png", + "language_code": "pt-BR" + }, + "counterfit-create-camera.a5de97f59c0bd3cb.webp": { + "original_hash": "d90405c8dbb6738e0e11a8ed2fea2b56", + "translation_date": "2026-01-16T11:49:50+00:00", + "source_file": "images/counterfit-create-camera.png", + "language_code": "pt-BR" + }, + "counterfit-create-distance-sensor.967c9fb98f27888d.webp": { + "original_hash": "fc393748f2ddbae005330e640d841c41", + "translation_date": "2026-01-16T11:50:34+00:00", + "source_file": "images/counterfit-create-distance-sensor.png", + "language_code": "pt-BR" + }, + "counterfit-create-gps-sensor.6385dc9357d85ad1.webp": { + "original_hash": "57eef4bdcf582fa280abe6860d6605c9", + "translation_date": "2026-01-16T11:50:38+00:00", + "source_file": "images/counterfit-create-gps-sensor.png", + "language_code": "pt-BR" + }, + "counterfit-create-humidity-sensor.2750e27b6f30e09c.webp": { + "original_hash": "2678e71d9f5f0b887059244ceb0747e2", + "translation_date": "2026-01-16T12:04:38+00:00", + "source_file": "images/counterfit-create-humidity-sensor.png", + "language_code": "pt-BR" + }, + "counterfit-create-led.ba9db1c9b8c622a6.webp": { + "original_hash": "748880e7a96e6fe87be2d253398d1d8a", + "translation_date": "2026-01-16T11:52:08+00:00", + "source_file": "images/counterfit-create-led.png", + "language_code": "pt-BR" + }, + "counterfit-create-light-sensor.9f36a5e0d4458d8d.webp": { + "original_hash": "8906d361868d0342fccec9bb4952c74b", + "translation_date": "2026-01-16T12:03:05+00:00", + "source_file": "images/counterfit-create-light-sensor.png", + "language_code": "pt-BR" + }, + "counterfit-create-relay.fa7c40fd0f2f6afc.webp": { + "original_hash": "69d09420bf11407584ef8f7c2a4b6934", + "translation_date": "2026-01-16T11:56:27+00:00", + "source_file": "images/counterfit-create-relay.png", + "language_code": "pt-BR" + }, + "counterfit-create-soil-moisture-sensor.35266135a5e0ae68.webp": { + "original_hash": "0d5b89d4e4a3e0fcd2b30cb15aa9c37f", + "translation_date": "2026-01-16T12:03:56+00:00", + "source_file": "images/counterfit-create-soil-moisture-sensor.png", + "language_code": "pt-BR" + }, + "counterfit-create-temperature-sensor.199350ed34f7343d.webp": { + "original_hash": "24a54b9c88c3efc0a31bb9d9db572985", + "translation_date": "2026-01-16T11:53:36+00:00", + "source_file": "images/counterfit-create-temperature-sensor.png", + "language_code": "pt-BR" + }, + "counterfit-distance-sensor.079eefeeea0b68af.webp": { + "original_hash": "87337c291c694bf955c4ea27d16b527b", + "translation_date": "2026-01-16T11:48:47+00:00", + "source_file": "images/counterfit-distance-sensor.png", + "language_code": "pt-BR" + }, + "counterfit-first-run.433326358b669b31.webp": { + "original_hash": "af69e87134afcc0b94a0ee13d7127e83", + "translation_date": "2026-01-16T11:47:48+00:00", + "source_file": "images/counterfit-first-run.png", + "language_code": "pt-BR" + }, + "counterfit-gps-sensor-gpxfile.8310b063ce8a425c.webp": { + "original_hash": "0160890d86b609909702f86540b4d7df", + "translation_date": "2026-01-16T11:49:59+00:00", + "source_file": "images/counterfit-gps-sensor-gpxfile.png", + "language_code": "pt-BR" + }, + "counterfit-gps-sensor-latlon.008c867d75464fbe.webp": { + "original_hash": "176d91894e0da37cc78d56aed5858fac", + "translation_date": "2026-01-16T12:02:39+00:00", + "source_file": "images/counterfit-gps-sensor-latlon.png", + "language_code": "pt-BR" + }, + "counterfit-gps-sensor-nmea.c62eea442171e17e.webp": { + "original_hash": "afbf9dca4a4c89c0b21abb6a6d163635", + "translation_date": "2026-01-16T11:46:58+00:00", + "source_file": "images/counterfit-gps-sensor-nmea.png", + "language_code": "pt-BR" + }, + "counterfit-gps-sensor.3fbb15af0a536756.webp": { + "original_hash": "f5317788426731587cefceac202102ed", + "translation_date": "2026-01-16T11:56:39+00:00", + "source_file": "images/counterfit-gps-sensor.png", + "language_code": "pt-BR" + }, + "counterfit-humidity-sensor.7b12f7f339e430cb.webp": { + "original_hash": "7bb1b1afc76c63ba7cf4c7f7bf9a134c", + "translation_date": "2026-01-16T12:07:29+00:00", + "source_file": "images/counterfit-humidity-sensor.png", + "language_code": "pt-BR" + }, + "counterfit-led.c0ab02de6d256ad8.webp": { + "original_hash": "c03cf80f7745d1caf7b7ece187e3ac7b", + "translation_date": "2026-01-16T12:06:55+00:00", + "source_file": "images/counterfit-led.png", + "language_code": "pt-BR" + }, + "counterfit-light-sensor.5d0f5584df56b90f.webp": { + "original_hash": "938da9f71fb2820061acca73bb053a68", + "translation_date": "2026-01-16T11:50:47+00:00", + "source_file": "images/counterfit-light-sensor.png", + "language_code": "pt-BR" + }, + "counterfit-relay.bbf74c1dbdc8b9ac.webp": { + "original_hash": "0a28fe42b27b9898e0eba6e65faef94a", + "translation_date": "2026-01-16T12:06:59+00:00", + "source_file": "images/counterfit-relay.png", + "language_code": "pt-BR" + }, + "counterfit-soil-moisture-sensor.81742b2de0e9de60.webp": { + "original_hash": "54613df49c9e3c09be6ddc351dae1875", + "translation_date": "2026-01-16T12:04:45+00:00", + "source_file": "images/counterfit-soil-moisture-sensor.png", + "language_code": "pt-BR" + }, + "counterfit-temperature-sensor.f0560236c96a9016.webp": { + "original_hash": "52e9ae650e824d9c36c419fcf6febef7", + "translation_date": "2026-01-16T11:48:30+00:00", + "source_file": "images/counterfit-temperature-sensor.png", + "language_code": "pt-BR" + }, + "custom-vision-banana-prediction.30cdff4e1d72db5d.webp": { + "original_hash": "1962f0cce26ba3d8a180acaec2972895", + "translation_date": "2026-01-16T12:03:10+00:00", + "source_file": "images/custom-vision-banana-prediction.png", + "language_code": "pt-BR" + }, + "custom-vision-create-object-detector-project.32d4fb9aa8e7e737.webp": { + "original_hash": "052a80c8a99c7f2a0400338775c8c132", + "translation_date": "2026-01-16T11:49:46+00:00", + "source_file": "images/custom-vision-create-object-detector-project.png", + "language_code": "pt-BR" + }, + "custom-vision-create-project.cf46325b92d8b131.webp": { + "original_hash": "4471516b6b46ce7920ac178930397ccc", + "translation_date": "2026-01-16T11:54:26+00:00", + "source_file": "images/custom-vision-create-project.png", + "language_code": "pt-BR" + }, + "custom-vision-logo.d3d4e7c8a87ec9da.webp": { + "original_hash": "b67626a2dbc98e461f19f42db2de3a5b", + "translation_date": "2026-01-16T12:03:47+00:00", + "source_file": "images/custom-vision-logo.png", + "language_code": "pt-BR" + }, + "custom-vision-object-detector-publish-button.34ee379fc650ccb9.webp": { + "original_hash": "dd33f3d305ce96a1831bd1726dc9353b", + "translation_date": "2026-01-16T12:01:15+00:00", + "source_file": "images/custom-vision-object-detector-publish-button.png", + "language_code": "pt-BR" + }, + "custom-vision-prediction-key-endpoint.30c569ffd0338864.webp": { + "original_hash": "99d1145bc97ed96e187d6a5590c4332c", + "translation_date": "2026-01-16T11:51:38+00:00", + "source_file": "images/custom-vision-prediction-key-endpoint.png", + "language_code": "pt-BR" + }, + "custom-vision-publish-button.b7174e1977b0c33b.webp": { + "original_hash": "60c4e9f0efc81552bf0ad33db2688757", + "translation_date": "2026-01-16T11:50:16+00:00", + "source_file": "images/custom-vision-publish-button.png", + "language_code": "pt-BR" + }, + "custom-vision-stock-prediction.942266ab1bcca341.webp": { + "original_hash": "0c70587ccdba9496866b14ffe90cfd7b", + "translation_date": "2026-01-16T11:59:51+00:00", + "source_file": "images/custom-vision-stock-prediction.png", + "language_code": "pt-BR" + }, + "dimmable-light.9ceffeb195dec1a8.webp": { + "original_hash": "d64c8b23c012ebdbcacfb9bc0ac88b78", + "translation_date": "2026-01-16T12:00:11+00:00", + "source_file": "images/dimmable-light.png", + "language_code": "pt-BR" + }, + "dmac-adc-buffers.4509aee49145c90b.webp": { + "original_hash": "1351cbaad314ff7f81234448cdc5a1c9", + "translation_date": "2026-01-16T11:51:46+00:00", + "source_file": "images/dmac-adc-buffers.png", + "language_code": "pt-BR" + }, + "dynamic-mic.8babac890a2d80df.webp": { + "original_hash": "56710f289e88457d2e977fc9d3806569", + "translation_date": "2026-01-16T12:04:04+00:00", + "source_file": "images/dynamic-mic.jpg", + "language_code": "pt-BR" + }, + "favicon.37b561214b36d454.webp": { + "original_hash": "228faa6584f8ba1f7e9a75e3200112e9", + "translation_date": "2026-01-16T11:48:31+00:00", + "source_file": "images/favicon.png", + "language_code": "pt-BR" + }, + "fetch-decode-execute.2fd6f150f6280392.webp": { + "original_hash": "5bf630278697e98b9d322229d98d403c", + "translation_date": "2026-01-16T11:45:14+00:00", + "source_file": "images/fetch-decode-execute.png", + "language_code": "pt-BR" + }, + "fruit-quality-detector-message-flow.adf2a65da8fd8741.webp": { + "original_hash": "a7dab1140d82034626bb8de5f186131e", + "translation_date": "2026-01-16T11:52:32+00:00", + "source_file": "images/fruit-quality-detector-message-flow.png", + "language_code": "pt-BR" + }, + "gdd-calculation-corn.64a58b7a7afcd0df.webp": { + "original_hash": "313f7af564decf12984266f48531ca25", + "translation_date": "2026-01-16T11:58:00+00:00", + "source_file": "images/gdd-calculation-corn.png", + "language_code": "pt-BR" + }, + "gdd-calculation-strawberries.59f57db94b22adb8.webp": { + "original_hash": "8bbc10fc92e798cafb77786f7fee2fec", + "translation_date": "2026-01-16T11:49:53+00:00", + "source_file": "images/gdd-calculation-strawberries.png", + "language_code": "pt-BR" + }, + "gdd-calculation.79b3660f9c5757aa.webp": { + "original_hash": "bf4227ba3a7cfaae2a832050d904960e", + "translation_date": "2026-01-16T11:54:51+00:00", + "source_file": "images/gdd-calculation.png", + "language_code": "pt-BR" + }, + "gdd-jupyter-notebook.c5b52cf21094f158.webp": { + "original_hash": "85379646b4bef7edbfb10f7f457a3fda", + "translation_date": "2026-01-16T11:51:29+00:00", + "source_file": "images/gdd-jupyter-notebook.png", + "language_code": "pt-BR" + }, + "geofence-crossing-inaccurate-gps.6a3ed911202ad9ca.webp": { + "original_hash": "478511d89755e68ad1b0a8cd6cb72eef", + "translation_date": "2026-01-16T12:00:48+00:00", + "source_file": "images/geofence-crossing-inaccurate-gps.png", + "language_code": "pt-BR" + }, + "geofence-examples.172fbc534665769f.webp": { + "original_hash": "e836773107dcaf3aa2dcbf4b072bf1d0", + "translation_date": "2026-01-16T11:49:28+00:00", + "source_file": "images/geofence-examples.png", + "language_code": "pt-BR" + }, + "gps-satellites.04acf1148fe25fbf.webp": { + "original_hash": "af44157de12f3de1e84ea34fc9da6647", + "translation_date": "2026-01-16T12:04:48+00:00", + "source_file": "images/gps-satellites.png", + "language_code": "pt-BR" + }, + "gps-telemetry-iot-hub-functions.24d3fa5592455e9f.webp": { + "original_hash": "fe6ecba627bb1ac7c0f7123dcdc89c1c", + "translation_date": "2026-01-16T11:46:23+00:00", + "source_file": "images/gps-telemetry-iot-hub-functions.png", + "language_code": "pt-BR" + }, + "gps-telemetry-iot-hub.8115335d51cd2c12.webp": { + "original_hash": "594448866b50836b5d5d664571ae8144", + "translation_date": "2026-01-16T11:56:24+00:00", + "source_file": "images/gps-telemetry-iot-hub.png", + "language_code": "pt-BR" + }, + "grove-base-hat-ribbon-cable.501fed202fcf73b1.webp": { + "original_hash": "aa2a325edef2b1fbd2d7639853d310fd", + "translation_date": "2026-01-16T12:00:02+00:00", + "source_file": "images/grove-base-hat-ribbon-cable.png", + "language_code": "pt-BR" + }, + "grove-button.a70cfbb809a85636.webp": { + "original_hash": "63615c1ec61dcf1763b1c406298bb67c", + "translation_date": "2026-01-16T12:00:40+00:00", + "source_file": "images/grove-button.png", + "language_code": "pt-BR" + }, + "grove-capacitive-soil-moisture-sensor.e7f0776cce30e78b.webp": { + "original_hash": "f1a5ee679e4c05c2b3047ef0d69f85f0", + "translation_date": "2026-01-16T12:01:27+00:00", + "source_file": "images/grove-capacitive-soil-moisture-sensor.png", + "language_code": "pt-BR" + }, + "grove-dht11.07f8eafceee17004.webp": { + "original_hash": "e66c4f14e29b96bcd1d5a8c86c19288d", + "translation_date": "2026-01-16T11:46:42+00:00", + "source_file": "images/grove-dht11.png", + "language_code": "pt-BR" + }, + "grove-gps-sensor.247943bf69b03f0d.webp": { + "original_hash": "2cdf74787c6cf892a6b1a0f1753f8b24", + "translation_date": "2026-01-16T11:53:09+00:00", + "source_file": "images/grove-gps-sensor.png", + "language_code": "pt-BR" + }, + "grove-led.6c853be93f473cf2.webp": { + "original_hash": "ccf9fb22df3755582b81bae02335135b", + "translation_date": "2026-01-16T12:01:20+00:00", + "source_file": "images/grove-led.png", + "language_code": "pt-BR" + }, + "grove-light-sensor.b8127b7c434e632d.webp": { + "original_hash": "1e6e9a840b1f0b0dd777593c38d31109", + "translation_date": "2026-01-16T11:52:16+00:00", + "source_file": "images/grove-light-sensor.png", + "language_code": "pt-BR" + }, + "grove-relay-labelled.293e068f5c3c2a19.webp": { + "original_hash": "b75dcabfa78bcfca34b6cce74323e178", + "translation_date": "2026-01-16T11:49:36+00:00", + "source_file": "images/grove-relay-labelled.png", + "language_code": "pt-BR" + }, + "grove-relay.d426958ca210fbd0.webp": { + "original_hash": "ceed414ceb65226b0e91bf1147d1fa01", + "translation_date": "2026-01-16T11:52:48+00:00", + "source_file": "images/grove-relay.png", + "language_code": "pt-BR" + }, + "grove-time-of-flight-sensor.d82ff2165bfded9f.webp": { + "original_hash": "dcc2dfd53862a2533a34b9bb7913ae90", + "translation_date": "2026-01-16T12:05:21+00:00", + "source_file": "images/grove-time-of-flight-sensor.png", + "language_code": "pt-BR" + }, + "gsm-calculation-example.99f9803b4f29e976.webp": { + "original_hash": "0421a50ee61d76fda1380f899c4fd99c", + "translation_date": "2026-01-16T12:06:01+00:00", + "source_file": "images/gsm-calculation-example.png", + "language_code": "pt-BR" + }, + "gsm-calculation.6da38c6201eec14e.webp": { + "original_hash": "9b2287a653a1fd6ee0480021a98bca3b", + "translation_date": "2026-01-16T12:05:17+00:00", + "source_file": "images/gsm-calculation.png", + "language_code": "pt-BR" + }, + "i2c.83da845dde02256b.webp": { + "original_hash": "198d21e02d4c69b84028bd69172ffa8e", + "translation_date": "2026-01-16T11:56:17+00:00", + "source_file": "images/i2c.png", + "language_code": "pt-BR" + }, + "image-classifier-cashews-tomato.bc2e16ab8f05cf9a.webp": { + "original_hash": "1b245f1520995579839a00cb93a09242", + "translation_date": "2026-01-16T12:03:43+00:00", + "source_file": "images/image-classifier-cashews-tomato.png", + "language_code": "pt-BR" + }, + "image-upload-bananas.0751639f3815e0ec.webp": { + "original_hash": "a293096ce03324bb0282c712610f6892", + "translation_date": "2026-01-16T11:59:15+00:00", + "source_file": "images/image-upload-bananas.png", + "language_code": "pt-BR" + }, + "image-upload-object-detector.77c7892c3093cb59.webp": { + "original_hash": "d66ff14cd73c4acfbb2ce4b15a256850", + "translation_date": "2026-01-16T11:46:17+00:00", + "source_file": "images/image-upload-object-detector.png", + "language_code": "pt-BR" + }, + "iot-device-and-hacked-device-connecting-encryption.5941aff601fc978f.webp": { + "original_hash": "b55ce16301f8b389703a495e87d30f89", + "translation_date": "2026-01-16T12:05:42+00:00", + "source_file": "images/iot-device-and-hacked-device-connecting-encryption.png", + "language_code": "pt-BR" + }, + "iot-device-and-hacked-device-connecting.e0671675df74d6d9.webp": { + "original_hash": "4424245692fededc88fa35415899b600", + "translation_date": "2026-01-16T12:04:01+00:00", + "source_file": "images/iot-device-and-hacked-device-connecting.png", + "language_code": "pt-BR" + }, + "iot-for-beginners.95958e2ed1900917.webp": { + "original_hash": "0ee1737da60391e3b1d48686e1d7c893", + "translation_date": "2026-01-16T11:49:30+00:00", + "source_file": "images/iot-for-beginners.png", + "language_code": "pt-BR" + }, + "iot-hub-cloud-to-device-message.f4f21fea772cc20b.webp": { + "original_hash": "d5e70a4a54a0038278c5bdc2b4988f8e", + "translation_date": "2026-01-16T12:07:34+00:00", + "source_file": "images/iot-hub-cloud-to-device-message.png", + "language_code": "pt-BR" + }, + "iot-hub-device-to-cloud-message.e46e584d87f35fd9.webp": { + "original_hash": "f080414808052183955ae04971260ebb", + "translation_date": "2026-01-16T12:06:52+00:00", + "source_file": "images/iot-hub-device-to-cloud-message.png", + "language_code": "pt-BR" + }, + "iot-hub-device-twins.7055a60fc5e2331c.webp": { + "original_hash": "ddaade630edadb655820875bc6a7a398", + "translation_date": "2026-01-16T11:47:04+00:00", + "source_file": "images/iot-hub-device-twins.png", + "language_code": "pt-BR" + }, + "iot-hub-direct-method-request.86a5026e91f4ca18.webp": { + "original_hash": "8940e81543500cb4f065eed262888ba0", + "translation_date": "2026-01-16T12:04:13+00:00", + "source_file": "images/iot-hub-direct-method-request.png", + "language_code": "pt-BR" + }, + "iot-messages-to-serverless.0194da1cc0732bb7.webp": { + "original_hash": "b845f5d76ec996b99ee19d76c7254e4f", + "translation_date": "2026-01-16T11:52:57+00:00", + "source_file": "images/iot-messages-to-serverless.png", + "language_code": "pt-BR" + }, + "iot-reference-architecture-azure.0b8d2161af924cb1.webp": { + "original_hash": "cf394dd153db645ed55d362824b4beff", + "translation_date": "2026-01-16T11:55:26+00:00", + "source_file": "images/iot-reference-architecture-azure.png", + "language_code": "pt-BR" + }, + "iot-reference-architecture-fruit-quality.cc705f121c3b6fa7.webp": { + "original_hash": "23d41791f8c62c0f91da0979160cada7", + "translation_date": "2026-01-16T11:50:56+00:00", + "source_file": "images/iot-reference-architecture-fruit-quality.png", + "language_code": "pt-BR" + }, + "iot-reference-architecture.2278b98b55c6d4e8.webp": { + "original_hash": "a06f575f400e2323f68d231b4867cee4", + "translation_date": "2026-01-16T11:59:22+00:00", + "source_file": "images/iot-reference-architecture.png", + "language_code": "pt-BR" + }, + "iot-service-allowed-denied-connection.818b0063ac213fb8.webp": { + "original_hash": "e39609b2a6e0a6f3a09f869f30654e4c", + "translation_date": "2026-01-16T12:04:09+00:00", + "source_file": "images/iot-service-allowed-denied-connection.png", + "language_code": "pt-BR" + }, + "iot-service-connectivity.7e873847921a5d6f.webp": { + "original_hash": "b69786f576a7862abc86d0d03a68ebb7", + "translation_date": "2026-01-16T11:54:09+00:00", + "source_file": "images/iot-service-connectivity.png", + "language_code": "pt-BR" + }, + "latitude-equator.feccc3214b7d9fb1.webp": { + "original_hash": "56a4f9ad1e573c57538578c32f9d86da", + "translation_date": "2026-01-16T11:52:33+00:00", + "source_file": "images/latitude-equator.png", + "language_code": "pt-BR" + }, + "latitude-lines.11d8d91dfb2014a5.webp": { + "original_hash": "a0c885ec44be899480f5e591ff23f911", + "translation_date": "2026-01-16T11:47:53+00:00", + "source_file": "images/latitude-lines.png", + "language_code": "pt-BR" + }, + "led-digital-control.13b9be14077ea49f.webp": { + "original_hash": "48875cd4b26e07780599d8a068c0bf83", + "translation_date": "2026-01-16T11:58:28+00:00", + "source_file": "images/led-digital-control.png", + "language_code": "pt-BR" + }, + "led.ec6d94f66676a174.webp": { + "original_hash": "8dd1438a3970c2bd893f35af372b1a60", + "translation_date": "2026-01-16T12:02:50+00:00", + "source_file": "images/led.png", + "language_code": "pt-BR" + }, + "lesson-1.2606670fa61ee904.webp": { + "original_hash": "84859c69fb3a2f18ffbe095a2102d7f6", + "translation_date": "2026-01-16T12:24:03+00:00", + "source_file": "sketchnotes/lesson-1.jpg", + "language_code": "pt-BR" + }, + "lesson-10.829c86b80b9403bb.webp": { + "original_hash": "d01fb71820808d72515cf0b7d68bab41", + "translation_date": "2026-01-16T12:24:10+00:00", + "source_file": "sketchnotes/lesson-10.jpg", + "language_code": "pt-BR" + }, + "lesson-11.9fddbac4b664c6d5.webp": { + "original_hash": "b1f802eab377a9252f62e9309f8e592a", + "translation_date": "2026-01-16T12:24:31+00:00", + "source_file": "sketchnotes/lesson-11.jpg", + "language_code": "pt-BR" + }, + "lesson-12.ca7f53039712a3ec.webp": { + "original_hash": "967e8e3853bc164050b097ea16490057", + "translation_date": "2026-01-16T12:14:48+00:00", + "source_file": "sketchnotes/lesson-12.jpg", + "language_code": "pt-BR" + }, + "lesson-13.a259db1485021be7.webp": { + "original_hash": "49048659f9a44917256f7b4b7f864f62", + "translation_date": "2026-01-16T12:14:01+00:00", + "source_file": "sketchnotes/lesson-13.jpg", + "language_code": "pt-BR" + }, + "lesson-14.63980c5150ae3c15.webp": { + "original_hash": "b6ce8e2bb49d1616057ee45f2e37fe8f", + "translation_date": "2026-01-16T12:20:48+00:00", + "source_file": "sketchnotes/lesson-14.jpg", + "language_code": "pt-BR" + }, + "lesson-15.843d21afdc6fb2bb.webp": { + "original_hash": "c44ff172164fdfbafabf0c806f5e8593", + "translation_date": "2026-01-16T12:07:58+00:00", + "source_file": "sketchnotes/lesson-15.jpg", + "language_code": "pt-BR" + }, + "lesson-16.215daf18b00631fb.webp": { + "original_hash": "0bd07a79a71954ad4f5b585972d4deb9", + "translation_date": "2026-01-16T12:15:01+00:00", + "source_file": "sketchnotes/lesson-16.jpg", + "language_code": "pt-BR" + }, + "lesson-17.bc333c3c35ba8e42.webp": { + "original_hash": "5f7d869576300be85ed519ef16ff6a39", + "translation_date": "2026-01-16T12:14:28+00:00", + "source_file": "sketchnotes/lesson-17.jpg", + "language_code": "pt-BR" + }, + "lesson-18.92c32ed1d354caa5.webp": { + "original_hash": "89d2f47ae6201d70aec617d32cd09f53", + "translation_date": "2026-01-16T12:24:24+00:00", + "source_file": "sketchnotes/lesson-18.jpg", + "language_code": "pt-BR" + }, + "lesson-19.cf6973cecadf080c.webp": { + "original_hash": "7e8769bcee6aeb9ebbb9c1752847f908", + "translation_date": "2026-01-16T12:11:06+00:00", + "source_file": "sketchnotes/lesson-19.jpg", + "language_code": "pt-BR" + }, + "lesson-2.324b0580d620c25e.webp": { + "original_hash": "ec89ab3c7a4154d500a4249e4b611ce3", + "translation_date": "2026-01-16T12:20:36+00:00", + "source_file": "sketchnotes/lesson-2.jpg", + "language_code": "pt-BR" + }, + "lesson-20.0211df9551a8abb3.webp": { + "original_hash": "6955631846f6c3a04436440cbe55ec9e", + "translation_date": "2026-01-16T12:07:52+00:00", + "source_file": "sketchnotes/lesson-20.jpg", + "language_code": "pt-BR" + }, + "lesson-21.e34de51354d6606f.webp": { + "original_hash": "918fab6c83b650cf67a39f5a9e740609", + "translation_date": "2026-01-16T12:14:08+00:00", + "source_file": "sketchnotes/lesson-21.jpg", + "language_code": "pt-BR" + }, + "lesson-22.6148ea28500d9e00.webp": { + "original_hash": "744a23c671043c5538445857370ea60e", + "translation_date": "2026-01-16T12:14:16+00:00", + "source_file": "sketchnotes/lesson-22.jpg", + "language_code": "pt-BR" + }, + "lesson-23.f38483e1d4df4828.webp": { + "original_hash": "cef842f7b80b336838233fcf1be1029c", + "translation_date": "2026-01-16T12:21:05+00:00", + "source_file": "sketchnotes/lesson-23.jpg", + "language_code": "pt-BR" + }, + "lesson-24.4246968ed058510a.webp": { + "original_hash": "08ff9d2f7cd0d595eb30e96375add9f3", + "translation_date": "2026-01-16T12:14:40+00:00", + "source_file": "sketchnotes/lesson-24.jpg", + "language_code": "pt-BR" + }, + "lesson-3.cc3b7b4cd646de59.webp": { + "original_hash": "4ef30b3fb0ed4914bfc4753db2e99a7b", + "translation_date": "2026-01-16T12:10:55+00:00", + "source_file": "sketchnotes/lesson-3.jpg", + "language_code": "pt-BR" + }, + "lesson-4.7344e074ea68fa54.webp": { + "original_hash": "8fec62a3c5722c6c9adeb713c30d685c", + "translation_date": "2026-01-16T12:17:41+00:00", + "source_file": "sketchnotes/lesson-4.jpg", + "language_code": "pt-BR" + }, + "lesson-5.42b234299279d263.webp": { + "original_hash": "691cf783fe7ef6b40bf300481e7326d2", + "translation_date": "2026-01-16T12:08:04+00:00", + "source_file": "sketchnotes/lesson-5.jpg", + "language_code": "pt-BR" + }, + "lesson-6.3e493b60eee85adc.webp": { + "original_hash": "94d827c7b07c857cf86360f7a42734e0", + "translation_date": "2026-01-16T12:20:42+00:00", + "source_file": "sketchnotes/lesson-6.jpg", + "language_code": "pt-BR" + }, + "lesson-7.30b5f577d3cb8e03.webp": { + "original_hash": "65e26ac18d8f2455e8c5241431133288", + "translation_date": "2026-01-16T12:07:43+00:00", + "source_file": "sketchnotes/lesson-7.jpg", + "language_code": "pt-BR" + }, + "lesson-8.3f21f3c11159e6a0.webp": { + "original_hash": "43f49f9a260610f3e5493dfdc6dc0d7f", + "translation_date": "2026-01-16T12:14:55+00:00", + "source_file": "sketchnotes/lesson-8.jpg", + "language_code": "pt-BR" + }, + "lesson-9.dfe99c8e891f48e1.webp": { + "original_hash": "7d6641c90a95897e05e60033cf61367f", + "translation_date": "2026-01-16T12:20:55+00:00", + "source_file": "sketchnotes/lesson-9.jpg", + "language_code": "pt-BR" + }, + "light-switch.760317ad6ab8bd6d.webp": { + "original_hash": "41d49f69f3e43729085745abb67167b8", + "translation_date": "2026-01-16T11:45:20+00:00", + "source_file": "images/light-switch.png", + "language_code": "pt-BR" + }, + "lines-of-longitude-and-latitude.032aca9d3e402c4e.webp": { + "original_hash": "f8604251b9319c765df2a2046e4d5f93", + "translation_date": "2026-01-16T12:03:34+00:00", + "source_file": "images/lines-of-longitude-and-latitude.png", + "language_code": "pt-BR" + }, + "longitude-meridians.ab4ef1c91c064586.webp": { + "original_hash": "dc8d5df51066d4009ed1696d40ae016d", + "translation_date": "2026-01-16T11:50:41+00:00", + "source_file": "images/longitude-meridians.png", + "language_code": "pt-BR" + }, + "longitude-prime-meridian.33b01b41ce615f9d.webp": { + "original_hash": "470be2d3dacf49b2a2a6ce93ac32169a", + "translation_date": "2026-01-16T12:05:18+00:00", + "source_file": "images/longitude-prime-meridian.png", + "language_code": "pt-BR" + }, + "luis-intent-examples.25716580b2d2723c.webp": { + "original_hash": "10c4351eab0a8d50545a8ae5dab7e893", + "translation_date": "2026-01-16T11:56:45+00:00", + "source_file": "images/luis-intent-examples.png", + "language_code": "pt-BR" + }, + "luis-logo.5cb4f3e88c020ee6.webp": { + "original_hash": "501332df88cd55536be18754a26caffd", + "translation_date": "2026-01-16T11:55:16+00:00", + "source_file": "images/luis-logo.png", + "language_code": "pt-BR" + }, + "map-image.8fb2c53eb23ef39c.webp": { + "original_hash": "77c5609ccd32add2358d07375e1fb4ae", + "translation_date": "2026-01-16T12:05:14+00:00", + "source_file": "images/map-image.png", + "language_code": "pt-BR" + }, + "map-path.896832e72dc696ff.webp": { + "original_hash": "208641a804743048d5172bdcb674c6ce", + "translation_date": "2026-01-16T12:07:14+00:00", + "source_file": "images/map-path.png", + "language_code": "pt-BR" + }, + "mems-microphone.80574019e1f5e4d9.webp": { + "original_hash": "9fcdab93cb1a5f075fd7a7b87ee53ebd", + "translation_date": "2026-01-16T11:54:54+00:00", + "source_file": "images/mems-microphone.png", + "language_code": "pt-BR" + }, + "microsoft-gps-location-world.a321d481b010f6ad.webp": { + "original_hash": "deb0e7f79cc481afac238c73149d2f22", + "translation_date": "2026-01-16T11:48:23+00:00", + "source_file": "images/microsoft-gps-location-world.png", + "language_code": "pt-BR" + }, + "microsoft-gps-location.9eb77a13b22b7e70.webp": { + "original_hash": "657b30303221896c044fd9e1b9477c95", + "translation_date": "2026-01-16T11:53:32+00:00", + "source_file": "images/microsoft-gps-location.png", + "language_code": "pt-BR" + }, + "mobile-controlled-thermostat.4a994010473d8d6a.webp": { + "original_hash": "e5d3e7697b231ed03c0c9fcb05a79862", + "translation_date": "2026-01-16T12:07:23+00:00", + "source_file": "images/mobile-controlled-thermostat.png", + "language_code": "pt-BR" + }, + "mqtt.cbf7f21d9adc3e17.webp": { + "original_hash": "2622674075f6379bb851806552374257", + "translation_date": "2026-01-16T12:06:04+00:00", + "source_file": "images/mqtt.png", + "language_code": "pt-BR" + }, + "noqsl-database.62d24ccf5b73f60d.webp": { + "original_hash": "64109b6306a3c464b6e2b8bfb6a45665", + "translation_date": "2026-01-16T11:55:49+00:00", + "source_file": "images/noqsl-database.png", + "language_code": "pt-BR" + }, + "object-detector-cashews-tomato.1af7c26686b4db0e.webp": { + "original_hash": "3cb4f511cff4896b333181b8c0d19aa1", + "translation_date": "2026-01-16T12:03:26+00:00", + "source_file": "images/object-detector-cashews-tomato.png", + "language_code": "pt-BR" + }, + "object-detector-detected-tomato-paste.52656fe87af4c37b.webp": { + "original_hash": "5957b9bcae573e01c045354fc978f5e8", + "translation_date": "2026-01-16T11:54:41+00:00", + "source_file": "images/object-detector-detected-tomato-paste.png", + "language_code": "pt-BR" + }, + "object-detector-tag-tomato-paste.f47c362fb0f0eb58.webp": { + "original_hash": "453f6250e67659d363e7933e3999cd64", + "translation_date": "2026-01-16T11:55:41+00:00", + "source_file": "images/object-detector-tag-tomato-paste.png", + "language_code": "pt-BR" + }, + "optical-tomato-sorting.61aa134bdda4e5b1.webp": { + "original_hash": "ded722d4e89f50699032f038b439866d", + "translation_date": "2026-01-16T11:45:25+00:00", + "source_file": "images/optical-tomato-sorting.png", + "language_code": "pt-BR" + }, + "overlap-object-detection.d431e03cae75072a.webp": { + "original_hash": "9948ca331a7cbbf2ac9d7bb692603b20", + "translation_date": "2026-01-16T11:59:32+00:00", + "source_file": "images/overlap-object-detection.png", + "language_code": "pt-BR" + }, + "pi-button.c7a1a4f55943341c.webp": { + "original_hash": "94a08cd32cf5d198961e75bfb4ccd2d1", + "translation_date": "2026-01-16T11:55:14+00:00", + "source_file": "images/pi-button.png", + "language_code": "pt-BR" + }, + "pi-camera-module.4278753c31bd6e75.webp": { + "original_hash": "296dbc7764a334c9eea6e07d2bdf5228", + "translation_date": "2026-01-16T11:58:25+00:00", + "source_file": "images/pi-camera-module.png", + "language_code": "pt-BR" + }, + "pi-camera-ribbon-cable.0bf82acd251611c2.webp": { + "original_hash": "3ac274f1a38658e40c3c392746941cbd", + "translation_date": "2026-01-16T11:56:59+00:00", + "source_file": "images/pi-camera-ribbon-cable.png", + "language_code": "pt-BR" + }, + "pi-camera-socket-ribbon-cable.a18309920b118009.webp": { + "original_hash": "b34d7c3590218945fe8ac3cae8e30a50", + "translation_date": "2026-01-16T11:48:39+00:00", + "source_file": "images/pi-camera-socket-ribbon-cable.png", + "language_code": "pt-BR" + }, + "pi-camera-upside-down.5376961ba3145988.webp": { + "original_hash": "b242672b0a16425dc0c42e3458102e8c", + "translation_date": "2026-01-16T12:05:30+00:00", + "source_file": "images/pi-camera-upside-down.png", + "language_code": "pt-BR" + }, + "pi-gps-sensor.1f99ee2b2f652891.webp": { + "original_hash": "8096ac9ce04e5268b552024983283a21", + "translation_date": "2026-01-16T11:55:01+00:00", + "source_file": "images/pi-gps-sensor.png", + "language_code": "pt-BR" + }, + "pi-hardware-kit.26dbadaedb7dd44c.webp": { + "original_hash": "ff01874bf7ab355748ac69e0d18cc3a8", + "translation_date": "2026-01-16T11:47:37+00:00", + "source_file": "images/pi-hardware-kit.png", + "language_code": "pt-BR" + }, + "pi-led.97f1d474981dc35d.webp": { + "original_hash": "8c9c44daca0bb84fff271932128548e7", + "translation_date": "2026-01-16T11:58:03+00:00", + "source_file": "images/pi-led.png", + "language_code": "pt-BR" + }, + "pi-light-sensor.66cc1e31fa48cd7d.webp": { + "original_hash": "24c2a1d065061a13b890b6808abf158f", + "translation_date": "2026-01-16T11:56:20+00:00", + "source_file": "images/pi-light-sensor.png", + "language_code": "pt-BR" + }, + "pi-relay-and-soil-moisture-sensor.02f3198975b8c53e.webp": { + "original_hash": "dc129413981ef906b6edd50f837a9e01", + "translation_date": "2026-01-16T11:50:23+00:00", + "source_file": "images/pi-relay-and-soil-moisture-sensor.png", + "language_code": "pt-BR" + }, + "pi-respeaker-hat.f00fabe7dd039a93.webp": { + "original_hash": "831331e5010f14df7262034ca67a316d", + "translation_date": "2026-01-16T11:48:51+00:00", + "source_file": "images/pi-respeaker-hat.png", + "language_code": "pt-BR" + }, + "pi-soil-moisture-sensor.fdd7eb2393792cf6.webp": { + "original_hash": "c50b9b78b749af1958d574aa38253e66", + "translation_date": "2026-01-16T11:59:28+00:00", + "source_file": "images/pi-soil-moisture-sensor.png", + "language_code": "pt-BR" + }, + "pi-temperature-sensor.3ff82fff672c8e56.webp": { + "original_hash": "feb99d03e3c82faf6a583cafea990fba", + "translation_date": "2026-01-16T12:02:52+00:00", + "source_file": "images/pi-temperature-sensor.png", + "language_code": "pt-BR" + }, + "pi-time-of-flight-sensor.58c8dc04eb3bfb57.webp": { + "original_hash": "ddc354c7922b02d7be67a7bbca792ad8", + "translation_date": "2026-01-16T12:01:51+00:00", + "source_file": "images/pi-time-of-flight-sensor.png", + "language_code": "pt-BR" + }, + "plant-growth-temp-graph copy.65baa28afd9b7f5f.webp": { + "original_hash": "af7d47772297c3a84f2c2f4c519a98ee", + "translation_date": "2026-01-16T11:47:40+00:00", + "source_file": "images/plant-growth-temp-graph copy.png", + "language_code": "pt-BR" + }, + "plant-growth-temp-graph.c6d69c9478e6ca83.webp": { + "original_hash": "af7d47772297c3a84f2c2f4c519a98ee", + "translation_date": "2026-01-16T12:04:26+00:00", + "source_file": "images/plant-growth-temp-graph.png", + "language_code": "pt-BR" + }, + "polygon-points.302193da381cb415.webp": { + "original_hash": "01b6fa2d97b4fecb638b5162873f5ea9", + "translation_date": "2026-01-16T11:54:00+00:00", + "source_file": "images/polygon-points.png", + "language_code": "pt-BR" + }, + "potentiometer.35a348b9ce22f6ec.webp": { + "original_hash": "1fb25de33028ef905bf4cce330a9e6df", + "translation_date": "2026-01-16T12:06:32+00:00", + "source_file": "images/potentiometer.png", + "language_code": "pt-BR" + }, + "proximity-sensor.f5cd752c77fb62fe.webp": { + "original_hash": "46a4e21d2d633afa6120896b66b1b1f3", + "translation_date": "2026-01-16T12:06:17+00:00", + "source_file": "images/proximity-sensor.png", + "language_code": "pt-BR" + }, + "pub-sub.7c7ed43fe9fd15d4.webp": { + "original_hash": "e5ec0def10a72676eb757b830b8ae56e", + "translation_date": "2026-01-16T12:01:33+00:00", + "source_file": "images/pub-sub.png", + "language_code": "pt-BR" + }, + "pump-wired-to-relay.66c5cfc0d8918990.webp": { + "original_hash": "84a8c5f06d634c142ee4764b91ec4f59", + "translation_date": "2026-01-16T12:06:08+00:00", + "source_file": "images/pump-wired-to-relay.png", + "language_code": "pt-BR" + }, + "pwm-motor-150rpm.83347ac04ca38482.webp": { + "original_hash": "f829c583c9b05918631c9afec52dfad9", + "translation_date": "2026-01-16T11:53:50+00:00", + "source_file": "images/pwm-motor-150rpm.png", + "language_code": "pt-BR" + }, + "pwm-motor-75rpm.a5e4c939934b6e14.webp": { + "original_hash": "27174930eae0dd1d408ca7474099ebed", + "translation_date": "2026-01-16T12:00:55+00:00", + "source_file": "images/pwm-motor-75rpm.png", + "language_code": "pt-BR" + }, + "ram-comparison.6beb73541b42ac6f.webp": { + "original_hash": "178bedf746f370deb9b3600fe15afeb1", + "translation_date": "2026-01-16T11:53:55+00:00", + "source_file": "images/ram-comparison.png", + "language_code": "pt-BR" + }, + "raspberry-pi-4.fd4590d308c3d456.webp": { + "original_hash": "a6546a4c48ae28af3154546daeec43b2", + "translation_date": "2026-01-16T11:45:18+00:00", + "source_file": "images/raspberry-pi-4.jpg", + "language_code": "pt-BR" + }, + "raspberry-pi-imager.24aedeab9e233d84.webp": { + "original_hash": "d60a21f44e34a41ca0b925837b7822d2", + "translation_date": "2026-01-16T11:58:21+00:00", + "source_file": "images/raspberry-pi-imager.png", + "language_code": "pt-BR" + }, + "raspberry-pi-logo.4efaa16605cee054.webp": { + "original_hash": "6dc3ec9908411f01f40bdb144eb0352d", + "translation_date": "2026-01-16T12:03:30+00:00", + "source_file": "images/raspberry-pi-logo.png", + "language_code": "pt-BR" + }, + "raspberry-pi-zero.f7a4133e1e7d54bb.webp": { + "original_hash": "a65b4f80e337bb75907ba9668d0ec4ec", + "translation_date": "2026-01-16T11:57:29+00:00", + "source_file": "images/raspberry-pi-zero.jpg", + "language_code": "pt-BR" + }, + "relay-off.c34a178a2960fecd.webp": { + "original_hash": "695bf246ae769e65b44448d48b762bd1", + "translation_date": "2026-01-16T11:46:08+00:00", + "source_file": "images/relay-off.png", + "language_code": "pt-BR" + }, + "relay-on.4db16a0fd6b66926.webp": { + "original_hash": "9845f9c1489a850aa549e224cbe72d2a", + "translation_date": "2026-01-16T11:47:51+00:00", + "source_file": "images/relay-on.png", + "language_code": "pt-BR" + }, + "resistive-soil-moisture-sensor.728a138a3d109e06.webp": { + "original_hash": "10868a092da0bc909f5cc4639401c811", + "translation_date": "2026-01-16T12:01:00+00:00", + "source_file": "images/resistive-soil-moisture-sensor.png", + "language_code": "pt-BR" + }, + "respeaker-35mm-speaker.ad79ef4f128c7751.webp": { + "original_hash": "8df5ce34dedc6d09c1b32061af983e1a", + "translation_date": "2026-01-16T12:03:00+00:00", + "source_file": "images/respeaker-35mm-speaker.png", + "language_code": "pt-BR" + }, + "respeaker-jst-speaker.a441d177809df945.webp": { + "original_hash": "c4dff6a9a83d65415477d8b77818c184", + "translation_date": "2026-01-16T11:57:25+00:00", + "source_file": "images/respeaker-jst-speaker.png", + "language_code": "pt-BR" + }, + "respeaker.f5d19d1c6b14ab16.webp": { + "original_hash": "f096205f8ed79a62c0b3223ca9760485", + "translation_date": "2026-01-16T11:47:09+00:00", + "source_file": "images/respeaker.png", + "language_code": "pt-BR" + }, + "ribbon-mic.eacc8e092c7441ca.webp": { + "original_hash": "2d5dac0dede2c3bee039d05cb8d5eb01", + "translation_date": "2026-01-16T11:50:29+00:00", + "source_file": "images/ribbon-mic.jpg", + "language_code": "pt-BR" + }, + "rpi-stock-with-bounding-boxes.b5540e2ecb7cd49f.webp": { + "original_hash": "d801ce817c0839b0f611e0b73bf4f05d", + "translation_date": "2026-01-16T11:57:46+00:00", + "source_file": "images/rpi-stock-with-bounding-boxes.jpg", + "language_code": "pt-BR" + }, + "sampling.6f4fadb3f2d9dfe7.webp": { + "original_hash": "0873e1919ecfcd1fac59791d08b2458f", + "translation_date": "2026-01-16T12:02:40+00:00", + "source_file": "images/sampling.png", + "language_code": "pt-BR" + }, + "save-telemetry-database.ddc9c6bea0c5ba39.webp": { + "original_hash": "161b3f7c079d04498fbc0d900788510e", + "translation_date": "2026-01-16T12:06:34+00:00", + "source_file": "images/save-telemetry-database.png", + "language_code": "pt-BR" + }, + "save-telemetry-to-storage-from-functions.ed3b1820980097f1.webp": { + "original_hash": "a03847815181206801649c4168cec3a1", + "translation_date": "2026-01-16T12:02:32+00:00", + "source_file": "images/save-telemetry-to-storage-from-functions.png", + "language_code": "pt-BR" + }, + "search-buffer-and-distance.e6a79af3898183c7.webp": { + "original_hash": "4fa75893d571e0dd38a6d9835877b318", + "translation_date": "2026-01-16T12:06:24+00:00", + "source_file": "images/search-buffer-and-distance.png", + "language_code": "pt-BR" + }, + "seeed-logo.74732b6b482b6e8e.webp": { + "original_hash": "c7479fe98cfdb3be95dda1ceee7a2b0f", + "translation_date": "2026-01-16T12:01:40+00:00", + "source_file": "images/seeed-logo.png", + "language_code": "pt-BR" + }, + "select-the-random-checkbox-and-set-a-range.32cf4bc7c12e797f.webp": { + "original_hash": "38727cd537789a1b4e18ca8277ee85b1", + "translation_date": "2026-01-16T12:07:22+00:00", + "source_file": "images/select-the-random-checkbox-and-set-a-range.png", + "language_code": "pt-BR" + }, + "send-message-asymmetric.7abe327c62615b8c.webp": { + "original_hash": "0873f3deafa225ede589e282db569fd3", + "translation_date": "2026-01-16T12:00:08+00:00", + "source_file": "images/send-message-asymmetric.png", + "language_code": "pt-BR" + }, + "send-message-certificate.9cc576ac1e46b76e.webp": { + "original_hash": "df8c0a10f8e11172061fb4bbde04cec0", + "translation_date": "2026-01-16T11:52:04+00:00", + "source_file": "images/send-message-certificate.png", + "language_code": "pt-BR" + }, + "send-message-symmetric-key-hacker.e7cb53db1707adfb.webp": { + "original_hash": "da84d1704f66fc3573b68394cd8d63ab", + "translation_date": "2026-01-16T11:57:55+00:00", + "source_file": "images/send-message-symmetric-key-hacker.png", + "language_code": "pt-BR" + }, + "send-message-symmetric-key.a2e8ad0d495896ff.webp": { + "original_hash": "ea8f8a45fea06564fb75f7444db90d6d", + "translation_date": "2026-01-16T11:52:54+00:00", + "source_file": "images/send-message-symmetric-key.png", + "language_code": "pt-BR" + }, + "sentence-as-intent-entities.301401696f992259.webp": { + "original_hash": "20bc069192582a5b8ba4a45d60362dd1", + "translation_date": "2026-01-16T12:04:34+00:00", + "source_file": "images/sentence-as-intent-entities.png", + "language_code": "pt-BR" + }, + "serverless-scaling.f8c769adf0413fd1.webp": { + "original_hash": "bfa04832aefaa493dbb81bda0fe64bf8", + "translation_date": "2026-01-16T11:46:02+00:00", + "source_file": "images/serverless-scaling.png", + "language_code": "pt-BR" + }, + "shapes-to-images.1a309f0ea88dd66f.webp": { + "original_hash": "4673701d4985ae9110e41a793f89d7a2", + "translation_date": "2026-01-16T12:05:58+00:00", + "source_file": "images/shapes-to-images.png", + "language_code": "pt-BR" + }, + "smarter-thermostat.a75855f15d2d9e63.webp": { + "original_hash": "7e07ad6473af5b68b49b1fb8b18be243", + "translation_date": "2026-01-16T12:06:45+00:00", + "source_file": "images/smarter-thermostat.png", + "language_code": "pt-BR" + }, + "soil-moisture-delay.865f3fae206db01d.webp": { + "original_hash": "2fbb54ffd35ea4b7bab4232986add7ff", + "translation_date": "2026-01-16T11:57:22+00:00", + "source_file": "images/soil-moisture-delay.png", + "language_code": "pt-BR" + }, + "soil-moisture-sensor-in-soil.bfad91002bda5e96.webp": { + "original_hash": "2b3a8b0115e4a957fc188dcd60aecbae", + "translation_date": "2026-01-16T11:55:32+00:00", + "source_file": "images/soil-moisture-sensor-in-soil.png", + "language_code": "pt-BR" + }, + "soil-moisture-to-voltage-with-reading.681cb3e1f8b68caf.webp": { + "original_hash": "feedc1062e7650b1033eae28a4718f5c", + "translation_date": "2026-01-16T12:01:44+00:00", + "source_file": "images/soil-moisture-to-voltage-with-reading.png", + "language_code": "pt-BR" + }, + "soil-moisture-to-voltage.df86d80cda158700.webp": { + "original_hash": "a8deda9a89889040b0802aacaf02c0db", + "translation_date": "2026-01-16T11:55:21+00:00", + "source_file": "images/soil-moisture-to-voltage.png", + "language_code": "pt-BR" + }, + "soil-moisture-travel.a0e31af222cf1438.webp": { + "original_hash": "dacaf2385f73dadd43abdacd4812399d", + "translation_date": "2026-01-16T12:03:45+00:00", + "source_file": "images/soil-moisture-travel.png", + "language_code": "pt-BR" + }, + "spi.297431d6f98b386b.webp": { + "original_hash": "69b6cd30118f966b9a2646d6ec34944f", + "translation_date": "2026-01-16T11:55:07+00:00", + "source_file": "images/spi.png", + "language_code": "pt-BR" + }, + "sql-database.be160f12bfccefd3.webp": { + "original_hash": "eab9c93e1f46ee7f1520b61a9486c9c0", + "translation_date": "2026-01-16T12:06:30+00:00", + "source_file": "images/sql-database.png", + "language_code": "pt-BR" + }, + "stock-7-cans-tomato-paste.f86059cc573d7bec.webp": { + "original_hash": "01dac6278467a7ebc669ccde8d957954", + "translation_date": "2026-01-16T11:45:56+00:00", + "source_file": "images/stock-7-cans-tomato-paste.png", + "language_code": "pt-BR" + }, + "stock-rogue-corn.be1f3ada8c457854.webp": { + "original_hash": "76a508a11e7a91138b7a515e6c1cd93c", + "translation_date": "2026-01-16T11:58:58+00:00", + "source_file": "images/stock-rogue-corn.png", + "language_code": "pt-BR" + }, + "strawberry-with-pump.b410fc72ac6aabad.webp": { + "original_hash": "af6fbb23fcab01f826392b6944dea49e", + "translation_date": "2026-01-16T11:55:43+00:00", + "source_file": "images/strawberry-with-pump.png", + "language_code": "pt-BR" + }, + "telemetry.21e5d8b97649d2eb.webp": { + "original_hash": "65fa3e3b915dbebffbab7d72f200e4e7", + "translation_date": "2026-01-16T11:50:48+00:00", + "source_file": "images/telemetry.png", + "language_code": "pt-BR" + }, + "temperature-as-digital.85004491b977bae1.webp": { + "original_hash": "cd1fed630adeb671a51171136afe0a11", + "translation_date": "2026-01-16T11:57:32+00:00", + "source_file": "images/temperature-as-digital.png", + "language_code": "pt-BR" + }, + "time-of-flight-banana.079921ad8b1496e4.webp": { + "original_hash": "2617486ad1d365e9272698f6c8e80523", + "translation_date": "2026-01-16T12:00:22+00:00", + "source_file": "images/time-of-flight-banana.png", + "language_code": "pt-BR" + }, + "traditional-vs-ml.5c20c169621fa539.webp": { + "original_hash": "7ba80f8ce61fc58a79619972640123b7", + "translation_date": "2026-01-16T11:53:47+00:00", + "source_file": "images/traditional-vs-ml.png", + "language_code": "pt-BR" + }, + "translated-smart-timer.08ac20057fdc5c37.webp": { + "original_hash": "f0bc8a93e3e880f4362f14db64377b44", + "translation_date": "2026-01-16T11:53:05+00:00", + "source_file": "images/translated-smart-timer.png", + "language_code": "pt-BR" + }, + "transpiration.b735aa34e4372e65.webp": { + "original_hash": "cdaa5c2392fbae09e27cecbd2163fead", + "translation_date": "2026-01-16T12:04:20+00:00", + "source_file": "images/transpiration.png", + "language_code": "pt-BR" + }, + "tts-overview.193843cf3f5ee09f.webp": { + "original_hash": "60bcfe389948c72835cba3d41cc92643", + "translation_date": "2026-01-16T12:02:57+00:00", + "source_file": "images/tts-overview.png", + "language_code": "pt-BR" + }, + "uart.d0dbd3fb9e3728c6.webp": { + "original_hash": "69f7d23a9049bf351ed17aaf49400cce", + "translation_date": "2026-01-16T12:00:21+00:00", + "source_file": "images/uart.png", + "language_code": "pt-BR" + }, + "vscode-azure-functions-init-notification.bd19b49229963edb.webp": { + "original_hash": "631bfd744e57eadbdf63c0bf59b5addf", + "translation_date": "2026-01-16T12:06:14+00:00", + "source_file": "images/vscode-azure-functions-init-notification.png", + "language_code": "pt-BR" + }, + "vscode-kill-terminal.1cc4de7c6f25ee08.webp": { + "original_hash": "b22d79cb8cfc5bfb5adea2ab797d1498", + "translation_date": "2026-01-16T11:57:37+00:00", + "source_file": "images/vscode-kill-terminal.png", + "language_code": "pt-BR" + }, + "vscode-new-file-button.182702340fe6723c.webp": { + "original_hash": "f53b77090608588ce1aea6e28ac7534b", + "translation_date": "2026-01-16T12:02:22+00:00", + "source_file": "images/vscode-new-file-button.png", + "language_code": "pt-BR" + }, + "vscode-new-terminal.77db8fc0f9cd3182.webp": { + "original_hash": "a692e413071b4224d251842fc4a95050", + "translation_date": "2026-01-16T11:52:22+00:00", + "source_file": "images/vscode-new-terminal.png", + "language_code": "pt-BR" + }, + "vscode-open-nightlight-remote.d3d2a4011e30d535.webp": { + "original_hash": "863d50888f94713346469b8afa0a56b3", + "translation_date": "2026-01-16T11:46:38+00:00", + "source_file": "images/vscode-open-nightlight-remote.png", + "language_code": "pt-BR" + }, + "vscode-platformio-build-command-palette.7708e7ec7d75d7ee.webp": { + "original_hash": "24236a76bf00a861dbf80d37b29265ce", + "translation_date": "2026-01-16T11:53:13+00:00", + "source_file": "images/vscode-platformio-build-command-palette.png", + "language_code": "pt-BR" + }, + "vscode-platformio-home-open.3f9a41bfd3f4da1c.webp": { + "original_hash": "68285f83d33fcd0a4b1e3141ef0afead", + "translation_date": "2026-01-16T11:50:03+00:00", + "source_file": "images/vscode-platformio-home-open.png", + "language_code": "pt-BR" + }, + "vscode-platformio-menu.297be26b9733e5c4.webp": { + "original_hash": "690ba1bf727223328bae1da7aef65b59", + "translation_date": "2026-01-16T11:54:05+00:00", + "source_file": "images/vscode-platformio-menu.png", + "language_code": "pt-BR" + }, + "vscode-platformio-nightlight-project-wizard.5c64db4da6037420.webp": { + "original_hash": "d55f8f702d005d082ea301248f7b70f9", + "translation_date": "2026-01-16T11:51:54+00:00", + "source_file": "images/vscode-platformio-nightlight-project-wizard.png", + "language_code": "pt-BR" + }, + "vscode-platformio-serial-monitor-command-palette.b348ec841b8a1c14.webp": { + "original_hash": "02340f15877c75b8ca3f08222c32b679", + "translation_date": "2026-01-16T12:01:24+00:00", + "source_file": "images/vscode-platformio-serial-monitor-command-palette.png", + "language_code": "pt-BR" + }, + "vscode-platformio-upload-command-palette.9e0f49cf80d1f1c3.webp": { + "original_hash": "ad07a4dbd27f86bd480dcfbbc1a56a01", + "translation_date": "2026-01-16T11:56:49+00:00", + "source_file": "images/vscode-platformio-upload-command-palette.png", + "language_code": "pt-BR" + }, + "vscode-platformio-welcome-new-button.ba6fc8a4c7b78cc8.webp": { + "original_hash": "c3bd57b44fe7628cc688f4d4fd814416", + "translation_date": "2026-01-16T11:46:50+00:00", + "source_file": "images/vscode-platformio-welcome-new-button.png", + "language_code": "pt-BR" + }, + "vscode-virtual-env.8ba42e04c3d533cf.webp": { + "original_hash": "f79cd090b385dfdfe774452b7d89eb84", + "translation_date": "2026-01-16T11:56:39+00:00", + "source_file": "images/vscode-virtual-env.png", + "language_code": "pt-BR" + }, + "what-is-azure-video-thumbnail.20174db09e03bbb8.webp": { + "original_hash": "ca9324cf5205832042b050d641f904b3", + "translation_date": "2026-01-16T11:50:50+00:00", + "source_file": "images/what-is-azure-video-thumbnail.png", + "language_code": "pt-BR" + }, + "wio-gps-sensor.19fd52b81ce58095.webp": { + "original_hash": "71ac9146b7ea28e48f6ee5b636cd1109", + "translation_date": "2026-01-16T11:56:11+00:00", + "source_file": "images/wio-gps-sensor.png", + "language_code": "pt-BR" + }, + "wio-hardware-kit.4c70c48b85e4283a.webp": { + "original_hash": "e428f5e0754412af1a8664ea7baff212", + "translation_date": "2026-01-16T12:00:35+00:00", + "source_file": "images/wio-hardware-kit.png", + "language_code": "pt-BR" + }, + "wio-led.265a1897e72d7f21.webp": { + "original_hash": "047202c8d9ddd146add1c33301f91d0e", + "translation_date": "2026-01-16T12:06:48+00:00", + "source_file": "images/wio-led.png", + "language_code": "pt-BR" + }, + "wio-light-sensor.b1f529f3c95f5165.webp": { + "original_hash": "7d3c253db81dc7f1b0fcd4554ae4bb1f", + "translation_date": "2026-01-16T11:57:11+00:00", + "source_file": "images/wio-light-sensor.png", + "language_code": "pt-BR" + }, + "wio-mic.3f8c843dbe8ad917.webp": { + "original_hash": "eb90afd4b3953d38218422601ae677b5", + "translation_date": "2026-01-16T11:52:23+00:00", + "source_file": "images/wio-mic.png", + "language_code": "pt-BR" + }, + "wio-relay-and-soil-moisture-sensor.ed722202d42babe0.webp": { + "original_hash": "ca90c734c88176a89d703b243c280333", + "translation_date": "2026-01-16T11:46:06+00:00", + "source_file": "images/wio-relay-and-soil-moisture-sensor.png", + "language_code": "pt-BR" + }, + "wio-respeaker-hat.bd54917d446e6f6f.webp": { + "original_hash": "040868428b85d90d767351cbbc89a23d", + "translation_date": "2026-01-16T12:02:18+00:00", + "source_file": "images/wio-respeaker-hat.png", + "language_code": "pt-BR" + }, + "wio-respeaker-wiring-0.767f80aa65081038.webp": { + "original_hash": "47daeac252937c129a4000dd216c04d8", + "translation_date": "2026-01-16T12:02:16+00:00", + "source_file": "images/wio-respeaker-wiring-0.png", + "language_code": "pt-BR" + }, + "wio-respeaker-wiring-1.8d894727f2ba2400.webp": { + "original_hash": "192d03a7a2cd1eab078ef6afa28a39c9", + "translation_date": "2026-01-16T11:55:29+00:00", + "source_file": "images/wio-respeaker-wiring-1.png", + "language_code": "pt-BR" + }, + "wio-respeaker-wiring-2.329e1cbd306e754f.webp": { + "original_hash": "76a795bfad251f217e7822f14ebd85e3", + "translation_date": "2026-01-16T11:59:35+00:00", + "source_file": "images/wio-respeaker-wiring-2.png", + "language_code": "pt-BR" + }, + "wio-respeaker-wiring-3.75b0be447e2fa930.webp": { + "original_hash": "430c8ab68fc9ee2c6bedae1d41325002", + "translation_date": "2026-01-16T11:52:12+00:00", + "source_file": "images/wio-respeaker-wiring-3.png", + "language_code": "pt-BR" + }, + "wio-respeaker-wiring-4.aa9cd434d8779437.webp": { + "original_hash": "c8febc847beb4a69180b745d5e718281", + "translation_date": "2026-01-16T11:45:26+00:00", + "source_file": "images/wio-respeaker-wiring-4.png", + "language_code": "pt-BR" + }, + "wio-respeaker-wiring-5.af117c20acf622f3.webp": { + "original_hash": "1953600b09247d9302e7011dceed8f28", + "translation_date": "2026-01-16T11:56:13+00:00", + "source_file": "images/wio-respeaker-wiring-5.png", + "language_code": "pt-BR" + }, + "wio-sd-card.acdcbe322fa4ee7f.webp": { + "original_hash": "88bd7dd4bc8b4c181e7b3743945a2edd", + "translation_date": "2026-01-16T11:50:04+00:00", + "source_file": "images/wio-sd-card.png", + "language_code": "pt-BR" + }, + "wio-soil-moisture-sensor.46919b61c3f6cb74.webp": { + "original_hash": "19186ea8705744d6f7ef80dd49a31037", + "translation_date": "2026-01-16T11:54:13+00:00", + "source_file": "images/wio-soil-moisture-sensor.png", + "language_code": "pt-BR" + }, + "wio-temperature-sensor.2934928f38c7f79a.webp": { + "original_hash": "9e8e3bc7a39149547dcfcce2493e151e", + "translation_date": "2026-01-16T11:57:16+00:00", + "source_file": "images/wio-temperature-sensor.png", + "language_code": "pt-BR" + }, + "wio-terminal-c-button.73df3cb1c1445ea0.webp": { + "original_hash": "7e8c595998491210a3ffd21ee338afe6", + "translation_date": "2026-01-16T11:57:15+00:00", + "source_file": "images/wio-terminal-c-button.png", + "language_code": "pt-BR" + }, + "wio-terminal-pin-sticker.b90b1535937b84bd.webp": { + "original_hash": "beeae0399efc567f78b9771eb986710a", + "translation_date": "2026-01-16T11:52:43+00:00", + "source_file": "images/wio-terminal-pin-sticker.png", + "language_code": "pt-BR" + }, + "wio-terminal.b8299ee16587db9a.webp": { + "original_hash": "e031f14d743539d41b871e8da6c516f7", + "translation_date": "2026-01-16T11:47:10+00:00", + "source_file": "images/wio-terminal.png", + "language_code": "pt-BR" + }, + "wio-time-of-flight-sensor.c4c182131d2ea73d.webp": { + "original_hash": "fe6b9bb1afee16f03bab8f6ddc3512b3", + "translation_date": "2026-01-16T11:53:51+00:00", + "source_file": "images/wio-time-of-flight-sensor.png", + "language_code": "pt-BR" + } +} \ No newline at end of file diff --git a/translated_images/pt-BR/IMG_5305.aa291c8812a9f1e5.webp b/translated_images/pt-BR/IMG_5305.aa291c8812a9f1e5.webp new file mode 100644 index 000000000..80f68b497 Binary files /dev/null and b/translated_images/pt-BR/IMG_5305.aa291c8812a9f1e5.webp differ diff --git a/translated_images/pt-BR/IMG_5306.d575b9ab7025877b.webp b/translated_images/pt-BR/IMG_5306.d575b9ab7025877b.webp new file mode 100644 index 000000000..fb6cf9b82 Binary files /dev/null and b/translated_images/pt-BR/IMG_5306.d575b9ab7025877b.webp differ diff --git a/translated_images/pt-BR/IMG_5307.f9c9b8361a8aa734.webp b/translated_images/pt-BR/IMG_5307.f9c9b8361a8aa734.webp new file mode 100644 index 000000000..1319b4354 Binary files /dev/null and b/translated_images/pt-BR/IMG_5307.f9c9b8361a8aa734.webp differ diff --git a/translated_images/pt-BR/IMG_5308.cbd6ed7007e69060.webp b/translated_images/pt-BR/IMG_5308.cbd6ed7007e69060.webp new file mode 100644 index 000000000..de860bc90 Binary files /dev/null and b/translated_images/pt-BR/IMG_5308.cbd6ed7007e69060.webp differ diff --git a/translated_images/pt-BR/IMG_5309.23fbc3b6667bfb64.webp b/translated_images/pt-BR/IMG_5309.23fbc3b6667bfb64.webp new file mode 100644 index 000000000..a6713a6dd Binary files /dev/null and b/translated_images/pt-BR/IMG_5309.23fbc3b6667bfb64.webp differ diff --git a/translated_images/pt-BR/IMG_5310.0ee0eb2fbc1c2d0e.webp b/translated_images/pt-BR/IMG_5310.0ee0eb2fbc1c2d0e.webp new file mode 100644 index 000000000..991e50c56 Binary files /dev/null and b/translated_images/pt-BR/IMG_5310.0ee0eb2fbc1c2d0e.webp differ diff --git a/translated_images/pt-BR/IMG_5311.8c90da6446c2d8c2.webp b/translated_images/pt-BR/IMG_5311.8c90da6446c2d8c2.webp new file mode 100644 index 000000000..7438fb75c Binary files /dev/null and b/translated_images/pt-BR/IMG_5311.8c90da6446c2d8c2.webp differ diff --git a/translated_images/pt-BR/IMG_5312.a45550ddd8ce8e65.webp b/translated_images/pt-BR/IMG_5312.a45550ddd8ce8e65.webp new file mode 100644 index 000000000..ea6a96e02 Binary files /dev/null and b/translated_images/pt-BR/IMG_5312.a45550ddd8ce8e65.webp differ diff --git a/translated_images/pt-BR/IMG_5313.ed1b45211271dbd2.webp b/translated_images/pt-BR/IMG_5313.ed1b45211271dbd2.webp new file mode 100644 index 000000000..18a7c9bd5 Binary files /dev/null and b/translated_images/pt-BR/IMG_5313.ed1b45211271dbd2.webp differ diff --git a/translated_images/pt-BR/IMG_5314.c2203206a05a74b5.webp b/translated_images/pt-BR/IMG_5314.c2203206a05a74b5.webp new file mode 100644 index 000000000..db699c4e8 Binary files /dev/null and b/translated_images/pt-BR/IMG_5314.c2203206a05a74b5.webp differ diff --git a/translated_images/pt-BR/IMG_5315.f698228e0e031bd4.webp b/translated_images/pt-BR/IMG_5315.f698228e0e031bd4.webp new file mode 100644 index 000000000..a108a4187 Binary files /dev/null and b/translated_images/pt-BR/IMG_5315.f698228e0e031bd4.webp differ diff --git a/translated_images/pt-BR/IMG_5316.29dc70d802ce8349.webp b/translated_images/pt-BR/IMG_5316.29dc70d802ce8349.webp new file mode 100644 index 000000000..bf35fd39a Binary files /dev/null and b/translated_images/pt-BR/IMG_5316.29dc70d802ce8349.webp differ diff --git a/translated_images/pt-BR/IMG_5317.ed81e4c1ca5046dc.webp b/translated_images/pt-BR/IMG_5317.ed81e4c1ca5046dc.webp new file mode 100644 index 000000000..ac98520f9 Binary files /dev/null and b/translated_images/pt-BR/IMG_5317.ed81e4c1ca5046dc.webp differ diff --git a/translated_images/pt-BR/IMG_5318.15dfffeb7f47abf7.webp b/translated_images/pt-BR/IMG_5318.15dfffeb7f47abf7.webp new file mode 100644 index 000000000..5744dae42 Binary files /dev/null and b/translated_images/pt-BR/IMG_5318.15dfffeb7f47abf7.webp differ diff --git a/translated_images/pt-BR/IMG_5319.b549b1fff0dcf143.webp b/translated_images/pt-BR/IMG_5319.b549b1fff0dcf143.webp new file mode 100644 index 000000000..fecb2b035 Binary files /dev/null and b/translated_images/pt-BR/IMG_5319.b549b1fff0dcf143.webp differ diff --git a/translated_images/pt-BR/IMG_5320.8268d3f61972f348.webp b/translated_images/pt-BR/IMG_5320.8268d3f61972f348.webp new file mode 100644 index 000000000..498f54ad2 Binary files /dev/null and b/translated_images/pt-BR/IMG_5320.8268d3f61972f348.webp differ diff --git a/translated_images/pt-BR/IMG_5321.b207cf143a59458d.webp b/translated_images/pt-BR/IMG_5321.b207cf143a59458d.webp new file mode 100644 index 000000000..7e4f0893b Binary files /dev/null and b/translated_images/pt-BR/IMG_5321.b207cf143a59458d.webp differ diff --git a/translated_images/pt-BR/IMG_5322.974809b9461a9e20.webp b/translated_images/pt-BR/IMG_5322.974809b9461a9e20.webp new file mode 100644 index 000000000..073ceca26 Binary files /dev/null and b/translated_images/pt-BR/IMG_5322.974809b9461a9e20.webp differ diff --git a/translated_images/pt-BR/IMG_5323.4939fa17958f291b.webp b/translated_images/pt-BR/IMG_5323.4939fa17958f291b.webp new file mode 100644 index 000000000..36bea27af Binary files /dev/null and b/translated_images/pt-BR/IMG_5323.4939fa17958f291b.webp differ diff --git a/translated_images/pt-BR/IMG_5324.0afbc6f0caceb1a3.webp b/translated_images/pt-BR/IMG_5324.0afbc6f0caceb1a3.webp new file mode 100644 index 000000000..9b03349c6 Binary files /dev/null and b/translated_images/pt-BR/IMG_5324.0afbc6f0caceb1a3.webp differ diff --git a/translated_images/pt-BR/IMG_5325.9e9d9e9b85a10b06.webp b/translated_images/pt-BR/IMG_5325.9e9d9e9b85a10b06.webp new file mode 100644 index 000000000..c092cddeb Binary files /dev/null and b/translated_images/pt-BR/IMG_5325.9e9d9e9b85a10b06.webp differ diff --git a/translated_images/pt-BR/IMG_5326.35bbc9e054c704d0.webp b/translated_images/pt-BR/IMG_5326.35bbc9e054c704d0.webp new file mode 100644 index 000000000..1c8b33666 Binary files /dev/null and b/translated_images/pt-BR/IMG_5326.35bbc9e054c704d0.webp differ diff --git a/translated_images/pt-BR/IMG_5327.804b63a605b5a77a.webp b/translated_images/pt-BR/IMG_5327.804b63a605b5a77a.webp new file mode 100644 index 000000000..f99216e1d Binary files /dev/null and b/translated_images/pt-BR/IMG_5327.804b63a605b5a77a.webp differ diff --git a/translated_images/pt-BR/IMG_5328.925a9da23d96759f.webp b/translated_images/pt-BR/IMG_5328.925a9da23d96759f.webp new file mode 100644 index 000000000..fb7cefbc7 Binary files /dev/null and b/translated_images/pt-BR/IMG_5328.925a9da23d96759f.webp differ diff --git a/translated_images/pt-BR/IMG_5329.27da5fcbc3336773.webp b/translated_images/pt-BR/IMG_5329.27da5fcbc3336773.webp new file mode 100644 index 000000000..8bff13f97 Binary files /dev/null and b/translated_images/pt-BR/IMG_5329.27da5fcbc3336773.webp differ diff --git a/translated_images/pt-BR/IMG_5330.3db3d5ea01c8cca2.webp b/translated_images/pt-BR/IMG_5330.3db3d5ea01c8cca2.webp new file mode 100644 index 000000000..c5034e3e1 Binary files /dev/null and b/translated_images/pt-BR/IMG_5330.3db3d5ea01c8cca2.webp differ diff --git a/translated_images/pt-BR/IMG_5331.181987d3d094472f.webp b/translated_images/pt-BR/IMG_5331.181987d3d094472f.webp new file mode 100644 index 000000000..c03229615 Binary files /dev/null and b/translated_images/pt-BR/IMG_5331.181987d3d094472f.webp differ diff --git a/translated_images/pt-BR/IMG_5332.4beed56eaa5158e3.webp b/translated_images/pt-BR/IMG_5332.4beed56eaa5158e3.webp new file mode 100644 index 000000000..6b09de689 Binary files /dev/null and b/translated_images/pt-BR/IMG_5332.4beed56eaa5158e3.webp differ diff --git a/translated_images/pt-BR/IMG_5333.53c3364c2ee0e7bb.webp b/translated_images/pt-BR/IMG_5333.53c3364c2ee0e7bb.webp new file mode 100644 index 000000000..79e64a4b9 Binary files /dev/null and b/translated_images/pt-BR/IMG_5333.53c3364c2ee0e7bb.webp differ diff --git a/translated_images/pt-BR/IMG_5334.979472e433948c10.webp b/translated_images/pt-BR/IMG_5334.979472e433948c10.webp new file mode 100644 index 000000000..4792237e2 Binary files /dev/null and b/translated_images/pt-BR/IMG_5334.979472e433948c10.webp differ diff --git a/translated_images/pt-BR/IMG_5335.9f5bfba69a8d5a90.webp b/translated_images/pt-BR/IMG_5335.9f5bfba69a8d5a90.webp new file mode 100644 index 000000000..c5948c997 Binary files /dev/null and b/translated_images/pt-BR/IMG_5335.9f5bfba69a8d5a90.webp differ diff --git a/translated_images/pt-BR/IMG_5336.1b46586fdec95767.webp b/translated_images/pt-BR/IMG_5336.1b46586fdec95767.webp new file mode 100644 index 000000000..302829271 Binary files /dev/null and b/translated_images/pt-BR/IMG_5336.1b46586fdec95767.webp differ diff --git a/translated_images/pt-BR/IMG_5337.91c82be4d37029b0.webp b/translated_images/pt-BR/IMG_5337.91c82be4d37029b0.webp new file mode 100644 index 000000000..e6904570b Binary files /dev/null and b/translated_images/pt-BR/IMG_5337.91c82be4d37029b0.webp differ diff --git a/translated_images/pt-BR/IMG_5338.9ab356541448923b.webp b/translated_images/pt-BR/IMG_5338.9ab356541448923b.webp new file mode 100644 index 000000000..d87e0b985 Binary files /dev/null and b/translated_images/pt-BR/IMG_5338.9ab356541448923b.webp differ diff --git a/translated_images/pt-BR/IMG_5340.8440651b3ce1dd35.webp b/translated_images/pt-BR/IMG_5340.8440651b3ce1dd35.webp new file mode 100644 index 000000000..4cb606434 Binary files /dev/null and b/translated_images/pt-BR/IMG_5340.8440651b3ce1dd35.webp differ diff --git a/translated_images/pt-BR/IMG_5341.a1aa041c42dbc534.webp b/translated_images/pt-BR/IMG_5341.a1aa041c42dbc534.webp new file mode 100644 index 000000000..9f3faa8fe Binary files /dev/null and b/translated_images/pt-BR/IMG_5341.a1aa041c42dbc534.webp differ diff --git a/translated_images/pt-BR/IMG_5342.9f3b93d9fab90d3b.webp b/translated_images/pt-BR/IMG_5342.9f3b93d9fab90d3b.webp new file mode 100644 index 000000000..71b831a35 Binary files /dev/null and b/translated_images/pt-BR/IMG_5342.9f3b93d9fab90d3b.webp differ diff --git a/translated_images/pt-BR/IMG_5343.fa30105d3c10cad2.webp b/translated_images/pt-BR/IMG_5343.fa30105d3c10cad2.webp new file mode 100644 index 000000000..238fdcf5d Binary files /dev/null and b/translated_images/pt-BR/IMG_5343.fa30105d3c10cad2.webp differ diff --git a/translated_images/pt-BR/IMG_5344.acfcd61ee5281321.webp b/translated_images/pt-BR/IMG_5344.acfcd61ee5281321.webp new file mode 100644 index 000000000..be8a88f6d Binary files /dev/null and b/translated_images/pt-BR/IMG_5344.acfcd61ee5281321.webp differ diff --git a/translated_images/pt-BR/IMG_5345.3d305ee2bb4ee804.webp b/translated_images/pt-BR/IMG_5345.3d305ee2bb4ee804.webp new file mode 100644 index 000000000..c1853e9e5 Binary files /dev/null and b/translated_images/pt-BR/IMG_5345.3d305ee2bb4ee804.webp differ diff --git a/translated_images/pt-BR/IMG_5346.281dcc267f69c70b.webp b/translated_images/pt-BR/IMG_5346.281dcc267f69c70b.webp new file mode 100644 index 000000000..d3760a507 Binary files /dev/null and b/translated_images/pt-BR/IMG_5346.281dcc267f69c70b.webp differ diff --git a/translated_images/pt-BR/IMG_5347.48a4a981e76910ae.webp b/translated_images/pt-BR/IMG_5347.48a4a981e76910ae.webp new file mode 100644 index 000000000..d84fa587c Binary files /dev/null and b/translated_images/pt-BR/IMG_5347.48a4a981e76910ae.webp differ diff --git a/translated_images/pt-BR/IMG_5348.3961d3b444537c13.webp b/translated_images/pt-BR/IMG_5348.3961d3b444537c13.webp new file mode 100644 index 000000000..b07f2c76e Binary files /dev/null and b/translated_images/pt-BR/IMG_5348.3961d3b444537c13.webp differ diff --git a/translated_images/pt-BR/IMG_5349.1f0ec7fbf8807b3b.webp b/translated_images/pt-BR/IMG_5349.1f0ec7fbf8807b3b.webp new file mode 100644 index 000000000..1e523a82e Binary files /dev/null and b/translated_images/pt-BR/IMG_5349.1f0ec7fbf8807b3b.webp differ diff --git a/translated_images/pt-BR/Roadmap.bb1dec285dda0eda.webp b/translated_images/pt-BR/Roadmap.bb1dec285dda0eda.webp new file mode 100644 index 000000000..5d64d7e98 Binary files /dev/null and b/translated_images/pt-BR/Roadmap.bb1dec285dda0eda.webp differ diff --git a/translated_images/pt-BR/amqp.804bd4fce8330157.webp b/translated_images/pt-BR/amqp.804bd4fce8330157.webp new file mode 100644 index 000000000..8f0051777 Binary files /dev/null and b/translated_images/pt-BR/amqp.804bd4fce8330157.webp differ diff --git a/translated_images/pt-BR/analog-sensor-voltage.3b6f315392247399.webp b/translated_images/pt-BR/analog-sensor-voltage.3b6f315392247399.webp new file mode 100644 index 000000000..a97b83210 Binary files /dev/null and b/translated_images/pt-BR/analog-sensor-voltage.3b6f315392247399.webp differ diff --git a/translated_images/pt-BR/arducam-wio-terminal-connections.a4d5a4049bdb5ab8.webp b/translated_images/pt-BR/arducam-wio-terminal-connections.a4d5a4049bdb5ab8.webp new file mode 100644 index 000000000..eed2d8ea2 Binary files /dev/null and b/translated_images/pt-BR/arducam-wio-terminal-connections.a4d5a4049bdb5ab8.webp differ diff --git a/translated_images/pt-BR/arducam.20e4e4cbb2682965.webp b/translated_images/pt-BR/arducam.20e4e4cbb2682965.webp new file mode 100644 index 000000000..5a361fb45 Binary files /dev/null and b/translated_images/pt-BR/arducam.20e4e4cbb2682965.webp differ diff --git a/translated_images/pt-BR/arduino-sketch.79590cb837ff7a7c.webp b/translated_images/pt-BR/arduino-sketch.79590cb837ff7a7c.webp new file mode 100644 index 000000000..a306b5588 Binary files /dev/null and b/translated_images/pt-BR/arduino-sketch.79590cb837ff7a7c.webp differ diff --git a/translated_images/pt-BR/assignment-1-flow.7552a51acb1a5ec8.webp b/translated_images/pt-BR/assignment-1-flow.7552a51acb1a5ec8.webp new file mode 100644 index 000000000..fc9dcdccb Binary files /dev/null and b/translated_images/pt-BR/assignment-1-flow.7552a51acb1a5ec8.webp differ diff --git a/translated_images/pt-BR/assignment-1-internet-flow.3256feab5f052fd2.webp b/translated_images/pt-BR/assignment-1-internet-flow.3256feab5f052fd2.webp new file mode 100644 index 000000000..420608f42 Binary files /dev/null and b/translated_images/pt-BR/assignment-1-internet-flow.3256feab5f052fd2.webp differ diff --git a/translated_images/pt-BR/azure-container-registry-logo.09494206991d4b29.webp b/translated_images/pt-BR/azure-container-registry-logo.09494206991d4b29.webp new file mode 100644 index 000000000..f2f34c14c Binary files /dev/null and b/translated_images/pt-BR/azure-container-registry-logo.09494206991d4b29.webp differ diff --git a/translated_images/pt-BR/azure-functions-logo.1cfc8e3204c9c44a.webp b/translated_images/pt-BR/azure-functions-logo.1cfc8e3204c9c44a.webp new file mode 100644 index 000000000..c662f7a78 Binary files /dev/null and b/translated_images/pt-BR/azure-functions-logo.1cfc8e3204c9c44a.webp differ diff --git a/translated_images/pt-BR/azure-iot-edge-logo.c1c076749b5cba2e.webp b/translated_images/pt-BR/azure-iot-edge-logo.c1c076749b5cba2e.webp new file mode 100644 index 000000000..771d5e6f8 Binary files /dev/null and b/translated_images/pt-BR/azure-iot-edge-logo.c1c076749b5cba2e.webp differ diff --git a/translated_images/pt-BR/azure-iot-hub-logo.28a19de76d0a1932.webp b/translated_images/pt-BR/azure-iot-hub-logo.28a19de76d0a1932.webp new file mode 100644 index 000000000..9c9f88d0d Binary files /dev/null and b/translated_images/pt-BR/azure-iot-hub-logo.28a19de76d0a1932.webp differ diff --git a/translated_images/pt-BR/azure-maps-logo.35d01dcfbd81fe61.webp b/translated_images/pt-BR/azure-maps-logo.35d01dcfbd81fe61.webp new file mode 100644 index 000000000..8577e5b49 Binary files /dev/null and b/translated_images/pt-BR/azure-maps-logo.35d01dcfbd81fe61.webp differ diff --git a/translated_images/pt-BR/azure-region-existing.73f704604f2aa6cb.webp b/translated_images/pt-BR/azure-region-existing.73f704604f2aa6cb.webp new file mode 100644 index 000000000..399308ca1 Binary files /dev/null and b/translated_images/pt-BR/azure-region-existing.73f704604f2aa6cb.webp differ diff --git a/translated_images/pt-BR/azure-region-planned-expansion.a5074a1e8af74f15.webp b/translated_images/pt-BR/azure-region-planned-expansion.a5074a1e8af74f15.webp new file mode 100644 index 000000000..e0ee60053 Binary files /dev/null and b/translated_images/pt-BR/azure-region-planned-expansion.a5074a1e8af74f15.webp differ diff --git a/translated_images/pt-BR/azure-speech-logo.a1f08c4befb0159f.webp b/translated_images/pt-BR/azure-speech-logo.a1f08c4befb0159f.webp new file mode 100644 index 000000000..754bd8eed Binary files /dev/null and b/translated_images/pt-BR/azure-speech-logo.a1f08c4befb0159f.webp differ diff --git a/translated_images/pt-BR/azure-storage-logo.605c0f602c640d48.webp b/translated_images/pt-BR/azure-storage-logo.605c0f602c640d48.webp new file mode 100644 index 000000000..c461149f7 Binary files /dev/null and b/translated_images/pt-BR/azure-storage-logo.605c0f602c640d48.webp differ diff --git a/translated_images/pt-BR/azure-translator-logo.c6ed3a4a433edfd2.webp b/translated_images/pt-BR/azure-translator-logo.c6ed3a4a433edfd2.webp new file mode 100644 index 000000000..2fd526f0f Binary files /dev/null and b/translated_images/pt-BR/azure-translator-logo.c6ed3a4a433edfd2.webp differ diff --git a/translated_images/pt-BR/banana-arducam.be1b32d4267a8194.webp b/translated_images/pt-BR/banana-arducam.be1b32d4267a8194.webp new file mode 100644 index 000000000..e0e788e08 Binary files /dev/null and b/translated_images/pt-BR/banana-arducam.be1b32d4267a8194.webp differ diff --git a/translated_images/pt-BR/banana-picture-compare.174df164dc326a42.webp b/translated_images/pt-BR/banana-picture-compare.174df164dc326a42.webp new file mode 100644 index 000000000..85618ec5d Binary files /dev/null and b/translated_images/pt-BR/banana-picture-compare.174df164dc326a42.webp differ diff --git a/translated_images/pt-BR/banana-ripe-1.6ed72365ffc92300.webp b/translated_images/pt-BR/banana-ripe-1.6ed72365ffc92300.webp new file mode 100644 index 000000000..c0714bbc3 Binary files /dev/null and b/translated_images/pt-BR/banana-ripe-1.6ed72365ffc92300.webp differ diff --git a/translated_images/pt-BR/banana-ripe-1.780e9be3a60d8879.webp b/translated_images/pt-BR/banana-ripe-1.780e9be3a60d8879.webp new file mode 100644 index 000000000..8075dc4ab Binary files /dev/null and b/translated_images/pt-BR/banana-ripe-1.780e9be3a60d8879.webp differ diff --git a/translated_images/pt-BR/banana-ripe-10.c3d98eb280e7464f.webp b/translated_images/pt-BR/banana-ripe-10.c3d98eb280e7464f.webp new file mode 100644 index 000000000..6d828b371 Binary files /dev/null and b/translated_images/pt-BR/banana-ripe-10.c3d98eb280e7464f.webp differ diff --git a/translated_images/pt-BR/banana-ripe-11.3d932f292b95b9a2.webp b/translated_images/pt-BR/banana-ripe-11.3d932f292b95b9a2.webp new file mode 100644 index 000000000..7dfafb15a Binary files /dev/null and b/translated_images/pt-BR/banana-ripe-11.3d932f292b95b9a2.webp differ diff --git a/translated_images/pt-BR/banana-ripe-12.9f87e663b9da6c85.webp b/translated_images/pt-BR/banana-ripe-12.9f87e663b9da6c85.webp new file mode 100644 index 000000000..f0e9b2d77 Binary files /dev/null and b/translated_images/pt-BR/banana-ripe-12.9f87e663b9da6c85.webp differ diff --git a/translated_images/pt-BR/banana-ripe-13.b7402e05160f4543.webp b/translated_images/pt-BR/banana-ripe-13.b7402e05160f4543.webp new file mode 100644 index 000000000..3d0ed4bb1 Binary files /dev/null and b/translated_images/pt-BR/banana-ripe-13.b7402e05160f4543.webp differ diff --git a/translated_images/pt-BR/banana-ripe-14.85cf309aa702cfa8.webp b/translated_images/pt-BR/banana-ripe-14.85cf309aa702cfa8.webp new file mode 100644 index 000000000..bdb2f1b6a Binary files /dev/null and b/translated_images/pt-BR/banana-ripe-14.85cf309aa702cfa8.webp differ diff --git a/translated_images/pt-BR/banana-ripe-15.933412eb14a3f8e4.webp b/translated_images/pt-BR/banana-ripe-15.933412eb14a3f8e4.webp new file mode 100644 index 000000000..4ecc1c8d5 Binary files /dev/null and b/translated_images/pt-BR/banana-ripe-15.933412eb14a3f8e4.webp differ diff --git a/translated_images/pt-BR/banana-ripe-16.781a68a01401f89e.webp b/translated_images/pt-BR/banana-ripe-16.781a68a01401f89e.webp new file mode 100644 index 000000000..b77a66a97 Binary files /dev/null and b/translated_images/pt-BR/banana-ripe-16.781a68a01401f89e.webp differ diff --git a/translated_images/pt-BR/banana-ripe-17.f8e2853a40d3ac45.webp b/translated_images/pt-BR/banana-ripe-17.f8e2853a40d3ac45.webp new file mode 100644 index 000000000..9ffb20deb Binary files /dev/null and b/translated_images/pt-BR/banana-ripe-17.f8e2853a40d3ac45.webp differ diff --git a/translated_images/pt-BR/banana-ripe-18.3d05f5f78ecf6f0d.webp b/translated_images/pt-BR/banana-ripe-18.3d05f5f78ecf6f0d.webp new file mode 100644 index 000000000..733a99b5a Binary files /dev/null and b/translated_images/pt-BR/banana-ripe-18.3d05f5f78ecf6f0d.webp differ diff --git a/translated_images/pt-BR/banana-ripe-19.ac3b0fc6cf6fdfd5.webp b/translated_images/pt-BR/banana-ripe-19.ac3b0fc6cf6fdfd5.webp new file mode 100644 index 000000000..aa4e5e453 Binary files /dev/null and b/translated_images/pt-BR/banana-ripe-19.ac3b0fc6cf6fdfd5.webp differ diff --git a/translated_images/pt-BR/banana-ripe-2.8ab96da692df69f1.webp b/translated_images/pt-BR/banana-ripe-2.8ab96da692df69f1.webp new file mode 100644 index 000000000..debf28d24 Binary files /dev/null and b/translated_images/pt-BR/banana-ripe-2.8ab96da692df69f1.webp differ diff --git a/translated_images/pt-BR/banana-ripe-2.96ddc53114c5f020.webp b/translated_images/pt-BR/banana-ripe-2.96ddc53114c5f020.webp new file mode 100644 index 000000000..5262b2b85 Binary files /dev/null and b/translated_images/pt-BR/banana-ripe-2.96ddc53114c5f020.webp differ diff --git a/translated_images/pt-BR/banana-ripe-20.a4d0ad33a7e6f037.webp b/translated_images/pt-BR/banana-ripe-20.a4d0ad33a7e6f037.webp new file mode 100644 index 000000000..9f6572948 Binary files /dev/null and b/translated_images/pt-BR/banana-ripe-20.a4d0ad33a7e6f037.webp differ diff --git a/translated_images/pt-BR/banana-ripe-21.07e03d64f265d55d.webp b/translated_images/pt-BR/banana-ripe-21.07e03d64f265d55d.webp new file mode 100644 index 000000000..958809792 Binary files /dev/null and b/translated_images/pt-BR/banana-ripe-21.07e03d64f265d55d.webp differ diff --git a/translated_images/pt-BR/banana-ripe-22.a63c05aeb7f866fc.webp b/translated_images/pt-BR/banana-ripe-22.a63c05aeb7f866fc.webp new file mode 100644 index 000000000..07de2a760 Binary files /dev/null and b/translated_images/pt-BR/banana-ripe-22.a63c05aeb7f866fc.webp differ diff --git a/translated_images/pt-BR/banana-ripe-23.6f3364afcab19e57.webp b/translated_images/pt-BR/banana-ripe-23.6f3364afcab19e57.webp new file mode 100644 index 000000000..e1656d2f0 Binary files /dev/null and b/translated_images/pt-BR/banana-ripe-23.6f3364afcab19e57.webp differ diff --git a/translated_images/pt-BR/banana-ripe-24.ff2c02cc80a9c430.webp b/translated_images/pt-BR/banana-ripe-24.ff2c02cc80a9c430.webp new file mode 100644 index 000000000..fda478f0f Binary files /dev/null and b/translated_images/pt-BR/banana-ripe-24.ff2c02cc80a9c430.webp differ diff --git a/translated_images/pt-BR/banana-ripe-25.65ce63418cdc4de2.webp b/translated_images/pt-BR/banana-ripe-25.65ce63418cdc4de2.webp new file mode 100644 index 000000000..50a1e1b38 Binary files /dev/null and b/translated_images/pt-BR/banana-ripe-25.65ce63418cdc4de2.webp differ diff --git a/translated_images/pt-BR/banana-ripe-3.4fae05a0a1d2b5f0.webp b/translated_images/pt-BR/banana-ripe-3.4fae05a0a1d2b5f0.webp new file mode 100644 index 000000000..9baa7684d Binary files /dev/null and b/translated_images/pt-BR/banana-ripe-3.4fae05a0a1d2b5f0.webp differ diff --git a/translated_images/pt-BR/banana-ripe-5.c762086879ccec4c.webp b/translated_images/pt-BR/banana-ripe-5.c762086879ccec4c.webp new file mode 100644 index 000000000..9e996d31d Binary files /dev/null and b/translated_images/pt-BR/banana-ripe-5.c762086879ccec4c.webp differ diff --git a/translated_images/pt-BR/banana-ripe-6.5131bcbf492980cb.webp b/translated_images/pt-BR/banana-ripe-6.5131bcbf492980cb.webp new file mode 100644 index 000000000..5c8d85b0c Binary files /dev/null and b/translated_images/pt-BR/banana-ripe-6.5131bcbf492980cb.webp differ diff --git a/translated_images/pt-BR/banana-ripe-7.5fc18dfe7b7ae9dc.webp b/translated_images/pt-BR/banana-ripe-7.5fc18dfe7b7ae9dc.webp new file mode 100644 index 000000000..a90c4fe6c Binary files /dev/null and b/translated_images/pt-BR/banana-ripe-7.5fc18dfe7b7ae9dc.webp differ diff --git a/translated_images/pt-BR/banana-ripe-8.dba1d33bd34d4830.webp b/translated_images/pt-BR/banana-ripe-8.dba1d33bd34d4830.webp new file mode 100644 index 000000000..48f5aab3d Binary files /dev/null and b/translated_images/pt-BR/banana-ripe-8.dba1d33bd34d4830.webp differ diff --git a/translated_images/pt-BR/banana-ripe-9.32f91462c8b0e2d3.webp b/translated_images/pt-BR/banana-ripe-9.32f91462c8b0e2d3.webp new file mode 100644 index 000000000..5e86630cd Binary files /dev/null and b/translated_images/pt-BR/banana-ripe-9.32f91462c8b0e2d3.webp differ diff --git a/translated_images/pt-BR/banana-training-images.530eb203346d73bc.webp b/translated_images/pt-BR/banana-training-images.530eb203346d73bc.webp new file mode 100644 index 000000000..5e012ab99 Binary files /dev/null and b/translated_images/pt-BR/banana-training-images.530eb203346d73bc.webp differ diff --git a/translated_images/pt-BR/banana-unripe-1.910c8606a300fa20.webp b/translated_images/pt-BR/banana-unripe-1.910c8606a300fa20.webp new file mode 100644 index 000000000..e045a73db Binary files /dev/null and b/translated_images/pt-BR/banana-unripe-1.910c8606a300fa20.webp differ diff --git a/translated_images/pt-BR/banana-unripe-1.b2c7051d9c8a4e61.webp b/translated_images/pt-BR/banana-unripe-1.b2c7051d9c8a4e61.webp new file mode 100644 index 000000000..5e88485a0 Binary files /dev/null and b/translated_images/pt-BR/banana-unripe-1.b2c7051d9c8a4e61.webp differ diff --git a/translated_images/pt-BR/banana-unripe-10.38dab0db918a2487.webp b/translated_images/pt-BR/banana-unripe-10.38dab0db918a2487.webp new file mode 100644 index 000000000..d863e575b Binary files /dev/null and b/translated_images/pt-BR/banana-unripe-10.38dab0db918a2487.webp differ diff --git a/translated_images/pt-BR/banana-unripe-11.ec8d0eefe63e10b9.webp b/translated_images/pt-BR/banana-unripe-11.ec8d0eefe63e10b9.webp new file mode 100644 index 000000000..d77f907da Binary files /dev/null and b/translated_images/pt-BR/banana-unripe-11.ec8d0eefe63e10b9.webp differ diff --git a/translated_images/pt-BR/banana-unripe-12.b95a088ccae935db.webp b/translated_images/pt-BR/banana-unripe-12.b95a088ccae935db.webp new file mode 100644 index 000000000..39fe8050a Binary files /dev/null and b/translated_images/pt-BR/banana-unripe-12.b95a088ccae935db.webp differ diff --git a/translated_images/pt-BR/banana-unripe-13.37e5a7cac5aa0920.webp b/translated_images/pt-BR/banana-unripe-13.37e5a7cac5aa0920.webp new file mode 100644 index 000000000..4991d4f65 Binary files /dev/null and b/translated_images/pt-BR/banana-unripe-13.37e5a7cac5aa0920.webp differ diff --git a/translated_images/pt-BR/banana-unripe-14.d19ddd6bbf63a259.webp b/translated_images/pt-BR/banana-unripe-14.d19ddd6bbf63a259.webp new file mode 100644 index 000000000..eff19a63b Binary files /dev/null and b/translated_images/pt-BR/banana-unripe-14.d19ddd6bbf63a259.webp differ diff --git a/translated_images/pt-BR/banana-unripe-15.274e48544326077a.webp b/translated_images/pt-BR/banana-unripe-15.274e48544326077a.webp new file mode 100644 index 000000000..e16197d1f Binary files /dev/null and b/translated_images/pt-BR/banana-unripe-15.274e48544326077a.webp differ diff --git a/translated_images/pt-BR/banana-unripe-16.bd058f64bd7ec014.webp b/translated_images/pt-BR/banana-unripe-16.bd058f64bd7ec014.webp new file mode 100644 index 000000000..4abdad3e5 Binary files /dev/null and b/translated_images/pt-BR/banana-unripe-16.bd058f64bd7ec014.webp differ diff --git a/translated_images/pt-BR/banana-unripe-17.408382d679bfa079.webp b/translated_images/pt-BR/banana-unripe-17.408382d679bfa079.webp new file mode 100644 index 000000000..81be6d428 Binary files /dev/null and b/translated_images/pt-BR/banana-unripe-17.408382d679bfa079.webp differ diff --git a/translated_images/pt-BR/banana-unripe-18.39c0eb79d7b3b9ba.webp b/translated_images/pt-BR/banana-unripe-18.39c0eb79d7b3b9ba.webp new file mode 100644 index 000000000..a012cd4eb Binary files /dev/null and b/translated_images/pt-BR/banana-unripe-18.39c0eb79d7b3b9ba.webp differ diff --git a/translated_images/pt-BR/banana-unripe-19.e61e6d7efaf2d8c8.webp b/translated_images/pt-BR/banana-unripe-19.e61e6d7efaf2d8c8.webp new file mode 100644 index 000000000..da22c29fe Binary files /dev/null and b/translated_images/pt-BR/banana-unripe-19.e61e6d7efaf2d8c8.webp differ diff --git a/translated_images/pt-BR/banana-unripe-2.43a73b544521afc7.webp b/translated_images/pt-BR/banana-unripe-2.43a73b544521afc7.webp new file mode 100644 index 000000000..10a0ab56d Binary files /dev/null and b/translated_images/pt-BR/banana-unripe-2.43a73b544521afc7.webp differ diff --git a/translated_images/pt-BR/banana-unripe-2.9591d1a6aa27deeb.webp b/translated_images/pt-BR/banana-unripe-2.9591d1a6aa27deeb.webp new file mode 100644 index 000000000..049459245 Binary files /dev/null and b/translated_images/pt-BR/banana-unripe-2.9591d1a6aa27deeb.webp differ diff --git a/translated_images/pt-BR/banana-unripe-20.85b7a74eaab5634e.webp b/translated_images/pt-BR/banana-unripe-20.85b7a74eaab5634e.webp new file mode 100644 index 000000000..80c5effcb Binary files /dev/null and b/translated_images/pt-BR/banana-unripe-20.85b7a74eaab5634e.webp differ diff --git a/translated_images/pt-BR/banana-unripe-21.ccc1333439b344bc.webp b/translated_images/pt-BR/banana-unripe-21.ccc1333439b344bc.webp new file mode 100644 index 000000000..a99702656 Binary files /dev/null and b/translated_images/pt-BR/banana-unripe-21.ccc1333439b344bc.webp differ diff --git a/translated_images/pt-BR/banana-unripe-22.27dff4b438163080.webp b/translated_images/pt-BR/banana-unripe-22.27dff4b438163080.webp new file mode 100644 index 000000000..87a3ab30c Binary files /dev/null and b/translated_images/pt-BR/banana-unripe-22.27dff4b438163080.webp differ diff --git a/translated_images/pt-BR/banana-unripe-23.c4c9067f23370e90.webp b/translated_images/pt-BR/banana-unripe-23.c4c9067f23370e90.webp new file mode 100644 index 000000000..8c554da6d Binary files /dev/null and b/translated_images/pt-BR/banana-unripe-23.c4c9067f23370e90.webp differ diff --git a/translated_images/pt-BR/banana-unripe-24.6f0b781c309da62f.webp b/translated_images/pt-BR/banana-unripe-24.6f0b781c309da62f.webp new file mode 100644 index 000000000..7998990dc Binary files /dev/null and b/translated_images/pt-BR/banana-unripe-24.6f0b781c309da62f.webp differ diff --git a/translated_images/pt-BR/banana-unripe-25.21d553d84880ac4f.webp b/translated_images/pt-BR/banana-unripe-25.21d553d84880ac4f.webp new file mode 100644 index 000000000..be2233b77 Binary files /dev/null and b/translated_images/pt-BR/banana-unripe-25.21d553d84880ac4f.webp differ diff --git a/translated_images/pt-BR/banana-unripe-26.823c48b61feb1d5c.webp b/translated_images/pt-BR/banana-unripe-26.823c48b61feb1d5c.webp new file mode 100644 index 000000000..ab902dbf6 Binary files /dev/null and b/translated_images/pt-BR/banana-unripe-26.823c48b61feb1d5c.webp differ diff --git a/translated_images/pt-BR/banana-unripe-27.f98fd272deeb02d9.webp b/translated_images/pt-BR/banana-unripe-27.f98fd272deeb02d9.webp new file mode 100644 index 000000000..ec3f75024 Binary files /dev/null and b/translated_images/pt-BR/banana-unripe-27.f98fd272deeb02d9.webp differ diff --git a/translated_images/pt-BR/banana-unripe-28.5331ba409ce41c07.webp b/translated_images/pt-BR/banana-unripe-28.5331ba409ce41c07.webp new file mode 100644 index 000000000..addfa4127 Binary files /dev/null and b/translated_images/pt-BR/banana-unripe-28.5331ba409ce41c07.webp differ diff --git a/translated_images/pt-BR/banana-unripe-29.84e126f389bf627e.webp b/translated_images/pt-BR/banana-unripe-29.84e126f389bf627e.webp new file mode 100644 index 000000000..0a17c8f7b Binary files /dev/null and b/translated_images/pt-BR/banana-unripe-29.84e126f389bf627e.webp differ diff --git a/translated_images/pt-BR/banana-unripe-3.896df8fb2c3b8f51.webp b/translated_images/pt-BR/banana-unripe-3.896df8fb2c3b8f51.webp new file mode 100644 index 000000000..b9c30fe66 Binary files /dev/null and b/translated_images/pt-BR/banana-unripe-3.896df8fb2c3b8f51.webp differ diff --git a/translated_images/pt-BR/banana-unripe-4.483e740d6fd7b5a6.webp b/translated_images/pt-BR/banana-unripe-4.483e740d6fd7b5a6.webp new file mode 100644 index 000000000..eefb7b624 Binary files /dev/null and b/translated_images/pt-BR/banana-unripe-4.483e740d6fd7b5a6.webp differ diff --git a/translated_images/pt-BR/banana-unripe-5.e9923cf1ffcfc1c9.webp b/translated_images/pt-BR/banana-unripe-5.e9923cf1ffcfc1c9.webp new file mode 100644 index 000000000..acfe59606 Binary files /dev/null and b/translated_images/pt-BR/banana-unripe-5.e9923cf1ffcfc1c9.webp differ diff --git a/translated_images/pt-BR/banana-unripe-6.e3a73307558caecc.webp b/translated_images/pt-BR/banana-unripe-6.e3a73307558caecc.webp new file mode 100644 index 000000000..72ae0174f Binary files /dev/null and b/translated_images/pt-BR/banana-unripe-6.e3a73307558caecc.webp differ diff --git a/translated_images/pt-BR/banana-unripe-7.634ca89acc17d68f.webp b/translated_images/pt-BR/banana-unripe-7.634ca89acc17d68f.webp new file mode 100644 index 000000000..283cae548 Binary files /dev/null and b/translated_images/pt-BR/banana-unripe-7.634ca89acc17d68f.webp differ diff --git a/translated_images/pt-BR/banana-unripe-8.75720b4cdebac8c3.webp b/translated_images/pt-BR/banana-unripe-8.75720b4cdebac8c3.webp new file mode 100644 index 000000000..f09e18518 Binary files /dev/null and b/translated_images/pt-BR/banana-unripe-8.75720b4cdebac8c3.webp differ diff --git a/translated_images/pt-BR/banana-unripe-9.e8076983351d2f54.webp b/translated_images/pt-BR/banana-unripe-9.e8076983351d2f54.webp new file mode 100644 index 000000000..c7f53d90f Binary files /dev/null and b/translated_images/pt-BR/banana-unripe-9.e8076983351d2f54.webp differ diff --git a/translated_images/pt-BR/banana-unripe-quick-test-prediction.dae9b5e1c4ef7c64.webp b/translated_images/pt-BR/banana-unripe-quick-test-prediction.dae9b5e1c4ef7c64.webp new file mode 100644 index 000000000..2b7fb541d Binary files /dev/null and b/translated_images/pt-BR/banana-unripe-quick-test-prediction.dae9b5e1c4ef7c64.webp differ diff --git a/translated_images/pt-BR/bananas-ripe-vs-unripe-predictions.8d0e2034014aa50e.webp b/translated_images/pt-BR/bananas-ripe-vs-unripe-predictions.8d0e2034014aa50e.webp new file mode 100644 index 000000000..939f9b327 Binary files /dev/null and b/translated_images/pt-BR/bananas-ripe-vs-unripe-predictions.8d0e2034014aa50e.webp differ diff --git a/translated_images/pt-BR/basic-thermostat.a923217fd1f37e5a.webp b/translated_images/pt-BR/basic-thermostat.a923217fd1f37e5a.webp new file mode 100644 index 000000000..b112cc52e Binary files /dev/null and b/translated_images/pt-BR/basic-thermostat.a923217fd1f37e5a.webp differ diff --git a/translated_images/pt-BR/bing-translate.348aa796d6efe2a9.webp b/translated_images/pt-BR/bing-translate.348aa796d6efe2a9.webp new file mode 100644 index 000000000..dece93849 Binary files /dev/null and b/translated_images/pt-BR/bing-translate.348aa796d6efe2a9.webp differ diff --git a/translated_images/pt-BR/bounding-box.1420a7ea0d3d15f7.webp b/translated_images/pt-BR/bounding-box.1420a7ea0d3d15f7.webp new file mode 100644 index 000000000..17bb3f78c Binary files /dev/null and b/translated_images/pt-BR/bounding-box.1420a7ea0d3d15f7.webp differ diff --git a/translated_images/pt-BR/bricked-car.dc38f8efadc6c59d.webp b/translated_images/pt-BR/bricked-car.dc38f8efadc6c59d.webp new file mode 100644 index 000000000..aa3abeccf Binary files /dev/null and b/translated_images/pt-BR/bricked-car.dc38f8efadc6c59d.webp differ diff --git a/translated_images/pt-BR/button-with-digital.3749edea8eb885af.webp b/translated_images/pt-BR/button-with-digital.3749edea8eb885af.webp new file mode 100644 index 000000000..45eeb7f3e Binary files /dev/null and b/translated_images/pt-BR/button-with-digital.3749edea8eb885af.webp differ diff --git a/translated_images/pt-BR/button.eadb560b77ac45e5.webp b/translated_images/pt-BR/button.eadb560b77ac45e5.webp new file mode 100644 index 000000000..7a106e983 Binary files /dev/null and b/translated_images/pt-BR/button.eadb560b77ac45e5.webp differ diff --git a/translated_images/pt-BR/chart-soil-moisture-relay.fbb391236d34a64d.webp b/translated_images/pt-BR/chart-soil-moisture-relay.fbb391236d34a64d.webp new file mode 100644 index 000000000..55bf52c5f Binary files /dev/null and b/translated_images/pt-BR/chart-soil-moisture-relay.fbb391236d34a64d.webp differ diff --git a/translated_images/pt-BR/chart-soil-moisture.fd6d9d0cdc0b5f75.webp b/translated_images/pt-BR/chart-soil-moisture.fd6d9d0cdc0b5f75.webp new file mode 100644 index 000000000..da2cc3815 Binary files /dev/null and b/translated_images/pt-BR/chart-soil-moisture.fd6d9d0cdc0b5f75.webp differ diff --git a/translated_images/pt-BR/child-watering-garden.9a5d3f1bfe6d0d8d.webp b/translated_images/pt-BR/child-watering-garden.9a5d3f1bfe6d0d8d.webp new file mode 100644 index 000000000..5aee7f4c6 Binary files /dev/null and b/translated_images/pt-BR/child-watering-garden.9a5d3f1bfe6d0d8d.webp differ diff --git a/translated_images/pt-BR/cloud-with-edge.1e26462c62c126fe.webp b/translated_images/pt-BR/cloud-with-edge.1e26462c62c126fe.webp new file mode 100644 index 000000000..4516e268c Binary files /dev/null and b/translated_images/pt-BR/cloud-with-edge.1e26462c62c126fe.webp differ diff --git a/translated_images/pt-BR/cloud-without-edge.b4da641f6022c95e.webp b/translated_images/pt-BR/cloud-without-edge.b4da641f6022c95e.webp new file mode 100644 index 000000000..83c53eec5 Binary files /dev/null and b/translated_images/pt-BR/cloud-without-edge.b4da641f6022c95e.webp differ diff --git a/translated_images/pt-BR/cmos-sensor.75f9cd74decb1371.webp b/translated_images/pt-BR/cmos-sensor.75f9cd74decb1371.webp new file mode 100644 index 000000000..ccf8737de Binary files /dev/null and b/translated_images/pt-BR/cmos-sensor.75f9cd74decb1371.webp differ diff --git a/translated_images/pt-BR/commands.d6c06bbbb3a02cce.webp b/translated_images/pt-BR/commands.d6c06bbbb3a02cce.webp new file mode 100644 index 000000000..5ce548847 Binary files /dev/null and b/translated_images/pt-BR/commands.d6c06bbbb3a02cce.webp differ diff --git a/translated_images/pt-BR/condenser-mic.6f6ed5b76ca19e0e.webp b/translated_images/pt-BR/condenser-mic.6f6ed5b76ca19e0e.webp new file mode 100644 index 000000000..966d982ec Binary files /dev/null and b/translated_images/pt-BR/condenser-mic.6f6ed5b76ca19e0e.webp differ diff --git a/translated_images/pt-BR/consumer-groups.a3262e26fc27ba20.webp b/translated_images/pt-BR/consumer-groups.a3262e26fc27ba20.webp new file mode 100644 index 000000000..109aa7786 Binary files /dev/null and b/translated_images/pt-BR/consumer-groups.a3262e26fc27ba20.webp differ diff --git a/translated_images/pt-BR/container-edge-flow.c246050dd60ceefd.webp b/translated_images/pt-BR/container-edge-flow.c246050dd60ceefd.webp new file mode 100644 index 000000000..22428ec1a Binary files /dev/null and b/translated_images/pt-BR/container-edge-flow.c246050dd60ceefd.webp differ diff --git a/translated_images/pt-BR/container-web-browser.4ee81dd4f0d8838c.webp b/translated_images/pt-BR/container-web-browser.4ee81dd4f0d8838c.webp new file mode 100644 index 000000000..97627a003 Binary files /dev/null and b/translated_images/pt-BR/container-web-browser.4ee81dd4f0d8838c.webp differ diff --git a/translated_images/pt-BR/counterfit-camera-options.eb3bd5150a8e7dff.webp b/translated_images/pt-BR/counterfit-camera-options.eb3bd5150a8e7dff.webp new file mode 100644 index 000000000..1ebb931a7 Binary files /dev/null and b/translated_images/pt-BR/counterfit-camera-options.eb3bd5150a8e7dff.webp differ diff --git a/translated_images/pt-BR/counterfit-camera.001ec52194c8ee5d.webp b/translated_images/pt-BR/counterfit-camera.001ec52194c8ee5d.webp new file mode 100644 index 000000000..613ace597 Binary files /dev/null and b/translated_images/pt-BR/counterfit-camera.001ec52194c8ee5d.webp differ diff --git a/translated_images/pt-BR/counterfit-connected.ed30b46d8f79b092.webp b/translated_images/pt-BR/counterfit-connected.ed30b46d8f79b092.webp new file mode 100644 index 000000000..cadd00bec Binary files /dev/null and b/translated_images/pt-BR/counterfit-connected.ed30b46d8f79b092.webp differ diff --git a/translated_images/pt-BR/counterfit-create-camera.a5de97f59c0bd3cb.webp b/translated_images/pt-BR/counterfit-create-camera.a5de97f59c0bd3cb.webp new file mode 100644 index 000000000..78ee15c89 Binary files /dev/null and b/translated_images/pt-BR/counterfit-create-camera.a5de97f59c0bd3cb.webp differ diff --git a/translated_images/pt-BR/counterfit-create-distance-sensor.967c9fb98f27888d.webp b/translated_images/pt-BR/counterfit-create-distance-sensor.967c9fb98f27888d.webp new file mode 100644 index 000000000..c610b9b74 Binary files /dev/null and b/translated_images/pt-BR/counterfit-create-distance-sensor.967c9fb98f27888d.webp differ diff --git a/translated_images/pt-BR/counterfit-create-gps-sensor.6385dc9357d85ad1.webp b/translated_images/pt-BR/counterfit-create-gps-sensor.6385dc9357d85ad1.webp new file mode 100644 index 000000000..c4e5e6374 Binary files /dev/null and b/translated_images/pt-BR/counterfit-create-gps-sensor.6385dc9357d85ad1.webp differ diff --git a/translated_images/pt-BR/counterfit-create-humidity-sensor.2750e27b6f30e09c.webp b/translated_images/pt-BR/counterfit-create-humidity-sensor.2750e27b6f30e09c.webp new file mode 100644 index 000000000..ce6a375c6 Binary files /dev/null and b/translated_images/pt-BR/counterfit-create-humidity-sensor.2750e27b6f30e09c.webp differ diff --git a/translated_images/pt-BR/counterfit-create-led.ba9db1c9b8c622a6.webp b/translated_images/pt-BR/counterfit-create-led.ba9db1c9b8c622a6.webp new file mode 100644 index 000000000..87c9a0fad Binary files /dev/null and b/translated_images/pt-BR/counterfit-create-led.ba9db1c9b8c622a6.webp differ diff --git a/translated_images/pt-BR/counterfit-create-light-sensor.9f36a5e0d4458d8d.webp b/translated_images/pt-BR/counterfit-create-light-sensor.9f36a5e0d4458d8d.webp new file mode 100644 index 000000000..d425a41fe Binary files /dev/null and b/translated_images/pt-BR/counterfit-create-light-sensor.9f36a5e0d4458d8d.webp differ diff --git a/translated_images/pt-BR/counterfit-create-relay.fa7c40fd0f2f6afc.webp b/translated_images/pt-BR/counterfit-create-relay.fa7c40fd0f2f6afc.webp new file mode 100644 index 000000000..4cb86ca67 Binary files /dev/null and b/translated_images/pt-BR/counterfit-create-relay.fa7c40fd0f2f6afc.webp differ diff --git a/translated_images/pt-BR/counterfit-create-soil-moisture-sensor.35266135a5e0ae68.webp b/translated_images/pt-BR/counterfit-create-soil-moisture-sensor.35266135a5e0ae68.webp new file mode 100644 index 000000000..dfaf9fc45 Binary files /dev/null and b/translated_images/pt-BR/counterfit-create-soil-moisture-sensor.35266135a5e0ae68.webp differ diff --git a/translated_images/pt-BR/counterfit-create-temperature-sensor.199350ed34f7343d.webp b/translated_images/pt-BR/counterfit-create-temperature-sensor.199350ed34f7343d.webp new file mode 100644 index 000000000..ab2b96659 Binary files /dev/null and b/translated_images/pt-BR/counterfit-create-temperature-sensor.199350ed34f7343d.webp differ diff --git a/translated_images/pt-BR/counterfit-distance-sensor.079eefeeea0b68af.webp b/translated_images/pt-BR/counterfit-distance-sensor.079eefeeea0b68af.webp new file mode 100644 index 000000000..f08648e66 Binary files /dev/null and b/translated_images/pt-BR/counterfit-distance-sensor.079eefeeea0b68af.webp differ diff --git a/translated_images/pt-BR/counterfit-first-run.433326358b669b31.webp b/translated_images/pt-BR/counterfit-first-run.433326358b669b31.webp new file mode 100644 index 000000000..2f0f8b8aa Binary files /dev/null and b/translated_images/pt-BR/counterfit-first-run.433326358b669b31.webp differ diff --git a/translated_images/pt-BR/counterfit-gps-sensor-gpxfile.8310b063ce8a425c.webp b/translated_images/pt-BR/counterfit-gps-sensor-gpxfile.8310b063ce8a425c.webp new file mode 100644 index 000000000..dc0d6ea49 Binary files /dev/null and b/translated_images/pt-BR/counterfit-gps-sensor-gpxfile.8310b063ce8a425c.webp differ diff --git a/translated_images/pt-BR/counterfit-gps-sensor-latlon.008c867d75464fbe.webp b/translated_images/pt-BR/counterfit-gps-sensor-latlon.008c867d75464fbe.webp new file mode 100644 index 000000000..5c7782acf Binary files /dev/null and b/translated_images/pt-BR/counterfit-gps-sensor-latlon.008c867d75464fbe.webp differ diff --git a/translated_images/pt-BR/counterfit-gps-sensor-nmea.c62eea442171e17e.webp b/translated_images/pt-BR/counterfit-gps-sensor-nmea.c62eea442171e17e.webp new file mode 100644 index 000000000..694d93b50 Binary files /dev/null and b/translated_images/pt-BR/counterfit-gps-sensor-nmea.c62eea442171e17e.webp differ diff --git a/translated_images/pt-BR/counterfit-gps-sensor.3fbb15af0a536756.webp b/translated_images/pt-BR/counterfit-gps-sensor.3fbb15af0a536756.webp new file mode 100644 index 000000000..36c3068c7 Binary files /dev/null and b/translated_images/pt-BR/counterfit-gps-sensor.3fbb15af0a536756.webp differ diff --git a/translated_images/pt-BR/counterfit-humidity-sensor.7b12f7f339e430cb.webp b/translated_images/pt-BR/counterfit-humidity-sensor.7b12f7f339e430cb.webp new file mode 100644 index 000000000..601252b12 Binary files /dev/null and b/translated_images/pt-BR/counterfit-humidity-sensor.7b12f7f339e430cb.webp differ diff --git a/translated_images/pt-BR/counterfit-led.c0ab02de6d256ad8.webp b/translated_images/pt-BR/counterfit-led.c0ab02de6d256ad8.webp new file mode 100644 index 000000000..38d388cc7 Binary files /dev/null and b/translated_images/pt-BR/counterfit-led.c0ab02de6d256ad8.webp differ diff --git a/translated_images/pt-BR/counterfit-light-sensor.5d0f5584df56b90f.webp b/translated_images/pt-BR/counterfit-light-sensor.5d0f5584df56b90f.webp new file mode 100644 index 000000000..45e52223f Binary files /dev/null and b/translated_images/pt-BR/counterfit-light-sensor.5d0f5584df56b90f.webp differ diff --git a/translated_images/pt-BR/counterfit-relay.bbf74c1dbdc8b9ac.webp b/translated_images/pt-BR/counterfit-relay.bbf74c1dbdc8b9ac.webp new file mode 100644 index 000000000..3b20c0303 Binary files /dev/null and b/translated_images/pt-BR/counterfit-relay.bbf74c1dbdc8b9ac.webp differ diff --git a/translated_images/pt-BR/counterfit-soil-moisture-sensor.81742b2de0e9de60.webp b/translated_images/pt-BR/counterfit-soil-moisture-sensor.81742b2de0e9de60.webp new file mode 100644 index 000000000..0f8cece4f Binary files /dev/null and b/translated_images/pt-BR/counterfit-soil-moisture-sensor.81742b2de0e9de60.webp differ diff --git a/translated_images/pt-BR/counterfit-temperature-sensor.f0560236c96a9016.webp b/translated_images/pt-BR/counterfit-temperature-sensor.f0560236c96a9016.webp new file mode 100644 index 000000000..ac41d1e87 Binary files /dev/null and b/translated_images/pt-BR/counterfit-temperature-sensor.f0560236c96a9016.webp differ diff --git a/translated_images/pt-BR/custom-vision-banana-prediction.30cdff4e1d72db5d.webp b/translated_images/pt-BR/custom-vision-banana-prediction.30cdff4e1d72db5d.webp new file mode 100644 index 000000000..9f6de2bc3 Binary files /dev/null and b/translated_images/pt-BR/custom-vision-banana-prediction.30cdff4e1d72db5d.webp differ diff --git a/translated_images/pt-BR/custom-vision-create-object-detector-project.32d4fb9aa8e7e737.webp b/translated_images/pt-BR/custom-vision-create-object-detector-project.32d4fb9aa8e7e737.webp new file mode 100644 index 000000000..77caa84e3 Binary files /dev/null and b/translated_images/pt-BR/custom-vision-create-object-detector-project.32d4fb9aa8e7e737.webp differ diff --git a/translated_images/pt-BR/custom-vision-create-project.cf46325b92d8b131.webp b/translated_images/pt-BR/custom-vision-create-project.cf46325b92d8b131.webp new file mode 100644 index 000000000..a42e7b88a Binary files /dev/null and b/translated_images/pt-BR/custom-vision-create-project.cf46325b92d8b131.webp differ diff --git a/translated_images/pt-BR/custom-vision-logo.d3d4e7c8a87ec9da.webp b/translated_images/pt-BR/custom-vision-logo.d3d4e7c8a87ec9da.webp new file mode 100644 index 000000000..e5bdf9b63 Binary files /dev/null and b/translated_images/pt-BR/custom-vision-logo.d3d4e7c8a87ec9da.webp differ diff --git a/translated_images/pt-BR/custom-vision-object-detector-publish-button.34ee379fc650ccb9.webp b/translated_images/pt-BR/custom-vision-object-detector-publish-button.34ee379fc650ccb9.webp new file mode 100644 index 000000000..82e7bb672 Binary files /dev/null and b/translated_images/pt-BR/custom-vision-object-detector-publish-button.34ee379fc650ccb9.webp differ diff --git a/translated_images/pt-BR/custom-vision-prediction-key-endpoint.30c569ffd0338864.webp b/translated_images/pt-BR/custom-vision-prediction-key-endpoint.30c569ffd0338864.webp new file mode 100644 index 000000000..9d55e23b8 Binary files /dev/null and b/translated_images/pt-BR/custom-vision-prediction-key-endpoint.30c569ffd0338864.webp differ diff --git a/translated_images/pt-BR/custom-vision-publish-button.b7174e1977b0c33b.webp b/translated_images/pt-BR/custom-vision-publish-button.b7174e1977b0c33b.webp new file mode 100644 index 000000000..9ec69e817 Binary files /dev/null and b/translated_images/pt-BR/custom-vision-publish-button.b7174e1977b0c33b.webp differ diff --git a/translated_images/pt-BR/custom-vision-stock-prediction.942266ab1bcca341.webp b/translated_images/pt-BR/custom-vision-stock-prediction.942266ab1bcca341.webp new file mode 100644 index 000000000..88688d437 Binary files /dev/null and b/translated_images/pt-BR/custom-vision-stock-prediction.942266ab1bcca341.webp differ diff --git a/translated_images/pt-BR/dimmable-light.9ceffeb195dec1a8.webp b/translated_images/pt-BR/dimmable-light.9ceffeb195dec1a8.webp new file mode 100644 index 000000000..f0c0beade Binary files /dev/null and b/translated_images/pt-BR/dimmable-light.9ceffeb195dec1a8.webp differ diff --git a/translated_images/pt-BR/dmac-adc-buffers.4509aee49145c90b.webp b/translated_images/pt-BR/dmac-adc-buffers.4509aee49145c90b.webp new file mode 100644 index 000000000..7e11f940d Binary files /dev/null and b/translated_images/pt-BR/dmac-adc-buffers.4509aee49145c90b.webp differ diff --git a/translated_images/pt-BR/dynamic-mic.8babac890a2d80df.webp b/translated_images/pt-BR/dynamic-mic.8babac890a2d80df.webp new file mode 100644 index 000000000..ca562661d Binary files /dev/null and b/translated_images/pt-BR/dynamic-mic.8babac890a2d80df.webp differ diff --git a/translated_images/pt-BR/favicon.37b561214b36d454.webp b/translated_images/pt-BR/favicon.37b561214b36d454.webp new file mode 100644 index 000000000..48a53960d Binary files /dev/null and b/translated_images/pt-BR/favicon.37b561214b36d454.webp differ diff --git a/translated_images/pt-BR/fetch-decode-execute.2fd6f150f6280392.webp b/translated_images/pt-BR/fetch-decode-execute.2fd6f150f6280392.webp new file mode 100644 index 000000000..677985cc7 Binary files /dev/null and b/translated_images/pt-BR/fetch-decode-execute.2fd6f150f6280392.webp differ diff --git a/translated_images/pt-BR/fruit-quality-detector-message-flow.adf2a65da8fd8741.webp b/translated_images/pt-BR/fruit-quality-detector-message-flow.adf2a65da8fd8741.webp new file mode 100644 index 000000000..4254ea2d8 Binary files /dev/null and b/translated_images/pt-BR/fruit-quality-detector-message-flow.adf2a65da8fd8741.webp differ diff --git a/translated_images/pt-BR/gdd-calculation-corn.64a58b7a7afcd0df.webp b/translated_images/pt-BR/gdd-calculation-corn.64a58b7a7afcd0df.webp new file mode 100644 index 000000000..c39379de7 Binary files /dev/null and b/translated_images/pt-BR/gdd-calculation-corn.64a58b7a7afcd0df.webp differ diff --git a/translated_images/pt-BR/gdd-calculation-strawberries.59f57db94b22adb8.webp b/translated_images/pt-BR/gdd-calculation-strawberries.59f57db94b22adb8.webp new file mode 100644 index 000000000..4d95505e5 Binary files /dev/null and b/translated_images/pt-BR/gdd-calculation-strawberries.59f57db94b22adb8.webp differ diff --git a/translated_images/pt-BR/gdd-calculation.79b3660f9c5757aa.webp b/translated_images/pt-BR/gdd-calculation.79b3660f9c5757aa.webp new file mode 100644 index 000000000..639771008 Binary files /dev/null and b/translated_images/pt-BR/gdd-calculation.79b3660f9c5757aa.webp differ diff --git a/translated_images/pt-BR/gdd-jupyter-notebook.c5b52cf21094f158.webp b/translated_images/pt-BR/gdd-jupyter-notebook.c5b52cf21094f158.webp new file mode 100644 index 000000000..af5054b55 Binary files /dev/null and b/translated_images/pt-BR/gdd-jupyter-notebook.c5b52cf21094f158.webp differ diff --git a/translated_images/pt-BR/geofence-crossing-inaccurate-gps.6a3ed911202ad9ca.webp b/translated_images/pt-BR/geofence-crossing-inaccurate-gps.6a3ed911202ad9ca.webp new file mode 100644 index 000000000..afd49b3db Binary files /dev/null and b/translated_images/pt-BR/geofence-crossing-inaccurate-gps.6a3ed911202ad9ca.webp differ diff --git a/translated_images/pt-BR/geofence-examples.172fbc534665769f.webp b/translated_images/pt-BR/geofence-examples.172fbc534665769f.webp new file mode 100644 index 000000000..ec9fe0bdf Binary files /dev/null and b/translated_images/pt-BR/geofence-examples.172fbc534665769f.webp differ diff --git a/translated_images/pt-BR/gps-satellites.04acf1148fe25fbf.webp b/translated_images/pt-BR/gps-satellites.04acf1148fe25fbf.webp new file mode 100644 index 000000000..41fb08f87 Binary files /dev/null and b/translated_images/pt-BR/gps-satellites.04acf1148fe25fbf.webp differ diff --git a/translated_images/pt-BR/gps-telemetry-iot-hub-functions.24d3fa5592455e9f.webp b/translated_images/pt-BR/gps-telemetry-iot-hub-functions.24d3fa5592455e9f.webp new file mode 100644 index 000000000..fc590cc10 Binary files /dev/null and b/translated_images/pt-BR/gps-telemetry-iot-hub-functions.24d3fa5592455e9f.webp differ diff --git a/translated_images/pt-BR/gps-telemetry-iot-hub.8115335d51cd2c12.webp b/translated_images/pt-BR/gps-telemetry-iot-hub.8115335d51cd2c12.webp new file mode 100644 index 000000000..a02d35be1 Binary files /dev/null and b/translated_images/pt-BR/gps-telemetry-iot-hub.8115335d51cd2c12.webp differ diff --git a/translated_images/pt-BR/grove-base-hat-ribbon-cable.501fed202fcf73b1.webp b/translated_images/pt-BR/grove-base-hat-ribbon-cable.501fed202fcf73b1.webp new file mode 100644 index 000000000..0ebb86600 Binary files /dev/null and b/translated_images/pt-BR/grove-base-hat-ribbon-cable.501fed202fcf73b1.webp differ diff --git a/translated_images/pt-BR/grove-button.a70cfbb809a85636.webp b/translated_images/pt-BR/grove-button.a70cfbb809a85636.webp new file mode 100644 index 000000000..83a150907 Binary files /dev/null and b/translated_images/pt-BR/grove-button.a70cfbb809a85636.webp differ diff --git a/translated_images/pt-BR/grove-capacitive-soil-moisture-sensor.e7f0776cce30e78b.webp b/translated_images/pt-BR/grove-capacitive-soil-moisture-sensor.e7f0776cce30e78b.webp new file mode 100644 index 000000000..cfd3a8b56 Binary files /dev/null and b/translated_images/pt-BR/grove-capacitive-soil-moisture-sensor.e7f0776cce30e78b.webp differ diff --git a/translated_images/pt-BR/grove-dht11.07f8eafceee17004.webp b/translated_images/pt-BR/grove-dht11.07f8eafceee17004.webp new file mode 100644 index 000000000..6a4f7666c Binary files /dev/null and b/translated_images/pt-BR/grove-dht11.07f8eafceee17004.webp differ diff --git a/translated_images/pt-BR/grove-gps-sensor.247943bf69b03f0d.webp b/translated_images/pt-BR/grove-gps-sensor.247943bf69b03f0d.webp new file mode 100644 index 000000000..8a66bb0c3 Binary files /dev/null and b/translated_images/pt-BR/grove-gps-sensor.247943bf69b03f0d.webp differ diff --git a/translated_images/pt-BR/grove-led.6c853be93f473cf2.webp b/translated_images/pt-BR/grove-led.6c853be93f473cf2.webp new file mode 100644 index 000000000..dc76a7b13 Binary files /dev/null and b/translated_images/pt-BR/grove-led.6c853be93f473cf2.webp differ diff --git a/translated_images/pt-BR/grove-light-sensor.b8127b7c434e632d.webp b/translated_images/pt-BR/grove-light-sensor.b8127b7c434e632d.webp new file mode 100644 index 000000000..bb0add7fc Binary files /dev/null and b/translated_images/pt-BR/grove-light-sensor.b8127b7c434e632d.webp differ diff --git a/translated_images/pt-BR/grove-relay-labelled.293e068f5c3c2a19.webp b/translated_images/pt-BR/grove-relay-labelled.293e068f5c3c2a19.webp new file mode 100644 index 000000000..5e5b86c17 Binary files /dev/null and b/translated_images/pt-BR/grove-relay-labelled.293e068f5c3c2a19.webp differ diff --git a/translated_images/pt-BR/grove-relay.d426958ca210fbd0.webp b/translated_images/pt-BR/grove-relay.d426958ca210fbd0.webp new file mode 100644 index 000000000..6a01f1c4c Binary files /dev/null and b/translated_images/pt-BR/grove-relay.d426958ca210fbd0.webp differ diff --git a/translated_images/pt-BR/grove-time-of-flight-sensor.d82ff2165bfded9f.webp b/translated_images/pt-BR/grove-time-of-flight-sensor.d82ff2165bfded9f.webp new file mode 100644 index 000000000..701381e21 Binary files /dev/null and b/translated_images/pt-BR/grove-time-of-flight-sensor.d82ff2165bfded9f.webp differ diff --git a/translated_images/pt-BR/gsm-calculation-example.99f9803b4f29e976.webp b/translated_images/pt-BR/gsm-calculation-example.99f9803b4f29e976.webp new file mode 100644 index 000000000..bee687226 Binary files /dev/null and b/translated_images/pt-BR/gsm-calculation-example.99f9803b4f29e976.webp differ diff --git a/translated_images/pt-BR/gsm-calculation.6da38c6201eec14e.webp b/translated_images/pt-BR/gsm-calculation.6da38c6201eec14e.webp new file mode 100644 index 000000000..f9b4c0ef3 Binary files /dev/null and b/translated_images/pt-BR/gsm-calculation.6da38c6201eec14e.webp differ diff --git a/translated_images/pt-BR/i2c.83da845dde02256b.webp b/translated_images/pt-BR/i2c.83da845dde02256b.webp new file mode 100644 index 000000000..75799e20c Binary files /dev/null and b/translated_images/pt-BR/i2c.83da845dde02256b.webp differ diff --git a/translated_images/pt-BR/image-classifier-cashews-tomato.bc2e16ab8f05cf9a.webp b/translated_images/pt-BR/image-classifier-cashews-tomato.bc2e16ab8f05cf9a.webp new file mode 100644 index 000000000..e81074de0 Binary files /dev/null and b/translated_images/pt-BR/image-classifier-cashews-tomato.bc2e16ab8f05cf9a.webp differ diff --git a/translated_images/pt-BR/image-upload-bananas.0751639f3815e0ec.webp b/translated_images/pt-BR/image-upload-bananas.0751639f3815e0ec.webp new file mode 100644 index 000000000..6d0cb94ae Binary files /dev/null and b/translated_images/pt-BR/image-upload-bananas.0751639f3815e0ec.webp differ diff --git a/translated_images/pt-BR/image-upload-object-detector.77c7892c3093cb59.webp b/translated_images/pt-BR/image-upload-object-detector.77c7892c3093cb59.webp new file mode 100644 index 000000000..67d0aabef Binary files /dev/null and b/translated_images/pt-BR/image-upload-object-detector.77c7892c3093cb59.webp differ diff --git a/translated_images/pt-BR/iot-device-and-hacked-device-connecting-encryption.5941aff601fc978f.webp b/translated_images/pt-BR/iot-device-and-hacked-device-connecting-encryption.5941aff601fc978f.webp new file mode 100644 index 000000000..1d92173a6 Binary files /dev/null and b/translated_images/pt-BR/iot-device-and-hacked-device-connecting-encryption.5941aff601fc978f.webp differ diff --git a/translated_images/pt-BR/iot-device-and-hacked-device-connecting.e0671675df74d6d9.webp b/translated_images/pt-BR/iot-device-and-hacked-device-connecting.e0671675df74d6d9.webp new file mode 100644 index 000000000..fc2459ce3 Binary files /dev/null and b/translated_images/pt-BR/iot-device-and-hacked-device-connecting.e0671675df74d6d9.webp differ diff --git a/translated_images/pt-BR/iot-for-beginners.95958e2ed1900917.webp b/translated_images/pt-BR/iot-for-beginners.95958e2ed1900917.webp new file mode 100644 index 000000000..471551259 Binary files /dev/null and b/translated_images/pt-BR/iot-for-beginners.95958e2ed1900917.webp differ diff --git a/translated_images/pt-BR/iot-hub-cloud-to-device-message.f4f21fea772cc20b.webp b/translated_images/pt-BR/iot-hub-cloud-to-device-message.f4f21fea772cc20b.webp new file mode 100644 index 000000000..ddfb051c7 Binary files /dev/null and b/translated_images/pt-BR/iot-hub-cloud-to-device-message.f4f21fea772cc20b.webp differ diff --git a/translated_images/pt-BR/iot-hub-device-to-cloud-message.e46e584d87f35fd9.webp b/translated_images/pt-BR/iot-hub-device-to-cloud-message.e46e584d87f35fd9.webp new file mode 100644 index 000000000..4a7e70e19 Binary files /dev/null and b/translated_images/pt-BR/iot-hub-device-to-cloud-message.e46e584d87f35fd9.webp differ diff --git a/translated_images/pt-BR/iot-hub-device-twins.7055a60fc5e2331c.webp b/translated_images/pt-BR/iot-hub-device-twins.7055a60fc5e2331c.webp new file mode 100644 index 000000000..e9c0e6e60 Binary files /dev/null and b/translated_images/pt-BR/iot-hub-device-twins.7055a60fc5e2331c.webp differ diff --git a/translated_images/pt-BR/iot-hub-direct-method-request.86a5026e91f4ca18.webp b/translated_images/pt-BR/iot-hub-direct-method-request.86a5026e91f4ca18.webp new file mode 100644 index 000000000..af26c08d6 Binary files /dev/null and b/translated_images/pt-BR/iot-hub-direct-method-request.86a5026e91f4ca18.webp differ diff --git a/translated_images/pt-BR/iot-messages-to-serverless.0194da1cc0732bb7.webp b/translated_images/pt-BR/iot-messages-to-serverless.0194da1cc0732bb7.webp new file mode 100644 index 000000000..12a354cbb Binary files /dev/null and b/translated_images/pt-BR/iot-messages-to-serverless.0194da1cc0732bb7.webp differ diff --git a/translated_images/pt-BR/iot-reference-architecture-azure.0b8d2161af924cb1.webp b/translated_images/pt-BR/iot-reference-architecture-azure.0b8d2161af924cb1.webp new file mode 100644 index 000000000..1062ea532 Binary files /dev/null and b/translated_images/pt-BR/iot-reference-architecture-azure.0b8d2161af924cb1.webp differ diff --git a/translated_images/pt-BR/iot-reference-architecture-fruit-quality.cc705f121c3b6fa7.webp b/translated_images/pt-BR/iot-reference-architecture-fruit-quality.cc705f121c3b6fa7.webp new file mode 100644 index 000000000..134018a4c Binary files /dev/null and b/translated_images/pt-BR/iot-reference-architecture-fruit-quality.cc705f121c3b6fa7.webp differ diff --git a/translated_images/pt-BR/iot-reference-architecture.2278b98b55c6d4e8.webp b/translated_images/pt-BR/iot-reference-architecture.2278b98b55c6d4e8.webp new file mode 100644 index 000000000..f9784b60e Binary files /dev/null and b/translated_images/pt-BR/iot-reference-architecture.2278b98b55c6d4e8.webp differ diff --git a/translated_images/pt-BR/iot-service-allowed-denied-connection.818b0063ac213fb8.webp b/translated_images/pt-BR/iot-service-allowed-denied-connection.818b0063ac213fb8.webp new file mode 100644 index 000000000..439af3f8f Binary files /dev/null and b/translated_images/pt-BR/iot-service-allowed-denied-connection.818b0063ac213fb8.webp differ diff --git a/translated_images/pt-BR/iot-service-connectivity.7e873847921a5d6f.webp b/translated_images/pt-BR/iot-service-connectivity.7e873847921a5d6f.webp new file mode 100644 index 000000000..4521328cf Binary files /dev/null and b/translated_images/pt-BR/iot-service-connectivity.7e873847921a5d6f.webp differ diff --git a/translated_images/pt-BR/latitude-equator.feccc3214b7d9fb1.webp b/translated_images/pt-BR/latitude-equator.feccc3214b7d9fb1.webp new file mode 100644 index 000000000..a1fe083b3 Binary files /dev/null and b/translated_images/pt-BR/latitude-equator.feccc3214b7d9fb1.webp differ diff --git a/translated_images/pt-BR/latitude-lines.11d8d91dfb2014a5.webp b/translated_images/pt-BR/latitude-lines.11d8d91dfb2014a5.webp new file mode 100644 index 000000000..1ee6b8f34 Binary files /dev/null and b/translated_images/pt-BR/latitude-lines.11d8d91dfb2014a5.webp differ diff --git a/translated_images/pt-BR/led-digital-control.13b9be14077ea49f.webp b/translated_images/pt-BR/led-digital-control.13b9be14077ea49f.webp new file mode 100644 index 000000000..768359f2e Binary files /dev/null and b/translated_images/pt-BR/led-digital-control.13b9be14077ea49f.webp differ diff --git a/translated_images/pt-BR/led.ec6d94f66676a174.webp b/translated_images/pt-BR/led.ec6d94f66676a174.webp new file mode 100644 index 000000000..d7f91c36f Binary files /dev/null and b/translated_images/pt-BR/led.ec6d94f66676a174.webp differ diff --git a/translated_images/pt-BR/lesson-1.2606670fa61ee904.webp b/translated_images/pt-BR/lesson-1.2606670fa61ee904.webp new file mode 100644 index 000000000..a7f4f1e17 Binary files /dev/null and b/translated_images/pt-BR/lesson-1.2606670fa61ee904.webp differ diff --git a/translated_images/pt-BR/lesson-10.829c86b80b9403bb.webp b/translated_images/pt-BR/lesson-10.829c86b80b9403bb.webp new file mode 100644 index 000000000..cf14afa36 Binary files /dev/null and b/translated_images/pt-BR/lesson-10.829c86b80b9403bb.webp differ diff --git a/translated_images/pt-BR/lesson-11.9fddbac4b664c6d5.webp b/translated_images/pt-BR/lesson-11.9fddbac4b664c6d5.webp new file mode 100644 index 000000000..557127683 Binary files /dev/null and b/translated_images/pt-BR/lesson-11.9fddbac4b664c6d5.webp differ diff --git a/translated_images/pt-BR/lesson-12.ca7f53039712a3ec.webp b/translated_images/pt-BR/lesson-12.ca7f53039712a3ec.webp new file mode 100644 index 000000000..443e448c6 Binary files /dev/null and b/translated_images/pt-BR/lesson-12.ca7f53039712a3ec.webp differ diff --git a/translated_images/pt-BR/lesson-13.a259db1485021be7.webp b/translated_images/pt-BR/lesson-13.a259db1485021be7.webp new file mode 100644 index 000000000..1423a23b5 Binary files /dev/null and b/translated_images/pt-BR/lesson-13.a259db1485021be7.webp differ diff --git a/translated_images/pt-BR/lesson-14.63980c5150ae3c15.webp b/translated_images/pt-BR/lesson-14.63980c5150ae3c15.webp new file mode 100644 index 000000000..cacd143e6 Binary files /dev/null and b/translated_images/pt-BR/lesson-14.63980c5150ae3c15.webp differ diff --git a/translations/pa/attributions.md b/translations/pa/attributions.md index 0a86e792f..d793d7088 100644 --- a/translations/pa/attributions.md +++ b/translations/pa/attributions.md @@ -1,12 +1,3 @@ - # ਚਿੱਤਰਾਂ ਦੇ ਸ਼੍ਰੇਯ * Bananas - abderraouf omara ਦੁਆਰਾ [Noun Project](https://thenounproject.com) ਤੋਂ diff --git a/translations/pa/clean-up.md b/translations/pa/clean-up.md index b96ba88b5..49acb7ca3 100644 --- a/translations/pa/clean-up.md +++ b/translations/pa/clean-up.md @@ -1,12 +1,3 @@ - # ਆਪਣੇ ਪ੍ਰੋਜੈਕਟ ਨੂੰ ਸਾਫ ਕਰੋ ਜਦੋਂ ਤੁਸੀਂ ਹਰ ਪ੍ਰੋਜੈਕਟ ਪੂਰਾ ਕਰ ਲੈਂਦੇ ਹੋ, ਤਾਂ ਆਪਣੇ ਕਲਾਉਡ ਸਰੋਤਾਂ ਨੂੰ ਮਿਟਾਉਣਾ ਚੰਗਾ ਹੁੰਦਾ ਹੈ। diff --git a/translations/pa/docs/_sidebar.md b/translations/pa/docs/_sidebar.md index ce58bd88e..77251c2d9 100644 --- a/translations/pa/docs/_sidebar.md +++ b/translations/pa/docs/_sidebar.md @@ -1,12 +1,3 @@ - - ਜਾਣ ਪਛਾਣ - [1](../1-getting-started/lessons/1-introduction-to-iot/README.md) - [2](../1-getting-started/lessons/2-deeper-dive/README.md) diff --git a/translations/pa/docs/troubleshooting.md b/translations/pa/docs/troubleshooting.md index 49d74799c..ea8922b55 100644 --- a/translations/pa/docs/troubleshooting.md +++ b/translations/pa/docs/troubleshooting.md @@ -1,12 +1,3 @@ - # Raspberry Pi Troubleshooting Guide ਇਹ ਗਾਈਡ Raspberry Pi ਡਿਵਾਈਸਾਂ 'ਤੇ IoT ਪ੍ਰੋਜੈਕਟ ਚਲਾਉਂਦੇ ਸਮੇਂ ਆਮ ਸਮੱਸਿਆਵਾਂ ਦੇ ਹੱਲ ਪ੍ਰਦਾਨ ਕਰਦੀ ਹੈ। diff --git a/translations/pa/for-teachers.md b/translations/pa/for-teachers.md index 73f4f0fda..6a6c94bbe 100644 --- a/translations/pa/for-teachers.md +++ b/translations/pa/for-teachers.md @@ -1,12 +1,3 @@ - # ਸਿੱਖਿਆਕਾਰਾਂ ਲਈ ਕੀ ਤੁਸੀਂ ਇਸ ਪਾਠਕ੍ਰਮ ਨੂੰ ਆਪਣੇ ਕਲਾਸਰੂਮ ਵਿੱਚ ਵਰਤਣਾ ਚਾਹੋਗੇ? ਬੇਝਿਜਕ ਵਰਤੋ! diff --git a/translations/pa/hardware.md b/translations/pa/hardware.md index ca886199e..0ace70c08 100644 --- a/translations/pa/hardware.md +++ b/translations/pa/hardware.md @@ -1,12 +1,3 @@ - # ਹਾਰਡਵੇਅਰ IoT ਵਿੱਚ **T** ਦਾ ਮਤਲਬ **ਚੀਜ਼ਾਂ** ਹੈ, ਜੋ ਉਹਨਾਂ ਡਿਵਾਈਸਾਂ ਨੂੰ ਦਰਸਾਉਂਦਾ ਹੈ ਜੋ ਸਾਡੇ ਆਲੇ-ਦੁਆਲੇ ਦੀ ਦੁਨੀਆ ਨਾਲ ਸੰਚਾਰ ਕਰਦੀਆਂ ਹਨ। ਹਰ ਪ੍ਰੋਜੈਕਟ ਵਿਦਿਆਰਥੀਆਂ ਅਤੇ ਸ਼ੌਕੀਨ ਲੋਕਾਂ ਲਈ ਉਪਲਬਧ ਅਸਲ-ਦੁਨੀਆ ਦੇ ਹਾਰਡਵੇਅਰ 'ਤੇ ਆਧਾਰਿਤ ਹੈ। ਸਾਡੇ ਕੋਲ IoT ਹਾਰਡਵੇਅਰ ਦੇ ਦੋ ਚੋਣਾਂ ਹਨ, ਜੋ ਨਿੱਜੀ ਪਸੰਦ, ਪ੍ਰੋਗਰਾਮਿੰਗ ਭਾਸ਼ਾ ਦੇ ਗਿਆਨ ਜਾਂ ਪਸੰਦਾਂ, ਸਿੱਖਣ ਦੇ ਲਕਸ਼ ਅਤੇ ਉਪਲਬਧਤਾ 'ਤੇ ਨਿਰਭਰ ਕਰਦੀਆਂ ਹਨ। ਜੇਕਰ ਤੁਹਾਡੇ ਕੋਲ ਹਾਰਡਵੇਅਰ ਦੀ ਪਹੁੰਚ ਨਹੀਂ ਹੈ ਜਾਂ ਖਰੀਦਣ ਤੋਂ ਪਹਿਲਾਂ ਹੋਰ ਸਿੱਖਣਾ ਚਾਹੁੰਦੇ ਹੋ, ਤਾਂ ਸਾਡੇ ਕੋਲ 'ਵਰਚੁਅਲ ਹਾਰਡਵੇਅਰ' ਵਰਜਨ ਵੀ ਉਪਲਬਧ ਹੈ। diff --git a/translations/pa/images/README.md b/translations/pa/images/README.md index b2037629a..ed1aa23ce 100644 --- a/translations/pa/images/README.md +++ b/translations/pa/images/README.md @@ -1,12 +1,3 @@ - # ਚਿੱਤਰ [icons](../../../images/icons) ਫੋਲਡਰ ਵਿੱਚ ਚਿੱਤਰ [Noun Project](https://thenounproject.com) ਤੋਂ ਲਏ ਗਏ ਹਨ ਅਤੇ ਇਨ੍ਹਾਂ ਲਈ ਸ਼੍ਰੇਯ ਦੀ ਲੋੜ ਹੈ। ਹਰ ਚਿੱਤਰ ਵਿੱਚ ਲਾਜ਼ਮੀ ਸ਼੍ਰੇਯ ਦੀ ਜਾਣਕਾਰੀ ਦਿੱਤੀ ਗਈ ਹੈ। ਇਹ ਚਿੱਤਰ ਕਿਸੇ ਵੀ ਡਾਇਗ੍ਰਾਮ ਲਈ ਵਰਤੇ ਜਾਣੇ ਚਾਹੀਦੇ ਹਨ ਤਾਂ ਜੋ ਚਿੱਤਰਕਲਾ ਵਿੱਚ ਸਥਿਰਤਾ ਬਣੀ ਰਹੇ। diff --git a/translations/pa/lesson-template/README.md b/translations/pa/lesson-template/README.md index e6ffb166a..8cab35093 100644 --- a/translations/pa/lesson-template/README.md +++ b/translations/pa/lesson-template/README.md @@ -1,12 +1,3 @@ - # [ਪਾਠ ਦਾ ਵਿਸ਼ਾ] ![ਇਥੇ ਇੱਕ ਵੀਡੀਓ ਸ਼ਾਮਲ ਕਰੋ](../../../lesson-template/video-url) diff --git a/translations/pa/lesson-template/assignment.md b/translations/pa/lesson-template/assignment.md index e4c3f0e21..605654ad0 100644 --- a/translations/pa/lesson-template/assignment.md +++ b/translations/pa/lesson-template/assignment.md @@ -1,12 +1,3 @@ - # [ਅਸਾਈਨਮੈਂਟ ਦਾ ਨਾਮ] ## ਹਦਾਇਤਾਂ diff --git a/translations/pa/quiz-app/README.md b/translations/pa/quiz-app/README.md index 85191aca2..43a1080fa 100644 --- a/translations/pa/quiz-app/README.md +++ b/translations/pa/quiz-app/README.md @@ -1,12 +1,3 @@ - # ਕਵਿਜ਼ ਇਹ ਕਵਿਜ਼ IoT for Beginners ਪਾਠਕ੍ਰਮ ਲਈ ਲੈਕਚਰ ਤੋਂ ਪਹਿਲਾਂ ਅਤੇ ਬਾਅਦ ਦੇ ਕਵਿਜ਼ ਹਨ। ਵੇਰਵੇ ਲਈ ਜਾਓ: https://aka.ms/iot-beginners diff --git a/translations/pa/recommended-learning-model.md b/translations/pa/recommended-learning-model.md index c214c5a0a..1515cac60 100644 --- a/translations/pa/recommended-learning-model.md +++ b/translations/pa/recommended-learning-model.md @@ -1,12 +1,3 @@ - # ਸਿਫਾਰਸ਼ੀ ਸਿੱਖਣ ਮਾਡਲ ਸਿੱਖਣ ਦੇ ਸਭ ਤੋਂ ਪ੍ਰਭਾਵਸ਼ਾਲੀ ਨਤੀਜੇ ਲਈ, **ਅਸੀਂ "ਫਲਿਪਡ ਮਾਡਲ" ਪਹੁੰਚ ਦੀ ਸਿਫਾਰਸ਼ ਕਰਦੇ ਹਾਂ**, ਜਿਵੇਂ ਕਿ ਵਿਗਿਆਨ ਦੀਆਂ ਲੈਬਾਂ: ਵਿਦਿਆਰਥੀ ਕਲਾਸ ਦੇ ਸਮੇਂ ਦੌਰਾਨ ਪ੍ਰੋਜੈਕਟਾਂ 'ਤੇ ਕੰਮ ਕਰਦੇ ਹਨ, ਚਰਚਾ, ਪ੍ਰਸ਼ਨ-ਉੱਤਰ, ਅਤੇ ਪ੍ਰੋਜੈਕਟ ਮਦਦ ਲਈ ਮੌਕੇ ਦੇ ਨਾਲ, ਅਤੇ ਲੈਕਚਰ ਦੇ ਅੰਗ ਆਪਣੇ ਸਮੇਂ 'ਤੇ ਪੜ੍ਹਦੇ ਹਨ। diff --git a/translations/pt/1-getting-started/README.md b/translations/pt/1-getting-started/README.md deleted file mode 100644 index 3a1d507b8..000000000 --- a/translations/pt/1-getting-started/README.md +++ /dev/null @@ -1,28 +0,0 @@ - -# Introdução ao IoT - -Nesta secção do currículo, será introduzido ao Internet das Coisas (IoT) e aprenderá os conceitos básicos, incluindo a criação do seu primeiro projeto 'Hello World' de IoT conectado à nuvem. Este projeto é uma luz noturna que se acende à medida que os níveis de luz medidos por um sensor diminuem. - -![O LED conectado ao WIO a ligar e desligar conforme os níveis de luz mudam](../../../images/wio-running-assignment-1-1.gif) - -## Tópicos - -1. [Introdução ao IoT](lessons/1-introduction-to-iot/README.md) -1. [Uma análise mais aprofundada do IoT](lessons/2-deeper-dive/README.md) -1. [Interagir com o mundo físico usando sensores e atuadores](lessons/3-sensors-and-actuators/README.md) -1. [Conectar o seu dispositivo à Internet](lessons/4-connect-internet/README.md) - -## Créditos - -Todas as lições foram escritas com ♥️ por [Jim Bennett](https://GitHub.com/JimBobBennett) - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, tenha em atenção que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes da utilização desta tradução. \ No newline at end of file diff --git a/translations/pt/1-getting-started/lessons/1-introduction-to-iot/README.md b/translations/pt/1-getting-started/lessons/1-introduction-to-iot/README.md deleted file mode 100644 index ae4d39be2..000000000 --- a/translations/pt/1-getting-started/lessons/1-introduction-to-iot/README.md +++ /dev/null @@ -1,240 +0,0 @@ - -# Introdução ao IoT - -![Uma visão geral ilustrada desta lição](../../../../../translated_images/pt-PT/lesson-1.2606670fa61ee904687da5d6fa4e726639d524d064c895117da1b95b9ff6251d.jpg) - -> Ilustração por [Nitya Narasimhan](https://github.com/nitya). Clique na imagem para uma versão maior. - -Esta lição foi apresentada como parte da série [Hello IoT](https://youtube.com/playlist?list=PLmsFUfdnGr3xRts0TIwyaHyQuHaNQcb6-) do [Microsoft Reactor](https://developer.microsoft.com/reactor/?WT.mc_id=academic-17441-jabenn). A lição foi dividida em 2 vídeos - uma aula de 1 hora e uma sessão de perguntas e respostas de 1 hora, explorando mais a fundo partes da lição e respondendo a dúvidas. - -[![Lição 1: Introdução ao IoT](https://img.youtube.com/vi/bVFfcYh6UBw/0.jpg)](https://youtu.be/bVFfcYh6UBw) - -[![Lição 1: Introdução ao IoT - Sessão de perguntas e respostas](https://img.youtube.com/vi/YI772q5v3yI/0.jpg)](https://youtu.be/YI772q5v3yI) - -> 🎥 Clique nas imagens acima para assistir aos vídeos - -## Questionário pré-aula - -[Questionário pré-aula](https://black-meadow-040d15503.1.azurestaticapps.net/quiz/1) - -## Introdução - -Esta lição aborda alguns dos tópicos introdutórios sobre a Internet das Coisas (IoT) e ajuda você a configurar o seu hardware. - -Nesta lição, abordaremos: - -* [O que é a 'Internet das Coisas'?](../../../../../1-getting-started/lessons/1-introduction-to-iot) -* [Dispositivos IoT](../../../../../1-getting-started/lessons/1-introduction-to-iot) -* [Configurar o seu dispositivo](../../../../../1-getting-started/lessons/1-introduction-to-iot) -* [Aplicações do IoT](../../../../../1-getting-started/lessons/1-introduction-to-iot) -* [Exemplos de dispositivos IoT ao seu redor](../../../../../1-getting-started/lessons/1-introduction-to-iot) - -## O que é a 'Internet das Coisas'? - -O termo 'Internet das Coisas' foi cunhado por [Kevin Ashton](https://wikipedia.org/wiki/Kevin_Ashton) em 1999, para se referir à conexão da Internet com o mundo físico por meio de sensores. Desde então, o termo tem sido usado para descrever qualquer dispositivo que interaja com o mundo físico ao seu redor, seja coletando dados de sensores ou realizando interações no mundo real por meio de atuadores (dispositivos que fazem algo, como ligar um interruptor ou acender um LED), geralmente conectados a outros dispositivos ou à Internet. - -> **Sensores** coletam informações do mundo, como medir velocidade, temperatura ou localização. -> -> **Atuadores** convertem sinais elétricos em interações no mundo real, como acionar um interruptor, ligar luzes, emitir sons ou enviar sinais de controle para outros dispositivos, por exemplo, para ligar uma tomada. - -IoT como área tecnológica vai além de dispositivos - inclui serviços baseados na nuvem que podem processar os dados dos sensores ou enviar comandos para atuadores conectados a dispositivos IoT. Também inclui dispositivos que não possuem ou não precisam de conectividade com a Internet, frequentemente chamados de dispositivos de borda. Estes são dispositivos que podem processar e responder aos dados dos sensores por conta própria, geralmente usando modelos de IA treinados na nuvem. - -IoT é um campo tecnológico em rápido crescimento. Estima-se que, até o final de 2020, 30 bilhões de dispositivos IoT estavam implantados e conectados à Internet. Olhando para o futuro, estima-se que, até 2025, os dispositivos IoT estarão coletando quase 80 zettabytes de dados, ou 80 trilhões de gigabytes. Isso é muito dado! - -![Um gráfico mostrando o aumento de dispositivos IoT ativos ao longo do tempo, de menos de 5 bilhões em 2015 para mais de 30 bilhões em 2025](../../../../../images/connected-iot-devices.svg) - -✅ Faça uma pequena pesquisa: Quanto dos dados gerados por dispositivos IoT é realmente utilizado e quanto é desperdiçado? Por que tantos dados são ignorados? - -Esses dados são a chave para o sucesso do IoT. Para ser um desenvolvedor de IoT bem-sucedido, você precisa entender quais dados coletar, como coletá-los, como tomar decisões com base neles e como usar essas decisões para interagir com o mundo físico, se necessário. - -## Dispositivos IoT - -O **T** em IoT significa **Things** (Coisas) - dispositivos que interagem com o mundo físico ao seu redor, seja coletando dados de sensores ou realizando interações no mundo real por meio de atuadores. - -Dispositivos para uso comercial ou de produção, como rastreadores de fitness para consumidores ou controladores de máquinas industriais, geralmente são feitos sob medida. Eles utilizam placas de circuito personalizadas, talvez até processadores personalizados, projetados para atender às necessidades de uma tarefa específica, seja ser pequeno o suficiente para caber no pulso ou robusto o suficiente para operar em ambientes de alta temperatura, alta pressão ou alta vibração. - -Como desenvolvedor aprendendo sobre IoT ou criando um protótipo de dispositivo, você precisará começar com um kit de desenvolvimento. Estes são dispositivos IoT de uso geral projetados para desenvolvedores, frequentemente com recursos que não estariam presentes em um dispositivo de produção, como pinos externos para conectar sensores ou atuadores, hardware para suporte à depuração ou recursos adicionais que aumentariam o custo desnecessariamente em uma produção em larga escala. - -Esses kits de desenvolvimento geralmente se dividem em duas categorias - microcontroladores e computadores de placa única. Eles serão apresentados aqui, e entraremos em mais detalhes na próxima lição. - -> 💁 O seu telemóvel também pode ser considerado um dispositivo IoT de uso geral, com sensores e atuadores integrados, sendo que diferentes aplicações utilizam esses sensores e atuadores de maneiras diferentes com serviços na nuvem. Você pode até encontrar alguns tutoriais de IoT que usam uma aplicação de telemóvel como dispositivo IoT. - -### Microcontroladores - -Um microcontrolador (também chamado de MCU, abreviação de microcontroller unit) é um pequeno computador composto por: - -🧠 Um ou mais processadores centrais (CPUs) - o 'cérebro' do microcontrolador que executa o seu programa - -💾 Memória (RAM e memória de programa) - onde o seu programa, dados e variáveis são armazenados - -🔌 Conexões de entrada/saída (I/O) programáveis - para comunicação com periféricos externos (dispositivos conectados), como sensores e atuadores - -Os microcontroladores são dispositivos de computação de baixo custo, com preços médios para aqueles usados em hardware personalizado caindo para cerca de US$0,50, e alguns dispositivos custando apenas US$0,03. Kits de desenvolvimento podem começar a partir de US$4, com os custos aumentando à medida que mais recursos são adicionados. O [Wio Terminal](https://www.seeedstudio.com/Wio-Terminal-p-4509.html), um kit de desenvolvimento de microcontrolador da [Seeed Studios](https://www.seeedstudio.com) que possui sensores, atuadores, WiFi e uma tela, custa cerca de US$30. - -![Um Wio Terminal](../../../../../translated_images/pt-PT/wio-terminal.b8299ee16587db9a.webp) - -> 💁 Ao pesquisar na Internet por microcontroladores, tenha cuidado ao procurar pelo termo **MCU**, pois isso trará muitos resultados relacionados ao Universo Cinematográfico da Marvel, e não a microcontroladores. - -Os microcontroladores são projetados para serem programados para realizar um número limitado de tarefas muito específicas, em vez de serem computadores de uso geral como PCs ou Macs. Exceto em cenários muito específicos, você não pode conectar um monitor, teclado e rato e usá-los para tarefas gerais. - -Os kits de desenvolvimento de microcontroladores geralmente vêm com sensores e atuadores adicionais integrados. A maioria das placas terá um ou mais LEDs que você pode programar, juntamente com outros dispositivos, como conectores padrão para adicionar mais sensores ou atuadores usando os ecossistemas de vários fabricantes ou sensores integrados (geralmente os mais populares, como sensores de temperatura). Alguns microcontroladores possuem conectividade sem fios integrada, como Bluetooth ou WiFi, ou têm microcontroladores adicionais na placa para adicionar essa conectividade. - -> 💁 Os microcontroladores geralmente são programados em C/C++. - -### Computadores de placa única - -Um computador de placa única é um pequeno dispositivo de computação que contém todos os elementos de um computador completo em uma única placa pequena. Estes dispositivos possuem especificações próximas a um PC ou Mac de secretária ou portátil, executam um sistema operativo completo, mas são menores, consomem menos energia e são substancialmente mais baratos. - -![Um Raspberry Pi 4](../../../../../translated_images/pt-PT/raspberry-pi-4.fd4590d308c3d456.webp) - -O Raspberry Pi é um dos computadores de placa única mais populares. - -Assim como um microcontrolador, os computadores de placa única possuem uma CPU, memória e pinos de entrada/saída, mas têm recursos adicionais, como um chip gráfico para permitir a conexão de monitores, saídas de áudio e portas USB para conectar teclados, ratos e outros dispositivos USB padrão, como webcams ou armazenamento externo. Os programas são armazenados em cartões SD ou discos rígidos, juntamente com um sistema operativo, em vez de um chip de memória integrado na placa. - -> 🎓 Você pode pensar em um computador de placa única como uma versão menor e mais barata do PC ou Mac que está a usar, com a adição de pinos GPIO (entrada/saída de uso geral) para interagir com sensores e atuadores. - -Os computadores de placa única são computadores completos, por isso podem ser programados em qualquer linguagem. Os dispositivos IoT geralmente são programados em Python. - -### Escolha de hardware para as próximas lições - -Todas as lições subsequentes incluem tarefas usando um dispositivo IoT para interagir com o mundo físico e comunicar com a nuvem. Cada lição suporta 3 opções de dispositivos - Arduino (usando um Seeed Studios Wio Terminal) ou um computador de placa única, seja um dispositivo físico (um Raspberry Pi 4) ou um computador de placa única virtual executado no seu PC ou Mac. - -Você pode ler sobre o hardware necessário para concluir todas as tarefas no [guia de hardware](../../../hardware.md). - -> 💁 Não é necessário adquirir nenhum hardware IoT para concluir as tarefas, você pode fazer tudo usando um computador de placa única virtual. - -A escolha do hardware depende de você - depende do que tem disponível em casa ou na escola e da linguagem de programação que conhece ou planeia aprender. Ambas as variantes de hardware usarão o mesmo ecossistema de sensores, então, se começar com uma, pode mudar para a outra sem precisar substituir a maior parte do kit. O computador de placa única virtual será equivalente a aprender em um Raspberry Pi, com a maior parte do código transferível para o Pi caso eventualmente adquira um dispositivo e sensores. - -### Kit de desenvolvimento Arduino - -Se estiver interessado em aprender desenvolvimento de microcontroladores, pode concluir as tarefas usando um dispositivo Arduino. Será necessário ter um conhecimento básico de programação em C/C++, pois as lições ensinarão apenas o código relevante para o framework Arduino, os sensores e atuadores utilizados e as bibliotecas que interagem com a nuvem. - -As tarefas usarão o [Visual Studio Code](https://code.visualstudio.com/?WT.mc_id=academic-17441-jabenn) com a [extensão PlatformIO para desenvolvimento de microcontroladores](https://platformio.org). Também pode usar o Arduino IDE se já tiver experiência com esta ferramenta, mas as instruções não serão fornecidas. - -### Kit de desenvolvimento de computador de placa única - -Se estiver interessado em aprender desenvolvimento IoT usando computadores de placa única, pode concluir as tarefas usando um Raspberry Pi ou um dispositivo virtual executado no seu PC ou Mac. - -Será necessário ter um conhecimento básico de programação em Python, pois as lições ensinarão apenas o código relevante para os sensores e atuadores utilizados e as bibliotecas que interagem com a nuvem. - -> 💁 Se quiser aprender a programar em Python, confira as seguintes séries de vídeos: -> -> * [Python para iniciantes](https://channel9.msdn.com/Series/Intro-to-Python-Development?WT.mc_id=academic-17441-jabenn) -> * [Mais Python para iniciantes](https://channel9.msdn.com/Series/More-Python-for-Beginners?WT.mc_id=academic-7372-jabenn) - -As tarefas usarão o [Visual Studio Code](https://code.visualstudio.com/?WT.mc_id=academic-17441-jabenn). - -Se estiver a usar um Raspberry Pi, pode executar o Pi com a versão completa do sistema operativo Raspberry Pi OS e fazer toda a programação diretamente no Pi usando [a versão do VS Code para Raspberry Pi OS](https://code.visualstudio.com/docs/setup/raspberry-pi?WT.mc_id=academic-17441-jabenn), ou executar o Pi como um dispositivo sem cabeça e programar a partir do seu PC ou Mac usando o VS Code com a [extensão Remote SSH](https://code.visualstudio.com/docs/remote/ssh?WT.mc_id=academic-17441-jabenn), que permite conectar-se ao Pi e editar, depurar e executar código como se estivesse a programar diretamente nele. - -Se optar pelo dispositivo virtual, programará diretamente no seu computador. Em vez de acessar sensores e atuadores, usará uma ferramenta para simular este hardware, fornecendo valores de sensores que pode definir e mostrando os resultados dos atuadores no ecrã. - -## Configurar o seu dispositivo - -Antes de começar a programar o seu dispositivo IoT, será necessário realizar uma pequena configuração. Siga as instruções relevantes abaixo, dependendo do dispositivo que irá utilizar. -> 💁 Se ainda não tens um dispositivo, consulta o [guia de hardware](../../../hardware.md) para te ajudar a decidir qual dispositivo vais usar e que hardware adicional precisas de adquirir. Não é necessário comprar hardware, pois todos os projetos podem ser executados em hardware virtual. -Estas instruções incluem links para websites de terceiros dos criadores do hardware ou ferramentas que irá utilizar. Isto garante que está sempre a usar as instruções mais atualizadas para as várias ferramentas e hardware. - -Siga o guia relevante para configurar o seu dispositivo e completar um projeto 'Hello World'. Este será o primeiro passo para criar uma luz noturna IoT ao longo das 4 lições desta parte introdutória. - -* [Arduino - Wio Terminal](wio-terminal.md) -* [Computador de placa única - Raspberry Pi](pi.md) -* [Computador de placa única - Dispositivo virtual](virtual-device.md) - -✅ Irá utilizar o VS Code tanto para Arduino como para computadores de placa única. Se nunca utilizou esta ferramenta antes, leia mais sobre ela no [site do VS Code](https://code.visualstudio.com?WT.mc_id=academic-17441-jabenn). - -## Aplicações da IoT - -A IoT abrange uma vasta gama de casos de uso, divididos em alguns grupos principais: - -* IoT para consumidores -* IoT comercial -* IoT industrial -* IoT de infraestrutura - -✅ Faça uma pequena pesquisa: Para cada uma das áreas descritas abaixo, encontre um exemplo concreto que não esteja mencionado no texto. - -### IoT para consumidores - -IoT para consumidores refere-se a dispositivos IoT que os consumidores compram e utilizam em casa. Alguns destes dispositivos são extremamente úteis, como altifalantes inteligentes, sistemas de aquecimento inteligentes e aspiradores robóticos. Outros têm uma utilidade questionável, como torneiras controladas por voz que depois não podem ser desligadas porque o controlo por voz não consegue ouvir devido ao som da água a correr. - -Os dispositivos IoT para consumidores estão a capacitar as pessoas a fazer mais no seu ambiente, especialmente os 1 bilião de pessoas que têm uma deficiência. Aspiradores robóticos podem proporcionar pisos limpos a pessoas com problemas de mobilidade que não conseguem aspirar sozinhas, fornos controlados por voz permitem que pessoas com visão limitada ou dificuldades motoras aqueçam os seus fornos apenas com a voz, monitores de saúde permitem que pacientes acompanhem condições crónicas com atualizações mais regulares e detalhadas sobre o seu estado. Estes dispositivos estão a tornar-se tão comuns que até crianças pequenas os utilizam como parte do seu dia-a-dia, por exemplo, estudantes que fazem ensino virtual durante a pandemia de COVID a definir temporizadores em dispositivos inteligentes para acompanhar o trabalho escolar ou alarmes para lembrar reuniões de aulas. - -✅ Que dispositivos IoT para consumidores tem consigo ou em sua casa? - -### IoT comercial - -IoT comercial abrange o uso de IoT no local de trabalho. Num ambiente de escritório, podem existir sensores de ocupação e detetores de movimento para gerir a iluminação e o aquecimento, mantendo as luzes e o calor desligados quando não são necessários, reduzindo custos e emissões de carbono. Numa fábrica, dispositivos IoT podem monitorizar perigos de segurança, como trabalhadores sem capacetes ou níveis de ruído perigosos. No comércio, dispositivos IoT podem medir a temperatura de armazenamento a frio, alertando o proprietário da loja se um frigorífico ou congelador estiver fora da faixa de temperatura necessária, ou podem monitorizar itens nas prateleiras para direcionar os funcionários a reabastecer produtos vendidos. A indústria de transportes está a depender cada vez mais da IoT para monitorizar a localização de veículos, rastrear quilometragem em estrada para cobrança de utilizadores, acompanhar horas de condução e cumprimento de pausas, ou notificar funcionários quando um veículo está a aproximar-se de um depósito para preparar o carregamento ou descarregamento. - -✅ Que dispositivos IoT comerciais tem na sua escola ou local de trabalho? - -### IoT industrial (IIoT) - -IoT industrial, ou IIoT, é o uso de dispositivos IoT para controlar e gerir máquinas em grande escala. Isto abrange uma ampla gama de casos de uso, desde fábricas até agricultura digital. - -As fábricas utilizam dispositivos IoT de várias formas. Máquinas podem ser monitorizadas com múltiplos sensores para acompanhar coisas como temperatura, vibração e velocidade de rotação. Estes dados podem ser monitorizados para permitir que a máquina seja desligada se ultrapassar certos limites - por exemplo, se estiver demasiado quente e for desligada. Estes dados também podem ser recolhidos e analisados ao longo do tempo para realizar manutenção preditiva, onde modelos de IA analisam os dados que antecedem uma falha e utilizam isso para prever outras falhas antes que aconteçam. - -A agricultura digital é importante para alimentar a população crescente, especialmente para os 2 biliões de pessoas em 500 milhões de lares que dependem da [agricultura de subsistência](https://wikipedia.org/wiki/Subsistence_agriculture). A agricultura digital pode variar desde sensores de poucos dólares até grandes instalações comerciais. Um agricultor pode começar por monitorizar temperaturas e usar [dias de grau de crescimento](https://wikipedia.org/wiki/Growing_degree-day) para prever quando uma colheita estará pronta para ser colhida. Pode ligar a monitorização da humidade do solo a sistemas de rega automatizados para dar às plantas a quantidade de água necessária, mas sem desperdiçar, garantindo que as colheitas não secam. Alguns agricultores estão a ir ainda mais longe, utilizando drones, dados de satélite e IA para monitorizar o crescimento das colheitas, doenças e qualidade do solo em grandes áreas de terreno agrícola. - -✅ Que outros dispositivos IoT poderiam ajudar os agricultores? - -### IoT de infraestrutura - -IoT de infraestrutura é a monitorização e controlo da infraestrutura local e global que as pessoas utilizam diariamente. - -[Cidades inteligentes](https://wikipedia.org/wiki/Smart_city) são áreas urbanas que utilizam dispositivos IoT para recolher dados sobre a cidade e utilizá-los para melhorar o funcionamento da mesma. Estas cidades geralmente são geridas com colaborações entre governos locais, academia e empresas locais, monitorizando e gerindo coisas como transporte, estacionamento e poluição. Por exemplo, em Copenhaga, Dinamarca, a poluição do ar é importante para os residentes locais, sendo medida e os dados utilizados para fornecer informações sobre as rotas mais limpas para ciclismo e jogging. - -[Redes elétricas inteligentes](https://wikipedia.org/wiki/Smart_grid) permitem melhores análises da procura de energia ao recolher dados de utilização ao nível de residências individuais. Estes dados podem orientar decisões a nível nacional, como onde construir novas centrais elétricas, e a nível pessoal, dando aos utilizadores informações sobre o consumo de energia, quando o utilizam e até sugestões para reduzir custos, como carregar carros elétricos à noite. - -✅ Se pudesse adicionar dispositivos IoT para medir algo onde vive, o que seria? - -## Exemplos de dispositivos IoT que pode ter à sua volta - -Ficaria surpreendido com a quantidade de dispositivos IoT que tem à sua volta. Estou a escrever isto de casa e tenho os seguintes dispositivos conectados à Internet com funcionalidades inteligentes, como controlo por aplicação, controlo por voz ou a capacidade de enviar dados para mim através do telemóvel: - -* Vários altifalantes inteligentes -* Frigorífico, máquina de lavar loiça, forno e micro-ondas -* Monitor de eletricidade para painéis solares -* Tomadas inteligentes -* Campainha de vídeo e câmaras de segurança -* Termóstato inteligente com vários sensores inteligentes de divisão -* Abridor de porta de garagem -* Sistemas de entretenimento doméstico e televisões controladas por voz -* Luzes -* Rastreadores de fitness e saúde - -Todos estes tipos de dispositivos têm sensores e/ou atuadores e comunicam com a Internet. Posso verificar no meu telemóvel se a porta da garagem está aberta e pedir ao meu altifalante inteligente para a fechar. Posso até configurá-la para um temporizador, para que, se ainda estiver aberta à noite, feche automaticamente. Quando a minha campainha toca, posso ver no meu telemóvel quem está lá, onde quer que esteja no mundo, e falar com eles através de um altifalante e microfone embutidos na campainha. Posso monitorizar a minha glicose no sangue, frequência cardíaca e padrões de sono, procurando padrões nos dados para melhorar a minha saúde. Posso controlar as minhas luzes através da nuvem e ficar no escuro quando a minha ligação à Internet falha. - ---- - -## 🚀 Desafio - -Liste o maior número possível de dispositivos IoT que tem em casa, na escola ou no local de trabalho - pode haver mais do que imagina! - -## Questionário pós-aula - -[Questionário pós-aula](https://black-meadow-040d15503.1.azurestaticapps.net/quiz/2) - -## Revisão e estudo autónomo - -Leia sobre os benefícios e falhas de projetos de IoT para consumidores. Consulte sites de notícias para artigos sobre quando algo correu mal, como questões de privacidade, problemas de hardware ou problemas causados pela falta de conectividade. - -Alguns exemplos: - -* Consulte a conta de Twitter **[Internet of Sh*t](https://twitter.com/internetofshit)** *(aviso de linguagem imprópria)* para alguns bons exemplos de falhas em IoT para consumidores. -* [c|net - O meu Apple Watch salvou a minha vida: 5 pessoas partilham as suas histórias](https://www.cnet.com/news/apple-watch-lifesaving-health-features-read-5-peoples-stories/) -* [c|net - Técnico da ADT declara-se culpado de espiar feeds de câmaras de clientes durante anos](https://www.cnet.com/news/adt-home-security-technician-pleads-guilty-to-spying-on-customer-camera-feeds-for-years/) *(aviso de conteúdo - voyeurismo não consensual)* - -## Tarefa - -[Investigue um projeto de IoT](assignment.md) - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, esteja ciente de que traduções automáticas podem conter erros ou imprecisões. O documento original no seu idioma nativo deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se uma tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas resultantes do uso desta tradução. \ No newline at end of file diff --git a/translations/pt/1-getting-started/lessons/1-introduction-to-iot/assignment.md b/translations/pt/1-getting-started/lessons/1-introduction-to-iot/assignment.md deleted file mode 100644 index 7674d9846..000000000 --- a/translations/pt/1-getting-started/lessons/1-introduction-to-iot/assignment.md +++ /dev/null @@ -1,25 +0,0 @@ - -# Investigar um projeto de IoT - -## Instruções - -Existem muitos projetos de IoT, de grande e pequeno porte, sendo implementados globalmente, desde quintas inteligentes a cidades inteligentes, na monitorização de saúde, transporte e para o uso de espaços públicos. - -Pesquise na web detalhes de um projeto que lhe interesse, idealmente um próximo de onde vive. Explique os benefícios e as desvantagens do projeto, como as vantagens que ele oferece, quaisquer problemas que cause e como a privacidade é considerada. - -## Rubrica - -| Critérios | Exemplar | Adequado | Necessita Melhorar | -| --------- | -------- | -------- | ------------------ | -| Explicar os benefícios e as desvantagens | Apresentou uma explicação clara dos benefícios e desvantagens do projeto | Apresentou uma explicação breve dos benefícios e desvantagens | Não explicou os benefícios nem as desvantagens | - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos pela precisão, esteja ciente de que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes do uso desta tradução. \ No newline at end of file diff --git a/translations/pt/1-getting-started/lessons/1-introduction-to-iot/pi.md b/translations/pt/1-getting-started/lessons/1-introduction-to-iot/pi.md deleted file mode 100644 index 7d0226165..000000000 --- a/translations/pt/1-getting-started/lessons/1-introduction-to-iot/pi.md +++ /dev/null @@ -1,284 +0,0 @@ - -# Raspberry Pi - -O [Raspberry Pi](https://raspberrypi.org) é um computador de placa única. Pode adicionar sensores e atuadores utilizando uma ampla gama de dispositivos e ecossistemas. Para estas lições, será utilizado um ecossistema de hardware chamado [Grove](https://www.seeedstudio.com/category/Grove-c-1003.html). Vai programar o seu Pi e aceder aos sensores Grove utilizando Python. - -![Um Raspberry Pi 4](../../../../../translated_images/pt-PT/raspberry-pi-4.fd4590d308c3d456.webp) - -## Configuração - -Se estiver a usar um Raspberry Pi como o seu hardware IoT, tem duas opções: pode trabalhar diretamente no Pi ao longo destas lições ou pode conectar-se remotamente a um Pi 'headless' e programar a partir do seu computador. - -Antes de começar, também precisa de ligar o Grove Base Hat ao seu Pi. - -### Tarefa - configuração - -Instale o Grove Base Hat no seu Pi e configure-o. - -1. Conecte o Grove Base Hat ao seu Pi. O conector do hat encaixa sobre todos os pinos GPIO do Pi, deslizando até ao fundo para se fixar firmemente na base. Ele cobre o Pi. - - ![Ajustar o Grove Hat](../../../../../images/pi-grove-hat-fitting.gif) - -1. Decida como pretende programar o seu Pi e siga para a secção correspondente abaixo: - - * [Trabalhar diretamente no seu Pi](../../../../../1-getting-started/lessons/1-introduction-to-iot) - * [Acesso remoto para programar o Pi](../../../../../1-getting-started/lessons/1-introduction-to-iot) - -### Trabalhar diretamente no seu Pi - -Se quiser trabalhar diretamente no seu Pi, pode usar a versão desktop do Raspberry Pi OS e instalar todas as ferramentas necessárias. - -#### Tarefa - trabalhar diretamente no seu Pi - -Prepare o seu Pi para desenvolvimento. - -1. Siga as instruções no [guia de configuração do Raspberry Pi](https://projects.raspberrypi.org/en/projects/raspberry-pi-setting-up) para configurar o seu Pi, conectá-lo a um teclado/ratinho/monitor, ligá-lo à sua rede Wi-Fi ou Ethernet e atualizar o software. - -Para programar o Pi utilizando os sensores e atuadores Grove, precisará de instalar um editor para escrever o código do dispositivo, bem como várias bibliotecas e ferramentas que interagem com o hardware Grove. - -1. Assim que o seu Pi reiniciar, abra o Terminal clicando no ícone **Terminal** na barra de menu superior ou escolha *Menu -> Acessórios -> Terminal*. - -1. Execute o seguinte comando para garantir que o sistema operativo e o software instalado estão atualizados: - - ```sh - sudo apt update && sudo apt full-upgrade --yes - ``` - -1. Execute os seguintes comandos para instalar todas as bibliotecas necessárias para o hardware Grove: - - ```sh - sudo apt install git python3-dev python3-pip --yes - - git clone https://github.com/Seeed-Studio/grove.py - cd grove.py - sudo pip3 install . - - sudo raspi-config nonint do_i2c 0 - ``` - - Isto começa por instalar o Git, juntamente com o Pip para instalar pacotes Python. - - Uma das funcionalidades mais poderosas do Python é a capacidade de instalar [pacotes Pip](https://pypi.org) - estes são pacotes de código escritos por outras pessoas e publicados na Internet. Pode instalar um pacote Pip no seu computador com um único comando e utilizá-lo no seu código. - - Os pacotes Python do Seeed Grove precisam de ser instalados a partir do código-fonte. Estes comandos irão clonar o repositório contendo o código-fonte deste pacote e instalá-lo localmente. - - > 💁 Por padrão, quando instala um pacote, ele fica disponível em todo o computador, o que pode causar problemas com versões de pacotes - como uma aplicação depender de uma versão que deixa de funcionar quando instala uma nova versão para outra aplicação. Para contornar este problema, pode usar um [ambiente virtual Python](https://docs.python.org/3/library/venv.html), essencialmente uma cópia do Python numa pasta dedicada, onde os pacotes Pip são instalados apenas nessa pasta. No entanto, não usará ambientes virtuais no seu Pi. O script de instalação do Grove instala os pacotes Python do Grove globalmente, então, para usar um ambiente virtual, teria de configurá-lo e reinstalar manualmente os pacotes Grove nesse ambiente. É mais fácil usar pacotes globais, especialmente porque muitos programadores de Pi preferem regravar um cartão SD limpo para cada projeto. - - Por fim, isto ativa a interface I2C. - -1. Reinicie o Pi utilizando o menu ou executando o seguinte comando no Terminal: - - ```sh - sudo reboot - ``` - -1. Assim que o Pi reiniciar, reabra o Terminal e execute o seguinte comando para instalar o [Visual Studio Code (VS Code)](https://code.visualstudio.com?WT.mc_id=academic-17441-jabenn) - este será o editor utilizado para escrever o código do dispositivo em Python. - - ```sh - sudo apt install code - ``` - - Após a instalação, o VS Code estará disponível na barra de menu superior. - - > 💁 Está livre para usar qualquer IDE ou editor Python de sua preferência para estas lições, mas as instruções serão baseadas no uso do VS Code. - -1. Instale o Pylance. Esta é uma extensão para o VS Code que fornece suporte à linguagem Python. Consulte a [documentação da extensão Pylance](https://marketplace.visualstudio.com/items?WT.mc_id=academic-17441-jabenn&itemName=ms-python.vscode-pylance) para obter instruções sobre como instalar esta extensão no VS Code. - -### Acesso remoto para programar o Pi - -Em vez de programar diretamente no Pi, pode configurá-lo para funcionar como 'headless', ou seja, sem estar conectado a um teclado/ratinho/monitor, e programá-lo a partir do seu computador utilizando o Visual Studio Code. - -#### Configurar o sistema operativo do Pi - -Para programar remotamente, o sistema operativo do Pi precisa de ser instalado num cartão SD. - -##### Tarefa - configurar o sistema operativo do Pi - -Configure o sistema operativo do Pi para funcionar como 'headless'. - -1. Faça o download do **Raspberry Pi Imager** na [página de software do Raspberry Pi OS](https://www.raspberrypi.org/software/) e instale-o. - -1. Insira um cartão SD no seu computador, utilizando um adaptador, se necessário. - -1. Abra o Raspberry Pi Imager. - -1. No Raspberry Pi Imager, selecione o botão **CHOOSE OS**, depois escolha *Raspberry Pi OS (Other)* e, em seguida, *Raspberry Pi OS Lite (32-bit)*. - - ![O Raspberry Pi Imager com o Raspberry Pi OS Lite selecionado](../../../../../translated_images/pt-PT/raspberry-pi-imager.24aedeab9e233d84.webp) - - > 💁 O Raspberry Pi OS Lite é uma versão do Raspberry Pi OS sem a interface gráfica ou ferramentas baseadas em UI. Estas não são necessárias para um Pi 'headless', tornando a instalação mais leve e o tempo de arranque mais rápido. - -1. Selecione o botão **CHOOSE STORAGE** e escolha o seu cartão SD. - -1. Abra as **Opções Avançadas** pressionando `Ctrl+Shift+X`. Estas opções permitem pré-configurar o Raspberry Pi OS antes de gravá-lo no cartão SD. - - 1. Marque a caixa **Enable SSH** e defina uma palavra-passe para o utilizador `pi`. Esta será a palavra-passe utilizada para iniciar sessão no Pi mais tarde. - - 1. Se planeia conectar-se ao Pi via Wi-Fi, marque a caixa **Configure WiFi** e insira o SSID e a palavra-passe da sua rede Wi-Fi, além de selecionar o seu país Wi-Fi. Não precisa de fazer isto se for usar um cabo Ethernet. Certifique-se de que a rede à qual se conecta é a mesma do seu computador. - - 1. Marque a caixa **Set locale settings** e defina o seu país e fuso horário. - - 1. Clique no botão **SAVE**. - -1. Clique no botão **WRITE** para gravar o sistema operativo no cartão SD. Se estiver a usar macOS, será solicitado que insira a sua palavra-passe, pois a ferramenta subjacente que grava imagens de disco requer acesso privilegiado. - -O sistema operativo será gravado no cartão SD e, ao concluir, o cartão será ejetado pelo sistema operativo, e será notificado. Remova o cartão SD do seu computador, insira-o no Pi, ligue o Pi e aguarde cerca de 2 minutos para que ele inicie corretamente. - -#### Conectar-se ao Pi - -O próximo passo é aceder remotamente ao Pi. Pode fazer isso utilizando `ssh`, disponível no macOS, Linux e versões recentes do Windows. - -##### Tarefa - conectar-se ao Pi - -Aceda remotamente ao Pi. - -1. Abra um Terminal ou Prompt de Comando e insira o seguinte comando para se conectar ao Pi: - - ```sh - ssh pi@raspberrypi.local - ``` - - Se estiver a usar uma versão mais antiga do Windows que não tenha `ssh` instalado, pode usar o OpenSSH. Pode encontrar as instruções de instalação na [documentação de instalação do OpenSSH](https://docs.microsoft.com//windows-server/administration/openssh/openssh_install_firstuse?WT.mc_id=academic-17441-jabenn). - -1. Isto deve conectar-se ao seu Pi e pedir a palavra-passe. - - A capacidade de encontrar computadores na sua rede utilizando `.local` é uma adição relativamente recente ao Linux e Windows. Se estiver a usar Linux ou Windows e receber erros sobre o nome do host não ser encontrado, precisará de instalar software adicional para ativar a rede ZeroConf (também referida pela Apple como Bonjour): - - 1. Se estiver a usar Linux, instale o Avahi utilizando o seguinte comando: - - ```sh - sudo apt-get install avahi-daemon - ``` - - 1. Se estiver a usar Windows, a forma mais fácil de ativar o ZeroConf é instalar o [Bonjour Print Services para Windows](http://support.apple.com/kb/DL999). Também pode instalar o [iTunes para Windows](https://www.apple.com/itunes/download/) para obter uma versão mais recente da utilidade (que não está disponível de forma independente). - - > 💁 Se não conseguir conectar-se utilizando `raspberrypi.local`, pode usar o endereço IP do seu Pi. Consulte a [documentação sobre endereços IP do Raspberry Pi](https://www.raspberrypi.org/documentation/remote-access/ip-address.md) para instruções sobre várias formas de obter o endereço IP. - -1. Insira a palavra-passe que definiu nas Opções Avançadas do Raspberry Pi Imager. - -#### Configurar o software no Pi - -Depois de se conectar ao Pi, precisa de garantir que o sistema operativo está atualizado e instalar várias bibliotecas e ferramentas que interagem com o hardware Grove. - -##### Tarefa - configurar o software no Pi - -Configure o software instalado no Pi e instale as bibliotecas Grove. - -1. A partir da sua sessão `ssh`, execute o seguinte comando para atualizar e reiniciar o Pi: - - ```sh - sudo apt update && sudo apt full-upgrade --yes && sudo reboot - ``` - - O Pi será atualizado e reiniciado. A sessão `ssh` será encerrada quando o Pi for reiniciado, então aguarde cerca de 30 segundos e reconecte-se. - -1. A partir da sessão `ssh` reconectada, execute os seguintes comandos para instalar todas as bibliotecas necessárias para o hardware Grove: - - ```sh - sudo apt install git python3-dev python3-pip --yes - - git clone https://github.com/Seeed-Studio/grove.py - cd grove.py - sudo pip3 install . - - sudo raspi-config nonint do_i2c 0 - ``` - - Isto começa por instalar o Git, juntamente com o Pip para instalar pacotes Python. - - Uma das funcionalidades mais poderosas do Python é a capacidade de instalar [pacotes Pip](https://pypi.org) - estes são pacotes de código escritos por outras pessoas e publicados na Internet. Pode instalar um pacote Pip no seu computador com um único comando e utilizá-lo no seu código. - - Os pacotes Python do Seeed Grove precisam de ser instalados a partir do código-fonte. Estes comandos irão clonar o repositório contendo o código-fonte deste pacote e instalá-lo localmente. - - > 💁 Por padrão, quando instala um pacote, ele fica disponível em todo o computador, o que pode causar problemas com versões de pacotes - como uma aplicação depender de uma versão que deixa de funcionar quando instala uma nova versão para outra aplicação. Para contornar este problema, pode usar um [ambiente virtual Python](https://docs.python.org/3/library/venv.html), essencialmente uma cópia do Python numa pasta dedicada, onde os pacotes Pip são instalados apenas nessa pasta. No entanto, não usará ambientes virtuais no seu Pi. O script de instalação do Grove instala os pacotes Python do Grove globalmente, então, para usar um ambiente virtual, teria de configurá-lo e reinstalar manualmente os pacotes Grove nesse ambiente. É mais fácil usar pacotes globais, especialmente porque muitos programadores de Pi preferem regravar um cartão SD limpo para cada projeto. - - Por fim, isto ativa a interface I2C. - -1. Reinicie o Pi executando o seguinte comando: - - ```sh - sudo reboot - ``` - - A sessão `ssh` será encerrada quando o Pi for reiniciado. Não é necessário reconectar-se. - -#### Configurar o VS Code para acesso remoto - -Depois de o Pi estar configurado, pode conectar-se a ele utilizando o Visual Studio Code (VS Code) a partir do seu computador - este é um editor de texto gratuito para programadores que será utilizado para escrever o código do dispositivo em Python. - -##### Tarefa - configurar o VS Code para acesso remoto - -Instale o software necessário e conecte-se remotamente ao seu Pi. - -1. Instale o VS Code no seu computador seguindo a [documentação do VS Code](https://code.visualstudio.com?WT.mc_id=academic-17441-jabenn). - -1. Siga as instruções na [documentação de Desenvolvimento Remoto do VS Code usando SSH](https://code.visualstudio.com/docs/remote/ssh?WT.mc_id=academic-17441-jabenn) para instalar os componentes necessários. - -1. Seguindo as mesmas instruções, conecte o VS Code ao Pi. - -1. Uma vez conectado, siga as instruções de [gestão de extensões](https://code.visualstudio.com/docs/remote/ssh#_managing-extensions?WT.mc_id=academic-17441-jabenn) para instalar remotamente a extensão [Pylance](https://marketplace.visualstudio.com/items?WT.mc_id=academic-17441-jabenn&itemName=ms-python.vscode-pylance) no Pi. - -## Olá, mundo -É tradicional, ao começar a aprender uma nova linguagem de programação ou tecnologia, criar uma aplicação 'Hello World' - uma pequena aplicação que exibe algo como o texto `"Hello World"` para confirmar que todas as ferramentas estão configuradas corretamente. - -A aplicação Hello World para o Pi garantirá que tens o Python e o Visual Studio Code instalados corretamente. - -Esta aplicação estará numa pasta chamada `nightlight`, e será reutilizada com código diferente em partes posteriores deste exercício para construir a aplicação nightlight. - -### Tarefa - hello world - -Cria a aplicação Hello World. - -1. Abre o VS Code, diretamente no Pi ou no teu computador, conectado ao Pi usando a extensão Remote SSH. - -1. Abre o Terminal do VS Code selecionando *Terminal -> New Terminal*, ou pressionando `` CTRL+` ``. O terminal abrirá no diretório home do utilizador `pi`. - -1. Executa os seguintes comandos para criar um diretório para o teu código e criar um ficheiro Python chamado `app.py` dentro desse diretório: - - ```sh - mkdir nightlight - cd nightlight - touch app.py - ``` - -1. Abre esta pasta no VS Code selecionando *File -> Open...* e escolhendo a pasta *nightlight*, depois seleciona **OK**. - - ![A janela de diálogo do VS Code a mostrar a pasta nightlight](../../../../../translated_images/pt-PT/vscode-open-nightlight-remote.d3d2a4011e30d535.webp) - -1. Abre o ficheiro `app.py` no explorador do VS Code e adiciona o seguinte código: - - ```python - print('Hello World!') - ``` - - A função `print` imprime na consola o que for passado como argumento. - -1. No Terminal do VS Code, executa o seguinte comando para correr a tua aplicação Python: - - ```sh - python app.py - ``` - - > 💁 Poderás precisar de chamar explicitamente `python3` para executar este código se tiveres o Python 2 instalado além do Python 3 (a versão mais recente). Se tiveres o Python 2 instalado, ao chamar `python`, será usada a versão 2 em vez da 3. Por padrão, as versões mais recentes do Raspberry Pi OS têm apenas o Python 3 instalado. - - A seguinte saída aparecerá no terminal: - - ```output - pi@raspberrypi:~/nightlight $ python3 app.py - Hello World! - ``` - -> 💁 Podes encontrar este código na pasta [code/pi](../../../../../1-getting-started/lessons/1-introduction-to-iot/code/pi). - -😀 O teu programa 'Hello World' foi um sucesso! - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos pela precisão, esteja ciente de que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes do uso desta tradução. \ No newline at end of file diff --git a/translations/pt/1-getting-started/lessons/1-introduction-to-iot/virtual-device.md b/translations/pt/1-getting-started/lessons/1-introduction-to-iot/virtual-device.md deleted file mode 100644 index f1005378c..000000000 --- a/translations/pt/1-getting-started/lessons/1-introduction-to-iot/virtual-device.md +++ /dev/null @@ -1,243 +0,0 @@ - -# Computador de placa única virtual - -Em vez de comprar um dispositivo IoT, juntamente com sensores e atuadores, pode usar o seu computador para simular hardware IoT. O [projeto CounterFit](https://github.com/CounterFit-IoT/CounterFit) permite executar uma aplicação localmente que simula hardware IoT, como sensores e atuadores, e aceder a esses sensores e atuadores a partir de código Python local, escrito da mesma forma que escreveria num Raspberry Pi utilizando hardware físico. - -## Configuração - -Para usar o CounterFit, precisará de instalar algum software gratuito no seu computador. - -### Tarefa - -Instale o software necessário. - -1. Instale o Python. Consulte a [página de downloads do Python](https://www.python.org/downloads/) para obter instruções sobre como instalar a versão mais recente do Python. - -1. Instale o Visual Studio Code (VS Code). Este será o editor que usará para escrever o código do seu dispositivo virtual em Python. Consulte a [documentação do VS Code](https://code.visualstudio.com?WT.mc_id=academic-17441-jabenn) para obter instruções sobre como instalar o VS Code. - - > 💁 Está livre para usar qualquer IDE ou editor de Python para estas lições, caso tenha uma ferramenta preferida, mas as instruções das lições serão baseadas no uso do VS Code. - -1. Instale a extensão Pylance para o VS Code. Esta é uma extensão para o VS Code que fornece suporte à linguagem Python. Consulte a [documentação da extensão Pylance](https://marketplace.visualstudio.com/items?WT.mc_id=academic-17441-jabenn&itemName=ms-python.vscode-pylance) para obter instruções sobre como instalar esta extensão no VS Code. - -As instruções para instalar e configurar a aplicação CounterFit serão fornecidas no momento relevante nas instruções do exercício, pois a instalação é feita por projeto. - -## Hello World - -É tradicional, ao começar com uma nova linguagem de programação ou tecnologia, criar uma aplicação 'Hello World' - uma pequena aplicação que exibe algo como o texto `"Hello World"` para mostrar que todas as ferramentas estão configuradas corretamente. - -A aplicação Hello World para o hardware IoT virtual garantirá que tem o Python e o Visual Studio Code instalados corretamente. Também se conectará ao CounterFit para os sensores e atuadores IoT virtuais. Não usará nenhum hardware, apenas se conectará para provar que tudo está a funcionar. - -Esta aplicação estará numa pasta chamada `nightlight`, e será reutilizada com código diferente em partes posteriores deste exercício para construir a aplicação de luz noturna. - -### Configurar um ambiente virtual Python - -Uma das funcionalidades poderosas do Python é a capacidade de instalar [pacotes Pip](https://pypi.org) - pacotes de código escritos por outras pessoas e publicados na Internet. Pode instalar um pacote Pip no seu computador com um único comando e, em seguida, usar esse pacote no seu código. Usará o Pip para instalar um pacote que permite comunicar com o CounterFit. - -Por padrão, quando instala um pacote, ele fica disponível em todo o computador, o que pode levar a problemas com versões de pacotes - como uma aplicação depender de uma versão de um pacote que deixa de funcionar quando instala uma nova versão para outra aplicação. Para contornar este problema, pode usar um [ambiente virtual Python](https://docs.python.org/3/library/venv.html), essencialmente uma cópia do Python numa pasta dedicada, e quando instala pacotes Pip, eles são instalados apenas nessa pasta. - -> 💁 Se estiver a usar um Raspberry Pi, não configurou um ambiente virtual nesse dispositivo para gerir pacotes Pip, em vez disso, está a usar pacotes globais, pois os pacotes Grove são instalados globalmente pelo script de instalação. - -#### Tarefa - configurar um ambiente virtual Python - -Configure um ambiente virtual Python e instale os pacotes Pip para o CounterFit. - -1. No seu terminal ou linha de comandos, execute o seguinte num local à sua escolha para criar e navegar para um novo diretório: - - ```sh - mkdir nightlight - cd nightlight - ``` - -1. Agora execute o seguinte para criar um ambiente virtual na pasta `.venv`: - - ```sh - python3 -m venv .venv - ``` - - > 💁 Precisa de chamar explicitamente `python3` para criar o ambiente virtual, caso tenha o Python 2 instalado além do Python 3 (a versão mais recente). Se tiver o Python 2 instalado, chamar `python` usará o Python 2 em vez do Python 3. - -1. Ative o ambiente virtual: - - * No Windows: - * Se estiver a usar o Command Prompt ou o Command Prompt através do Windows Terminal, execute: - - ```cmd - .venv\Scripts\activate.bat - ``` - - * Se estiver a usar o PowerShell, execute: - - ```powershell - .\.venv\Scripts\Activate.ps1 - ``` - - > Se receber um erro sobre a execução de scripts estar desativada neste sistema, precisará de ativar a execução de scripts definindo uma política de execução apropriada. Pode fazer isso ao iniciar o PowerShell como administrador e, em seguida, executar o seguinte comando: - - ```powershell - Set-ExecutionPolicy -ExecutionPolicy Unrestricted - ``` - - Insira `Y` quando solicitado a confirmar. Depois, reinicie o PowerShell e tente novamente. - - Pode redefinir esta política de execução mais tarde, se necessário. Pode ler mais sobre isso na [página de Políticas de Execução na documentação da Microsoft](https://docs.microsoft.com/powershell/module/microsoft.powershell.core/about/about_execution_policies?WT.mc_id=academic-17441-jabenn). - - * No macOS ou Linux, execute: - - ```cmd - source ./.venv/bin/activate - ``` - - > 💁 Estes comandos devem ser executados a partir do mesmo local onde executou o comando para criar o ambiente virtual. Nunca precisará de navegar para dentro da pasta `.venv`, deve sempre executar o comando de ativação e quaisquer comandos para instalar pacotes ou executar código a partir da pasta onde estava quando criou o ambiente virtual. - -1. Uma vez ativado o ambiente virtual, o comando padrão `python` executará a versão do Python usada para criar o ambiente virtual. Execute o seguinte para obter a versão: - - ```sh - python --version - ``` - - O resultado deve conter o seguinte: - - ```output - (.venv) ➜ nightlight python --version - Python 3.9.1 - ``` - - > 💁 A sua versão do Python pode ser diferente - desde que seja a versão 3.6 ou superior, está tudo bem. Caso contrário, elimine esta pasta, instale uma versão mais recente do Python e tente novamente. - -1. Execute os seguintes comandos para instalar os pacotes Pip para o CounterFit. Estes pacotes incluem a aplicação principal do CounterFit, bem como shims para hardware Grove. Estes shims permitem escrever código como se estivesse a programar com sensores e atuadores físicos do ecossistema Grove, mas conectados a dispositivos IoT virtuais. - - ```sh - pip install CounterFit - pip install counterfit-connection - pip install counterfit-shims-grove - ``` - - Estes pacotes Pip serão instalados apenas no ambiente virtual e não estarão disponíveis fora dele. - -### Escrever o código - -Depois de o ambiente virtual Python estar pronto, pode escrever o código para a aplicação 'Hello World'. - -#### Tarefa - escrever o código - -Crie uma aplicação Python para imprimir `"Hello World"` no terminal. - -1. No seu terminal ou linha de comandos, execute o seguinte dentro do ambiente virtual para criar um ficheiro Python chamado `app.py`: - - * No Windows, execute: - - ```cmd - type nul > app.py - ``` - - * No macOS ou Linux, execute: - - ```cmd - touch app.py - ``` - -1. Abra a pasta atual no VS Code: - - ```sh - code . - ``` - - > 💁 Se o seu terminal retornar `command not found` no macOS, significa que o VS Code não foi adicionado ao seu PATH. Pode adicionar o VS Code ao PATH seguindo as instruções na [secção de Lançamento a partir da linha de comandos na documentação do VS Code](https://code.visualstudio.com/docs/setup/mac?WT.mc_id=academic-17441-jabenn#_launching-from-the-command-line) e executar o comando novamente. O VS Code é adicionado ao PATH por padrão no Windows e Linux. - -1. Quando o VS Code for iniciado, ativará o ambiente virtual Python. O ambiente virtual selecionado aparecerá na barra de estado inferior: - - ![VS Code mostrando o ambiente virtual selecionado](../../../../../translated_images/pt-PT/vscode-virtual-env.8ba42e04c3d533cf.webp) - -1. Se o Terminal do VS Code já estiver em execução quando o VS Code for iniciado, ele não terá o ambiente virtual ativado. A forma mais fácil de resolver isso é encerrar o terminal usando o botão **Kill the active terminal instance**: - - ![Botão Kill the active terminal instance no VS Code](../../../../../translated_images/pt-PT/vscode-kill-terminal.1cc4de7c6f25ee08.webp) - - Pode verificar se o terminal tem o ambiente virtual ativado, pois o nome do ambiente virtual será um prefixo no prompt do terminal. Por exemplo, pode ser: - - ```sh - (.venv) ➜ nightlight - ``` - - Se não tiver `.venv` como prefixo no prompt, o ambiente virtual não está ativo no terminal. - -1. Inicie um novo Terminal do VS Code selecionando *Terminal -> New Terminal*, ou pressionando `` CTRL+` ``. O novo terminal carregará o ambiente virtual, e a chamada para ativá-lo aparecerá no terminal. O prompt também terá o nome do ambiente virtual (`.venv`): - - ```output - ➜ nightlight source .venv/bin/activate - (.venv) ➜ nightlight - ``` - -1. Abra o ficheiro `app.py` no explorador do VS Code e adicione o seguinte código: - - ```python - print('Hello World!') - ``` - - A função `print` imprime no terminal o que for passado para ela. - -1. No terminal do VS Code, execute o seguinte para executar a sua aplicação Python: - - ```sh - python app.py - ``` - - O seguinte será exibido no terminal: - - ```output - (.venv) ➜ nightlight python app.py - Hello World! - ``` - -😀 O seu programa 'Hello World' foi um sucesso! - -### Conectar o 'hardware' - -Como um segundo passo do 'Hello World', irá executar a aplicação CounterFit e conectar o seu código a ela. Este é o equivalente virtual a ligar algum hardware IoT a um kit de desenvolvimento. - -#### Tarefa - conectar o 'hardware' - -1. No terminal do VS Code, inicie a aplicação CounterFit com o seguinte comando: - - ```sh - counterfit - ``` - - A aplicação começará a ser executada e abrirá no seu navegador: - - ![A aplicação CounterFit a ser executada num navegador](../../../../../translated_images/pt-PT/counterfit-first-run.433326358b669b31d0e99c3513cb01bfbb13724d162c99cdcc8f51ecf5f9c779.png) - - Será marcada como *Disconnected*, com o LED no canto superior direito desligado. - -1. Adicione o seguinte código ao início do ficheiro `app.py`: - - ```python - from counterfit_connection import CounterFitConnection - CounterFitConnection.init('127.0.0.1', 5000) - ``` - - Este código importa a classe `CounterFitConnection` do módulo `counterfit_connection`, que vem do pacote Pip `counterfit-connection` que instalou anteriormente. Em seguida, inicializa uma conexão com a aplicação CounterFit em execução no `127.0.0.1`, que é um endereço IP que pode sempre usar para aceder ao seu computador local (frequentemente referido como *localhost*), na porta 5000. - - > 💁 Se tiver outras aplicações a usar a porta 5000, pode alterar isso atualizando a porta no código e executando o CounterFit usando `CounterFit --port `, substituindo `` pela porta que deseja usar. - -1. Precisará de iniciar um novo terminal no VS Code selecionando o botão **Create a new integrated terminal**. Isto porque a aplicação CounterFit está a ser executada no terminal atual. - - ![Botão Create a new integrated terminal no VS Code](../../../../../translated_images/pt-PT/vscode-new-terminal.77db8fc0f9cd3182.webp) - -1. Neste novo terminal, execute o ficheiro `app.py` como antes. O estado do CounterFit mudará para **Connected** e o LED acenderá. - - ![CounterFit mostrando como conectado](../../../../../translated_images/pt-PT/counterfit-connected.ed30b46d8f79b0921f3fc70be10366e596a89dca3f80c2224a9d9fc98fccf884.png) - -> 💁 Pode encontrar este código na pasta [code/virtual-device](../../../../../1-getting-started/lessons/1-introduction-to-iot/code/virtual-device). - -😀 A sua conexão com o hardware foi um sucesso! - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos pela precisão, esteja ciente de que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes do uso desta tradução. \ No newline at end of file diff --git a/translations/pt/1-getting-started/lessons/1-introduction-to-iot/wio-terminal.md b/translations/pt/1-getting-started/lessons/1-introduction-to-iot/wio-terminal.md deleted file mode 100644 index b24d25477..000000000 --- a/translations/pt/1-getting-started/lessons/1-introduction-to-iot/wio-terminal.md +++ /dev/null @@ -1,220 +0,0 @@ - -# Wio Terminal - -O [Wio Terminal da Seeed Studios](https://www.seeedstudio.com/Wio-Terminal-p-4509.html) é um microcontrolador compatível com Arduino, com WiFi e alguns sensores e atuadores integrados, bem como portas para adicionar mais sensores e atuadores, utilizando um ecossistema de hardware chamado [Grove](https://www.seeedstudio.com/category/Grove-c-1003.html). - -![Um Wio Terminal da Seeed Studios](../../../../../translated_images/pt-PT/wio-terminal.b8299ee16587db9a.webp) - -## Configuração - -Para usar o seu Wio Terminal, será necessário instalar algum software gratuito no seu computador. Também será necessário atualizar o firmware do Wio Terminal antes de conectá-lo ao WiFi. - -### Tarefa - configuração - -Instale o software necessário e atualize o firmware. - -1. Instale o Visual Studio Code (VS Code). Este será o editor que você usará para escrever o código do dispositivo em C/C++. Consulte a [documentação do VS Code](https://code.visualstudio.com?WT.mc_id=academic-17441-jabenn) para instruções sobre como instalar o VS Code. - - > 💁 Outro IDE popular para desenvolvimento com Arduino é o [Arduino IDE](https://www.arduino.cc/en/software). Se você já estiver familiarizado com esta ferramenta, pode usá-la em vez do VS Code e do PlatformIO, mas as lições fornecerão instruções baseadas no uso do VS Code. - -1. Instale a extensão PlatformIO para o VS Code. Esta é uma extensão para o VS Code que suporta a programação de microcontroladores em C/C++. Consulte a [documentação da extensão PlatformIO](https://marketplace.visualstudio.com/items?WT.mc_id=academic-17441-jabenn&itemName=platformio.platformio-ide) para instruções sobre como instalar esta extensão no VS Code. Esta extensão depende da extensão Microsoft C/C++ para trabalhar com código C e C++, e a extensão C/C++ é instalada automaticamente ao instalar o PlatformIO. - -1. Conecte o seu Wio Terminal ao computador. O Wio Terminal possui uma porta USB-C na parte inferior, que precisa ser conectada a uma porta USB do seu computador. O Wio Terminal vem com um cabo USB-C para USB-A, mas se o seu computador tiver apenas portas USB-C, será necessário um cabo USB-C ou um adaptador USB-A para USB-C. - -1. Siga as instruções na [documentação de visão geral do WiFi no Wio Terminal Wiki](https://wiki.seeedstudio.com/Wio-Terminal-Network-Overview/) para configurar o seu Wio Terminal e atualizar o firmware. - -## Hello World - -É tradicional, ao começar com uma nova linguagem de programação ou tecnologia, criar uma aplicação 'Hello World' - uma pequena aplicação que exibe algo como o texto `"Hello World"` para mostrar que todas as ferramentas estão configuradas corretamente. - -A aplicação Hello World para o Wio Terminal garantirá que você tenha o Visual Studio Code instalado corretamente com o PlatformIO e configurado para desenvolvimento de microcontroladores. - -### Criar um projeto PlatformIO - -O primeiro passo é criar um novo projeto usando o PlatformIO configurado para o Wio Terminal. - -#### Tarefa - criar um projeto PlatformIO - -Crie o projeto PlatformIO. - -1. Conecte o Wio Terminal ao seu computador. - -1. Abra o VS Code. - -1. O ícone do PlatformIO estará na barra de menu lateral: - - ![A opção de menu do PlatformIO](../../../../../translated_images/pt-PT/vscode-platformio-menu.297be26b9733e5c4.webp) - - Selecione este item de menu e, em seguida, selecione *PIO Home -> Open*. - - ![A opção de abrir o PlatformIO](../../../../../translated_images/pt-PT/vscode-platformio-home-open.3f9a41bfd3f4da1c.webp) - -1. Na tela de boas-vindas, selecione o botão **+ New Project**. - - ![O botão de novo projeto](../../../../../translated_images/pt-PT/vscode-platformio-welcome-new-button.ba6fc8a4c7b78cc8.webp) - -1. Configure o projeto no *Project Wizard*: - - 1. Nomeie o seu projeto como `nightlight`. - - 1. No menu suspenso *Board*, digite `WIO` para filtrar as placas e selecione *Seeeduino Wio Terminal*. - - 1. Deixe o *Framework* como *Arduino*. - - 1. Mantenha a caixa de seleção *Use default location* marcada ou desmarque-a e selecione um local para o seu projeto. - - 1. Selecione o botão **Finish**. - - ![O assistente de projeto concluído](../../../../../translated_images/pt-PT/vscode-platformio-nightlight-project-wizard.5c64db4da6037420.webp) - - O PlatformIO fará o download dos componentes necessários para compilar o código para o Wio Terminal e criará o seu projeto. Isso pode levar alguns minutos. - -### Explorar o projeto PlatformIO - -O explorador do VS Code mostrará vários arquivos e pastas criados pelo assistente do PlatformIO. - -#### Pastas - -* `.pio` - esta pasta contém dados temporários necessários pelo PlatformIO, como bibliotecas ou código compilado. Ela é recriada automaticamente se for excluída, e você não precisa adicioná-la ao controle de versão se estiver compartilhando seu projeto em sites como o GitHub. -* `.vscode` - esta pasta contém a configuração usada pelo PlatformIO e pelo VS Code. Ela é recriada automaticamente se for excluída, e você não precisa adicioná-la ao controle de versão se estiver compartilhando seu projeto em sites como o GitHub. -* `include` - esta pasta é para arquivos de cabeçalho externos necessários ao adicionar bibliotecas adicionais ao seu código. Você não usará esta pasta em nenhuma destas lições. -* `lib` - esta pasta é para bibliotecas externas que você deseja chamar a partir do seu código. Você não usará esta pasta em nenhuma destas lições. -* `src` - esta pasta contém o código-fonte principal da sua aplicação. Inicialmente, ela conterá um único arquivo - `main.cpp`. -* `test` - esta pasta é onde você colocaria quaisquer testes unitários para o seu código. - -#### Arquivos - -* `main.cpp` - este arquivo na pasta `src` contém o ponto de entrada para a sua aplicação. Abra este arquivo, e ele conterá o seguinte código: - - ```cpp - #include - - void setup() { - // put your setup code here, to run once: - } - - void loop() { - // put your main code here, to run repeatedly: - } - ``` - - Quando o dispositivo é iniciado, o framework Arduino executa a função `setup` uma vez e, em seguida, executa a função `loop` repetidamente até que o dispositivo seja desligado. - -* `.gitignore` - este arquivo lista os arquivos e diretórios a serem ignorados ao adicionar seu código ao controle de versão git, como ao fazer upload para um repositório no GitHub. - -* `platformio.ini` - este arquivo contém a configuração para o seu dispositivo e aplicação. Abra este arquivo, e ele conterá o seguinte código: - - ```ini - [env:seeed_wio_terminal] - platform = atmelsam - board = seeed_wio_terminal - framework = arduino - ``` - - A seção `[env:seeed_wio_terminal]` tem a configuração para o Wio Terminal. Você pode ter várias seções `env` para que o seu código possa ser compilado para várias placas. - - Os outros valores correspondem à configuração do assistente de projeto: - - * `platform = atmelsam` define o hardware que o Wio Terminal usa (um microcontrolador baseado em ATSAMD51). - * `board = seeed_wio_terminal` define o tipo de placa do microcontrolador (o Wio Terminal). - * `framework = arduino` define que este projeto está usando o framework Arduino. - -### Escrever a aplicação Hello World - -Agora você está pronto para escrever a aplicação Hello World. - -#### Tarefa - escrever a aplicação Hello World - -Escreva a aplicação Hello World. - -1. Abra o arquivo `main.cpp` no VS Code. - -1. Altere o código para corresponder ao seguinte: - - ```cpp - #include - - void setup() - { - Serial.begin(9600); - - while (!Serial) - ; // Wait for Serial to be ready - - delay(1000); - } - - void loop() - { - Serial.println("Hello World"); - delay(5000); - } - ``` - - A função `setup` inicializa uma conexão com a porta serial - neste caso, a porta USB usada para conectar o Wio Terminal ao seu computador. O parâmetro `9600` é a [taxa de transmissão](https://wikipedia.org/wiki/Symbol_rate) (também conhecida como taxa de símbolos), ou a velocidade com que os dados serão enviados pela porta serial em bits por segundo. Esta configuração significa que 9.600 bits (0s e 1s) de dados são enviados a cada segundo. Em seguida, ela aguarda até que a porta serial esteja pronta. - - A função `loop` envia a linha `Hello World!` para a porta serial, ou seja, os caracteres de `Hello World!` junto com um caractere de nova linha. Em seguida, ela entra em modo de espera por 5.000 milissegundos ou 5 segundos. Após o término do `loop`, ele é executado novamente, e assim por diante, enquanto o microcontrolador estiver ligado. - -1. Coloque o seu Wio Terminal no modo de upload. Será necessário fazer isso toda vez que você carregar um novo código no dispositivo: - - 1. Puxe o interruptor de energia para baixo duas vezes rapidamente - ele voltará automaticamente para a posição ligada a cada vez. - - 1. Verifique o LED azul de status à direita da porta USB. Ele deve estar pulsando. - - [![Um vídeo mostrando como colocar o Wio Terminal no modo de upload](https://img.youtube.com/vi/LeKU_7zLRrQ/0.jpg)](https://youtu.be/LeKU_7zLRrQ) - - Clique na imagem acima para assistir a um vídeo mostrando como fazer isso. - -1. Compile e carregue o código no Wio Terminal. - - 1. Abra o painel de comandos do VS Code. - - 1. Digite `PlatformIO Upload` para procurar a opção de upload e selecione *PlatformIO: Upload*. - - ![A opção de upload do PlatformIO no painel de comandos](../../../../../translated_images/pt-PT/vscode-platformio-upload-command-palette.9e0f49cf80d1f1c3.webp) - - O PlatformIO compilará automaticamente o código, se necessário, antes de carregá-lo. - - 1. O código será compilado e carregado no Wio Terminal. - - > 💁 Se você estiver usando macOS, uma notificação sobre um *DISCO NÃO EJETADO CORRETAMENTE* aparecerá. Isso ocorre porque o Wio Terminal é montado como uma unidade durante o processo de gravação e é desconectado quando o código compilado é escrito no dispositivo. Você pode ignorar esta notificação. - - ⚠️ Se você receber erros sobre a porta de upload estar indisponível, primeiro certifique-se de que o Wio Terminal está conectado ao seu computador, ligado usando o interruptor no lado esquerdo da tela e configurado no modo de upload. A luz verde na parte inferior deve estar acesa, e a luz azul deve estar pulsando. Se o erro persistir, puxe o interruptor de ligar/desligar para baixo duas vezes rapidamente novamente para forçar o Wio Terminal ao modo de upload e tente o upload novamente. - -O PlatformIO possui um Monitor Serial que pode monitorar os dados enviados pelo cabo USB do Wio Terminal. Isso permite monitorar os dados enviados pelo comando `Serial.println("Hello World");`. - -1. Abra o painel de comandos do VS Code. - -1. Digite `PlatformIO Serial` para procurar a opção de Monitor Serial e selecione *PlatformIO: Serial Monitor*. - - ![A opção de Monitor Serial do PlatformIO no painel de comandos](../../../../../translated_images/pt-PT/vscode-platformio-serial-monitor-command-palette.b348ec841b8a1c14.webp) - - Um novo terminal será aberto, e os dados enviados pela porta serial serão exibidos neste terminal: - - ```output - > Executing task: platformio device monitor < - - --- Available filters and text transformations: colorize, debug, default, direct, hexlify, log2file, nocontrol, printable, send_on_enter, time - --- More details at http://bit.ly/pio-monitor-filters - --- Miniterm on /dev/cu.usbmodem101 9600,8,N,1 --- - --- Quit: Ctrl+C | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H --- - Hello World - Hello World - ``` - - `Hello World` será exibido no monitor serial a cada 5 segundos. - -> 💁 Você pode encontrar este código na pasta [code/wio-terminal](../../../../../1-getting-started/lessons/1-introduction-to-iot/code/wio-terminal). - -😀 O seu programa 'Hello World' foi um sucesso! - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, esteja ciente de que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes do uso desta tradução. \ No newline at end of file diff --git a/translations/pt/1-getting-started/lessons/2-deeper-dive/README.md b/translations/pt/1-getting-started/lessons/2-deeper-dive/README.md deleted file mode 100644 index cccf6ad6b..000000000 --- a/translations/pt/1-getting-started/lessons/2-deeper-dive/README.md +++ /dev/null @@ -1,275 +0,0 @@ - -# Uma exploração mais profunda no IoT - -![Uma visão geral ilustrada desta lição](../../../../../translated_images/pt-PT/lesson-2.324b0580d620c25e0a24fb7fddfc0b29a846dd4b82c08e7a9466d580ee78ce51.jpg) - -> Ilustração por [Nitya Narasimhan](https://github.com/nitya). Clique na imagem para uma versão maior. - -Esta lição foi ensinada como parte da série [Hello IoT](https://youtube.com/playlist?list=PLmsFUfdnGr3xRts0TIwyaHyQuHaNQcb6-) do [Microsoft Reactor](https://developer.microsoft.com/reactor/?WT.mc_id=academic-17441-jabenn). A lição foi apresentada em 2 vídeos - uma aula de 1 hora e uma sessão de perguntas e respostas de 1 hora, explorando mais a fundo partes da lição e respondendo a dúvidas. - -[![Lição 2: Uma exploração mais profunda no IoT](https://img.youtube.com/vi/t0SySWw3z9M/0.jpg)](https://youtu.be/t0SySWw3z9M) - -[![Lição 2: Uma exploração mais profunda no IoT - Sessão de perguntas e respostas](https://img.youtube.com/vi/tTZYf9EST1E/0.jpg)](https://youtu.be/tTZYf9EST1E) - -> 🎥 Clique nas imagens acima para assistir aos vídeos - -## Questionário pré-aula - -[Questionário pré-aula](https://black-meadow-040d15503.1.azurestaticapps.net/quiz/3) - -## Introdução - -Esta lição explora mais profundamente alguns dos conceitos abordados na última lição. - -Nesta lição, vamos abordar: - -* [Componentes de uma aplicação IoT](../../../../../1-getting-started/lessons/2-deeper-dive) -* [Exploração mais profunda de microcontroladores](../../../../../1-getting-started/lessons/2-deeper-dive) -* [Exploração mais profunda de computadores de placa única](../../../../../1-getting-started/lessons/2-deeper-dive) - -## Componentes de uma aplicação IoT - -Os dois componentes de uma aplicação IoT são a *Internet* e o *dispositivo*. Vamos analisar esses dois componentes com mais detalhes. - -### O Dispositivo - -![Um Raspberry Pi 4](../../../../../translated_images/pt-PT/raspberry-pi-4.fd4590d308c3d456.webp) - -A parte **Dispositivo** do IoT refere-se a um equipamento que pode interagir com o mundo físico. Esses dispositivos geralmente são pequenos, de baixo custo, operando em velocidades reduzidas e consumindo pouca energia - por exemplo, microcontroladores simples com apenas alguns kilobytes de RAM (em comparação com gigabytes em um PC), operando a algumas centenas de megahertz (em comparação com gigahertz em um PC), mas consumindo tão pouca energia que podem funcionar por semanas, meses ou até anos com baterias. - -Esses dispositivos interagem com o mundo físico, seja usando sensores para coletar dados do ambiente ou controlando saídas ou atuadores para realizar mudanças físicas. Um exemplo típico é um termostato inteligente - um dispositivo que possui um sensor de temperatura, um meio de definir a temperatura desejada, como um botão ou tela sensível ao toque, e uma conexão com um sistema de aquecimento ou refrigeração que pode ser ativado quando a temperatura detectada estiver fora do intervalo desejado. O sensor de temperatura detecta que o ambiente está muito frio e um atuador liga o aquecimento. - -![Um diagrama mostrando a temperatura e um botão como entradas para um dispositivo IoT, e o controle de um aquecedor como saída](../../../../../translated_images/pt-PT/basic-thermostat.a923217fd1f37e5a6f3390396a65c22a387419ea2dd17e518ec24315ba6ae9a8.png) - -Há uma enorme variedade de dispositivos que podem atuar como dispositivos IoT, desde hardware dedicado que detecta uma única coisa até dispositivos de uso geral, incluindo o seu smartphone! Um smartphone pode usar sensores para detectar o ambiente ao seu redor e atuadores para interagir com o mundo - por exemplo, usando um sensor GPS para detectar sua localização e um alto-falante para fornecer instruções de navegação até um destino. - -✅ Pense em outros sistemas ao seu redor que leem dados de um sensor e os utilizam para tomar decisões. Um exemplo seria o termostato de um forno. Consegue encontrar mais exemplos? - -### A Internet - -A parte **Internet** de uma aplicação IoT consiste em aplicações às quais o dispositivo IoT pode se conectar para enviar e receber dados, bem como outras aplicações que podem processar os dados do dispositivo IoT e ajudar a tomar decisões sobre quais solicitações enviar aos atuadores do dispositivo IoT. - -Uma configuração típica seria ter algum tipo de serviço em nuvem ao qual o dispositivo IoT se conecta. Esse serviço em nuvem lida com aspectos como segurança, além de receber mensagens do dispositivo IoT e enviar mensagens de volta ao dispositivo. Esse serviço em nuvem, por sua vez, conecta-se a outras aplicações que podem processar ou armazenar dados de sensores, ou usar esses dados em conjunto com informações de outros sistemas para tomar decisões. - -Os dispositivos nem sempre se conectam diretamente à Internet via WiFi ou conexões com fio. Alguns dispositivos usam redes mesh para se comunicarem entre si por meio de tecnologias como Bluetooth, conectando-se a um dispositivo hub que possui uma conexão com a Internet. - -No exemplo de um termostato inteligente, o termostato se conectaria usando o WiFi doméstico a um serviço em nuvem. Ele enviaria os dados de temperatura para esse serviço em nuvem, que, por sua vez, os gravaria em um banco de dados, permitindo que o proprietário verificasse as temperaturas atuais e passadas por meio de um aplicativo no telefone. Outro serviço na nuvem saberia qual temperatura o proprietário deseja e enviaria mensagens de volta ao dispositivo IoT por meio do serviço em nuvem para informar ao sistema de aquecimento se deve ligar ou desligar. - -![Um diagrama mostrando a temperatura e um botão como entradas para um dispositivo IoT, o dispositivo IoT com comunicação bidirecional com a nuvem, que, por sua vez, tem comunicação bidirecional com um telefone, e o controle de um aquecedor como saída do dispositivo IoT](../../../../../translated_images/pt-PT/mobile-controlled-thermostat.4a994010473d8d6a52ba68c67e5f02dc8928c717e93ca4b9bc55525aa75bbb60.png) - -Uma versão ainda mais inteligente poderia usar IA na nuvem com dados de outros sensores conectados a outros dispositivos IoT, como sensores de ocupação que detectam quais cômodos estão em uso, além de dados como condições climáticas e até mesmo o seu calendário, para tomar decisões sobre como ajustar a temperatura de forma inteligente. Por exemplo, poderia desligar o aquecimento se o calendário indicar que você está de férias ou ajustar o aquecimento de forma personalizada para cada cômodo, dependendo de quais você utiliza, aprendendo com os dados para se tornar cada vez mais preciso ao longo do tempo. - -![Um diagrama mostrando múltiplos sensores de temperatura e um botão como entradas para um dispositivo IoT, o dispositivo IoT com comunicação bidirecional com a nuvem, que, por sua vez, tem comunicação bidirecional com um telefone, um calendário e um serviço meteorológico, e o controle de um aquecedor como saída do dispositivo IoT](../../../../../translated_images/pt-PT/smarter-thermostat.a75855f15d2d9e63.webp) - -✅ Que outros dados poderiam ajudar a tornar um termostato conectado à Internet mais inteligente? - -### IoT na Borda - -Embora o "I" em IoT signifique Internet, esses dispositivos não precisam necessariamente se conectar à Internet. Em alguns casos, os dispositivos podem se conectar a dispositivos de borda - dispositivos gateway que operam na sua rede local, permitindo que você processe dados sem fazer chamadas pela Internet. Isso pode ser mais rápido quando há muitos dados ou uma conexão lenta com a Internet, permite operar offline onde a conectividade com a Internet não é possível, como em um navio ou em uma área de desastre durante uma crise humanitária, e permite manter os dados privados. Alguns dispositivos contêm código de processamento criado com ferramentas em nuvem e executam esse código localmente para coletar e responder a dados sem usar uma conexão com a Internet para tomar decisões. - -Um exemplo disso é um dispositivo doméstico inteligente, como um Apple HomePod, Amazon Alexa ou Google Home, que escuta sua voz usando modelos de IA treinados na nuvem, mas que operam localmente no dispositivo. Esses dispositivos "acordam" quando uma determinada palavra ou frase é dita e, somente então, enviam sua fala pela Internet para processamento. O dispositivo para de enviar a fala em um momento apropriado, como quando detecta uma pausa na sua fala. Tudo o que você diz antes de ativar o dispositivo com a palavra de ativação e tudo o que você diz após o dispositivo parar de ouvir não será enviado pela Internet ao provedor do dispositivo, garantindo assim a privacidade. - -✅ Pense em outros cenários onde a privacidade é importante, de modo que o processamento de dados seria melhor realizado na borda em vez de na nuvem. Como dica - pense em dispositivos IoT com câmeras ou outros dispositivos de imagem. - -### Segurança no IoT - -Com qualquer conexão à Internet, a segurança é uma consideração importante. Há uma piada antiga que diz que "o S no IoT significa Segurança" - mas não há "S" em IoT, implicando que não é seguro. - -Dispositivos IoT conectam-se a um serviço em nuvem e, portanto, são tão seguros quanto esse serviço em nuvem - se o serviço permitir que qualquer dispositivo se conecte, dados maliciosos podem ser enviados ou ataques de vírus podem ocorrer. Isso pode ter consequências muito reais, já que dispositivos IoT interagem e controlam outros dispositivos. Por exemplo, o [worm Stuxnet](https://wikipedia.org/wiki/Stuxnet) manipulou válvulas em centrífugas para danificá-las. Hackers também aproveitaram [falhas de segurança para acessar monitores de bebês](https://www.npr.org/sections/thetwo-way/2018/06/05/617196788/s-c-mom-says-baby-monitor-was-hacked-experts-say-many-devices-are-vulnerable) e outros dispositivos de vigilância doméstica. - -> 💁 Às vezes, dispositivos IoT e dispositivos de borda operam em uma rede completamente isolada da Internet para manter os dados privados e seguros. Isso é conhecido como [air-gapping](https://wikipedia.org/wiki/Air_gap_(networking)). - -## Exploração mais profunda de microcontroladores - -Na última lição, introduzimos os microcontroladores. Agora, vamos analisá-los mais detalhadamente. - -### CPU - -A CPU é o "cérebro" do microcontrolador. É o processador que executa o seu código e pode enviar e receber dados de dispositivos conectados. CPUs podem conter um ou mais núcleos - essencialmente, um ou mais processadores que podem trabalhar juntos para executar o seu código. - -CPUs dependem de um relógio que "tique" milhões ou bilhões de vezes por segundo. Cada tique, ou ciclo, sincroniza as ações que a CPU pode realizar. A cada tique, a CPU pode executar uma instrução de um programa, como recuperar dados de um dispositivo externo ou realizar um cálculo matemático. Esse ciclo regular permite que todas as ações sejam concluídas antes que a próxima instrução seja processada. - -Quanto mais rápido o ciclo do relógio, mais instruções podem ser processadas por segundo e, portanto, mais rápida é a CPU. As velocidades das CPUs são medidas em [Hertz (Hz)](https://wikipedia.org/wiki/Hertz), uma unidade padrão onde 1 Hz significa um ciclo ou tique do relógio por segundo. - -> 🎓 As velocidades das CPUs geralmente são dadas em MHz ou GHz. 1MHz é 1 milhão de Hz, 1GHz é 1 bilhão de Hz. - -> 💁 As CPUs executam programas usando o [ciclo buscar-decodificar-executar](https://wikipedia.org/wiki/Instruction_cycle). A cada tique do relógio, a CPU buscará a próxima instrução na memória, decodificará e, em seguida, executará, como usar uma unidade lógica aritmética (ALU) para somar dois números. Algumas execuções levarão múltiplos tiques para serem concluídas, então o próximo ciclo será executado no próximo tique após a conclusão da instrução. - -![Os ciclos buscar-decodificar-executar mostrando a busca de uma instrução do programa armazenado na RAM, depois decodificando e executando na CPU](../../../../../translated_images/pt-PT/fetch-decode-execute.2fd6f150f6280392807f4475382319abd0cee0b90058e1735444d6baa6f2078c.png) - -Microcontroladores têm velocidades de relógio muito mais baixas do que computadores de mesa ou portáteis, ou mesmo a maioria dos smartphones. O Wio Terminal, por exemplo, tem uma CPU que opera a 120MHz ou 120.000.000 ciclos por segundo. - -✅ Um PC ou Mac médio tem uma CPU com múltiplos núcleos operando a múltiplos GigaHertz, o que significa que o relógio tica bilhões de vezes por segundo. Pesquise a velocidade do relógio do seu computador e compare quantas vezes ele é mais rápido do que o Wio Terminal. - -Cada ciclo do relógio consome energia e gera calor. Quanto mais rápidos os tiques, mais energia é consumida e mais calor é gerado. PCs possuem dissipadores de calor e ventoinhas para remover o calor, sem os quais eles superaqueceriam e desligariam em segundos. Microcontroladores geralmente não possuem esses componentes, pois operam muito mais frios e, portanto, muito mais lentos. PCs funcionam com energia elétrica ou grandes baterias por algumas horas, enquanto microcontroladores podem operar por dias, meses ou até anos com pequenas baterias. Microcontroladores também podem ter núcleos que operam em velocidades diferentes, alternando para núcleos mais lentos e de baixo consumo quando a demanda na CPU é baixa, para reduzir o consumo de energia. - -> 💁 Alguns PCs e Macs estão adotando a mesma combinação de núcleos rápidos de alto desempenho e núcleos mais lentos de alta eficiência, alternando para economizar bateria. Por exemplo, o chip M1 nos últimos laptops da Apple pode alternar entre 4 núcleos de desempenho e 4 núcleos de eficiência para otimizar a vida útil da bateria ou a velocidade, dependendo da tarefa em execução. - -✅ Faça uma pequena pesquisa: Leia sobre CPUs no [artigo da Wikipedia sobre CPUs](https://wikipedia.org/wiki/Central_processing_unit). - -#### Tarefa - -Investigue o Wio Terminal. - -Se você estiver usando um Wio Terminal para estas lições, tente localizar a CPU. Encontre a seção *Hardware Overview* na [página do produto Wio Terminal](https://www.seeedstudio.com/Wio-Terminal-p-4509.html) para uma imagem do interior e tente localizar a CPU através da janela de plástico transparente na parte de trás. - -### Memória - -Microcontroladores geralmente possuem dois tipos de memória - memória de programa e memória de acesso aleatório (RAM). - -A memória de programa é não volátil, o que significa que o que for escrito nela permanece mesmo quando não há energia no dispositivo. Esta é a memória que armazena o código do seu programa. - -A RAM é a memória usada pelo programa para ser executado, contendo variáveis alocadas pelo seu programa e dados coletados de periféricos. A RAM é volátil, ou seja, quando a energia é desligada, o conteúdo é perdido, efetivamente reiniciando o programa. -🎓 A memória de programa armazena o seu código e permanece mesmo quando não há energia. -> 🎓 A RAM é usada para executar o seu programa e é reiniciada quando não há energia - -Tal como acontece com a CPU, a memória de um microcontrolador é várias ordens de magnitude menor do que a de um PC ou Mac. Um PC típico pode ter 8 Gigabytes (GB) de RAM, ou 8.000.000.000 bytes, sendo que cada byte tem espaço suficiente para armazenar uma única letra ou um número de 0 a 255. Um microcontrolador, por outro lado, teria apenas Kilobytes (KB) de RAM, sendo que um kilobyte equivale a 1.000 bytes. O terminal Wio mencionado acima tem 192KB de RAM, ou 192.000 bytes - mais de 40.000 vezes menos do que um PC médio! - -O diagrama abaixo mostra a diferença relativa de tamanho entre 192KB e 8GB - o pequeno ponto no centro representa 192KB. - -![Uma comparação entre 192KB e 8GB - mais de 40.000 vezes maior](../../../../../translated_images/pt-PT/ram-comparison.6beb73541b42ac6f.webp) - -O armazenamento de programas também é menor do que num PC. Um PC típico pode ter um disco rígido de 500GB para armazenamento de programas, enquanto um microcontrolador pode ter apenas kilobytes ou, talvez, alguns megabytes (MB) de armazenamento (1MB é 1.000KB, ou 1.000.000 bytes). O terminal Wio tem 4MB de armazenamento para programas. - -✅ Faça uma pequena pesquisa: Quanta RAM e armazenamento tem o computador que está a usar para ler isto? Como isso se compara a um microcontrolador? - -### Entrada/Saída - -Os microcontroladores precisam de conexões de entrada e saída (I/O) para ler dados de sensores e enviar sinais de controlo para atuadores. Normalmente, eles possuem vários pinos de entrada/saída de uso geral (GPIO). Estes pinos podem ser configurados por software como entrada (ou seja, recebem um sinal) ou saída (enviam um sinal). - -🧠⬅️ Os pinos de entrada são usados para ler valores de sensores. - -🧠➡️ Os pinos de saída enviam instruções para atuadores. - -✅ Vai aprender mais sobre isto numa lição posterior. - -#### Tarefa - -Investigue o terminal Wio. - -Se estiver a usar um terminal Wio para estas lições, encontre os pinos GPIO. Consulte a secção *Pinout diagram* na [página do produto Wio Terminal](https://www.seeedstudio.com/Wio-Terminal-p-4509.html) para saber quais pinos correspondem a quê. O terminal Wio vem com um autocolante que pode colar na parte de trás com os números dos pinos, por isso adicione-o agora, se ainda não o fez. - -### Tamanho físico - -Os microcontroladores são geralmente pequenos, sendo que o menor, um [Freescale Kinetis KL03 MCU, é pequeno o suficiente para caber na cavidade de uma bola de golfe](https://www.edn.com/tiny-arm-cortex-m0-based-mcu-shrinks-package/). Apenas a CPU de um PC pode medir 40mm x 40mm, sem incluir os dissipadores de calor e ventoinhas necessários para garantir que a CPU funcione por mais de alguns segundos sem sobreaquecer, sendo substancialmente maior do que um microcontrolador completo. O kit de desenvolvimento do terminal Wio, com um microcontrolador, caixa, ecrã e uma gama de conexões e componentes, não é muito maior do que uma CPU Intel i9 nua e é substancialmente menor do que a CPU com um dissipador de calor e ventoinha! - -| Dispositivo | Tamanho | -| ------------------------------- | --------------------- | -| Freescale Kinetis KL03 | 1,6mm x 2mm x 1mm | -| Terminal Wio | 72mm x 57mm x 12mm | -| Intel i9 CPU, dissipador e ventoinha | 136mm x 145mm x 103mm | - -### Frameworks e sistemas operativos - -Devido à sua baixa velocidade e tamanho de memória, os microcontroladores não executam um sistema operativo (SO) no sentido tradicional de um desktop. O sistema operativo que faz o seu computador funcionar (Windows, Linux ou macOS) precisa de muita memória e poder de processamento para executar tarefas que são completamente desnecessárias para um microcontrolador. Lembre-se de que os microcontroladores são geralmente programados para realizar uma ou mais tarefas muito específicas, ao contrário de um computador de uso geral como um PC ou Mac, que precisa de suportar uma interface de utilizador, reproduzir música ou filmes, fornecer ferramentas para escrever documentos ou código, jogar ou navegar na Internet. - -Para programar um microcontrolador sem um SO, é necessário algum tipo de ferramenta que permita construir o seu código de forma que o microcontrolador o consiga executar, utilizando APIs que possam comunicar com quaisquer periféricos. Cada microcontrolador é diferente, por isso os fabricantes normalmente suportam frameworks padrão que permitem seguir uma 'receita' padrão para construir o seu código e executá-lo em qualquer microcontrolador que suporte esse framework. - -Pode programar microcontroladores usando um SO - frequentemente referido como um sistema operativo em tempo real (RTOS), pois estes são projetados para lidar com o envio de dados para e a partir de periféricos em tempo real. Estes sistemas operativos são muito leves e oferecem funcionalidades como: - -* Multithreading, permitindo que o seu código execute mais de um bloco de código ao mesmo tempo, seja em múltiplos núcleos ou alternando num único núcleo. -* Networking para permitir comunicação segura pela Internet. -* Componentes de interface gráfica (GUI) para construir interfaces de utilizador (UI) em dispositivos com ecrãs. - -✅ Leia sobre alguns RTOS diferentes: [Azure RTOS](https://azure.microsoft.com/services/rtos/?WT.mc_id=academic-17441-jabenn), [FreeRTOS](https://www.freertos.org), [Zephyr](https://www.zephyrproject.org) - -#### Arduino - -![O logótipo do Arduino](../../../../../images/arduino-logo.svg) - -[Arduino](https://www.arduino.cc) é provavelmente o framework de microcontroladores mais popular, especialmente entre estudantes, entusiastas e makers. Arduino é uma plataforma de eletrónica open source que combina software e hardware. Pode comprar placas compatíveis com Arduino da própria Arduino ou de outros fabricantes e, em seguida, programá-las usando o framework Arduino. - -As placas Arduino são programadas em C ou C++. Usar C/C++ permite que o seu código seja compilado de forma muito compacta e execute rapidamente, algo necessário num dispositivo com recursos limitados, como um microcontrolador. O núcleo de uma aplicação Arduino é chamado de sketch e é um código em C/C++ com 2 funções - `setup` e `loop`. Quando a placa é ligada, o código do framework Arduino executa a função `setup` uma vez e, em seguida, executa a função `loop` repetidamente, continuamente, até que a energia seja desligada. - -Escreveria o seu código de configuração na função `setup`, como conectar-se ao WiFi e serviços na cloud ou inicializar pinos para entrada e saída. O seu código de processamento ficaria na função `loop`, como ler de um sensor e enviar o valor para a cloud. Normalmente, incluiria um atraso em cada loop; por exemplo, se quiser que os dados do sensor sejam enviados apenas a cada 10 segundos, adicionaria um atraso de 10 segundos no final do loop para que o microcontrolador possa entrar em modo de suspensão, economizando energia, e depois executar o loop novamente quando necessário, 10 segundos depois. - -![Um sketch Arduino executando setup primeiro, depois executando loop repetidamente](../../../../../translated_images/pt-PT/arduino-sketch.79590cb837ff7a7c6a68d1afda6cab83fd53d3bb1bd9a8bf2eaf8d693a4d3ea6.png) - -✅ Esta arquitetura de programa é conhecida como *event loop* ou *message loop*. Muitas aplicações utilizam este modelo nos bastidores e é o padrão para a maioria das aplicações desktop que executam em SOs como Windows, macOS ou Linux. O `loop` escuta mensagens de componentes da interface de utilizador, como botões, ou dispositivos como o teclado, e responde a elas. Pode ler mais neste [artigo sobre o event loop](https://wikipedia.org/wiki/Event_loop). - -O Arduino fornece bibliotecas padrão para interagir com microcontroladores e os pinos de I/O, com diferentes implementações nos bastidores para funcionar em diferentes microcontroladores. Por exemplo, a função [`delay`](https://www.arduino.cc/reference/en/language/functions/time/delay/) pausa o programa por um período de tempo especificado, e a função [`digitalRead`](https://www.arduino.cc/reference/en/language/functions/digital-io/digitalread/) lê um valor `HIGH` ou `LOW` do pino especificado, independentemente da placa em que o código está a ser executado. Estas bibliotecas padrão significam que o código Arduino escrito para uma placa pode ser recompilado para qualquer outra placa Arduino e funcionará, assumindo que os pinos são os mesmos e as placas suportam os mesmos recursos. - -Existe um grande ecossistema de bibliotecas Arduino de terceiros que permitem adicionar funcionalidades extras aos seus projetos Arduino, como usar sensores e atuadores ou conectar-se a serviços IoT na cloud. - -##### Tarefa - -Investigue o terminal Wio. - -Se estiver a usar um terminal Wio para estas lições, releia o código que escreveu na última lição. Encontre as funções `setup` e `loop`. Monitorize a saída serial para verificar que a função `loop` está a ser chamada repetidamente. Experimente adicionar código à função `setup` para escrever na porta serial e observe que este código é chamado apenas uma vez cada vez que reinicia o dispositivo. Experimente reiniciar o dispositivo com o interruptor de energia na lateral para verificar que este código é chamado sempre que o dispositivo é reiniciado. - -## Exploração mais profunda de computadores de placa única - -Na última lição, introduzimos os computadores de placa única. Vamos agora explorá-los mais a fundo. - -### Raspberry Pi - -![O logótipo do Raspberry Pi](../../../../../translated_images/pt-PT/raspberry-pi-logo.4efaa16605cee054.webp) - -A [Raspberry Pi Foundation](https://www.raspberrypi.org) é uma instituição de caridade do Reino Unido fundada em 2009 para promover o estudo da ciência da computação, especialmente ao nível escolar. Como parte desta missão, desenvolveram um computador de placa única, chamado Raspberry Pi. Atualmente, os Raspberry Pis estão disponíveis em 3 variantes - uma versão de tamanho completo, o menor Pi Zero, e um módulo de computação que pode ser integrado no seu dispositivo IoT final. - -![Um Raspberry Pi 4](../../../../../translated_images/pt-PT/raspberry-pi-4.fd4590d308c3d456.webp) - -A iteração mais recente do Raspberry Pi de tamanho completo é o Raspberry Pi 4B. Este possui uma CPU quad-core (4 núcleos) a 1,5GHz, 2, 4 ou 8GB de RAM, ethernet gigabit, WiFi, 2 portas HDMI que suportam ecrãs 4k, uma porta de saída de áudio e vídeo composto, portas USB (2 USB 2.0, 2 USB 3.0), 40 pinos GPIO, um conector de câmara para um módulo de câmara Raspberry Pi e um slot para cartão SD. Tudo isto numa placa de 88mm x 58mm x 19,5mm, alimentada por uma fonte de alimentação USB-C de 3A. Estes começam a partir de US$35, muito mais baratos do que um PC ou Mac. - -> 💁 Existe também um Pi400, um computador tudo-em-um com um Pi4 integrado num teclado. - -![Um Raspberry Pi Zero](../../../../../translated_images/pt-PT/raspberry-pi-zero.f7a4133e1e7d54bb.webp) - -O Pi Zero é muito menor e consome menos energia. Ele possui uma CPU de núcleo único a 1GHz, 512MB de RAM, WiFi (no modelo Zero W), uma única porta HDMI, uma porta micro-USB, 40 pinos GPIO, um conector de câmara para um módulo de câmara Raspberry Pi e um slot para cartão SD. Mede 65mm x 30mm x 5mm e consome muito pouca energia. O Zero custa US$5, enquanto a versão W com WiFi custa US$10. - -> 🎓 As CPUs de ambos são processadores ARM, ao contrário dos processadores Intel/AMD x86 ou x64 encontrados na maioria dos PCs e Macs. Estes são semelhantes às CPUs encontradas em alguns microcontroladores, bem como na maioria dos telemóveis, no Microsoft Surface X e nos novos Macs com Apple Silicon. - -Todas as variantes do Raspberry Pi executam uma versão do Debian Linux chamada Raspberry Pi OS. Esta está disponível numa versão lite, sem ambiente de trabalho, perfeita para projetos 'headless' onde não precisa de um ecrã, ou numa versão completa com um ambiente de trabalho completo, incluindo navegador web, aplicações de escritório, ferramentas de programação e jogos. Como o SO é uma versão do Debian Linux, pode instalar qualquer aplicação ou ferramenta que funcione no Debian e seja construída para o processador ARM dentro do Pi. - -#### Tarefa - -Investigue o Raspberry Pi. - -Se estiver a usar um Raspberry Pi para estas lições, leia sobre os diferentes componentes de hardware na placa. - -* Pode encontrar detalhes sobre os processadores usados na [página de documentação de hardware do Raspberry Pi](https://www.raspberrypi.org/documentation/hardware/raspberrypi/). Leia sobre o processador usado no Pi que está a usar. -* Localize os pinos GPIO. Leia mais sobre eles na [documentação GPIO do Raspberry Pi](https://www.raspberrypi.org/documentation/hardware/raspberrypi/gpio/README.md). Use o [guia de utilização dos pinos GPIO](https://www.raspberrypi.org/documentation/usage/gpio/README.md) para identificar os diferentes pinos no seu Pi. - -### Programar computadores de placa única - -Os computadores de placa única são computadores completos, que executam um SO completo. Isto significa que existe uma ampla gama de linguagens de programação, frameworks e ferramentas que pode usar para programá-los, ao contrário dos microcontroladores, que dependem do suporte da placa em frameworks como o Arduino. A maioria das linguagens de programação possui bibliotecas que podem aceder aos pinos GPIO para enviar e receber dados de sensores e atuadores. - -✅ Que linguagens de programação conhece? São suportadas no Linux? - -A linguagem de programação mais comum para construir aplicações IoT num Raspberry Pi é o Python. Existe um enorme ecossistema de hardware projetado para o Pi, e quase todos incluem o código necessário para utilizá-los como bibliotecas Python. Alguns destes ecossistemas são baseados em 'hats' - assim chamados porque se encaixam no topo do Pi como um chapéu e conectam-se através de um grande conector aos 40 pinos GPIO. Estes hats fornecem capacidades adicionais, como ecrãs, sensores, carros telecomandados ou adaptadores para ligar sensores com cabos padronizados. -### Utilização de computadores de placa única em implementações profissionais de IoT - -Os computadores de placa única são utilizados em implementações profissionais de IoT, não apenas como kits de desenvolvimento. Eles podem ser uma forma poderosa de controlar hardware e executar tarefas complexas, como a execução de modelos de machine learning. Por exemplo, existe o [módulo de computação Raspberry Pi 4](https://www.raspberrypi.org/blog/raspberry-pi-compute-module-4/) que oferece toda a potência de um Raspberry Pi 4, mas num formato compacto e mais económico, sem a maioria das portas, projetado para ser integrado em hardware personalizado. - ---- - -## 🚀 Desafio - -O desafio da última lição foi listar o maior número possível de dispositivos IoT que existem na sua casa, escola ou local de trabalho. Para cada dispositivo dessa lista, acha que são baseados em microcontroladores, computadores de placa única ou até numa combinação de ambos? - -## Questionário pós-aula - -[Questionário pós-aula](https://black-meadow-040d15503.1.azurestaticapps.net/quiz/4) - -## Revisão e Estudo Individual - -* Leia o [guia de introdução ao Arduino](https://www.arduino.cc/en/Guide/Introduction) para compreender melhor a plataforma Arduino. -* Leia a [introdução ao Raspberry Pi 4](https://www.raspberrypi.org/products/raspberry-pi-4-model-b/) para aprender mais sobre os Raspberry Pis. -* Saiba mais sobre alguns dos conceitos e siglas no artigo [O que são CPUs, MPUs, MCUs e GPUs no Electrical Engineering Journal](https://www.eejournal.com/article/what-the-faq-are-cpus-mpus-mcus-and-gpus/). - -✅ Utilize estes guias, juntamente com os custos apresentados nos links do [guia de hardware](../../../hardware.md), para decidir qual plataforma de hardware deseja utilizar ou se prefere usar um dispositivo virtual. - -## Tarefa - -[Compare e contraste microcontroladores e computadores de placa única](assignment.md) - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, é importante notar que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes da utilização desta tradução. \ No newline at end of file diff --git a/translations/pt/1-getting-started/lessons/2-deeper-dive/assignment.md b/translations/pt/1-getting-started/lessons/2-deeper-dive/assignment.md deleted file mode 100644 index 1748642d6..000000000 --- a/translations/pt/1-getting-started/lessons/2-deeper-dive/assignment.md +++ /dev/null @@ -1,24 +0,0 @@ - -# Comparar e contrastar microcontroladores e computadores de placa única - -## Instruções - -Esta lição abordou microcontroladores e computadores de placa única. Crie uma tabela comparando e contrastando-os, e indique pelo menos 2 razões para usar um microcontrolador em vez de um computador de placa única, e pelo menos 2 razões para usar um computador de placa única em vez de um microcontrolador. - -## Rubrica - -| Critérios | Exemplar | Adequado | Precisa de Melhorias | -| --------- | -------- | -------- | -------------------- | -| Criar uma tabela comparando microcontroladores a computadores de placa única | Criou uma lista com vários itens comparando e contrastando corretamente | Criou uma lista com apenas alguns itens | Foi capaz de apresentar apenas um item, ou nenhum item para comparar e contrastar | -| Razões para usar um em vez do outro | Foi capaz de fornecer 2 ou mais razões para microcontroladores, e 2 ou mais para computadores de placa única | Foi capaz de fornecer apenas 1-2 razões para um microcontrolador, e 1-2 razões para um computador de placa única | Não foi capaz de fornecer 1 ou mais razões para um microcontrolador ou para um computador de placa única | - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, esteja ciente de que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes do uso desta tradução. \ No newline at end of file diff --git a/translations/pt/1-getting-started/lessons/3-sensors-and-actuators/README.md b/translations/pt/1-getting-started/lessons/3-sensors-and-actuators/README.md deleted file mode 100644 index 6a659ce96..000000000 --- a/translations/pt/1-getting-started/lessons/3-sensors-and-actuators/README.md +++ /dev/null @@ -1,228 +0,0 @@ - -# Interagir com o mundo físico com sensores e atuadores - -![Uma visão geral ilustrada desta lição](../../../../../translated_images/pt-PT/lesson-3.cc3b7b4cd646de598698cce043c0393fd62ef42bac2eaf60e61272cd844250f4.jpg) - -> Ilustração por [Nitya Narasimhan](https://github.com/nitya). Clique na imagem para uma versão maior. - -Esta lição foi ensinada como parte da série [Hello IoT](https://youtube.com/playlist?list=PLmsFUfdnGr3xRts0TIwyaHyQuHaNQcb6-) do [Microsoft Reactor](https://developer.microsoft.com/reactor/?WT.mc_id=academic-17441-jabenn). A lição foi apresentada em 2 vídeos - uma aula de 1 hora e uma sessão de perguntas e respostas de 1 hora, explorando mais profundamente partes da lição e respondendo a dúvidas. - -[![Lição 3: Interagir com o Mundo Físico com Sensores e Atuadores](https://img.youtube.com/vi/Lqalu1v6aF4/0.jpg)](https://youtu.be/Lqalu1v6aF4) - -[![Lição 3: Interagir com o Mundo Físico com Sensores e Atuadores - Sessão de perguntas e respostas](https://img.youtube.com/vi/qR3ekcMlLWA/0.jpg)](https://youtu.be/qR3ekcMlLWA) - -> 🎥 Clique nas imagens acima para assistir aos vídeos - -## Questionário pré-aula - -[Questionário pré-aula](https://black-meadow-040d15503.1.azurestaticapps.net/quiz/5) - -## Introdução - -Esta lição apresenta dois conceitos importantes para o seu dispositivo IoT - sensores e atuadores. Você também terá a oportunidade de trabalhar com ambos, adicionando um sensor de luz ao seu projeto IoT e, em seguida, um LED controlado pelos níveis de luz, criando efetivamente uma luz noturna. - -Nesta lição, abordaremos: - -* [O que são sensores?](../../../../../1-getting-started/lessons/3-sensors-and-actuators) -* [Usar um sensor](../../../../../1-getting-started/lessons/3-sensors-and-actuators) -* [Tipos de sensores](../../../../../1-getting-started/lessons/3-sensors-and-actuators) -* [O que são atuadores?](../../../../../1-getting-started/lessons/3-sensors-and-actuators) -* [Usar um atuador](../../../../../1-getting-started/lessons/3-sensors-and-actuators) -* [Tipos de atuadores](../../../../../1-getting-started/lessons/3-sensors-and-actuators) - -## O que são sensores? - -Sensores são dispositivos de hardware que percebem o mundo físico - ou seja, medem uma ou mais propriedades ao seu redor e enviam essas informações para um dispositivo IoT. Os sensores abrangem uma ampla gama de dispositivos, pois há muitas coisas que podem ser medidas, desde propriedades naturais como a temperatura do ar até interações físicas como movimento. - -Alguns sensores comuns incluem: - -* Sensores de temperatura - medem a temperatura do ar ou do objeto em que estão imersos. Para entusiastas e desenvolvedores, esses sensores geralmente combinam pressão atmosférica e umidade em um único dispositivo. -* Botões - detectam quando são pressionados. -* Sensores de luz - detectam níveis de luz e podem ser específicos para cores, luz UV, luz IR ou luz visível geral. -* Câmeras - capturam uma representação visual do mundo ao tirar uma foto ou transmitir vídeo. -* Acelerômetros - detectam movimento em várias direções. -* Microfones - captam som, seja níveis gerais de som ou som direcional. - -✅ Faça uma pesquisa. Quais sensores o seu telemóvel possui? - -Todos os sensores têm algo em comum - eles convertem o que percebem em um sinal elétrico que pode ser interpretado por um dispositivo IoT. A forma como esse sinal elétrico é interpretado depende do sensor, bem como do protocolo de comunicação usado para se comunicar com o dispositivo IoT. - -## Usar um sensor - -Siga o guia relevante abaixo para adicionar um sensor ao seu dispositivo IoT: - -* [Arduino - Wio Terminal](wio-terminal-sensor.md) -* [Computador de placa única - Raspberry Pi](pi-sensor.md) -* [Computador de placa única - Dispositivo virtual](virtual-device-sensor.md) - -## Tipos de sensores - -Os sensores podem ser analógicos ou digitais. - -### Sensores analógicos - -Alguns dos sensores mais básicos são analógicos. Esses sensores recebem uma tensão do dispositivo IoT, os componentes do sensor ajustam essa tensão e a tensão retornada pelo sensor é medida para fornecer o valor do sensor. - -> 🎓 Tensão é uma medida de quanta força existe para mover eletricidade de um lugar para outro, como do terminal positivo de uma bateria para o terminal negativo. Por exemplo, uma bateria AA padrão tem 1,5V (V é o símbolo para volts) e pode empurrar eletricidade com a força de 1,5V do seu terminal positivo para o terminal negativo. Diferentes componentes elétricos requerem diferentes tensões para funcionar, por exemplo, um LED pode acender com entre 2-3V, mas uma lâmpada incandescente de 100W precisaria de 240V. Você pode ler mais sobre tensão na [página sobre tensão na Wikipedia](https://wikipedia.org/wiki/Voltage). - -Um exemplo disso é um potenciômetro. Este é um botão que você pode girar entre duas posições, e o sensor mede a rotação. - -![Um potenciômetro ajustado para um ponto médio sendo enviado 5 volts e retornando 3,8 volts](../../../../../translated_images/pt-PT/potentiometer.35a348b9ce22f6ec.webp) - -O dispositivo IoT enviará um sinal elétrico ao potenciômetro com uma tensão, como 5 volts (5V). À medida que o potenciômetro é ajustado, ele altera a tensão que sai do outro lado. Imagine que você tem um potenciômetro rotulado como um botão que vai de 0 a [11](https://wikipedia.org/wiki/Up_to_eleven), como um botão de volume em um amplificador. Quando o potenciômetro está na posição totalmente desligada (0), então 0V (0 volts) sairão. Quando está na posição totalmente ligada (11), 5V (5 volts) sairão. - -> 🎓 Esta é uma simplificação, e você pode ler mais sobre potenciômetros e resistores variáveis na [página sobre potenciômetros na Wikipedia](https://wikipedia.org/wiki/Potentiometer). - -A tensão que sai do sensor é então lida pelo dispositivo IoT, e o dispositivo pode responder a ela. Dependendo do sensor, essa tensão pode ser um valor arbitrário ou pode corresponder a uma unidade padrão. Por exemplo, um sensor de temperatura analógico baseado em um [termistor](https://wikipedia.org/wiki/Thermistor) altera sua resistência dependendo da temperatura. A tensão de saída pode então ser convertida em uma temperatura em Kelvin, e correspondentemente em °C ou °F, por cálculos no código. - -✅ O que você acha que acontece se o sensor retornar uma tensão maior do que foi enviada (por exemplo, vindo de uma fonte de alimentação externa)? ⛔️ NÃO teste isso. - -#### Conversão de analógico para digital - -Dispositivos IoT são digitais - eles não conseguem trabalhar com valores analógicos, apenas com 0s e 1s. Isso significa que os valores de sensores analógicos precisam ser convertidos para um sinal digital antes de serem processados. Muitos dispositivos IoT possuem conversores analógico-digital (ADCs) para converter entradas analógicas em representações digitais de seus valores. Sensores também podem funcionar com ADCs através de uma placa de conexão. Por exemplo, no ecossistema Seeed Grove com um Raspberry Pi, sensores analógicos conectam-se a portas específicas em um 'hat' que fica no Pi conectado aos pinos GPIO do Pi, e este hat possui um ADC para converter a tensão em um sinal digital que pode ser enviado pelos pinos GPIO do Pi. - -Imagine que você tem um sensor de luz analógico conectado a um dispositivo IoT que usa 3,3V e está retornando um valor de 1V. Este 1V não significa nada no mundo digital, então precisa ser convertido. A tensão será convertida para um valor analógico usando uma escala dependendo do dispositivo e sensor. Um exemplo é o sensor de luz Seeed Grove, que gera valores de 0 a 1.023. Para este sensor funcionando a 3,3V, uma saída de 1V seria um valor de 300. Um dispositivo IoT não consegue lidar com 300 como um valor analógico, então o valor seria convertido para `0000000100101100`, a representação binária de 300 pelo hat Grove. Isso seria então processado pelo dispositivo IoT. - -✅ Se você não conhece binário, faça uma pequena pesquisa para aprender como os números são representados por 0s e 1s. A [lição introdutória sobre binário do BBC Bitesize](https://www.bbc.co.uk/bitesize/guides/zwsbwmn/revision/1) é um ótimo lugar para começar. - -Do ponto de vista da programação, tudo isso geralmente é tratado por bibliotecas que acompanham os sensores, então você não precisa se preocupar com essa conversão. Para o sensor de luz Grove, você usaria a biblioteca Python e chamaria a propriedade `light`, ou usaria a biblioteca Arduino e chamaria `analogRead` para obter um valor de 300. - -### Sensores digitais - -Sensores digitais, como sensores analógicos, detectam o mundo ao seu redor usando mudanças na tensão elétrica. A diferença é que eles geram um sinal digital, seja medindo apenas dois estados ou usando um ADC embutido. Sensores digitais estão se tornando cada vez mais comuns para evitar a necessidade de usar um ADC em uma placa de conexão ou no próprio dispositivo IoT. - -O sensor digital mais simples é um botão ou interruptor. Este é um sensor com dois estados, ligado ou desligado. - -![Um botão é enviado 5 volts. Quando não pressionado, retorna 0 volts; quando pressionado, retorna 5 volts](../../../../../translated_images/pt-PT/button.eadb560b77ac45e56f523d9d8876e40444f63b419e33eb820082d461fa79490b.png) - -Pinos em dispositivos IoT, como pinos GPIO, podem medir este sinal diretamente como 0 ou 1. Se a tensão enviada for igual à tensão retornada, o valor lido é 1; caso contrário, o valor lido é 0. Não há necessidade de converter o sinal, ele só pode ser 1 ou 0. - -> 💁 As tensões nunca são exatas, especialmente porque os componentes em um sensor terão alguma resistência, então geralmente há uma tolerância. Por exemplo, os pinos GPIO de um Raspberry Pi funcionam com 3,3V e leem um sinal de retorno acima de 1,8V como 1, abaixo de 1,8V como 0. - -* 3,3V entram no botão. O botão está desligado, então 0V saem, dando um valor de 0. -* 3,3V entram no botão. O botão está ligado, então 3,3V saem, dando um valor de 1. - -Sensores digitais mais avançados leem valores analógicos e os convertem usando ADCs embutidos para sinais digitais. Por exemplo, um sensor de temperatura digital ainda usará um termopar da mesma forma que um sensor analógico e ainda medirá a mudança na tensão causada pela resistência do termopar na temperatura atual. Em vez de retornar um valor analógico e depender do dispositivo ou da placa de conexão para converter em um sinal digital, um ADC embutido no sensor converterá o valor e o enviará como uma série de 0s e 1s para o dispositivo IoT. Esses 0s e 1s são enviados da mesma forma que o sinal digital de um botão, com 1 sendo tensão total e 0 sendo 0V. - -![Um sensor de temperatura digital convertendo uma leitura analógica em dados binários com 0 como 0 volts e 1 como 5 volts antes de enviá-los para um dispositivo IoT](../../../../../translated_images/pt-PT/temperature-as-digital.85004491b977bae1.webp) - -O envio de dados digitais permite que os sensores se tornem mais complexos e enviem dados mais detalhados, até mesmo dados criptografados para sensores seguros. Um exemplo é uma câmera. Este é um sensor que captura uma imagem e a envia como dados digitais contendo essa imagem, geralmente em um formato comprimido como JPEG, para ser lida pelo dispositivo IoT. Ela pode até transmitir vídeo capturando imagens e enviando ou o quadro completo imagem por imagem ou um fluxo de vídeo comprimido. - -## O que são atuadores? - -Atuadores são o oposto de sensores - eles convertem um sinal elétrico do seu dispositivo IoT em uma interação com o mundo físico, como emitir luz ou som, ou mover um motor. - -Alguns atuadores comuns incluem: - -* LED - emitem luz quando ligados. -* Altifalante - emitem som com base no sinal enviado a eles, desde um simples zumbido até um altifalante que pode reproduzir música. -* Motor de passo - convertem um sinal em uma quantidade definida de rotação, como girar um botão 90°. -* Relé - são interruptores que podem ser ligados ou desligados por um sinal elétrico. Permitem que uma pequena tensão de um dispositivo IoT ligue tensões maiores. -* Ecrãs - são atuadores mais complexos e mostram informações em um display de vários segmentos. Os ecrãs variam de simples displays LED a monitores de vídeo de alta resolução. - -✅ Faça uma pesquisa. Quais atuadores o seu telemóvel possui? - -## Usar um atuador - -Siga o guia relevante abaixo para adicionar um atuador ao seu dispositivo IoT, controlado pelo sensor, para construir uma luz noturna IoT. Ele reunirá os níveis de luz do sensor de luz e usará um atuador na forma de um LED para emitir luz quando o nível de luz detectado for muito baixo. - -![Um diagrama de fluxo da tarefa mostrando os níveis de luz sendo lidos e verificados, e o LED sendo controlado](../../../../../translated_images/pt-PT/assignment-1-flow.7552a51acb1a5ec858dca6e855cdbb44206434006df8ba3799a25afcdab1665d.png) - -* [Arduino - Wio Terminal](wio-terminal-actuator.md) -* [Computador de placa única - Raspberry Pi](pi-actuator.md) -* [Computador de placa única - Dispositivo virtual](virtual-device-actuator.md) - -## Tipos de atuadores - -Assim como os sensores, os atuadores podem ser analógicos ou digitais. - -### Atuadores analógicos - -Atuadores analógicos recebem um sinal analógico e o convertem em algum tipo de interação, onde a interação muda com base na tensão fornecida. - -Um exemplo é uma luz regulável, como as que você pode ter em sua casa. A quantidade de tensão fornecida à luz determina o quão brilhante ela será. -![Uma luz regulada com baixa voltagem e mais brilhante com alta voltagem](../../../../../translated_images/pt-PT/dimmable-light.9ceffeb195dec1a849da718b2d71b32c35171ff7dfea9c07bbf82646a67acf6b.png) - -Tal como acontece com os sensores, o dispositivo IoT funciona com sinais digitais, não analógicos. Isso significa que, para enviar um sinal analógico, o dispositivo IoT precisa de um conversor digital para analógico (DAC), seja diretamente no dispositivo IoT ou numa placa de conexão. Este conversor transforma os 0s e 1s do dispositivo IoT numa voltagem analógica que o atuador pode utilizar. - -✅ O que achas que acontece se o dispositivo IoT enviar uma voltagem maior do que o atuador consegue suportar? -⛔️ NÃO testes isto. - -#### Modulação por Largura de Pulso - -Outra opção para converter sinais digitais de um dispositivo IoT em sinais analógicos é a modulação por largura de pulso (PWM). Isto envolve o envio de vários pulsos digitais curtos que simulam um sinal analógico. - -Por exemplo, podes usar PWM para controlar a velocidade de um motor. - -Imagina que estás a controlar um motor com uma alimentação de 5V. Envias um pulso curto para o motor, alternando a voltagem para alta (5V) durante dois centésimos de segundo (0,02s). Nesse tempo, o motor pode girar um décimo de uma rotação, ou 36°. O sinal então pausa durante dois centésimos de segundo (0,02s), enviando um sinal baixo (0V). Cada ciclo de ligado e desligado dura 0,04s. O ciclo repete-se. - -![Modulação por largura de pulso na rotação de um motor a 150 RPM](../../../../../translated_images/pt-PT/pwm-motor-150rpm.83347ac04ca38482.webp) - -Isto significa que, em um segundo, tens 25 pulsos de 5V com duração de 0,02s que fazem o motor girar, seguidos por pausas de 0,02s com 0V, onde o motor não gira. Cada pulso faz o motor girar um décimo de uma rotação, o que significa que o motor completa 2,5 rotações por segundo. Usaste um sinal digital para girar o motor a 2,5 rotações por segundo, ou 150 [rotações por minuto](https://wikipedia.org/wiki/Revolutions_per_minute) (uma medida não padronizada de velocidade de rotação). - -```output -25 pulses per second x 0.1 rotations per pulse = 2.5 rotations per second -2.5 rotations per second x 60 seconds in a minute = 150rpm -``` - -> 🎓 Quando um sinal PWM está ligado metade do tempo e desligado na outra metade, isso é chamado de [ciclo de trabalho de 50%](https://wikipedia.org/wiki/Duty_cycle). Os ciclos de trabalho são medidos como a percentagem de tempo em que o sinal está no estado ligado em comparação com o estado desligado. - -![Modulação por largura de pulso na rotação de um motor a 75 RPM](../../../../../translated_images/pt-PT/pwm-motor-75rpm.a5e4c939934b6e14.webp) - -Podes alterar a velocidade do motor ajustando o tamanho dos pulsos. Por exemplo, com o mesmo motor, podes manter o mesmo tempo de ciclo de 0,04s, reduzindo o pulso ligado para 0,01s e aumentando o pulso desligado para 0,03s. Tens o mesmo número de pulsos por segundo (25), mas cada pulso ligado tem metade da duração. Um pulso com metade da duração faz o motor girar um vigésimo de uma rotação, e com 25 pulsos por segundo, o motor completará 1,25 rotações por segundo ou 75rpm. Alterando a velocidade dos pulsos de um sinal digital, reduziste pela metade a velocidade de um motor analógico. - -```output -25 pulses per second x 0.05 rotations per pulse = 1.25 rotations per second -1.25 rotations per second x 60 seconds in a minute = 75rpm -``` - -✅ Como manterias a rotação do motor suave, especialmente em velocidades baixas? Usarias um pequeno número de pulsos longos com pausas longas ou muitos pulsos muito curtos com pausas muito curtas? - -> 💁 Alguns sensores também utilizam PWM para converter sinais analógicos em digitais. - -> 🎓 Podes ler mais sobre modulação por largura de pulso na [página de modulação por largura de pulso na Wikipedia](https://wikipedia.org/wiki/Pulse-width_modulation). - -### Atuadores digitais - -Atuadores digitais, tal como sensores digitais, têm dois estados controlados por uma voltagem alta ou baixa, ou possuem um DAC integrado que pode converter um sinal digital em analógico. - -Um atuador digital simples é um LED. Quando um dispositivo envia um sinal digital de 1, uma voltagem alta é enviada, acendendo o LED. Quando um sinal digital de 0 é enviado, a voltagem cai para 0V e o LED apaga-se. - -![Um LED está apagado a 0 volts e aceso a 5V](../../../../../translated_images/pt-PT/led.ec6d94f66676a174ad06d9fa9ea49c2ee89beb18b312d5c6476467c66375b07f.png) - -✅ Que outros atuadores simples de 2 estados consegues imaginar? Um exemplo é um solenóide, que é um eletroímã que pode ser ativado para realizar ações como mover um trinco de porta, trancando ou destrancando-a. - -Atuadores digitais mais avançados, como ecrãs, requerem que os dados digitais sejam enviados em formatos específicos. Normalmente, vêm com bibliotecas que facilitam o envio dos dados corretos para controlá-los. - ---- - -## 🚀 Desafio - -O desafio nas últimas duas lições foi listar o maior número possível de dispositivos IoT que tens em casa, na escola ou no local de trabalho e decidir se são construídos com microcontroladores ou computadores de placa única, ou até mesmo uma mistura de ambos. - -Para cada dispositivo listado, que sensores e atuadores estão conectados a eles? Qual é o propósito de cada sensor e atuador conectado a esses dispositivos? - -## Questionário pós-aula - -[Questionário pós-aula](https://black-meadow-040d15503.1.azurestaticapps.net/quiz/6) - -## Revisão e Autoestudo - -* Lê sobre eletricidade e circuitos no [ThingLearn](http://thinglearn.jenlooper.com/curriculum/). -* Lê sobre os diferentes tipos de sensores de temperatura no [guia de sensores de temperatura da Seeed Studios](https://www.seeedstudio.com/blog/2019/10/14/temperature-sensors-for-arduino-projects/) -* Lê sobre LEDs na [página de LEDs na Wikipedia](https://wikipedia.org/wiki/Light-emitting_diode) - -## Tarefa - -[Investigar sensores e atuadores](assignment.md) - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, é importante notar que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes da utilização desta tradução. \ No newline at end of file diff --git a/translations/pt/1-getting-started/lessons/3-sensors-and-actuators/assignment.md b/translations/pt/1-getting-started/lessons/3-sensors-and-actuators/assignment.md deleted file mode 100644 index 4aca19797..000000000 --- a/translations/pt/1-getting-started/lessons/3-sensors-and-actuators/assignment.md +++ /dev/null @@ -1,29 +0,0 @@ - -# Investigar sensores e atuadores - -## Instruções - -Esta lição abordou sensores e atuadores. Investigue e descreva um sensor e um atuador que podem ser usados com um kit de desenvolvimento IoT, incluindo: - -* O que faz -* Os componentes eletrónicos/hardware utilizados internamente -* Se é analógico ou digital -* Quais são as unidades e o intervalo de entradas ou medições - -## Rubrica - -| Critérios | Exemplar | Adequado | Necessita Melhorias | -| --------- | --------- | -------- | ------------------- | -| Descrever um sensor | Descreveu um sensor incluindo detalhes para todas as 4 secções listadas acima. | Descreveu um sensor, mas conseguiu fornecer apenas 2-3 das secções acima. | Descreveu um sensor, mas conseguiu fornecer apenas 1 das secções acima. | -| Descrever um atuador | Descreveu um atuador incluindo detalhes para todas as 4 secções listadas acima. | Descreveu um atuador, mas conseguiu fornecer apenas 2-3 das secções acima. | Descreveu um atuador, mas conseguiu fornecer apenas 1 das secções acima. | - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, tenha em atenção que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes da utilização desta tradução. \ No newline at end of file diff --git a/translations/pt/1-getting-started/lessons/3-sensors-and-actuators/pi-actuator.md b/translations/pt/1-getting-started/lessons/3-sensors-and-actuators/pi-actuator.md deleted file mode 100644 index 32d1ff609..000000000 --- a/translations/pt/1-getting-started/lessons/3-sensors-and-actuators/pi-actuator.md +++ /dev/null @@ -1,128 +0,0 @@ - -# Construir uma luz de presença - Raspberry Pi - -Nesta parte da lição, vais adicionar um LED ao teu Raspberry Pi e utilizá-lo para criar uma luz de presença. - -## Hardware - -A luz de presença agora precisa de um atuador. - -O atuador é um **LED**, um [díodo emissor de luz](https://wikipedia.org/wiki/Diodo_emissor_de_luz) que emite luz quando a corrente passa por ele. Este é um atuador digital que tem dois estados: ligado e desligado. Enviar um valor de 1 liga o LED, e 0 desliga-o. O LED é um atuador externo Grove e precisa de ser ligado ao Grove Base hat no Raspberry Pi. - -A lógica da luz de presença em pseudo-código é: - -```output -Check the light level. -If the light is less than 300 - Turn the LED on -Otherwise - Turn the LED off -``` - -### Ligar o LED - -O LED Grove vem como um módulo com uma seleção de LEDs, permitindo-te escolher a cor. - -#### Tarefa - ligar o LED - -Liga o LED. - -![Um LED Grove](../../../../../translated_images/pt-PT/grove-led.6c853be93f473cf2c439cfc74bb1064732b22251a83cedf66e62f783f9cc1a79.png) - -1. Escolhe o teu LED favorito e insere as pernas nos dois orifícios do módulo LED. - - Os LEDs são díodos emissores de luz, e os díodos são dispositivos eletrónicos que só permitem a passagem de corrente num sentido. Isto significa que o LED precisa de ser ligado na orientação correta, caso contrário não funcionará. - - Uma das pernas do LED é o pino positivo, e a outra é o pino negativo. O LED não é perfeitamente redondo e é ligeiramente mais achatado de um lado. O lado ligeiramente mais achatado é o pino negativo. Quando ligares o LED ao módulo, certifica-te de que o pino do lado arredondado está ligado à tomada marcada com **+** na parte externa do módulo, e o lado achatado está ligado à tomada mais próxima do centro do módulo. - -1. O módulo LED tem um botão rotativo que permite controlar o brilho. Gira-o completamente para cima no início, rodando-o no sentido anti-horário até ao limite, utilizando uma pequena chave de fendas Phillips. - -1. Insere uma extremidade de um cabo Grove na tomada do módulo LED. Ele só encaixará de uma forma. - -1. Com o Raspberry Pi desligado, liga a outra extremidade do cabo Grove à tomada digital marcada como **D5** no Grove Base hat ligado ao Pi. Esta tomada é a segunda a contar da esquerda, na fila de tomadas ao lado dos pinos GPIO. - -![O LED Grove ligado à tomada D5](../../../../../translated_images/pt-PT/pi-led.97f1d474981dc35d1c7996c7b17de355d3d0a6bc9606d79fa5f89df933415122.png) - -## Programar a luz de presença - -A luz de presença pode agora ser programada utilizando o sensor de luz Grove e o LED Grove. - -### Tarefa - programar a luz de presença - -Programa a luz de presença. - -1. Liga o Pi e espera que ele inicie. - -1. Abre o projeto da luz de presença no VS Code que criaste na parte anterior desta tarefa, seja diretamente no Pi ou conectado usando a extensão Remote SSH. - -1. Adiciona o seguinte código ao ficheiro `app.py` para importar uma biblioteca necessária. Isto deve ser adicionado no topo, abaixo das outras linhas `import`. - - ```python - from grove.grove_led import GroveLed - ``` - - A instrução `from grove.grove_led import GroveLed` importa o `GroveLed` das bibliotecas Python Grove. Esta biblioteca contém código para interagir com um LED Grove. - -1. Adiciona o seguinte código após a declaração `light_sensor` para criar uma instância da classe que gere o LED: - - ```python - led = GroveLed(5) - ``` - - A linha `led = GroveLed(5)` cria uma instância da classe `GroveLed` conectada ao pino **D5** - o pino digital Grove ao qual o LED está ligado. - - > 💁 Todas as tomadas têm números de pinos únicos. Os pinos 0, 2, 4 e 6 são pinos analógicos, enquanto os pinos 5, 16, 18, 22, 24 e 26 são pinos digitais. - -1. Adiciona uma verificação dentro do `while` loop, antes do `time.sleep`, para verificar os níveis de luz e ligar ou desligar o LED: - - ```python - if light < 300: - led.on() - else: - led.off() - ``` - - Este código verifica o valor de `light`. Se for inferior a 300, chama o método `on` da classe `GroveLed`, que envia um valor digital de 1 para o LED, ligando-o. Se o valor de luz for maior ou igual a 300, chama o método `off`, enviando um valor digital de 0 para o LED, desligando-o. - - > 💁 Este código deve estar indentado ao mesmo nível que a linha `print('Light level:', light)` para estar dentro do loop while! - - > 💁 Ao enviar valores digitais para atuadores, um valor de 0 corresponde a 0V, e um valor de 1 corresponde à voltagem máxima do dispositivo. Para o Raspberry Pi com sensores e atuadores Grove, a voltagem de 1 é 3.3V. - -1. No Terminal do VS Code, executa o seguinte comando para correr a tua aplicação Python: - - ```sh - python3 app.py - ``` - - Os valores de luz serão exibidos na consola. - - ```output - pi@raspberrypi:~/nightlight $ python3 app.py - Light level: 634 - Light level: 634 - Light level: 634 - Light level: 230 - Light level: 104 - Light level: 290 - ``` - -1. Cobre e descobre o sensor de luz. Observa como o LED acende se o nível de luz for 300 ou menos, e apaga-se quando o nível de luz for superior a 300. - - > 💁 Se o LED não acender, certifica-te de que está ligado na orientação correta e que o botão rotativo está ajustado para o máximo. - -![O LED ligado ao Pi a acender e apagar conforme o nível de luz muda](../../../../../images/pi-running-assignment-1-1.gif) - -> 💁 Podes encontrar este código na pasta [code-actuator/pi](../../../../../1-getting-started/lessons/3-sensors-and-actuators/code-actuator/pi). - -😀 O teu programa de luz de presença foi um sucesso! - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, é importante notar que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes do uso desta tradução. \ No newline at end of file diff --git a/translations/pt/1-getting-started/lessons/3-sensors-and-actuators/pi-sensor.md b/translations/pt/1-getting-started/lessons/3-sensors-and-actuators/pi-sensor.md deleted file mode 100644 index 1109437cc..000000000 --- a/translations/pt/1-getting-started/lessons/3-sensors-and-actuators/pi-sensor.md +++ /dev/null @@ -1,108 +0,0 @@ - -# Construir uma luz de presença - Raspberry Pi - -Nesta parte da lição, vais adicionar um sensor de luz ao teu Raspberry Pi. - -## Hardware - -O sensor utilizado nesta lição é um **sensor de luz** que usa um [fotodíodo](https://wikipedia.org/wiki/Photodiode) para converter luz em um sinal elétrico. Este é um sensor analógico que envia um valor inteiro de 0 a 1.000, indicando uma quantidade relativa de luz que não corresponde a nenhuma unidade de medida padrão, como [lux](https://wikipedia.org/wiki/Lux). - -O sensor de luz é um sensor externo Grove e precisa ser conectado ao Grove Base hat no Raspberry Pi. - -### Conectar o sensor de luz - -O sensor de luz Grove, utilizado para detetar os níveis de luz, precisa ser conectado ao Raspberry Pi. - -#### Tarefa - conectar o sensor de luz - -Conecta o sensor de luz. - -![Um sensor de luz Grove](../../../../../translated_images/pt-PT/grove-light-sensor.b8127b7c434e632d6bcdb57587a14e9ef69a268a22df95d08628f62b8fa5505c.png) - -1. Insere uma extremidade de um cabo Grove na entrada do módulo do sensor de luz. Ele só encaixará de uma forma. - -1. Com o Raspberry Pi desligado, conecta a outra extremidade do cabo Grove à entrada analógica marcada como **A0** no Grove Base hat conectado ao Pi. Esta entrada é a segunda da direita, na fila de entradas ao lado dos pinos GPIO. - -![O sensor de luz Grove conectado à entrada A0](../../../../../translated_images/pt-PT/pi-light-sensor.66cc1e31fa48cd7d5f23400d4b2119aa41508275cb7c778053a7923b4e972d7e.png) - -## Programar o sensor de luz - -Agora o dispositivo pode ser programado utilizando o sensor de luz Grove. - -### Tarefa - programar o sensor de luz - -Programa o dispositivo. - -1. Liga o Raspberry Pi e espera que ele inicie. - -1. Abre o projeto da luz de presença no VS Code que criaste na parte anterior desta tarefa, seja diretamente no Pi ou conectado usando a extensão Remote SSH. - -1. Abre o ficheiro `app.py` e remove todo o código existente. - -1. Adiciona o seguinte código ao ficheiro `app.py` para importar algumas bibliotecas necessárias: - - ```python - import time - from grove.grove_light_sensor_v1_2 import GroveLightSensor - ``` - - A instrução `import time` importa o módulo `time`, que será utilizado mais tarde nesta tarefa. - - A instrução `from grove.grove_light_sensor_v1_2 import GroveLightSensor` importa o `GroveLightSensor` das bibliotecas Python do Grove. Esta biblioteca contém o código para interagir com um sensor de luz Grove e foi instalada globalmente durante a configuração do Pi. - -1. Adiciona o seguinte código após o código acima para criar uma instância da classe que gere o sensor de luz: - - ```python - light_sensor = GroveLightSensor(0) - ``` - - A linha `light_sensor = GroveLightSensor(0)` cria uma instância da classe `GroveLightSensor` conectando ao pino **A0** - o pino analógico Grove ao qual o sensor de luz está conectado. - -1. Adiciona um loop infinito após o código acima para consultar o valor do sensor de luz e imprimi-lo no terminal: - - ```python - while True: - light = light_sensor.light - print('Light level:', light) - ``` - - Isto irá ler o nível atual de luz numa escala de 0-1.023 utilizando a propriedade `light` da classe `GroveLightSensor`. Esta propriedade lê o valor analógico do pino. Este valor é então impresso no terminal. - -1. Adiciona uma pequena pausa de um segundo no final do `loop`, pois os níveis de luz não precisam ser verificados continuamente. Uma pausa reduz o consumo de energia do dispositivo. - - ```python - time.sleep(1) - ``` - -1. No Terminal do VS Code, executa o seguinte comando para correr a tua aplicação Python: - - ```sh - python3 app.py - ``` - - Os valores de luz serão exibidos no terminal. Cobre e descobre o sensor de luz, e os valores irão mudar: - - ```output - pi@raspberrypi:~/nightlight $ python3 app.py - Light level: 634 - Light level: 634 - Light level: 634 - Light level: 230 - Light level: 104 - Light level: 290 - ``` - -> 💁 Podes encontrar este código na pasta [code-sensor/pi](../../../../../1-getting-started/lessons/3-sensors-and-actuators/code-sensor/pi). - -😀 Adicionar um sensor ao teu programa de luz de presença foi um sucesso! - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, é importante notar que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes do uso desta tradução. \ No newline at end of file diff --git a/translations/pt/1-getting-started/lessons/3-sensors-and-actuators/virtual-device-actuator.md b/translations/pt/1-getting-started/lessons/3-sensors-and-actuators/virtual-device-actuator.md deleted file mode 100644 index ffcc55bb1..000000000 --- a/translations/pt/1-getting-started/lessons/3-sensors-and-actuators/virtual-device-actuator.md +++ /dev/null @@ -1,122 +0,0 @@ - -# Construir uma luz de presença - Hardware IoT Virtual - -Nesta parte da lição, irá adicionar um LED ao seu dispositivo IoT virtual e utilizá-lo para criar uma luz de presença. - -## Hardware Virtual - -A luz de presença necessita de um atuador, criado na aplicação CounterFit. - -O atuador é um **LED**. Num dispositivo IoT físico, seria um [díodo emissor de luz](https://wikipedia.org/wiki/Light-emitting_diode) que emite luz quando a corrente passa por ele. Este é um atuador digital que possui 2 estados: ligado e desligado. Enviar um valor de 1 liga o LED, e 0 desliga-o. - -A lógica da luz de presença em pseudo-código é: - -```output -Check the light level. -If the light is less than 300 - Turn the LED on -Otherwise - Turn the LED off -``` - -### Adicionar o atuador ao CounterFit - -Para utilizar um LED virtual, é necessário adicioná-lo à aplicação CounterFit. - -#### Tarefa - adicionar o atuador ao CounterFit - -Adicione o LED à aplicação CounterFit. - -1. Certifique-se de que a aplicação web CounterFit está a ser executada a partir da parte anterior deste exercício. Caso contrário, inicie-a e volte a adicionar o sensor de luz. - -1. Crie um LED: - - 1. Na caixa *Create actuator* no painel *Actuator*, abra o menu suspenso *Actuator type* e selecione *LED*. - - 1. Defina o *Pin* para *5*. - - 1. Selecione o botão **Add** para criar o LED no Pin 5. - - ![As definições do LED](../../../../../translated_images/pt-PT/counterfit-create-led.ba9db1c9b8c622a635d6dfae5cdc4e70c2b250635bd4f0601c6cf0bd22b7ba46.png) - - O LED será criado e aparecerá na lista de atuadores. - - ![O LED criado](../../../../../translated_images/pt-PT/counterfit-led.c0ab02de6d256ad84d9bad4d67a7faa709f0ea83e410cfe9b5561ef0cef30b1c.png) - - Depois de criar o LED, pode alterar a cor utilizando o seletor *Color*. Selecione o botão **Set** para alterar a cor após a sua escolha. - -### Programar a luz de presença - -Agora pode programar a luz de presença utilizando o sensor de luz e o LED do CounterFit. - -#### Tarefa - programar a luz de presença - -Programe a luz de presença. - -1. Abra o projeto da luz de presença no VS Code que criou na parte anterior deste exercício. Encerre e recrie o terminal para garantir que está a ser executado com o ambiente virtual, se necessário. - -1. Abra o ficheiro `app.py`. - -1. Adicione o seguinte código ao ficheiro `app.py` para importar uma biblioteca necessária. Isto deve ser adicionado no topo, abaixo das outras linhas de `import`. - - ```python - from counterfit_shims_grove.grove_led import GroveLed - ``` - - A instrução `from counterfit_shims_grove.grove_led import GroveLed` importa o `GroveLed` das bibliotecas Python CounterFit Grove shim. Esta biblioteca contém o código para interagir com um LED criado na aplicação CounterFit. - -1. Adicione o seguinte código após a declaração de `light_sensor` para criar uma instância da classe que gere o LED: - - ```python - led = GroveLed(5) - ``` - - A linha `led = GroveLed(5)` cria uma instância da classe `GroveLed` conectada ao pino **5** - o pino Grove do CounterFit ao qual o LED está ligado. - -1. Adicione uma verificação dentro do ciclo `while`, antes do `time.sleep`, para verificar os níveis de luz e ligar ou desligar o LED: - - ```python - if light < 300: - led.on() - else: - led.off() - ``` - - Este código verifica o valor de `light`. Se for inferior a 300, chama o método `on` da classe `GroveLed`, que envia um valor digital de 1 para o LED, ligando-o. Se o valor de luz for maior ou igual a 300, chama o método `off`, enviando um valor digital de 0 para o LED, desligando-o. - - > 💁 Este código deve estar indentado ao mesmo nível da linha `print('Light level:', light)` para estar dentro do ciclo while! - -1. No Terminal do VS Code, execute o seguinte comando para executar a sua aplicação Python: - - ```sh - python3 app.py - ``` - - Os valores de luz serão exibidos no console. - - ```output - (.venv) ➜ GroveTest python3 app.py - Light level: 143 - Light level: 244 - Light level: 246 - Light level: 253 - ``` - -1. Altere as definições de *Value* ou *Random* para variar o nível de luz acima e abaixo de 300. O LED irá ligar e desligar. - -![O LED na aplicação CounterFit a ligar e desligar conforme o nível de luz muda](../../../../../images/virtual-device-running-assignment-1-1.gif) - -> 💁 Pode encontrar este código na pasta [code-actuator/virtual-device](../../../../../1-getting-started/lessons/3-sensors-and-actuators/code-actuator/virtual-device). - -😀 O seu programa de luz de presença foi um sucesso! - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, esteja ciente de que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes do uso desta tradução. \ No newline at end of file diff --git a/translations/pt/1-getting-started/lessons/3-sensors-and-actuators/virtual-device-sensor.md b/translations/pt/1-getting-started/lessons/3-sensors-and-actuators/virtual-device-sensor.md deleted file mode 100644 index d33221987..000000000 --- a/translations/pt/1-getting-started/lessons/3-sensors-and-actuators/virtual-device-sensor.md +++ /dev/null @@ -1,122 +0,0 @@ - -# Construir uma luz de presença - Hardware IoT Virtual - -Nesta parte da lição, irá adicionar um sensor de luz ao seu dispositivo IoT virtual. - -## Hardware Virtual - -A luz de presença necessita de um sensor, criado na aplicação CounterFit. - -O sensor é um **sensor de luz**. Num dispositivo IoT físico, seria um [fotodíodo](https://wikipedia.org/wiki/Photodiode) que converte luz em um sinal elétrico. Sensores de luz são sensores analógicos que enviam um valor inteiro indicando uma quantidade relativa de luz, que não corresponde a nenhuma unidade de medida padrão, como [lux](https://wikipedia.org/wiki/Lux). - -### Adicionar os sensores ao CounterFit - -Para usar um sensor de luz virtual, é necessário adicioná-lo à aplicação CounterFit. - -#### Tarefa - adicionar os sensores ao CounterFit - -Adicione o sensor de luz à aplicação CounterFit. - -1. Certifique-se de que a aplicação web CounterFit está em execução a partir da parte anterior deste exercício. Caso contrário, inicie-a. - -1. Crie um sensor de luz: - - 1. Na caixa *Create sensor* no painel *Sensors*, abra o menu suspenso *Sensor type* e selecione *Light*. - - 1. Deixe a opção *Units* definida como *NoUnits*. - - 1. Certifique-se de que o *Pin* está definido como *0*. - - 1. Selecione o botão **Add** para criar o sensor de luz no Pin 0. - - ![As definições do sensor de luz](../../../../../translated_images/pt-PT/counterfit-create-light-sensor.9f36a5e0d4458d8d554d54b34d2c806d56093d6e49fddcda2d20f6fef7f5cce1.png) - - O sensor de luz será criado e aparecerá na lista de sensores. - - ![O sensor de luz criado](../../../../../translated_images/pt-PT/counterfit-light-sensor.5d0f5584df56b90f6b2561910d9cb20dfbd73eeff2177c238d38f4de54aefae1.png) - -## Programar o sensor de luz - -O dispositivo pode agora ser programado para usar o sensor de luz integrado. - -### Tarefa - programar o sensor de luz - -Programe o dispositivo. - -1. Abra o projeto da luz de presença no VS Code que criou na parte anterior deste exercício. Termine e recrie o terminal para garantir que está a ser executado no ambiente virtual, se necessário. - -1. Abra o ficheiro `app.py`. - -1. Adicione o seguinte código ao topo do ficheiro `app.py`, junto com as restantes declarações `import`, para importar algumas bibliotecas necessárias: - - ```python - import time - from counterfit_shims_grove.grove_light_sensor_v1_2 import GroveLightSensor - ``` - - A declaração `import time` importa o módulo `time` do Python, que será usado mais tarde neste exercício. - - A declaração `from counterfit_shims_grove.grove_light_sensor_v1_2 import GroveLightSensor` importa o `GroveLightSensor` das bibliotecas Python CounterFit Grove shim. Esta biblioteca contém código para interagir com um sensor de luz criado na aplicação CounterFit. - -1. Adicione o seguinte código ao final do ficheiro para criar instâncias de classes que gerem o sensor de luz: - - ```python - light_sensor = GroveLightSensor(0) - ``` - - A linha `light_sensor = GroveLightSensor(0)` cria uma instância da classe `GroveLightSensor` conectada ao pin **0** - o pin Grove do CounterFit ao qual o sensor de luz está ligado. - -1. Adicione um loop infinito após o código acima para consultar o valor do sensor de luz e imprimi-lo no terminal: - - ```python - while True: - light = light_sensor.light - print('Light level:', light) - ``` - - Isto irá ler o nível de luz atual usando a propriedade `light` da classe `GroveLightSensor`. Esta propriedade lê o valor analógico do pin. Este valor é então impresso no terminal. - -1. Adicione uma pequena pausa de um segundo no final do loop `while`, pois os níveis de luz não precisam de ser verificados continuamente. Uma pausa reduz o consumo de energia do dispositivo. - - ```python - time.sleep(1) - ``` - -1. No Terminal do VS Code, execute o seguinte comando para executar a sua aplicação Python: - - ```sh - python3 app.py - ``` - - Os valores de luz serão exibidos no terminal. Inicialmente, este valor será 0. - -1. Na aplicação CounterFit, altere o valor do sensor de luz que será lido pela aplicação. Pode fazer isso de duas formas: - - * Insira um número na caixa *Value* do sensor de luz e, em seguida, selecione o botão **Set**. O número que inserir será o valor retornado pelo sensor. - - * Marque a caixa *Random* e insira um valor *Min* e *Max*, depois selecione o botão **Set**. Sempre que o sensor ler um valor, será gerado um número aleatório entre *Min* e *Max*. - - Os valores que definir serão exibidos no terminal. Altere o *Value* ou as definições de *Random* para fazer o valor mudar. - - ```output - (.venv) ➜ GroveTest python3 app.py - Light level: 143 - Light level: 244 - Light level: 246 - Light level: 253 - ``` - -> 💁 Pode encontrar este código na pasta [code-sensor/virtual-device](../../../../../1-getting-started/lessons/3-sensors-and-actuators/code-sensor/virtual-device). - -😀 O seu programa de luz de presença foi um sucesso! - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, é importante notar que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes do uso desta tradução. \ No newline at end of file diff --git a/translations/pt/1-getting-started/lessons/3-sensors-and-actuators/wio-terminal-actuator.md b/translations/pt/1-getting-started/lessons/3-sensors-and-actuators/wio-terminal-actuator.md deleted file mode 100644 index 18837dca5..000000000 --- a/translations/pt/1-getting-started/lessons/3-sensors-and-actuators/wio-terminal-actuator.md +++ /dev/null @@ -1,122 +0,0 @@ - -# Construa uma luz de presença - Wio Terminal - -Nesta parte da lição, irá adicionar um LED ao seu Wio Terminal e usá-lo para criar uma luz de presença. - -## Hardware - -A luz de presença agora precisa de um atuador. - -O atuador é um **LED**, um [díodo emissor de luz](https://wikipedia.org/wiki/Light-emitting_diode) que emite luz quando a corrente passa por ele. Este é um atuador digital que tem 2 estados: ligado e desligado. Enviar um valor de 1 liga o LED, e 0 desliga-o. Este é um atuador externo Grove e precisa de ser ligado ao Wio Terminal. - -A lógica da luz de presença em pseudo-código é: - -```output -Check the light level. -If the light is less than 300 - Turn the LED on -Otherwise - Turn the LED off -``` - -### Ligar o LED - -O LED Grove vem como um módulo com uma seleção de LEDs, permitindo-lhe escolher a cor. - -#### Tarefa - ligar o LED - -Ligue o LED. - -![Um LED Grove](../../../../../translated_images/pt-PT/grove-led.6c853be93f473cf2c439cfc74bb1064732b22251a83cedf66e62f783f9cc1a79.png) - -1. Escolha o seu LED favorito e insira as pernas nos dois orifícios do módulo LED. - - Os LEDs são díodos emissores de luz, e os díodos são dispositivos eletrónicos que só permitem a passagem de corrente num sentido. Isto significa que o LED precisa de ser ligado na orientação correta, caso contrário, não funcionará. - - Uma das pernas do LED é o pino positivo, a outra é o pino negativo. O LED não é perfeitamente redondo e é ligeiramente mais plano de um lado. O lado ligeiramente mais plano é o pino negativo. Ao ligar o LED ao módulo, certifique-se de que o pino do lado arredondado está ligado à tomada marcada com **+** na parte externa do módulo, e o lado mais plano está ligado à tomada mais próxima do centro do módulo. - -1. O módulo LED tem um botão rotativo que permite controlar o brilho. Rode-o completamente para cima no início, girando-o no sentido anti-horário até ao limite, usando uma pequena chave de fendas Phillips. - -1. Insira uma extremidade de um cabo Grove na tomada do módulo LED. Só encaixará de uma forma. - -1. Com o Wio Terminal desligado do computador ou de outra fonte de alimentação, ligue a outra extremidade do cabo Grove à tomada Grove do lado direito do Wio Terminal, olhando para o ecrã. Esta é a tomada mais distante do botão de energia. - - > 💁 A tomada Grove do lado direito pode ser usada com sensores e atuadores analógicos ou digitais. A tomada do lado esquerdo é apenas para sensores e atuadores digitais. O C será abordado numa lição posterior. - -![O LED Grove ligado à tomada do lado direito](../../../../../translated_images/pt-PT/wio-led.265a1897e72d7f21.webp) - -## Programar a luz de presença - -A luz de presença pode agora ser programada usando o sensor de luz embutido e o LED Grove. - -### Tarefa - programar a luz de presença - -Programe a luz de presença. - -1. Abra o projeto da luz de presença no VS Code que criou na parte anterior desta tarefa. - -1. Adicione a seguinte linha ao final da função `setup`: - - ```cpp - pinMode(D0, OUTPUT); - ``` - - Esta linha configura o pino usado para comunicar com o LED através da porta Grove. - - O pino `D0` é o pino digital para a tomada Grove do lado direito. Este pino é configurado como `OUTPUT`, o que significa que está ligado a um atuador e os dados serão escritos no pino. - -1. Adicione o seguinte código imediatamente antes do `delay` na função loop: - - ```cpp - if (light < 300) - { - digitalWrite(D0, HIGH); - } - else - { - digitalWrite(D0, LOW); - } - ``` - - Este código verifica o valor de `light`. Se for inferior a 300, envia um valor `HIGH` para o pino digital `D0`. Este `HIGH` é um valor de 1, ligando o LED. Se o valor de luz for maior ou igual a 300, um valor `LOW` de 0 é enviado para o pino, desligando o LED. - - > 💁 Ao enviar valores digitais para atuadores, um valor LOW é 0v, e um valor HIGH é a voltagem máxima para o dispositivo. Para o Wio Terminal, a voltagem HIGH é 3.3V. - -1. Volte a ligar o Wio Terminal ao seu computador e carregue o novo código como fez anteriormente. - -1. Ligue o Monitor Serial. Os valores de luz serão exibidos no terminal. - - ```output - > Executing task: platformio device monitor < - - --- Available filters and text transformations: colorize, debug, default, direct, hexlify, log2file, nocontrol, printable, send_on_enter, time - --- More details at http://bit.ly/pio-monitor-filters - --- Miniterm on /dev/cu.usbmodem101 9600,8,N,1 --- - --- Quit: Ctrl+C | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H --- - Light value: 4 - Light value: 5 - Light value: 4 - Light value: 158 - Light value: 343 - Light value: 348 - Light value: 344 - ``` - -1. Tape e destape o sensor de luz. Note como o LED acende se o nível de luz for 300 ou menos, e apaga-se quando o nível de luz for superior a 300. - -![O LED ligado ao WIO a acender e apagar conforme o nível de luz muda](../../../../../images/wio-running-assignment-1-1.gif) - -> 💁 Pode encontrar este código na pasta [code-actuator/wio-terminal](../../../../../1-getting-started/lessons/3-sensors-and-actuators/code-actuator/wio-terminal). - -😀 O seu programa de luz de presença foi um sucesso! - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos pela precisão, esteja ciente de que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes do uso desta tradução. \ No newline at end of file diff --git a/translations/pt/1-getting-started/lessons/3-sensors-and-actuators/wio-terminal-sensor.md b/translations/pt/1-getting-started/lessons/3-sensors-and-actuators/wio-terminal-sensor.md deleted file mode 100644 index aeb9a1637..000000000 --- a/translations/pt/1-getting-started/lessons/3-sensors-and-actuators/wio-terminal-sensor.md +++ /dev/null @@ -1,85 +0,0 @@ - -# Adicionar um sensor - Wio Terminal - -Nesta parte da lição, vais utilizar o sensor de luz do teu Wio Terminal. - -## Hardware - -O sensor para esta lição é um **sensor de luz** que utiliza um [fotodíodo](https://wikipedia.org/wiki/Photodiode) para converter luz em um sinal elétrico. Este é um sensor analógico que envia um valor inteiro de 0 a 1.023, indicando uma quantidade relativa de luz que não corresponde a nenhuma unidade de medida padrão, como [lux](https://wikipedia.org/wiki/Lux). - -O sensor de luz está integrado no Wio Terminal e é visível através da janela de plástico transparente na parte de trás. - -![O sensor de luz na parte de trás do Wio Terminal](../../../../../translated_images/pt-PT/wio-light-sensor.b1f529f3c95f5165.webp) - -## Programar o sensor de luz - -O dispositivo pode agora ser programado para utilizar o sensor de luz integrado. - -### Tarefa - -Programa o dispositivo. - -1. Abre o projeto da luz noturna no VS Code que criaste na parte anterior deste exercício. - -1. Adiciona a seguinte linha ao final da função `setup`: - - ```cpp - pinMode(WIO_LIGHT, INPUT); - ``` - - Esta linha configura os pinos utilizados para comunicar com o hardware do sensor. - - O pino `WIO_LIGHT` é o número do pino GPIO conectado ao sensor de luz integrado. Este pino é configurado como `INPUT`, o que significa que está ligado a um sensor e os dados serão lidos a partir do pino. - -1. Apaga o conteúdo da função `loop`. - -1. Adiciona o seguinte código à função `loop`, que agora está vazia. - - ```cpp - int light = analogRead(WIO_LIGHT); - Serial.print("Light value: "); - Serial.println(light); - ``` - - Este código lê um valor analógico do pino `WIO_LIGHT`. Ele lê um valor de 0 a 1.023 do sensor de luz integrado. Este valor é então enviado para a porta serial para que possas lê-lo no Monitor Serial enquanto este código estiver a ser executado. `Serial.print` escreve o texto sem uma nova linha no final, então cada linha começará com `Light value:` e terminará com o valor real da luz. - -1. Adiciona um pequeno atraso de um segundo (1.000ms) no final do `loop`, já que os níveis de luz não precisam de ser verificados continuamente. Um atraso reduz o consumo de energia do dispositivo. - - ```cpp - delay(1000); - ``` - -1. Reconecta o Wio Terminal ao teu computador e faz o upload do novo código como fizeste anteriormente. - -1. Conecta o Monitor Serial. Os valores de luz serão exibidos no terminal. Cobre e descobre o sensor de luz na parte de trás do Wio Terminal, e os valores irão mudar. - - ```output - > Executing task: platformio device monitor < - - --- Available filters and text transformations: colorize, debug, default, direct, hexlify, log2file, nocontrol, printable, send_on_enter, time - --- More details at http://bit.ly/pio-monitor-filters - --- Miniterm on /dev/cu.usbmodem101 9600,8,N,1 --- - --- Quit: Ctrl+C | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H --- - Light value: 4 - Light value: 5 - Light value: 4 - Light value: 158 - Light value: 343 - Light value: 348 - Light value: 344 - ``` - -> 💁 Podes encontrar este código na pasta [code-sensor/wio-terminal](../../../../../1-getting-started/lessons/3-sensors-and-actuators/code-sensor/wio-terminal). - -😀 Adicionar um sensor ao teu programa de luz noturna foi um sucesso! - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, é importante notar que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes do uso desta tradução. \ No newline at end of file diff --git a/translations/pt/1-getting-started/lessons/4-connect-internet/README.md b/translations/pt/1-getting-started/lessons/4-connect-internet/README.md deleted file mode 100644 index 625f5c3aa..000000000 --- a/translations/pt/1-getting-started/lessons/4-connect-internet/README.md +++ /dev/null @@ -1,464 +0,0 @@ - -# Conecte o seu dispositivo à Internet - -![Uma visão geral ilustrada desta lição](../../../../../translated_images/pt-PT/lesson-4.7344e074ea68fa545fd320b12dce36d72dd62d28c3b4596cb26cf315f434b98f.jpg) - -> Ilustração por [Nitya Narasimhan](https://github.com/nitya). Clique na imagem para uma versão maior. - -Esta lição foi ensinada como parte da série [Hello IoT](https://youtube.com/playlist?list=PLmsFUfdnGr3xRts0TIwyaHyQuHaNQcb6-) do [Microsoft Reactor](https://developer.microsoft.com/reactor/?WT.mc_id=academic-17441-jabenn). A lição foi apresentada em 2 vídeos - uma aula de 1 hora e uma sessão de perguntas e respostas de 1 hora, explorando mais a fundo partes da lição e respondendo a dúvidas. - -[![Lição 4: Conecte o seu dispositivo à Internet](https://img.youtube.com/vi/O4dd172mZhs/0.jpg)](https://youtu.be/O4dd172mZhs) - -[![Lição 4: Conecte o seu dispositivo à Internet - Sessão de perguntas e respostas](https://img.youtube.com/vi/j-cVCzRDE2Q/0.jpg)](https://youtu.be/j-cVCzRDE2Q) - -> 🎥 Clique nas imagens acima para assistir aos vídeos - -## Questionário pré-aula - -[Questionário pré-aula](https://black-meadow-040d15503.1.azurestaticapps.net/quiz/7) - -## Introdução - -O **I** em IoT significa **Internet** - a conectividade com a nuvem e os serviços que possibilitam muitas das funcionalidades dos dispositivos IoT, desde a coleta de medições dos sensores conectados ao dispositivo até o envio de mensagens para controlar os atuadores. Dispositivos IoT geralmente se conectam a um único serviço de IoT na nuvem usando um protocolo de comunicação padrão, e esse serviço está conectado ao restante da sua aplicação IoT, desde serviços de IA para tomar decisões inteligentes com base nos dados até aplicativos web para controle ou relatórios. - -> 🎓 Dados coletados de sensores e enviados para a nuvem são chamados de telemetria. - -Dispositivos IoT podem receber mensagens da nuvem. Muitas vezes, essas mensagens contêm comandos - ou seja, instruções para realizar uma ação, seja internamente (como reiniciar ou atualizar o firmware) ou usando um atuador (como acender uma luz). - -Esta lição apresenta alguns dos protocolos de comunicação que dispositivos IoT podem usar para se conectar à nuvem e os tipos de dados que podem enviar ou receber. Você também terá uma experiência prática com ambos, adicionando controle pela Internet à sua luz noturna, movendo a lógica de controle do LED para um código 'servidor' executado localmente. - -Nesta lição, abordaremos: - -* [Protocolos de comunicação](../../../../../1-getting-started/lessons/4-connect-internet) -* [Message Queueing Telemetry Transport (MQTT)](../../../../../1-getting-started/lessons/4-connect-internet) -* [Telemetria](../../../../../1-getting-started/lessons/4-connect-internet) -* [Comandos](../../../../../1-getting-started/lessons/4-connect-internet) - -## Protocolos de comunicação - -Existem vários protocolos de comunicação populares usados por dispositivos IoT para se comunicar com a Internet. Os mais comuns são baseados em mensagens de publicação/assinatura via algum tipo de broker. Os dispositivos IoT se conectam ao broker, publicam telemetria e assinam comandos. Os serviços na nuvem também se conectam ao broker, assinam todas as mensagens de telemetria e publicam comandos, seja para dispositivos específicos ou para grupos de dispositivos. - -![Dispositivos IoT conectam-se a um broker, publicam telemetria e assinam comandos. Serviços na nuvem conectam-se ao broker, assinam toda a telemetria e enviam comandos para dispositivos específicos.](../../../../../translated_images/pt-PT/pub-sub.7c7ed43fe9fd15d4.webp) - -O MQTT é o protocolo de comunicação mais popular para dispositivos IoT e será abordado nesta lição. Outros protocolos incluem AMQP e HTTP/HTTPS. - -## Message Queueing Telemetry Transport (MQTT) - -[MQTT](http://mqtt.org) é um protocolo de mensagens leve e de padrão aberto que pode enviar mensagens entre dispositivos. Ele foi projetado em 1999 para monitorar oleodutos, antes de ser lançado como um padrão aberto 15 anos depois pela IBM. - -O MQTT possui um único broker e vários clientes. Todos os clientes se conectam ao broker, e o broker encaminha mensagens para os clientes relevantes. As mensagens são roteadas usando tópicos nomeados, em vez de serem enviadas diretamente para um cliente individual. Um cliente pode publicar em um tópico, e qualquer cliente que assinar esse tópico receberá a mensagem. - -![Dispositivo IoT publicando telemetria no tópico /telemetry, e o serviço na nuvem assinando esse tópico](../../../../../translated_images/pt-PT/mqtt.cbf7f21d9adc3e17548b359444cc11bb4bf2010543e32ece9a47becf54438c23.png) - -✅ Faça uma pesquisa. Se você tiver muitos dispositivos IoT, como pode garantir que o seu broker MQTT consiga lidar com todas as mensagens? - -### Conecte o seu dispositivo IoT ao MQTT - -A primeira parte de adicionar controle pela Internet à sua luz noturna é conectá-la a um broker MQTT. - -#### Tarefa - -Conecte o seu dispositivo a um broker MQTT. - -Nesta parte da lição, você conectará sua luz noturna IoT à Internet para permitir que ela seja controlada remotamente. Mais tarde nesta lição, o seu dispositivo IoT enviará uma mensagem de telemetria via MQTT para um broker MQTT público com o nível de luz, onde será captada por um código de servidor que você escreverá. Esse código verificará o nível de luz e enviará uma mensagem de comando de volta ao dispositivo, instruindo-o a ligar ou desligar o LED. - -O caso de uso real para tal configuração poderia ser coletar dados de vários sensores de luz antes de decidir acender as luzes em um local com muitas luzes, como um estádio. Isso poderia evitar que as luzes fossem acesas se apenas um sensor estivesse coberto por nuvens ou por um pássaro, mas os outros sensores detectassem luz suficiente. - -✅ Que outras situações exigiriam a avaliação de dados de vários sensores antes de enviar comandos? - -Em vez de lidar com as complexidades de configurar um broker MQTT como parte desta tarefa, você pode usar um servidor de teste público que executa o [Eclipse Mosquitto](https://www.mosquitto.org), um broker MQTT de código aberto. Este broker de teste está disponível publicamente em [test.mosquitto.org](https://test.mosquitto.org) e não exige a criação de uma conta, tornando-o uma ótima ferramenta para testar clientes e servidores MQTT. - -> 💁 Este broker de teste é público e não é seguro. Qualquer pessoa pode estar ouvindo o que você publica, então ele não deve ser usado com dados que precisam ser mantidos privados. - -![Um fluxograma da tarefa mostrando os níveis de luz sendo lidos e verificados, e o LED sendo controlado](../../../../../translated_images/pt-PT/assignment-1-internet-flow.3256feab5f052fd273bf4e331157c574c2c3fa42e479836fc9c3586f41db35a5.png) - -Siga o passo relevante abaixo para conectar o seu dispositivo ao broker MQTT: - -* [Arduino - Wio Terminal](wio-terminal-mqtt.md) -* [Computador de placa única - Raspberry Pi/Dispositivo IoT virtual](single-board-computer-mqtt.md) - -### Um mergulho mais profundo no MQTT - -Os tópicos podem ter uma hierarquia, e os clientes podem assinar diferentes níveis da hierarquia usando curingas. Por exemplo, você pode enviar mensagens de telemetria de temperatura para o tópico `/telemetry/temperature` e mensagens de umidade para o tópico `/telemetry/humidity`, e então, no seu aplicativo na nuvem, assinar o tópico `/telemetry/*` para receber ambas as mensagens de telemetria de temperatura e umidade. - -As mensagens podem ser enviadas com uma qualidade de serviço (QoS), que determina a garantia de que a mensagem será recebida. - -* No máximo uma vez - a mensagem é enviada apenas uma vez e o cliente e o broker não tomam medidas adicionais para confirmar a entrega (enviar e esquecer). -* Pelo menos uma vez - a mensagem é reenviada pelo remetente várias vezes até que o recebimento seja confirmado (entrega reconhecida). -* Exatamente uma vez - o remetente e o receptor realizam um processo de handshake em dois níveis para garantir que apenas uma cópia da mensagem seja recebida (entrega garantida). - -✅ Que situações podem exigir uma mensagem de entrega garantida em vez de uma mensagem de enviar e esquecer? - -Embora o nome seja Message Queueing (iniciais em MQTT), ele na verdade não suporta filas de mensagens. Isso significa que, se um cliente se desconectar e depois se reconectar, ele não receberá mensagens enviadas durante a desconexão, exceto aquelas que ele já havia começado a processar usando o processo de QoS. As mensagens podem ter um sinalizador de retenção ativado. Se este sinalizador estiver ativado, o broker MQTT armazenará a última mensagem enviada em um tópico com este sinalizador e enviará esta mensagem para qualquer cliente que posteriormente assinar o tópico. Desta forma, os clientes sempre receberão a mensagem mais recente. - -O MQTT também suporta uma função de keep alive que verifica se a conexão ainda está ativa durante longos intervalos entre mensagens. - -> 🦟 [Mosquitto da Eclipse Foundation](https://mosquitto.org) oferece um broker MQTT gratuito que você pode executar para experimentar o MQTT, além de um broker MQTT público que você pode usar para testar seu código, hospedado em [test.mosquitto.org](https://test.mosquitto.org). - -As conexões MQTT podem ser públicas e abertas, ou criptografadas e protegidas usando nomes de usuário e senhas, ou certificados. - -> 💁 O MQTT se comunica via TCP/IP, o mesmo protocolo de rede subjacente ao HTTP, mas em uma porta diferente. Você também pode usar MQTT sobre websockets para se comunicar com aplicativos web executados em um navegador ou em situações onde firewalls ou outras regras de rede bloqueiam conexões MQTT padrão. - -## Telemetria - -A palavra telemetria é derivada de raízes gregas que significam medir remotamente. Telemetria é o ato de coletar dados de sensores e enviá-los para a nuvem. - -> 💁 Um dos primeiros dispositivos de telemetria foi inventado na França em 1874 e enviava em tempo real dados meteorológicos e de profundidade de neve do Mont Blanc para Paris. Ele usava fios físicos, pois tecnologias sem fio não estavam disponíveis na época. - -Vamos relembrar o exemplo do termostato inteligente da Lição 1. - -![Um termostato conectado à Internet usando vários sensores de ambiente](../../../../../translated_images/pt-PT/telemetry.21e5d8b97649d2eb.webp) - -O termostato possui sensores de temperatura para coletar telemetria. Provavelmente teria um sensor de temperatura embutido e poderia se conectar a vários sensores de temperatura externos via um protocolo sem fio, como [Bluetooth Low Energy](https://wikipedia.org/wiki/Bluetooth_Low_Energy) (BLE). - -Um exemplo dos dados de telemetria que ele enviaria poderia ser: - -| Nome | Valor | Descrição | -| ---- | ----- | ----------- | -| `thermostat_temperature` | 18°C | A temperatura medida pelo sensor de temperatura embutido no termostato | -| `livingroom_temperature` | 19°C | A temperatura medida por um sensor de temperatura remoto que foi nomeado como `livingroom` para identificar a sala onde está localizado | -| `bedroom_temperature` | 21°C | A temperatura medida por um sensor de temperatura remoto que foi nomeado como `bedroom` para identificar o quarto onde está localizado | - -O serviço na nuvem pode então usar esses dados de telemetria para tomar decisões sobre quais comandos enviar para controlar o aquecimento. - -### Enviar telemetria do seu dispositivo IoT - -A próxima parte de adicionar controle pela Internet à sua luz noturna é enviar a telemetria do nível de luz para o broker MQTT em um tópico de telemetria. - -#### Tarefa - enviar telemetria do seu dispositivo IoT - -Envie telemetria do nível de luz para o broker MQTT. - -Os dados são enviados codificados como JSON - abreviação de JavaScript Object Notation, um padrão para codificar dados em texto usando pares chave/valor. - -✅ Se você nunca ouviu falar de JSON antes, pode aprender mais sobre ele na [documentação do JSON.org](https://www.json.org/). - -Siga o passo relevante abaixo para enviar telemetria do seu dispositivo para o broker MQTT: - -* [Arduino - Wio Terminal](wio-terminal-telemetry.md) -* [Computador de placa única - Raspberry Pi/Dispositivo IoT virtual](single-board-computer-telemetry.md) - -### Receber telemetria do broker MQTT - -Não faz sentido enviar telemetria se não houver nada na outra ponta para ouvi-la. A telemetria do nível de luz precisa de algo que a processe. Este código 'servidor' é o tipo de código que você implantará em um serviço na nuvem como parte de uma aplicação IoT maior, mas aqui você executará este código localmente no seu computador (ou no seu Pi, se estiver programando diretamente nele). O código do servidor consiste em um aplicativo Python que escuta mensagens de telemetria via MQTT com níveis de luz. Mais tarde nesta lição, você fará com que ele responda com uma mensagem de comando com instruções para ligar ou desligar o LED. - -✅ Faça uma pesquisa: O que acontece com as mensagens MQTT se não houver um ouvinte? - -#### Instalar Python e VS Code - -Se você não tiver Python e VS Code instalados localmente, precisará instalá-los para programar o servidor. Se estiver usando um dispositivo IoT virtual ou trabalhando no seu Raspberry Pi, pode pular esta etapa, pois já deve ter isso instalado e configurado. - -##### Tarefa - instalar Python e VS Code - -Instale Python e VS Code. - -1. Instale o Python. Consulte a [página de downloads do Python](https://www.python.org/downloads/) para instruções sobre como instalar a versão mais recente do Python. - -1. Instale o Visual Studio Code (VS Code). Este será o editor que você usará para escrever o código do dispositivo virtual em Python. Consulte a [documentação do VS Code](https://code.visualstudio.com?WT.mc_id=academic-17441-jabenn) para instruções sobre como instalar o VS Code. -💁 Está à vontade para usar qualquer IDE ou editor de Python para estas lições, caso tenha uma ferramenta preferida, mas as lições fornecerão instruções baseadas no uso do VS Code. -1. Instale a extensão Pylance para VS Code. Esta é uma extensão para o VS Code que oferece suporte à linguagem Python. Consulte a [documentação da extensão Pylance](https://marketplace.visualstudio.com/items?WT.mc_id=academic-17441-jabenn&itemName=ms-python.vscode-pylance) para instruções sobre como instalar esta extensão no VS Code. - -#### Configurar um ambiente virtual Python - -Uma das funcionalidades mais poderosas do Python é a capacidade de instalar [pacotes pip](https://pypi.org) - pacotes de código escritos por outras pessoas e publicados na Internet. Pode instalar um pacote pip no seu computador com um único comando e, em seguida, usar esse pacote no seu código. Vai usar o pip para instalar um pacote que permite comunicação via MQTT. - -Por padrão, quando instala um pacote, ele fica disponível em todo o computador, o que pode levar a problemas com versões de pacotes - como uma aplicação depender de uma versão específica de um pacote que deixa de funcionar quando instala uma nova versão para outra aplicação. Para contornar este problema, pode usar um [ambiente virtual Python](https://docs.python.org/3/library/venv.html), que é essencialmente uma cópia do Python numa pasta dedicada. Quando instala pacotes pip, eles são instalados apenas nessa pasta. - -##### Tarefa - configurar um ambiente virtual Python - -Configure um ambiente virtual Python e instale os pacotes pip para MQTT. - -1. No terminal ou linha de comandos, execute o seguinte numa localização à sua escolha para criar e navegar para um novo diretório: - - ```sh - mkdir nightlight-server - cd nightlight-server - ``` - -1. Agora execute o seguinte para criar um ambiente virtual na pasta `.venv`: - - ```sh - python3 -m venv .venv - ``` - - > 💁 Deve chamar explicitamente `python3` para criar o ambiente virtual, caso tenha o Python 2 instalado além do Python 3 (a versão mais recente). Se tiver o Python 2 instalado, ao chamar `python`, será usado o Python 2 em vez do Python 3. - -1. Ative o ambiente virtual: - - * No Windows: - * Se estiver a usar o Command Prompt ou o Command Prompt através do Windows Terminal, execute: - - ```cmd - .venv\Scripts\activate.bat - ``` - - * Se estiver a usar o PowerShell, execute: - - ```powershell - .\.venv\Scripts\Activate.ps1 - ``` - - * No macOS ou Linux, execute: - - ```cmd - source ./.venv/bin/activate - ``` - - > 💁 Estes comandos devem ser executados na mesma localização onde executou o comando para criar o ambiente virtual. Nunca precisará de navegar para dentro da pasta `.venv`; deve sempre executar o comando de ativação e quaisquer comandos para instalar pacotes ou executar código a partir da pasta onde criou o ambiente virtual. - -1. Uma vez ativado o ambiente virtual, o comando padrão `python` executará a versão do Python usada para criar o ambiente virtual. Execute o seguinte para verificar a versão: - - ```sh - python --version - ``` - - A saída será semelhante ao seguinte: - - ```output - (.venv) ➜ nightlight-server python --version - Python 3.9.1 - ``` - - > 💁 A sua versão do Python pode ser diferente - desde que seja a versão 3.6 ou superior, está tudo bem. Caso contrário, elimine esta pasta, instale uma versão mais recente do Python e tente novamente. - -1. Execute os seguintes comandos para instalar o pacote pip [Paho-MQTT](https://pypi.org/project/paho-mqtt/), uma biblioteca popular de MQTT. - - ```sh - pip install paho-mqtt - ``` - - Este pacote pip será instalado apenas no ambiente virtual e não estará disponível fora dele. - -#### Escrever o código do servidor - -Agora pode escrever o código do servidor em Python. - -##### Tarefa - escrever o código do servidor - -Escreva o código do servidor. - -1. No terminal ou linha de comandos, execute o seguinte dentro do ambiente virtual para criar um ficheiro Python chamado `app.py`: - - * No Windows, execute: - - ```cmd - type nul > app.py - ``` - - * No macOS ou Linux, execute: - - ```cmd - touch app.py - ``` - -1. Abra a pasta atual no VS Code: - - ```sh - code . - ``` - -1. Quando o VS Code for iniciado, ele ativará o ambiente virtual Python. Isto será indicado na barra de estado inferior: - - ![VS Code mostrando o ambiente virtual selecionado](../../../../../translated_images/pt-PT/vscode-virtual-env.8ba42e04c3d533cf.webp) - -1. Se o terminal do VS Code já estiver em execução quando o VS Code for iniciado, o ambiente virtual não será ativado nele. A forma mais fácil de resolver isto é encerrar o terminal usando o botão **Kill the active terminal instance**: - - ![Botão do VS Code para encerrar a instância ativa do terminal](../../../../../translated_images/pt-PT/vscode-kill-terminal.1cc4de7c6f25ee08.webp) - -1. Inicie um novo terminal no VS Code selecionando *Terminal -> New Terminal*, ou pressionando `` CTRL+` ``. O novo terminal carregará o ambiente virtual, com a chamada para ativá-lo aparecendo no terminal. O nome do ambiente virtual (`.venv`) também estará no prompt: - - ```output - ➜ nightlight-server source .venv/bin/activate - (.venv) ➜ nightlight - ``` - -1. Abra o ficheiro `app.py` no explorador do VS Code e adicione o seguinte código: - - ```python - import json - import time - - import paho.mqtt.client as mqtt - - id = '' - - client_telemetry_topic = id + '/telemetry' - client_name = id + 'nightlight_server' - - mqtt_client = mqtt.Client(client_name) - mqtt_client.connect('test.mosquitto.org') - - mqtt_client.loop_start() - - def handle_telemetry(client, userdata, message): - payload = json.loads(message.payload.decode()) - print("Message received:", payload) - - mqtt_client.subscribe(client_telemetry_topic) - mqtt_client.on_message = handle_telemetry - - while True: - time.sleep(2) - ``` - - Substitua `` na linha 6 pelo ID único que usou ao criar o código do seu dispositivo. - - ⚠️ Este **deve** ser o mesmo ID que usou no seu dispositivo, caso contrário o código do servidor não irá subscrever ou publicar no tópico correto. - - Este código cria um cliente MQTT com um nome único e conecta-se ao broker *test.mosquitto.org*. Em seguida, inicia um loop de processamento que é executado numa thread em segundo plano, ouvindo mensagens em quaisquer tópicos subscritos. - - O cliente subscreve mensagens no tópico de telemetria e define uma função que é chamada quando uma mensagem é recebida. Quando uma mensagem de telemetria é recebida, a função `handle_telemetry` é chamada, imprimindo a mensagem recebida no terminal. - - Por fim, um loop infinito mantém a aplicação em execução. O cliente MQTT está a ouvir mensagens numa thread em segundo plano e funciona enquanto a aplicação principal estiver em execução. - -1. No terminal do VS Code, execute o seguinte para executar a sua aplicação Python: - - ```sh - python app.py - ``` - - A aplicação começará a ouvir mensagens do dispositivo IoT. - -1. Certifique-se de que o seu dispositivo está em execução e a enviar mensagens de telemetria. Ajuste os níveis de luz detetados pelo seu dispositivo físico ou virtual. As mensagens recebidas serão impressas no terminal. - - ```output - (.venv) ➜ nightlight-server python app.py - Message received: {'light': 0} - Message received: {'light': 400} - ``` - - O ficheiro app.py no ambiente virtual nightlight deve estar em execução para que o ficheiro app.py no ambiente virtual nightlight-server receba as mensagens enviadas. - -> 💁 Pode encontrar este código na pasta [code-server/server](../../../../../1-getting-started/lessons/4-connect-internet/code-server/server). - -### Com que frequência deve ser enviada telemetria? - -Uma consideração importante sobre telemetria é com que frequência medir e enviar os dados. A resposta é - depende. Se medir frequentemente, pode responder mais rapidamente a mudanças nas medições, mas usa mais energia, mais largura de banda, gera mais dados e precisa de mais recursos na cloud para processar. Deve medir com frequência suficiente, mas não em excesso. - -Para um termóstato, medir a cada poucos minutos provavelmente é mais do que suficiente, já que as temperaturas não mudam com tanta frequência. Se medir apenas uma vez por dia, pode acabar por aquecer a casa para temperaturas noturnas no meio de um dia ensolarado, enquanto que, se medir a cada segundo, terá milhares de medições de temperatura desnecessariamente duplicadas, o que consumirá a velocidade e largura de banda da Internet dos utilizadores (um problema para pessoas com planos de largura de banda limitada), usará mais energia, o que pode ser um problema para dispositivos alimentados por bateria, como sensores remotos, e aumentará o custo dos recursos de computação na cloud para processar e armazenar os dados. - -Se estiver a monitorizar dados de uma máquina numa fábrica que, caso falhe, pode causar danos catastróficos e milhões de euros em perdas de receita, então medir várias vezes por segundo pode ser necessário. É melhor desperdiçar largura de banda do que perder telemetria que indica que uma máquina precisa de ser parada e reparada antes de quebrar. - -> 💁 Nesta situação, pode considerar ter um dispositivo de edge para processar a telemetria primeiro, reduzindo a dependência da Internet. - -### Perda de conectividade - -Conexões à Internet podem ser instáveis, com interrupções frequentes. O que deve um dispositivo IoT fazer nestas circunstâncias - deve perder os dados ou armazená-los até que a conectividade seja restaurada? Mais uma vez, a resposta é depende. - -Para um termóstato, os dados podem provavelmente ser descartados assim que uma nova medição de temperatura for feita. O sistema de aquecimento não se importa que há 20 minutos a temperatura era de 20,5°C se agora é de 19°C; é a temperatura atual que determina se o aquecimento deve estar ligado ou desligado. - -Para máquinas, pode querer manter os dados, especialmente se forem usados para procurar tendências. Existem modelos de machine learning que podem detetar anomalias em fluxos de dados analisando dados de um período definido (como a última hora) e identificando dados anómalos. Isto é frequentemente usado para manutenção preditiva, procurando indicações de que algo pode falhar em breve para que possa ser reparado ou substituído antes que isso aconteça. Pode querer que toda a telemetria de uma máquina seja enviada para que possa ser processada para deteção de anomalias, então, assim que o dispositivo IoT puder reconectar-se, enviará toda a telemetria gerada durante a interrupção da Internet. - -Os designers de dispositivos IoT também devem considerar se o dispositivo IoT pode ser usado durante uma interrupção da Internet ou perda de sinal causada pela localização. Um termóstato inteligente deve ser capaz de tomar algumas decisões limitadas para controlar o aquecimento se não puder enviar telemetria para a cloud devido a uma interrupção. - -[![Este Ferrari ficou inutilizado porque alguém tentou atualizá-lo num local subterrâneo sem receção de sinal](../../../../../translated_images/pt-PT/bricked-car.dc38f8efadc6c59d76211f981a521efb300939283dee468f79503aae3ec67615.png)](https://twitter.com/internetofshit/status/1315736960082808832) - -Para o MQTT lidar com uma perda de conectividade, o código do dispositivo e do servidor será responsável por garantir a entrega das mensagens, se necessário, por exemplo, exigindo que todas as mensagens enviadas sejam respondidas por mensagens adicionais num tópico de resposta e, caso contrário, sejam enfileiradas manualmente para serem reproduzidas mais tarde. - -## Comandos - -Comandos são mensagens enviadas pela cloud para um dispositivo, instruindo-o a fazer algo. Na maioria das vezes, isso envolve fornecer algum tipo de saída através de um atuador, mas pode ser uma instrução para o próprio dispositivo, como reiniciar ou recolher telemetria extra e devolvê-la como resposta ao comando. - -![Um termóstato conectado à Internet a receber um comando para ligar o aquecimento](../../../../../translated_images/pt-PT/commands.d6c06bbbb3a02cce95f2831a1c331daf6dedd4e470c4aa2b0ae54f332016e504.png) - -Um termóstato pode receber um comando da cloud para ligar o aquecimento. Com base nos dados de telemetria de todos os sensores, se o serviço na cloud decidir que o aquecimento deve estar ligado, envia o comando relevante. - -### Enviar comandos para o broker MQTT - -O próximo passo para o nosso candeeiro noturno controlado pela Internet é o código do servidor enviar um comando de volta para o dispositivo IoT para controlar a luz com base nos níveis de luz que deteta. - -1. Abra o código do servidor no VS Code. - -1. Adicione a seguinte linha após a declaração do `client_telemetry_topic` para definir qual tópico enviar comandos: - - ```python - server_command_topic = id + '/commands' - ``` - -1. Adicione o seguinte código ao final da função `handle_telemetry`: - - ```python - command = { 'led_on' : payload['light'] < 300 } - print("Sending message:", command) - - client.publish(server_command_topic, json.dumps(command)) - ``` - - Isto envia uma mensagem JSON para o tópico de comandos com o valor de `led_on` definido como verdadeiro ou falso, dependendo se a luz é inferior a 300 ou não. Se a luz for inferior a 300, é enviado verdadeiro para instruir o dispositivo a ligar o LED. - -1. Execute o código como antes. - -1. Ajuste os níveis de luz detetados pelo seu dispositivo físico ou virtual. As mensagens recebidas e os comandos enviados serão escritos no terminal: - - ```output - (.venv) ➜ nightlight-server python app.py - Message received: {'light': 0} - Sending message: {'led_on': True} - Message received: {'light': 400} - Sending message: {'led_on': False} - ``` - -> 💁 A telemetria e os comandos estão a ser enviados num único tópico cada. Isto significa que a telemetria de vários dispositivos aparecerá no mesmo tópico de telemetria e os comandos para vários dispositivos aparecerão no mesmo tópico de comandos. Se quiser enviar um comando para um dispositivo específico, pode usar vários tópicos, nomeados com um ID único do dispositivo, como `/commands/device1`, `/commands/device2`. Dessa forma, um dispositivo pode ouvir mensagens destinadas apenas a ele. - -> 💁 Pode encontrar este código na pasta [code-commands/server](../../../../../1-getting-started/lessons/4-connect-internet/code-commands/server). - -### Lidar com comandos no dispositivo IoT - -Agora que os comandos estão a ser enviados pelo servidor, pode adicionar código ao dispositivo IoT para lidar com eles e controlar o LED. - -Siga o passo relevante abaixo para ouvir comandos do broker MQTT: - -* [Arduino - Wio Terminal](wio-terminal-commands.md) -* [Computador de placa única - Raspberry Pi/Dispositivo IoT virtual](single-board-computer-commands.md) - -Depois de escrever e executar este código, experimente alterar os níveis de luz. Veja a saída do servidor e do dispositivo e observe o LED enquanto altera os níveis de luz. - -### Perda de conectividade - -O que deve um serviço na cloud fazer se precisar de enviar um comando para um dispositivo IoT que está offline? Mais uma vez, a resposta é depende. - -Se o último comando substituir um anterior, então os anteriores podem provavelmente ser ignorados. Se um serviço na cloud enviar um comando para ligar o aquecimento e depois enviar um comando para desligá-lo, então o comando de ligar pode ser ignorado e não reenviado. - -Se os comandos precisarem de ser processados em sequência, como mover um braço robótico para cima e depois fechar uma garra, então precisam de ser enviados na ordem correta assim que a conectividade for restaurada. - -✅ Como o código do dispositivo ou do servidor poderia garantir que os comandos sejam sempre enviados e processados na ordem correta via MQTT, se necessário? - ---- - -## 🚀 Desafio - -O desafio nas últimas três lições foi listar o maior número possível de dispositivos IoT que estão na sua casa, escola ou local de trabalho e decidir se são construídos em torno de microcontroladores ou computadores de placa única, ou até mesmo uma mistura de ambos, e pensar sobre quais sensores e atuadores estão a usar. -Para estes dispositivos, pense nas mensagens que podem estar a enviar ou receber. Que telemetria enviam? Que mensagens ou comandos podem receber? Acha que são seguros? - -## Questionário pós-aula - -[Questionário pós-aula](https://black-meadow-040d15503.1.azurestaticapps.net/quiz/8) - -## Revisão e Estudo Individual - -Leia mais sobre MQTT na [página da Wikipedia sobre MQTT](https://wikipedia.org/wiki/MQTT). - -Experimente executar um broker MQTT por conta própria utilizando [Mosquitto](https://www.mosquitto.org) e conecte-se a partir do seu dispositivo IoT e código de servidor. - -> 💁 Dica - por padrão, o Mosquitto não permite conexões anónimas (ou seja, conectar sem um nome de utilizador e palavra-passe), e não permite conexões de fora do computador onde está a ser executado. -> Pode resolver isto com um [ficheiro de configuração `mosquitto.conf`](https://www.mosquitto.org/man/mosquitto-conf-5.html) com o seguinte: -> -> ```sh -> listener 1883 0.0.0.0 -> allow_anonymous true -> ``` - -## Tarefa - -[Compare e contraste o MQTT com outros protocolos de comunicação](assignment.md) - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos pela precisão, esteja ciente de que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes da utilização desta tradução. \ No newline at end of file diff --git a/translations/pt/1-getting-started/lessons/4-connect-internet/assignment.md b/translations/pt/1-getting-started/lessons/4-connect-internet/assignment.md deleted file mode 100644 index dee0c12a5..000000000 --- a/translations/pt/1-getting-started/lessons/4-connect-internet/assignment.md +++ /dev/null @@ -1,26 +0,0 @@ - -# Comparar e contrastar MQTT com outros protocolos de comunicação - -## Instruções - -Esta lição abordou o MQTT como um protocolo de comunicação. Existem outros, incluindo AMQP e HTTP/HTTPS. - -Pesquise ambos e compare/contraste-os com o MQTT. Considere o consumo de energia, segurança e persistência de mensagens caso as conexões sejam perdidas. - -## Rubrica - -| Critério | Exemplar | Adequado | Necessita Melhorias | -| -------- | --------- | -------- | ------------------- | -| Comparar AMQP com MQTT | Consegue comparar e contrastar AMQP com MQTT e aborda consumo de energia, segurança e persistência de mensagens. | Consegue parcialmente comparar e contrastar AMQP com MQTT e aborda dois dos seguintes: consumo de energia, segurança e persistência de mensagens. | Consegue parcialmente comparar e contrastar AMQP com MQTT e aborda um dos seguintes: consumo de energia, segurança e persistência de mensagens. | -| Comparar HTTP/HTTPS com MQTT | Consegue comparar e contrastar HTTP/HTTPS com MQTT e aborda consumo de energia, segurança e persistência de mensagens. | Consegue parcialmente comparar e contrastar HTTP/HTTPS com MQTT e aborda dois dos seguintes: consumo de energia, segurança e persistência de mensagens. | Consegue parcialmente comparar e contrastar HTTP/HTTPS com MQTT e aborda um dos seguintes: consumo de energia, segurança e persistência de mensagens. | - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, tenha em atenção que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes da utilização desta tradução. \ No newline at end of file diff --git a/translations/pt/1-getting-started/lessons/4-connect-internet/single-board-computer-commands.md b/translations/pt/1-getting-started/lessons/4-connect-internet/single-board-computer-commands.md deleted file mode 100644 index e007678f3..000000000 --- a/translations/pt/1-getting-started/lessons/4-connect-internet/single-board-computer-commands.md +++ /dev/null @@ -1,65 +0,0 @@ - -# Controle a sua luz noturna pela Internet - Hardware IoT Virtual e Raspberry Pi - -Nesta parte da lição, irá subscrever comandos enviados de um broker MQTT para o seu Raspberry Pi ou dispositivo IoT virtual. - -## Subscrever comandos - -O próximo passo é subscrever os comandos enviados pelo broker MQTT e responder a eles. - -### Tarefa - -Subscrever comandos. - -1. Abra o projeto da luz noturna no VS Code. - -1. Se estiver a usar um dispositivo IoT virtual, certifique-se de que o terminal está a executar o ambiente virtual. Se estiver a usar um Raspberry Pi, não estará a usar um ambiente virtual. - -1. Adicione o seguinte código após as definições de `client_telemetry_topic`: - - ```python - server_command_topic = id + '/commands' - ``` - - O `server_command_topic` é o tópico MQTT ao qual o dispositivo irá subscrever para receber comandos para o LED. - -1. Adicione o seguinte código logo acima do loop principal, após a linha `mqtt_client.loop_start()`: - - ```python - def handle_command(client, userdata, message): - payload = json.loads(message.payload.decode()) - print("Message received:", payload) - - if payload['led_on']: - led.on() - else: - led.off() - - mqtt_client.subscribe(server_command_topic) - mqtt_client.on_message = handle_command - ``` - - Este código define uma função, `handle_command`, que lê uma mensagem como um documento JSON e procura o valor da propriedade `led_on`. Se estiver definido como `True`, o LED será ligado; caso contrário, será desligado. - - O cliente MQTT subscreve o tópico no qual o servidor enviará mensagens e define a função `handle_command` para ser chamada quando uma mensagem for recebida. - - > 💁 O handler `on_message` é chamado para todos os tópicos subscritos. Se mais tarde escrever código que escute múltiplos tópicos, pode obter o tópico ao qual a mensagem foi enviada a partir do objeto `message` passado para a função handler. - -1. Execute o código da mesma forma que executou o código da parte anterior da tarefa. Se estiver a usar um dispositivo IoT virtual, certifique-se de que a aplicação CounterFit está a funcionar e que o sensor de luz e o LED foram criados nos pinos corretos. - -1. Ajuste os níveis de luz detetados pelo seu dispositivo físico ou virtual. As mensagens recebidas e os comandos enviados serão escritos no terminal. O LED também será ligado e desligado dependendo do nível de luz. - -> 💁 Pode encontrar este código na pasta [code-commands/virtual-device](../../../../../1-getting-started/lessons/4-connect-internet/code-commands/virtual-device) ou na pasta [code-commands/pi](../../../../../1-getting-started/lessons/4-connect-internet/code-commands/pi). - -😀 Conseguiu programar o seu dispositivo para responder a comandos de um broker MQTT com sucesso. - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos pela precisão, esteja ciente de que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes do uso desta tradução. \ No newline at end of file diff --git a/translations/pt/1-getting-started/lessons/4-connect-internet/single-board-computer-mqtt.md b/translations/pt/1-getting-started/lessons/4-connect-internet/single-board-computer-mqtt.md deleted file mode 100644 index 3ab383ea3..000000000 --- a/translations/pt/1-getting-started/lessons/4-connect-internet/single-board-computer-mqtt.md +++ /dev/null @@ -1,91 +0,0 @@ - -# Controle a sua luz de presença pela Internet - Hardware IoT Virtual e Raspberry Pi - -O dispositivo IoT precisa ser programado para comunicar-se com *test.mosquitto.org* usando MQTT, a fim de enviar valores de telemetria com a leitura do sensor de luz e receber comandos para controlar o LED. - -Nesta parte da lição, irá ligar o seu Raspberry Pi ou dispositivo IoT virtual a um broker MQTT. - -## Instalar o pacote cliente MQTT - -Para comunicar-se com o broker MQTT, é necessário instalar uma biblioteca MQTT através do pacote pip, seja no seu Pi ou no ambiente virtual, caso esteja a usar um dispositivo virtual. - -### Tarefa - -Instale o pacote pip - -1. Abra o projeto da luz de presença no VS Code. - -1. Se estiver a usar um dispositivo IoT virtual, certifique-se de que o terminal está a executar o ambiente virtual. Se estiver a usar um Raspberry Pi, não estará a usar um ambiente virtual. - -1. Execute o seguinte comando para instalar o pacote pip MQTT: - - ```sh - pip3 install paho-mqtt - ``` - -## Programar o dispositivo - -O dispositivo está pronto para ser programado. - -### Tarefa - -Escreva o código do dispositivo. - -1. Adicione a seguinte importação no início do ficheiro `app.py`: - - ```python - import paho.mqtt.client as mqtt - ``` - - A biblioteca `paho.mqtt.client` permite que a sua aplicação comunique via MQTT. - -1. Adicione o seguinte código após as definições do sensor de luz e do LED: - - ```python - id = '' - - client_name = id + 'nightlight_client' - ``` - - Substitua `` por um ID único que será usado como o nome deste cliente do dispositivo e, mais tarde, para os tópicos que este dispositivo publica e subscreve. O broker *test.mosquitto.org* é público e usado por muitas pessoas, incluindo outros estudantes a trabalhar nesta tarefa. Ter um nome de cliente MQTT único e nomes de tópicos únicos garante que o seu código não entre em conflito com o de outras pessoas. Também precisará deste ID ao criar o código do servidor mais tarde nesta tarefa. - - > 💁 Pode usar um site como [GUIDGen](https://www.guidgen.com) para gerar um ID único. - - O `client_name` é um nome único para este cliente MQTT no broker. - -1. Adicione o seguinte código abaixo deste novo código para criar um objeto cliente MQTT e conectá-lo ao broker MQTT: - - ```python - mqtt_client = mqtt.Client(client_name) - mqtt_client.connect('test.mosquitto.org') - - mqtt_client.loop_start() - - print("MQTT connected!") - ``` - - Este código cria o objeto cliente, conecta-se ao broker MQTT público e inicia um loop de processamento que é executado numa thread em segundo plano, ouvindo mensagens em quaisquer tópicos subscritos. - -1. Execute o código da mesma forma que executou o código da parte anterior da tarefa. Se estiver a usar um dispositivo IoT virtual, certifique-se de que a aplicação CounterFit está em execução e que o sensor de luz e o LED foram criados nos pinos corretos. - - ```output - (.venv) ➜ nightlight python app.py - MQTT connected! - Light level: 0 - Light level: 0 - ``` - -> 💁 Pode encontrar este código na pasta [code-mqtt/virtual-device](../../../../../1-getting-started/lessons/4-connect-internet/code-mqtt/virtual-device) ou na pasta [code-mqtt/pi](../../../../../1-getting-started/lessons/4-connect-internet/code-mqtt/pi). - -😀 Conseguiu ligar o seu dispositivo a um broker MQTT com sucesso. - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos pela precisão, esteja ciente de que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes do uso desta tradução. \ No newline at end of file diff --git a/translations/pt/1-getting-started/lessons/4-connect-internet/single-board-computer-telemetry.md b/translations/pt/1-getting-started/lessons/4-connect-internet/single-board-computer-telemetry.md deleted file mode 100644 index 9a65242a7..000000000 --- a/translations/pt/1-getting-started/lessons/4-connect-internet/single-board-computer-telemetry.md +++ /dev/null @@ -1,72 +0,0 @@ - -# Controle a sua luz noturna pela Internet - Hardware IoT Virtual e Raspberry Pi - -Nesta parte da lição, irá enviar telemetria com níveis de luz a partir do seu Raspberry Pi ou dispositivo IoT virtual para um broker MQTT. - -## Publicar telemetria - -O próximo passo é criar um documento JSON com telemetria e enviá-lo para o broker MQTT. - -### Tarefa - -Publique telemetria no broker MQTT. - -1. Abra o projeto da luz noturna no VS Code. - -1. Se estiver a usar um dispositivo IoT virtual, certifique-se de que o terminal está a executar o ambiente virtual. Se estiver a usar um Raspberry Pi, não estará a usar um ambiente virtual. - -1. Adicione a seguinte importação ao topo do ficheiro `app.py`: - - ```python - import json - ``` - - A biblioteca `json` é usada para codificar a telemetria como um documento JSON. - -1. Adicione o seguinte após a declaração de `client_name`: - - ```python - client_telemetry_topic = id + '/telemetry' - ``` - - O `client_telemetry_topic` é o tópico MQTT onde o dispositivo irá publicar os níveis de luz. - -1. Substitua o conteúdo do ciclo `while True:` no final do ficheiro pelo seguinte: - - ```python - while True: - light = light_sensor.light - telemetry = json.dumps({'light' : light}) - - print("Sending telemetry ", telemetry) - - mqtt_client.publish(client_telemetry_topic, telemetry) - - time.sleep(5) - ``` - - Este código empacota o nível de luz num documento JSON e publica-o no broker MQTT. Em seguida, faz uma pausa para reduzir a frequência com que as mensagens são enviadas. - -1. Execute o código da mesma forma que executou o código na parte anterior da tarefa. Se estiver a usar um dispositivo IoT virtual, certifique-se de que a aplicação CounterFit está a funcionar e que o sensor de luz e o LED foram criados nos pinos corretos. - - ```output - (.venv) ➜ nightlight python app.py - MQTT connected! - Sending telemetry {"light": 0} - Sending telemetry {"light": 0} - ``` - -> 💁 Pode encontrar este código na pasta [code-telemetry/virtual-device](../../../../../1-getting-started/lessons/4-connect-internet/code-telemetry/virtual-device) ou na pasta [code-telemetry/pi](../../../../../1-getting-started/lessons/4-connect-internet/code-telemetry/pi). - -😀 Conseguiu enviar telemetria a partir do seu dispositivo com sucesso. - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, esteja ciente de que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se uma tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes do uso desta tradução. \ No newline at end of file diff --git a/translations/pt/1-getting-started/lessons/4-connect-internet/wio-terminal-commands.md b/translations/pt/1-getting-started/lessons/4-connect-internet/wio-terminal-commands.md deleted file mode 100644 index ce2572d24..000000000 --- a/translations/pt/1-getting-started/lessons/4-connect-internet/wio-terminal-commands.md +++ /dev/null @@ -1,91 +0,0 @@ - -# Controle a sua luz noturna pela Internet - Wio Terminal - -Nesta parte da lição, irá subscrever-se a comandos enviados de um broker MQTT para o seu Wio Terminal. - -## Subscrever-se a comandos - -O próximo passo é subscrever-se aos comandos enviados pelo broker MQTT e responder a eles. - -### Tarefa - -Subscrever-se a comandos. - -1. Abra o projeto da luz noturna no VS Code. - -1. Adicione o seguinte código ao final do ficheiro `config.h` para definir o nome do tópico para os comandos: - - ```cpp - const string SERVER_COMMAND_TOPIC = ID + "/commands"; - ``` - - O `SERVER_COMMAND_TOPIC` é o tópico ao qual o dispositivo irá subscrever-se para receber comandos para o LED. - -1. Adicione a seguinte linha ao final da função `reconnectMQTTClient` para subscrever-se ao tópico de comandos quando o cliente MQTT for reconectado: - - ```cpp - client.subscribe(SERVER_COMMAND_TOPIC.c_str()); - ``` - -1. Adicione o seguinte código abaixo da função `reconnectMQTTClient`. - - ```cpp - void clientCallback(char *topic, uint8_t *payload, unsigned int length) - { - char buff[length + 1]; - for (int i = 0; i < length; i++) - { - buff[i] = (char)payload[i]; - } - buff[length] = '\0'; - - Serial.print("Message received:"); - Serial.println(buff); - - DynamicJsonDocument doc(1024); - deserializeJson(doc, buff); - JsonObject obj = doc.as(); - - bool led_on = obj["led_on"]; - - if (led_on) - digitalWrite(D0, HIGH); - else - digitalWrite(D0, LOW); - } - ``` - - Esta função será o callback que o cliente MQTT chamará quando receber uma mensagem do servidor. - - A mensagem é recebida como um array de inteiros não assinados de 8 bits, por isso precisa ser convertida para um array de caracteres para ser tratada como texto. - - A mensagem contém um documento JSON, que é decodificado usando a biblioteca ArduinoJson. A propriedade `led_on` do documento JSON é lida e, dependendo do valor, o LED é ligado ou desligado. - -1. Adicione o seguinte código à função `createMQTTClient`: - - ```cpp - client.setCallback(clientCallback); - ``` - - Este código define o `clientCallback` como o callback a ser chamado quando uma mensagem for recebida do broker MQTT. - - > 💁 O handler `clientCallback` é chamado para todos os tópicos subscritos. Se mais tarde escrever código que escute múltiplos tópicos, pode obter o tópico ao qual a mensagem foi enviada a partir do parâmetro `topic` passado para a função callback. - -1. Carregue o código para o seu Wio Terminal e use o Monitor Serial para ver os níveis de luz sendo enviados para o broker MQTT. - -1. Ajuste os níveis de luz detetados pelo seu dispositivo físico ou virtual. Verá mensagens sendo recebidas e comandos sendo enviados no terminal. Também verá o LED sendo ligado e desligado dependendo do nível de luz. - -> 💁 Pode encontrar este código na pasta [code-commands/wio-terminal](../../../../../1-getting-started/lessons/4-connect-internet/code-commands/wio-terminal). - -😀 Conseguiu programar o seu dispositivo para responder a comandos de um broker MQTT. - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, esteja ciente de que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se uma tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes do uso desta tradução. \ No newline at end of file diff --git a/translations/pt/1-getting-started/lessons/4-connect-internet/wio-terminal-mqtt.md b/translations/pt/1-getting-started/lessons/4-connect-internet/wio-terminal-mqtt.md deleted file mode 100644 index 0f366aa25..000000000 --- a/translations/pt/1-getting-started/lessons/4-connect-internet/wio-terminal-mqtt.md +++ /dev/null @@ -1,249 +0,0 @@ - -# Controle a sua luz noturna pela Internet - Wio Terminal - -O dispositivo IoT precisa ser programado para comunicar-se com *test.mosquitto.org* usando MQTT, enviando valores de telemetria com a leitura do sensor de luz e recebendo comandos para controlar o LED. - -Nesta parte da lição, irá conectar o seu Wio Terminal a um broker MQTT. - -## Instalar as bibliotecas WiFi e MQTT para Arduino - -Para comunicar-se com o broker MQTT, é necessário instalar algumas bibliotecas Arduino para utilizar o chip WiFi do Wio Terminal e comunicar-se com MQTT. Ao desenvolver para dispositivos Arduino, pode usar uma ampla gama de bibliotecas que contêm código de código aberto e implementam uma enorme variedade de funcionalidades. A Seeed publica bibliotecas para o Wio Terminal que permitem a comunicação via WiFi. Outros desenvolvedores publicaram bibliotecas para comunicação com brokers MQTT, e irá utilizar estas com o seu dispositivo. - -Estas bibliotecas são fornecidas como código-fonte que pode ser importado automaticamente para o PlatformIO e compilado para o seu dispositivo. Desta forma, as bibliotecas Arduino funcionarão em qualquer dispositivo que suporte o framework Arduino, desde que o dispositivo tenha o hardware específico necessário para essa biblioteca. Algumas bibliotecas, como as bibliotecas WiFi da Seeed, são específicas para determinados hardwares. - -As bibliotecas podem ser instaladas globalmente e compiladas, se necessário, ou em um projeto específico. Para esta tarefa, as bibliotecas serão instaladas no projeto. - -✅ Pode aprender mais sobre gestão de bibliotecas e como encontrar e instalar bibliotecas na [documentação de bibliotecas do PlatformIO](https://docs.platformio.org/en/latest/librarymanager/index.html). - -### Tarefa - instalar as bibliotecas WiFi e MQTT para Arduino - -Instale as bibliotecas Arduino. - -1. Abra o projeto da luz noturna no VS Code. - -1. Adicione o seguinte ao final do ficheiro `platformio.ini`: - - ```ini - lib_deps = - seeed-studio/Seeed Arduino rpcWiFi @ 1.0.5 - seeed-studio/Seeed Arduino FS @ 2.1.1 - seeed-studio/Seeed Arduino SFUD @ 2.0.2 - seeed-studio/Seeed Arduino rpcUnified @ 2.1.3 - seeed-studio/Seeed_Arduino_mbedtls @ 3.0.1 - ``` - - Isto importa as bibliotecas WiFi da Seeed. A sintaxe `@ ` refere-se a uma versão específica da biblioteca. - - > 💁 Pode remover o `@ ` para sempre usar a versão mais recente das bibliotecas, mas não há garantias de que as versões posteriores funcionarão com o código abaixo. O código aqui foi testado com esta versão das bibliotecas. - - Isto é tudo o que precisa fazer para adicionar as bibliotecas. Na próxima vez que o PlatformIO construir o projeto, ele irá descarregar o código-fonte destas bibliotecas e compilá-lo no seu projeto. - -1. Adicione o seguinte ao `lib_deps`: - - ```ini - knolleary/PubSubClient @ 2.8 - ``` - - Isto importa [PubSubClient](https://github.com/knolleary/pubsubclient), um cliente MQTT para Arduino. - -## Conectar ao WiFi - -O Wio Terminal agora pode ser conectado ao WiFi. - -### Tarefa - conectar ao WiFi - -Conecte o Wio Terminal ao WiFi. - -1. Crie um novo ficheiro na pasta `src` chamado `config.h`. Pode fazer isso selecionando a pasta `src` ou o ficheiro `main.cpp` dentro dela e clicando no botão **Novo ficheiro** no explorador. Este botão só aparece quando o cursor está sobre o explorador. - - ![O botão novo ficheiro](../../../../../translated_images/pt-PT/vscode-new-file-button.182702340fe6723c.webp) - -1. Adicione o seguinte código a este ficheiro para definir constantes para as credenciais do WiFi: - - ```cpp - #pragma once - - #include - - using namespace std; - - // WiFi credentials - const char *SSID = ""; - const char *PASSWORD = ""; - ``` - - Substitua `` pelo SSID do seu WiFi. Substitua `` pela sua palavra-passe do WiFi. - -1. Abra o ficheiro `main.cpp`. - -1. Adicione as seguintes diretivas `#include` ao topo do ficheiro: - - ```cpp - #include - #include - #include - - #include "config.h" - ``` - - Isto inclui ficheiros de cabeçalho para as bibliotecas que adicionou anteriormente, bem como o ficheiro de cabeçalho de configuração. Estes ficheiros de cabeçalho são necessários para informar o PlatformIO a trazer o código das bibliotecas. Sem incluir explicitamente estes ficheiros de cabeçalho, algum código não será compilado e irá obter erros de compilação. - -1. Adicione o seguinte código acima da função `setup`: - - ```cpp - void connectWiFi() - { - while (WiFi.status() != WL_CONNECTED) - { - Serial.println("Connecting to WiFi.."); - WiFi.begin(SSID, PASSWORD); - delay(500); - } - - Serial.println("Connected!"); - } - ``` - - Este código faz um loop enquanto o dispositivo não está conectado ao WiFi e tenta conectar-se usando o SSID e a palavra-passe do ficheiro de cabeçalho de configuração. - -1. Adicione uma chamada a esta função no final da função `setup`, após os pinos terem sido configurados. - - ```cpp - connectWiFi(); - ``` - -1. Carregue este código no seu dispositivo para verificar se a conexão WiFi está a funcionar. Deve ver isto no monitor serial. - - ```output - > Executing task: platformio device monitor < - - --- Available filters and text transformations: colorize, debug, default, direct, hexlify, log2file, nocontrol, printable, send_on_enter, time - --- More details at http://bit.ly/pio-monitor-filters - --- Miniterm on /dev/cu.usbmodem1101 9600,8,N,1 --- - --- Quit: Ctrl+C | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H --- - Connecting to WiFi.. - Connected! - ``` - -## Conectar ao MQTT - -Depois de o Wio Terminal estar conectado ao WiFi, pode conectar-se ao broker MQTT. - -### Tarefa - conectar ao MQTT - -Conecte-se ao broker MQTT. - -1. Adicione o seguinte código ao final do ficheiro `config.h` para definir os detalhes de conexão para o broker MQTT: - - ```cpp - // MQTT settings - const string ID = ""; - - const string BROKER = "test.mosquitto.org"; - const string CLIENT_NAME = ID + "nightlight_client"; - ``` - - Substitua `` por um ID único que será usado como o nome deste cliente do dispositivo e, mais tarde, para os tópicos que este dispositivo publica e subscreve. O broker *test.mosquitto.org* é público e usado por muitas pessoas, incluindo outros estudantes que estão a realizar esta tarefa. Ter um nome único para o cliente MQTT e nomes de tópicos garante que o seu código não entre em conflito com o de outras pessoas. Também irá precisar deste ID ao criar o código do servidor mais tarde nesta tarefa. - - > 💁 Pode usar um site como [GUIDGen](https://www.guidgen.com) para gerar um ID único. - - O `BROKER` é o URL do broker MQTT. - - O `CLIENT_NAME` é um nome único para este cliente MQTT no broker. - -1. Abra o ficheiro `main.cpp` e adicione o seguinte código abaixo da função `connectWiFi` e acima da função `setup`: - - ```cpp - WiFiClient wioClient; - PubSubClient client(wioClient); - ``` - - Este código cria um cliente WiFi usando as bibliotecas WiFi do Wio Terminal e utiliza-o para criar um cliente MQTT. - -1. Abaixo deste código, adicione o seguinte: - - ```cpp - void reconnectMQTTClient() - { - while (!client.connected()) - { - Serial.print("Attempting MQTT connection..."); - - if (client.connect(CLIENT_NAME.c_str())) - { - Serial.println("connected"); - } - else - { - Serial.print("Retying in 5 seconds - failed, rc="); - Serial.println(client.state()); - - delay(5000); - } - } - } - ``` - - Esta função testa a conexão ao broker MQTT e reconecta-se caso não esteja conectado. Faz um loop enquanto não está conectado e tenta conectar-se usando o nome único do cliente definido no ficheiro de cabeçalho de configuração. - - Se a conexão falhar, tenta novamente após 5 segundos. - -1. Adicione o seguinte código abaixo da função `reconnectMQTTClient`: - - ```cpp - void createMQTTClient() - { - client.setServer(BROKER.c_str(), 1883); - reconnectMQTTClient(); - } - ``` - - Este código define o broker MQTT para o cliente, bem como configura o callback para quando uma mensagem for recebida. Em seguida, tenta conectar-se ao broker. - -1. Chame a função `createMQTTClient` na função `setup` após o WiFi estar conectado. - -1. Substitua toda a função `loop` pelo seguinte: - - ```cpp - void loop() - { - reconnectMQTTClient(); - client.loop(); - - delay(2000); - } - ``` - - Este código começa por reconectar-se ao broker MQTT. Estas conexões podem ser facilmente interrompidas, por isso vale a pena verificar regularmente e reconectar-se, se necessário. Em seguida, chama o método `loop` no cliente MQTT para processar quaisquer mensagens que estejam a chegar no tópico subscrito. Esta aplicação é single-threaded, então as mensagens não podem ser recebidas numa thread em segundo plano; portanto, é necessário alocar tempo na thread principal para processar quaisquer mensagens que estejam a aguardar na conexão de rede. - - Finalmente, um atraso de 2 segundos garante que os níveis de luz não sejam enviados com muita frequência e reduz o consumo de energia do dispositivo. - -1. Carregue o código no seu Wio Terminal e use o Monitor Serial para ver o dispositivo conectar-se ao WiFi e ao MQTT. - - ```output - > Executing task: platformio device monitor < - - source /Users/jimbennett/GitHub/IoT-For-Beginners/1-getting-started/lessons/4-connect-internet/code-mqtt/wio-terminal/nightlight/.venv/bin/activate - --- Available filters and text transformations: colorize, debug, default, direct, hexlify, log2file, nocontrol, printable, send_on_enter, time - --- More details at http://bit.ly/pio-monitor-filters - --- Miniterm on /dev/cu.usbmodem1201 9600,8,N,1 --- - --- Quit: Ctrl+C | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H --- - Connecting to WiFi.. - Connected! - Attempting MQTT connection...connected - ``` - -> 💁 Pode encontrar este código na pasta [code-mqtt/wio-terminal](../../../../../1-getting-started/lessons/4-connect-internet/code-mqtt/wio-terminal). - -😀 Conseguiu conectar o seu dispositivo a um broker MQTT com sucesso. - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, tenha em atenção que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes da utilização desta tradução. \ No newline at end of file diff --git a/translations/pt/1-getting-started/lessons/4-connect-internet/wio-terminal-telemetry.md b/translations/pt/1-getting-started/lessons/4-connect-internet/wio-terminal-telemetry.md deleted file mode 100644 index 7cd895f96..000000000 --- a/translations/pt/1-getting-started/lessons/4-connect-internet/wio-terminal-telemetry.md +++ /dev/null @@ -1,91 +0,0 @@ - -# Controle a sua luz noturna pela Internet - Wio Terminal - -Nesta parte da lição, irá enviar telemetria com os níveis de luz do seu Wio Terminal para o broker MQTT. - -## Instalar as bibliotecas JSON para Arduino - -Uma forma popular de enviar mensagens através do MQTT é utilizando JSON. Existe uma biblioteca Arduino para JSON que facilita a leitura e escrita de documentos JSON. - -### Tarefa - -Instale a biblioteca Arduino JSON. - -1. Abra o projeto da luz noturna no VS Code. - -1. Adicione a seguinte linha adicional à lista `lib_deps` no ficheiro `platformio.ini`: - - ```ini - bblanchon/ArduinoJson @ 6.17.3 - ``` - - Isto importa a [ArduinoJson](https://arduinojson.org), uma biblioteca JSON para Arduino. - -## Publicar telemetria - -O próximo passo é criar um documento JSON com a telemetria e enviá-lo para o broker MQTT. - -### Tarefa - publicar telemetria - -Publique telemetria no broker MQTT. - -1. Adicione o seguinte código ao final do ficheiro `config.h` para definir o nome do tópico de telemetria para o broker MQTT: - - ```cpp - const string CLIENT_TELEMETRY_TOPIC = ID + "/telemetry"; - ``` - - O `CLIENT_TELEMETRY_TOPIC` é o tópico onde o dispositivo irá publicar os níveis de luz. - -1. Abra o ficheiro `main.cpp`. - -1. Adicione a seguinte diretiva `#include` ao início do ficheiro: - - ```cpp - #include - ``` - -1. Adicione o seguinte código dentro da função `loop`, mesmo antes do `delay`: - - ```cpp - int light = analogRead(WIO_LIGHT); - - DynamicJsonDocument doc(1024); - doc["light"] = light; - - string telemetry; - serializeJson(doc, telemetry); - - Serial.print("Sending telemetry "); - Serial.println(telemetry.c_str()); - - client.publish(CLIENT_TELEMETRY_TOPIC.c_str(), telemetry.c_str()); - ``` - - Este código lê o nível de luz e cria um documento JSON utilizando a ArduinoJson com este nível. Depois, este é serializado para uma string e publicado no tópico de telemetria MQTT pelo cliente MQTT. - -1. Carregue o código para o seu Wio Terminal e utilize o Monitor Serial para ver os níveis de luz a serem enviados para o broker MQTT. - - ```output - Connecting to WiFi.. - Connected! - Attempting MQTT connection...connected - Sending telemetry {"light":652} - Sending telemetry {"light":612} - Sending telemetry {"light":583} - ``` - -> 💁 Pode encontrar este código na pasta [code-telemetry/wio-terminal](../../../../../1-getting-started/lessons/4-connect-internet/code-telemetry/wio-terminal). - -😀 Conseguiu enviar telemetria com sucesso a partir do seu dispositivo. - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, tenha em atenção que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes da utilização desta tradução. \ No newline at end of file diff --git a/translations/pt/2-farm/README.md b/translations/pt/2-farm/README.md deleted file mode 100644 index 8b871590e..000000000 --- a/translations/pt/2-farm/README.md +++ /dev/null @@ -1,32 +0,0 @@ - -# Agricultura com IoT - -À medida que a população cresce, também aumenta a pressão sobre a agricultura. A quantidade de terra disponível não muda, mas o clima sim - trazendo ainda mais desafios para os agricultores, especialmente os 2 mil milhões de [agricultores de subsistência](https://wikipedia.org/wiki/Subsistence_agriculture) que dependem do que cultivam para se alimentarem e sustentarem as suas famílias. A IoT pode ajudar os agricultores a tomarem decisões mais inteligentes sobre o que cultivar e quando colher, aumentar a produtividade, reduzir o trabalho manual e detetar e lidar com pragas. - -Nestes 6 módulos, vais aprender como aplicar a Internet das Coisas para melhorar e automatizar a agricultura. - -> 💁 Estes módulos irão utilizar alguns recursos na cloud. Se não completares todas as lições deste projeto, certifica-te de que [limpas o teu projeto](../clean-up.md). - -## Tópicos - -1. [Prever o crescimento das plantas com IoT](lessons/1-predict-plant-growth/README.md) -1. [Detetar a humidade do solo](lessons/2-detect-soil-moisture/README.md) -1. [Rega automatizada de plantas](lessons/3-automated-plant-watering/README.md) -1. [Migrar a tua planta para a cloud](lessons/4-migrate-your-plant-to-the-cloud/README.md) -1. [Migrar a lógica da tua aplicação para a cloud](lessons/5-migrate-application-to-the-cloud/README.md) -1. [Manter a tua planta segura](lessons/6-keep-your-plant-secure/README.md) - -## Créditos - -Todas as lições foram escritas com ♥️ por [Jim Bennett](https://GitHub.com/JimBobBennett) - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos pela precisão, esteja ciente de que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes do uso desta tradução. \ No newline at end of file diff --git a/translations/pt/2-farm/lessons/1-predict-plant-growth/README.md b/translations/pt/2-farm/lessons/1-predict-plant-growth/README.md deleted file mode 100644 index 8afbc61e9..000000000 --- a/translations/pt/2-farm/lessons/1-predict-plant-growth/README.md +++ /dev/null @@ -1,145 +0,0 @@ - -# Prever o crescimento das plantas com IoT - -![Uma visão geral ilustrada desta lição](../../../../../translated_images/pt-PT/lesson-5.42b234299279d263143148b88ab4583861a32ddb03110c6c1120e41bb88b2592.jpg) - -> Ilustração por [Nitya Narasimhan](https://github.com/nitya). Clique na imagem para uma versão maior. - -## Questionário pré-aula - -[Questionário pré-aula](https://black-meadow-040d15503.1.azurestaticapps.net/quiz/9) - -## Introdução - -As plantas precisam de certos elementos para crescer - água, dióxido de carbono, nutrientes, luz e calor. Nesta lição, vais aprender a calcular as taxas de crescimento e maturação das plantas medindo a temperatura do ar. - -Nesta lição, vamos abordar: - -* [Agricultura digital](../../../../../2-farm/lessons/1-predict-plant-growth) -* [Por que a temperatura é importante na agricultura?](../../../../../2-farm/lessons/1-predict-plant-growth) -* [Medir a temperatura ambiente](../../../../../2-farm/lessons/1-predict-plant-growth) -* [Dias de grau de crescimento (GDD)](../../../../../2-farm/lessons/1-predict-plant-growth) -* [Calcular GDD usando dados de sensores de temperatura](../../../../../2-farm/lessons/1-predict-plant-growth) - -## Agricultura digital - -A Agricultura Digital está a transformar a forma como cultivamos, utilizando ferramentas para recolher, armazenar e analisar dados agrícolas. Estamos atualmente num período descrito como a 'Quarta Revolução Industrial' pelo Fórum Económico Mundial, e o surgimento da agricultura digital tem sido apelidado de 'Quarta Revolução Agrícola', ou 'Agricultura 4.0'. - -> 🎓 O termo Agricultura Digital também inclui toda a 'cadeia de valor agrícola', ou seja, todo o percurso desde a quinta até à mesa. Inclui o rastreio da qualidade dos produtos enquanto são transportados e processados, sistemas de armazém e comércio eletrónico, até mesmo aplicações para aluguer de tratores! - -Estas mudanças permitem aos agricultores aumentar a produtividade, usar menos fertilizantes e pesticidas, e gerir a água de forma mais eficiente. Embora seja usada principalmente em países mais ricos, os sensores e outros dispositivos estão gradualmente a reduzir de preço, tornando-se mais acessíveis em países em desenvolvimento. - -Algumas técnicas possibilitadas pela agricultura digital são: - -* Medição de temperatura - medir a temperatura permite aos agricultores prever o crescimento e a maturação das plantas. -* Rega automatizada - medir a humidade do solo e ativar os sistemas de irrigação quando o solo está demasiado seco, em vez de regar em horários fixos. A rega programada pode levar a que as culturas fiquem sub-regadas durante um período quente e seco, ou sobre-regadas durante a chuva. Ao regar apenas quando o solo precisa, os agricultores podem otimizar o uso da água. -* Controlo de pragas - os agricultores podem usar câmaras em robôs automatizados ou drones para verificar a presença de pragas e aplicar pesticidas apenas onde for necessário, reduzindo a quantidade de pesticidas usados e o escoamento de pesticidas para os recursos hídricos locais. - -✅ Faz uma pesquisa. Que outras técnicas são usadas para melhorar os rendimentos agrícolas? - -> 🎓 O termo 'Agricultura de Precisão' é usado para definir a observação, medição e resposta às culturas numa base por campo, ou até mesmo em partes de um campo. Isto inclui medir os níveis de água, nutrientes e pragas e responder de forma precisa, como regar apenas uma pequena parte de um campo. - -## Por que a temperatura é importante na agricultura? - -Ao aprender sobre plantas, a maioria dos alunos é ensinada sobre a necessidade de água, luz, dióxido de carbono e nutrientes. As plantas também precisam de calor para crescer - é por isso que florescem na primavera, quando a temperatura aumenta, porque os narcisos ou campainhas podem brotar cedo devido a um curto período de calor, e porque as estufas e casas de vegetação são tão eficazes para o crescimento das plantas. - -> 🎓 As casas de vegetação e as estufas têm funções semelhantes, mas com uma diferença importante. As casas de vegetação são aquecidas artificialmente e permitem aos agricultores controlar as temperaturas com mais precisão, enquanto as estufas dependem do sol para o calor e geralmente o único controlo são janelas ou outras aberturas para deixar o calor sair. - -As plantas têm uma temperatura base ou mínima, uma temperatura ótima e uma temperatura máxima, todas baseadas nas temperaturas médias diárias. - -* Temperatura base - esta é a temperatura média diária mínima necessária para que uma planta cresça. -* Temperatura ótima - esta é a melhor temperatura média diária para obter o maior crescimento. -* Temperatura máxima - esta é a temperatura máxima que uma planta pode suportar. Acima disso, a planta interrompe o crescimento numa tentativa de conservar água e sobreviver. - -> 💁 Estas são temperaturas médias, calculadas a partir das temperaturas diurnas e noturnas. As plantas também precisam de temperaturas diferentes durante o dia e a noite para ajudar na fotossíntese de forma mais eficiente e poupar energia à noite. - -Cada espécie de planta tem valores diferentes para a sua temperatura base, ótima e máxima. É por isso que algumas plantas prosperam em países quentes e outras em países mais frios. - -✅ Faz uma pesquisa. Para qualquer planta que tenhas no teu jardim, escola ou parque local, vê se consegues encontrar a temperatura base. - -![Um gráfico mostrando a taxa de crescimento a aumentar com a temperatura, depois a cair quando a temperatura fica demasiado alta](../../../../../translated_images/pt-PT/plant-growth-temp-graph.c6d69c9478e6ca83.webp) - -O gráfico acima mostra um exemplo de taxa de crescimento em relação à temperatura. Até à temperatura base, não há crescimento. A taxa de crescimento aumenta até à temperatura ótima e depois diminui após atingir este pico. Na temperatura máxima, o crescimento para. - -A forma deste gráfico varia de espécie para espécie. Algumas têm quedas mais acentuadas acima da temperatura ótima, outras têm aumentos mais lentos da base até à ótima. - -> 💁 Para que um agricultor obtenha o melhor crescimento, ele precisará de conhecer os três valores de temperatura e entender a forma dos gráficos para as plantas que está a cultivar. - -Se um agricultor tiver controlo sobre a temperatura, por exemplo, numa casa de vegetação comercial, ele pode otimizar para as suas plantas. Uma casa de vegetação comercial que cultiva tomates, por exemplo, terá a temperatura ajustada para cerca de 25°C durante o dia e 20°C à noite para obter o crescimento mais rápido. - -> 🍅 Combinando estas temperaturas com luzes artificiais, fertilizantes e níveis controlados de CO -Este código abre o ficheiro CSV e adiciona uma nova linha no final. A linha contém a data e hora atual formatadas de forma legível, seguidas pela temperatura recebida do dispositivo IoT. Os dados são armazenados no [formato ISO 8601](https://wikipedia.org/wiki/ISO_8601) com o fuso horário, mas sem os microsegundos. - -1. Execute este código da mesma forma que antes, certificando-se de que o seu dispositivo IoT está a enviar dados. Um ficheiro CSV chamado `temperature.csv` será criado na mesma pasta. Se o abrir, verá datas/horas e medições de temperatura: - - ```output - date,temperature - 2021-04-19T17:21:36-07:00,25 - 2021-04-19T17:31:36-07:00,24 - 2021-04-19T17:41:36-07:00,25 - ``` - -1. Execute este código durante algum tempo para capturar dados. Idealmente, deve executá-lo durante um dia inteiro para recolher dados suficientes para os cálculos de GDD. - - -> 💁 Se estiver a usar um Dispositivo IoT Virtual, selecione a caixa de verificação aleatória e defina um intervalo para evitar obter sempre a mesma temperatura quando o valor da temperatura for retornado. - ![Selecione a caixa de verificação aleatória e defina um intervalo](../../../../../translated_images/pt-PT/select-the-random-checkbox-and-set-a-range.32cf4bc7c12e797f.webp) - - > 💁 Se quiser executar isto durante um dia inteiro, então precisa de garantir que o computador onde o código do servidor está a correr não entra em modo de suspensão, seja alterando as definições de energia ou executando algo como [este script Python para manter o sistema ativo](https://github.com/jaqsparow/keep-system-active). - -> 💁 Pode encontrar este código na pasta [code-server/temperature-sensor-server](../../../../../2-farm/lessons/1-predict-plant-growth/code-server/temperature-sensor-server). - -### Tarefa - calcular GDD usando os dados armazenados - -Depois de o servidor ter capturado os dados de temperatura, o GDD para uma planta pode ser calculado. - -Os passos para fazer isto manualmente são: - -1. Descubra a temperatura base para a planta. Por exemplo, para morangos a temperatura base é 10°C. - -1. No ficheiro `temperature.csv`, encontre as temperaturas mais altas e mais baixas do dia. - -1. Use o cálculo de GDD dado anteriormente para calcular o GDD. - -Por exemplo, se a temperatura mais alta do dia for 25°C e a mais baixa for 12°C: - -![GDD = 25 + 12 dividido por 2, depois subtraia 10 do resultado, obtendo 8.5](../../../../../translated_images/pt-PT/gdd-calculation-strawberries.59f57db94b22adb8ff6efb951ace33af104a1c6ccca3ffb0f8169c14cb160c90.png) - -* 25 + 12 = 37 -* 37 / 2 = 18.5 -* 18.5 - 10 = 8.5 - -Portanto, os morangos receberam **8.5** GDD. Os morangos precisam de cerca de 250 GDD para dar frutos, então ainda falta algum tempo. - ---- - -## 🚀 Desafio - -As plantas precisam de mais do que calor para crescer. Que outras coisas são necessárias? - -Para estas, descubra se existem sensores que podem medi-las. E quanto a atuadores para controlar esses níveis? Como poderia montar um ou mais dispositivos IoT para otimizar o crescimento das plantas? - -## Questionário pós-aula - -[Questionário pós-aula](https://black-meadow-040d15503.1.azurestaticapps.net/quiz/10) - -## Revisão & Autoestudo - -* Leia mais sobre agricultura digital na [página da Wikipedia sobre Agricultura Digital](https://wikipedia.org/wiki/Digital_agriculture). Leia também mais sobre agricultura de precisão na [página da Wikipedia sobre Agricultura de Precisão](https://wikipedia.org/wiki/Precision_agriculture). -* O cálculo completo dos graus-dia de crescimento é mais complicado do que o simplificado apresentado aqui. Leia mais sobre a equação mais complexa e como lidar com temperaturas abaixo do limite na [página da Wikipedia sobre Graus-Dia de Crescimento](https://wikipedia.org/wiki/Growing_degree-day). -* A comida pode ser escassa no futuro se continuarmos a usar os mesmos métodos de cultivo. Saiba mais sobre técnicas de agricultura de alta tecnologia neste [vídeo sobre Fazendas Hi-Tech do Futuro no YouTube](https://www.youtube.com/watch?v=KIEOuKD9KX8). - -## Trabalho - -[Visualizar dados de GDD usando um Jupyter Notebook](assignment.md) - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, esteja ciente de que traduções automáticas podem conter erros ou imprecisões. O documento original no seu idioma nativo deve ser considerado a fonte autoritativa. Para informações críticas, recomenda-se uma tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas resultantes do uso desta tradução. \ No newline at end of file diff --git a/translations/pt/2-farm/lessons/1-predict-plant-growth/assignment.md b/translations/pt/2-farm/lessons/1-predict-plant-growth/assignment.md deleted file mode 100644 index 1bd6dc979..000000000 --- a/translations/pt/2-farm/lessons/1-predict-plant-growth/assignment.md +++ /dev/null @@ -1,55 +0,0 @@ - -# Visualizar dados de GDD usando um Jupyter Notebook - -## Instruções - -Nesta lição, recolheste dados de GDD utilizando um sensor IoT. Para obter bons dados de GDD, é necessário recolher dados durante vários dias. Para ajudar a visualizar os dados de temperatura e calcular o GDD, podes usar ferramentas como [Jupyter Notebooks](https://jupyter.org) para analisar os dados. - -Começa por recolher dados durante alguns dias. Terás de garantir que o código do teu servidor está a funcionar durante todo o tempo em que o dispositivo IoT estiver ativo, ajustando as definições de gestão de energia ou executando algo como [este script Python para manter o sistema ativo](https://github.com/jaqsparow/keep-system-active). - -Depois de teres os dados de temperatura, podes usar o Jupyter Notebook neste repositório para visualizá-los e calcular o GDD. Os Jupyter Notebooks misturam código e instruções em blocos chamados *células*, frequentemente com código em Python. Podes ler as instruções e executar cada bloco de código, um de cada vez. Também podes editar o código. Neste notebook, por exemplo, podes editar a temperatura base usada para calcular o GDD para a tua planta. - -1. Cria uma pasta chamada `gdd-calculation` - -1. Faz o download do ficheiro [gdd.ipynb](../../../../../2-farm/lessons/1-predict-plant-growth/code-notebook/gdd.ipynb) e copia-o para a pasta `gdd-calculation`. - -1. Copia o ficheiro `temperature.csv` criado pelo servidor MQTT. - -1. Cria um novo ambiente virtual Python na pasta `gdd-calculation`. - -1. Instala alguns pacotes pip para Jupyter Notebooks, juntamente com bibliotecas necessárias para gerir e visualizar os dados: - - ```sh - pip install --upgrade pip - pip install pandas - pip install matplotlib - pip install jupyter - ``` - -1. Executa o notebook no Jupyter: - - ```sh - jupyter notebook gdd.ipynb - ``` - - O Jupyter será iniciado e abrirá o notebook no teu navegador. Segue as instruções no notebook para visualizar as temperaturas medidas e calcular os graus-dia de crescimento. - - ![O Jupyter Notebook](../../../../../translated_images/pt-PT/gdd-jupyter-notebook.c5b52cf21094f158a61f47f455490fd95f1729777ff90861a4521820bf354cdc.png) - -## Rubrica - -| Critério | Exemplar | Adequado | Necessita de Melhorias | -| -------- | --------- | -------- | ---------------------- | -| Recolher dados | Recolher pelo menos 2 dias completos de dados | Recolher pelo menos 1 dia completo de dados | Recolher alguns dados | -| Calcular GDD | Executar o notebook com sucesso e calcular o GDD | Executar o notebook com sucesso | Não conseguir executar o notebook | - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos pela precisão, esteja ciente de que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes do uso desta tradução. \ No newline at end of file diff --git a/translations/pt/2-farm/lessons/1-predict-plant-growth/code-notebook/gdd.ipynb b/translations/pt/2-farm/lessons/1-predict-plant-growth/code-notebook/gdd.ipynb deleted file mode 100644 index 885a60ca8..000000000 --- a/translations/pt/2-farm/lessons/1-predict-plant-growth/code-notebook/gdd.ipynb +++ /dev/null @@ -1,167 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Dias de Grau de Crescimento\n", - "\n", - "Este notebook carrega dados de temperatura guardados num ficheiro CSV e analisa-os. Ele apresenta os gráficos das temperaturas, mostra os valores mais altos e mais baixos de cada dia, e calcula o GDD.\n", - "\n", - "Para utilizar este notebook:\n", - "\n", - "* Copie o ficheiro `temperature.csv` para a mesma pasta deste notebook\n", - "* Execute todas as células utilizando o botão **▶︎ Run** acima. Isto irá executar a célula selecionada e, em seguida, passar para a próxima.\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Na célula abaixo, defina `base_temperature` para a temperatura base da planta.\n" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "base_temperature = 10" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "O ficheiro CSV agora precisa de ser carregado, utilizando pandas\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "import matplotlib.pyplot as plt\n", - "\n", - "# Read the temperature CSV file\n", - "df = pd.read_csv('temperature.csv')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "plt.figure(figsize=(20, 10))\n", - "plt.plot(df['date'], df['temperature'])\n", - "plt.xticks(rotation='vertical');" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Depois de os dados serem lidos, podem ser agrupados pela coluna `date`, e as temperaturas mínima e máxima extraídas para cada data.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Convert datetimes to pure dates so we can group by the date\n", - "df['date'] = pd.to_datetime(df['date']).dt.date\n", - "\n", - "# Group the data by date so it can be analyzed by date\n", - "data_by_date = df.groupby('date')\n", - "\n", - "# Get the minimum and maximum temperatures for each date\n", - "min_by_date = data_by_date.min()\n", - "max_by_date = data_by_date.max()\n", - "\n", - "# Join the min and max temperatures into one dataframe and flatten it\n", - "min_max_by_date = min_by_date.join(max_by_date, on='date', lsuffix='_min', rsuffix='_max')\n", - "min_max_by_date = min_max_by_date.reset_index()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "O GDD pode ser calculado usando a equação padrão de GDD\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def calculate_gdd(row):\n", - " return ((row['temperature_max'] + row['temperature_min']) / 2) - base_temperature\n", - "\n", - "# Calculate the GDD for each row\n", - "min_max_by_date['gdd'] = min_max_by_date.apply (lambda row: calculate_gdd(row), axis=1)\n", - "\n", - "# Print the results\n", - "print(min_max_by_date[['date', 'gdd']].to_string(index=False))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n---\n\n**Aviso**: \nEste documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos pela precisão, é importante notar que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se uma tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes da utilização desta tradução.\n" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.9.1" - }, - "metadata": { - "interpreter": { - "hash": "aee8b7b246df8f9039afb4144a1f6fd8d2ca17a180786b69acc140d282b71a49" - } - }, - "coopTranslator": { - "original_hash": "8fcf954f6042f0bf3601a2c836a09574", - "translation_date": "2025-08-26T15:59:17+00:00", - "source_file": "2-farm/lessons/1-predict-plant-growth/code-notebook/gdd.ipynb", - "language_code": "pt" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/translations/pt/2-farm/lessons/1-predict-plant-growth/pi-temp.md b/translations/pt/2-farm/lessons/1-predict-plant-growth/pi-temp.md deleted file mode 100644 index 89a70e36d..000000000 --- a/translations/pt/2-farm/lessons/1-predict-plant-growth/pi-temp.md +++ /dev/null @@ -1,123 +0,0 @@ - -# Medir a temperatura - Raspberry Pi - -Nesta parte da lição, vais adicionar um sensor de temperatura ao teu Raspberry Pi. - -## Hardware - -O sensor que vais utilizar é um [sensor de humidade e temperatura DHT11](https://www.seeedstudio.com/Grove-Temperature-Humidity-Sensor-DHT11.html), que combina 2 sensores num único dispositivo. Este sensor é bastante popular, com vários modelos disponíveis comercialmente que combinam temperatura, humidade e, por vezes, pressão atmosférica. O componente de temperatura é um termistor de coeficiente de temperatura negativo (NTC), ou seja, um termistor cuja resistência diminui à medida que a temperatura aumenta. - -Este é um sensor digital, pelo que possui um ADC integrado para criar um sinal digital contendo os dados de temperatura e humidade que o microcontrolador pode ler. - -### Ligar o sensor de temperatura - -O sensor de temperatura Grove pode ser ligado ao Raspberry Pi. - -#### Tarefa - -Liga o sensor de temperatura. - -![Um sensor de temperatura Grove](../../../../../translated_images/pt-PT/grove-dht11.07f8eafceee170043efbb53e1d15722bd4e00fbaa9ff74290b57e9f66eb82c17.png) - -1. Insere uma extremidade de um cabo Grove na entrada do sensor de humidade e temperatura. O cabo só encaixa de uma forma. - -1. Com o Raspberry Pi desligado, liga a outra extremidade do cabo Grove à entrada digital marcada como **D5** no Grove Base Hat conectado ao Pi. Esta entrada é a segunda a contar da esquerda, na fila de entradas ao lado dos pinos GPIO. - -![O sensor de temperatura Grove ligado à entrada A0](../../../../../translated_images/pt-PT/pi-temperature-sensor.3ff82fff672c8e56.webp) - -## Programar o sensor de temperatura - -Agora o dispositivo pode ser programado para utilizar o sensor de temperatura conectado. - -### Tarefa - -Programa o dispositivo. - -1. Liga o Pi e espera que ele inicie. - -1. Abre o VS Code, diretamente no Pi ou através da extensão Remote SSH. - - > ⚠️ Podes consultar [as instruções para configurar e abrir o VS Code na lição 1, se necessário](../../../1-getting-started/lessons/1-introduction-to-iot/pi.md). - -1. No terminal, cria uma nova pasta no diretório home do utilizador `pi` chamada `temperature-sensor`. Cria um ficheiro nesta pasta chamado `app.py`: - - ```sh - mkdir temperature-sensor - cd temperature-sensor - touch app.py - ``` - -1. Abre esta pasta no VS Code. - -1. Para utilizar o sensor de temperatura e humidade, é necessário instalar um pacote adicional do Pip. No Terminal do VS Code, executa o seguinte comando para instalar este pacote no Pi: - - ```sh - pip3 install seeed-python-dht - ``` - -1. Adiciona o seguinte código ao ficheiro `app.py` para importar as bibliotecas necessárias: - - ```python - import time - from seeed_dht import DHT - ``` - - A instrução `from seeed_dht import DHT` importa a classe `DHT` para interagir com um sensor de temperatura Grove do módulo `seeed_dht`. - -1. Adiciona o seguinte código após o código acima para criar uma instância da classe que gere o sensor de temperatura: - - ```python - sensor = DHT("11", 5) - ``` - - Isto declara uma instância da classe `DHT` que gere o sensor digital de humidade e temperatura (**D**igital **H**umidity and **T**emperature). O primeiro parâmetro indica que o sensor utilizado é o *DHT11* - a biblioteca que estás a usar suporta outras variantes deste sensor. O segundo parâmetro indica que o sensor está ligado à entrada digital `D5` no Grove Base Hat. - - > ✅ Lembra-te, todas as entradas têm números de pinos únicos. Os pinos 0, 2, 4 e 6 são pinos analógicos, enquanto os pinos 5, 16, 18, 22, 24 e 26 são pinos digitais. - -1. Adiciona um loop infinito após o código acima para obter o valor do sensor de temperatura e imprimi-lo na consola: - - ```python - while True: - _, temp = sensor.read() - print(f'Temperature {temp}°C') - ``` - - A chamada a `sensor.read()` devolve uma tupla com os valores de humidade e temperatura. Apenas precisas do valor da temperatura, por isso o valor da humidade é ignorado. O valor da temperatura é então impresso na consola. - -1. Adiciona uma pequena pausa de dez segundos no final do `loop`, pois os níveis de temperatura não precisam de ser verificados continuamente. Uma pausa reduz o consumo de energia do dispositivo. - - ```python - time.sleep(10) - ``` - -1. No Terminal do VS Code, executa o seguinte comando para correr a tua aplicação Python: - - ```sh - python3 app.py - ``` - - Deverás ver os valores de temperatura a serem exibidos na consola. Usa algo para aquecer o sensor, como pressionar o polegar sobre ele ou usar um ventilador, para observar as mudanças nos valores: - - ```output - pi@raspberrypi:~/temperature-sensor $ python3 app.py - Temperature 26°C - Temperature 26°C - Temperature 28°C - Temperature 30°C - Temperature 32°C - ``` - -> 💁 Podes encontrar este código na pasta [code-temperature/pi](../../../../../2-farm/lessons/1-predict-plant-growth/code-temperature/pi). - -😀 O teu programa para o sensor de temperatura foi um sucesso! - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, tenha em atenção que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes da utilização desta tradução. \ No newline at end of file diff --git a/translations/pt/2-farm/lessons/1-predict-plant-growth/single-board-computer-temp-publish.md b/translations/pt/2-farm/lessons/1-predict-plant-growth/single-board-computer-temp-publish.md deleted file mode 100644 index 48b5c19e6..000000000 --- a/translations/pt/2-farm/lessons/1-predict-plant-growth/single-board-computer-temp-publish.md +++ /dev/null @@ -1,69 +0,0 @@ - -# Publicar temperatura - Hardware IoT Virtual e Raspberry Pi - -Nesta parte da lição, irá publicar os valores de temperatura detetados pelo Raspberry Pi ou Dispositivo IoT Virtual via MQTT, para que possam ser utilizados posteriormente no cálculo do GDD. - -## Publicar a temperatura - -Depois de ler a temperatura, pode publicá-la via MQTT para algum código 'servidor' que irá ler os valores e armazená-los, prontos para serem usados no cálculo do GDD. - -### Tarefa - publicar a temperatura - -Programe o dispositivo para publicar os dados de temperatura. - -1. Abra o projeto da aplicação `temperature-sensor` caso ainda não esteja aberto. - -1. Repita os passos que realizou na lição 4 para se conectar ao MQTT e enviar telemetria. Irá utilizar o mesmo broker público Mosquitto. - - Os passos para isso são: - - - Adicionar o pacote pip do MQTT - - Adicionar o código para se conectar ao broker MQTT - - Adicionar o código para publicar telemetria - - > ⚠️ Consulte as [instruções para se conectar ao MQTT](../../../1-getting-started/lessons/4-connect-internet/single-board-computer-mqtt.md) e as [instruções para enviar telemetria](../../../1-getting-started/lessons/4-connect-internet/single-board-computer-telemetry.md) da lição 4, se necessário. - -1. Certifique-se de que o `client_name` reflete o nome deste projeto: - - ```python - client_name = id + 'temperature_sensor_client' - ``` - -1. Para a telemetria, em vez de enviar um valor de luz, envie o valor de temperatura lido do sensor DHT numa propriedade do documento JSON chamada `temperature`: - - ```python - _, temp = sensor.read() - telemetry = json.dumps({'temperature' : temp}) - ``` - -1. O valor da temperatura não precisa de ser lido com muita frequência - não irá mudar muito num curto espaço de tempo, por isso defina o `time.sleep` para 10 minutos: - - ```cpp - time.sleep(10 * 60); - ``` - - > 💁 A função `sleep` recebe o tempo em segundos, por isso, para facilitar a leitura, o valor é passado como resultado de um cálculo. 60s num minuto, então 10 x (60s num minuto) dá um atraso de 10 minutos. - -1. Execute o código da mesma forma que executou o código da parte anterior da tarefa. Se estiver a usar um dispositivo IoT virtual, certifique-se de que a aplicação CounterFit está a funcionar e que os sensores de humidade e temperatura foram criados nos pinos corretos. - - ```output - pi@raspberrypi:~/temperature-sensor $ python3 app.py - MQTT connected! - Sending telemetry {"temperature": 25} - Sending telemetry {"temperature": 25} - ``` - -> 💁 Pode encontrar este código na pasta [code-publish-temperature/virtual-device](../../../../../2-farm/lessons/1-predict-plant-growth/code-publish-temperature/virtual-device) ou na pasta [code-publish-temperature/pi](../../../../../2-farm/lessons/1-predict-plant-growth/code-publish-temperature/pi). - -😀 Conseguiu publicar com sucesso a temperatura como telemetria a partir do seu dispositivo. - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos pela precisão, esteja ciente de que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se uma tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes do uso desta tradução. \ No newline at end of file diff --git a/translations/pt/2-farm/lessons/1-predict-plant-growth/virtual-device-temp.md b/translations/pt/2-farm/lessons/1-predict-plant-growth/virtual-device-temp.md deleted file mode 100644 index b88359651..000000000 --- a/translations/pt/2-farm/lessons/1-predict-plant-growth/virtual-device-temp.md +++ /dev/null @@ -1,152 +0,0 @@ - -# Medir temperatura - Hardware Virtual IoT - -Nesta parte da lição, irá adicionar um sensor de temperatura ao seu dispositivo IoT virtual. - -## Hardware Virtual - -O dispositivo IoT virtual utilizará um sensor simulado Grove Digital Humidity and Temperature. Isto mantém este laboratório semelhante ao uso de um Raspberry Pi com um sensor físico Grove DHT11. - -O sensor combina um **sensor de temperatura** com um **sensor de humidade**, mas neste laboratório está apenas interessado no componente do sensor de temperatura. Num dispositivo IoT físico, o sensor de temperatura seria um [termístor](https://wikipedia.org/wiki/Thermistor) que mede a temperatura ao detetar uma mudança na resistência conforme a temperatura varia. Os sensores de temperatura são geralmente sensores digitais que internamente convertem a resistência medida numa temperatura em graus Celsius (ou Kelvin, ou Fahrenheit). - -### Adicionar os sensores ao CounterFit - -Para utilizar um sensor virtual de humidade e temperatura, precisa de adicionar os dois sensores à aplicação CounterFit. - -#### Tarefa - adicionar os sensores ao CounterFit - -Adicione os sensores de humidade e temperatura à aplicação CounterFit. - -1. Crie uma nova aplicação Python no seu computador numa pasta chamada `temperature-sensor` com um único ficheiro chamado `app.py`, um ambiente virtual Python, e adicione os pacotes pip do CounterFit. - - > ⚠️ Pode consultar [as instruções para criar e configurar um projeto Python CounterFit na lição 1, se necessário](../../../1-getting-started/lessons/1-introduction-to-iot/virtual-device.md). - -1. Instale um pacote adicional do Pip para instalar um shim CounterFit para o sensor DHT11. Certifique-se de que está a instalar isto a partir de um terminal com o ambiente virtual ativado. - - ```sh - pip install counterfit-shims-seeed-python-dht - ``` - -1. Certifique-se de que a aplicação web CounterFit está em execução. - -1. Crie um sensor de humidade: - - 1. Na caixa *Create sensor* no painel *Sensors*, abra o menu suspenso *Sensor type* e selecione *Humidity*. - - 1. Deixe as *Units* definidas como *Percentage*. - - 1. Certifique-se de que o *Pin* está definido como *5*. - - 1. Selecione o botão **Add** para criar o sensor de humidade no Pin 5. - - ![As definições do sensor de humidade](../../../../../translated_images/pt-PT/counterfit-create-humidity-sensor.2750e27b6f30e09cf4e22101defd5252710717620816ab41ba688f91f757c49a.png) - - O sensor de humidade será criado e aparecerá na lista de sensores. - - ![O sensor de humidade criado](../../../../../translated_images/pt-PT/counterfit-humidity-sensor.7b12f7f339e430cb26c8211d2dba4ef75261b353a01da0932698b5bebd693f27.png) - -1. Crie um sensor de temperatura: - - 1. Na caixa *Create sensor* no painel *Sensors*, abra o menu suspenso *Sensor type* e selecione *Temperature*. - - 1. Deixe as *Units* definidas como *Celsius*. - - 1. Certifique-se de que o *Pin* está definido como *6*. - - 1. Selecione o botão **Add** para criar o sensor de temperatura no Pin 6. - - ![As definições do sensor de temperatura](../../../../../translated_images/pt-PT/counterfit-create-temperature-sensor.199350ed34f7343d79dccbe95eaf6c11d2121f03d1c35ab9613b330c23f39b29.png) - - O sensor de temperatura será criado e aparecerá na lista de sensores. - - ![O sensor de temperatura criado](../../../../../translated_images/pt-PT/counterfit-temperature-sensor.f0560236c96a9016bafce7f6f792476fe3367bc6941a1f7d5811d144d4bcbfff.png) - -## Programar a aplicação do sensor de temperatura - -A aplicação do sensor de temperatura pode agora ser programada utilizando os sensores do CounterFit. - -### Tarefa - programar a aplicação do sensor de temperatura - -Programe a aplicação do sensor de temperatura. - -1. Certifique-se de que a aplicação `temperature-sensor` está aberta no VS Code. - -1. Abra o ficheiro `app.py`. - -1. Adicione o seguinte código ao topo do `app.py` para ligar a aplicação ao CounterFit: - - ```python - from counterfit_connection import CounterFitConnection - CounterFitConnection.init('127.0.0.1', 5000) - ``` - -1. Adicione o seguinte código ao ficheiro `app.py` para importar as bibliotecas necessárias: - - ```python - import time - from counterfit_shims_seeed_python_dht import DHT - ``` - - A instrução `from seeed_dht import DHT` importa a classe `DHT` para interagir com um sensor virtual Grove de temperatura utilizando um shim do módulo `counterfit_shims_seeed_python_dht`. - -1. Adicione o seguinte código após o código acima para criar uma instância da classe que gere o sensor virtual de humidade e temperatura: - - ```python - sensor = DHT("11", 5) - ``` - - Isto declara uma instância da classe `DHT` que gere o sensor virtual de **H**umidade e **T**emperatura **D**igital. O primeiro parâmetro indica ao código que o sensor utilizado é um sensor virtual *DHT11*. O segundo parâmetro indica ao código que o sensor está ligado à porta `5`. - - > 💁 O CounterFit simula este sensor combinado de humidade e temperatura ao ligar-se a 2 sensores, um sensor de humidade no pino indicado quando a classe `DHT` é criada, e um sensor de temperatura que funciona no pino seguinte. Se o sensor de humidade estiver no pino 5, o shim espera que o sensor de temperatura esteja no pino 6. - -1. Adicione um loop infinito após o código acima para consultar o valor do sensor de temperatura e imprimi-lo no console: - - ```python - while True: - _, temp = sensor.read() - print(f'Temperature {temp}°C') - ``` - - A chamada a `sensor.read()` retorna uma tupla de humidade e temperatura. Apenas precisa do valor da temperatura, por isso a humidade é ignorada. O valor da temperatura é então impresso no console. - -1. Adicione uma pequena pausa de dez segundos no final do `loop`, uma vez que os níveis de temperatura não precisam de ser verificados continuamente. Uma pausa reduz o consumo de energia do dispositivo. - - ```python - time.sleep(10) - ``` - -1. A partir do Terminal do VS Code com um ambiente virtual ativado, execute o seguinte para executar a sua aplicação Python: - - ```sh - python app.py - ``` - -1. Na aplicação CounterFit, altere o valor do sensor de temperatura que será lido pela aplicação. Pode fazer isto de duas formas: - - * Insira um número na caixa *Value* do sensor de temperatura e selecione o botão **Set**. O número que inserir será o valor retornado pelo sensor. - - * Marque a caixa *Random* e insira um valor *Min* e *Max*, depois selecione o botão **Set**. Sempre que o sensor ler um valor, será lido um número aleatório entre *Min* e *Max*. - - Deve ver os valores que definiu aparecerem no console. Altere o *Value* ou as definições *Random* para ver a mudança de valor. - - ```output - (.venv) ➜ temperature-sensor python app.py - Temperature 28.25°C - Temperature 30.71°C - Temperature 25.17°C - ``` - -> 💁 Pode encontrar este código na pasta [code-temperature/virtual-device](../../../../../2-farm/lessons/1-predict-plant-growth/code-temperature/virtual-device). - -😀 O seu programa do sensor de temperatura foi um sucesso! - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos pela precisão, esteja ciente de que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes do uso desta tradução. \ No newline at end of file diff --git a/translations/pt/2-farm/lessons/1-predict-plant-growth/wio-terminal-temp-publish.md b/translations/pt/2-farm/lessons/1-predict-plant-growth/wio-terminal-temp-publish.md deleted file mode 100644 index e08a56fda..000000000 --- a/translations/pt/2-farm/lessons/1-predict-plant-growth/wio-terminal-temp-publish.md +++ /dev/null @@ -1,80 +0,0 @@ - -# Publicar temperatura - Wio Terminal - -Nesta parte da lição, irá publicar os valores de temperatura detetados pelo Wio Terminal através de MQTT, para que possam ser usados mais tarde no cálculo do GDD. - -## Publicar a temperatura - -Depois de ler a temperatura, esta pode ser publicada via MQTT para algum código 'servidor' que irá ler os valores e armazená-los, prontos para serem usados no cálculo do GDD. Os microcontroladores não obtêm a hora da Internet nem acompanham o tempo com um relógio em tempo real por padrão; o dispositivo precisa ser programado para isso, assumindo que possui o hardware necessário. - -Para simplificar as coisas nesta lição, a hora não será enviada com os dados do sensor; em vez disso, pode ser adicionada pelo código do servidor mais tarde, quando este receber as mensagens. - -### Tarefa - -Programar o dispositivo para publicar os dados de temperatura. - -1. Abra o projeto `temperature-sensor` do Wio Terminal. - -1. Repita os passos que realizou na lição 4 para se conectar ao MQTT e enviar telemetria. Irá usar o mesmo broker público Mosquitto. - - Os passos para isso são: - - - Adicionar as bibliotecas Seeed WiFi e MQTT ao ficheiro `.ini` - - Adicionar o ficheiro de configuração e o código para se conectar ao WiFi - - Adicionar o código para se conectar ao broker MQTT - - Adicionar o código para publicar telemetria - - > ⚠️ Consulte as [instruções para se conectar ao MQTT](../../../1-getting-started/lessons/4-connect-internet/wio-terminal-mqtt.md) e as [instruções para enviar telemetria](../../../1-getting-started/lessons/4-connect-internet/wio-terminal-telemetry.md) da lição 4, se necessário. - -1. Certifique-se de que o `CLIENT_NAME` no ficheiro de cabeçalho `config.h` reflete este projeto: - - ```cpp - const string CLIENT_NAME = ID + "temperature_sensor_client"; - ``` - -1. Para a telemetria, em vez de enviar um valor de luz, envie o valor de temperatura lido do sensor DHT numa propriedade do documento JSON chamada `temperature`, alterando a função `loop` no `main.cpp`: - - ```cpp - float temp_hum_val[2] = {0}; - dht.readTempAndHumidity(temp_hum_val); - - DynamicJsonDocument doc(1024); - doc["temperature"] = temp_hum_val[1]; - ``` - -1. O valor da temperatura não precisa de ser lido com muita frequência - não mudará muito num curto espaço de tempo, por isso defina o `delay` na função `loop` para 10 minutos: - - ```cpp - delay(10 * 60 * 1000); - ``` - - > 💁 A função `delay` recebe o tempo em milissegundos, por isso, para facilitar a leitura, o valor é passado como o resultado de um cálculo. 1.000ms num segundo, 60s num minuto, então 10 x (60s num minuto) x (1.000ms num segundo) dá um atraso de 10 minutos. - -1. Carregue este código para o seu Wio Terminal e use o monitor serial para ver a temperatura a ser enviada para o broker MQTT. - - ```output - --- Available filters and text transformations: colorize, debug, default, direct, hexlify, log2file, nocontrol, printable, send_on_enter, time - --- More details at http://bit.ly/pio-monitor-filters - --- Miniterm on /dev/cu.usbmodem1201 9600,8,N,1 --- - --- Quit: Ctrl+C | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H --- - Connecting to WiFi.. - Connected! - Attempting MQTT connection...connected - Sending telemetry {"temperature":25} - Sending telemetry {"temperature":25} - ``` - -> 💁 Pode encontrar este código na pasta [code-publish-temperature/wio-terminal](../../../../../2-farm/lessons/1-predict-plant-growth/code-publish-temperature/wio-terminal). - -😀 Conseguiu publicar com sucesso a temperatura como telemetria a partir do seu dispositivo. - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, é importante notar que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes do uso desta tradução. \ No newline at end of file diff --git a/translations/pt/2-farm/lessons/1-predict-plant-growth/wio-terminal-temp.md b/translations/pt/2-farm/lessons/1-predict-plant-growth/wio-terminal-temp.md deleted file mode 100644 index d6a8f9446..000000000 --- a/translations/pt/2-farm/lessons/1-predict-plant-growth/wio-terminal-temp.md +++ /dev/null @@ -1,141 +0,0 @@ - -# Medir a temperatura - Wio Terminal - -Nesta parte da lição, irá adicionar um sensor de temperatura ao seu Wio Terminal e ler os valores de temperatura a partir dele. - -## Hardware - -O Wio Terminal necessita de um sensor de temperatura. - -O sensor que irá utilizar é um [sensor de humidade e temperatura DHT11](https://www.seeedstudio.com/Grove-Temperature-Humidity-Sensor-DHT11.html), que combina 2 sensores num único dispositivo. Este é bastante popular, com vários sensores comercialmente disponíveis que combinam temperatura, humidade e, por vezes, pressão atmosférica. O componente do sensor de temperatura é um termistor de coeficiente de temperatura negativo (NTC), um termistor cuja resistência diminui à medida que a temperatura aumenta. - -Este é um sensor digital, pelo que possui um ADC integrado para criar um sinal digital contendo os dados de temperatura e humidade que o microcontrolador pode ler. - -### Ligar o sensor de temperatura - -O sensor de temperatura Grove pode ser ligado à porta digital do Wio Terminal. - -#### Tarefa - ligar o sensor de temperatura - -Ligue o sensor de temperatura. - -![Um sensor de temperatura Grove](../../../../../translated_images/pt-PT/grove-dht11.07f8eafceee170043efbb53e1d15722bd4e00fbaa9ff74290b57e9f66eb82c17.png) - -1. Insira uma extremidade de um cabo Grove na entrada do sensor de humidade e temperatura. Só encaixará de uma forma. - -1. Com o Wio Terminal desligado do computador ou de outra fonte de alimentação, ligue a outra extremidade do cabo Grove à entrada Grove do lado direito do Wio Terminal, olhando para o ecrã. Esta é a entrada mais distante do botão de energia. - -![O sensor de temperatura Grove ligado à entrada do lado direito](../../../../../translated_images/pt-PT/wio-temperature-sensor.2934928f38c7f79a.webp) - -## Programar o sensor de temperatura - -O Wio Terminal pode agora ser programado para utilizar o sensor de temperatura ligado. - -### Tarefa - programar o sensor de temperatura - -Programe o dispositivo. - -1. Crie um novo projeto Wio Terminal utilizando o PlatformIO. Chame este projeto `temperature-sensor`. Adicione código na função `setup` para configurar a porta serial. - - > ⚠️ Pode consultar [as instruções para criar um projeto PlatformIO no projeto 1, lição 1, se necessário](../../../1-getting-started/lessons/1-introduction-to-iot/wio-terminal.md#create-a-platformio-project). - -1. Adicione uma dependência de biblioteca para a biblioteca Seeed Grove Humidity and Temperature sensor no ficheiro `platformio.ini` do projeto: - - ```ini - lib_deps = - seeed-studio/Grove Temperature And Humidity Sensor @ 1.0.1 - ``` - - > ⚠️ Pode consultar [as instruções para adicionar bibliotecas a um projeto PlatformIO no projeto 1, lição 4, se necessário](../../../1-getting-started/lessons/4-connect-internet/wio-terminal-mqtt.md#install-the-wifi-and-mqtt-arduino-libraries). - -1. Adicione as seguintes diretivas `#include` ao topo do ficheiro, abaixo do `#include ` existente: - - ```cpp - #include - #include - ``` - - Isto importa os ficheiros necessários para interagir com o sensor. O ficheiro de cabeçalho `DHT.h` contém o código para o próprio sensor, e adicionar o cabeçalho `SPI.h` garante que o código necessário para comunicar com o sensor é incluído quando a aplicação é compilada. - -1. Antes da função `setup`, declare o sensor DHT: - - ```cpp - DHT dht(D0, DHT11); - ``` - - Isto declara uma instância da classe `DHT` que gere o sensor de **H**umidade e **T**emperatura **D**igital. Este está ligado à porta `D0`, a entrada Grove do lado direito do Wio Terminal. O segundo parâmetro informa o código de que o sensor utilizado é o *DHT11* - a biblioteca que está a usar suporta outras variantes deste sensor. - -1. Na função `setup`, adicione código para configurar a ligação serial: - - ```cpp - void setup() - { - Serial.begin(9600); - - while (!Serial) - ; // Wait for Serial to be ready - - delay(1000); - } - ``` - -1. No final da função `setup`, após o último `delay`, adicione uma chamada para iniciar o sensor DHT: - - ```cpp - dht.begin(); - ``` - -1. Na função `loop`, adicione código para chamar o sensor e imprimir a temperatura na porta serial: - - ```cpp - void loop() - { - float temp_hum_val[2] = {0}; - dht.readTempAndHumidity(temp_hum_val); - Serial.print("Temperature: "); - Serial.print(temp_hum_val[1]); - Serial.println ("°C"); - - delay(10000); - } - ``` - - Este código declara um array vazio de 2 floats e passa-o para a chamada `readTempAndHumidity` na instância `DHT`. Esta chamada preenche o array com 2 valores - a humidade é colocada no item 0 do array (lembre-se de que em C++ os arrays começam no índice 0, por isso o item 0 é o 'primeiro' item do array), e a temperatura é colocada no item 1. - - A temperatura é lida a partir do item 1 do array e impressa na porta serial. - - > 🇺🇸 A temperatura é lida em Celsius. Para os americanos, para converter para Fahrenheit, divida o valor em Celsius por 5, depois multiplique por 9 e, por fim, adicione 32. Por exemplo, uma leitura de temperatura de 20°C torna-se ((20/5)*9) + 32 = 68°F. - -1. Compile e carregue o código no Wio Terminal. - - > ⚠️ Pode consultar [as instruções para criar um projeto PlatformIO no projeto 1, lição 1, se necessário](../../../1-getting-started/lessons/1-introduction-to-iot/wio-terminal.md#write-the-hello-world-app). - -1. Depois de carregado, pode monitorizar a temperatura utilizando o monitor serial: - - ```output - > Executing task: platformio device monitor < - - --- Available filters and text transformations: colorize, debug, default, direct, hexlify, log2file, nocontrol, printable, send_on_enter, time - --- More details at http://bit.ly/pio-monitor-filters - --- Miniterm on /dev/cu.usbmodem1201 9600,8,N,1 --- - --- Quit: Ctrl+C | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H --- - Temperature: 25.00°C - Temperature: 25.00°C - Temperature: 25.00°C - Temperature: 24.00°C - ``` - -> 💁 Pode encontrar este código na pasta [code-temperature/wio-terminal](../../../../../2-farm/lessons/1-predict-plant-growth/code-temperature/wio-terminal). - -😀 O programa do sensor de temperatura foi um sucesso! - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, é importante notar que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes da utilização desta tradução. \ No newline at end of file diff --git a/translations/pt/2-farm/lessons/2-detect-soil-moisture/README.md b/translations/pt/2-farm/lessons/2-detect-soil-moisture/README.md deleted file mode 100644 index 9bf257795..000000000 --- a/translations/pt/2-farm/lessons/2-detect-soil-moisture/README.md +++ /dev/null @@ -1,167 +0,0 @@ - -C, pronunciado como *I-quadrado-C*, é um protocolo multi-controlador e multi-periférico, onde qualquer dispositivo conectado pode atuar como controlador ou periférico, comunicando-se através do barramento I²C (o nome para um sistema de comunicação que transfere dados). Os dados são enviados como pacotes endereçados, com cada pacote contendo o endereço do dispositivo conectado ao qual se destinam. - -> 💁 Este modelo costumava ser referido como master/slave, mas essa terminologia está sendo abandonada devido à sua associação com a escravidão. A [Open Source Hardware Association adotou os termos controlador/periférico](https://www.oshwa.org/a-resolution-to-redefine-spi-signal-names/), mas você ainda pode encontrar referências à terminologia antiga. - -Os dispositivos possuem um endereço que é usado quando se conectam ao barramento I²C, e geralmente é codificado no próprio dispositivo. Por exemplo, cada tipo de sensor Grove da Seeed tem o mesmo endereço, então todos os sensores de luz têm o mesmo endereço, todos os botões têm o mesmo endereço, que é diferente do endereço do sensor de luz. Alguns dispositivos permitem alterar o endereço, mudando as configurações de jumpers ou soldando pinos juntos. - -O I²C possui um barramento composto por 2 fios principais, além de 2 fios de alimentação: - -| Fio | Nome | Descrição | -| ---- | --------- | ----------- | -| SDA | Dados Seriais | Este fio é usado para enviar dados entre dispositivos. | -| SCL | Relógio Serial | Este fio envia um sinal de relógio a uma taxa definida pelo controlador. | -| VCC | Coletor Comum de Tensão | A fonte de alimentação para os dispositivos. Está conectado aos fios SDA e SCL para fornecer energia através de um resistor pull-up que desliga o sinal quando nenhum dispositivo é o controlador. | -| GND | Terra | Fornece um terra comum para o circuito elétrico. | - -![Barramento I2C com 3 dispositivos conectados aos fios SDA e SCL, compartilhando um fio de terra comum](../../../../../translated_images/pt-PT/i2c.83da845dde02256bdd462dbe0d5145461416b74930571b89d1ae142841eeb584.png) - -Para enviar dados, um dispositivo emite uma condição de início para indicar que está pronto para enviar dados. Ele então se torna o controlador. O controlador envia o endereço do dispositivo com o qual deseja se comunicar, juntamente com a indicação se deseja ler ou escrever dados. Após a transmissão dos dados, o controlador envia uma condição de parada para indicar que terminou. Depois disso, outro dispositivo pode se tornar o controlador e enviar ou receber dados. - -2C tem limites de velocidade, com 3 modos diferentes que operam a velocidades fixas. O mais rápido é o modo de Alta Velocidade, com uma velocidade máxima de 3,4Mbps (megabits por segundo), embora poucos dispositivos suportem essa velocidade. O Raspberry Pi, por exemplo, está limitado ao modo rápido a 400Kbps (kilobits por segundo). O modo padrão opera a 100Kbps. - -> 💁 Se estiver a usar um Raspberry Pi com um Grove Base hat como o seu hardware IoT, poderá ver várias tomadas I2C na placa que pode usar para comunicar com sensores I2C. Sensores analógicos Grove também utilizam I2C com um ADC para enviar valores analógicos como dados digitais, por isso o sensor de luz que utilizou simulou um pino analógico, com o valor enviado através de I2C, já que o Raspberry Pi apenas suporta pinos digitais. - -### Recetor-transmissor assíncrono universal (UART) - -UART envolve circuitos físicos que permitem a comunicação entre dois dispositivos. Cada dispositivo tem 2 pinos de comunicação - transmitir (Tx) e receber (Rx), com o pino Tx do primeiro dispositivo conectado ao pino Rx do segundo, e o pino Tx do segundo dispositivo conectado ao pino Rx do primeiro. Isto permite que os dados sejam enviados em ambas as direções. - -* O dispositivo 1 transmite dados do seu pino Tx, que são recebidos pelo dispositivo 2 no seu pino Rx. -* O dispositivo 1 recebe dados no seu pino Rx que são transmitidos pelo dispositivo 2 a partir do seu pino Tx. - -![UART com o pino Tx de um chip conectado ao pino Rx de outro, e vice-versa](../../../../../translated_images/pt-PT/uart.d0dbd3fb9e3728c6.webp) - -> 🎓 Os dados são enviados um bit de cada vez, e isto é conhecido como comunicação *serial*. A maioria dos sistemas operativos e microcontroladores têm *portas seriais*, ou seja, conexões que podem enviar e receber dados seriais disponíveis para o seu código. - -Os dispositivos UART têm uma [taxa de transmissão](https://wikipedia.org/wiki/Symbol_rate) (também conhecida como taxa de símbolos), que é a velocidade com que os dados serão enviados e recebidos em bits por segundo. Uma taxa de transmissão comum é 9.600, o que significa que 9.600 bits (0s e 1s) de dados são enviados a cada segundo. - -UART utiliza bits de início e fim - ou seja, envia um bit de início para indicar que está prestes a enviar um byte (8 bits) de dados, e um bit de fim após enviar os 8 bits. - -A velocidade do UART depende do hardware, mas mesmo as implementações mais rápidas não excedem 6,5 Mbps (megabits por segundo, ou milhões de bits, 0 ou 1, enviados por segundo). - -Pode usar UART através de pinos GPIO - pode definir um pino como Tx e outro como Rx, e depois conectá-los a outro dispositivo. - -> 💁 Se estiver a usar um Raspberry Pi com um Grove Base hat como o seu hardware IoT, poderá ver uma tomada UART na placa que pode usar para comunicar com sensores que utilizam o protocolo UART. - -### Interface Serial Periférica (SPI) - -SPI foi projetado para comunicação a curtas distâncias, como num microcontrolador para falar com um dispositivo de armazenamento, como memória flash. Baseia-se num modelo de controlador/periférico, com um único controlador (geralmente o processador do dispositivo IoT) interagindo com múltiplos periféricos. O controlador controla tudo ao selecionar um periférico e enviar ou solicitar dados. - -> 💁 Tal como I2C, os termos controlador e periférico são mudanças recentes, por isso pode encontrar os termos mais antigos ainda em uso. - -Os controladores SPI utilizam 3 fios, juntamente com 1 fio extra por periférico. Os periféricos utilizam 4 fios. Estes fios são: - -| Fio | Nome | Descrição | -| ---- | --------- | ----------- | -| COPI | Saída do Controlador, Entrada do Periférico | Este fio é usado para enviar dados do controlador para o periférico. | -| CIPO | Entrada do Controlador, Saída do Periférico | Este fio é usado para enviar dados do periférico para o controlador. | -| SCLK | Relógio Serial | Este fio envia um sinal de relógio a uma taxa definida pelo controlador. | -| CS | Seleção de Chip | O controlador tem múltiplos fios, um por periférico, e cada fio conecta-se ao fio CS no periférico correspondente. | - -![SPI com um controlador e dois periféricos](../../../../../translated_images/pt-PT/spi.297431d6f98b386b.webp) - -O fio CS é usado para ativar um periférico de cada vez, comunicando através dos fios COPI e CIPO. Quando o controlador precisa de mudar de periférico, desativa o fio CS conectado ao periférico atualmente ativo e ativa o fio conectado ao periférico com o qual deseja comunicar a seguir. - -SPI é *full-duplex*, o que significa que o controlador pode enviar e receber dados ao mesmo tempo do mesmo periférico usando os fios COPI e CIPO. SPI utiliza um sinal de relógio no fio SCLK para manter os dispositivos sincronizados, por isso, ao contrário do envio direto através de UART, não necessita de bits de início e fim. - -Não há limites de velocidade definidos para SPI, com implementações frequentemente capazes de transmitir múltiplos megabytes de dados por segundo. - -Os kits de desenvolvimento IoT frequentemente suportam SPI em alguns dos pinos GPIO. Por exemplo, num Raspberry Pi pode usar os pinos GPIO 19, 21, 23, 24 e 26 para SPI. - -### Sem fios - -Alguns sensores podem comunicar através de protocolos sem fios padrão, como Bluetooth (principalmente Bluetooth Low Energy, ou BLE), LoRaWAN (um protocolo de rede de baixo consumo e **Lo**nga **Ra**nge), ou WiFi. Estes permitem sensores remotos que não estão fisicamente conectados a um dispositivo IoT. - -Um exemplo é em sensores comerciais de humidade do solo. Estes medem a humidade do solo num campo e enviam os dados através de LoRaWAN para um dispositivo central, que processa os dados ou os envia pela Internet. Isto permite que o sensor esteja longe do dispositivo IoT que gere os dados, reduzindo o consumo de energia e a necessidade de grandes redes WiFi ou cabos longos. - -BLE é popular para sensores avançados, como rastreadores de fitness que funcionam no pulso. Estes combinam múltiplos sensores e enviam os dados dos sensores para um dispositivo IoT, como o seu telemóvel, via BLE. - -✅ Tem algum sensor Bluetooth consigo, na sua casa ou na sua escola? Estes podem incluir sensores de temperatura, sensores de ocupação, rastreadores de dispositivos e dispositivos de fitness. - -Uma forma popular para dispositivos comerciais se conectarem é Zigbee. Zigbee utiliza WiFi para formar redes em malha entre dispositivos, onde cada dispositivo se conecta ao maior número possível de dispositivos próximos, formando um grande número de conexões como uma teia de aranha. Quando um dispositivo quer enviar uma mensagem para a Internet, pode enviá-la para os dispositivos mais próximos, que a encaminham para outros dispositivos próximos e assim por diante, até chegar a um coordenador e ser enviada para a Internet. - -> 🐝 O nome Zigbee refere-se à dança de abanar das abelhas após o seu retorno à colmeia. - -## Medir os níveis de humidade no solo - -Pode medir o nível de humidade no solo usando um sensor de humidade do solo, um dispositivo IoT e uma planta doméstica ou um pedaço de solo próximo. - -### Tarefa - medir a humidade do solo - -Siga o guia relevante para medir a humidade do solo usando o seu dispositivo IoT: - -* [Arduino - Wio Terminal](wio-terminal-soil-moisture.md) -* [Computador de placa única - Raspberry Pi](pi-soil-moisture.md) -* [Computador de placa única - Dispositivo virtual](virtual-device-soil-moisture.md) - -## Calibração de sensores - -Os sensores dependem da medição de propriedades elétricas, como resistência ou capacitância. - -> 🎓 Resistência, medida em ohms (Ω), é a oposição ao fluxo de corrente elétrica através de algo. Quando uma tensão é aplicada a um material, a quantidade de corrente que passa por ele depende da resistência do material. Pode ler mais na [página de resistência elétrica na Wikipedia](https://wikipedia.org/wiki/Electrical_resistance_and_conductance). - -> 🎓 Capacitância, medida em farads (F), é a capacidade de um componente ou circuito de coletar e armazenar energia elétrica. Pode ler mais sobre capacitância na [página de capacitância na Wikipedia](https://wikipedia.org/wiki/Capacitance). - -Estas medições nem sempre são úteis - imagine um sensor de temperatura que lhe dá uma medição de 22,5KΩ! Em vez disso, o valor medido precisa de ser convertido numa unidade útil através de calibração - ou seja, correspondendo os valores medidos à quantidade medida para permitir que novas medições sejam convertidas na unidade correta. - -Alguns sensores vêm pré-calibrados. Por exemplo, o sensor de temperatura que utilizou na última lição já estava calibrado para retornar uma medição de temperatura em °C. Na fábrica, o primeiro sensor criado seria exposto a uma gama de temperaturas conhecidas e a resistência medida. Isto seria então usado para construir um cálculo que pode converter do valor medido em Ω (a unidade de resistência) para °C. - -> 💁 A fórmula para calcular a resistência a partir da temperatura é chamada de [equação de Steinhart–Hart](https://wikipedia.org/wiki/Steinhart–Hart_equation). - -### Calibração do sensor de humidade do solo - -A humidade do solo é medida usando o conteúdo de água gravimétrico ou volumétrico. - -* Gravimétrico é o peso da água numa unidade de peso de solo medido, como o número de quilogramas de água por quilograma de solo seco. -* Volumétrico é o volume de água numa unidade de volume de solo medido, como o número de metros cúbicos de água por metros cúbicos de solo seco. - -> 🇺🇸 Para os americanos, devido à consistência das unidades, estas podem ser medidas em libras em vez de quilogramas ou pés cúbicos em vez de metros cúbicos. - -Os sensores de humidade do solo medem resistência elétrica ou capacitância - isto varia não apenas com a humidade do solo, mas também com o tipo de solo, já que os componentes no solo podem alterar as suas características elétricas. Idealmente, os sensores devem ser calibrados - ou seja, fazer leituras do sensor e compará-las com medições obtidas usando uma abordagem mais científica. Por exemplo, um laboratório pode calcular a humidade gravimétrica do solo usando amostras de um campo específico recolhidas algumas vezes por ano, e esses números usados para calibrar o sensor, correspondendo a leitura do sensor à humidade gravimétrica do solo. - -![Um gráfico de tensão vs conteúdo de humidade do solo](../../../../../translated_images/pt-PT/soil-moisture-to-voltage.df86d80cda158700.webp) - -O gráfico acima mostra como calibrar um sensor. A tensão é capturada para uma amostra de solo que é então medida num laboratório, comparando o peso húmido com o peso seco (medindo o peso húmido, depois secando num forno e medindo seco). Depois de algumas leituras serem feitas, estas podem ser plotadas num gráfico e uma linha ajustada aos pontos. Esta linha pode então ser usada para converter leituras de sensores de humidade do solo feitas por um dispositivo IoT em medições reais de humidade do solo. - -💁 Para sensores resistivos de humidade do solo, a tensão aumenta à medida que a humidade do solo aumenta. Para sensores capacitivos de humidade do solo, a tensão diminui à medida que a humidade do solo aumenta, por isso os gráficos para estes inclinariam para baixo, não para cima. - -![Um valor de humidade do solo interpolado a partir do gráfico](../../../../../translated_images/pt-PT/soil-moisture-to-voltage-with-reading.681cb3e1f8b68caf.webp) - -O gráfico acima mostra uma leitura de tensão de um sensor de humidade do solo, e ao seguir essa leitura até à linha no gráfico, a humidade real do solo pode ser calculada. - -Esta abordagem significa que o agricultor só precisa de obter algumas medições laboratoriais para um campo, e depois pode usar dispositivos IoT para medir a humidade do solo - acelerando drasticamente o tempo para obter medições. - ---- - -## 🚀 Desafio - -Sensores resistivos e capacitivos de humidade do solo têm várias diferenças. Quais são essas diferenças, e qual tipo (se algum) é o melhor para um agricultor usar? Esta resposta muda entre países em desenvolvimento e desenvolvidos? - -## Questionário pós-aula - -[Questionário pós-aula](https://black-meadow-040d15503.1.azurestaticapps.net/quiz/12) - -## Revisão & Autoestudo - -Leia sobre o hardware e os protocolos usados por sensores e atuadores: - -* [Página da Wikipedia sobre GPIO](https://wikipedia.org/wiki/General-purpose_input/output) -* [Página da Wikipedia sobre UART](https://wikipedia.org/wiki/Universal_asynchronous_receiver-transmitter) -* [Página da Wikipedia sobre SPI](https://wikipedia.org/wiki/Serial_Peripheral_Interface) -* [Página da Wikipedia sobre I2C](https://wikipedia.org/wiki/I²C) -* [Página da Wikipedia sobre Zigbee](https://wikipedia.org/wiki/Zigbee) - -## Tarefa - -[Calibre o seu sensor](assignment.md) - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, esteja ciente de que traduções automáticas podem conter erros ou imprecisões. O documento original no seu idioma nativo deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se uma tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas resultantes do uso desta tradução. \ No newline at end of file diff --git a/translations/pt/2-farm/lessons/2-detect-soil-moisture/assignment.md b/translations/pt/2-farm/lessons/2-detect-soil-moisture/assignment.md deleted file mode 100644 index 525c2a31a..000000000 --- a/translations/pt/2-farm/lessons/2-detect-soil-moisture/assignment.md +++ /dev/null @@ -1,61 +0,0 @@ - -# Calibre o seu sensor - -## Instruções - -Nesta lição, recolheu leituras do sensor de humidade do solo, medidas em valores de 0-1023. Para converter estas leituras em valores reais de humidade do solo, é necessário calibrar o sensor. Pode fazer isso recolhendo amostras de solo e calculando o teor gravimétrico de humidade do solo a partir dessas amostras. - -Será necessário repetir estes passos várias vezes para obter as leituras necessárias, utilizando solos com diferentes níveis de humidade em cada tentativa. - -1. Faça uma leitura de humidade do solo utilizando o sensor de humidade do solo. Registe esta leitura. - -1. Recolha uma amostra do solo e pese-a. Registe este peso. - -1. Seque o solo - um forno quente a 110°C (230°F) durante algumas horas é o método ideal. Pode também secá-lo ao sol ou colocá-lo num local quente e seco até que o solo esteja completamente seco. O solo deve ficar pulverulento e solto. - - > 💁 Num laboratório, para obter resultados mais precisos, deve secar o solo num forno durante 48-72 horas. Se a sua escola tiver fornos de secagem, veja se pode utilizá-los para secar por mais tempo. Quanto mais tempo secar, mais seco ficará o solo e mais precisos serão os resultados. - -1. Pese novamente o solo. - - > 🔥 Se o secou num forno, certifique-se de que o solo arrefeceu antes de o pesar! - -A humidade gravimétrica do solo é calculada como: - -![humidade do solo % é o peso húmido menos o peso seco, dividido pelo peso seco, vezes 100](../../../../../translated_images/pt-PT/gsm-calculation.6da38c6201eec14e7573bb2647aa18892883193553d23c9d77e5dc681522dfb2.png) - -* W -- o peso do solo húmido -* W -- o peso do solo seco - -Por exemplo, suponha que tem uma amostra de solo que pesa 212g húmida e 197g seca. - -![O cálculo preenchido](../../../../../translated_images/pt-PT/gsm-calculation-example.99f9803b4f29e97668e7c15412136c0c399ab12dbba0b89596fdae9d8aedb6fb.png) - -* W = 212g -* W = 197g -* 212 - 197 = 15 -* 15 / 197 = 0,076 -* 0,076 * 100 = 7,6% - -Neste exemplo, o solo tem uma humidade gravimétrica de 7,6%. - -Depois de obter as leituras de pelo menos 3 amostras, faça um gráfico da humidade do solo % em relação às leituras do sensor de humidade do solo e adicione uma linha que melhor se ajuste aos pontos. Pode então usar este gráfico para calcular o teor gravimétrico de humidade do solo para uma determinada leitura do sensor, lendo o valor na linha. - -## Rubrica - -| Critério | Exemplar | Adequado | Necessita de Melhorias | -| -------- | --------- | -------- | ---------------------- | -| Recolher dados de calibração | Captura pelo menos 3 amostras de calibração | Captura pelo menos 2 amostras de calibração | Captura pelo menos 1 amostra de calibração | -| Fazer uma leitura calibrada | Consegue traçar com sucesso o gráfico de calibração, fazer uma leitura do sensor e convertê-la em teor gravimétrico de humidade do solo | Consegue traçar com sucesso o gráfico de calibração | Não consegue traçar o gráfico | - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, esteja ciente de que traduções automáticas podem conter erros ou imprecisões. O documento original no seu idioma nativo deve ser considerado a fonte autoritativa. Para informações críticas, recomenda-se uma tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas resultantes do uso desta tradução. \ No newline at end of file diff --git a/translations/pt/2-farm/lessons/2-detect-soil-moisture/pi-soil-moisture.md b/translations/pt/2-farm/lessons/2-detect-soil-moisture/pi-soil-moisture.md deleted file mode 100644 index c4a9e260a..000000000 --- a/translations/pt/2-farm/lessons/2-detect-soil-moisture/pi-soil-moisture.md +++ /dev/null @@ -1,106 +0,0 @@ - -# Medir a humidade do solo - Raspberry Pi - -Nesta parte da lição, vais adicionar um sensor capacitivo de humidade do solo ao teu Raspberry Pi e ler os valores obtidos. - -## Hardware - -O Raspberry Pi necessita de um sensor capacitivo de humidade do solo. - -O sensor que vais utilizar é um [Sensor Capacitivo de Humidade do Solo](https://www.seeedstudio.com/Grove-Capacitive-Moisture-Sensor-Corrosion-Resistant.html), que mede a humidade do solo ao detetar a capacitância do mesmo, uma propriedade que muda conforme a humidade do solo varia. À medida que a humidade do solo aumenta, a voltagem diminui. - -Este é um sensor analógico, por isso utiliza um pino analógico e o ADC de 10 bits no Grove Base Hat do Pi para converter a voltagem num sinal digital entre 1 e 1.023. Este sinal é então enviado via I2C através dos pinos GPIO do Pi. - -### Ligar o sensor de humidade do solo - -O sensor de humidade do solo Grove pode ser ligado ao Raspberry Pi. - -#### Tarefa - ligar o sensor de humidade do solo - -Liga o sensor de humidade do solo. - -![Um sensor Grove de humidade do solo](../../../../../translated_images/pt-PT/grove-capacitive-soil-moisture-sensor.e7f0776cce30e78be5cc5a07839385fd6718857f31b5bf5ad3d0c73c83b2f0ef.png) - -1. Insere uma extremidade de um cabo Grove na entrada do sensor de humidade do solo. Só encaixará de uma forma. - -1. Com o Raspberry Pi desligado, liga a outra extremidade do cabo Grove à entrada analógica marcada como **A0** no Grove Base Hat ligado ao Pi. Esta entrada é a segunda da direita, na fila de entradas ao lado dos pinos GPIO. - -![O sensor Grove de humidade do solo ligado à entrada A0](../../../../../translated_images/pt-PT/pi-soil-moisture-sensor.fdd7eb2393792cf6739cacf1985d9f55beda16d372f30d0b5a51d586f978a870.png) - -1. Insere o sensor de humidade do solo na terra. O sensor tem uma 'linha de posição máxima' - uma linha branca ao longo do sensor. Insere o sensor até essa linha, mas não ultrapasses. - -![O sensor Grove de humidade do solo na terra](../../../../../translated_images/pt-PT/soil-moisture-sensor-in-soil.bfad91002bda5e96.webp) - -## Programar o sensor de humidade do solo - -O Raspberry Pi pode agora ser programado para utilizar o sensor de humidade do solo ligado. - -### Tarefa - programar o sensor de humidade do solo - -Programa o dispositivo. - -1. Liga o Pi e espera que ele arranque. - -1. Abre o VS Code, diretamente no Pi ou através da extensão Remote SSH. - - > ⚠️ Podes consultar [as instruções para configurar e abrir o VS Code no nightlight - lição 1, se necessário](../../../1-getting-started/lessons/1-introduction-to-iot/pi.md). - -1. No terminal, cria uma nova pasta no diretório home do utilizador `pi` chamada `soil-moisture-sensor`. Cria um ficheiro nesta pasta chamado `app.py`. - -1. Abre esta pasta no VS Code. - -1. Adiciona o seguinte código ao ficheiro `app.py` para importar algumas bibliotecas necessárias: - - ```python - import time - from grove.adc import ADC - ``` - - A instrução `import time` importa o módulo `time`, que será utilizado mais tarde nesta tarefa. - - A instrução `from grove.adc import ADC` importa o `ADC` das bibliotecas Python do Grove. Esta biblioteca contém código para interagir com o conversor analógico-digital no Base Hat do Pi e ler voltagens de sensores analógicos. - -1. Adiciona o seguinte código abaixo para criar uma instância da classe `ADC`: - - ```python - adc = ADC() - ``` - -1. Adiciona um loop infinito que lê este ADC no pino A0 e escreve o resultado na consola. Este loop pode então aguardar 10 segundos entre leituras. - - ```python - while True: - soil_moisture = adc.read(0) - print("Soil moisture:", soil_moisture) - - time.sleep(10) - ``` - -1. Executa a aplicação Python. Vais ver as medições de humidade do solo escritas na consola. Adiciona água à terra ou remove o sensor da terra e observa a mudança nos valores. - - ```output - pi@raspberrypi:~/soil-moisture-sensor $ python3 app.py - Soil moisture: 615 - Soil moisture: 612 - Soil moisture: 498 - Soil moisture: 493 - Soil moisture: 490 - Soil Moisture: 388 - ``` - - No exemplo de saída acima, podes ver a voltagem a diminuir à medida que a água é adicionada. - -> 💁 Podes encontrar este código na pasta [code/pi](../../../../../2-farm/lessons/2-detect-soil-moisture/code/pi). - -😀 O programa do sensor de humidade do solo foi um sucesso! - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, é importante notar que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes do uso desta tradução. \ No newline at end of file diff --git a/translations/pt/2-farm/lessons/2-detect-soil-moisture/virtual-device-soil-moisture.md b/translations/pt/2-farm/lessons/2-detect-soil-moisture/virtual-device-soil-moisture.md deleted file mode 100644 index d5110bc6d..000000000 --- a/translations/pt/2-farm/lessons/2-detect-soil-moisture/virtual-device-soil-moisture.md +++ /dev/null @@ -1,121 +0,0 @@ - -# Medir a humidade do solo - Hardware Virtual IoT - -Nesta parte da lição, irá adicionar um sensor capacitivo de humidade do solo ao seu dispositivo IoT virtual e ler os valores obtidos. - -## Hardware Virtual - -O dispositivo IoT virtual utilizará um sensor capacitivo de humidade do solo simulado da Grove. Isto mantém este laboratório semelhante ao uso de um Raspberry Pi com um sensor capacitivo de humidade do solo físico da Grove. - -Num dispositivo IoT físico, o sensor de humidade do solo seria um sensor capacitivo que mede a humidade do solo ao detetar a capacitância do mesmo, uma propriedade que muda conforme a humidade do solo varia. À medida que a humidade do solo aumenta, a voltagem diminui. - -Este é um sensor analógico, por isso utiliza um ADC simulado de 10 bits para reportar um valor entre 1 e 1.023. - -### Adicionar o sensor de humidade do solo ao CounterFit - -Para utilizar um sensor virtual de humidade do solo, é necessário adicioná-lo à aplicação CounterFit. - -#### Tarefa - Adicionar o sensor de humidade do solo ao CounterFit - -Adicione o sensor de humidade do solo à aplicação CounterFit. - -1. Crie uma nova aplicação Python no seu computador numa pasta chamada `soil-moisture-sensor` com um único ficheiro chamado `app.py`, um ambiente virtual Python, e adicione os pacotes pip do CounterFit. - - > ⚠️ Pode consultar [as instruções para criar e configurar um projeto Python no CounterFit na lição 1, se necessário](../../../1-getting-started/lessons/1-introduction-to-iot/virtual-device.md). - -1. Certifique-se de que a aplicação web do CounterFit está em execução. - -1. Crie um sensor de humidade do solo: - - 1. Na caixa *Create sensor* no painel *Sensors*, abra o menu suspenso *Sensor type* e selecione *Soil Moisture*. - - 1. Deixe as *Units* definidas como *NoUnits*. - - 1. Certifique-se de que o *Pin* está definido como *0*. - - 1. Selecione o botão **Add** para criar o sensor *Soil Moisture* no Pin 0. - - ![As definições do sensor de humidade do solo](../../../../../translated_images/pt-PT/counterfit-create-soil-moisture-sensor.35266135a5e0ae68b29a684d7db0d2933a8098b2307d197f7c71577b724603aa.png) - - O sensor de humidade do solo será criado e aparecerá na lista de sensores. - - ![O sensor de humidade do solo criado](../../../../../translated_images/pt-PT/counterfit-soil-moisture-sensor.81742b2de0e9de60a3b3b9a2ff8ecc686d428eb6d71820f27a693be26e5aceee.png) - -## Programar a aplicação do sensor de humidade do solo - -A aplicação do sensor de humidade do solo pode agora ser programada utilizando os sensores do CounterFit. - -### Tarefa - Programar a aplicação do sensor de humidade do solo - -Programe a aplicação do sensor de humidade do solo. - -1. Certifique-se de que a aplicação `soil-moisture-sensor` está aberta no VS Code. - -1. Abra o ficheiro `app.py`. - -1. Adicione o seguinte código ao início do ficheiro `app.py` para ligar a aplicação ao CounterFit: - - ```python - from counterfit_connection import CounterFitConnection - CounterFitConnection.init('127.0.0.1', 5000) - ``` - -1. Adicione o seguinte código ao ficheiro `app.py` para importar algumas bibliotecas necessárias: - - ```python - import time - from counterfit_shims_grove.adc import ADC - ``` - - A instrução `import time` importa o módulo `time`, que será utilizado mais tarde nesta tarefa. - - A instrução `from counterfit_shims_grove.adc import ADC` importa a classe `ADC` para interagir com um conversor analógico para digital virtual que pode ser ligado a um sensor do CounterFit. - -1. Adicione o seguinte código abaixo para criar uma instância da classe `ADC`: - - ```python - adc = ADC() - ``` - -1. Adicione um loop infinito que lê os valores deste ADC no pin 0 e escreve o resultado na consola. Este loop pode então aguardar 10 segundos entre as leituras. - - ```python - while True: - soil_moisture = adc.read(0) - print("Soil moisture:", soil_moisture) - - time.sleep(10) - ``` - -1. Na aplicação CounterFit, altere o valor do sensor de humidade do solo que será lido pela aplicação. Pode fazer isto de duas formas: - - * Insira um número na caixa *Value* do sensor de humidade do solo e, em seguida, selecione o botão **Set**. O número inserido será o valor retornado pelo sensor. - - * Marque a caixa *Random* e insira um valor *Min* e *Max*, depois selecione o botão **Set**. Sempre que o sensor ler um valor, será gerado um número aleatório entre *Min* e *Max*. - -1. Execute a aplicação Python. Verá as medições de humidade do solo escritas na consola. Altere o *Value* ou as definições *Random* para observar a mudança nos valores. - - ```output - (.venv) ➜ soil-moisture-sensor $ python app.py - Soil moisture: 615 - Soil moisture: 612 - Soil moisture: 498 - Soil moisture: 493 - Soil moisture: 490 - Soil Moisture: 388 - ``` - -> 💁 Pode encontrar este código na pasta [code/virtual-device](../../../../../2-farm/lessons/2-detect-soil-moisture/code/virtual-device). - -😀 O seu programa do sensor de humidade do solo foi um sucesso! - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos pela precisão, esteja ciente de que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes do uso desta tradução. \ No newline at end of file diff --git a/translations/pt/2-farm/lessons/2-detect-soil-moisture/wio-terminal-soil-moisture.md b/translations/pt/2-farm/lessons/2-detect-soil-moisture/wio-terminal-soil-moisture.md deleted file mode 100644 index 9ccb86c31..000000000 --- a/translations/pt/2-farm/lessons/2-detect-soil-moisture/wio-terminal-soil-moisture.md +++ /dev/null @@ -1,115 +0,0 @@ - -# Medir a humidade do solo - Wio Terminal - -Nesta parte da lição, irá adicionar um sensor capacitivo de humidade do solo ao seu Wio Terminal e ler os valores obtidos. - -## Hardware - -O Wio Terminal necessita de um sensor capacitivo de humidade do solo. - -O sensor que irá utilizar é um [Sensor Capacitivo de Humidade do Solo](https://www.seeedstudio.com/Grove-Capacitive-Moisture-Sensor-Corrosion-Resistant.html), que mede a humidade do solo ao detetar a capacitância do mesmo, uma propriedade que muda conforme a humidade do solo varia. À medida que a humidade do solo aumenta, a voltagem diminui. - -Este é um sensor analógico, por isso conecta-se aos pinos analógicos do Wio Terminal, utilizando um ADC integrado para criar um valor entre 0-1.023. - -### Conectar o sensor de humidade do solo - -O sensor Grove de humidade do solo pode ser conectado à porta analógica/digital configurável do Wio Terminal. - -#### Tarefa - conectar o sensor de humidade do solo - -Conecte o sensor de humidade do solo. - -![Um sensor Grove de humidade do solo](../../../../../translated_images/pt-PT/grove-capacitive-soil-moisture-sensor.e7f0776cce30e78be5cc5a07839385fd6718857f31b5bf5ad3d0c73c83b2f0ef.png) - -1. Insira uma extremidade de um cabo Grove na entrada do sensor de humidade do solo. O cabo só encaixa de uma forma. - -1. Com o Wio Terminal desconectado do seu computador ou outra fonte de alimentação, conecte a outra extremidade do cabo Grove à entrada Grove do lado direito do Wio Terminal, olhando para o ecrã. Esta é a entrada mais distante do botão de energia. - -![O sensor Grove de humidade do solo conectado à entrada do lado direito](../../../../../translated_images/pt-PT/wio-soil-moisture-sensor.46919b61c3f6cb74.webp) - -1. Insira o sensor de humidade do solo na terra. O sensor tem uma 'linha de posição máxima' - uma linha branca atravessando o sensor. Insira o sensor até esta linha, mas não ultrapasse. - -![O sensor Grove de humidade do solo na terra](../../../../../translated_images/pt-PT/soil-moisture-sensor-in-soil.bfad91002bda5e96.webp) - -1. Agora pode conectar o Wio Terminal ao seu computador. - -## Programar o sensor de humidade do solo - -O Wio Terminal pode agora ser programado para utilizar o sensor de humidade do solo conectado. - -### Tarefa - programar o sensor de humidade do solo - -Programe o dispositivo. - -1. Crie um novo projeto para o Wio Terminal utilizando o PlatformIO. Chame este projeto `soil-moisture-sensor`. Adicione código na função `setup` para configurar a porta serial. - - > ⚠️ Pode consultar [as instruções para criar um projeto PlatformIO no projeto 1, lição 1, se necessário](../../../1-getting-started/lessons/1-introduction-to-iot/wio-terminal.md#create-a-platformio-project). - -1. Não existe uma biblioteca para este sensor, mas pode ler o pino analógico utilizando a função [`analogRead`](https://www.arduino.cc/reference/en/language/functions/analog-io/analogread/) integrada do Arduino. Comece por configurar o pino analógico como entrada para que os valores possam ser lidos, adicionando o seguinte à função `setup`. - - ```cpp - pinMode(A0, INPUT); - ``` - - Isto define o pino `A0`, o pino combinado analógico/digital, como um pino de entrada de onde a voltagem pode ser lida. - -1. Adicione o seguinte à função `loop` para ler a voltagem deste pino: - - ```cpp - int soil_moisture = analogRead(A0); - ``` - -1. Abaixo deste código, adicione o seguinte código para imprimir o valor na porta serial: - - ```cpp - Serial.print("Soil Moisture: "); - Serial.println(soil_moisture); - ``` - -1. Finalmente, adicione um atraso de 10 segundos no final: - - ```cpp - delay(10000); - ``` - -1. Compile e carregue o código no Wio Terminal. - - > ⚠️ Pode consultar [as instruções para criar um projeto PlatformIO no projeto 1, lição 1, se necessário](../../../1-getting-started/lessons/1-introduction-to-iot/wio-terminal.md#write-the-hello-world-app). - -1. Depois de carregado, pode monitorizar a humidade do solo utilizando o monitor serial. Adicione água à terra ou remova o sensor da terra e veja o valor mudar. - - ```output - > Executing task: platformio device monitor < - - --- Available filters and text transformations: colorize, debug, default, direct, hexlify, log2file, nocontrol, printable, send_on_enter, time - --- More details at http://bit.ly/pio-monitor-filters - --- Miniterm on /dev/cu.usbmodem1201 9600,8,N,1 --- - --- Quit: Ctrl+C | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H --- - Soil Moisture: 526 - Soil Moisture: 529 - Soil Moisture: 521 - Soil Moisture: 494 - Soil Moisture: 454 - Soil Moisture: 456 - Soil Moisture: 395 - Soil Moisture: 388 - Soil Moisture: 394 - Soil Moisture: 391 - ``` - - No exemplo de saída acima, pode ver a voltagem diminuir à medida que a água é adicionada. - -> 💁 Pode encontrar este código na pasta [code/wio-terminal](../../../../../2-farm/lessons/2-detect-soil-moisture/code/wio-terminal). - -😀 O programa do sensor de humidade do solo foi um sucesso! - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, esteja ciente de que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes do uso desta tradução. \ No newline at end of file diff --git a/translations/pt/2-farm/lessons/3-automated-plant-watering/README.md b/translations/pt/2-farm/lessons/3-automated-plant-watering/README.md deleted file mode 100644 index 1d971ae2f..000000000 --- a/translations/pt/2-farm/lessons/3-automated-plant-watering/README.md +++ /dev/null @@ -1,312 +0,0 @@ - -# Rega automática de plantas - -![Uma visão geral ilustrada desta lição](../../../../../translated_images/pt-PT/lesson-7.30b5f577d3cb8e031238751475cb519c7d6dbaea261b5df4643d086ffb2a03bb.jpg) - -> Ilustração por [Nitya Narasimhan](https://github.com/nitya). Clique na imagem para uma versão maior. - -Esta lição foi ensinada como parte da [série IoT para Iniciantes - Agricultura Digital, Projeto 2](https://youtube.com/playlist?list=PLmsFUfdnGr3yCutmcVg6eAUEfsGiFXgcx) do [Microsoft Reactor](https://developer.microsoft.com/reactor/?WT.mc_id=academic-17441-jabenn). - -[![Rega automática de plantas com IoT](https://img.youtube.com/vi/g9FfZwv9R58/0.jpg)](https://youtu.be/g9FfZwv9R58) - -## Questionário pré-aula - -[Questionário pré-aula](https://black-meadow-040d15503.1.azurestaticapps.net/quiz/13) - -## Introdução - -Na última lição, aprendeste a monitorizar a humidade do solo. Nesta lição, vais aprender a construir os componentes principais de um sistema de rega automática que responde à humidade do solo. Também vais aprender sobre temporização - como os sensores podem demorar a responder a mudanças e como os atuadores podem levar tempo para alterar as propriedades medidas pelos sensores. - -Nesta lição, abordaremos: - -* [Controlar dispositivos de alta potência com um dispositivo IoT de baixa potência](../../../../../2-farm/lessons/3-automated-plant-watering) -* [Controlar um relé](../../../../../2-farm/lessons/3-automated-plant-watering) -* [Controlar a tua planta via MQTT](../../../../../2-farm/lessons/3-automated-plant-watering) -* [Temporização de sensores e atuadores](../../../../../2-farm/lessons/3-automated-plant-watering) -* [Adicionar temporização ao servidor de controlo da tua planta](../../../../../2-farm/lessons/3-automated-plant-watering) - -## Controlar dispositivos de alta potência com um dispositivo IoT de baixa potência - -Os dispositivos IoT utilizam uma baixa voltagem. Embora isso seja suficiente para sensores e atuadores de baixa potência, como LEDs, é insuficiente para controlar hardware maior, como uma bomba de água usada para irrigação. Mesmo bombas pequenas, adequadas para plantas de interior, consomem demasiada corrente para um kit de desenvolvimento IoT e poderiam danificar a placa. - -> 🎓 Corrente, medida em Amperes (A), é a quantidade de eletricidade que circula num circuito. A voltagem fornece o impulso, enquanto a corrente é a quantidade que é impulsionada. Podes ler mais sobre corrente na [página sobre corrente elétrica na Wikipédia](https://wikipedia.org/wiki/Electric_current). - -A solução para isto é ligar a bomba a uma fonte de alimentação externa e usar um atuador para ligar a bomba, de forma semelhante a como ligarias uma luz. É necessário apenas uma pequena quantidade de energia (na forma de energia do teu corpo) para o teu dedo acionar um interruptor, conectando a luz à eletricidade da rede elétrica, que opera a 110V/240V. - -![Um interruptor liga a energia a uma luz](../../../../../translated_images/pt-PT/light-switch.760317ad6ab8bd6d611da5352dfe9c73a94a0822ccec7df3c8bae35da18e1658.png) - -> 🎓 [Eletricidade da rede](https://wikipedia.org/wiki/Mains_electricity) refere-se à eletricidade fornecida a casas e empresas através da infraestrutura nacional em muitas partes do mundo. - -✅ Os dispositivos IoT geralmente fornecem 3,3V ou 5V, com menos de 1 ampere (1A) de corrente. Em comparação, a eletricidade da rede opera frequentemente a 230V (120V na América do Norte e 100V no Japão) e pode fornecer energia para dispositivos que consomem até 30A. - -Existem vários tipos de atuadores que podem fazer isso, incluindo dispositivos mecânicos que podes anexar a interruptores existentes para simular um dedo a ligá-los. O mais popular é o relé. - -### Relés - -Um relé é um interruptor eletromecânico que converte um sinal elétrico num movimento mecânico para ligar um interruptor. O núcleo de um relé é um eletroíman. - -> 🎓 [Eletroímanes](https://wikipedia.org/wiki/Electromagnet) são ímanes criados ao passar eletricidade por uma bobina de fio. Quando a eletricidade é ligada, a bobina torna-se magnetizada. Quando a eletricidade é desligada, a bobina perde o magnetismo. - -![Quando ligado, o eletroíman cria um campo magnético, ativando o interruptor do circuito de saída](../../../../../translated_images/pt-PT/relay-on.4db16a0fd6b66926.webp) - -Num relé, um circuito de controlo alimenta o eletroíman. Quando o eletroíman está ligado, ele puxa uma alavanca que move um interruptor, fechando um par de contactos e completando um circuito de saída. - -![Quando desligado, o eletroíman não cria um campo magnético, desligando o interruptor do circuito de saída](../../../../../translated_images/pt-PT/relay-off.c34a178a2960fecd.webp) - -Quando o circuito de controlo está desligado, o eletroíman desliga-se, libertando a alavanca e abrindo os contactos, desligando o circuito de saída. Os relés são atuadores digitais - um sinal alto liga o relé, um sinal baixo desliga-o. - -O circuito de saída pode ser usado para alimentar hardware adicional, como um sistema de irrigação. O dispositivo IoT pode ligar o relé, completando o circuito de saída que alimenta o sistema de irrigação, e as plantas são regadas. O dispositivo IoT pode então desligar o relé, cortando a energia do sistema de irrigação e desligando a água. - -![Um relé a ligar, ativando uma bomba que envia água para uma planta](../../../../../images/strawberry-pump.gif) - -No vídeo acima, um relé é ativado. Um LED no relé acende-se para indicar que está ligado (algumas placas de relé têm LEDs para indicar se o relé está ligado ou desligado), e a energia é enviada para a bomba, ligando-a e bombeando água para uma planta. - -> 💁 Os relés também podem ser usados para alternar entre dois circuitos de saída em vez de ligar ou desligar um. À medida que a alavanca se move, ela muda um interruptor de completar um circuito de saída para completar outro circuito de saída, geralmente compartilhando uma conexão de energia comum ou de terra comum. - -✅ Faz uma pesquisa: Existem vários tipos de relés, com diferenças como se o circuito de controlo liga ou desliga o relé quando a energia é aplicada, ou múltiplos circuitos de saída. Descobre mais sobre esses diferentes tipos. - -Quando a alavanca se move, geralmente podes ouvi-la fazer contacto com o eletroíman, produzindo um clique bem definido. - -> 💁 Um relé pode ser ligado de forma que a conexão interrompa a energia do próprio relé, desligando-o, o que então envia energia de volta para o relé, ligando-o novamente, e assim por diante. Isso faz com que o relé clique muito rapidamente, produzindo um som de zumbido. Foi assim que alguns dos primeiros campainhas elétricas funcionavam. - -### Alimentação do relé - -O eletroíman não precisa de muita energia para ativar e puxar a alavanca; ele pode ser controlado usando a saída de 3,3V ou 5V de um kit de desenvolvimento IoT. O circuito de saída pode transportar muito mais energia, dependendo do relé, incluindo voltagem da rede elétrica ou até níveis de potência mais altos para uso industrial. Desta forma, um kit de desenvolvimento IoT pode controlar um sistema de irrigação, desde uma pequena bomba para uma única planta até um sistema industrial massivo para uma exploração agrícola comercial. - -![Um relé Grove com o circuito de controlo, circuito de saída e relé identificados](../../../../../translated_images/pt-PT/grove-relay-labelled.293e068f5c3c2a199bd7892f2661fdc9e10c920b535cfed317fbd6d1d4ae1168.png) - -A imagem acima mostra um relé Grove. O circuito de controlo conecta-se a um dispositivo IoT e liga ou desliga o relé usando 3,3V ou 5V. O circuito de saída tem dois terminais, qualquer um pode ser energia ou terra. O circuito de saída pode lidar com até 250V a 10A, suficiente para uma variedade de dispositivos alimentados pela rede elétrica. Existem relés que podem lidar com níveis de potência ainda mais altos. - -![Uma bomba ligada através de um relé](../../../../../translated_images/pt-PT/pump-wired-to-relay.66c5cfc0d8918990.webp) - -Na imagem acima, a energia é fornecida a uma bomba através de um relé. Há um fio vermelho que conecta o terminal +5V de uma fonte de alimentação USB a um terminal do circuito de saída do relé, e outro fio vermelho que conecta o outro terminal do circuito de saída à bomba. Um fio preto conecta a bomba ao terra da fonte de alimentação USB. Quando o relé é ligado, ele completa o circuito, enviando 5V para a bomba, ligando-a. - -## Controlar um relé - -Podes controlar um relé a partir do teu kit de desenvolvimento IoT. - -### Tarefa - controlar um relé - -Segue o guia relevante para controlar um relé usando o teu dispositivo IoT: - -* [Arduino - Wio Terminal](wio-terminal-relay.md) -* [Computador de placa única - Raspberry Pi](pi-relay.md) -* [Computador de placa única - Dispositivo virtual](virtual-device-relay.md) - -## Controlar a tua planta via MQTT - -Até agora, o teu relé é controlado diretamente pelo dispositivo IoT com base numa única leitura de humidade do solo. Num sistema de irrigação comercial, a lógica de controlo será centralizada, permitindo tomar decisões de rega com base em dados de múltiplos sensores e permitindo que qualquer configuração seja alterada num único local. Para simular isso, podes controlar o relé via MQTT. - -### Tarefa - controlar o relé via MQTT - -1. Adiciona as bibliotecas/pacotes pip MQTT relevantes e o código ao teu projeto `soil-moisture-sensor` para te conectares ao MQTT. Nomeia o ID do cliente como `soilmoisturesensor_client` prefixado pelo teu ID. - - > ⚠️ Podes consultar [as instruções para te conectares ao MQTT no projeto 1, lição 4, se necessário](../../../1-getting-started/lessons/4-connect-internet/README.md#connect-your-iot-device-to-mqtt). - -1. Adiciona o código relevante do dispositivo para enviar telemetria com as configurações de humidade do solo. Para a mensagem de telemetria, nomeia a propriedade `soil_moisture`. - - > ⚠️ Podes consultar [as instruções para enviar telemetria ao MQTT no projeto 1, lição 4, se necessário](../../../1-getting-started/lessons/4-connect-internet/README.md#send-telemetry-from-your-iot-device). - -1. Cria algum código de servidor local para subscrever a telemetria e enviar um comando para controlar o relé numa pasta chamada `soil-moisture-sensor-server`. Nomeia a propriedade na mensagem de comando `relay_on` e define o ID do cliente como `soilmoisturesensor_server` prefixado pelo teu ID. Mantém a mesma estrutura do código do servidor que escreveste para o projeto 1, lição 4, pois vais adicionar a este código mais tarde nesta lição. - - > ⚠️ Podes consultar [as instruções para enviar telemetria ao MQTT](../../../1-getting-started/lessons/4-connect-internet/README.md#write-the-server-code) e [enviar comandos via MQTT](../../../1-getting-started/lessons/4-connect-internet/README.md#send-commands-to-the-mqtt-broker) no projeto 1, lição 4, se necessário. - -1. Adiciona o código relevante do dispositivo para controlar o relé a partir dos comandos recebidos, usando a propriedade `relay_on` da mensagem. Envia `true` para `relay_on` se a `soil_moisture` for maior que 450, caso contrário, envia `false`, o mesmo que a lógica que adicionaste para o dispositivo IoT anteriormente. - - > ⚠️ Podes consultar [as instruções para responder a comandos do MQTT no projeto 1, lição 4, se necessário](../../../1-getting-started/lessons/4-connect-internet/README.md#handle-commands-on-the-iot-device). - -> 💁 Podes encontrar este código na pasta [code-mqtt](../../../../../2-farm/lessons/3-automated-plant-watering/code-mqtt). - -Certifica-te de que o código está a ser executado no teu dispositivo e servidor local, e testa-o alterando os níveis de humidade do solo, seja alterando os valores enviados pelo sensor virtual ou alterando os níveis de humidade do solo ao adicionar água ou remover o sensor do solo. - -## Temporização de sensores e atuadores - -Na lição 3, construíste uma luz noturna - um LED que se acende assim que um nível baixo de luz é detetado por um sensor de luz. O sensor de luz detetava uma mudança nos níveis de luz instantaneamente, e o dispositivo conseguia responder rapidamente, limitado apenas pelo comprimento do atraso na função `loop` ou no ciclo `while True:`. Como programador de IoT, não podes sempre contar com um ciclo de feedback tão rápido. - -### Temporização para humidade do solo - -Se fizeste a última lição sobre humidade do solo usando um sensor físico, terás notado que demorava alguns segundos para a leitura de humidade do solo diminuir após regares a tua planta. Isto não acontece porque o sensor é lento, mas porque a água demora a infiltrar-se no solo. -💁 Se regou muito perto do sensor, pode ter notado que a leitura desceu rapidamente e depois voltou a subir - isto acontece porque a água próxima do sensor se espalha pelo resto do solo, reduzindo a humidade do solo junto ao sensor. -![Uma medição de humidade do solo de 658 não muda durante a rega, só cai para 320 após a rega quando a água penetra no solo](../../../../../translated_images/pt-PT/soil-moisture-travel.a0e31af222cf1438.webp) - -No diagrama acima, uma leitura de humidade do solo mostra 658. A planta é regada, mas esta leitura não muda imediatamente, pois a água ainda não chegou ao sensor. A rega pode até terminar antes que a água alcance o sensor e o valor diminua para refletir o novo nível de humidade. - -Se estivesse a escrever código para controlar um sistema de irrigação através de um relé com base nos níveis de humidade do solo, teria de levar este atraso em consideração e implementar uma temporização mais inteligente no seu dispositivo IoT. - -✅ Reserve um momento para pensar em como poderia fazer isso. - -### Controlar a temporização do sensor e do atuador - -Imagine que lhe foi atribuída a tarefa de construir um sistema de irrigação para uma quinta. Com base no tipo de solo, descobriu-se que o nível ideal de humidade do solo para as plantas cultivadas corresponde a uma leitura de tensão analógica entre 400 e 450. - -Poderia programar o dispositivo da mesma forma que uma luz noturna - sempre que o sensor lê acima de 450, ligar um relé para ativar uma bomba. O problema é que a água demora algum tempo a passar da bomba, através do solo, até ao sensor. O sensor irá parar a água quando detetar um nível de 450, mas o nível de água continuará a cair à medida que a água bombeada continua a infiltrar-se no solo. O resultado final é desperdício de água e o risco de danificar as raízes. - -✅ Lembre-se - demasiada água pode ser tão prejudicial para as plantas quanto pouca água, além de desperdiçar um recurso precioso. - -A melhor solução é compreender que existe um atraso entre o momento em que o atuador é ativado e a alteração da propriedade que o sensor lê. Isto significa que não só o sensor deve esperar algum tempo antes de medir novamente o valor, como também o atuador precisa de ser desligado durante algum tempo antes de a próxima medição do sensor ser realizada. - -Quanto tempo deve o relé estar ligado de cada vez? É melhor pecar por excesso de cautela e ligar o relé apenas por um curto período, depois esperar que a água se infiltre e, em seguida, voltar a verificar os níveis de humidade. Afinal, pode sempre ligar novamente para adicionar mais água, mas não pode retirar água do solo. - -> 💁 Este tipo de controlo de temporização é muito específico para o dispositivo IoT que está a construir, a propriedade que está a medir e os sensores e atuadores utilizados. - -![Uma planta de morango conectada a água através de uma bomba, com a bomba ligada a um relé. O relé e um sensor de humidade do solo na planta estão ambos conectados a um Raspberry Pi](../../../../../translated_images/pt-PT/strawberry-with-pump.b410fc72ac6aabad.webp) - -Por exemplo, tenho uma planta de morango com um sensor de humidade do solo e uma bomba controlada por um relé. Observei que, quando adiciono água, demora cerca de 20 segundos para a leitura de humidade do solo estabilizar. Isto significa que preciso de desligar o relé e esperar 20 segundos antes de verificar os níveis de humidade. Prefiro ter pouca água do que demasiada - posso sempre ligar a bomba novamente, mas não posso retirar água da planta. - -![Passo 1, medir. Passo 2, adicionar água. Passo 3, esperar que a água se infiltre no solo. Passo 4, medir novamente](../../../../../translated_images/pt-PT/soil-moisture-delay.865f3fae206db01d.webp) - -Isto significa que o melhor processo seria um ciclo de rega semelhante a: - -* Ligar a bomba durante 5 segundos -* Esperar 20 segundos -* Verificar a humidade do solo -* Se o nível ainda estiver acima do necessário, repetir os passos acima - -5 segundos podem ser demasiado tempo para a bomba, especialmente se os níveis de humidade estiverem apenas ligeiramente acima do nível necessário. A melhor forma de saber qual a temporização a usar é experimentando e ajustando com base nos dados do sensor, num ciclo constante de feedback. Isto pode até levar a uma temporização mais granular, como ligar a bomba durante 1 segundo para cada 100 acima do nível de humidade necessário, em vez de um tempo fixo de 5 segundos. - -✅ Faça uma pesquisa: Existem outras considerações de temporização? A planta pode ser regada a qualquer momento em que a humidade do solo esteja baixa, ou existem horários específicos do dia que são bons ou maus para regar as plantas? - -> 💁 As previsões meteorológicas também podem ser consideradas ao controlar sistemas de rega automatizados para cultivo ao ar livre. Se houver previsão de chuva, a rega pode ser adiada até que a chuva termine. Nesse ponto, o solo pode estar suficientemente húmido, eliminando a necessidade de rega, o que é muito mais eficiente do que desperdiçar água ao regar antes da chuva. - -## Adicionar temporização ao servidor de controlo da planta - -O código do servidor pode ser modificado para adicionar controlo em torno da temporização do ciclo de rega e da espera pelos níveis de humidade do solo para mudarem. A lógica do servidor para controlar a temporização do relé é: - -1. Mensagem de telemetria recebida -1. Verificar o nível de humidade do solo -1. Se estiver ok, não fazer nada. Se a leitura for demasiado alta (significando que a humidade do solo está demasiado baixa), então: - 1. Enviar um comando para ligar o relé - 1. Esperar 5 segundos - 1. Enviar um comando para desligar o relé - 1. Esperar 20 segundos para os níveis de humidade do solo estabilizarem - -O ciclo de rega, o processo desde a receção da mensagem de telemetria até estar pronto para processar novamente os níveis de humidade do solo, demora cerca de 25 segundos. Estamos a enviar os níveis de humidade do solo a cada 10 segundos, por isso há uma sobreposição em que uma mensagem é recebida enquanto o servidor está a aguardar a estabilização dos níveis de humidade do solo, o que pode iniciar outro ciclo de rega. - -Existem duas opções para contornar isto: - -* Alterar o código do dispositivo IoT para enviar telemetria apenas a cada minuto, garantindo que o ciclo de rega será concluído antes de a próxima mensagem ser enviada -* Cancelar a subscrição da telemetria durante o ciclo de rega - -A primeira opção nem sempre é uma boa solução para grandes quintas. O agricultor pode querer capturar os níveis de humidade do solo enquanto o solo está a ser regado para análise posterior, por exemplo, para estar ciente do fluxo de água em diferentes áreas da quinta e orientar uma rega mais direcionada. A segunda opção é melhor - o código simplesmente ignora a telemetria quando não pode usá-la, mas a telemetria ainda está disponível para outros serviços que possam subscrever-se a ela. - -> 💁 Os dados IoT não são enviados de apenas um dispositivo para apenas um serviço; em vez disso, muitos dispositivos podem enviar dados para um broker, e muitos serviços podem ouvir os dados do broker. Por exemplo, um serviço pode ouvir os dados de humidade do solo e armazená-los numa base de dados para análise posterior. Outro serviço pode também ouvir a mesma telemetria para controlar um sistema de irrigação. - -### Tarefa - adicionar temporização ao servidor de controlo da planta - -Atualize o código do servidor para executar o relé durante 5 segundos e, em seguida, esperar 20 segundos. - -1. Abra a pasta `soil-moisture-sensor-server` no VS Code, se ainda não estiver aberta. Certifique-se de que o ambiente virtual está ativado. - -1. Abra o ficheiro `app.py`. - -1. Adicione o seguinte código ao ficheiro `app.py` abaixo das importações existentes: - - ```python - import threading - ``` - - Esta instrução importa `threading` das bibliotecas Python. O threading permite que o Python execute outro código enquanto espera. - -1. Adicione o seguinte código antes da função `handle_telemetry` que processa as mensagens de telemetria recebidas pelo código do servidor: - - ```python - water_time = 5 - wait_time = 20 - ``` - - Isto define quanto tempo o relé deve funcionar (`water_time`) e quanto tempo deve esperar depois para verificar a humidade do solo (`wait_time`). - -1. Abaixo deste código, adicione o seguinte: - - ```python - def send_relay_command(client, state): - command = { 'relay_on' : state } - print("Sending message:", command) - client.publish(server_command_topic, json.dumps(command)) - ``` - - Este código define uma função chamada `send_relay_command` que envia um comando via MQTT para controlar o relé. A telemetria é criada como um dicionário e, em seguida, convertida numa string JSON. O valor passado para `state` determina se o relé deve estar ligado ou desligado. - -1. Após a função `send_relay_command`, adicione o seguinte código: - - ```python - def control_relay(client): - print("Unsubscribing from telemetry") - mqtt_client.unsubscribe(client_telemetry_topic) - - send_relay_command(client, True) - time.sleep(water_time) - send_relay_command(client, False) - - time.sleep(wait_time) - - print("Subscribing to telemetry") - mqtt_client.subscribe(client_telemetry_topic) - ``` - - Isto define uma função para controlar o relé com base na temporização necessária. Começa por cancelar a subscrição da telemetria para que as mensagens de humidade do solo não sejam processadas enquanto a rega está a decorrer. Em seguida, envia um comando para ligar o relé. Depois, espera pelo `water_time` antes de enviar um comando para desligar o relé. Finalmente, espera que os níveis de humidade do solo estabilizem durante `wait_time` segundos. Depois, volta a subscrever-se à telemetria. - -1. Altere a função `handle_telemetry` para o seguinte: - - ```python - def handle_telemetry(client, userdata, message): - payload = json.loads(message.payload.decode()) - print("Message received:", payload) - - if payload['soil_moisture'] > 450: - threading.Thread(target=control_relay, args=(client,)).start() - ``` - - Este código verifica o nível de humidade do solo. Se for superior a 450, o solo precisa de ser regado, por isso chama a função `control_relay`. Esta função é executada numa thread separada, em segundo plano. - -1. Certifique-se de que o seu dispositivo IoT está a funcionar e, em seguida, execute este código. Altere os níveis de humidade do solo e observe o que acontece ao relé - ele deve ligar-se durante 5 segundos e, em seguida, permanecer desligado por pelo menos 20 segundos, ligando-se apenas se os níveis de humidade do solo não forem suficientes. - - ```output - (.venv) ➜ soil-moisture-sensor-server ✗ python app.py - Message received: {'soil_moisture': 457} - Unsubscribing from telemetry - Sending message: {'relay_on': True} - Sending message: {'relay_on': False} - Subscribing to telemetry - Message received: {'soil_moisture': 302} - ``` - - Uma boa forma de testar isto num sistema de irrigação simulado é usar solo seco e, em seguida, adicionar água manualmente enquanto o relé está ligado, parando de adicionar água quando o relé se desliga. - -> 💁 Pode encontrar este código na pasta [code-timing](../../../../../2-farm/lessons/3-automated-plant-watering/code-timing). - -> 💁 Se quiser usar uma bomba para construir um sistema de irrigação real, pode usar uma [bomba de água de 6V](https://www.seeedstudio.com/6V-Mini-Water-Pump-p-1945.html) com uma [fonte de alimentação USB](https://www.adafruit.com/product/3628). Certifique-se de que a energia para ou da bomba está conectada através do relé. - ---- - -## 🚀 Desafio - -Consegue pensar noutros dispositivos IoT ou elétricos que tenham um problema semelhante, onde demora algum tempo para os resultados do atuador chegarem ao sensor? Provavelmente tem alguns em sua casa ou escola. - -* Que propriedades medem? -* Quanto tempo demora para a propriedade mudar após o uso do atuador? -* É aceitável que a propriedade ultrapasse o valor necessário? -* Como pode ser retornada ao valor necessário, se necessário? - -## Questionário pós-aula - -[Questionário pós-aula](https://black-meadow-040d15503.1.azurestaticapps.net/quiz/14) - -## Revisão e Autoestudo - -* Leia mais sobre relés, incluindo o seu uso histórico em centrais telefónicas, na [página da Wikipédia sobre relés](https://wikipedia.org/wiki/Relay). - -## Tarefa - -[Construa um ciclo de rega mais eficiente](assignment.md) - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, é importante notar que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes da utilização desta tradução. \ No newline at end of file diff --git a/translations/pt/2-farm/lessons/3-automated-plant-watering/assignment.md b/translations/pt/2-farm/lessons/3-automated-plant-watering/assignment.md deleted file mode 100644 index 69de9d64e..000000000 --- a/translations/pt/2-farm/lessons/3-automated-plant-watering/assignment.md +++ /dev/null @@ -1,52 +0,0 @@ - -# Construir um ciclo de rega mais eficiente - -## Instruções - -Esta lição abordou como controlar um relé através de dados de sensores, e esse relé, por sua vez, pode controlar uma bomba para um sistema de irrigação. Para um volume definido de solo, operar uma bomba por um período fixo de tempo deve sempre ter o mesmo impacto na humidade do solo. Isto significa que pode ter uma ideia de quantos segundos de irrigação correspondem a uma determinada redução na leitura da humidade do solo. Usando estes dados, pode construir um sistema de irrigação mais controlado. - -Para esta tarefa, irá calcular quanto tempo a bomba deve funcionar para alcançar um aumento específico na humidade do solo. - -> ⚠️ Se estiver a usar hardware IoT virtual, pode seguir este processo, mas simular os resultados aumentando manualmente a leitura da humidade do solo por uma quantidade fixa por segundo enquanto o relé está ligado. - -1. Comece com o solo seco. Meça a humidade do solo. - -1. Adicione uma quantidade fixa de água, seja operando a bomba durante 1 segundo ou despejando uma quantidade fixa de água. - - > A bomba deve funcionar sempre a uma taxa constante, de modo que, a cada segundo de funcionamento, forneça a mesma quantidade de água. - -1. Aguarde até que o nível de humidade do solo estabilize e faça uma leitura. - -1. Repita este processo várias vezes e crie uma tabela com os resultados. Um exemplo desta tabela é apresentado abaixo. - - | Tempo total da bomba | Humidade do solo | Redução | - | --- | --: | -: | - | Seco | 643 | 0 | - | 1s | 621 | 22 | - | 2s | 601 | 20 | - | 3s | 579 | 22 | - | 4s | 560 | 19 | - | 5s | 539 | 21 | - | 6s | 521 | 18 | - -1. Calcule um aumento médio na humidade do solo por segundo de água. No exemplo acima, cada segundo de água reduz a leitura em uma média de 20,3. - -1. Use estes dados para melhorar a eficiência do código do servidor, fazendo a bomba funcionar pelo tempo necessário para atingir o nível de humidade desejado. - -## Rubrica - -| Critério | Exemplar | Adequado | Necessita de Melhorias | -| -------- | --------- | -------- | ---------------------- | -| Captura de dados de humidade do solo | Consegue capturar várias leituras após adicionar quantidades fixas de água | Consegue capturar algumas leituras com quantidades fixas de água | Só consegue capturar uma ou duas leituras, ou não consegue usar quantidades fixas de água | -| Calibração do código do servidor | Consegue calcular uma redução média na leitura da humidade do solo e atualizar o código do servidor para usar este valor | Consegue calcular uma redução média, mas não consegue atualizar o código do servidor, ou não consegue calcular corretamente uma média, mas usa este valor para atualizar corretamente o código do servidor | Não consegue calcular uma média ou atualizar o código do servidor | - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos pela precisão, esteja ciente de que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes do uso desta tradução. \ No newline at end of file diff --git a/translations/pt/2-farm/lessons/3-automated-plant-watering/pi-relay.md b/translations/pt/2-farm/lessons/3-automated-plant-watering/pi-relay.md deleted file mode 100644 index 4cacda16b..000000000 --- a/translations/pt/2-farm/lessons/3-automated-plant-watering/pi-relay.md +++ /dev/null @@ -1,121 +0,0 @@ - -# Controlar um relé - Raspberry Pi - -Nesta parte da lição, irá adicionar um relé ao seu Raspberry Pi, além do sensor de humidade do solo, e controlá-lo com base no nível de humidade do solo. - -## Hardware - -O Raspberry Pi necessita de um relé. - -O relé que irá utilizar é um [relé Grove](https://www.seeedstudio.com/Grove-Relay.html), um relé normalmente aberto (o que significa que o circuito de saída está aberto, ou desconectado, quando não é enviado nenhum sinal para o relé) que pode lidar com circuitos de saída até 250V e 10A. - -Este é um atuador digital, por isso conecta-se a um pino digital no Grove Base Hat. - -### Ligar o relé - -O relé Grove pode ser ligado ao Raspberry Pi. - -#### Tarefa - -Ligue o relé. - -![Um relé Grove](../../../../../translated_images/pt-PT/grove-relay.d426958ca210fbd0fb7983d7edc069d46c73a8b0a099d94797bd756f7b6bb6be.png) - -1. Insira uma extremidade de um cabo Grove na entrada do relé. Ele só encaixará de uma forma. - -1. Com o Raspberry Pi desligado, conecte a outra extremidade do cabo Grove à entrada digital marcada como **D5** no Grove Base Hat ligado ao Pi. Esta entrada é a segunda da esquerda, na fila de entradas ao lado dos pinos GPIO. Deixe o sensor de humidade do solo conectado à entrada **A0**. - -![O relé Grove conectado à entrada D5 e o sensor de humidade do solo conectado à entrada A0](../../../../../translated_images/pt-PT/pi-relay-and-soil-moisture-sensor.02f3198975b8c53e69ec716cd2719ce117700bd1fc933eaf93476c103c57939b.png) - -1. Insira o sensor de humidade do solo na terra, caso ainda não o tenha feito na lição anterior. - -## Programar o relé - -O Raspberry Pi pode agora ser programado para utilizar o relé conectado. - -### Tarefa - -Programe o dispositivo. - -1. Ligue o Pi e aguarde que ele inicie. - -1. Abra o projeto `soil-moisture-sensor` da última lição no VS Code, caso ainda não esteja aberto. Irá adicionar código a este projeto. - -1. Adicione o seguinte código ao ficheiro `app.py` abaixo das importações existentes: - - ```python - from grove.grove_relay import GroveRelay - ``` - - Esta instrução importa o `GroveRelay` das bibliotecas Python do Grove para interagir com o relé Grove. - -1. Adicione o seguinte código abaixo da declaração da classe `ADC` para criar uma instância de `GroveRelay`: - - ```python - relay = GroveRelay(5) - ``` - - Isto cria um relé utilizando o pino **D5**, o pino digital ao qual conectou o relé. - -1. Para testar se o relé está a funcionar, adicione o seguinte ao ciclo `while True:`: - - ```python - relay.on() - time.sleep(.5) - relay.off() - ``` - - O código liga o relé, espera 0,5 segundos e depois desliga o relé. - -1. Execute a aplicação Python. O relé irá ligar e desligar a cada 10 segundos, com um intervalo de meio segundo entre ligar e desligar. Irá ouvir o relé a clicar ao ligar e a clicar ao desligar. Um LED na placa Grove acenderá quando o relé estiver ligado e apagará quando estiver desligado. - - ![O relé a ligar e desligar](../../../../../images/relay-turn-on-off.gif) - -## Controlar o relé com base na humidade do solo - -Agora que o relé está a funcionar, pode ser controlado em resposta às leituras de humidade do solo. - -### Tarefa - -Controle o relé. - -1. Elimine as 3 linhas de código que adicionou para testar o relé. Substitua-as pelo seguinte código: - - ```python - if soil_moisture > 450: - print("Soil Moisture is too low, turning relay on.") - relay.on() - else: - print("Soil Moisture is ok, turning relay off.") - relay.off() - ``` - - Este código verifica o nível de humidade do solo a partir do sensor de humidade do solo. Se estiver acima de 450, liga o relé, e desliga-o quando estiver abaixo de 450. - - > 💁 Lembre-se de que o sensor capacitivo de humidade do solo lê: quanto mais baixo for o nível de humidade do solo, maior é a humidade na terra, e vice-versa. - -1. Execute a aplicação Python. Verá o relé a ligar ou desligar dependendo do nível de humidade do solo. Experimente em terra seca e depois adicione água. - - ```output - Soil Moisture: 638 - Soil Moisture is too low, turning relay on. - Soil Moisture: 452 - Soil Moisture is too low, turning relay on. - Soil Moisture: 347 - Soil Moisture is ok, turning relay off. - ``` - -> 💁 Pode encontrar este código na pasta [code-relay/pi](../../../../../2-farm/lessons/3-automated-plant-watering/code-relay/pi). - -😀 O seu programa de controlo de um relé com base no sensor de humidade do solo foi um sucesso! - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos pela precisão, esteja ciente de que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes do uso desta tradução. \ No newline at end of file diff --git a/translations/pt/2-farm/lessons/3-automated-plant-watering/virtual-device-relay.md b/translations/pt/2-farm/lessons/3-automated-plant-watering/virtual-device-relay.md deleted file mode 100644 index d7cf18884..000000000 --- a/translations/pt/2-farm/lessons/3-automated-plant-watering/virtual-device-relay.md +++ /dev/null @@ -1,125 +0,0 @@ - -# Controlar um relé - Hardware IoT Virtual - -Nesta parte da lição, irá adicionar um relé ao seu dispositivo IoT virtual, além do sensor de humidade do solo, e controlá-lo com base no nível de humidade do solo. - -## Hardware Virtual - -O dispositivo IoT virtual utilizará um relé simulado Grove. Isto mantém este laboratório semelhante ao uso de um Raspberry Pi com um relé físico Grove. - -Num dispositivo IoT físico, o relé seria um relé normalmente aberto (o que significa que o circuito de saída está aberto, ou desconectado, quando não há sinal enviado para o relé). Um relé deste tipo pode lidar com circuitos de saída até 250V e 10A. - -### Adicionar o relé ao CounterFit - -Para usar um relé virtual, é necessário adicioná-lo à aplicação CounterFit. - -#### Tarefa - -Adicione o relé à aplicação CounterFit. - -1. Abra o projeto `soil-moisture-sensor` da última lição no VS Code, caso ainda não esteja aberto. Irá adicionar a este projeto. - -1. Certifique-se de que a aplicação web CounterFit está em execução. - -1. Crie um relé: - - 1. Na caixa *Create actuator* no painel *Actuators*, abra o menu suspenso *Actuator type* e selecione *Relay*. - - 1. Defina o *Pin* para *5*. - - 1. Selecione o botão **Add** para criar o relé no Pin 5. - - ![As definições do relé](../../../../../translated_images/pt-PT/counterfit-create-relay.fa7c40fd0f2f6afc33b35ea94fcb235085be4861e14e3fe6b9b7bcfc82d1c888.png) - - O relé será criado e aparecerá na lista de atuadores. - - ![O relé criado](../../../../../translated_images/pt-PT/counterfit-relay.bbf74c1dbdc8b9acd983367fcbd06703a402aefef6af54ddb28e11307ba8a12c.png) - -## Programar o relé - -A aplicação do sensor de humidade do solo pode agora ser programada para usar o relé virtual. - -### Tarefa - -Programe o dispositivo virtual. - -1. Abra o projeto `soil-moisture-sensor` da última lição no VS Code, caso ainda não esteja aberto. Irá adicionar a este projeto. - -1. Adicione o seguinte código ao ficheiro `app.py` abaixo das importações existentes: - - ```python - from counterfit_shims_grove.grove_relay import GroveRelay - ``` - - Esta instrução importa o `GroveRelay` das bibliotecas Grove Python shim para interagir com o relé virtual Grove. - -1. Adicione o seguinte código abaixo da declaração da classe `ADC` para criar uma instância de `GroveRelay`: - - ```python - relay = GroveRelay(5) - ``` - - Isto cria um relé utilizando o pin **5**, o pin ao qual conectou o relé. - -1. Para testar se o relé está a funcionar, adicione o seguinte ao ciclo `while True:`: - - ```python - relay.on() - time.sleep(.5) - relay.off() - ``` - - O código liga o relé, espera 0,5 segundos e depois desliga o relé. - -1. Execute a aplicação Python. O relé irá ligar e desligar a cada 10 segundos, com um atraso de meio segundo entre ligar e desligar. Verá o relé virtual na aplicação CounterFit fechar e abrir à medida que o relé é ligado e desligado. - - ![O relé virtual a ligar e desligar](../../../../../images/virtual-relay-turn-on-off.gif) - -## Controlar o relé com base na humidade do solo - -Agora que o relé está a funcionar, pode ser controlado em resposta às leituras de humidade do solo. - -### Tarefa - -Controle o relé. - -1. Elimine as 3 linhas de código que adicionou para testar o relé. Substitua-as pelo seguinte código no mesmo local: - - ```python - if soil_moisture > 450: - print("Soil Moisture is too low, turning relay on.") - relay.on() - else: - print("Soil Moisture is ok, turning relay off.") - relay.off() - ``` - - Este código verifica o nível de humidade do solo a partir do sensor de humidade do solo. Se estiver acima de 450, liga o relé, desligando-o se descer abaixo de 450. - - > 💁 Lembre-se de que o sensor capacitivo de humidade do solo lê: quanto mais baixo o nível de humidade do solo, maior é a humidade no solo, e vice-versa. - -1. Execute a aplicação Python. Verá o relé ligar ou desligar dependendo dos níveis de humidade do solo. Altere o *Value* ou as definições de *Random* para o sensor de humidade do solo para ver o valor mudar. - - ```output - Soil Moisture: 638 - Soil Moisture is too low, turning relay on. - Soil Moisture: 452 - Soil Moisture is too low, turning relay on. - Soil Moisture: 347 - Soil Moisture is ok, turning relay off. - ``` - -> 💁 Pode encontrar este código na pasta [code-relay/virtual-device](../../../../../2-farm/lessons/3-automated-plant-watering/code-relay/virtual-device). - -😀 O seu programa de sensor de humidade do solo virtual a controlar um relé foi um sucesso! - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, é importante notar que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes do uso desta tradução. \ No newline at end of file diff --git a/translations/pt/2-farm/lessons/3-automated-plant-watering/wio-terminal-relay.md b/translations/pt/2-farm/lessons/3-automated-plant-watering/wio-terminal-relay.md deleted file mode 100644 index 56ce5cb8a..000000000 --- a/translations/pt/2-farm/lessons/3-automated-plant-watering/wio-terminal-relay.md +++ /dev/null @@ -1,119 +0,0 @@ - -# Controlar um relé - Wio Terminal - -Nesta parte da lição, vais adicionar um relé ao teu Wio Terminal, além do sensor de humidade do solo, e controlá-lo com base no nível de humidade do solo. - -## Hardware - -O Wio Terminal precisa de um relé. - -O relé que vais usar é um [relé Grove](https://www.seeedstudio.com/Grove-Relay.html), um relé normalmente aberto (o que significa que o circuito de saída está aberto ou desconectado quando não há sinal enviado para o relé) que pode lidar com circuitos de saída até 250V e 10A. - -Este é um atuador digital, por isso conecta-se aos pinos digitais do Wio Terminal. A porta combinada analógica/digital já está a ser usada com o sensor de humidade do solo, por isso este será ligado à outra porta, que é uma porta combinada I2C e digital. - -### Ligar o relé - -O relé Grove pode ser ligado à porta digital do Wio Terminal. - -#### Tarefa - -Liga o relé. - -![Um relé Grove](../../../../../translated_images/pt-PT/grove-relay.d426958ca210fbd0fb7983d7edc069d46c73a8b0a099d94797bd756f7b6bb6be.png) - -1. Insere uma extremidade de um cabo Grove na entrada do relé. Só encaixará de uma forma. - -1. Com o Wio Terminal desconectado do computador ou de outra fonte de energia, liga a outra extremidade do cabo Grove à entrada Grove do lado esquerdo do Wio Terminal, olhando para o ecrã. Deixa o sensor de humidade do solo ligado à entrada do lado direito. - -![O relé Grove ligado à entrada do lado esquerdo e o sensor de humidade do solo ligado à entrada do lado direito](../../../../../translated_images/pt-PT/wio-relay-and-soil-moisture-sensor.ed722202d42babe0.webp) - -1. Insere o sensor de humidade do solo na terra, caso ainda não esteja inserido da lição anterior. - -## Programar o relé - -Agora o Wio Terminal pode ser programado para usar o relé ligado. - -### Tarefa - -Programa o dispositivo. - -1. Abre o projeto `soil-moisture-sensor` da última lição no VS Code, caso ainda não esteja aberto. Vais adicionar código a este projeto. - -2. Não existe uma biblioteca para este atuador - é um atuador digital controlado por um sinal alto ou baixo. Para o ligar, envias um sinal alto para o pino (3.3V); para o desligar, envias um sinal baixo (0V). Podes fazer isso usando a função [`digitalWrite`](https://www.arduino.cc/reference/en/language/functions/digital-io/digitalwrite/) integrada no Arduino. Começa por adicionar o seguinte ao final da função `setup` para configurar a porta combinada I2C/digital como um pino de saída para enviar uma tensão ao relé: - - ```cpp - pinMode(PIN_WIRE_SCL, OUTPUT); - ``` - - `PIN_WIRE_SCL` é o número da porta para a porta combinada I2C/digital. - -1. Para testar se o relé está a funcionar, adiciona o seguinte à função `loop`, abaixo do último `delay`: - - ```cpp - digitalWrite(PIN_WIRE_SCL, HIGH); - delay(500); - digitalWrite(PIN_WIRE_SCL, LOW); - ``` - - O código envia um sinal alto para o pino ao qual o relé está ligado para o ligar, espera 500ms (meio segundo) e depois envia um sinal baixo para o desligar. - -1. Compila e carrega o código para o Wio Terminal. - -1. Depois de carregado, o relé irá ligar e desligar a cada 10 segundos, com um atraso de meio segundo entre ligar e desligar. Vais ouvir o relé a clicar ao ligar e a clicar ao desligar. Um LED na placa Grove acenderá quando o relé estiver ligado e apagará quando estiver desligado. - - ![O relé a ligar e desligar](../../../../../images/relay-turn-on-off.gif) - -## Controlar o relé com base na humidade do solo - -Agora que o relé está a funcionar, pode ser controlado em resposta às leituras de humidade do solo. - -### Tarefa - -Controla o relé. - -1. Apaga as 3 linhas de código que adicionaste para testar o relé. Substitui-as pelo seguinte código: - - ```cpp - if (soil_moisture > 450) - { - Serial.println("Soil Moisture is too low, turning relay on."); - digitalWrite(PIN_WIRE_SCL, HIGH); - } - else - { - Serial.println("Soil Moisture is ok, turning relay off."); - digitalWrite(PIN_WIRE_SCL, LOW); - } - ``` - - Este código verifica o nível de humidade do solo a partir do sensor de humidade do solo. Se estiver acima de 450, liga o relé; se estiver abaixo de 450, desliga-o. - - > 💁 Lembra-te de que o sensor de humidade do solo capacitivo lê: quanto mais baixo o nível de humidade do solo, mais húmido está o solo, e vice-versa. - -1. Compila e carrega o código para o Wio Terminal. - -1. Monitoriza o dispositivo através do monitor serial. Vais ver o relé a ligar ou desligar dependendo do nível de humidade do solo. Experimenta em solo seco e depois adiciona água. - - ```output - Soil Moisture: 638 - Soil Moisture is too low, turning relay on. - Soil Moisture: 452 - Soil Moisture is too low, turning relay on. - Soil Moisture: 347 - Soil Moisture is ok, turning relay off. - ``` - -> 💁 Podes encontrar este código na pasta [code-relay/wio-terminal](../../../../../2-farm/lessons/3-automated-plant-watering/code-relay/wio-terminal). - -😀 O teu programa de controlo de relé com base no sensor de humidade do solo foi um sucesso! - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, é importante notar que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes do uso desta tradução. \ No newline at end of file diff --git a/translations/pt/2-farm/lessons/4-migrate-your-plant-to-the-cloud/README.md b/translations/pt/2-farm/lessons/4-migrate-your-plant-to-the-cloud/README.md deleted file mode 100644 index f8eeaa2ec..000000000 --- a/translations/pt/2-farm/lessons/4-migrate-your-plant-to-the-cloud/README.md +++ /dev/null @@ -1,449 +0,0 @@ - -# Migre a sua planta para a nuvem - -![Uma visão geral ilustrada desta lição](../../../../../translated_images/pt-PT/lesson-8.3f21f3c11159e6a0a376351973ea5724d5de68fa23b4288853a174bed9ac48c3.jpg) - -> Ilustração por [Nitya Narasimhan](https://github.com/nitya). Clique na imagem para uma versão maior. - -Esta lição foi ensinada como parte da série [IoT para Iniciantes - Agricultura Digital, Projeto 2](https://youtube.com/playlist?list=PLmsFUfdnGr3yCutmcVg6eAUEfsGiFXgcx) do [Microsoft Reactor](https://developer.microsoft.com/reactor/?WT.mc_id=academic-17441-jabenn). - -[![Conecte o seu dispositivo à nuvem com o Azure IoT Hub](https://img.youtube.com/vi/bNxjopXkhvk/0.jpg)](https://youtu.be/bNxjopXkhvk) - -## Questionário pré-aula - -[Questionário pré-aula](https://black-meadow-040d15503.1.azurestaticapps.net/quiz/15) - -## Introdução - -Na última lição, aprendeu a conectar a sua planta a um broker MQTT e a controlar um relé a partir de código de servidor executado localmente. Isso forma o núcleo de um sistema automatizado de irrigação conectado à internet, usado desde plantas individuais em casa até grandes explorações agrícolas comerciais. - -O dispositivo IoT comunicou-se com um broker MQTT público para demonstrar os princípios, mas esta não é a forma mais confiável ou segura. Nesta lição, aprenderá sobre a nuvem e as capacidades de IoT fornecidas por serviços de nuvem pública. Também aprenderá como migrar a sua planta para um desses serviços de nuvem a partir do broker MQTT público. - -Nesta lição, abordaremos: - -* [O que é a nuvem?](../../../../../2-farm/lessons/4-migrate-your-plant-to-the-cloud) -* [Criar uma subscrição na nuvem](../../../../../2-farm/lessons/4-migrate-your-plant-to-the-cloud) -* [Serviços de IoT na nuvem](../../../../../2-farm/lessons/4-migrate-your-plant-to-the-cloud) -* [Criar um serviço de IoT na nuvem](../../../../../2-farm/lessons/4-migrate-your-plant-to-the-cloud) -* [Comunicar com o IoT Hub](../../../../../2-farm/lessons/4-migrate-your-plant-to-the-cloud) -* [Conectar o seu dispositivo ao serviço de IoT](../../../../../2-farm/lessons/4-migrate-your-plant-to-the-cloud) - -## O que é a nuvem? - -Antes da nuvem, quando uma empresa queria fornecer serviços aos seus funcionários (como bases de dados ou armazenamento de ficheiros) ou ao público (como websites), construía e geria um centro de dados. Isso podia variar desde uma sala com poucos computadores até um edifício com muitos computadores. A empresa geria tudo, incluindo: - -* Compra de computadores -* Manutenção de hardware -* Energia e refrigeração -* Rede -* Segurança, incluindo a segurança do edifício e do software nos computadores -* Instalação e atualização de software - -Isso podia ser muito caro, exigir uma ampla gama de funcionários especializados e ser muito lento para mudar quando necessário. Por exemplo, se uma loja online precisasse de se preparar para uma época de férias movimentada, teria de planear meses antes para comprar mais hardware, configurá-lo, instalá-lo e instalar o software para gerir o processo de vendas. Após a época de férias terminar e as vendas diminuírem, ficariam com computadores pagos mas inativos até à próxima época movimentada. - -✅ Acha que isso permitiria às empresas moverem-se rapidamente? Se uma loja de roupas online se tornasse popular de repente porque uma celebridade foi vista com as suas roupas, conseguiria aumentar rapidamente a capacidade computacional para suportar o aumento repentino de pedidos? - -### O computador de outra pessoa - -A nuvem é frequentemente referida de forma humorística como "o computador de outra pessoa". A ideia inicial era simples - em vez de comprar computadores, aluga-se o computador de outra pessoa. Outra pessoa, um fornecedor de computação em nuvem, geriria enormes centros de dados. Eles seriam responsáveis por comprar e instalar o hardware, gerir energia e refrigeração, rede, segurança do edifício, atualizações de hardware e software, tudo. Como cliente, aluga-se os computadores necessários, alugando mais conforme a procura aumenta e reduzindo o número alugado se a procura diminuir. Esses centros de dados na nuvem estão espalhados pelo mundo. - -![Um centro de dados na nuvem da Microsoft](../../../../../translated_images/pt-PT/azure-region-existing.73f704604f2aa6cb9b5a49ed40e93d4fd81ae3f4e6af4a8ca504023902832f56.png) -![Expansão planeada de um centro de dados na nuvem da Microsoft](../../../../../translated_images/pt-PT/azure-region-planned-expansion.a5074a1e8af74f156a73552d502429e5b126ea5019274d767ecb4b9afdad442b.png) - -Esses centros de dados podem ter vários quilómetros quadrados de tamanho. As imagens acima foram tiradas há alguns anos num centro de dados na nuvem da Microsoft e mostram o tamanho inicial, juntamente com uma expansão planeada. A área limpa para a expansão tem mais de 5 quilómetros quadrados. - -> 💁 Esses centros de dados requerem quantidades tão grandes de energia que alguns têm as suas próprias centrais elétricas. Devido ao seu tamanho e ao nível de investimento dos fornecedores de nuvem, geralmente são muito ecológicos. São mais eficientes do que grandes números de pequenos centros de dados, funcionam principalmente com energia renovável e os fornecedores de nuvem trabalham arduamente para reduzir desperdícios, cortar o uso de água e replantar florestas para compensar as que foram derrubadas para fornecer espaço para construir centros de dados. Pode ler mais sobre como um fornecedor de nuvem está a trabalhar na sustentabilidade no [site de sustentabilidade do Azure](https://azure.microsoft.com/global-infrastructure/sustainability/?WT.mc_id=academic-17441-jabenn). - -✅ Faça uma pesquisa: Leia sobre as principais nuvens, como [Azure da Microsoft](https://azure.microsoft.com/?WT.mc_id=academic-17441-jabenn) ou [GCP da Google](https://cloud.google.com). Quantos centros de dados têm e onde estão localizados no mundo? - -Usar a nuvem reduz os custos para as empresas e permite que se concentrem no que fazem melhor, deixando a especialização em computação na nuvem nas mãos do fornecedor. As empresas já não precisam de alugar ou comprar espaço em centros de dados, pagar a diferentes fornecedores por conectividade e energia ou contratar especialistas. Em vez disso, podem pagar uma única fatura mensal ao fornecedor de nuvem para que tudo seja tratado. - -O fornecedor de nuvem pode então usar economias de escala para reduzir os custos, comprando computadores em grandes quantidades a preços mais baixos, investindo em ferramentas para reduzir o trabalho de manutenção e até projetando e construindo o seu próprio hardware para melhorar a oferta de nuvem. - -### Microsoft Azure - -Azure é a nuvem para desenvolvedores da Microsoft, e será a nuvem que usará nestas lições. O vídeo abaixo oferece uma breve visão geral do Azure: - -[![Vídeo de visão geral do Azure](../../../../../translated_images/pt-PT/what-is-azure-video-thumbnail.20174db09e03bbb8.webp)](https://www.microsoft.com/videoplayer/embed/RE4Ibng?WT.mc_id=academic-17441-jabenn) - -## Criar uma subscrição na nuvem - -Para usar serviços na nuvem, precisará de se inscrever numa subscrição com um fornecedor de nuvem. Para esta lição, inscrever-se-á numa subscrição do Microsoft Azure. Se já tiver uma subscrição do Azure, pode ignorar esta tarefa. Os detalhes da subscrição descritos aqui estão corretos no momento da escrita, mas podem mudar. - -> 💁 Se estiver a aceder a estas lições através da sua escola, pode já ter uma subscrição do Azure disponível. Verifique com o seu professor. - -Existem dois tipos diferentes de subscrição gratuita do Azure que pode inscrever-se: - -* **Azure para Estudantes** - Esta é uma subscrição projetada para estudantes com 18 anos ou mais. Não precisa de um cartão de crédito para se inscrever e usa o endereço de email da sua escola para validar que é estudante. Ao inscrever-se, recebe US$100 para gastar em recursos na nuvem, juntamente com serviços gratuitos, incluindo uma versão gratuita de um serviço de IoT. Isso dura 12 meses e pode renovar todos os anos enquanto continuar a ser estudante. - -* **Subscrição gratuita do Azure** - Esta é uma subscrição para qualquer pessoa que não seja estudante. Precisará de um cartão de crédito para se inscrever, mas o seu cartão não será cobrado, sendo usado apenas para verificar que é uma pessoa real, não um bot. Recebe $200 de crédito para usar nos primeiros 30 dias em qualquer serviço, juntamente com níveis gratuitos de serviços do Azure. Depois de usar o crédito, o seu cartão não será cobrado, a menos que converta para uma subscrição paga conforme o uso. - -> 💁 A Microsoft oferece uma subscrição Azure para Estudantes Starter para estudantes com menos de 18 anos, mas no momento da escrita isso não suporta serviços de IoT. - -### Tarefa - inscrever-se numa subscrição gratuita na nuvem - -Se for estudante com 18 anos ou mais, pode inscrever-se numa subscrição Azure para Estudantes. Precisará de validar com um endereço de email da escola. Pode fazer isso de duas formas: - -* Inscreva-se num pacote de desenvolvedor estudante do GitHub em [education.github.com/pack](https://education.github.com/pack). Isso dá-lhe acesso a uma variedade de ferramentas e ofertas, incluindo GitHub e Microsoft Azure. Depois de se inscrever no pacote de desenvolvedor, pode ativar a oferta Azure para Estudantes. - -* Inscreva-se diretamente numa conta Azure para Estudantes em [azure.microsoft.com/free/students](https://azure.microsoft.com/free/students/?WT.mc_id=academic-17441-jabenn). - -> ⚠️ Se o endereço de email da sua escola não for reconhecido, abra um [issue neste repositório](https://github.com/Microsoft/IoT-For-Beginners/issues) e veremos se pode ser adicionado à lista de permissões do Azure para Estudantes. - -Se não for estudante ou não tiver um endereço de email válido da escola, pode inscrever-se numa subscrição gratuita do Azure. - -* Inscreva-se numa subscrição gratuita do Azure em [azure.microsoft.com/free](https://azure.microsoft.com/free/?WT.mc_id=academic-17441-jabenn) - -## Serviços de IoT na nuvem - -O broker MQTT público de teste que tem usado é uma ótima ferramenta para aprender, mas tem várias desvantagens como ferramenta para uso comercial: - -* Confiabilidade - é um serviço gratuito sem garantias e pode ser desligado a qualquer momento -* Segurança - é público, então qualquer pessoa pode ouvir a sua telemetria ou enviar comandos para controlar o seu hardware -* Desempenho - foi projetado para apenas algumas mensagens de teste, então não suportaria um grande volume de mensagens enviadas -* Descoberta - não há como saber quais dispositivos estão conectados - -Os serviços de IoT na nuvem resolvem esses problemas. São mantidos por grandes fornecedores de nuvem que investem fortemente em confiabilidade e estão disponíveis para resolver quaisquer problemas que possam surgir. Têm segurança integrada para impedir que hackers leiam os seus dados ou enviem comandos maliciosos. Também têm alto desempenho, sendo capazes de lidar com muitos milhões de mensagens todos os dias, aproveitando a nuvem para escalar conforme necessário. - -> 💁 Embora pague por essas vantagens com uma taxa mensal, a maioria dos fornecedores de nuvem oferece uma versão gratuita do seu serviço de IoT com um número limitado de mensagens por dia ou dispositivos que podem conectar-se. Essa versão gratuita geralmente é mais do que suficiente para um desenvolvedor aprender sobre o serviço. Nesta lição, usará uma versão gratuita. - -Os dispositivos IoT conectam-se a um serviço na nuvem usando um SDK de dispositivo (uma biblioteca que fornece código para trabalhar com os recursos do serviço) ou diretamente através de um protocolo de comunicação como MQTT ou HTTP. O SDK de dispositivo geralmente é a rota mais fácil, pois lida com tudo para si, como saber quais tópicos publicar ou subscrever e como lidar com a segurança. - -![Dispositivos conectam-se a um serviço usando um SDK de dispositivo. Código de servidor também conecta-se ao serviço via SDK](../../../../../translated_images/pt-PT/iot-service-connectivity.7e873847921a5d6fd60d0ba3a943210194518cee0d4e362476624316443275c3.png) - -O seu dispositivo então comunica com outras partes da sua aplicação através deste serviço - semelhante à forma como enviou telemetria e recebeu comandos via MQTT. Isso geralmente é feito usando um SDK de serviço ou uma biblioteca semelhante. As mensagens vêm do seu dispositivo para o serviço, onde outros componentes da sua aplicação podem lê-las, e as mensagens podem ser enviadas de volta para o seu dispositivo. - -![Dispositivos sem uma chave secreta válida não podem conectar-se ao serviço de IoT](../../../../../translated_images/pt-PT/iot-service-allowed-denied-connection.818b0063ac213fb84204a7229303764d9b467ca430fb822b4ac2fca267d56726.png) - -Esses serviços implementam segurança ao conhecer todos os dispositivos que podem conectar-se e enviar dados, seja pré-registrando os dispositivos no serviço ou fornecendo aos dispositivos chaves secretas ou certificados que podem usar para se registrar no serviço na primeira vez que se conectarem. Dispositivos desconhecidos não conseguem conectar-se; se tentarem, o serviço rejeita a conexão e ignora as mensagens enviadas por eles. - -✅ Faça uma pesquisa: Qual é a desvantagem de ter um serviço de IoT aberto onde qualquer dispositivo ou código pode conectar-se? Consegue encontrar exemplos específicos de hackers que tiraram proveito disso? - -Outros componentes da sua aplicação podem conectar-se ao serviço de IoT e aprender sobre todos os dispositivos que estão conectados ou registrados, e comunicar com eles diretamente, seja em massa ou individualmente. -💁 Os serviços de IoT também implementam capacidades adicionais, e os fornecedores de cloud têm serviços e aplicações adicionais que podem ser ligados ao serviço. Por exemplo, se quiser armazenar todas as mensagens de telemetria enviadas por todos os dispositivos numa base de dados, geralmente basta alguns cliques na ferramenta de configuração do fornecedor de cloud para ligar o serviço a uma base de dados e transmitir os dados. -## Criar um serviço IoT na nuvem - -Agora que tem uma subscrição do Azure, pode inscrever-se num serviço IoT. O serviço IoT da Microsoft chama-se Azure IoT Hub. - -![O logótipo do Azure IoT Hub](../../../../../translated_images/pt-PT/azure-iot-hub-logo.28a19de76d0a1932464d858f7558712bcdace3e5ec69c434d482ed7ce41c3a26.png) - -O vídeo abaixo oferece uma breve visão geral do Azure IoT Hub: - -[![Visão geral do vídeo do Azure IoT Hub](https://img.youtube.com/vi/smuZaZZXKsU/0.jpg)](https://www.youtube.com/watch?v=smuZaZZXKsU) - -> 🎥 Clique na imagem acima para assistir ao vídeo - -✅ Dedique um momento para pesquisar e ler a visão geral do IoT Hub na [documentação do Microsoft IoT Hub](https://docs.microsoft.com/azure/iot-hub/about-iot-hub?WT.mc_id=academic-17441-jabenn). - -Os serviços na nuvem disponíveis no Azure podem ser configurados através de um portal baseado na web ou de uma interface de linha de comando (CLI). Para esta tarefa, irá utilizar o CLI. - -### Tarefa - instalar o Azure CLI - -Para usar o Azure CLI, primeiro precisa de instalá-lo no seu PC ou Mac. - -1. Siga as instruções na [documentação do Azure CLI](https://docs.microsoft.com/cli/azure/install-azure-cli?WT.mc_id=academic-17441-jabenn) para instalar o CLI. - -1. O Azure CLI suporta várias extensões que adicionam capacidades para gerir uma ampla gama de serviços do Azure. Instale a extensão IoT executando o seguinte comando na sua linha de comando ou terminal: - - ```sh - az extension add --name azure-iot - ``` - -1. Na sua linha de comando ou terminal, execute o seguinte comando para iniciar sessão na sua subscrição do Azure a partir do Azure CLI. - - ```sh - az login - ``` - - Uma página web será aberta no seu navegador padrão. Inicie sessão usando a conta que utilizou para se inscrever na sua subscrição do Azure. Depois de iniciar sessão, pode fechar o separador do navegador. - -1. Se tiver várias subscrições do Azure, como uma fornecida pela escola e a sua própria subscrição do Azure para Estudantes, precisará de selecionar a que deseja usar. Execute o seguinte comando para listar todas as subscrições às quais tem acesso: - - ```sh - az account list --output table - ``` - - Na saída, verá o nome de cada subscrição juntamente com o seu `SubscriptionId`. - - ```output - ➜ ~ az account list --output table - Name CloudName SubscriptionId State IsDefault - ---------------------- ----------- ------------------------------------ ------- ----------- - School-subscription AzureCloud cb30cde9-814a-42f0-a111-754cb788e4e1 Enabled True - Azure for Students AzureCloud fa51c31b-162c-4599-add6-781def2e1fbf Enabled False - ``` - - Para selecionar a subscrição que deseja usar, utilize o seguinte comando: - - ```sh - az account set --subscription - ``` - - Substitua `` pelo Id da subscrição que deseja usar. Depois de executar este comando, volte a executar o comando para listar as suas contas. Verá que a coluna `IsDefault` estará marcada como `True` para a subscrição que acabou de definir. - -### Tarefa - criar um grupo de recursos - -Os serviços do Azure, como instâncias do IoT Hub, máquinas virtuais, bases de dados ou serviços de IA, são referidos como **recursos**. Cada recurso precisa de estar dentro de um **Grupo de Recursos**, uma agrupação lógica de um ou mais recursos. - -> 💁 Usar grupos de recursos significa que pode gerir vários serviços de uma só vez. Por exemplo, depois de concluir todas as lições deste projeto, pode eliminar o grupo de recursos, e todos os recursos nele serão eliminados automaticamente. - -1. Existem vários centros de dados do Azure em todo o mundo, divididos em regiões. Quando cria um recurso ou grupo de recursos no Azure, precisa de especificar onde deseja que seja criado. Execute o seguinte comando para obter a lista de localizações: - - ```sh - az account list-locations --output table - ``` - - Verá uma lista de localizações. Esta lista será longa. - - > 💁 No momento da escrita, existem 65 localizações onde pode fazer a implementação. - - ```output - ➜ ~ az account list-locations --output table - DisplayName Name RegionalDisplayName - ------------------------ ------------------- ------------------------------------- - East US eastus (US) East US - East US 2 eastus2 (US) East US 2 - South Central US southcentralus (US) South Central US - ... - ``` - - Anote o valor da coluna `Name` da região mais próxima de si. Pode encontrar as regiões num mapa na [página de geografias do Azure](https://azure.microsoft.com/global-infrastructure/geographies/?WT.mc_id=academic-17441-jabenn). - -1. Execute o seguinte comando para criar um grupo de recursos chamado `soil-moisture-sensor`. Os nomes dos grupos de recursos precisam de ser únicos na sua subscrição. - - ```sh - az group create --name soil-moisture-sensor \ - --location - ``` - - Substitua `` pela localização que selecionou no passo anterior. - -### Tarefa - criar um IoT Hub - -Agora pode criar um recurso IoT Hub no seu grupo de recursos. - -1. Utilize o seguinte comando para criar o recurso IoT Hub: - - ```sh - az iot hub create --resource-group soil-moisture-sensor \ - --sku F1 \ - --partition-count 2 \ - --name - ``` - - Substitua `` por um nome para o seu hub. Este nome precisa de ser globalmente único - ou seja, nenhum outro IoT Hub criado por qualquer pessoa pode ter o mesmo nome. Este nome é usado num URL que aponta para o hub, por isso precisa de ser único. Use algo como `soil-moisture-sensor-` e adicione um identificador único no final, como algumas palavras aleatórias ou o seu nome. - - A opção `--sku F1` indica que será utilizado o nível gratuito. O nível gratuito suporta 8.000 mensagens por dia, juntamente com a maioria das funcionalidades dos níveis pagos. - - > 🎓 Diferentes níveis de preços dos serviços do Azure são referidos como tiers. Cada tier tem um custo diferente e oferece diferentes funcionalidades ou volumes de dados. - - > 💁 Se quiser saber mais sobre preços, pode consultar o [guia de preços do Azure IoT Hub](https://azure.microsoft.com/pricing/details/iot-hub/?WT.mc_id=academic-17441-jabenn). - - A opção `--partition-count 2` define quantos fluxos de dados o IoT Hub suporta; mais partições reduzem bloqueios de dados quando várias entidades lêem e escrevem no IoT Hub. Partições estão fora do âmbito destas lições, mas este valor precisa de ser definido para criar um IoT Hub no nível gratuito. - - > 💁 Só pode ter um IoT Hub no nível gratuito por subscrição. - -O IoT Hub será criado. Pode levar um minuto ou mais para ser concluído. - -## Comunicar com o IoT Hub - -Na lição anterior, utilizou MQTT e enviou mensagens de ida e volta em diferentes tópicos, com os diferentes tópicos tendo diferentes propósitos. Em vez de enviar mensagens por diferentes tópicos, o IoT Hub tem várias formas definidas para o dispositivo comunicar com o Hub, ou para o Hub comunicar com o dispositivo. - -> 💁 Por baixo, esta comunicação entre o IoT Hub e o seu dispositivo pode usar MQTT, HTTPS ou AMQP. - -* Mensagens de dispositivo para nuvem (D2C) - estas são mensagens enviadas de um dispositivo para o IoT Hub, como telemetria. Elas podem ser lidas do IoT Hub pelo código da sua aplicação. - - > 🎓 Por baixo, o IoT Hub utiliza um serviço do Azure chamado [Event Hubs](https://docs.microsoft.com/azure/event-hubs/?WT.mc_id=academic-17441-jabenn). Quando escreve código para ler mensagens enviadas para o hub, estas são frequentemente chamadas de eventos. - -* Mensagens de nuvem para dispositivo (C2D) - estas são mensagens enviadas pelo código da aplicação, através de um IoT Hub para um dispositivo IoT. - -* Pedidos de métodos diretos - estas são mensagens enviadas pelo código da aplicação através de um IoT Hub para um dispositivo IoT para solicitar que o dispositivo faça algo, como controlar um atuador. Estas mensagens requerem uma resposta para que o código da aplicação possa saber se foram processadas com sucesso. - -* Twins de dispositivos - estes são documentos JSON mantidos sincronizados entre o dispositivo e o IoT Hub, e são usados para armazenar configurações ou outras propriedades relatadas pelo dispositivo ou que devem ser definidas no dispositivo (conhecidas como desejadas) pelo IoT Hub. - -O IoT Hub pode armazenar mensagens e pedidos de métodos diretos por um período de tempo configurável (por padrão, um dia), então, se um dispositivo ou código da aplicação perder a conexão, ainda pode recuperar mensagens enviadas enquanto estava offline após reconectar-se. Os twins de dispositivos são mantidos permanentemente no IoT Hub, então, a qualquer momento, um dispositivo pode reconectar-se e obter o twin de dispositivo mais recente. - -✅ Faça uma pesquisa: Leia mais sobre estes tipos de mensagens na [orientação de comunicações de dispositivo para nuvem](https://docs.microsoft.com/azure/iot-hub/iot-hub-devguide-d2c-guidance?WT.mc_id=academic-17441-jabenn) e na [orientação de comunicações de nuvem para dispositivo](https://docs.microsoft.com/azure/iot-hub/iot-hub-devguide-c2d-guidance?WT.mc_id=academic-17441-jabenn) na documentação do IoT Hub. - -## Conectar o seu dispositivo ao serviço IoT - -Depois de criar o hub, o seu dispositivo IoT pode conectar-se a ele. Apenas dispositivos registados podem conectar-se a um serviço, então precisará de registar o seu dispositivo primeiro. Quando o regista, pode obter uma string de conexão que o dispositivo pode usar para se conectar. Esta string de conexão é específica do dispositivo e contém informações sobre o IoT Hub, o dispositivo e uma chave secreta que permitirá que este dispositivo se conecte. - -> 🎓 Uma string de conexão é um termo genérico para um pedaço de texto que contém detalhes de conexão. Estas são usadas ao conectar-se a IoT Hubs, bases de dados e muitos outros serviços. Geralmente consistem num identificador para o serviço, como um URL, e informações de segurança, como uma chave secreta. Estas são passadas para SDKs para se conectar ao serviço. - -> ⚠️ As strings de conexão devem ser mantidas seguras! A segurança será abordada em mais detalhe numa lição futura. - -### Tarefa - registar o seu dispositivo IoT - -O dispositivo IoT pode ser registado no seu IoT Hub usando o Azure CLI. - -1. Execute o seguinte comando para registar um dispositivo: - - ```sh - az iot hub device-identity create --device-id soil-moisture-sensor \ - --hub-name - ``` - - Substitua `` pelo nome que utilizou para o seu IoT Hub. - - Isto criará um dispositivo com um ID de `soil-moisture-sensor`. - -1. Quando o seu dispositivo IoT se conecta ao seu IoT Hub usando o SDK, precisa de usar uma string de conexão que fornece o URL do hub, juntamente com uma chave secreta. Execute o seguinte comando para obter a string de conexão: - - ```sh - az iot hub device-identity connection-string show --device-id soil-moisture-sensor \ - --output table \ - --hub-name - ``` - - Substitua `` pelo nome que utilizou para o seu IoT Hub. - -1. Guarde a string de conexão que aparece na saída, pois precisará dela mais tarde. - -### Tarefa - conectar o seu dispositivo IoT à nuvem - -Siga o guia relevante para conectar o seu dispositivo IoT à nuvem: - -* [Arduino - Wio Terminal](wio-terminal-connect-hub.md) -* [Computador de placa única - Raspberry Pi/Dispositivo IoT Virtual](single-board-computer-connect-hub.md) - -### Tarefa - monitorizar eventos - -Por enquanto, não irá atualizar o código do servidor. Em vez disso, pode usar o Azure CLI para monitorizar eventos do seu dispositivo IoT. - -1. Certifique-se de que o seu dispositivo IoT está a funcionar e a enviar valores de telemetria de humidade do solo. - -1. Execute o seguinte comando no seu prompt de comando ou terminal para monitorizar mensagens enviadas ao seu IoT Hub: - - ```sh - az iot hub monitor-events --hub-name - ``` - - Substitua `` pelo nome que utilizou para o seu IoT Hub. - - Verá mensagens aparecerem na saída do console à medida que são enviadas pelo seu dispositivo IoT. - - ```output - Starting event monitor, use ctrl-c to stop... - { - "event": { - "origin": "soil-moisture-sensor", - "module": "", - "interface": "", - "component": "", - "payload": "{\"soil_moisture\": 376}" - } - }, - { - "event": { - "origin": "soil-moisture-sensor", - "module": "", - "interface": "", - "component": "", - "payload": "{\"soil_moisture\": 381}" - } - } - ``` - - O conteúdo do `payload` corresponderá à mensagem enviada pelo seu dispositivo IoT. - - > No momento da escrita, a extensão `az iot` não está totalmente funcional em dispositivos Apple Silicon. Se estiver a usar um dispositivo Apple Silicon, precisará de monitorizar as mensagens de outra forma, como usando as [Ferramentas Azure IoT para Visual Studio Code](https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-vscode-iot-toolkit-cloud-device-messaging). - -1. Estas mensagens têm várias propriedades anexadas automaticamente, como o carimbo de data/hora em que foram enviadas. Estas são conhecidas como *anotações*. Para visualizar todas as anotações das mensagens, use o seguinte comando: - - ```sh - az iot hub monitor-events --properties anno --hub-name - ``` - - Substitua `` pelo nome que utilizou para o seu IoT Hub. - - Verá mensagens aparecerem na saída do console à medida que são enviadas pelo seu dispositivo IoT. - - ```output - Starting event monitor, use ctrl-c to stop... - { - "event": { - "origin": "soil-moisture-sensor", - "module": "", - "interface": "", - "component": "", - "properties": {}, - "annotations": { - "iothub-connection-device-id": "soil-moisture-sensor", - "iothub-connection-auth-method": "{\"scope\":\"device\",\"type\":\"sas\",\"issuer\":\"iothub\",\"acceptingIpFilterRule\":null}", - "iothub-connection-auth-generation-id": "637553997165220462", - "iothub-enqueuedtime": 1619976150288, - "iothub-message-source": "Telemetry", - "x-opt-sequence-number": 1379, - "x-opt-offset": "550576", - "x-opt-enqueued-time": 1619976150277 - }, - "payload": "{\"soil_moisture\": 381}" - } - } - ``` - - Os valores de tempo nas anotações estão em [tempo UNIX](https://wikipedia.org/wiki/Unix_time), representando o número de segundos desde a meia-noite de 1 de janeiro de 1970. - - Saia do monitor de eventos quando terminar. - -### Tarefa - controlar o seu dispositivo IoT - -Também pode usar o Azure CLI para chamar métodos diretos no seu dispositivo IoT. - -1. Execute o seguinte comando no seu prompt de comando ou terminal para invocar o método `relay_on` no dispositivo IoT: - - ```sh - az iot hub invoke-device-method --device-id soil-moisture-sensor \ - --method-name relay_on \ - --method-payload '{}' \ - --hub-name - ``` - - Substitua ` - -` com o nome que utilizou para o seu IoT Hub. - - Isto envia um pedido de método direto para o método especificado por `method-name`. Os métodos diretos podem receber um payload contendo dados para o método, e este pode ser especificado no parâmetro `method-payload` como JSON. - - Verá o relé ligar-se e a saída correspondente do seu dispositivo IoT: - - ```output - Direct method received - relay_on - ``` - -1. Repita o passo acima, mas defina o `--method-name` como `relay_off`. Verá o relé desligar-se e a saída correspondente do dispositivo IoT. - ---- - -## 🚀 Desafio - -O nível gratuito do IoT Hub permite 8.000 mensagens por dia. O código que escreveu envia mensagens de telemetria a cada 10 segundos. Quantas mensagens por dia são enviadas com uma mensagem a cada 10 segundos? - -Pense na frequência com que as medições de humidade do solo devem ser enviadas. Como pode alterar o seu código para permanecer dentro do limite do nível gratuito e verificar com a frequência necessária, mas sem exagerar? E se quisesse adicionar um segundo dispositivo? - -## Questionário pós-aula - -[Questionário pós-aula](https://black-meadow-040d15503.1.azurestaticapps.net/quiz/16) - -## Revisão e Estudo Individual - -O SDK do IoT Hub é open source tanto para Arduino como para Python. Nos repositórios de código no GitHub, existem vários exemplos que mostram como trabalhar com diferentes funcionalidades do IoT Hub. - -* Se estiver a usar um Wio Terminal, consulte os [exemplos de Arduino no GitHub](https://github.com/Azure/azure-iot-pal-arduino/tree/master/pal/samples) -* Se estiver a usar um Raspberry Pi ou um dispositivo virtual, consulte os [exemplos de Python no GitHub](https://github.com/Azure/azure-iot-sdk-python/tree/master/azure-iot-hub/samples) - -## Tarefa - -[Saiba mais sobre serviços na cloud](assignment.md) - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, é importante notar que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes do uso desta tradução. \ No newline at end of file diff --git a/translations/pt/2-farm/lessons/4-migrate-your-plant-to-the-cloud/assignment.md b/translations/pt/2-farm/lessons/4-migrate-your-plant-to-the-cloud/assignment.md deleted file mode 100644 index 692de85b6..000000000 --- a/translations/pt/2-farm/lessons/4-migrate-your-plant-to-the-cloud/assignment.md +++ /dev/null @@ -1,31 +0,0 @@ - -# Aprenda sobre serviços na cloud - -## Instruções - -As clouds, como o Azure da Microsoft, oferecem mais do que apenas computação para alugar. Os principais tipos de ofertas na cloud incluem: - -* Infraestrutura como serviço (IaaS) -* Plataforma como serviço (PaaS) -* Serverless -* Software como serviço (SaaS) - -Aprenda sobre estes diferentes tipos de ofertas e explique o que são e como diferem. Explique quais destas ofertas são relevantes para os desenvolvedores de IoT. - -## Critérios de Avaliação - -| Critério | Exemplar | Adequado | Necessita de Melhorias | -| -------- | --------- | -------- | ----------------------- | -| Explicar as diferentes ofertas na cloud | Forneceu explicações claras sobre os 4 tipos de ofertas | Conseguiu explicar 3 tipos de ofertas | Apenas conseguiu explicar 1 ou 2 tipos de ofertas | -| Explicar qual oferta é relevante para IoT | Descreveu uma explicação de quais ofertas são relevantes para os desenvolvedores de IoT e porquê | Descreveu uma explicação de quais ofertas são relevantes para os desenvolvedores de IoT, mas não explicou porquê | Não conseguiu descrever quais ofertas são relevantes para os desenvolvedores de IoT | - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, esteja ciente de que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes do uso desta tradução. \ No newline at end of file diff --git a/translations/pt/2-farm/lessons/4-migrate-your-plant-to-the-cloud/single-board-computer-connect-hub.md b/translations/pt/2-farm/lessons/4-migrate-your-plant-to-the-cloud/single-board-computer-connect-hub.md deleted file mode 100644 index d7039e723..000000000 --- a/translations/pt/2-farm/lessons/4-migrate-your-plant-to-the-cloud/single-board-computer-connect-hub.md +++ /dev/null @@ -1,128 +0,0 @@ - -# Conecte o seu dispositivo IoT à nuvem - Hardware IoT Virtual e Raspberry Pi - -Nesta parte da lição, irá conectar o seu dispositivo IoT virtual ou Raspberry Pi ao IoT Hub, para enviar telemetria e receber comandos. - -## Conectar o seu dispositivo ao IoT Hub - -O próximo passo é conectar o seu dispositivo ao IoT Hub. - -### Tarefa - conectar ao IoT Hub - -1. Abra a pasta `soil-moisture-sensor` no VS Code. Certifique-se de que o ambiente virtual está a funcionar no terminal, caso esteja a usar um dispositivo IoT virtual. - -1. Instale alguns pacotes adicionais do Pip: - - ```sh - pip3 install azure-iot-device - ``` - - `azure-iot-device` é uma biblioteca para comunicar com o seu IoT Hub. - -1. Adicione as seguintes importações ao topo do ficheiro `app.py`, abaixo das importações existentes: - - ```python - from azure.iot.device import IoTHubDeviceClient, Message, MethodResponse - ``` - - Este código importa o SDK para comunicar com o seu IoT Hub. - -1. Remova a linha `import paho.mqtt.client as mqtt`, pois esta biblioteca já não é necessária. Remova todo o código MQTT, incluindo os nomes dos tópicos, todo o código que utiliza `mqtt_client` e o `handle_command`. Mantenha o ciclo `while True:`, apenas elimine a linha `mqtt_client.publish` deste ciclo. - -1. Adicione o seguinte código abaixo das declarações de importação: - - ```python - connection_string = "" - ``` - - Substitua `` pela cadeia de conexão que obteve para o dispositivo anteriormente nesta lição. - - > 💁 Isto não é uma boa prática. As cadeias de conexão nunca devem ser armazenadas no código fonte, pois podem ser incluídas no controlo de versão e encontradas por qualquer pessoa. Estamos a fazer isto aqui por simplicidade. Idealmente, deveria usar algo como uma variável de ambiente e uma ferramenta como [`python-dotenv`](https://pypi.org/project/python-dotenv/). Aprenderá mais sobre isto numa lição futura. - -1. Abaixo deste código, adicione o seguinte para criar um objeto cliente do dispositivo que pode comunicar com o IoT Hub e conectá-lo: - - ```python - device_client = IoTHubDeviceClient.create_from_connection_string(connection_string) - - print('Connecting') - device_client.connect() - print('Connected') - ``` - -1. Execute este código. Verá o seu dispositivo conectar-se. - - ```output - pi@raspberrypi:~/soil-moisture-sensor $ python3 app.py - Connecting - Connected - Soil moisture: 379 - ``` - -## Enviar telemetria - -Agora que o seu dispositivo está conectado, pode enviar telemetria para o IoT Hub em vez do broker MQTT. - -### Tarefa - enviar telemetria - -1. Adicione o seguinte código dentro do ciclo `while True`, logo antes do comando de pausa: - - ```python - message = Message(json.dumps({ 'soil_moisture': soil_moisture })) - device_client.send_message(message) - ``` - - Este código cria uma `Message` do IoT Hub contendo a leitura da humidade do solo como uma string JSON e envia-a para o IoT Hub como uma mensagem de dispositivo para nuvem. - -## Lidar com comandos - -O seu dispositivo precisa de lidar com um comando do código do servidor para controlar o relé. Este é enviado como um pedido de método direto. - -## Tarefa - lidar com um pedido de método direto - -1. Adicione o seguinte código antes do ciclo `while True`: - - ```python - 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() - ``` - - Isto define um método, `handle_method_request`, que será chamado quando um método direto for invocado pelo IoT Hub. Cada método direto tem um nome, e este código espera um método chamado `relay_on` para ligar o relé e `relay_off` para desligar o relé. - - > 💁 Isto também poderia ser implementado num único pedido de método direto, passando o estado desejado do relé num payload que pode ser enviado com o pedido de método e disponível a partir do objeto `request`. - -1. Os métodos diretos requerem uma resposta para informar o código que os invocou de que foram tratados. Adicione o seguinte código no final da função `handle_method_request` para criar uma resposta ao pedido: - - ```python - method_response = MethodResponse.create_from_method_request(request, 200) - device_client.send_method_response(method_response) - ``` - - Este código envia uma resposta ao pedido de método direto com um código de estado HTTP 200 e envia-a de volta para o IoT Hub. - -1. Adicione o seguinte código abaixo da definição desta função: - - ```python - device_client.on_method_request_received = handle_method_request - ``` - - Este código informa o cliente do IoT Hub para chamar a função `handle_method_request` quando um método direto for invocado. - -> 💁 Pode encontrar este código na pasta [code/pi](../../../../../2-farm/lessons/4-migrate-your-plant-to-the-cloud/code/pi) ou [code/virtual-device](../../../../../2-farm/lessons/4-migrate-your-plant-to-the-cloud/code/virtual-device). - -😀 O programa do seu sensor de humidade do solo está conectado ao seu IoT Hub! - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, é importante notar que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes da utilização desta tradução. \ No newline at end of file diff --git a/translations/pt/2-farm/lessons/4-migrate-your-plant-to-the-cloud/wio-terminal-connect-hub.md b/translations/pt/2-farm/lessons/4-migrate-your-plant-to-the-cloud/wio-terminal-connect-hub.md deleted file mode 100644 index 9643d06e0..000000000 --- a/translations/pt/2-farm/lessons/4-migrate-your-plant-to-the-cloud/wio-terminal-connect-hub.md +++ /dev/null @@ -1,304 +0,0 @@ - -# Conecte o seu dispositivo IoT à nuvem - Wio Terminal - -Nesta parte da lição, irá conectar o seu Wio Terminal ao IoT Hub para enviar telemetria e receber comandos. - -## Conectar o dispositivo ao IoT Hub - -O próximo passo é conectar o seu dispositivo ao IoT Hub. - -### Tarefa - conectar ao IoT Hub - -1. Abra o projeto `soil-moisture-sensor` no VS Code. - -1. Abra o ficheiro `platformio.ini`. Remova a dependência da biblioteca `knolleary/PubSubClient`. Esta era usada para conectar ao broker MQTT público e não é necessária para conectar ao IoT Hub. - -1. Adicione as seguintes dependências de biblioteca: - - ```ini - seeed-studio/Seeed Arduino RTC @ 2.0.0 - arduino-libraries/AzureIoTHub @ 1.6.0 - azure/AzureIoTUtility @ 1.6.1 - azure/AzureIoTProtocol_MQTT @ 1.6.0 - azure/AzureIoTProtocol_HTTP @ 1.6.0 - azure/AzureIoTSocket_WiFi @ 1.0.2 - ``` - - A biblioteca `Seeed Arduino RTC` fornece código para interagir com um relógio em tempo real no Wio Terminal, usado para acompanhar o tempo. As restantes bibliotecas permitem que o seu dispositivo IoT se conecte ao IoT Hub. - -1. Adicione o seguinte ao final do ficheiro `platformio.ini`: - - ```ini - build_flags = - -DDONT_USE_UPLOADTOBLOB - ``` - - Isto define uma flag do compilador necessária ao compilar o código do Arduino IoT Hub. - -1. Abra o ficheiro de cabeçalho `config.h`. Remova todas as configurações de MQTT e adicione a seguinte constante para a string de conexão do dispositivo: - - ```cpp - // IoT Hub settings - const char *CONNECTION_STRING = ""; - ``` - - Substitua `` pela string de conexão do seu dispositivo que copiou anteriormente. - -1. A conexão ao IoT Hub utiliza um token baseado no tempo. Isto significa que o dispositivo IoT precisa de saber a hora atual. Diferentemente de sistemas operativos como Windows, macOS ou Linux, os microcontroladores não sincronizam automaticamente a hora atual pela Internet. Por isso, será necessário adicionar código para obter a hora atual de um servidor [NTP](https://wikipedia.org/wiki/Network_Time_Protocol). Depois de obter a hora, esta pode ser armazenada num relógio em tempo real no Wio Terminal, permitindo que a hora correta seja solicitada posteriormente, assumindo que o dispositivo não perde energia. Adicione um novo ficheiro chamado `ntp.h` com o seguinte código: - - ```cpp - #pragma once - - #include "DateTime.h" - #include - #include "samd/NTPClientAz.h" - #include - - static void initTime() - { - WiFiUDP _udp; - time_t epochTime = (time_t)-1; - NTPClientAz ntpClient; - - ntpClient.begin(); - - while (true) - { - epochTime = ntpClient.getEpochTime("0.pool.ntp.org"); - - if (epochTime == (time_t)-1) - { - Serial.println("Fetching NTP epoch time failed! Waiting 2 seconds to retry."); - delay(2000); - } - else - { - Serial.print("Fetched NTP epoch time is: "); - - char buff[32]; - sprintf(buff, "%.f", difftime(epochTime, (time_t)0)); - Serial.println(buff); - break; - } - } - - ntpClient.end(); - - struct timeval tv; - tv.tv_sec = epochTime; - tv.tv_usec = 0; - - settimeofday(&tv, NULL); - } - ``` - - Os detalhes deste código estão fora do âmbito desta lição. Ele define uma função chamada `initTime` que obtém a hora atual de um servidor NTP e usa-a para configurar o relógio no Wio Terminal. - -1. Abra o ficheiro `main.cpp` e remova todo o código MQTT, incluindo o ficheiro de cabeçalho `PubSubClient.h`, a declaração da variável `PubSubClient`, os métodos `reconnectMQTTClient` e `createMQTTClient`, e quaisquer chamadas a estas variáveis e métodos. Este ficheiro deve conter apenas código para conectar ao WiFi, obter a humidade do solo e criar um documento JSON com esta informação. - -1. Adicione as seguintes diretivas `#include` ao topo do ficheiro `main.cpp` para incluir os ficheiros de cabeçalho das bibliotecas do IoT Hub e para configurar a hora: - - ```cpp - #include - #include - #include - #include "ntp.h" - ``` - -1. Adicione a seguinte chamada ao final da função `setup` para configurar a hora atual: - - ```cpp - initTime(); - ``` - -1. Adicione a seguinte declaração de variável ao topo do ficheiro, logo abaixo das diretivas de inclusão: - - ```cpp - IOTHUB_DEVICE_CLIENT_LL_HANDLE _device_ll_handle; - ``` - - Isto declara um `IOTHUB_DEVICE_CLIENT_LL_HANDLE`, um identificador para uma conexão ao IoT Hub. - -1. Abaixo disso, adicione o seguinte código: - - ```cpp - static void connectionStatusCallback(IOTHUB_CLIENT_CONNECTION_STATUS result, IOTHUB_CLIENT_CONNECTION_STATUS_REASON reason, void *user_context) - { - if (result == IOTHUB_CLIENT_CONNECTION_AUTHENTICATED) - { - Serial.println("The device client is connected to iothub"); - } - else - { - Serial.println("The device client has been disconnected"); - } - } - ``` - - Isto declara uma função de callback que será chamada quando a conexão ao IoT Hub mudar de estado, como conectar ou desconectar. O estado é enviado para a porta serial. - -1. Abaixo disso, adicione uma função para conectar ao IoT Hub: - - ```cpp - void connectIoTHub() - { - IoTHub_Init(); - - _device_ll_handle = IoTHubDeviceClient_LL_CreateFromConnectionString(CONNECTION_STRING, MQTT_Protocol); - - if (_device_ll_handle == NULL) - { - Serial.println("Failure creating Iothub device. Hint: Check your connection string."); - return; - } - - IoTHubDeviceClient_LL_SetConnectionStatusCallback(_device_ll_handle, connectionStatusCallback, NULL); - } - ``` - - Este código inicializa o código da biblioteca do IoT Hub e cria uma conexão usando a string de conexão no ficheiro de cabeçalho `config.h`. Esta conexão é baseada em MQTT. Se a conexão falhar, isso será enviado para a porta serial - se vir isto na saída, verifique a string de conexão. Finalmente, o callback de estado da conexão é configurado. - -1. Chame esta função na função `setup` abaixo da chamada para `initTime`: - - ```cpp - connectIoTHub(); - ``` - -1. Tal como com o cliente MQTT, este código funciona numa única thread, por isso precisa de tempo para processar mensagens enviadas pelo hub e para o hub. Adicione o seguinte ao topo da função `loop` para fazer isto: - - ```cpp - IoTHubDeviceClient_LL_DoWork(_device_ll_handle); - ``` - -1. Compile e carregue este código. Verá a conexão no monitor serial: - - ```output - Connecting to WiFi.. - Connected! - Fetched NTP epoch time is: 1619983687 - Sending telemetry {"soil_moisture":391} - The device client is connected to iothub - ``` - - Na saída, pode ver a hora NTP a ser obtida, seguida pela conexão do cliente do dispositivo. Pode demorar alguns segundos para conectar, por isso pode ver a humidade do solo na saída enquanto o dispositivo está a conectar. - - > 💁 Pode converter o tempo UNIX do NTP para uma versão mais legível usando um site como [unixtimestamp.com](https://www.unixtimestamp.com) - -## Enviar telemetria - -Agora que o seu dispositivo está conectado, pode enviar telemetria para o IoT Hub em vez do broker MQTT. - -### Tarefa - enviar telemetria - -1. Adicione a seguinte função acima da função `setup`: - - ```cpp - void sendTelemetry(const char *telemetry) - { - IOTHUB_MESSAGE_HANDLE message_handle = IoTHubMessage_CreateFromString(telemetry); - IoTHubDeviceClient_LL_SendEventAsync(_device_ll_handle, message_handle, NULL, NULL); - IoTHubMessage_Destroy(message_handle); - } - ``` - - Este código cria uma mensagem do IoT Hub a partir de uma string passada como parâmetro, envia-a para o hub e, em seguida, limpa o objeto da mensagem. - -1. Chame este código na função `loop`, logo após a linha onde a telemetria é enviada para a porta serial: - - ```cpp - sendTelemetry(telemetry.c_str()); - ``` - -## Processar comandos - -O seu dispositivo precisa de processar um comando do código do servidor para controlar o relé. Este é enviado como uma solicitação de método direto. - -### Tarefa - processar uma solicitação de método direto - -1. Adicione o seguinte código antes da função `connectIoTHub`: - - ```cpp - int directMethodCallback(const char *method_name, const unsigned char *payload, size_t size, unsigned char **response, size_t *response_size, void *userContextCallback) - { - Serial.printf("Direct method received %s\r\n", method_name); - - if (strcmp(method_name, "relay_on") == 0) - { - digitalWrite(PIN_WIRE_SCL, HIGH); - } - else if (strcmp(method_name, "relay_off") == 0) - { - digitalWrite(PIN_WIRE_SCL, LOW); - } - } - ``` - - Este código define uma função de callback que a biblioteca do IoT Hub pode chamar quando recebe uma solicitação de método direto. O método solicitado é enviado no parâmetro `method_name`. Esta função imprime o método chamado na porta serial e, em seguida, liga ou desliga o relé dependendo do nome do método. - - > 💁 Isto também poderia ser implementado num único pedido de método direto, passando o estado desejado do relé num payload que pode ser enviado com o pedido de método e disponível no parâmetro `payload`. - -1. Adicione o seguinte código ao final da função `directMethodCallback`: - - ```cpp - char resultBuff[16]; - sprintf(resultBuff, "{\"Result\":\"\"}"); - *response_size = strlen(resultBuff); - *response = (unsigned char *)malloc(*response_size); - memcpy(*response, resultBuff, *response_size); - - return IOTHUB_CLIENT_OK; - ``` - - As solicitações de método direto precisam de uma resposta, e a resposta é composta por duas partes - uma resposta em texto e um código de retorno. Este código criará um resultado como o seguinte documento JSON: - - ```JSON - { - "Result": "" - } - ``` - - Este é então copiado para o parâmetro `response`, e o tamanho desta resposta é definido no parâmetro `response_size`. Este código retorna `IOTHUB_CLIENT_OK` para indicar que o método foi processado corretamente. - -1. Configure o callback adicionando o seguinte ao final da função `connectIoTHub`: - - ```cpp - IoTHubClient_LL_SetDeviceMethodCallback(_device_ll_handle, directMethodCallback, NULL); - ``` - -1. A função `loop` chamará a função `IoTHubDeviceClient_LL_DoWork` para processar eventos enviados pelo IoT Hub. Isto é chamado apenas a cada 10 segundos devido ao `delay`, o que significa que os métodos diretos são processados apenas a cada 10 segundos. Para tornar isto mais eficiente, o atraso de 10 segundos pode ser implementado como vários atrasos mais curtos, chamando `IoTHubDeviceClient_LL_DoWork` cada vez. Para fazer isto, adicione o seguinte código acima da função `loop`: - - ```cpp - void work_delay(int delay_time) - { - int current = 0; - do - { - IoTHubDeviceClient_LL_DoWork(_device_ll_handle); - delay(100); - current += 100; - } while (current < delay_time); - } - ``` - - Este código irá fazer um loop repetidamente, chamando `IoTHubDeviceClient_LL_DoWork` e atrasando por 100ms cada vez. Fará isto tantas vezes quanto necessário para atrasar pelo tempo dado no parâmetro `delay_time`. Isto significa que o dispositivo está a esperar no máximo 100ms para processar solicitações de método direto. - -1. Na função `loop`, remova a chamada para `IoTHubDeviceClient_LL_DoWork` e substitua a chamada `delay(10000)` pelo seguinte para chamar esta nova função: - - ```cpp - work_delay(10000); - ``` - -> 💁 Pode encontrar este código na pasta [code/wio-terminal](../../../../../2-farm/lessons/4-migrate-your-plant-to-the-cloud/code/wio-terminal). - -😀 O programa do sensor de humidade do solo está conectado ao seu IoT Hub! - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, é importante notar que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes do uso desta tradução. \ No newline at end of file diff --git a/translations/pt/2-farm/lessons/5-migrate-application-to-the-cloud/README.md b/translations/pt/2-farm/lessons/5-migrate-application-to-the-cloud/README.md deleted file mode 100644 index fab0b7231..000000000 --- a/translations/pt/2-farm/lessons/5-migrate-application-to-the-cloud/README.md +++ /dev/null @@ -1,654 +0,0 @@ - -# Migre a lógica da sua aplicação para a cloud - -![Uma visão geral ilustrada desta lição](../../../../../translated_images/pt-PT/lesson-9.dfe99c8e891f48e179724520da9f5794392cf9a625079281ccdcbf09bd85e1b6.jpg) - -> Ilustração por [Nitya Narasimhan](https://github.com/nitya). Clique na imagem para uma versão maior. - -Esta lição foi ensinada como parte da [série IoT para Iniciantes - Agricultura Digital, Projeto 2](https://youtube.com/playlist?list=PLmsFUfdnGr3yCutmcVg6eAUEfsGiFXgcx) do [Microsoft Reactor](https://developer.microsoft.com/reactor/?WT.mc_id=academic-17441-jabenn). - -[![Controle o seu dispositivo IoT com código serverless](https://img.youtube.com/vi/VVZDcs5u1_I/0.jpg)](https://youtu.be/VVZDcs5u1_I) - -## Questionário pré-aula - -[Questionário pré-aula](https://black-meadow-040d15503.1.azurestaticapps.net/quiz/17) - -## Introdução - -Na última lição, aprendeu a conectar o monitoramento de humidade do solo da sua planta e o controlo do relé a um serviço IoT baseado na cloud. O próximo passo é mover o código do servidor que controla o tempo do relé para a cloud. Nesta lição, aprenderá a fazer isso utilizando funções serverless. - -Nesta lição, abordaremos: - -* [O que é serverless?](../../../../../2-farm/lessons/5-migrate-application-to-the-cloud) -* [Criar uma aplicação serverless](../../../../../2-farm/lessons/5-migrate-application-to-the-cloud) -* [Criar um trigger de evento do IoT Hub](../../../../../2-farm/lessons/5-migrate-application-to-the-cloud) -* [Enviar pedidos de método direto a partir de código serverless](../../../../../2-farm/lessons/5-migrate-application-to-the-cloud) -* [Desplegar o seu código serverless na cloud](../../../../../2-farm/lessons/5-migrate-application-to-the-cloud) - -## O que é serverless? - -Serverless, ou computação serverless, envolve criar pequenos blocos de código que são executados na cloud em resposta a diferentes tipos de eventos. Quando o evento ocorre, o seu código é executado e recebe dados sobre o evento. Estes eventos podem vir de várias fontes, incluindo pedidos web, mensagens colocadas numa fila, alterações a dados numa base de dados ou mensagens enviadas para um serviço IoT por dispositivos IoT. - -![Eventos enviados de um serviço IoT para um serviço serverless, todos processados ao mesmo tempo por várias funções em execução](../../../../../translated_images/pt-PT/iot-messages-to-serverless.0194da1cc0732bb7d0f823aed3fce54735c6b1ad3bf36089804d8aaefc0a774f.png) - -> 💁 Se já utilizou triggers de base de dados antes, pode pensar nisto como algo semelhante: código sendo acionado por um evento, como a inserção de uma linha. - -![Quando muitos eventos são enviados ao mesmo tempo, o serviço serverless escala para executá-los todos simultaneamente](../../../../../translated_images/pt-PT/serverless-scaling.f8c769adf0413fd1.webp) - -O seu código só é executado quando o evento ocorre, não permanecendo ativo em outros momentos. O evento ocorre, o seu código é carregado e executado. Isto torna o serverless altamente escalável - se muitos eventos ocorrerem ao mesmo tempo, o fornecedor da cloud pode executar a sua função tantas vezes quanto necessário, simultaneamente, em qualquer servidor disponível. A desvantagem é que, se precisar de partilhar informações entre eventos, terá de armazená-las em algum lugar, como uma base de dados, em vez de as manter na memória. - -O seu código é escrito como uma função que recebe detalhes sobre o evento como parâmetro. Pode usar uma ampla gama de linguagens de programação para escrever estas funções serverless. - -> 🎓 Serverless também é conhecido como Functions as a Service (FaaS), pois cada trigger de evento é implementado como uma função no código. - -Apesar do nome, serverless utiliza servidores. O nome refere-se ao facto de que, como programador, não precisa de se preocupar com os servidores necessários para executar o seu código; tudo o que importa é que o código seja executado em resposta a um evento. O fornecedor da cloud possui um *runtime* serverless que gere a alocação de servidores, redes, armazenamento, CPU, memória e tudo o mais necessário para executar o seu código. Este modelo significa que não paga por servidor, mas sim pelo tempo em que o código está em execução e pela quantidade de memória utilizada. - -> 💰 Serverless é uma das formas mais económicas de executar código na cloud. Por exemplo, no momento em que este texto foi escrito, um fornecedor de cloud permite que todas as suas funções serverless sejam executadas até 1.000.000 de vezes por mês antes de começar a cobrar, e depois disso cobra 0,20 USD por cada 1.000.000 de execuções. Quando o seu código não está em execução, não paga. - -Como programador IoT, o modelo serverless é ideal. Pode escrever uma função que é chamada em resposta a mensagens enviadas por qualquer dispositivo IoT conectado ao seu serviço IoT hospedado na cloud. O seu código lidará com todas as mensagens enviadas, mas só será executado quando necessário. - -✅ Relembre o código que escreveu como servidor a ouvir mensagens via MQTT. Como acha que isso poderia ser executado na cloud usando serverless? Que alterações seriam necessárias no código para suportar a computação serverless? - -> 💁 O modelo serverless está a expandir-se para outros serviços na cloud, além da execução de código. Por exemplo, bases de dados serverless estão disponíveis na cloud, utilizando um modelo de preços serverless onde paga por cada pedido feito à base de dados, como uma consulta ou inserção, geralmente com preços baseados no trabalho necessário para atender ao pedido. Por exemplo, uma consulta simples de uma linha por chave primária custará menos do que uma operação complexa que junta várias tabelas e retorna milhares de linhas. - -## Criar uma aplicação serverless - -O serviço de computação serverless da Microsoft chama-se Azure Functions. - -![O logótipo do Azure Functions](../../../../../translated_images/pt-PT/azure-functions-logo.1cfc8e3204c9c44aaf80fcf406fc8544d80d7f00f8d3e8ed6fed764563e17564.png) - -O vídeo curto abaixo apresenta uma visão geral do Azure Functions. - -[![Vídeo de visão geral do Azure Functions](https://img.youtube.com/vi/8-jz5f_JyEQ/0.jpg)](https://www.youtube.com/watch?v=8-jz5f_JyEQ) - -> 🎥 Clique na imagem acima para assistir ao vídeo. - -✅ Reserve um momento para pesquisar e ler a visão geral do Azure Functions na [documentação do Microsoft Azure Functions](https://docs.microsoft.com/azure/azure-functions/functions-overview?WT.mc_id=academic-17441-jabenn). - -Para escrever Azure Functions, começa com uma aplicação Azure Functions na linguagem de sua escolha. O Azure Functions suporta, de forma nativa, Python, JavaScript, TypeScript, C#, F#, Java e Powershell. Nesta lição, aprenderá a escrever uma aplicação Azure Functions em Python. - -> 💁 O Azure Functions também suporta *handlers* personalizados, permitindo que escreva funções em qualquer linguagem que suporte pedidos HTTP, incluindo linguagens mais antigas, como COBOL. - -As aplicações de funções consistem em um ou mais *triggers* - funções que respondem a eventos. Pode ter vários triggers dentro de uma aplicação de funções, todos partilhando uma configuração comum. Por exemplo, no ficheiro de configuração da sua aplicação de funções, pode ter os detalhes de conexão do seu IoT Hub, e todas as funções na aplicação podem usar isso para se conectar e ouvir eventos. - -### Tarefa - instalar as ferramentas do Azure Functions - -> No momento em que este texto foi escrito, as ferramentas de código do Azure Functions não funcionam totalmente em Macs com Apple Silicon para projetos em Python. Será necessário usar um Mac baseado em Intel, um PC com Windows ou um PC com Linux. - -Uma grande funcionalidade do Azure Functions é que pode executá-lo localmente. O mesmo runtime usado na cloud pode ser executado no seu computador, permitindo que escreva código que responde a mensagens IoT e o execute localmente. Pode até depurar o seu código enquanto os eventos são processados. Quando estiver satisfeito com o código, pode implementá-lo na cloud. - -As ferramentas do Azure Functions estão disponíveis como uma CLI, conhecida como Azure Functions Core Tools. - -1. Instale as ferramentas principais do Azure Functions seguindo as instruções na [documentação do Azure Functions Core Tools](https://docs.microsoft.com/azure/azure-functions/functions-run-local?WT.mc_id=academic-17441-jabenn). - -1. Instale a extensão do Azure Functions para o VS Code. Esta extensão fornece suporte para criar, depurar e implementar funções do Azure. Consulte a [documentação da extensão do Azure Functions](https://marketplace.visualstudio.com/items?WT.mc_id=academic-17441-jabenn&itemName=ms-azuretools.vscode-azurefunctions) para instruções sobre como instalar esta extensão no VS Code. - -Quando implementar a sua aplicação Azure Functions na cloud, será necessário usar uma pequena quantidade de armazenamento na cloud para guardar ficheiros da aplicação e ficheiros de log. Quando executa a sua aplicação de funções localmente, ainda precisa de se conectar ao armazenamento na cloud, mas, em vez de usar armazenamento real, pode usar um emulador de armazenamento chamado [Azurite](https://github.com/Azure/Azurite). Este emulador é executado localmente, mas age como se fosse armazenamento na cloud. - -> 🎓 No Azure, o armazenamento usado pelo Azure Functions é uma Conta de Armazenamento do Azure. Estas contas podem armazenar ficheiros, blobs, dados em tabelas ou dados em filas. Pode partilhar uma conta de armazenamento entre várias aplicações, como uma aplicação de funções e uma aplicação web. - -1. O Azurite é uma aplicação Node.js, por isso será necessário instalar o Node.js. Pode encontrar as instruções de download e instalação no [site do Node.js](https://nodejs.org/). Se estiver a usar um Mac, também pode instalá-lo através do [Homebrew](https://formulae.brew.sh/formula/node). - -1. Instale o Azurite usando o seguinte comando (`npm` é uma ferramenta instalada juntamente com o Node.js): - - ```sh - npm install -g azurite - ``` - -1. Crie uma pasta chamada `azurite` para o Azurite usar como armazenamento de dados: - - ```sh - mkdir azurite - ``` - -1. Execute o Azurite, passando-lhe esta nova pasta: - - ```sh - azurite --location azurite - ``` - - O emulador de armazenamento Azurite será iniciado e estará pronto para o runtime local do Functions se conectar. - - ```output - ➜ ~ azurite --location azurite - Azurite Blob service is starting at http://127.0.0.1:10000 - Azurite Blob service is successfully listening at http://127.0.0.1:10000 - Azurite Queue service is starting at http://127.0.0.1:10001 - Azurite Queue service is successfully listening at http://127.0.0.1:10001 - Azurite Table service is starting at http://127.0.0.1:10002 - Azurite Table service is successfully listening at http://127.0.0.1:10002 - ``` - -### Tarefa - criar um projeto Azure Functions - -A CLI do Azure Functions pode ser usada para criar uma nova aplicação de funções. - -1. Crie uma pasta para a sua aplicação de funções e navegue até ela. Chame-a de `soil-moisture-trigger`. - - ```sh - mkdir soil-moisture-trigger - cd soil-moisture-trigger - ``` - -1. Crie um ambiente virtual Python dentro desta pasta: - - ```sh - python3 -m venv .venv - ``` - -1. Ative o ambiente virtual: - - * No Windows: - * Se estiver a usar o Command Prompt ou o Command Prompt através do Windows Terminal, execute: - - ```cmd - .venv\Scripts\activate.bat - ``` - - * Se estiver a usar o PowerShell, execute: - - ```powershell - .\.venv\Scripts\Activate.ps1 - ``` - - * No macOS ou Linux, execute: - - ```cmd - source ./.venv/bin/activate - ``` - - > 💁 Estes comandos devem ser executados a partir do mesmo local onde criou o ambiente virtual. Nunca precisará de navegar para dentro da pasta `.venv`; deve sempre executar o comando de ativação e quaisquer comandos para instalar pacotes ou executar código a partir da pasta onde criou o ambiente virtual. - -1. Execute o seguinte comando para criar uma aplicação de funções nesta pasta: - - ```sh - func init --worker-runtime python soil-moisture-trigger - ``` - - Isto criará três ficheiros dentro da pasta atual: - - * `host.json` - este documento JSON contém configurações para a sua aplicação de funções. Não será necessário modificar estas configurações. - * `local.settings.json` - este documento JSON contém configurações que a sua aplicação usará ao ser executada localmente, como strings de conexão para o seu IoT Hub. Estas configurações são apenas locais e não devem ser adicionadas ao controlo de versão. Quando implementar a aplicação na cloud, estas configurações não serão implementadas; em vez disso, as configurações serão carregadas a partir das definições da aplicação. Isto será abordado mais tarde nesta lição. - * `requirements.txt` - este é um [ficheiro de requisitos do Pip](https://pip.pypa.io/en/stable/user_guide/#requirements-files) que contém os pacotes necessários para executar a sua aplicação de funções. - -1. O ficheiro `local.settings.json` tem uma configuração para a conta de armazenamento que a aplicação de funções usará. Por padrão, esta configuração está vazia, por isso precisa de ser definida. Para se conectar ao emulador de armazenamento local Azurite, defina este valor como o seguinte: - - ```json - "AzureWebJobsStorage": "UseDevelopmentStorage=true", - ``` - -1. Instale os pacotes necessários do Pip usando o ficheiro de requisitos: - - ```sh - pip install -r requirements.txt - ``` - - > 💁 Os pacotes necessários do Pip precisam de estar neste ficheiro, para que, quando a aplicação de funções for implementada na cloud, o runtime possa garantir que instala os pacotes corretos. - -1. Para testar se tudo está a funcionar corretamente, pode iniciar o runtime do Functions. Execute o seguinte comando para fazer isso: - - ```sh - func start - ``` - - Verá o runtime iniciar e relatar que não encontrou nenhuma função de trabalho (triggers). - - ```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-05-05T01:24:46.795Z] No job functions found. - ``` -> ⚠️ Se receber uma notificação do firewall, conceda acesso, pois a aplicação `func` precisa de permissão para ler e escrever na sua rede. -> ⚠️ Se estiver a usar macOS, podem surgir avisos na saída: -> -> ```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. - > ``` -> -> Pode ignorá-los desde que a aplicação Functions inicie corretamente e liste as funções em execução. Como mencionado [nesta questão no 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), estes avisos podem ser ignorados. - -1. Pare a aplicação Functions pressionando `ctrl+c`. - -1. Abra a pasta atual no VS Code, seja abrindo o VS Code e depois esta pasta, ou executando o seguinte comando: - - ```sh - code . - ``` - - O VS Code irá detetar o seu projeto Functions e mostrar uma notificação dizendo: - - ```output - Detected an Azure Functions Project in folder "soil-moisture-trigger" that may have been created outside of - VS Code. Initialize for optimal use with VS Code? - ``` - - ![A notificação](../../../../../translated_images/pt-PT/vscode-azure-functions-init-notification.bd19b49229963edb.webp) - - Selecione **Yes** nesta notificação. - -1. Certifique-se de que o ambiente virtual Python está em execução no terminal do VS Code. Termine-o e reinicie-o, se necessário. - -## Criar um trigger de evento do IoT Hub - -A aplicação Functions é a estrutura do seu código serverless. Para responder a eventos do IoT Hub, pode adicionar um trigger do IoT Hub a esta aplicação. Este trigger precisa de se conectar ao fluxo de mensagens enviadas para o IoT Hub e responder a elas. Para obter este fluxo de mensagens, o seu trigger precisa de se conectar ao *endpoint compatível com Event Hub* do IoT Hub. - -O IoT Hub baseia-se noutro serviço Azure chamado Azure Event Hubs. O Event Hubs é um serviço que permite enviar e receber mensagens, e o IoT Hub estende-o para adicionar funcionalidades para dispositivos IoT. A forma como se conecta para ler mensagens do IoT Hub é a mesma que usaria se estivesse a usar o Event Hubs. - -✅ Faça uma pesquisa: Leia a visão geral do Event Hubs na [documentação do Azure Event Hubs](https://docs.microsoft.com/azure/event-hubs/event-hubs-about?WT.mc_id=academic-17441-jabenn). Como é que as funcionalidades básicas se comparam ao IoT Hub? - -Para que um dispositivo IoT se conecte ao IoT Hub, tem de usar uma chave secreta que garante que apenas dispositivos autorizados podem conectar-se. O mesmo se aplica ao conectar-se para ler mensagens; o seu código precisará de uma string de conexão que contenha uma chave secreta, juntamente com os detalhes do IoT Hub. - -> 💁 A string de conexão padrão que obtém tem permissões de **iothubowner**, o que dá a qualquer código que a utilize permissões totais no IoT Hub. Idealmente, deve conectar-se com o nível mais baixo de permissões necessário. Isto será abordado na próxima lição. - -Depois de o seu trigger estar conectado, o código dentro da função será chamado para cada mensagem enviada ao IoT Hub, independentemente do dispositivo que a enviou. O trigger passará a mensagem como um parâmetro. - -### Tarefa - obter a string de conexão do endpoint compatível com Event Hub - -1. No terminal do VS Code, execute o seguinte comando para obter a string de conexão para o endpoint compatível com Event Hub do IoT Hub: - - ```sh - az iot hub connection-string show --default-eventhub \ - --output table \ - --hub-name - ``` - - Substitua `` pelo nome que utilizou para o seu IoT Hub. - -1. No VS Code, abra o ficheiro `local.settings.json`. Adicione o seguinte valor adicional dentro da secção `Values`: - - ```json - "IOT_HUB_CONNECTION_STRING": "" - ``` - - Substitua `` pelo valor do passo anterior. Será necessário adicionar uma vírgula após a linha acima para que seja um JSON válido. - -### Tarefa - criar um trigger de evento - -Agora está pronto para criar o trigger de evento. - -1. No terminal do VS Code, execute o seguinte comando dentro da pasta `soil-moisture-trigger`: - - ```sh - func new --name iot-hub-trigger --template "Azure Event Hub trigger" - ``` - - Isto cria uma nova Function chamada `iot-hub-trigger`. O trigger irá conectar-se ao endpoint compatível com Event Hub no IoT Hub, permitindo-lhe usar um trigger de Event Hub. Não existe um trigger específico para IoT Hub. - -Isto criará uma pasta dentro da pasta `soil-moisture-trigger` chamada `iot-hub-trigger`, que contém esta função. Esta pasta terá os seguintes ficheiros: - -* `__init__.py` - este é o ficheiro de código Python que contém o trigger, usando a convenção padrão de nomes de ficheiros Python para transformar esta pasta num módulo Python. - - Este ficheiro conterá o seguinte código: - - ```python - import logging - - import azure.functions as func - - - def main(event: func.EventHubEvent): - logging.info('Python EventHub trigger processed an event: %s', - event.get_body().decode('utf-8')) - ``` - - O núcleo do trigger é a função `main`. É esta função que é chamada com os eventos do IoT Hub. Esta função tem um parâmetro chamado `event` que contém um `EventHubEvent`. Sempre que uma mensagem é enviada para o IoT Hub, esta função é chamada passando essa mensagem como o `event`, juntamente com propriedades que são as mesmas que as anotações que viu na última lição. - - O núcleo desta função regista o evento. - -* `function.json` - este ficheiro contém a configuração para o trigger. A configuração principal está numa secção chamada `bindings`. Um binding é o termo para uma ligação entre Azure Functions e outros serviços Azure. Esta função tem um binding de entrada para um Event Hub - conecta-se a um Event Hub e recebe dados. - - > 💁 Também pode ter bindings de saída para que o output de uma função seja enviado para outro serviço. Por exemplo, poderia adicionar um binding de saída para uma base de dados e retornar o evento do IoT Hub a partir da função, e este seria automaticamente inserido na base de dados. - - ✅ Faça uma pesquisa: Leia sobre bindings na [documentação de conceitos de triggers e bindings do Azure Functions](https://docs.microsoft.com/azure/azure-functions/functions-triggers-bindings?WT.mc_id=academic-17441-jabenn&tabs=python). - - A secção `bindings` inclui a configuração para o binding. Os valores de interesse são: - - * `"type": "eventHubTrigger"` - isto indica que a função precisa de ouvir eventos de um Event Hub - * `"name": "events"` - este é o nome do parâmetro a usar para os eventos do Event Hub. Este corresponde ao nome do parâmetro na função `main` no código Python. - * `"direction": "in"` - este é um binding de entrada, os dados do Event Hub entram na função - * `"connection": ""` - isto define o nome da configuração para ler a string de conexão. Quando executado localmente, esta configuração será lida do ficheiro `local.settings.json`. - - > 💁 A string de conexão não pode ser armazenada no ficheiro `function.json`, tem de ser lida das configurações. Isto é para evitar expor acidentalmente a sua string de conexão. - -1. Devido a [um bug no template do Azure Functions](https://github.com/Azure/azure-functions-templates/issues/1250), o ficheiro `function.json` tem um valor incorreto para o campo `cardinality`. Atualize este campo de `many` para `one`: - - ```json - "cardinality": "one", - ``` - -1. Atualize o valor de `"connection"` no ficheiro `function.json` para apontar para o novo valor que adicionou ao ficheiro `local.settings.json`: - - ```json - "connection": "IOT_HUB_CONNECTION_STRING", - ``` - - > 💁 Lembre-se - isto precisa de apontar para a configuração, não conter a string de conexão real. - -1. A string de conexão contém o valor `eventHubName`, por isso o valor para este no ficheiro `function.json` precisa de ser limpo. Atualize este valor para uma string vazia: - - ```json - "eventHubName": "", - ``` - -### Tarefa - executar o trigger de evento - -1. Certifique-se de que não está a executar o monitor de eventos do IoT Hub. Se este estiver a ser executado ao mesmo tempo que a aplicação Functions, a aplicação Functions não conseguirá conectar-se e consumir eventos. - - > 💁 Várias aplicações podem conectar-se aos endpoints do IoT Hub usando diferentes *consumer groups*. Estes serão abordados numa lição posterior. - -1. Para executar a aplicação Functions, execute o seguinte comando no terminal do VS Code: - - ```sh - func start - ``` - - A aplicação Functions será iniciada e descobrirá a função `iot-hub-trigger`. Em seguida, processará quaisquer eventos que já tenham sido enviados para o IoT Hub no último dia. - - ```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 - - Functions: - - iot-hub-trigger: eventHubTrigger - - For detailed output, run func with --verbose flag. - [2021-05-05T02:44:07.517Z] Worker process started and initialized. - [2021-05-05T02:44:09.202Z] Executing 'Functions.iot-hub-trigger' (Reason='(null)', Id=802803a5-eae9-4401-a1f4-176631456ce4) - [2021-05-05T02:44:09.205Z] Trigger Details: PartitionId: 0, Offset: 1011240-1011632, EnqueueTimeUtc: 2021-05-04T19:04:04.2030000Z-2021-05-04T19:04:04.3900000Z, SequenceNumber: 2546-2547, Count: 2 - [2021-05-05T02:44:09.352Z] Python EventHub trigger processed an event: {"soil_moisture":628} - [2021-05-05T02:44:09.354Z] Python EventHub trigger processed an event: {"soil_moisture":624} - [2021-05-05T02:44:09.395Z] Executed 'Functions.iot-hub-trigger' (Succeeded, Id=802803a5-eae9-4401-a1f4-176631456ce4, Duration=245ms) - ``` - - Cada chamada à função será rodeada por um bloco `Executing 'Functions.iot-hub-trigger'`/`Executed 'Functions.iot-hub-trigger'` na saída, para que possa ver quantas mensagens foram processadas em cada chamada da função. - -1. Certifique-se de que o seu dispositivo IoT está em execução. Verá novas mensagens de humidade do solo a aparecer na aplicação Functions. - -1. Pare e reinicie a aplicação Functions. Verá que não processará mensagens anteriores novamente, apenas processará novas mensagens. - -> 💁 O VS Code também suporta a depuração das suas Functions. Pode definir pontos de interrupção clicando na margem ao lado do início de cada linha de código, ou colocando o cursor numa linha de código e selecionando *Run -> Toggle breakpoint*, ou pressionando `F9`. Pode iniciar o depurador selecionando *Run -> Start debugging*, pressionando `F5`, ou selecionando o painel *Run and debug* e clicando no botão **Start debugging**. Ao fazer isto, pode ver os detalhes dos eventos que estão a ser processados. - -#### Resolução de problemas - -* Se receber o seguinte erro: - - ```output - The listener for function 'Functions.iot-hub-trigger' was unable to start. Microsoft.WindowsAzure.Storage: Connection refused. System.Net.Http: Connection refused. System.Private.CoreLib: Connection refused. - ``` - - Verifique se o Azurite está em execução e se definiu o `AzureWebJobsStorage` no ficheiro `local.settings.json` como `UseDevelopmentStorage=true`. - -* Se receber o seguinte erro: - - ```output - System.Private.CoreLib: Exception while executing function: Functions.iot-hub-trigger. System.Private.CoreLib: Result: Failure Exception: AttributeError: 'list' object has no attribute 'get_body' - ``` - - Verifique se definiu o `cardinality` no ficheiro `function.json` como `one`. - -* Se receber o seguinte erro: - - ```output - Azure.Messaging.EventHubs: The path to an Event Hub may be specified as part of the connection string or as a separate value, but not both. Please verify that your connection string does not have the `EntityPath` token if you are passing an explicit Event Hub name. (Parameter 'connectionString'). - ``` - - Verifique se definiu o `eventHubName` no ficheiro `function.json` como uma string vazia. - -## Enviar pedidos de método direto a partir de código serverless - -Até agora, a sua aplicação Functions está a ouvir mensagens do IoT Hub usando o endpoint compatível com Event Hub. Agora precisa de enviar comandos para o dispositivo IoT. Isto é feito usando uma conexão diferente ao IoT Hub através do *Registry Manager*. O Registry Manager é uma ferramenta que permite ver quais os dispositivos registados no IoT Hub e comunicar com esses dispositivos enviando mensagens cloud-to-device, pedidos de método direto ou atualizando o device twin. Também pode usá-lo para registar, atualizar ou eliminar dispositivos IoT do IoT Hub. - -Para se conectar ao Registry Manager, precisa de uma string de conexão. - -### Tarefa - obter a string de conexão do Registry Manager - -1. Para obter a string de conexão, execute o seguinte comando: - - ```sh - az iot hub connection-string show --policy-name service \ - --output table \ - --hub-name - ``` - - Substitua `` pelo nome que utilizou para o seu IoT Hub. - - A string de conexão é solicitada para a política *ServiceConnect* usando o parâmetro `--policy-name service`. Quando solicita uma string de conexão, pode especificar quais as permissões que essa string de conexão permitirá. A política ServiceConnect permite que o seu código se conecte e envie mensagens para dispositivos IoT. - - ✅ Faça uma pesquisa: Leia sobre as diferentes políticas na [documentação de permissões do IoT Hub](https://docs.microsoft.com/azure/iot-hub/iot-hub-devguide-security#iot-hub-permissions?WT.mc_id=academic-17441-jabenn) - -1. No VS Code, abra o ficheiro `local.settings.json`. Adicione o seguinte valor adicional dentro da secção `Values`: - - ```json - "REGISTRY_MANAGER_CONNECTION_STRING": "" - ``` - - Substitua `` pelo valor do passo anterior. Será necessário adicionar uma vírgula após a linha acima para que seja um JSON válido. - -### Tarefa - enviar um pedido de método direto para um dispositivo - -1. O SDK para o Registry Manager está disponível através de um pacote Pip. Adicione a seguinte linha ao ficheiro `requirements.txt` para adicionar a dependência deste pacote: - - ```sh - azure-iot-hub - ``` - -1. Certifique-se de que o terminal do VS Code tem o ambiente virtual ativado e execute o seguinte comando para instalar os pacotes Pip: - - ```sh - pip install -r requirements.txt - ``` - -1. Adicione as seguintes importações ao ficheiro `__init__.py`: - - ```python - import json - import os - from azure.iot.hub import IoTHubRegistryManager - from azure.iot.hub.models import CloudToDeviceMethod - ``` - - Isto importa algumas bibliotecas do sistema, bem como as bibliotecas para interagir com o Registry Manager e enviar pedidos de método direto. - -1. Remova o código de dentro do método `main`, mas mantenha o método em si. - -1. No método `main`, adicione o seguinte código: - - ```python - body = json.loads(event.get_body().decode('utf-8')) - device_id = event.iothub_metadata['connection-device-id'] - - logging.info(f'Received message: {body} from {device_id}') - ``` - - Este código extrai o corpo do evento, que contém a mensagem JSON enviada pelo dispositivo IoT. - - Em seguida, obtém o ID do dispositivo a partir das anotações passadas com a mensagem. O corpo do evento contém a mensagem enviada como telemetria, e o dicionário `iothub_metadata` contém propriedades definidas pelo IoT Hub, como o ID do dispositivo do remetente e a hora em que a mensagem foi enviada. - - Esta informação é então registada. Verá este registo no terminal quando executar a aplicação Function localmente. - -1. Abaixo disto, adicione o seguinte código: - - ```python - soil_moisture = body['soil_moisture'] - - if soil_moisture > 450: - direct_method = CloudToDeviceMethod(method_name='relay_on', payload='{}') - else: - direct_method = CloudToDeviceMethod(method_name='relay_off', payload='{}') - ``` - - Este código obtém a humidade do solo da mensagem. Em seguida, verifica a humidade do solo e, dependendo do valor, cria uma classe auxiliar para o pedido de método direto para o método `relay_on` ou `relay_off`. O pedido de método não precisa de um payload, por isso é enviado um documento JSON vazio. - -1. Abaixo disto, adicione o seguinte código: - - ```python - logging.info(f'Sending direct method request for {direct_method.method_name} for device {device_id}') - - registry_manager_connection_string = os.environ['REGISTRY_MANAGER_CONNECTION_STRING'] - registry_manager = IoTHubRegistryManager(registry_manager_connection_string) - ``` -Este código carrega a `REGISTRY_MANAGER_CONNECTION_STRING` do ficheiro `local.settings.json`. Os valores neste ficheiro são disponibilizados como variáveis de ambiente, que podem ser lidas utilizando a função `os.environ`, uma função que retorna um dicionário com todas as variáveis de ambiente. - -> 💁 Quando este código é implementado na cloud, os valores no ficheiro `local.settings.json` serão definidos como *Application Settings*, e podem ser lidos a partir das variáveis de ambiente. - -O código cria então uma instância da classe auxiliar Registry Manager utilizando a connection string. - -1. Abaixo disso, adicione o seguinte código: - - ```python - registry_manager.invoke_device_method(device_id, direct_method) - - logging.info('Direct method request sent!') - ``` - - Este código instrui o registry manager a enviar o pedido de método direto para o dispositivo que enviou a telemetria. - - > 💁 Nas versões da aplicação que criou em lições anteriores utilizando MQTT, os comandos de controlo do relé eram enviados para todos os dispositivos. O código assumia que teria apenas um dispositivo. Esta versão do código envia o pedido de método para um único dispositivo, funcionando assim caso tenha múltiplas configurações de sensores de humidade e relés, enviando o pedido de método direto para o dispositivo correto. - -1. Execute a aplicação Functions e certifique-se de que o seu dispositivo IoT está a enviar dados. Verá as mensagens a serem processadas e os pedidos de método direto a serem enviados. Mova o sensor de humidade do solo para dentro e fora do solo para ver os valores mudarem e o relé ligar e desligar. - -> 💁 Pode encontrar este código na pasta [code/functions](../../../../../2-farm/lessons/5-migrate-application-to-the-cloud/code/functions). - -## Implemente o seu código serverless na cloud - -O seu código já está a funcionar localmente, então o próximo passo é implementar a aplicação Functions na cloud. - -### Tarefa - criar os recursos na cloud - -A sua aplicação Functions precisa de ser implementada num recurso Functions App no Azure, dentro do Resource Group que criou para o seu IoT Hub. Também precisará de uma Storage Account criada no Azure para substituir o emulador que está a usar localmente. - -1. Execute o seguinte comando para criar uma storage account: - - ```sh - az storage account create --resource-group soil-moisture-sensor \ - --sku Standard_LRS \ - --name - ``` - - Substitua `` por um nome para a sua storage account. Este nome precisa de ser único globalmente, pois faz parte do URL usado para aceder à storage account. Pode usar apenas letras minúsculas e números para este nome, sem outros caracteres, e está limitado a 24 caracteres. Use algo como `sms` e adicione um identificador único no final, como algumas palavras aleatórias ou o seu nome. - - A opção `--sku Standard_LRS` seleciona o nível de preços, escolhendo a conta geral de menor custo. Não existe um nível gratuito de armazenamento, e paga pelo que utiliza. Os custos são relativamente baixos, sendo o armazenamento mais caro menos de US$0.05 por mês por gigabyte armazenado. - - ✅ Leia mais sobre preços na [página de preços do Azure Storage Account](https://azure.microsoft.com/pricing/details/storage/?WT.mc_id=academic-17441-jabenn) - -1. Execute o seguinte comando para criar uma Function App: - - ```sh - az functionapp create --resource-group soil-moisture-sensor \ - --runtime python \ - --functions-version 3 \ - --os-type Linux \ - --consumption-plan-location \ - --storage-account \ - --name - ``` - - Substitua `` pela localização que utilizou ao criar o Resource Group na lição anterior. - - Substitua `` pelo nome da storage account que criou no passo anterior. - - Substitua `` por um nome único para a sua Function App. Este nome precisa de ser único globalmente, pois faz parte de um URL que pode ser usado para aceder à Function App. Use algo como `soil-moisture-sensor-` e adicione um identificador único no final, como algumas palavras aleatórias ou o seu nome. - - A opção `--functions-version 3` define a versão do Azure Functions a utilizar. A versão 3 é a mais recente. - - A opção `--os-type Linux` indica ao runtime do Functions para usar Linux como sistema operativo para hospedar estas funções. As funções podem ser hospedadas em Linux ou Windows, dependendo da linguagem de programação utilizada. Aplicações Python são suportadas apenas em Linux. - -### Tarefa - carregar as suas configurações de aplicação - -Quando desenvolveu a sua Function App, armazenou algumas configurações no ficheiro `local.settings.json` para as connection strings do seu IoT Hub. Estas precisam de ser escritas nas Application Settings na sua Function App no Azure para que possam ser utilizadas pelo seu código. - -> 🎓 O ficheiro `local.settings.json` é apenas para configurações de desenvolvimento local e não deve ser incluído no controlo de código fonte, como o GitHub. Quando implementado na cloud, são utilizadas Application Settings. Application Settings são pares chave/valor hospedados na cloud e são lidos a partir de variáveis de ambiente, quer no seu código, quer pelo runtime ao conectar o seu código ao IoT Hub. - -1. Execute o seguinte comando para definir a configuração `IOT_HUB_CONNECTION_STRING` nas Application Settings da Function App: - - ```sh - az functionapp config appsettings set --resource-group soil-moisture-sensor \ - --name \ - --settings "IOT_HUB_CONNECTION_STRING=" - ``` - - Substitua `` pelo nome que utilizou para a sua Function App. - - Substitua `` pelo valor de `IOT_HUB_CONNECTION_STRING` do seu ficheiro `local.settings.json`. - -1. Repita o passo acima, mas defina o valor de `REGISTRY_MANAGER_CONNECTION_STRING` para o valor correspondente do seu ficheiro `local.settings.json`. - -Quando executar estes comandos, será exibida uma lista de todas as Application Settings da Function App. Pode usar esta lista para verificar se os valores estão definidos corretamente. - -> 💁 Verá um valor já definido para `AzureWebJobsStorage`. No seu ficheiro `local.settings.json`, este foi definido para usar o emulador de armazenamento local. Quando criou a Function App, passou a storage account como parâmetro, e esta configuração foi definida automaticamente. - -### Tarefa - implementar a sua Function App na cloud - -Agora que a Function App está pronta, o seu código pode ser implementado. - -1. Execute o seguinte comando no terminal do VS Code para publicar a sua Function App: - - ```sh - func azure functionapp publish - ``` - - Substitua `` pelo nome que utilizou para a sua Function App. - -O código será empacotado e enviado para a Function App, onde será implementado e iniciado. Haverá uma grande quantidade de saída no console, terminando com a confirmação da implementação e uma lista das funções implementadas. Neste caso, a lista conterá apenas o trigger. - -```output -Deployment successful. -Remote build succeeded! -Syncing triggers... -Functions in soil-moisture-sensor: - iot-hub-trigger - [eventHubTrigger] -``` - -Certifique-se de que o seu dispositivo IoT está a funcionar. Altere os níveis de humidade ajustando a humidade do solo ou movendo o sensor para dentro e fora do solo. Verá o relé ligar e desligar à medida que a humidade do solo muda. - ---- - -## 🚀 Desafio - -Na lição anterior, geriu o tempo do relé ao cancelar a subscrição de mensagens MQTT enquanto o relé estava ligado e por um curto período após ser desligado. Não pode usar este método aqui - não pode cancelar a subscrição do trigger do IoT Hub. - -Pense em diferentes formas de lidar com isto na sua Function App. - -## Questionário pós-aula - -[Questionário pós-aula](https://black-meadow-040d15503.1.azurestaticapps.net/quiz/18) - -## Revisão & Estudo Individual - -* Leia sobre computação serverless na [página de Serverless Computing na Wikipedia](https://wikipedia.org/wiki/Serverless_computing) -* Leia sobre o uso de serverless no Azure, incluindo mais exemplos, no [post do blog do Azure sobre serverless para IoT](https://azure.microsoft.com/blog/go-serverless-for-your-iot-needs/?WT.mc_id=academic-17441-jabenn) -* Aprenda mais sobre Azure Functions no [canal do YouTube Azure Functions](https://www.youtube.com/c/AzureFunctions) - -## Tarefa - -[Adicionar controlo manual do relé](assignment.md) - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, esteja ciente de que traduções automáticas podem conter erros ou imprecisões. O documento original no seu idioma nativo deve ser considerado a fonte autoritativa. Para informações críticas, recomenda-se a tradução profissional humana. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas resultantes do uso desta tradução. \ No newline at end of file diff --git a/translations/pt/2-farm/lessons/5-migrate-application-to-the-cloud/assignment.md b/translations/pt/2-farm/lessons/5-migrate-application-to-the-cloud/assignment.md deleted file mode 100644 index 05400ec41..000000000 --- a/translations/pt/2-farm/lessons/5-migrate-application-to-the-cloud/assignment.md +++ /dev/null @@ -1,68 +0,0 @@ - -# Adicionar controlo manual ao relé - -## Instruções - -Código serverless pode ser acionado por diversos eventos, incluindo pedidos HTTP. Pode usar triggers HTTP para adicionar um controlo manual ao relé, permitindo que alguém ligue ou desligue o relé através de um pedido web. - -Para esta tarefa, precisa de adicionar dois triggers HTTP à sua Functions App para ligar e desligar o relé, reutilizando o que aprendeu nesta lição para enviar comandos ao dispositivo. - -Algumas dicas: - -* Pode adicionar um trigger HTTP à sua Functions App existente com o seguinte comando: - - ```sh - func new --name --template "HTTP trigger" - ``` - - Substitua `` pelo nome do seu trigger HTTP. Use algo como `relay_on` e `relay_off`. - -* Triggers HTTP podem ter controlo de acesso. Por padrão, requerem uma chave API específica da função que deve ser passada com o URL para serem executados. Para esta tarefa, pode remover esta restrição para que qualquer pessoa possa executar a função. Para fazer isso, atualize a configuração `authLevel` no ficheiro `function.json` para os triggers HTTP com o seguinte: - - ```json - "authLevel": "anonymous" - ``` - - > 💁 Pode ler mais sobre este controlo de acesso na [documentação sobre chaves de acesso de funções](https://docs.microsoft.com/azure/azure-functions/functions-bindings-http-webhook-trigger?WT.mc_id=academic-17441-jabenn#authorization-keys). - -* Triggers HTTP, por padrão, suportam pedidos GET e POST. Isto significa que pode chamá-los usando o seu navegador web - navegadores web fazem pedidos GET. - - Quando executar a sua Functions App localmente, verá o URL do trigger: - - ```output - Functions: - - relay_off: [GET,POST] http://localhost:7071/api/relay_off - - relay_on: [GET,POST] http://localhost:7071/api/relay_on - - iot-hub-trigger: eventHubTrigger - ``` - - Cole o URL no seu navegador e pressione `enter`, ou `Ctrl+click` (`Cmd+click` no macOS) no link na janela do terminal no VS Code para abri-lo no navegador padrão. Isto irá executar o trigger. - - > 💁 Note que o URL contém `/api` - triggers HTTP estão, por padrão, no subdomínio `api`. - -* Quando publicar a Functions App, o URL do trigger HTTP será: - - `https://.azurewebsites.net/api/` - - Onde `` é o nome da sua Functions App, e `` é o nome do seu trigger. - -## Rubrica - -| Critério | Exemplar | Adequado | Necessita Melhorias | -| -------- | --------- | -------- | ------------------- | -| Criar triggers HTTP | Criou 2 triggers para ligar e desligar o relé, com nomes apropriados | Criou um trigger com um nome apropriado | Não conseguiu criar nenhum trigger | -| Controlar o relé a partir dos triggers HTTP | Conseguiu ligar ambos os triggers ao IoT Hub e controlar o relé corretamente | Conseguiu ligar um trigger ao IoT Hub e controlar o relé corretamente | Não conseguiu ligar os triggers ao IoT Hub | - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos pela precisão, esteja ciente de que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes do uso desta tradução. \ No newline at end of file diff --git a/translations/pt/2-farm/lessons/6-keep-your-plant-secure/README.md b/translations/pt/2-farm/lessons/6-keep-your-plant-secure/README.md deleted file mode 100644 index ba26a7ba4..000000000 --- a/translations/pt/2-farm/lessons/6-keep-your-plant-secure/README.md +++ /dev/null @@ -1,243 +0,0 @@ - -# Mantenha a sua planta segura - -![Uma visão geral ilustrada desta lição](../../../../../translated_images/pt-PT/lesson-10.829c86b80b9403bb770929ee553a1d293afe50dc23121aaf9be144673ae012cc.jpg) - -> Ilustração por [Nitya Narasimhan](https://github.com/nitya). Clique na imagem para uma versão maior. - -## Questionário pré-aula - -[Questionário pré-aula](https://black-meadow-040d15503.1.azurestaticapps.net/quiz/19) - -## Introdução - -Nas últimas lições, criou um dispositivo IoT para monitorização do solo e conectou-o à nuvem. Mas e se hackers a trabalhar para um agricultor rival conseguissem tomar controlo dos seus dispositivos IoT? E se eles enviassem leituras de humidade do solo muito altas para que as suas plantas nunca fossem regadas, ou ligassem o sistema de rega continuamente, matando as plantas por excesso de água e gerando custos elevados com água? - -Nesta lição, aprenderá a proteger dispositivos IoT. Como esta é a última lição deste projeto, também aprenderá a limpar os seus recursos na nuvem, reduzindo potenciais custos. - -Nesta lição, abordaremos: - -* [Por que é necessário proteger dispositivos IoT?](../../../../../2-farm/lessons/6-keep-your-plant-secure) -* [Criptografia](../../../../../2-farm/lessons/6-keep-your-plant-secure) -* [Proteja os seus dispositivos IoT](../../../../../2-farm/lessons/6-keep-your-plant-secure) -* [Gerar e usar um certificado X.509](../../../../../2-farm/lessons/6-keep-your-plant-secure) - -> 🗑 Esta é a última lição deste projeto, por isso, após concluir esta lição e o exercício, não se esqueça de limpar os seus serviços na nuvem. Precisará dos serviços para concluir o exercício, por isso certifique-se de o fazer primeiro. -> -> Consulte [o guia para limpar o seu projeto](../../../clean-up.md) se necessário, para obter instruções sobre como fazê-lo. - -## Por que é necessário proteger dispositivos IoT? - -A segurança em IoT envolve garantir que apenas dispositivos esperados possam conectar-se ao seu serviço IoT na nuvem e enviar telemetria, e que apenas o seu serviço na nuvem possa enviar comandos aos seus dispositivos. Os dados de IoT também podem ser pessoais, incluindo informações médicas ou íntimas, por isso toda a aplicação precisa considerar a segurança para evitar que esses dados sejam expostos. - -Se a sua aplicação IoT não for segura, existem vários riscos: - -* Um dispositivo falso pode enviar dados incorretos, fazendo com que a sua aplicação responda de forma errada. Por exemplo, podem enviar leituras constantes de alta humidade do solo, o que significa que o sistema de irrigação nunca será ativado e as suas plantas morrerão por falta de água. -* Utilizadores não autorizados podem ler dados de dispositivos IoT, incluindo dados pessoais ou críticos para o negócio. -* Hackers podem enviar comandos para controlar um dispositivo de forma a causar danos ao dispositivo ou ao hardware conectado. -* Ao conectar-se a um dispositivo IoT, hackers podem usar isso para aceder a redes adicionais e obter acesso a sistemas privados. -* Utilizadores mal-intencionados podem aceder a dados pessoais e usá-los para chantagem. - -Estes são cenários do mundo real e acontecem frequentemente. Alguns exemplos foram dados em lições anteriores, mas aqui estão mais alguns: - -* Em 2018, hackers usaram um ponto de acesso WiFi aberto num termóstato de aquário para aceder à rede de um casino e roubar dados. [The Hacker News - Casino Gets Hacked Through Its Internet-Connected Fish Tank Thermometer](https://thehackernews.com/2018/04/iot-hacking-thermometer.html) -* Em 2016, o Mirai Botnet lançou um ataque de negação de serviço contra a Dyn, um fornecedor de serviços de Internet, derrubando grandes partes da Internet. Este botnet usou malware para conectar-se a dispositivos IoT, como DVRs e câmaras, que usavam nomes de utilizador e senhas padrão, e a partir daí lançou o ataque. [The Guardian - DDoS attack that disrupted internet was largest of its kind in history, experts say](https://www.theguardian.com/technology/2016/oct/26/ddos-attack-dyn-mirai-botnet) -* A Spiral Toys tinha uma base de dados de utilizadores dos seus brinquedos conectados CloudPets disponível publicamente na Internet. [Troy Hunt - Data from connected CloudPets teddy bears leaked and ransomed, exposing kids' voice messages](https://www.troyhunt.com/data-from-connected-cloudpets-teddy-bears-leaked-and-ransomed-exposing-kids-voice-messages/). -* A Strava identificava corredores que passavam por si e mostrava as suas rotas, permitindo que estranhos vissem onde você mora. [Kim Komando - Fitness app could lead a stranger right to your home — change this setting](https://www.komando.com/security-privacy/strava-fitness-app-privacy/755349/). - -✅ Faça uma pesquisa: Procure mais exemplos de ataques e violações de dados em IoT, especialmente com itens pessoais, como escovas de dentes ou balanças conectadas à Internet. Pense no impacto que esses ataques podem ter nas vítimas ou clientes. - -> 💁 A segurança é um tópico vasto, e esta lição abordará apenas alguns dos conceitos básicos relacionados com a conexão do seu dispositivo à nuvem. Outros tópicos que não serão abordados incluem monitorização de alterações de dados em trânsito, hacking direto de dispositivos ou alterações nas configurações dos dispositivos. O hacking de IoT é uma ameaça tão grande que ferramentas como [Azure Defender for IoT](https://azure.microsoft.com/services/azure-defender-for-iot/?WT.mc_id=academic-17441-jabenn) foram desenvolvidas. Estas ferramentas são semelhantes aos antivírus e ferramentas de segurança que pode ter no seu computador, mas projetadas para dispositivos IoT pequenos e de baixo consumo. - -## Criptografia - -Quando um dispositivo conecta-se a um serviço IoT, ele usa um ID para se identificar. O problema é que este ID pode ser clonado - um hacker pode configurar um dispositivo malicioso que usa o mesmo ID de um dispositivo real, mas envia dados falsos. - -![Tanto dispositivos válidos quanto maliciosos podem usar o mesmo ID para enviar telemetria](../../../../../translated_images/pt-PT/iot-device-and-hacked-device-connecting.e0671675df74d6d99eb1dedb5a670e606f698efa6202b1ad4c8ae548db299cc6.png) - -A solução para isso é converter os dados enviados num formato codificado, usando um valor conhecido apenas pelo dispositivo e pela nuvem para codificar os dados. Este processo é chamado de *encriptação*, e o valor usado para encriptar os dados é chamado de *chave de encriptação*. - -![Se a encriptação for usada, apenas mensagens encriptadas serão aceites, outras serão rejeitadas](../../../../../translated_images/pt-PT/iot-device-and-hacked-device-connecting-encryption.5941aff601fc978f979e46f2849b573564eeb4a4dc5b52f669f62745397492fb.png) - -O serviço na nuvem pode então converter os dados de volta para um formato legível, usando um processo chamado *desencriptação*, utilizando a mesma chave de encriptação ou uma *chave de desencriptação*. Se a mensagem encriptada não puder ser desencriptada pela chave, o dispositivo foi hackeado e a mensagem é rejeitada. - -A técnica para realizar encriptação e desencriptação é chamada de *criptografia*. - -### Criptografia antiga - -Os primeiros tipos de criptografia eram cifras de substituição, datando de 3.500 anos atrás. As cifras de substituição envolvem substituir uma letra por outra. Por exemplo, a [cifra de César](https://wikipedia.org/wiki/Caesar_cipher) envolve deslocar o alfabeto por uma quantidade definida, sendo que apenas o remetente da mensagem encriptada e o destinatário pretendido sabem quantas letras deslocar. - -A [cifra de Vigenère](https://wikipedia.org/wiki/Vigenère_cipher) levou isso mais longe, usando palavras para encriptar texto, de forma que cada letra no texto original fosse deslocada por uma quantidade diferente, em vez de sempre deslocar pelo mesmo número de letras. - -A criptografia foi usada para uma ampla gama de propósitos, como proteger receitas de esmalte de cerâmica na antiga Mesopotâmia, escrever bilhetes de amor secretos na Índia ou manter feitiços mágicos egípcios em segredo. - -### Criptografia moderna - -A criptografia moderna é muito mais avançada, tornando-a mais difícil de decifrar do que os métodos antigos. A criptografia moderna usa matemática complexa para encriptar dados, com um número de chaves possíveis tão grande que ataques de força bruta tornam-se inviáveis. - -A criptografia é usada de várias formas para comunicações seguras. Se está a ler esta página no GitHub, pode notar que o endereço do site começa com *HTTPS*, o que significa que a comunicação entre o seu navegador e os servidores do GitHub está encriptada. Se alguém conseguisse ler o tráfego da Internet entre o seu navegador e o GitHub, não conseguiria ler os dados, pois estão encriptados. O seu computador pode até encriptar todos os dados no disco rígido, para que, se alguém o roubar, não consiga ler os seus dados sem a sua palavra-passe. - -> 🎓 HTTPS significa HyperText Transfer Protocol **Secure** - -Infelizmente, nem tudo é seguro. Alguns dispositivos não têm segurança, outros são protegidos com chaves fáceis de decifrar, ou às vezes todos os dispositivos do mesmo tipo usam a mesma chave. Há relatos de dispositivos IoT muito pessoais que têm a mesma palavra-passe para se conectarem via WiFi ou Bluetooth. Se consegue conectar-se ao seu próprio dispositivo, pode conectar-se ao de outra pessoa. Uma vez conectado, pode aceder a dados muito privados ou controlar o dispositivo de outra pessoa. - -> 💁 Apesar da complexidade da criptografia moderna e das alegações de que quebrar a encriptação pode levar bilhões de anos, o avanço da computação quântica trouxe a possibilidade de quebrar toda a encriptação conhecida em muito pouco tempo! - -### Chaves simétricas e assimétricas - -A encriptação pode ser de dois tipos - simétrica e assimétrica. - -A encriptação **simétrica** usa a mesma chave para encriptar e desencriptar os dados. Tanto o remetente quanto o destinatário precisam conhecer a mesma chave. Este é o tipo menos seguro, pois a chave precisa ser partilhada de alguma forma. Para que um remetente envie uma mensagem encriptada a um destinatário, o remetente pode primeiro ter que enviar a chave ao destinatário. - -![A encriptação com chave simétrica usa a mesma chave para encriptar e desencriptar uma mensagem](../../../../../translated_images/pt-PT/send-message-symmetric-key.a2e8ad0d495896ff.webp) - -Se a chave for roubada durante o envio, ou se o remetente ou destinatário forem hackeados e a chave for descoberta, a encriptação pode ser comprometida. - -![A encriptação com chave simétrica só é segura se um hacker não obtiver a chave - caso contrário, podem interceptar e desencriptar a mensagem](../../../../../translated_images/pt-PT/send-message-symmetric-key-hacker.e7cb53db1707adfb.webp) - -A encriptação **assimétrica** usa 2 chaves - uma chave de encriptação e uma chave de desencriptação, conhecidas como par de chaves pública/privada. A chave pública é usada para encriptar a mensagem, mas não pode ser usada para desencriptá-la; a chave privada é usada para desencriptar a mensagem, mas não pode ser usada para encriptá-la. - -![A encriptação assimétrica usa uma chave diferente para encriptar e desencriptar. A chave de encriptação é enviada a qualquer remetente para que possam encriptar uma mensagem antes de enviá-la ao destinatário que possui as chaves](../../../../../translated_images/pt-PT/send-message-asymmetric.7abe327c62615b8c.webp) - -O destinatário partilha a sua chave pública, e o remetente usa-a para encriptar a mensagem. Depois de enviada, o destinatário desencripta-a com a sua chave privada. A encriptação assimétrica é mais segura, pois a chave privada é mantida em segredo pelo destinatário e nunca é partilhada. Qualquer pessoa pode ter a chave pública, pois ela só pode ser usada para encriptar mensagens. - -A encriptação simétrica é mais rápida do que a assimétrica, mas a assimétrica é mais segura. Alguns sistemas usam ambas - utilizam a encriptação assimétrica para encriptar e partilhar a chave simétrica, e depois usam a chave simétrica para encriptar todos os dados. Isso torna mais seguro partilhar a chave simétrica entre remetente e destinatário, e mais rápido encriptar e desencriptar os dados. - -## Proteja os seus dispositivos IoT - -Os dispositivos IoT podem ser protegidos usando encriptação simétrica ou assimétrica. A simétrica é mais fácil, mas menos segura. - -### Chaves simétricas - -Quando configurou o seu dispositivo IoT para interagir com o IoT Hub, utilizou uma string de conexão. Um exemplo de string de conexão é: - -```output -HostName=soil-moisture-sensor.azure-devices.net;DeviceId=soil-moisture-sensor;SharedAccessKey=Bhry+ind7kKEIDxubK61RiEHHRTrPl7HUow8cEm/mU0= -``` - -Esta string de conexão é composta por três partes separadas por ponto e vírgula, com cada parte sendo uma chave e um valor: - -| Chave | Valor | Descrição | -| --- | ----- | ----------- | -| HostName | `soil-moisture-sensor.azure-devices.net` | O URL do IoT Hub | -| DeviceId | `soil-moisture-sensor` | O ID único do dispositivo | -| SharedAccessKey | `Bhry+ind7kKEIDxubK61RiEHHRTrPl7HUow8cEm/mU0=` | Uma chave simétrica conhecida pelo dispositivo e pelo IoT Hub | - -A última parte desta string de conexão, o `SharedAccessKey`, é a chave simétrica conhecida tanto pelo dispositivo quanto pelo IoT Hub. Esta chave nunca é enviada do dispositivo para a nuvem, nem da nuvem para o dispositivo. Em vez disso, é usada para encriptar os dados enviados ou recebidos. - -✅ Faça uma experiência. O que acha que acontecerá se alterar a parte `SharedAccessKey` da string de conexão ao conectar o seu dispositivo IoT? Experimente. - -Quando o dispositivo tenta conectar-se pela primeira vez, ele envia um token de assinatura de acesso partilhado (SAS) que consiste no URL do IoT Hub, um carimbo de data/hora indicando quando a assinatura de acesso expirará (geralmente 1 dia a partir do momento atual) e uma assinatura. Esta assinatura consiste no URL e no tempo de expiração encriptados com a chave de acesso partilhada da string de conexão. - -O IoT Hub desencripta esta assinatura com a chave de acesso partilhada e, se o valor desencriptado corresponder ao URL e à expiração, o dispositivo é autorizado a conectar-se. Ele também verifica se o horário atual é anterior à expiração, para impedir que um dispositivo malicioso capture o token SAS de um dispositivo real e o utilize. - -Esta é uma forma elegante de verificar se o remetente é o dispositivo correto. Ao enviar alguns dados conhecidos tanto em forma desencriptada quanto encriptada, o servidor pode verificar o dispositivo garantindo que, ao desencriptar os dados encriptados, o resultado corresponde à versão desencriptada enviada. Se corresponder, então tanto o remetente quanto o destinatário possuem a mesma chave de encriptação simétrica. -💁 Devido ao tempo de expiração, o seu dispositivo IoT precisa saber a hora exata, geralmente obtida de um servidor [NTP](https://wikipedia.org/wiki/Network_Time_Protocol). Se a hora não estiver correta, a ligação falhará. -Após a conexão, todos os dados enviados para o IoT Hub a partir do dispositivo, ou para o dispositivo a partir do IoT Hub, serão encriptados com a chave de acesso partilhada. - -✅ O que acha que acontecerá se vários dispositivos partilharem a mesma string de conexão? - -> 💁 Não é uma boa prática de segurança armazenar esta chave no código. Se um hacker obtiver o seu código-fonte, poderá aceder à sua chave. Além disso, torna-se mais difícil ao lançar o código, pois seria necessário recompilar com uma chave atualizada para cada dispositivo. É melhor carregar esta chave a partir de um módulo de segurança de hardware - um chip no dispositivo IoT que armazena valores encriptados que podem ser lidos pelo seu código. -> -> Quando está a aprender IoT, muitas vezes é mais fácil colocar a chave no código, como fez numa lição anterior, mas deve garantir que esta chave não seja incluída num controlo de código-fonte público. - -Os dispositivos têm 2 chaves e 2 strings de conexão correspondentes. Isto permite rodar as chaves - ou seja, alternar de uma chave para outra caso a primeira seja comprometida, e gerar novamente a primeira chave. - -### Certificados X.509 - -Quando utiliza encriptação assimétrica com um par de chaves pública/privada, precisa de fornecer a sua chave pública a quem quiser enviar-lhe dados. O problema é: como é que o destinatário da sua chave pode ter a certeza de que é realmente a sua chave pública e não de alguém a fingir ser você? Em vez de fornecer uma chave, pode fornecer a sua chave pública dentro de um certificado que foi verificado por uma terceira parte confiável, chamado certificado X.509. - -Os certificados X.509 são documentos digitais que contêm a parte pública do par de chaves pública/privada. Normalmente, são emitidos por uma das várias organizações confiáveis chamadas [Autoridades de Certificação](https://wikipedia.org/wiki/Certificate_authority) (CAs) e assinados digitalmente pela CA para indicar que a chave é válida e vem de si. Confia no certificado e na chave pública porque confia na CA, de forma semelhante a como confiaria num passaporte ou carta de condução porque confia no país que os emitiu. Os certificados têm um custo, mas também pode "auto-assinar", ou seja, criar um certificado você mesmo e assiná-lo para fins de teste. - -> 💁 Nunca deve usar um certificado auto-assinado numa versão de produção. - -Estes certificados têm vários campos, incluindo quem é o proprietário da chave pública, os detalhes da CA que o emitiu, o período de validade e a própria chave pública. Antes de usar um certificado, é uma boa prática verificá-lo, confirmando que foi assinado pela CA original. - -✅ Pode consultar uma lista completa dos campos do certificado no [tutorial da Microsoft sobre Certificados de Chave Pública X.509](https://docs.microsoft.com/azure/iot-hub/tutorial-x509-certificates?WT.mc_id=academic-17441-jabenn#certificate-fields) - -Ao usar certificados X.509, tanto o remetente quanto o destinatário terão as suas próprias chaves públicas e privadas, bem como certificados X.509 que contêm as chaves públicas. Eles trocam os certificados X.509 de alguma forma, usando as chaves públicas um do outro para encriptar os dados que enviam e as suas próprias chaves privadas para desencriptar os dados que recebem. - -![Em vez de partilhar uma chave pública, pode partilhar um certificado. O utilizador do certificado pode verificar que ele vem de si ao confirmar com a autoridade de certificação que o assinou.](../../../../../translated_images/pt-PT/send-message-certificate.9cc576ac1e46b76e.webp) - -Uma grande vantagem de usar certificados X.509 é que podem ser partilhados entre dispositivos. Pode criar um certificado, carregá-lo para o IoT Hub e usá-lo para todos os seus dispositivos. Cada dispositivo só precisa de conhecer a chave privada para desencriptar as mensagens que recebe do IoT Hub. - -O certificado usado pelo seu dispositivo para encriptar mensagens enviadas para o IoT Hub é publicado pela Microsoft. É o mesmo certificado que muitos serviços do Azure utilizam e, por vezes, está integrado nos SDKs. - -> 💁 Lembre-se, uma chave pública é exatamente isso - pública. A chave pública do Azure só pode ser usada para encriptar dados enviados para o Azure, não para os desencriptar, por isso pode ser partilhada em qualquer lugar, incluindo no código-fonte. Por exemplo, pode vê-la no [código-fonte do SDK C do Azure IoT](https://github.com/Azure/azure-iot-sdk-c/blob/master/certs/certs.c). - -✅ Há muitos termos técnicos associados aos certificados X.509. Pode consultar as definições de alguns dos termos que poderá encontrar no [Guia simplificado sobre o jargão dos certificados X.509](https://techcommunity.microsoft.com/t5/internet-of-things/the-layman-s-guide-to-x-509-certificate-jargon/ba-p/2203540?WT.mc_id=academic-17441-jabenn) - -## Gerar e usar um certificado X.509 - -Os passos para gerar um certificado X.509 são: - -1. Criar um par de chaves pública/privada. Um dos algoritmos mais amplamente utilizados para gerar um par de chaves pública/privada é chamado [Rivest–Shamir–Adleman](https://wikipedia.org/wiki/RSA_(cryptosystem)) (RSA). - -1. Submeter a chave pública com os dados associados para assinatura, seja por uma CA ou por auto-assinatura. - -O Azure CLI tem comandos para criar uma nova identidade de dispositivo no IoT Hub, gerar automaticamente o par de chaves pública/privada e criar um certificado auto-assinado. - -> 💁 Se quiser ver os passos em detalhe, em vez de usar o Azure CLI, pode encontrá-los no [tutorial sobre como usar o OpenSSL para criar certificados auto-assinados na documentação do Microsoft IoT Hub](https://docs.microsoft.com/azure/iot-hub/tutorial-x509-self-sign?WT.mc_id=academic-17441-jabenn) - -### Tarefa - criar uma identidade de dispositivo usando um certificado X.509 - -1. Execute o seguinte comando para registar a nova identidade de dispositivo, gerando automaticamente as chaves e os certificados: - - ```sh - az iot hub device-identity create --device-id soil-moisture-sensor-x509 \ - --am x509_thumbprint \ - --output-dir . \ - --hub-name - ``` - - Substitua `` pelo nome que utilizou para o seu IoT Hub. - - Isto criará um dispositivo com o ID `soil-moisture-sensor-x509` para o distinguir da identidade de dispositivo que criou na última lição. Este comando também criará 2 ficheiros no diretório atual: - - * `soil-moisture-sensor-x509-key.pem` - este ficheiro contém a chave privada do dispositivo. - * `soil-moisture-sensor-x509-cert.pem` - este é o ficheiro de certificado X.509 do dispositivo. - - Guarde estes ficheiros em segurança! O ficheiro da chave privada não deve ser incluído num controlo de código-fonte público. - -### Tarefa - usar o certificado X.509 no código do seu dispositivo - -Siga o guia relevante para conectar o seu dispositivo IoT à cloud usando o certificado X.509: - -* [Arduino - Wio Terminal](wio-terminal-x509.md) -* [Computador de placa única - Raspberry Pi/Dispositivo IoT Virtual](single-board-computer-x509.md) - ---- - -## 🚀 Desafio - -Existem várias formas de criar, gerir e eliminar serviços Azure, como Grupos de Recursos e IoT Hubs. Uma delas é o [Azure Portal](https://portal.azure.com?WT.mc_id=academic-17441-jabenn) - uma interface web que oferece um GUI para gerir os seus serviços Azure. - -Aceda a [portal.azure.com](https://portal.azure.com?WT.mc_id=academic-17441-jabenn) e explore o portal. Veja se consegue criar um IoT Hub através do portal e, em seguida, eliminá-lo. - -**Dica** - ao criar serviços através do portal, não precisa de criar um Grupo de Recursos antecipadamente, pode criá-lo durante a criação do serviço. Certifique-se de que o elimina quando terminar! - -Pode encontrar muita documentação, tutoriais e guias sobre o Azure Portal na [documentação do Azure Portal](https://docs.microsoft.com/azure/azure-portal/?WT.mc_id=academic-17441-jabenn). - -## Questionário pós-aula - -[Questionário pós-aula](https://black-meadow-040d15503.1.azurestaticapps.net/quiz/20) - -## Revisão e Estudo Individual - -* Leia sobre a história da criptografia na [página da História da Criptografia na Wikipedia](https://wikipedia.org/wiki/History_of_cryptography). -* Leia sobre certificados X.509 na [página X.509 na Wikipedia](https://wikipedia.org/wiki/X.509). - -## Tarefa - -[Crie um novo dispositivo IoT](assignment.md) - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, é importante notar que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes da utilização desta tradução. \ No newline at end of file diff --git a/translations/pt/2-farm/lessons/6-keep-your-plant-secure/assignment.md b/translations/pt/2-farm/lessons/6-keep-your-plant-secure/assignment.md deleted file mode 100644 index 157063cc2..000000000 --- a/translations/pt/2-farm/lessons/6-keep-your-plant-secure/assignment.md +++ /dev/null @@ -1,27 +0,0 @@ - -# Construir um novo dispositivo IoT - -## Instruções - -Ao longo das últimas 6 lições, aprendeste sobre agricultura digital e como usar dispositivos IoT para recolher dados, prever o crescimento das plantas e automatizar a rega com base nas leituras de humidade do solo. - -Usa o que aprendeste para construir um novo dispositivo IoT utilizando um sensor e um atuador à tua escolha. Envia telemetria para um IoT Hub e utiliza isso para controlar um atuador através de código sem servidor. Podes usar um sensor e um atuador que já tenhas utilizado neste ou no projeto anterior, ou, se tiveres outro hardware, experimenta algo novo. - -## Critérios de Avaliação - -| Critério | Exemplar | Adequado | Necessita de Melhorias | -| -------- | --------- | -------- | ---------------------- | -| Programar um dispositivo IoT para usar um sensor e um atuador | Programou um dispositivo IoT que funciona com um sensor e um atuador | Programou um dispositivo IoT que funciona com um sensor ou um atuador | Não conseguiu programar um dispositivo IoT para usar um sensor ou um atuador | -| Conectar o dispositivo IoT ao IoT Hub | Conseguiu implementar um IoT Hub, enviar telemetria para ele e receber comandos dele | Conseguiu implementar um IoT Hub e enviar telemetria ou receber comandos | Não conseguiu implementar um IoT Hub nem comunicar com ele a partir de um dispositivo IoT | -| Controlar o atuador usando código sem servidor | Conseguiu implementar uma Azure Function para controlar o dispositivo acionada por eventos de telemetria | Conseguiu implementar uma Azure Function acionada por eventos de telemetria, mas não conseguiu controlar o atuador | Não conseguiu implementar uma Azure Function | - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, é importante notar que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes da utilização desta tradução. \ No newline at end of file diff --git a/translations/pt/2-farm/lessons/6-keep-your-plant-secure/single-board-computer-x509.md b/translations/pt/2-farm/lessons/6-keep-your-plant-secure/single-board-computer-x509.md deleted file mode 100644 index b1225993f..000000000 --- a/translations/pt/2-farm/lessons/6-keep-your-plant-secure/single-board-computer-x509.md +++ /dev/null @@ -1,69 +0,0 @@ - -# Utilize o certificado X.509 no código do seu dispositivo - Hardware IoT Virtual e Raspberry Pi - -Nesta parte da lição, irá conectar o seu dispositivo IoT virtual ou Raspberry Pi ao IoT Hub utilizando o certificado X.509. - -## Conectar o seu dispositivo ao IoT Hub - -O próximo passo é conectar o seu dispositivo ao IoT Hub utilizando os certificados X.509. - -### Tarefa - conectar ao IoT Hub - -1. Copie os ficheiros de chave e certificado para a pasta que contém o código do seu dispositivo IoT. Se estiver a usar um Raspberry Pi através do VS Code Remote SSH e criou as chaves no seu PC ou Mac, pode arrastar e largar os ficheiros no explorador do VS Code para os copiar. - -1. Abra o ficheiro `app.py`. - -1. Para conectar utilizando um certificado X.509, precisará do nome do host do IoT Hub e do certificado X.509. Comece por criar uma variável que contenha o nome do host, adicionando o seguinte código antes de criar o cliente do dispositivo: - - ```python - host_name = "" - ``` - - Substitua `` pelo nome do host do seu IoT Hub. Pode encontrar esta informação na secção `HostName` da `connection_string`. Será o nome do seu IoT Hub, terminando com `.azure-devices.net`. - -1. Abaixo disso, declare uma variável com o ID do dispositivo: - - ```python - device_id = "soil-moisture-sensor-x509" - ``` - -1. Precisará de uma instância da classe `X509` que contenha os ficheiros X.509. Adicione `X509` à lista de classes importadas do módulo `azure.iot.device`: - - ```python - from azure.iot.device import IoTHubDeviceClient, Message, MethodResponse, X509 - ``` - -1. Crie uma instância da classe `X509` utilizando os seus ficheiros de certificado e chave, adicionando este código abaixo da declaração de `host_name`: - - ```python - x509 = X509("./soil-moisture-sensor-x509-cert.pem", "./soil-moisture-sensor-x509-key.pem") - ``` - - Isto criará a classe `X509` utilizando os ficheiros `soil-moisture-sensor-x509-cert.pem` e `soil-moisture-sensor-x509-key.pem` criados anteriormente. - -1. Substitua a linha de código que cria o `device_client` a partir de uma connection string pela seguinte: - - ```python - device_client = IoTHubDeviceClient.create_from_x509_certificate(x509, host_name, device_id) - ``` - - Isto conectará utilizando o certificado X.509 em vez de uma connection string. - -1. Apague a linha com a variável `connection_string`. - -1. Execute o seu código. Monitorize as mensagens enviadas ao IoT Hub e envie pedidos de método direto como antes. Verá o dispositivo conectar-se e enviar leituras de humidade do solo, bem como receber pedidos de método direto. - -> 💁 Pode encontrar este código na pasta [code/pi](../../../../../2-farm/lessons/6-keep-your-plant-secure/code/pi) ou [code/virtual-device](../../../../../2-farm/lessons/6-keep-your-plant-secure/code/virtual-device). - -😀 O programa do seu sensor de humidade do solo está conectado ao seu IoT Hub utilizando um certificado X.509! - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, é importante notar que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes do uso desta tradução. \ No newline at end of file diff --git a/translations/pt/2-farm/lessons/6-keep-your-plant-secure/wio-terminal-x509.md b/translations/pt/2-farm/lessons/6-keep-your-plant-secure/wio-terminal-x509.md deleted file mode 100644 index aa4a1f2e3..000000000 --- a/translations/pt/2-farm/lessons/6-keep-your-plant-secure/wio-terminal-x509.md +++ /dev/null @@ -1,15 +0,0 @@ - -# Utilizar o certificado X.509 no código do seu dispositivo - Wio Terminal - -No momento da redação, o SDK do Azure para Arduino não suporta certificados X.509. Se quiser experimentar com certificados X.509, pode consultar as [instruções para dispositivos IoT virtuais utilizando o SDK Python](single-board-computer-x509.md) - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos pela precisão, esteja ciente de que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes do uso desta tradução. \ No newline at end of file diff --git a/translations/pt/3-transport/README.md b/translations/pt/3-transport/README.md deleted file mode 100644 index 58c643958..000000000 --- a/translations/pt/3-transport/README.md +++ /dev/null @@ -1,36 +0,0 @@ - -# Transporte da quinta para a fábrica - usando IoT para rastrear entregas de alimentos - -Muitos agricultores cultivam alimentos para vender - seja como agricultores comerciais que vendem tudo o que produzem, ou como agricultores de subsistência que vendem o excedente para comprar bens essenciais. De alguma forma, os alimentos têm de ser transportados da quinta para o consumidor, e isso geralmente depende de transporte em massa das quintas para centros ou fábricas de processamento, e depois para as lojas. Por exemplo, um agricultor de tomates colhe os tomates, embala-os em caixas, carrega as caixas num camião e entrega-os numa fábrica de processamento. Os tomates são então classificados e, a partir daí, entregues aos consumidores na forma de alimentos processados, vendas a retalho ou consumidos em restaurantes. - -A IoT pode ajudar nesta cadeia de abastecimento ao rastrear os alimentos em trânsito - garantindo que os motoristas seguem o percurso correto, monitorizando a localização dos veículos e recebendo alertas quando os veículos chegam, para que os alimentos possam ser descarregados e estejam prontos para processamento o mais rapidamente possível. - -> 🎓 Uma *cadeia de abastecimento* é a sequência de atividades para produzir e entregar algo. Por exemplo, na produção de tomates, inclui o fornecimento de sementes, solo, fertilizantes e água, o cultivo dos tomates, a entrega dos tomates a um centro central, o transporte para o centro local de um supermercado, o transporte para o supermercado individual, a exposição para venda, a compra pelo consumidor e o transporte para casa para consumo. Cada etapa é como os elos de uma cadeia. - -> 🎓 A parte de transporte da cadeia de abastecimento é conhecida como *logística*. - -Nestes 4 módulos, vais aprender como aplicar a Internet das Coisas para melhorar a cadeia de abastecimento, monitorizando os alimentos enquanto são carregados num camião (virtual), que será rastreado enquanto se desloca até ao destino. Vais aprender sobre rastreamento por GPS, como armazenar e visualizar dados de GPS, e como receber alertas quando um camião chega ao seu destino. - -> 💁 Estes módulos irão utilizar alguns recursos na nuvem. Se não completares todos os módulos deste projeto, certifica-te de que [limpas o teu projeto](../clean-up.md). - -## Tópicos - -1. [Rastreamento de localização](lessons/1-location-tracking/README.md) -1. [Armazenar dados de localização](lessons/2-store-location-data/README.md) -1. [Visualizar dados de localização](lessons/3-visualize-location-data/README.md) -1. [Geofences](lessons/4-geofences/README.md) - -## Créditos - -Todos os módulos foram escritos com ♥️ por [Jen Looper](https://github.com/jlooper) e [Jim Bennett](https://GitHub.com/JimBobBennett) - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, tenha em atenção que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes da utilização desta tradução. \ No newline at end of file diff --git a/translations/pt/3-transport/lessons/1-location-tracking/README.md b/translations/pt/3-transport/lessons/1-location-tracking/README.md deleted file mode 100644 index 88d78f8e4..000000000 --- a/translations/pt/3-transport/lessons/1-location-tracking/README.md +++ /dev/null @@ -1,214 +0,0 @@ - -# Localização de veículos - -![Uma visão geral ilustrada desta lição](../../../../../translated_images/pt-PT/lesson-11.9fddbac4b664c6d50ab7ac9bb32f1fc3f945f03760e72f7f43938073762fb017.jpg) - -> Ilustração por [Nitya Narasimhan](https://github.com/nitya). Clique na imagem para uma versão maior. - -## Questionário pré-aula - -[Questionário pré-aula](https://black-meadow-040d15503.1.azurestaticapps.net/quiz/21) - -## Introdução - -O processo principal para levar alimentos de um agricultor até um consumidor envolve carregar caixas de produtos em camiões, navios, aviões ou outros veículos de transporte comercial, e entregar os alimentos em algum lugar - seja diretamente a um cliente, ou a um centro de distribuição ou armazém para processamento. Todo o processo de ponta a ponta, desde a fazenda até o consumidor, faz parte de um processo chamado *cadeia de abastecimento*. O vídeo abaixo, da W. P. Carey School of Business da Universidade Estadual do Arizona, explica o conceito de cadeia de abastecimento e como ela é gerida em mais detalhe. - -[![O que é Gestão da Cadeia de Abastecimento? Um vídeo da W. P. Carey School of Business da Universidade Estadual do Arizona](https://img.youtube.com/vi/Mi1QBxVjZAw/0.jpg)](https://www.youtube.com/watch?v=Mi1QBxVjZAw) - -> 🎥 Clique na imagem acima para assistir ao vídeo - -A adição de dispositivos IoT pode melhorar drasticamente a sua cadeia de abastecimento, permitindo gerir onde os itens estão, planear melhor o transporte e o manuseamento de mercadorias, e responder mais rapidamente a problemas. - -Ao gerir uma frota de veículos, como camiões, é útil saber onde cada veículo está em determinado momento. Os veículos podem ser equipados com sensores GPS que enviam a sua localização para sistemas IoT, permitindo aos proprietários localizar os veículos, ver o percurso realizado e saber quando chegarão ao destino. A maioria dos veículos opera fora da cobertura Wi-Fi, por isso utilizam redes móveis para enviar este tipo de dados. Por vezes, o sensor GPS está integrado em dispositivos IoT mais complexos, como livros de registo eletrónicos. Estes dispositivos monitorizam quanto tempo um camião esteve em trânsito para garantir que os condutores cumprem as leis locais sobre horas de trabalho. - -Nesta lição, aprenderá como rastrear a localização de um veículo utilizando um sensor de Sistema de Posicionamento Global (GPS). - -Nesta lição, abordaremos: - -* [Veículos conectados](../../../../../3-transport/lessons/1-location-tracking) -* [Coordenadas geoespaciais](../../../../../3-transport/lessons/1-location-tracking) -* [Sistemas de Posicionamento Global (GPS)](../../../../../3-transport/lessons/1-location-tracking) -* [Ler dados de sensores GPS](../../../../../3-transport/lessons/1-location-tracking) -* [Dados GPS NMEA](../../../../../3-transport/lessons/1-location-tracking) -* [Decodificar dados de sensores GPS](../../../../../3-transport/lessons/1-location-tracking) - -## Veículos conectados - -A IoT está a transformar a forma como as mercadorias são transportadas, criando frotas de *veículos conectados*. Estes veículos estão ligados a sistemas de TI centrais, reportando informações sobre a sua localização e outros dados de sensores. Ter uma frota de veículos conectados oferece uma ampla gama de benefícios: - -* Rastreio de localização - pode localizar um veículo a qualquer momento, permitindo: - - * Receber alertas quando um veículo está prestes a chegar ao destino, para preparar a equipa para o descarregamento - * Localizar veículos roubados - * Combinar dados de localização e rota com problemas de trânsito para redirecionar veículos durante a viagem - * Cumprir obrigações fiscais. Alguns países cobram taxas aos veículos com base na quilometragem percorrida em estradas públicas (como o [RUC da Nova Zelândia](https://www.nzta.govt.nz/vehicles/licensing-rego/road-user-charges/)), por isso, saber quando um veículo está em estradas públicas versus privadas facilita o cálculo dos impostos devidos. - * Saber onde enviar equipas de manutenção em caso de avaria - -* Telemetria do condutor - garantir que os condutores respeitam os limites de velocidade, fazem curvas a velocidades adequadas, travam de forma eficiente e conduzem com segurança. Veículos conectados também podem ter câmaras para gravar incidentes. Isto pode ser associado a seguros, oferecendo tarifas reduzidas para bons condutores. - -* Conformidade com horas de condução - garantir que os condutores conduzem apenas durante as horas legalmente permitidas, com base nos horários em que ligam e desligam o motor. - -Estes benefícios podem ser combinados - por exemplo, combinar a conformidade com horas de condução com o rastreio de localização para redirecionar condutores caso não consigam chegar ao destino dentro das horas permitidas. Também podem ser combinados com outras telemetrias específicas do veículo, como dados de temperatura de camiões com controlo de temperatura, permitindo redirecionar veículos se a rota atual comprometer a manutenção da temperatura das mercadorias. - -> 🎓 Logística é o processo de transporte de mercadorias de um local para outro, como de uma fazenda para um supermercado, passando por um ou mais armazéns. Um agricultor embala caixas de tomates que são carregadas num camião, entregues a um armazém central e colocadas num segundo camião que pode conter uma mistura de diferentes tipos de produtos, que são então entregues a um supermercado. - -O componente principal do rastreio de veículos é o GPS - sensores que podem localizar a sua posição em qualquer lugar da Terra. Nesta lição, aprenderá a usar um sensor GPS, começando por aprender como definir uma localização na Terra. - -## Coordenadas geoespaciais - -As coordenadas geoespaciais são usadas para definir pontos na superfície da Terra, de forma semelhante a como as coordenadas podem ser usadas para desenhar um pixel num ecrã de computador ou posicionar pontos num bordado. Para um único ponto, tem-se um par de coordenadas. Por exemplo, o Campus da Microsoft em Redmond, Washington, EUA, está localizado em 47.6423109, -122.1390293. - -### Latitude e longitude - -A Terra é uma esfera - um círculo tridimensional. Por isso, os pontos são definidos dividindo-a em 360 graus, o mesmo que a geometria dos círculos. A latitude mede o número de graus de norte a sul, e a longitude mede o número de graus de leste a oeste. - -> 💁 Ninguém sabe ao certo a razão original para os círculos serem divididos em 360 graus. A [página sobre graus (ângulo) na Wikipédia](https://wikipedia.org/wiki/Degree_(angle)) aborda algumas das possíveis razões. - -![Linhas de latitude de 90° no Polo Norte, 45° a meio caminho entre o Polo Norte e o equador, 0° no equador, -45° a meio caminho entre o equador e o Polo Sul, e -90° no Polo Sul](../../../../../translated_images/pt-PT/latitude-lines.11d8d91dfb2014a57437272d7db7fd6607243098e8685f06e0c5f1ec984cb7eb.png) - -A latitude é medida usando linhas que circundam a Terra e correm paralelas ao equador, dividindo os hemisférios Norte e Sul em 90° cada. O equador está a 0°, o Polo Norte está a 90°, também conhecido como 90° Norte, e o Polo Sul está a -90°, ou 90° Sul. - -A longitude é medida como o número de graus a leste e oeste. A origem de 0° da longitude é chamada de *Meridiano Principal* e foi definida em 1884 como uma linha do Polo Norte ao Polo Sul que passa pelo [Observatório Real Britânico em Greenwich, Inglaterra](https://wikipedia.org/wiki/Royal_Observatory,_Greenwich). - -![Linhas de longitude que vão de -180° a oeste do Meridiano Principal, até 0° no Meridiano Principal, até 180° a leste do Meridiano Principal](../../../../../translated_images/pt-PT/longitude-meridians.ab4ef1c91c064586b0185a3c8d39e585903696c6a7d28c098a93a629cddb5d20.png) - -> 🎓 Um meridiano é uma linha imaginária reta que vai do Polo Norte ao Polo Sul, formando um semicírculo. - -Para medir a longitude de um ponto, mede-se o número de graus ao longo do equador, desde o Meridiano Principal até um meridiano que passa por esse ponto. A longitude varia de -180°, ou 180° Oeste, passando por 0° no Meridiano Principal, até 180°, ou 180° Este. 180° e -180° referem-se ao mesmo ponto, o antimeridiano ou 180º meridiano. Este é um meridiano no lado oposto da Terra em relação ao Meridiano Principal. - -> 💁 O antimeridiano não deve ser confundido com a Linha Internacional de Data, que está aproximadamente na mesma posição, mas não é uma linha reta e varia para se ajustar às fronteiras geopolíticas. - -✅ Faça uma pesquisa: Tente encontrar a latitude e longitude da sua localização atual. - -### Graus, minutos e segundos vs graus decimais - -Tradicionalmente, as medições de graus de latitude e longitude eram feitas usando numeração sexagesimal, ou base-60, um sistema de numeração usado pelos antigos babilónios, que fizeram as primeiras medições e registos de tempo e distância. Provavelmente usa o sistema sexagesimal todos os dias sem perceber - dividindo horas em 60 minutos e minutos em 60 segundos. - -A longitude e a latitude são medidas em graus, minutos e segundos, com um minuto sendo 1/60 de um grau, e 1 segundo sendo 1/60 de um minuto. - -Por exemplo, no equador: - -* 1° de latitude é **111,3 quilómetros** -* 1 minuto de latitude é 111,3/60 = **1,855 quilómetros** -* 1 segundo de latitude é 1,855/60 = **0,031 quilómetros** - -O símbolo para um minuto é uma aspa simples, para um segundo é uma aspa dupla. Por exemplo, 2 graus, 17 minutos e 43 segundos seriam escritos como 2°17'43". Partes de segundos são dadas como decimais, por exemplo, meio segundo é 0°0'0,5". - -Os computadores não trabalham em base-60, por isso estas coordenadas são dadas como graus decimais ao usar dados GPS na maioria dos sistemas informáticos. Por exemplo, 2°17'43" é 2,295277. O símbolo de grau geralmente é omitido. - -As coordenadas de um ponto são sempre dadas como `latitude, longitude`, então o exemplo anterior do Campus da Microsoft em 47.6423109,-122.117198 tem: - -* Uma latitude de 47.6423109 (47.6423109 graus ao norte do equador) -* Uma longitude de -122.1390293 (122.1390293 graus a oeste do Meridiano Principal). - -![O Campus da Microsoft em 47.6423109,-122.117198](../../../../../translated_images/pt-PT/microsoft-gps-location-world.a321d481b010f6adfcca139b2ba0adc53b79f58a540495b8e2ce7f779ea64bfe.png) - -## Sistemas de Posicionamento Global (GPS) - -Os sistemas GPS utilizam múltiplos satélites em órbita da Terra para localizar a sua posição. Provavelmente já utilizou sistemas GPS sem sequer perceber - para encontrar a sua localização numa aplicação de mapas no telemóvel, como Apple Maps ou Google Maps, para ver onde está o seu transporte numa aplicação como Uber ou Bolt, ou ao usar navegação por satélite (sat-nav) no carro. - -> 🎓 Os satélites na 'navegação por satélite' são satélites GPS! - -Os sistemas GPS funcionam com vários satélites que enviam um sinal com a posição atual de cada satélite e um carimbo de tempo preciso. Estes sinais são enviados por ondas de rádio e detetados por uma antena no sensor GPS. Um sensor GPS deteta estes sinais e, utilizando o tempo atual, mede quanto tempo o sinal demorou a chegar ao sensor a partir do satélite. Como a velocidade das ondas de rádio é constante, o sensor GPS pode usar o carimbo de tempo enviado para calcular a distância entre o sensor e o satélite. Combinando os dados de pelo menos 3 satélites com as posições enviadas, o sensor GPS consegue determinar a sua localização na Terra. - -> 💁 Os sensores GPS precisam de antenas para detetar ondas de rádio. As antenas integradas em camiões e carros com GPS incorporado são posicionadas para obter um bom sinal, geralmente no para-brisas ou no teto. Se estiver a usar um sistema GPS separado, como um smartphone ou um dispositivo IoT, deve garantir que a antena integrada no sistema GPS ou telemóvel tem uma visão desobstruída do céu, como estar montada no para-brisas. - -![Sabendo a distância do sensor a vários satélites, a localização pode ser calculada](../../../../../translated_images/pt-PT/gps-satellites.04acf1148fe25fbf1586bc2e8ba698e8d79b79a50c36824b38417dd13372b90f.png) - -Os satélites GPS estão a orbitar a Terra, não num ponto fixo acima do sensor, por isso os dados de localização incluem altitude acima do nível do mar, bem como latitude e longitude. - -O GPS costumava ter limitações de precisão impostas pelos militares dos EUA, limitando a precisão a cerca de 5 metros. Esta limitação foi removida em 2000, permitindo uma precisão de 30 centímetros. No entanto, alcançar esta precisão nem sempre é possível devido a interferências nos sinais. - -✅ Se tiver um smartphone, abra a aplicação de mapas e veja quão precisa é a sua localização. Pode demorar um pouco para o telemóvel detetar vários satélites e obter uma localização mais precisa. -💁 Os satélites possuem relógios atómicos extremamente precisos, mas sofrem um desvio de 38 microssegundos (0,0000038 segundos) por dia em comparação com os relógios atómicos na Terra, devido à desaceleração do tempo à medida que a velocidade aumenta, conforme previsto pelas teorias da relatividade especial e geral de Einstein - os satélites deslocam-se mais rapidamente do que a rotação da Terra. Este desvio foi utilizado para comprovar as previsões da relatividade especial e geral e precisa de ser ajustado no design dos sistemas GPS. Literalmente, o tempo passa mais devagar num satélite GPS. -Os sistemas GPS foram desenvolvidos e implementados por vários países e uniões políticas, incluindo os EUA, Rússia, Japão, Índia, UE e China. Os sensores GPS modernos podem conectar-se à maioria destes sistemas para obter localizações mais rápidas e precisas. - -> 🎓 Os grupos de satélites em cada implementação são chamados de constelações. - -## Ler dados do sensor GPS - -A maioria dos sensores GPS envia dados GPS através de UART. - -> ⚠️ UART foi abordado no [projeto 2, lição 2](../../../2-farm/lessons/2-detect-soil-moisture/README.md#universal-asynchronous-receiver-transmitter-uart). Consulte essa lição novamente, se necessário. - -Pode utilizar um sensor GPS no seu dispositivo IoT para obter dados GPS. - -### Tarefa - conectar um sensor GPS e ler dados GPS - -Siga o guia relevante para ler dados GPS usando o seu dispositivo IoT: - -* [Arduino - Wio Terminal](wio-terminal-gps-sensor.md) -* [Computador de placa única - Raspberry Pi](pi-gps-sensor.md) -* [Computador de placa única - Dispositivo virtual](virtual-device-gps-sensor.md) - -## Dados GPS NMEA - -Quando executou o seu código, pode ter visto algo que parece ser um conjunto de caracteres sem sentido na saída. Na verdade, trata-se de dados GPS padrão, e tudo tem um significado. - -Os sensores GPS produzem dados usando mensagens NMEA, de acordo com o padrão NMEA 0183. NMEA é um acrónimo para a [National Marine Electronics Association](https://www.nmea.org), uma organização comercial sediada nos EUA que define padrões para comunicação entre dispositivos eletrónicos marítimos. - -> 💁 Este padrão é proprietário e custa pelo menos 2.000 USD, mas há informações suficientes no domínio público para que a maior parte do padrão tenha sido revertida e possa ser usada em código open source e outros projetos não comerciais. - -Estas mensagens são baseadas em texto. Cada mensagem consiste numa *frase* que começa com o caractere `$`, seguido por 2 caracteres que indicam a origem da mensagem (por exemplo, GP para o sistema GPS dos EUA, GN para o GLONASS, o sistema GPS russo) e 3 caracteres que indicam o tipo de mensagem. O restante da mensagem é composto por campos separados por vírgulas, terminando com um caractere de nova linha. - -Alguns dos tipos de mensagens que podem ser recebidas são: - -| Tipo | Descrição | -| ---- | --------- | -| GGA | Dados de Fixação GPS, incluindo a latitude, longitude e altitude do sensor GPS, juntamente com o número de satélites visíveis para calcular esta fixação. | -| ZDA | A data e hora atuais, incluindo o fuso horário local. | -| GSV | Detalhes dos satélites visíveis - definidos como os satélites dos quais o sensor GPS consegue detetar sinais. | - -> 💁 Os dados GPS incluem carimbos de data e hora, permitindo que o seu dispositivo IoT obtenha a hora, se necessário, a partir de um sensor GPS, em vez de depender de um servidor NTP ou de um relógio interno em tempo real. - -A mensagem GGA inclui a localização atual no formato `(dd)dmm.mmmm`, juntamente com um único caractere para indicar a direção. O `d` no formato representa graus, o `m` representa minutos, com os segundos como decimais dos minutos. Por exemplo, 2°17'43" seria 217.716666667 - 2 graus, 17.716666667 minutos. - -O caractere de direção pode ser `N` ou `S` para latitude, indicando norte ou sul, e `E` ou `W` para longitude, indicando este ou oeste. Por exemplo, uma latitude de 2°17'43" teria um caractere de direção `N`, enquanto -2°17'43" teria um caractere de direção `S`. - -Por exemplo - a frase NMEA `$GNGGA,020604.001,4738.538654,N,12208.341758,W,1,3,,164.7,M,-17.1,M,,*67` - -* A parte da latitude é `4738.538654,N`, que se converte para 47.6423109 em graus decimais. `4738.538654` é 47.6423109, e a direção é `N` (norte), portanto, é uma latitude positiva. - -* A parte da longitude é `12208.341758,W`, que se converte para -122.1390293 em graus decimais. `12208.341758` é 122.1390293°, e a direção é `W` (oeste), portanto, é uma longitude negativa. - -## Decodificar dados do sensor GPS - -Em vez de usar os dados NMEA brutos, é melhor decodificá-los para um formato mais útil. Existem várias bibliotecas open source que pode usar para ajudar a extrair dados úteis das mensagens NMEA brutas. - -### Tarefa - decodificar dados do sensor GPS - -Siga o guia relevante para decodificar dados do sensor GPS usando o seu dispositivo IoT: - -* [Arduino - Wio Terminal](wio-terminal-gps-decode.md) -* [Computador de placa única - Raspberry Pi/Dispositivo IoT virtual](single-board-computer-gps-decode.md) - ---- - -## 🚀 Desafio - -Escreva o seu próprio decodificador NMEA! Em vez de depender de bibliotecas de terceiros para decodificar frases NMEA, consegue escrever o seu próprio decodificador para extrair latitude e longitude das frases NMEA? - -## Questionário pós-aula - -[Questionário pós-aula](https://black-meadow-040d15503.1.azurestaticapps.net/quiz/22) - -## Revisão e Autoestudo - -* Leia mais sobre Coordenadas Geoespaciais na [página do sistema de coordenadas geográficas na Wikipedia](https://wikipedia.org/wiki/Geographic_coordinate_system). -* Leia sobre os Meridianos de Referência em outros corpos celestes além da Terra na [página do Meridiano de Referência na Wikipedia](https://wikipedia.org/wiki/Prime_meridian#Prime_meridian_on_other_planetary_bodies). -* Pesquise os vários sistemas GPS diferentes de vários governos e uniões políticas mundiais, como a UE, Japão, Rússia, Índia e EUA. - -## Tarefa - -[Investigar outros dados GPS](assignment.md) - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, esteja ciente de que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se uma tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes do uso desta tradução. \ No newline at end of file diff --git a/translations/pt/3-transport/lessons/1-location-tracking/assignment.md b/translations/pt/3-transport/lessons/1-location-tracking/assignment.md deleted file mode 100644 index a76cc56ce..000000000 --- a/translations/pt/3-transport/lessons/1-location-tracking/assignment.md +++ /dev/null @@ -1,27 +0,0 @@ - -# Investigar outros dados GPS - -## Instruções - -As frases NMEA provenientes do seu sensor GPS contêm outros dados além da localização. Investigue esses dados adicionais e utilize-os no seu dispositivo IoT. - -Por exemplo - consegue obter a data e hora atuais? Se estiver a usar um microcontrolador, consegue ajustar o relógio utilizando os dados GPS da mesma forma que o fez com os sinais NTP no projeto anterior? Consegue obter a elevação (a sua altura acima do nível do mar) ou a sua velocidade atual? - -Se estiver a usar um dispositivo IoT virtual, pode obter alguns desses dados enviando frases NMEA geradas com ferramentas como [nmeagen.org](https://www.nmeagen.org). - -## Rubrica - -| Critério | Exemplar | Adequado | Necessita de Melhorias | -| -------- | --------- | -------- | ---------------------- | -| Obter mais dados GPS | Consegue obter e utilizar mais dados GPS, seja como telemetria ou para configurar o dispositivo IoT | Consegue obter mais dados GPS, mas não consegue utilizá-los | Não consegue obter mais dados GPS | - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, é importante notar que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes do uso desta tradução. \ No newline at end of file diff --git a/translations/pt/3-transport/lessons/1-location-tracking/pi-gps-sensor.md b/translations/pt/3-transport/lessons/1-location-tracking/pi-gps-sensor.md deleted file mode 100644 index 3d3999a03..000000000 --- a/translations/pt/3-transport/lessons/1-location-tracking/pi-gps-sensor.md +++ /dev/null @@ -1,191 +0,0 @@ - -# Ler dados de GPS - Raspberry Pi - -Nesta parte da lição, vais adicionar um sensor GPS ao teu Raspberry Pi e ler os valores obtidos. - -## Hardware - -O Raspberry Pi necessita de um sensor GPS. - -O sensor que vais utilizar é o [sensor Grove GPS Air530](https://www.seeedstudio.com/Grove-GPS-Air530-p-4584.html). Este sensor pode conectar-se a múltiplos sistemas GPS para obter uma localização rápida e precisa. O sensor é composto por 2 partes - a eletrónica principal do sensor e uma antena externa conectada por um fio fino para captar as ondas de rádio dos satélites. - -Este é um sensor UART, o que significa que envia dados GPS através de UART. - -## Conectar o sensor GPS - -O sensor Grove GPS pode ser conectado ao Raspberry Pi. - -### Tarefa - conectar o sensor GPS - -Conecta o sensor GPS. - -![Um sensor Grove GPS](../../../../../translated_images/pt-PT/grove-gps-sensor.247943bf69b03f0d1820ef6ed10c587f9b650e8db55b936851c92412180bd3e2.png) - -1. Insere uma extremidade de um cabo Grove na entrada do sensor GPS. O cabo só encaixa de uma forma. - -1. Com o Raspberry Pi desligado, conecta a outra extremidade do cabo Grove à entrada UART marcada como **UART** no Grove Base Hat ligado ao Pi. Esta entrada está na fila do meio, no lado mais próximo da ranhura do cartão SD, oposto às portas USB e à entrada Ethernet. - - ![O sensor Grove GPS conectado à entrada UART](../../../../../translated_images/pt-PT/pi-gps-sensor.1f99ee2b2f6528915047ec78967bd362e0e4ee0ed594368a3837b9cf9cdaca64.png) - -1. Posiciona o sensor GPS de forma que a antena conectada tenha visibilidade para o céu - idealmente junto a uma janela aberta ou no exterior. É mais fácil obter um sinal claro sem obstruções à antena. - -## Programar o sensor GPS - -Agora podes programar o Raspberry Pi para utilizar o sensor GPS conectado. - -### Tarefa - programar o sensor GPS - -Programa o dispositivo. - -1. Liga o Pi e espera que ele inicie. - -1. O sensor GPS tem 2 LEDs - um LED azul que pisca quando os dados são transmitidos e um LED verde que pisca a cada segundo ao receber dados dos satélites. Certifica-te de que o LED azul está a piscar quando ligas o Pi. Após alguns minutos, o LED verde começará a piscar - se não, pode ser necessário reposicionar a antena. - -1. Abre o VS Code, diretamente no Pi ou conectando-te através da extensão Remote SSH. - - > ⚠️ Podes consultar [as instruções para configurar e abrir o VS Code na lição 1, se necessário](../../../1-getting-started/lessons/1-introduction-to-iot/pi.md). - -1. Com versões mais recentes do Raspberry Pi que suportam Bluetooth, existe um conflito entre a porta serial usada para Bluetooth e a usada pela porta UART do Grove. Para resolver isto, faz o seguinte: - - 1. No terminal do VS Code, edita o ficheiro `/boot/config.txt` usando o `nano`, um editor de texto integrado no terminal, com o seguinte comando: - - ```sh - sudo nano /boot/config.txt - ``` - - > Este ficheiro não pode ser editado diretamente no VS Code, pois precisas de permissões elevadas (`sudo`). O VS Code não executa estas permissões. - - 1. Usa as teclas de seta para navegar até ao final do ficheiro. Copia o código abaixo e cola-o no final do ficheiro: - - ```ini - dtoverlay=pi3-miniuart-bt - dtoverlay=pi3-disable-bt - enable_uart=1 - ``` - - Podes colar utilizando os atalhos normais do teu dispositivo (`Ctrl+v` no Windows, Linux ou Raspberry Pi OS, `Cmd+v` no macOS). - - 1. Guarda o ficheiro e sai do `nano` pressionando `Ctrl+x`. Pressiona `y` quando te for perguntado se queres guardar as alterações e, em seguida, `enter` para confirmar que queres sobrescrever o ficheiro `/boot/config.txt`. - - > Se cometeres um erro, podes sair sem guardar e repetir os passos. - - 1. Edita o ficheiro `/boot/cmdline.txt` no `nano` com o seguinte comando: - - ```sh - sudo nano /boot/cmdline.txt - ``` - - 1. Este ficheiro contém vários pares de chave/valor separados por espaços. Remove quaisquer pares de chave/valor com a chave `console`. Provavelmente terão este aspeto: - - ```output - console=serial0,115200 console=tty1 - ``` - - Podes navegar até estas entradas usando as teclas de seta e apagá-las com as teclas `del` ou `backspace`. - - Por exemplo, se o teu ficheiro original for assim: - - ```output - console=serial0,115200 console=tty1 root=PARTUUID=058e2867-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait - ``` - - A nova versão será: - - ```output - root=PARTUUID=058e2867-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait - ``` - - 1. Segue os passos acima para guardar este ficheiro e sair do `nano`. - - 1. Reinicia o teu Pi e volta a conectar-te no VS Code após o reinício. - -1. No terminal, cria uma nova pasta no diretório home do utilizador `pi` chamada `gps-sensor`. Cria um ficheiro nesta pasta chamado `app.py`. - -1. Abre esta pasta no VS Code. - -1. O módulo GPS envia dados UART através de uma porta serial. Instala o pacote `pyserial` do Pip para comunicar com a porta serial no teu código Python: - - ```sh - pip3 install pyserial - ``` - -1. Adiciona o seguinte código ao teu ficheiro `app.py`: - - ```python - import time - import serial - - serial = serial.Serial('/dev/ttyAMA0', 9600, timeout=1) - serial.reset_input_buffer() - serial.flush() - - def print_gps_data(line): - print(line.rstrip()) - - while True: - line = serial.readline().decode('utf-8') - - while len(line) > 0: - print_gps_data(line) - line = serial.readline().decode('utf-8') - - time.sleep(1) - ``` - - Este código importa o módulo `serial` do pacote `pyserial`. Em seguida, conecta-se à porta serial `/dev/ttyAMA0` - este é o endereço da porta serial que o Grove Pi Base Hat utiliza para a sua porta UART. Depois, limpa quaisquer dados existentes desta conexão serial. - - A seguir, é definida uma função chamada `print_gps_data` que imprime no terminal a linha passada para ela. - - O código entra então num loop infinito, lendo o máximo de linhas de texto possível da porta serial em cada iteração. Chama a função `print_gps_data` para cada linha. - - Após ler todos os dados, o loop faz uma pausa de 1 segundo e tenta novamente. - -1. Executa este código. Verás a saída bruta do sensor GPS, algo como o seguinte: - - ```output - $GNGGA,020604.001,4738.538654,N,12208.341758,W,1,3,,164.7,M,-17.1,M,,*67 - $GPGSA,A,1,,,,,,,,,,,,,,,*1E - $BDGSA,A,1,,,,,,,,,,,,,,,*0F - $GPGSV,1,1,00*79 - $BDGSV,1,1,00*68 - ``` - - > Se obtiveres um dos seguintes erros ao parar e reiniciar o código, adiciona um bloco `try - except` ao teu loop `while`. - - ```output - UnicodeDecodeError: 'utf-8' codec can't decode byte 0x93 in position 0: invalid start byte - UnicodeDecodeError: 'utf-8' codec can't decode byte 0xf1 in position 0: invalid continuation byte - ``` - - ```python - while True: - try: - line = serial.readline().decode('utf-8') - - while len(line) > 0: - print_gps_data() - line = serial.readline().decode('utf-8') - - # There's a random chance the first byte being read is part way through a character. - # Read another full line and continue. - - except UnicodeDecodeError: - line = serial.readline().decode('utf-8') - - time.sleep(1) - ``` - -> 💁 Podes encontrar este código na pasta [code-gps/pi](../../../../../3-transport/lessons/1-location-tracking/code-gps/pi). - -😀 O teu programa para o sensor GPS foi um sucesso! - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos pela precisão, esteja ciente de que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes do uso desta tradução. \ No newline at end of file diff --git a/translations/pt/3-transport/lessons/1-location-tracking/single-board-computer-gps-decode.md b/translations/pt/3-transport/lessons/1-location-tracking/single-board-computer-gps-decode.md deleted file mode 100644 index ba2d91c09..000000000 --- a/translations/pt/3-transport/lessons/1-location-tracking/single-board-computer-gps-decode.md +++ /dev/null @@ -1,73 +0,0 @@ - -# Decodificar dados GPS - Hardware IoT Virtual e Raspberry Pi - -Nesta parte da lição, vais decodificar as mensagens NMEA lidas do sensor GPS pelo Raspberry Pi ou Dispositivo IoT Virtual e extrair a latitude e a longitude. - -## Decodificar dados GPS - -Depois de os dados NMEA brutos serem lidos da porta serial, podem ser decodificados utilizando uma biblioteca NMEA de código aberto. - -### Tarefa - decodificar dados GPS - -Programa o dispositivo para decodificar os dados GPS. - -1. Abre o projeto da aplicação `gps-sensor` se ainda não estiver aberto. - -1. Instala o pacote Pip `pynmea2`. Este pacote contém código para decodificar mensagens NMEA. - - ```sh - pip3 install pynmea2 - ``` - -1. Adiciona o seguinte código às importações no ficheiro `app.py` para importar o módulo `pynmea2`: - - ```python - import pynmea2 - ``` - -1. Substitui o conteúdo da função `print_gps_data` pelo seguinte: - - ```python - msg = pynmea2.parse(line) - if msg.sentence_type == 'GGA': - lat = pynmea2.dm_to_sd(msg.lat) - lon = pynmea2.dm_to_sd(msg.lon) - - if msg.lat_dir == 'S': - lat = lat * -1 - - if msg.lon_dir == 'W': - lon = lon * -1 - - print(f'{lat},{lon} - from {msg.num_sats} satellites') - ``` - - Este código utiliza a biblioteca `pynmea2` para analisar a linha lida da porta serial UART. - - Se o tipo de sentença da mensagem for `GGA`, então trata-se de uma mensagem de fixação de posição e será processada. Os valores de latitude e longitude são lidos da mensagem e convertidos para graus decimais a partir do formato NMEA `(d)ddmm.mmmm`. A função `dm_to_sd` realiza esta conversão. - - Em seguida, verifica-se a direção da latitude, e se a latitude for sul, o valor é convertido para um número negativo. O mesmo acontece com a longitude: se for oeste, é convertida para um número negativo. - - Por fim, as coordenadas são impressas na consola, juntamente com o número de satélites utilizados para obter a localização. - -1. Executa o código. Se estiveres a usar um dispositivo IoT virtual, certifica-te de que a aplicação CounterFit está em execução e os dados GPS estão a ser enviados. - - ```output - pi@raspberrypi:~/gps-sensor $ python3 app.py - 47.6423109,-122.1390293 - from 3 satellites - ``` - -> 💁 Podes encontrar este código na pasta [code-gps-decode/virtual-device](../../../../../3-transport/lessons/1-location-tracking/code-gps-decode/virtual-device) ou na pasta [code-gps-decode/pi](../../../../../3-transport/lessons/1-location-tracking/code-gps-decode/pi). - -😀 O teu programa do sensor GPS com decodificação de dados foi um sucesso! - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos pela precisão, esteja ciente de que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes do uso desta tradução. \ No newline at end of file diff --git a/translations/pt/3-transport/lessons/1-location-tracking/virtual-device-gps-sensor.md b/translations/pt/3-transport/lessons/1-location-tracking/virtual-device-gps-sensor.md deleted file mode 100644 index c069720e2..000000000 --- a/translations/pt/3-transport/lessons/1-location-tracking/virtual-device-gps-sensor.md +++ /dev/null @@ -1,142 +0,0 @@ - -# Ler dados de GPS - Hardware Virtual IoT - -Nesta parte da lição, irá adicionar um sensor GPS ao seu dispositivo IoT virtual e ler os valores dele. - -## Hardware Virtual - -O dispositivo IoT virtual usará um sensor GPS simulado que é acessível via UART através de uma porta serial. - -Um sensor GPS físico terá uma antena para captar ondas de rádio dos satélites GPS e converter os sinais GPS em dados GPS. A versão virtual simula isso, permitindo que defina uma latitude e longitude, envie frases NMEA brutas ou carregue um ficheiro GPX com várias localizações que podem ser retornadas sequencialmente. - -> 🎓 As frases NMEA serão abordadas mais tarde nesta lição. - -### Adicionar o sensor ao CounterFit - -Para usar um sensor GPS virtual, precisa de adicionar um à aplicação CounterFit. - -#### Tarefa - adicionar o sensor ao CounterFit - -Adicione o sensor GPS à aplicação CounterFit. - -1. Crie uma nova aplicação Python no seu computador numa pasta chamada `gps-sensor` com um único ficheiro chamado `app.py` e um ambiente virtual Python, e adicione os pacotes pip do CounterFit. - - > ⚠️ Pode consultar [as instruções para criar e configurar um projeto Python do CounterFit na lição 1, se necessário](../../../1-getting-started/lessons/1-introduction-to-iot/virtual-device.md). - -1. Instale um pacote Pip adicional para instalar um shim do CounterFit que pode comunicar com sensores baseados em UART através de uma ligação serial. Certifique-se de que está a instalar isto a partir de um terminal com o ambiente virtual ativado. - - ```sh - pip install counterfit-shims-serial - ``` - -1. Certifique-se de que a aplicação web do CounterFit está em execução. - -1. Crie um sensor GPS: - - 1. Na caixa *Create sensor* no painel *Sensors*, abra o menu suspenso *Sensor type* e selecione *UART GPS*. - - 1. Deixe a *Port* definida como */dev/ttyAMA0*. - - 1. Selecione o botão **Add** para criar o sensor GPS na porta `/dev/ttyAMA0`. - - ![As definições do sensor GPS](../../../../../translated_images/pt-PT/counterfit-create-gps-sensor.6385dc9357d85ad1d47b4abb2525e7651fd498917d25eefc5a72feab09eedc70.png) - - O sensor GPS será criado e aparecerá na lista de sensores. - - ![O sensor GPS criado](../../../../../translated_images/pt-PT/counterfit-gps-sensor.3fbb15af0a5367566f2f11324ef5a6f30861cdf2b497071a5e002b7aa473550e.png) - -## Programar o sensor GPS - -O dispositivo IoT virtual pode agora ser programado para usar o sensor GPS virtual. - -### Tarefa - programar o sensor GPS - -Programe a aplicação do sensor GPS. - -1. Certifique-se de que a aplicação `gps-sensor` está aberta no VS Code. - -1. Abra o ficheiro `app.py`. - -1. Adicione o seguinte código no início do `app.py` para ligar a aplicação ao CounterFit: - - ```python - from counterfit_connection import CounterFitConnection - CounterFitConnection.init('127.0.0.1', 5000) - ``` - -1. Adicione o seguinte código abaixo deste para importar algumas bibliotecas necessárias, incluindo a biblioteca para a porta serial do CounterFit: - - ```python - import time - import counterfit_shims_serial - - serial = counterfit_shims_serial.Serial('/dev/ttyAMA0') - ``` - - Este código importa o módulo `serial` do pacote Pip `counterfit_shims_serial`. Em seguida, liga-se à porta serial `/dev/ttyAMA0` - este é o endereço da porta serial que o sensor GPS virtual usa para a sua porta UART. - -1. Adicione o seguinte código abaixo deste para ler da porta serial e imprimir os valores no terminal: - - ```python - def print_gps_data(line): - print(line.rstrip()) - - while True: - line = serial.readline().decode('utf-8') - - while len(line) > 0: - print_gps_data(line) - line = serial.readline().decode('utf-8') - - time.sleep(1) - ``` - - É definida uma função chamada `print_gps_data` que imprime no terminal a linha passada para ela. - - Em seguida, o código entra num loop infinito, lendo o máximo de linhas de texto possível da porta serial em cada iteração. Chama a função `print_gps_data` para cada linha. - - Depois de todos os dados serem lidos, o loop faz uma pausa de 1 segundo e tenta novamente. - -1. Execute este código, garantindo que está a usar um terminal diferente daquele em que a aplicação CounterFit está a ser executada, para que a aplicação CounterFit continue em funcionamento. - -1. Na aplicação CounterFit, altere o valor do sensor GPS. Pode fazer isso de uma das seguintes formas: - - * Defina a **Source** como `Lat/Lon` e configure uma latitude, longitude e número de satélites usados para obter a fixação GPS. Este valor será enviado apenas uma vez, por isso marque a caixa **Repeat** para que os dados sejam repetidos a cada segundo. - - ![O sensor GPS com lat lon selecionado](../../../../../translated_images/pt-PT/counterfit-gps-sensor-latlon.008c867d75464fbe7f84107cc57040df565ac07cb57d2f21db37d087d470197d.png) - - * Defina a **Source** como `NMEA` e adicione algumas frases NMEA na caixa de texto. Todos estes valores serão enviados, com um atraso de 1 segundo antes de cada nova frase GGA (fixação de posição) poder ser lida. - - ![O sensor GPS com frases NMEA definidas](../../../../../translated_images/pt-PT/counterfit-gps-sensor-nmea.c62eea442171e17e19528b051b104cfcecdc9cd18db7bc72920f29821ae63f73.png) - - Pode usar uma ferramenta como [nmeagen.org](https://www.nmeagen.org) para gerar estas frases desenhando num mapa. Estes valores serão enviados apenas uma vez, por isso marque a caixa **Repeat** para que os dados sejam repetidos um segundo após todos terem sido enviados. - - * Defina a **Source** como ficheiro GPX e carregue um ficheiro GPX com localizações de trilhos. Pode descarregar ficheiros GPX de vários sites populares de mapas e caminhadas, como [AllTrails](https://www.alltrails.com/). Estes ficheiros contêm várias localizações GPS como um trilho, e o sensor GPS retornará cada nova localização em intervalos de 1 segundo. - - ![O sensor GPS com um ficheiro GPX definido](../../../../../translated_images/pt-PT/counterfit-gps-sensor-gpxfile.8310b063ce8a425ccc8ebeec8306aeac5e8e55207f007d52c6e1194432a70cd9.png) - - Estes valores serão enviados apenas uma vez, por isso marque a caixa **Repeat** para que os dados sejam repetidos um segundo após todos terem sido enviados. - - Depois de configurar as definições do GPS, selecione o botão **Set** para confirmar estes valores no sensor. - -1. Verá a saída bruta do sensor GPS, algo como o seguinte: - - ```output - $GNGGA,020604.001,4738.538654,N,12208.341758,W,1,3,,164.7,M,-17.1,M,,*67 - $GNGGA,020604.001,4738.538654,N,12208.341758,W,1,3,,164.7,M,-17.1,M,,*67 - ``` - -> 💁 Pode encontrar este código na pasta [code-gps/virtual-device](../../../../../3-transport/lessons/1-location-tracking/code-gps/virtual-device). - -😀 O seu programa do sensor GPS foi um sucesso! - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, esteja ciente de que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes do uso desta tradução. \ No newline at end of file diff --git a/translations/pt/3-transport/lessons/1-location-tracking/wio-terminal-gps-decode.md b/translations/pt/3-transport/lessons/1-location-tracking/wio-terminal-gps-decode.md deleted file mode 100644 index bf4908bb1..000000000 --- a/translations/pt/3-transport/lessons/1-location-tracking/wio-terminal-gps-decode.md +++ /dev/null @@ -1,81 +0,0 @@ - -# Decodificar dados GPS - Wio Terminal - -Nesta parte da lição, vais decodificar as mensagens NMEA lidas do sensor GPS pelo Wio Terminal e extrair a latitude e a longitude. - -## Decodificar dados GPS - -Depois de os dados NMEA brutos serem lidos da porta série, podem ser decodificados utilizando uma biblioteca NMEA de código aberto. - -### Tarefa - decodificar dados GPS - -Programa o dispositivo para decodificar os dados GPS. - -1. Abre o projeto da aplicação `gps-sensor` se ainda não estiver aberto. - -1. Adiciona uma dependência de biblioteca para a biblioteca [TinyGPSPlus](https://github.com/mikalhart/TinyGPSPlus) no ficheiro `platformio.ini` do projeto. Esta biblioteca contém código para decodificar dados NMEA. - - ```ini - lib_deps = - mikalhart/TinyGPSPlus @ 1.0.2 - ``` - -1. No ficheiro `main.cpp`, adiciona uma diretiva de inclusão para a biblioteca TinyGPSPlus: - - ```cpp - #include - ``` - -1. Abaixo da declaração de `Serial3`, declara um objeto TinyGPSPlus para processar as sentenças NMEA: - - ```cpp - TinyGPSPlus gps; - ``` - -1. Altera o conteúdo da função `printGPSData` para o seguinte: - - ```cpp - if (gps.encode(Serial3.read())) - { - if (gps.location.isValid()) - { - Serial.print(gps.location.lat(), 6); - Serial.print(F(",")); - Serial.print(gps.location.lng(), 6); - Serial.print(" - from "); - Serial.print(gps.satellites.value()); - Serial.println(" satellites"); - } - } - ``` - - Este código lê o próximo carácter da porta série UART para o decodificador NMEA `gps`. Após cada carácter, verifica se o decodificador leu uma sentença válida e, em seguida, verifica se leu uma localização válida. Se a localização for válida, envia-a para o monitor série, juntamente com o número de satélites que contribuíram para esta fixação. - -1. Compila e carrega o código para o Wio Terminal. - -1. Depois de carregado, podes monitorizar os dados de localização GPS utilizando o monitor série. - - ```output - > Executing task: platformio device monitor < - - --- Available filters and text transformations: colorize, debug, default, direct, hexlify, log2file, nocontrol, printable, send_on_enter, time - --- More details at http://bit.ly/pio-monitor-filters - --- Miniterm on /dev/cu.usbmodem1201 9600,8,N,1 --- - --- Quit: Ctrl+C | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H --- - 47.6423109,-122.1390293 - from 3 satellites - ``` - -> 💁 Podes encontrar este código na pasta [code-gps-decode/wio-terminal](../../../../../3-transport/lessons/1-location-tracking/code-gps-decode/wio-terminal). - -😀 O teu programa do sensor GPS com decodificação de dados foi um sucesso! - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, é importante notar que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes do uso desta tradução. \ No newline at end of file diff --git a/translations/pt/3-transport/lessons/1-location-tracking/wio-terminal-gps-sensor.md b/translations/pt/3-transport/lessons/1-location-tracking/wio-terminal-gps-sensor.md deleted file mode 100644 index 69cacaa44..000000000 --- a/translations/pt/3-transport/lessons/1-location-tracking/wio-terminal-gps-sensor.md +++ /dev/null @@ -1,152 +0,0 @@ - -# Ler dados de GPS - Wio Terminal - -Nesta parte da lição, irá adicionar um sensor GPS ao seu Wio Terminal e ler os valores obtidos. - -## Hardware - -O Wio Terminal necessita de um sensor GPS. - -O sensor que irá utilizar é o [sensor Grove GPS Air530](https://www.seeedstudio.com/Grove-GPS-Air530-p-4584.html). Este sensor pode conectar-se a múltiplos sistemas GPS para obter uma localização rápida e precisa. O sensor é composto por 2 partes - a eletrónica principal do sensor e uma antena externa conectada por um fio fino para captar as ondas de rádio dos satélites. - -Este é um sensor UART, o que significa que envia dados GPS através de UART. - -### Conectar o sensor GPS - -O sensor Grove GPS pode ser conectado ao Wio Terminal. - -#### Tarefa - conectar o sensor GPS - -Conecte o sensor GPS. - -![Um sensor Grove GPS](../../../../../translated_images/pt-PT/grove-gps-sensor.247943bf69b03f0d1820ef6ed10c587f9b650e8db55b936851c92412180bd3e2.png) - -1. Insira uma extremidade de um cabo Grove na entrada do sensor GPS. O cabo só encaixa de uma forma. - -1. Com o Wio Terminal desconectado do seu computador ou de outra fonte de energia, conecte a outra extremidade do cabo Grove à entrada Grove do lado esquerdo do Wio Terminal, olhando para o ecrã. Esta é a entrada mais próxima do botão de energia. - - ![O sensor Grove GPS conectado à entrada do lado esquerdo](../../../../../translated_images/pt-PT/wio-gps-sensor.19fd52b81ce58095.webp) - -1. Posicione o sensor GPS de forma que a antena conectada tenha visibilidade para o céu - idealmente próximo de uma janela aberta ou no exterior. É mais fácil obter um sinal claro sem obstruções à antena. - -1. Agora pode conectar o Wio Terminal ao seu computador. - -1. O sensor GPS tem 2 LEDs - um LED azul que pisca quando os dados são transmitidos e um LED verde que pisca a cada segundo ao receber dados dos satélites. Certifique-se de que o LED azul está a piscar quando ligar o Wio Terminal. Após alguns minutos, o LED verde começará a piscar - se não, pode ser necessário reposicionar a antena. - -## Programar o sensor GPS - -O Wio Terminal pode agora ser programado para utilizar o sensor GPS conectado. - -### Tarefa - programar o sensor GPS - -Programe o dispositivo. - -1. Crie um novo projeto Wio Terminal utilizando o PlatformIO. Chame este projeto `gps-sensor`. Adicione código na função `setup` para configurar a porta serial. - -1. Adicione a seguinte diretiva de inclusão no topo do ficheiro `main.cpp`. Isto inclui um ficheiro de cabeçalho com funções para configurar a entrada Grove do lado esquerdo para UART. - - ```cpp - #include - ``` - -1. Abaixo disso, adicione a seguinte linha de código para declarar uma conexão de porta serial para a porta UART: - - ```cpp - static Uart Serial3(&sercom3, PIN_WIRE_SCL, PIN_WIRE_SDA, SERCOM_RX_PAD_1, UART_TX_PAD_0); - ``` - -1. É necessário adicionar algum código para redirecionar alguns manipuladores de sinal internos para esta porta serial. Adicione o seguinte código abaixo da declaração `Serial3`: - - ```cpp - void SERCOM3_0_Handler() - { - Serial3.IrqHandler(); - } - - void SERCOM3_1_Handler() - { - Serial3.IrqHandler(); - } - - void SERCOM3_2_Handler() - { - Serial3.IrqHandler(); - } - - void SERCOM3_3_Handler() - { - Serial3.IrqHandler(); - } - ``` - -1. Na função `setup`, abaixo da configuração da porta `Serial`, configure a porta serial UART com o seguinte código: - - ```cpp - Serial3.begin(9600); - - while (!Serial3) - ; // Wait for Serial3 to be ready - - delay(1000); - ``` - -1. Abaixo deste código na função `setup`, adicione o seguinte código para conectar o pino Grove à porta serial: - - ```cpp - pinPeripheral(PIN_WIRE_SCL, PIO_SERCOM_ALT); - ``` - -1. Adicione a seguinte função antes da função `loop` para enviar os dados do GPS para o monitor serial: - - ```cpp - void printGPSData() - { - Serial.println(Serial3.readStringUntil('\n')); - } - ``` - -1. Na função `loop`, adicione o seguinte código para ler da porta serial UART e imprimir a saída no monitor serial: - - ```cpp - while (Serial3.available() > 0) - { - printGPSData(); - } - - delay(1000); - ``` - - Este código lê da porta serial UART. A função `readStringUntil` lê até encontrar um carácter terminador, neste caso uma nova linha. Isto irá ler uma frase completa em formato NMEA (as frases NMEA terminam com um carácter de nova linha). Enquanto houver dados para ler da porta serial UART, estes são lidos e enviados para o monitor serial através da função `printGPSData`. Quando não houver mais dados para ler, o `loop` faz uma pausa de 1 segundo (1.000ms). - -1. Compile e carregue o código no Wio Terminal. - -1. Após o carregamento, pode monitorizar os dados do GPS utilizando o monitor serial. - - ```output - > Executing task: platformio device monitor < - - --- Available filters and text transformations: colorize, debug, default, direct, hexlify, log2file, nocontrol, printable, send_on_enter, time - --- More details at http://bit.ly/pio-monitor-filters - --- Miniterm on /dev/cu.usbmodem1201 9600,8,N,1 --- - --- Quit: Ctrl+C | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H --- - $GNGGA,020604.001,4738.538654,N,12208.341758,W,1,3,,164.7,M,-17.1,M,,*67 - $GPGSA,A,1,,,,,,,,,,,,,,,*1E - $BDGSA,A,1,,,,,,,,,,,,,,,*0F - $GPGSV,1,1,00*79 - $BDGSV,1,1,00*68 - ``` - -> 💁 Pode encontrar este código na pasta [code-gps/wio-terminal](../../../../../3-transport/lessons/1-location-tracking/code-gps/wio-terminal). - -😀 O seu programa para o sensor GPS foi um sucesso! - -**Aviso Legal**: -Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, é importante notar que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes do uso desta tradução. \ No newline at end of file diff --git a/translations/pt/3-transport/lessons/2-store-location-data/README.md b/translations/pt/3-transport/lessons/2-store-location-data/README.md deleted file mode 100644 index bd1694512..000000000 --- a/translations/pt/3-transport/lessons/2-store-location-data/README.md +++ /dev/null @@ -1,477 +0,0 @@ - -# Dados de localização da loja - -![Uma visão geral ilustrada desta lição](../../../../../translated_images/pt-PT/lesson-12.ca7f53039712a3ec14ad6474d8445361c84adab643edc53fa6269b77895606bb.jpg) - -> Ilustração por [Nitya Narasimhan](https://github.com/nitya). Clique na imagem para uma versão maior. - -## Questionário pré-aula - -[Questionário pré-aula](https://black-meadow-040d15503.1.azurestaticapps.net/quiz/23) - -## Introdução - -Na última lição, aprendeste a usar um sensor GPS para capturar dados de localização. Para utilizar esses dados e visualizar a localização de um camião carregado de alimentos e a sua jornada, é necessário enviá-los para um serviço IoT na nuvem e armazená-los em algum lugar. - -Nesta lição, vais aprender sobre as diferentes formas de armazenar dados IoT e como armazenar dados do teu serviço IoT utilizando código sem servidor. - -Nesta lição, abordaremos: - -* [Dados estruturados e não estruturados](../../../../../3-transport/lessons/2-store-location-data) -* [Enviar dados GPS para um IoT Hub](../../../../../3-transport/lessons/2-store-location-data) -* [Caminhos quente, morno e frio](../../../../../3-transport/lessons/2-store-location-data) -* [Lidar com eventos GPS usando código sem servidor](../../../../../3-transport/lessons/2-store-location-data) -* [Contas de armazenamento Azure](../../../../../3-transport/lessons/2-store-location-data) -* [Conectar o teu código sem servidor ao armazenamento](../../../../../3-transport/lessons/2-store-location-data) - -## Dados estruturados e não estruturados - -Os sistemas informáticos lidam com dados, e esses dados podem ter diferentes formas e tamanhos. Podem variar de números simples a grandes quantidades de texto, vídeos e imagens, e até dados IoT. Os dados geralmente podem ser divididos em duas categorias: *dados estruturados* e *dados não estruturados*. - -* **Dados estruturados** são dados com uma estrutura bem definida e rígida que não muda e geralmente se mapeiam para tabelas de dados com relações. Um exemplo é os detalhes de uma pessoa, incluindo o nome, data de nascimento e morada. - -* **Dados não estruturados** são dados sem uma estrutura bem definida e rígida, incluindo dados que podem mudar de estrutura frequentemente. Um exemplo são documentos como textos escritos ou folhas de cálculo. - -✅ Faz uma pesquisa: Consegues pensar noutros exemplos de dados estruturados e não estruturados? - -> 💁 Também existem dados semi-estruturados que são estruturados, mas não se encaixam em tabelas fixas de dados. - -Os dados IoT geralmente são considerados dados não estruturados. - -Imagina que estás a adicionar dispositivos IoT a uma frota de veículos de uma grande exploração agrícola comercial. Poderias querer usar dispositivos diferentes para diferentes tipos de veículos. Por exemplo: - -* Para veículos agrícolas como tratores, queres dados GPS para garantir que estão a trabalhar nos campos corretos. -* Para camiões de entrega que transportam alimentos para armazéns, queres dados GPS, bem como dados de velocidade e aceleração para garantir que o motorista está a conduzir de forma segura, além de dados de identidade do motorista e início/paragem para garantir conformidade com as leis locais sobre horas de trabalho. -* Para camiões refrigerados, também queres dados de temperatura para garantir que os alimentos não ficam demasiado quentes ou frios e estragam durante o transporte. - -Esses dados podem mudar constantemente. Por exemplo, se o dispositivo IoT estiver na cabine de um camião, os dados enviados podem mudar conforme o reboque muda, enviando dados de temperatura apenas quando um reboque refrigerado é usado. - -✅ Que outros dados IoT poderiam ser capturados? Pensa nos tipos de cargas que os camiões podem transportar, bem como nos dados de manutenção. - -Esses dados variam de veículo para veículo, mas todos são enviados para o mesmo serviço IoT para processamento. O serviço IoT precisa ser capaz de processar esses dados não estruturados, armazenando-os de forma que possam ser pesquisados ou analisados, mas que funcione com diferentes estruturas desses dados. - -### Armazenamento SQL vs NoSQL - -Bases de dados são serviços que permitem armazenar e consultar dados. As bases de dados podem ser de dois tipos: SQL e NoSQL. - -#### Bases de dados SQL - -As primeiras bases de dados foram Sistemas de Gestão de Bases de Dados Relacionais (RDBMS), ou bases de dados relacionais. Estas também são conhecidas como bases de dados SQL devido à Linguagem de Consulta Estruturada (SQL) usada para interagir com elas para adicionar, remover, atualizar ou consultar dados. Estas bases de dados consistem num esquema - um conjunto bem definido de tabelas de dados, semelhante a uma folha de cálculo. Cada tabela tem várias colunas nomeadas. Quando inseres dados, adicionas uma linha à tabela, colocando valores em cada uma das colunas. Isso mantém os dados numa estrutura muito rígida - embora possas deixar colunas vazias, se quiseres adicionar uma nova coluna, tens de fazer isso na base de dados, preenchendo valores para as linhas existentes. Estas bases de dados são relacionais - uma tabela pode ter uma relação com outra. - -![Uma base de dados relacional com o ID da tabela de utilizadores relacionado com a coluna de ID de utilizador da tabela de compras, e o ID da tabela de produtos relacionado com o ID de produto da tabela de compras](../../../../../translated_images/pt-PT/sql-database.be160f12bfccefd3.webp) - -Por exemplo, se armazenares os detalhes pessoais de um utilizador numa tabela, terás algum tipo de ID único interno por utilizador que é usado numa linha numa tabela que contém o nome e a morada do utilizador. Se quiseres armazenar outros detalhes sobre esse utilizador, como as suas compras, noutra tabela, terás uma coluna na nova tabela para o ID desse utilizador. Quando procuras um utilizador, podes usar o ID para obter os seus detalhes pessoais de uma tabela e as suas compras de outra. - -Bases de dados SQL são ideais para armazenar dados estruturados e para quando queres garantir que os dados correspondem ao teu esquema. - -✅ Se nunca usaste SQL antes, tira um momento para ler sobre isso na [página de SQL na Wikipedia](https://wikipedia.org/wiki/SQL). - -Algumas bases de dados SQL conhecidas são Microsoft SQL Server, MySQL e PostgreSQL. - -✅ Faz uma pesquisa: Lê sobre algumas dessas bases de dados SQL e as suas capacidades. - -#### Bases de dados NoSQL - -Bases de dados NoSQL são chamadas NoSQL porque não têm a mesma estrutura rígida das bases de dados SQL. Também são conhecidas como bases de dados de documentos, pois podem armazenar dados não estruturados, como documentos. - -> 💁 Apesar do nome, algumas bases de dados NoSQL permitem usar SQL para consultar os dados. - -![Documentos em pastas numa base de dados NoSQL](../../../../../translated_images/pt-PT/noqsl-database.62d24ccf5b73f60d35c245a8533f1c7147c0928e955b82cb290b2e184bb434df.png) - -Bases de dados NoSQL não têm um esquema pré-definido que limite como os dados são armazenados; em vez disso, podes inserir qualquer dado não estruturado, geralmente usando documentos JSON. Esses documentos podem ser organizados em pastas, semelhante a ficheiros no teu computador. Cada documento pode ter campos diferentes de outros documentos - por exemplo, se estivesses a armazenar dados IoT dos teus veículos agrícolas, alguns poderiam ter campos para dados de acelerómetro e velocidade, outros poderiam ter campos para a temperatura no reboque. Se adicionasses um novo tipo de camião, como um com balanças integradas para rastrear o peso dos produtos transportados, o teu dispositivo IoT poderia adicionar este novo campo e ele poderia ser armazenado sem alterações na base de dados. - -Algumas bases de dados NoSQL conhecidas incluem Azure CosmosDB, MongoDB e CouchDB. - -✅ Faz uma pesquisa: Lê sobre algumas dessas bases de dados NoSQL e as suas capacidades. - -Nesta lição, vais usar armazenamento NoSQL para armazenar dados IoT. - -## Enviar dados GPS para um IoT Hub - -Na última lição, capturaste dados GPS de um sensor GPS conectado ao teu dispositivo IoT. Para armazenar esses dados IoT na nuvem, precisas enviá-los para um serviço IoT. Mais uma vez, vais usar o Azure IoT Hub, o mesmo serviço IoT na nuvem que usaste no projeto anterior. - -![Enviar telemetria GPS de um dispositivo IoT para o IoT Hub](../../../../../translated_images/pt-PT/gps-telemetry-iot-hub.8115335d51cd2c1285d20e9d1b18cf685e59a8e093e7797291ef173445af6f3d.png) - -### Tarefa - enviar dados GPS para um IoT Hub - -1. Cria um novo IoT Hub usando o nível gratuito. - - > ⚠️ Podes consultar as [instruções para criar um IoT Hub do projeto 2, lição 4](../../../2-farm/lessons/4-migrate-your-plant-to-the-cloud/README.md#create-an-iot-service-in-the-cloud) se necessário. - - Lembra-te de criar um novo Grupo de Recursos. Nomeia o novo Grupo de Recursos como `gps-sensor` e o novo IoT Hub com um nome único baseado em `gps-sensor`, como `gps-sensor-`. - - > 💁 Se ainda tiveres o teu IoT Hub do projeto anterior, podes reutilizá-lo. Lembra-te de usar o nome deste IoT Hub e o Grupo de Recursos em que está ao criar outros serviços. - -1. Adiciona um novo dispositivo ao IoT Hub. Chama este dispositivo `gps-sensor`. Obtém a string de conexão para o dispositivo. - -1. Atualiza o código do teu dispositivo para enviar os dados GPS para o novo IoT Hub usando a string de conexão do dispositivo obtida no passo anterior. - - > ⚠️ Podes consultar as [instruções para conectar o teu dispositivo ao IoT do projeto 2, lição 4](../../../2-farm/lessons/4-migrate-your-plant-to-the-cloud/README.md#connect-your-device-to-the-iot-service) se necessário. - -1. Quando enviares os dados GPS, faz isso em formato JSON no seguinte formato: - - ```json - { - "gps" : - { - "lat" : , - "lon" : - } - } - ``` - -1. Envia dados GPS a cada minuto para não ultrapassares a tua alocação diária de mensagens. - -Se estiveres a usar o Wio Terminal, lembra-te de adicionar todas as bibliotecas necessárias e definir a hora usando um servidor NTP. O teu código também precisará garantir que leu todos os dados da porta serial antes de enviar a localização GPS, usando o código existente da última lição. Usa o seguinte código para construir o documento JSON: - -```cpp -DynamicJsonDocument doc(1024); -doc["gps"]["lat"] = gps.location.lat(); -doc["gps"]["lon"] = gps.location.lng(); -``` - -Se estiveres a usar um dispositivo IoT virtual, lembra-te de instalar todas as bibliotecas necessárias usando um ambiente virtual. - -Para o Raspberry Pi e o dispositivo IoT virtual, usa o código existente da última lição para obter os valores de latitude e longitude e, em seguida, envia-os no formato JSON correto com o seguinte código: - -```python -message_json = { "gps" : { "lat":lat, "lon":lon } } -print("Sending telemetry", message_json) -message = Message(json.dumps(message_json)) -``` - -> 💁 Podes encontrar este código na pasta [code/wio-terminal](../../../../../3-transport/lessons/2-store-location-data/code/wio-terminal), [code/pi](../../../../../3-transport/lessons/2-store-location-data/code/pi) ou [code/virtual-device](../../../../../3-transport/lessons/2-store-location-data/code/virtual-device). - -Executa o código do teu dispositivo e garante que as mensagens estão a fluir para o IoT Hub usando o comando CLI `az iot hub monitor-events`. - -## Caminhos quente, morno e frio - -Os dados que fluem de um dispositivo IoT para a nuvem nem sempre são processados em tempo real. Alguns dados precisam de processamento em tempo real, outros podem ser processados pouco tempo depois, e outros podem ser processados muito mais tarde. O fluxo de dados para diferentes serviços que processam os dados em diferentes momentos é referido como caminhos quente, morno e frio. - -### Caminho quente - -O caminho quente refere-se a dados que precisam ser processados em tempo real ou quase em tempo real. Usarias dados do caminho quente para alertas, como receber notificações de que um veículo está a aproximar-se de um depósito ou que a temperatura num camião refrigerado está demasiado alta. - -Para usar dados do caminho quente, o teu código responderia a eventos assim que fossem recebidos pelos teus serviços na nuvem. - -### Caminho morno - -O caminho morno refere-se a dados que podem ser processados pouco tempo depois de serem recebidos, por exemplo, para relatórios ou análises de curto prazo. Usarias dados do caminho morno para relatórios diários sobre a quilometragem dos veículos, usando dados recolhidos no dia anterior. - -Os dados do caminho morno são armazenados assim que são recebidos pelo serviço na nuvem dentro de algum tipo de armazenamento que pode ser rapidamente acessado. - -### Caminho frio - -O caminho frio refere-se a dados históricos, armazenando dados a longo prazo para serem processados sempre que necessário. Por exemplo, poderias usar o caminho frio para obter relatórios anuais de quilometragem dos veículos ou realizar análises sobre rotas para encontrar a rota mais eficiente para reduzir custos de combustível. - -Os dados do caminho frio são armazenados em armazéns de dados - bases de dados projetadas para armazenar grandes quantidades de dados que nunca mudam e podem ser consultados de forma rápida e fácil. Normalmente, terias uma tarefa regular na tua aplicação na nuvem que seria executada num horário regular, diariamente, semanalmente ou mensalmente, para mover dados do armazenamento do caminho morno para o armazém de dados. - -✅ Pensa nos dados que capturaste até agora nestas lições. São dados do caminho quente, morno ou frio? - -## Lidar com eventos GPS usando código sem servidor - -Assim que os dados estiverem a fluir para o teu IoT Hub, podes escrever algum código sem servidor para ouvir eventos publicados no endpoint compatível com Event-Hub. Este é o caminho morno - esses dados serão armazenados e usados na próxima lição para relatórios sobre a jornada. - -![Enviar telemetria GPS de um dispositivo IoT para o IoT Hub, depois para Azure Functions via um gatilho de event hub](../../../../../translated_images/pt-PT/gps-telemetry-iot-hub-functions.24d3fa5592455e9f4e2fe73856b40c3915a292b90263c31d652acfd976cfedd8.png) - -### Tarefa - lidar com eventos GPS usando código sem servidor - -1. Cria uma aplicação Azure Functions usando o CLI do Azure Functions. Usa o runtime Python e cria-a numa pasta chamada `gps-trigger`, usando o mesmo nome para o nome do projeto da aplicação Functions. Certifica-te de criar um ambiente virtual para isso. -> ⚠️ Pode consultar as [instruções para criar um Projeto Azure Functions a partir do projeto 2, lição 5](../../../2-farm/lessons/5-migrate-application-to-the-cloud/README.md#create-a-serverless-application) se necessário. -1. Adicione um gatilho de evento do IoT Hub que utilize o endpoint compatível com Event Hub do IoT Hub. - - > ⚠️ Pode consultar as [instruções para criar um gatilho de evento do IoT Hub no projeto 2, lição 5](../../../2-farm/lessons/5-migrate-application-to-the-cloud/README.md#create-an-iot-hub-event-trigger) se necessário. - -1. Defina a string de conexão do endpoint compatível com Event Hub no ficheiro `local.settings.json` e utilize a chave dessa entrada no ficheiro `function.json`. - -1. Utilize a aplicação Azurite como emulador de armazenamento local. - -1. Execute a aplicação de funções para garantir que está a receber eventos do seu dispositivo GPS. Certifique-se de que o seu dispositivo IoT também está a funcionar e a enviar dados GPS. - - ```output - Python EventHub trigger processed an event: {"gps": {"lat": 47.73481, "lon": -122.25701}} - ``` - -## Contas de Armazenamento Azure - -![O logótipo do Azure Storage](../../../../../translated_images/pt-PT/azure-storage-logo.605c0f602c640d482a80f1b35a2629a32d595711b7ab1d7ceea843250615ff32.png) - -As Contas de Armazenamento Azure são um serviço de armazenamento de propósito geral que pode armazenar dados de várias formas diferentes. Pode armazenar dados como blobs, em filas, em tabelas ou como ficheiros, tudo ao mesmo tempo. - -### Armazenamento de blobs - -A palavra *Blob* significa objetos binários grandes, mas tornou-se o termo para qualquer dado não estruturado. Pode armazenar qualquer tipo de dados no armazenamento de blobs, desde documentos JSON contendo dados de IoT até ficheiros de imagem e vídeo. O armazenamento de blobs tem o conceito de *containers*, que são baldes nomeados onde pode armazenar dados, semelhante a tabelas numa base de dados relacional. Estes containers podem ter uma ou mais pastas para armazenar blobs, e cada pasta pode conter outras pastas, semelhante à forma como os ficheiros são armazenados no disco rígido do seu computador. - -Utilizará o armazenamento de blobs nesta lição para armazenar dados de IoT. - -✅ Faça uma pesquisa: Leia sobre [Azure Blob Storage](https://docs.microsoft.com/azure/storage/blobs/storage-blobs-overview?WT.mc_id=academic-17441-jabenn) - -### Armazenamento de tabelas - -O armazenamento de tabelas permite armazenar dados semi-estruturados. O armazenamento de tabelas é, na verdade, uma base de dados NoSQL, por isso não requer um conjunto definido de tabelas previamente, mas é projetado para armazenar dados em uma ou mais tabelas, com chaves únicas para definir cada linha. - -✅ Faça uma pesquisa: Leia sobre [Azure Table Storage](https://docs.microsoft.com/azure/storage/tables/table-storage-overview?WT.mc_id=academic-17441-jabenn) - -### Armazenamento de filas - -O armazenamento de filas permite armazenar mensagens de até 64KB de tamanho numa fila. Pode adicionar mensagens ao final da fila e lê-las do início. As filas armazenam mensagens indefinidamente, desde que ainda haja espaço de armazenamento, permitindo que as mensagens sejam armazenadas a longo prazo e lidas quando necessário. Por exemplo, se quiser executar um trabalho mensal para processar dados GPS, pode adicioná-los a uma fila todos os dias durante um mês e, no final do mês, processar todas as mensagens da fila. - -✅ Faça uma pesquisa: Leia sobre [Azure Queue Storage](https://docs.microsoft.com/azure/storage/queues/storage-queues-introduction?WT.mc_id=academic-17441-jabenn) - -### Armazenamento de ficheiros - -O armazenamento de ficheiros é o armazenamento de ficheiros na nuvem, e qualquer aplicação ou dispositivo pode conectar-se utilizando protocolos padrão da indústria. Pode escrever ficheiros no armazenamento de ficheiros e montá-lo como uma unidade no seu PC ou Mac. - -✅ Faça uma pesquisa: Leia sobre [Azure File Storage](https://docs.microsoft.com/azure/storage/files/storage-files-introduction?WT.mc_id=academic-17441-jabenn) - -## Conecte o seu código serverless ao armazenamento - -A sua aplicação de funções agora precisa de se conectar ao armazenamento de blobs para armazenar as mensagens do IoT Hub. Há duas formas de fazer isso: - -* Dentro do código da função, conecte-se ao armazenamento de blobs utilizando o SDK de Python para blobs e escreva os dados como blobs. -* Utilize uma ligação de saída da função para vincular o valor de retorno da função ao armazenamento de blobs e ter o blob guardado automaticamente. - -Nesta lição, utilizará o SDK de Python para ver como interagir com o armazenamento de blobs. - -![Enviar telemetria GPS de um dispositivo IoT para o IoT Hub, depois para Azure Functions via um gatilho de Event Hub, e finalmente guardá-lo no armazenamento de blobs](../../../../../translated_images/pt-PT/save-telemetry-to-storage-from-functions.ed3b1820980097f1.webp) - -Os dados serão guardados como um blob JSON com o seguinte formato: - -```json -{ - "device_id": , - "timestamp" :