# آبیاری خودکار گیاهان ![نمای کلی درس به صورت اسکچ‌نوت](../../../../../translated_images/lesson-7.30b5f577d3cb8e031238751475cb519c7d6dbaea261b5df4643d086ffb2a03bb.fa.jpg) > اسکچ‌نوت توسط [نیتیا ناراسیمهان](https://github.com/nitya). برای مشاهده نسخه بزرگ‌تر روی تصویر کلیک کنید. این درس بخشی از [پروژه IoT برای مبتدیان - سری کشاورزی دیجیتال](https://youtube.com/playlist?list=PLmsFUfdnGr3yCutmcVg6eAUEfsGiFXgcx) از [Microsoft Reactor](https://developer.microsoft.com/reactor/?WT.mc_id=academic-17441-jabenn) آموزش داده شده است. [![آبیاری خودکار گیاهان با IoT](https://img.youtube.com/vi/g9FfZwv9R58/0.jpg)](https://youtu.be/g9FfZwv9R58) ## آزمون پیش از درس [آزمون پیش از درس](https://black-meadow-040d15503.1.azurestaticapps.net/quiz/13) ## مقدمه در درس قبلی یاد گرفتید که چگونه رطوبت خاک را نظارت کنید. در این درس یاد خواهید گرفت که چگونه اجزای اصلی یک سیستم آبیاری خودکار را بسازید که به رطوبت خاک واکنش نشان دهد. همچنین درباره زمان‌بندی یاد خواهید گرفت - اینکه چگونه سنسورها ممکن است برای پاسخ به تغییرات زمان ببرند و چگونه عملگرها ممکن است برای تغییر ویژگی‌هایی که توسط سنسورها اندازه‌گیری می‌شوند زمان نیاز داشته باشند. در این درس موارد زیر را پوشش خواهیم داد: * [کنترل دستگاه‌های پرقدرت از یک دستگاه IoT کم‌قدرت](../../../../../2-farm/lessons/3-automated-plant-watering) * [کنترل یک رله](../../../../../2-farm/lessons/3-automated-plant-watering) * [کنترل گیاه خود از طریق MQTT](../../../../../2-farm/lessons/3-automated-plant-watering) * [زمان‌بندی سنسور و عملگر](../../../../../2-farm/lessons/3-automated-plant-watering) * [افزودن زمان‌بندی به سرور کنترل گیاه](../../../../../2-farm/lessons/3-automated-plant-watering) ## کنترل دستگاه‌های پرقدرت از یک دستگاه IoT کم‌قدرت دستگاه‌های IoT از ولتاژ پایین استفاده می‌کنند. در حالی که این ولتاژ برای سنسورها و عملگرهای کم‌قدرت مانند LEDها کافی است، برای کنترل سخت‌افزارهای بزرگ‌تر، مانند پمپ آب مورد استفاده در آبیاری، بسیار کم است. حتی پمپ‌های کوچک که می‌توانید برای گیاهان خانگی استفاده کنید جریان زیادی برای یک کیت توسعه IoT می‌کشند و ممکن است برد را بسوزانند. > 🎓 جریان، که با آمپر (A) اندازه‌گیری می‌شود، مقدار الکتریسیته‌ای است که از یک مدار عبور می‌کند. ولتاژ فشار را فراهم می‌کند، جریان مقدار فشار است. می‌توانید درباره جریان بیشتر در صفحه [جریان الکتریکی در ویکی‌پدیا](https://wikipedia.org/wiki/Electric_current) بخوانید. راه‌حل این است که پمپ به یک منبع تغذیه خارجی متصل شود و از یک عملگر برای روشن کردن پمپ استفاده شود، مشابه اینکه چگونه یک چراغ را روشن می‌کنید. مقدار کمی انرژی (به شکل انرژی در بدن شما) برای انگشت شما کافی است تا یک کلید را فشار دهد، و این کلید چراغ را به برق اصلی متصل می‌کند که با ولتاژ 110v/240v کار می‌کند. ![یک کلید چراغ برق را به چراغ وصل می‌کند](../../../../../translated_images/light-switch.760317ad6ab8bd6d611da5352dfe9c73a94a0822ccec7df3c8bae35da18e1658.fa.png) > 🎓 [برق اصلی](https://wikipedia.org/wiki/Mains_electricity) به برق تحویلی به خانه‌ها و کسب‌وکارها از طریق زیرساخت ملی در بسیاری از نقاط جهان اشاره دارد. ✅ دستگاه‌های IoT معمولاً می‌توانند 3.3V یا 5V، با کمتر از 1 آمپر (1A) جریان فراهم کنند. این را با برق اصلی مقایسه کنید که اغلب با 230V (120V در آمریکای شمالی و 100V در ژاپن) کار می‌کند و می‌تواند برق دستگاه‌هایی که 30A جریان می‌کشند را فراهم کند. تعدادی عملگر وجود دارد که می‌توانند این کار را انجام دهند، از جمله دستگاه‌های مکانیکی که می‌توانید به کلیدهای موجود متصل کنید و مانند انگشت آنها را روشن کنید. محبوب‌ترین آنها رله است. ### رله‌ها رله یک کلید الکترومکانیکی است که یک سیگنال الکتریکی را به حرکت مکانیکی تبدیل می‌کند که یک کلید را روشن می‌کند. هسته یک رله یک الکترومغناطیس است. > 🎓 [الکترومغناطیس‌ها](https://wikipedia.org/wiki/Electromagnet) آهنرباهایی هستند که با عبور الکتریسیته از یک سیم‌پیچ ایجاد می‌شوند. وقتی الکتریسیته روشن شود، سیم‌پیچ مغناطیسی می‌شود. وقتی الکتریسیته خاموش شود، سیم‌پیچ مغناطیس خود را از دست می‌دهد. ![وقتی روشن است، الکترومغناطیس میدان مغناطیسی ایجاد می‌کند و کلید مدار خروجی را روشن می‌کند](../../../../../translated_images/relay-on.4db16a0fd6b669262fd6699aff3fbcd31b6057c06d90411b6bddc06326d1cf75.fa.png) در یک رله، یک مدار کنترل الکترومغناطیس را تغذیه می‌کند. وقتی الکترومغناطیس روشن است، یک اهرم را می‌کشد که یک کلید را حرکت می‌دهد، یک جفت تماس را می‌بندد و یک مدار خروجی را کامل می‌کند. ![وقتی خاموش است، الکترومغناطیس میدان مغناطیسی ایجاد نمی‌کند و کلید مدار خروجی را خاموش می‌کند](../../../../../translated_images/relay-off.c34a178a2960fecdc3c6400d43e633ed11c6746cd653cfb4a768fa097c40394c.fa.png) وقتی مدار کنترل خاموش است، الکترومغناطیس خاموش می‌شود، اهرم را آزاد می‌کند و تماس‌ها را باز می‌کند، مدار خروجی را خاموش می‌کند. رله‌ها عملگرهای دیجیتال هستند - یک سیگنال بالا به رله آن را روشن می‌کند، یک سیگنال پایین آن را خاموش می‌کند. مدار خروجی می‌تواند برای تغذیه سخت‌افزار اضافی مانند یک سیستم آبیاری استفاده شود. دستگاه IoT می‌تواند رله را روشن کند، مدار خروجی که سیستم آبیاری را تغذیه می‌کند کامل شود و گیاهان آبیاری شوند. سپس دستگاه IoT می‌تواند رله را خاموش کند، برق سیستم آبیاری را قطع کند و آب را خاموش کند. ![یک رله روشن می‌شود و یک پمپ را روشن می‌کند که آب را به گیاه می‌رساند](../../../../../images/strawberry-pump.gif) در ویدئوی بالا، یک رله روشن می‌شود. یک LED روی رله روشن می‌شود تا نشان دهد که رله روشن است (برخی از بردهای رله دارای LEDهایی هستند که نشان می‌دهند رله روشن یا خاموش است)، و برق به پمپ ارسال می‌شود، پمپ روشن می‌شود و آب به گیاه پمپ می‌شود. > 💁 رله‌ها همچنین می‌توانند برای جابجایی بین دو مدار خروجی به جای روشن و خاموش کردن یکی استفاده شوند. وقتی اهرم حرکت می‌کند، یک کلید را از کامل کردن یک مدار خروجی به کامل کردن یک مدار خروجی دیگر حرکت می‌دهد، معمولاً یک اتصال برق مشترک یا اتصال زمین مشترک را به اشتراک می‌گذارند. ✅ تحقیق کنید: انواع مختلفی از رله‌ها وجود دارد، با تفاوت‌هایی مانند اینکه آیا مدار کنترل رله را روشن یا خاموش می‌کند وقتی برق اعمال می‌شود، یا مدارهای خروجی متعدد. درباره این انواع مختلف اطلاعات کسب کنید. وقتی اهرم حرکت می‌کند، معمولاً می‌توانید صدای کلیک مشخصی را بشنوید که با تماس با الکترومغناطیس ایجاد می‌شود. > 💁 یک رله می‌تواند به گونه‌ای سیم‌کشی شود که ایجاد اتصال در واقع برق را به رله قطع کند، رله را خاموش کند، که سپس برق را به رله ارسال می‌کند و دوباره آن را روشن می‌کند، و به همین ترتیب. این به این معنی است که رله بسیار سریع کلیک می‌کند و صدای وزوز ایجاد می‌کند. این روش کار برخی از اولین زنگ‌های درب الکتریکی بود. ### توان رله الکترومغناطیس برای فعال شدن و کشیدن اهرم به مقدار زیادی برق نیاز ندارد، می‌توان آن را با خروجی 3.3V یا 5V از یک کیت توسعه IoT کنترل کرد. مدار خروجی می‌تواند برق بیشتری حمل کند، بسته به رله، از جمله ولتاژ اصلی یا حتی سطوح توان بالاتر برای استفاده صنعتی. به این ترتیب یک کیت توسعه IoT می‌تواند یک سیستم آبیاری را کنترل کند، از یک پمپ کوچک برای یک گیاه واحد تا یک سیستم صنعتی عظیم برای یک مزرعه تجاری کامل. ![یک رله Grove با مدار کنترل، مدار خروجی و رله برچسب‌گذاری شده](../../../../../translated_images/grove-relay-labelled.293e068f5c3c2a199bd7892f2661fdc9e10c920b535cfed317fbd6d1d4ae1168.fa.png) تصویر بالا یک رله Grove را نشان می‌دهد. مدار کنترل به یک دستگاه IoT متصل می‌شود و رله را با استفاده از 3.3V یا 5V روشن یا خاموش می‌کند. مدار خروجی دارای دو ترمینال است، هر کدام می‌توانند برق یا زمین باشند. مدار خروجی می‌تواند تا 250V با 10A را تحمل کند، که برای طیف وسیعی از دستگاه‌های تغذیه‌شده با برق اصلی کافی است. شما می‌توانید رله‌هایی تهیه کنید که حتی سطوح توان بالاتری را تحمل کنند. ![یک پمپ که از طریق یک رله سیم‌کشی شده است](../../../../../translated_images/pump-wired-to-relay.66c5cfc0d89189900cd601777f5caeb39ee35c6250f6c86bf38feaceedb21fe9.fa.png) در تصویر بالا، برق از طریق یک رله به یک پمپ تامین می‌شود. یک سیم قرمز ترمینال +5V یک منبع تغذیه USB را به یک ترمینال مدار خروجی رله متصل می‌کند، و یک سیم قرمز دیگر ترمینال دیگر مدار خروجی را به پمپ متصل می‌کند. یک سیم سیاه پمپ را به زمین منبع تغذیه USB متصل می‌کند. وقتی رله روشن می‌شود، مدار کامل می‌شود، 5V به پمپ ارسال می‌شود و پمپ روشن می‌شود. ## کنترل یک رله شما می‌توانید یک رله را از کیت توسعه IoT خود کنترل کنید. ### وظیفه - کنترل یک رله راهنمای مربوطه را دنبال کنید تا یک رله را با استفاده از دستگاه IoT خود کنترل کنید: * [Arduino - Wio Terminal](wio-terminal-relay.md) * [کامپیوتر تک‌برد - Raspberry Pi](pi-relay.md) * [کامپیوتر تک‌برد - دستگاه مجازی](virtual-device-relay.md) ## کنترل گیاه خود از طریق MQTT تا اینجا رله شما مستقیماً توسط دستگاه IoT بر اساس یک خوانش رطوبت خاک کنترل شده است. در یک سیستم آبیاری تجاری، منطق کنترل متمرکز خواهد بود، که به آن اجازه می‌دهد تصمیمات آبیاری را با استفاده از داده‌های چندین سنسور بگیرد و هر تنظیماتی را در یک مکان واحد تغییر دهد. برای شبیه‌سازی این، می‌توانید رله را از طریق MQTT کنترل کنید. ### وظیفه - کنترل رله از طریق MQTT 1. کتابخانه‌ها/بسته‌های pip مربوطه و کد را به پروژه `soil-moisture-sensor` خود اضافه کنید تا به MQTT متصل شوید. شناسه کلاینت را به صورت `soilmoisturesensor_client` با پیشوند شناسه خود نام‌گذاری کنید. > ⚠️ می‌توانید به [دستورالعمل‌های اتصال به MQTT در پروژه 1، درس 4 در صورت نیاز](../../../1-getting-started/lessons/4-connect-internet/README.md#connect-your-iot-device-to-mqtt) مراجعه کنید. 1. کد دستگاه مربوطه را برای ارسال تله‌متری با تنظیمات رطوبت خاک اضافه کنید. برای پیام تله‌متری، ویژگی را `soil_moisture` نام‌گذاری کنید. > ⚠️ می‌توانید به [دستورالعمل‌های ارسال تله‌متری به MQTT در پروژه 1، درس 4 در صورت نیاز](../../../1-getting-started/lessons/4-connect-internet/README.md#send-telemetry-from-your-iot-device) مراجعه کنید. 1. کدی برای سرور محلی ایجاد کنید تا به تله‌متری مشترک شود و یک فرمان برای کنترل رله ارسال کند، در پوشه‌ای به نام `soil-moisture-sensor-server`. ویژگی پیام فرمان را `relay_on` نام‌گذاری کنید و شناسه کلاینت را به صورت `soilmoisturesensor_server` با پیشوند شناسه خود تنظیم کنید. ساختار مشابه کدی که برای سرور در پروژه 1، درس 4 نوشتید را حفظ کنید، زیرا بعداً در این درس به این کد اضافه خواهید کرد. > ⚠️ می‌توانید به [دستورالعمل‌های ارسال تله‌متری به MQTT](../../../1-getting-started/lessons/4-connect-internet/README.md#write-the-server-code) و [ارسال فرمان‌ها از طریق MQTT](../../../1-getting-started/lessons/4-connect-internet/README.md#send-commands-to-the-mqtt-broker) در پروژه 1، درس 4 در صورت نیاز مراجعه کنید. 1. کد دستگاه مربوطه را برای کنترل رله از فرمان‌های دریافت‌شده اضافه کنید، با استفاده از ویژگی `relay_on` از پیام. مقدار true را برای `relay_on` ارسال کنید اگر `soil_moisture` بیشتر از 450 باشد، در غیر این صورت مقدار false را ارسال کنید، همان منطقی که قبلاً برای دستگاه IoT اضافه کردید. > ⚠️ می‌توانید به [دستورالعمل‌های پاسخ به فرمان‌ها از MQTT در پروژه 1، درس 4 در صورت نیاز](../../../1-getting-started/lessons/4-connect-internet/README.md#handle-commands-on-the-iot-device) مراجعه کنید. > 💁 می‌توانید این کد را در پوشه [code-mqtt](../../../../../2-farm/lessons/3-automated-plant-watering/code-mqtt) پیدا کنید. اطمینان حاصل کنید که کد روی دستگاه و سرور محلی شما اجرا می‌شود و آن را با تغییر سطح رطوبت خاک آزمایش کنید، یا با تغییر مقادیر ارسال‌شده توسط سنسور مجازی، یا با تغییر سطح رطوبت خاک با افزودن آب یا برداشتن سنسور از خاک. ## زمان‌بندی سنسور و عملگر در درس 3 یک چراغ شبانه ساختید - یک LED که به محض تشخیص سطح پایین نور توسط یک سنسور نور روشن می‌شود. سنسور نور تغییرات سطح نور را فوراً تشخیص داد و دستگاه توانست سریعاً واکنش نشان دهد، تنها محدود به طول تأخیر در تابع `loop` یا حلقه `while True:`. به عنوان یک توسعه‌دهنده IoT، نمی‌توانید همیشه به چنین حلقه بازخورد سریعی اعتماد کنید. ### زمان‌بندی برای رطوبت خاک اگر درس قبلی درباره رطوبت خاک را با استفاده از یک سنسور فیزیکی انجام داده باشید، متوجه شده‌اید که چند ثانیه طول می‌کشد تا خوانش رطوبت خاک پس از آبیاری گیاه کاهش یابد. این به دلیل کندی سنسور نیست، بلکه به این دلیل است که آب زمان می‌برد تا در خاک نفوذ کند. 💁 اگر خیلی نزدیک به حسگر آبیاری کرده باشید، ممکن است دیده باشید که مقدار خوانده شده سریع کاهش پیدا کرده و سپس دوباره افزایش یافته است - این اتفاق به دلیل پخش شدن آب نزدیک حسگر در سراسر خاک رخ می‌دهد که رطوبت خاک در نزدیکی حسگر را کاهش می‌دهد. ![اندازه‌گیری رطوبت خاک با مقدار 658 که هنگام آبیاری تغییر نمی‌کند و تنها پس از نفوذ آب به خاک به 320 کاهش می‌یابد](../../../../../translated_images/soil-moisture-travel.a0e31af222cf14385de5380dfc32c7b8213960965228b8e4f7b7ab7f73b310a3.fa.png) در نمودار بالا، مقدار رطوبت خاک 658 نشان داده شده است. گیاه آبیاری می‌شود، اما این مقدار بلافاصله تغییر نمی‌کند، زیرا آب هنوز به حسگر نرسیده است. حتی ممکن است آبیاری تمام شود قبل از اینکه آب به حسگر برسد و مقدار رطوبت کاهش یابد تا سطح جدید رطوبت را نشان دهد. اگر بخواهید کدی برای کنترل یک سیستم آبیاری از طریق رله بر اساس سطح رطوبت خاک بنویسید، باید این تأخیر را در نظر بگیرید و زمان‌بندی هوشمندتری را در دستگاه IoT خود پیاده‌سازی کنید. ✅ کمی فکر کنید که چگونه می‌توانید این کار را انجام دهید. ### کنترل زمان‌بندی حسگر و عملگر تصور کنید که وظیفه ساخت یک سیستم آبیاری برای یک مزرعه به شما محول شده است. بر اساس نوع خاک، سطح ایده‌آل رطوبت خاک برای گیاهان کشت‌شده معادل یک مقدار ولتاژ آنالوگ بین 400 تا 450 تعیین شده است. می‌توانید دستگاه را به همان شیوه چراغ‌خواب برنامه‌ریزی کنید - هر زمان که حسگر مقداری بالاتر از 450 را نشان دهد، یک رله را روشن کنید تا پمپ روشن شود. مشکل این است که آب مدتی طول می‌کشد تا از پمپ، از طریق خاک به حسگر برسد. حسگر آب را زمانی متوقف می‌کند که سطح 450 را تشخیص دهد، اما سطح آب همچنان کاهش می‌یابد زیرا آب پمپاژ شده همچنان در خاک نفوذ می‌کند. نتیجه نهایی هدر رفت آب و خطر آسیب به ریشه‌ها است. ✅ به یاد داشته باشید - آب بیش از حد می‌تواند به اندازه کمبود آب برای گیاهان مضر باشد و یک منبع ارزشمند را هدر دهد. راه‌حل بهتر این است که درک کنیم بین روشن شدن عملگر و تغییر خاصیتی که حسگر اندازه‌گیری می‌کند، تأخیری وجود دارد. این بدان معناست که نه تنها حسگر باید مدتی صبر کند تا دوباره مقدار را اندازه‌گیری کند، بلکه عملگر نیز باید مدتی خاموش بماند تا اندازه‌گیری بعدی حسگر انجام شود. هر بار رله چه مدت باید روشن باشد؟ بهتر است جانب احتیاط را رعایت کنید و رله را فقط برای مدت کوتاهی روشن کنید، سپس صبر کنید تا آب در خاک نفوذ کند و سپس سطح رطوبت را دوباره بررسی کنید. در نهایت، همیشه می‌توانید دوباره پمپ را روشن کنید تا آب بیشتری اضافه کنید، اما نمی‌توانید آب را از خاک خارج کنید. > 💁 این نوع کنترل زمان‌بندی بسیار خاص دستگاه IoT است که می‌سازید، خاصیتی که اندازه‌گیری می‌کنید و حسگرها و عملگرهای مورد استفاده. ![یک گیاه توت‌فرنگی که از طریق پمپ به آب متصل است، با پمپی که به یک رله متصل است. رله و حسگر رطوبت خاک هر دو به یک Raspberry Pi متصل هستند](../../../../../translated_images/strawberry-with-pump.b410fc72ac6aabad3e28de9775bf2393ead73dcfec6fd8c9bc01cf107ecd171a.fa.png) برای مثال، من یک گیاه توت‌فرنگی دارم که به یک حسگر رطوبت خاک و یک پمپ متصل به رله مجهز است. مشاهده کرده‌ام که وقتی آب اضافه می‌کنم، حدود 20 ثانیه طول می‌کشد تا مقدار رطوبت خاک پایدار شود. این بدان معناست که باید رله را خاموش کنم و 20 ثانیه صبر کنم تا سطح رطوبت بررسی شود. ترجیح می‌دهم آب کمتری اضافه کنم تا بیش از حد - همیشه می‌توانم دوباره پمپ را روشن کنم، اما نمی‌توانم آب را از گیاه خارج کنم. ![مرحله 1، اندازه‌گیری. مرحله 2، اضافه کردن آب. مرحله 3، صبر برای نفوذ آب در خاک. مرحله 4، اندازه‌گیری مجدد](../../../../../translated_images/soil-moisture-delay.865f3fae206db01d5f8f100f4f44040215d44a0412dd3450aef7ff7b93b6d273.fa.png) این بدان معناست که بهترین فرآیند یک چرخه آبیاری به این صورت است: * پمپ را برای 5 ثانیه روشن کنید * 20 ثانیه صبر کنید * سطح رطوبت خاک را بررسی کنید * اگر سطح هنوز بالاتر از مقدار مورد نیاز است، مراحل بالا را تکرار کنید 5 ثانیه ممکن است برای پمپ زمان زیادی باشد، به‌ویژه اگر سطح رطوبت فقط کمی بالاتر از سطح مورد نیاز باشد. بهترین راه برای تعیین زمان‌بندی مناسب این است که آن را امتحان کنید و سپس با داشتن داده‌های حسگر، تنظیمات لازم را انجام دهید و یک چرخه بازخورد مداوم ایجاد کنید. این حتی می‌تواند به زمان‌بندی دقیق‌تر منجر شود، مانند روشن کردن پمپ برای 1 ثانیه به ازای هر 100 واحد بالاتر از سطح رطوبت مورد نیاز، به جای یک زمان ثابت 5 ثانیه. ✅ تحقیق کنید: آیا ملاحظات زمانی دیگری وجود دارد؟ آیا می‌توان گیاه را هر زمان که رطوبت خاک خیلی کم است آبیاری کرد، یا زمان‌های خاصی از روز برای آبیاری گیاهان مناسب یا نامناسب است؟ > 💁 پیش‌بینی‌های آب‌وهوا نیز می‌توانند در کنترل سیستم‌های آبیاری خودکار برای کشت در فضای باز در نظر گرفته شوند. اگر باران پیش‌بینی شده باشد، آبیاری می‌تواند تا بعد از پایان باران به تعویق بیفتد. در این صورت خاک ممکن است به اندازه کافی مرطوب باشد که نیازی به آبیاری نداشته باشد، که بسیار کارآمدتر از هدر دادن آب با آبیاری درست قبل از باران است. ## اضافه کردن زمان‌بندی به سرور کنترل گیاه کد سرور را می‌توان تغییر داد تا کنترل زمان‌بندی چرخه آبیاری و انتظار برای تغییر سطح رطوبت خاک اضافه شود. منطق سرور برای کنترل زمان‌بندی رله به این صورت است: 1. پیام تله‌متری دریافت شد 1. سطح رطوبت خاک بررسی شود 1. اگر مقدار مناسب است، هیچ کاری انجام ندهید. اگر مقدار خیلی زیاد است (به این معنی که رطوبت خاک خیلی کم است)، سپس: 1. فرمانی برای روشن کردن رله ارسال کنید 1. 5 ثانیه صبر کنید 1. فرمانی برای خاموش کردن رله ارسال کنید 1. 20 ثانیه صبر کنید تا سطح رطوبت خاک پایدار شود چرخه آبیاری، فرآیند از دریافت پیام تله‌متری تا آماده شدن برای پردازش مجدد سطح رطوبت خاک، حدود 25 ثانیه طول می‌کشد. ما هر 10 ثانیه سطح رطوبت خاک را ارسال می‌کنیم، بنابراین یک هم‌پوشانی وجود دارد که در آن یک پیام در حالی دریافت می‌شود که سرور در حال انتظار برای پایدار شدن سطح رطوبت خاک است، که می‌تواند یک چرخه آبیاری دیگر را شروع کند. دو گزینه برای حل این مشکل وجود دارد: * کد دستگاه IoT را تغییر دهید تا تله‌متری را فقط هر دقیقه ارسال کند، به این ترتیب چرخه آبیاری قبل از ارسال پیام بعدی کامل می‌شود * در طول چرخه آبیاری از تله‌متری لغو اشتراک کنید گزینه اول همیشه برای مزارع بزرگ راه‌حل خوبی نیست. ممکن است کشاورز بخواهد سطح رطوبت خاک را در حین آبیاری برای تحلیل‌های بعدی ثبت کند، مثلاً برای آگاهی از جریان آب در مناطق مختلف مزرعه جهت هدایت آبیاری هدفمندتر. گزینه دوم بهتر است - کد فقط زمانی که نمی‌تواند از تله‌متری استفاده کند آن را نادیده می‌گیرد، اما تله‌متری همچنان برای سایر سرویس‌هایی که ممکن است به آن اشتراک داشته باشند در دسترس است. > 💁 داده‌های IoT فقط از یک دستگاه به یک سرویس ارسال نمی‌شوند، بلکه بسیاری از دستگاه‌ها می‌توانند داده‌ها را به یک بروکر ارسال کنند و بسیاری از سرویس‌ها می‌توانند داده‌ها را از بروکر دریافت کنند. برای مثال، یک سرویس می‌تواند داده‌های رطوبت خاک را گوش دهد و آن را در یک پایگاه داده برای تحلیل‌های بعدی ذخیره کند. سرویس دیگری نیز می‌تواند به همان تله‌متری گوش دهد تا یک سیستم آبیاری را کنترل کند. ### وظیفه - اضافه کردن زمان‌بندی به سرور کنترل گیاه کد سرور خود را به‌روزرسانی کنید تا رله را برای 5 ثانیه اجرا کند، سپس 20 ثانیه صبر کند. 1. پوشه `soil-moisture-sensor-server` را در VS Code باز کنید اگر هنوز باز نشده است. مطمئن شوید که محیط مجازی فعال است. 1. فایل `app.py` را باز کنید 1. کد زیر را به فایل `app.py` در زیر ایمپورت‌های موجود اضافه کنید: ```python import threading ``` این دستور `threading` را از کتابخانه‌های پایتون ایمپورت می‌کند. Threading به پایتون اجازه می‌دهد در حین انتظار، کد دیگری را اجرا کند. 1. کد زیر را قبل از تابع `handle_telemetry` که پیام‌های تله‌متری دریافتی توسط کد سرور را مدیریت می‌کند، اضافه کنید: ```python water_time = 5 wait_time = 20 ``` این مدت زمان روشن بودن رله (`water_time`) و مدت زمان انتظار پس از آن برای بررسی رطوبت خاک (`wait_time`) را تعریف می‌کند. 1. کد زیر را در زیر این کد اضافه کنید: ```python def send_relay_command(client, state): command = { 'relay_on' : state } print("Sending message:", command) client.publish(server_command_topic, json.dumps(command)) ``` این کد تابعی به نام `send_relay_command` تعریف می‌کند که فرمانی را از طریق MQTT برای کنترل رله ارسال می‌کند. تله‌متری به‌صورت یک دیکشنری ایجاد شده و سپس به یک رشته JSON تبدیل می‌شود. مقدار وارد شده به `state` تعیین می‌کند که آیا رله باید روشن یا خاموش باشد. 1. پس از تابع `send_relay_code`، کد زیر را اضافه کنید: ```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) ``` این تابعی برای کنترل رله بر اساس زمان‌بندی مورد نیاز تعریف می‌کند. ابتدا از تله‌متری لغو اشتراک می‌کند تا پیام‌های رطوبت خاک در حین آبیاری پردازش نشوند. سپس فرمانی برای روشن کردن رله ارسال می‌کند. بعد از آن برای مدت زمان `water_time` صبر می‌کند و سپس فرمانی برای خاموش کردن رله ارسال می‌کند. در نهایت برای مدت زمان `wait_time` صبر می‌کند تا سطح رطوبت خاک پایدار شود. سپس دوباره به تله‌متری اشتراک می‌کند. 1. تابع `handle_telemetry` را به کد زیر تغییر دهید: ```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() ``` این کد سطح رطوبت خاک را بررسی می‌کند. اگر مقدار بیشتر از 450 باشد، خاک نیاز به آبیاری دارد، بنابراین تابع `control_relay` را فراخوانی می‌کند. این تابع در یک رشته جداگانه اجرا می‌شود و در پس‌زمینه اجرا می‌شود. 1. مطمئن شوید که دستگاه IoT شما در حال اجرا است، سپس این کد را اجرا کنید. سطح رطوبت خاک را تغییر دهید و مشاهده کنید که چه اتفاقی برای رله می‌افتد - باید برای 5 ثانیه روشن شود و سپس حداقل 20 ثانیه خاموش بماند و فقط در صورتی روشن شود که سطح رطوبت خاک کافی نباشد. ```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} ``` یک روش خوب برای آزمایش این سیستم آبیاری شبیه‌سازی‌شده این است که از خاک خشک استفاده کنید و سپس به‌صورت دستی در حین روشن بودن رله آب بریزید و ریختن آب را زمانی که رله خاموش می‌شود متوقف کنید. > 💁 می‌توانید این کد را در پوشه [code-timing](../../../../../2-farm/lessons/3-automated-plant-watering/code-timing) پیدا کنید. > 💁 اگر می‌خواهید از یک پمپ برای ساخت یک سیستم آبیاری واقعی استفاده کنید، می‌توانید از یک [پمپ آب 6 ولتی](https://www.seeedstudio.com/6V-Mini-Water-Pump-p-1945.html) با یک [منبع تغذیه ترمینال USB](https://www.adafruit.com/product/3628) استفاده کنید. مطمئن شوید که برق به پمپ یا از پمپ از طریق رله متصل است. --- ## 🚀 چالش آیا می‌توانید به دستگاه‌های IoT یا دستگاه‌های الکتریکی دیگری فکر کنید که مشکل مشابهی دارند، جایی که مدتی طول می‌کشد تا نتایج عملگر به حسگر برسد؟ احتمالاً چند مورد از آن‌ها را در خانه یا مدرسه خود دارید. * چه خاصیتی را اندازه‌گیری می‌کنند؟ * چقدر طول می‌کشد تا خاصیت پس از استفاده از عملگر تغییر کند؟ * آیا اشکالی دارد که خاصیت از مقدار مورد نیاز فراتر رود؟ * اگر لازم باشد، چگونه می‌توان آن را به مقدار مورد نیاز بازگرداند؟ ## آزمون پس از درس [آزمون پس از درس](https://black-meadow-040d15503.1.azurestaticapps.net/quiz/14) ## مرور و مطالعه شخصی * درباره رله‌ها و استفاده تاریخی آن‌ها در مراکز تلفن بیشتر بخوانید در [صفحه ویکی‌پدیا رله](https://wikipedia.org/wiki/Relay). ## تکلیف [یک چرخه آبیاری کارآمدتر بسازید](assignment.md) **سلب مسئولیت**: این سند با استفاده از سرویس ترجمه هوش مصنوعی [Co-op Translator](https://github.com/Azure/co-op-translator) ترجمه شده است. در حالی که ما تلاش می‌کنیم دقت را حفظ کنیم، لطفاً توجه داشته باشید که ترجمه‌های خودکار ممکن است شامل خطاها یا نادرستی‌ها باشند. سند اصلی به زبان اصلی آن باید به عنوان منبع معتبر در نظر گرفته شود. برای اطلاعات حساس، توصیه می‌شود از ترجمه حرفه‌ای انسانی استفاده کنید. ما مسئولیتی در قبال سوء تفاهم‌ها یا تفسیرهای نادرست ناشی از استفاده از این ترجمه نداریم.