Merge branch 'microsoft:main' into main

pull/259/head
AdityaGarg00 4 years ago committed by GitHub
commit 560865a52c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -239,6 +239,6 @@
Hello World!
```
> 💁 你可以在[code/pi](code/pi) 文件夹里找到这个代码
> 💁 你可以在[code/pi](../code/pi) 文件夹里找到这个代码
😀 你的'Hello World'程序成功了!

@ -0,0 +1,115 @@
# 开发一个夜灯 - 树莓派
在这个部分的课程中你会把一个LED加到树莓派上并使用它来创建一个夜灯。
## 硬件
现在夜灯需要一个执行器。
这个执行器是**LED**,一个[发光二极管](https://wikipedia.org/wiki/Light-emitting_diode)当电流通过它时会发光。这是一个有两个打开或者关闭状态的数字执行器发送一个1值把灯打开发送0把灯关闭。这个LED是一个外部Grove执行器而且需要被连接到树莓派上的Grove基础扩展板。
这个夜灯的逻辑用伪代码表示是:
```output
检查光照等级。
如果光照小于300
打开LED
否则
关闭LED
```
### 连接LED
Grove LED 作为一个模块出现以及一系列可供你选择颜色的LED。
#### 任务 - 连接LED
连接LED。
![一个grove LED](../../../../images/grove-led.png)
1. 选择你最喜欢的LED然后把引脚插到LED模块的两个洞里面。
LED是发光二极管而且二极管是只允许电流单个方向通过的电子设备。这意味LED需要被连接在正确的方向不然就不会工作。
LED引脚中的一个是正极引脚另一个是负极引脚。LED不是完全的圆形而且在一边是有些平的。这略平的一边是负极引脚。当你连接LED到这个模块的时候需要确保圆形这边的引脚是连接到模块上外边标着 **+** 的插孔,而扁平的这边是连接到靠近模块中间的插孔。
1. LED模块有一个允许你控制亮度的旋转按钮用一个小十字螺丝起子逆时针旋转它拧到头来完全打开它。
1. 把Grove线缆的一端插到LED模块的插孔中这个只能从一个方向插入。
1. 在树莓派断电的情况下把Grove线缆的另一端连接到树莓派上插着的Grove基础扩展板标着 **D5** 的数字插孔。这个插孔在靠近GPIO引脚的一排左数第二个。
![连接到D5插孔的Grove LED](../../../../images/pi-led.png)
## 编写夜灯程序
现在夜灯可以用Grove光照传感器和Grove LED来编码了。
### 任务 - 编写夜灯程序
编写夜灯程序
1. 打开树莓派并等待启动完成。
1. 直接在树莓派上或者通过远程SSH扩展打开你在这个作业上一部分创建的VS Code中的夜灯项目。
1. 把下面的代码加到`app.py`文件中来导入一个需要的函数库。这一行需要加在文件顶部,在其他`import`代码行下面。
```python
from grove.grove_led import GroveLed
```
`from grove.grove_led import GroveLed`语句从Grove Python函数库中导入了`GroveLED`。这个函数库中有和Grove LED交互的代码。
1. 把下面的代码加到`light_sensor`声明之后来创建一个管理LED的类的实例
```python
led = GroveLed(5)
```
`led = GroveLed(5)`这一行创建了一个连接到 **D5** 引脚的`GroveLED`类的实例,**D5** 也就是LED连接的那个数字Grove引脚。
> 💁 所有的插孔都有唯一的引脚号引脚0、2、4和6是模拟引脚引脚5、16、18、22、24和26是数字引脚。
1. 在`while`循环中增加一个判断,在`time.sleep`之前来检查光照等级并控制LED打开或者关闭
```python
if light < 300:
led.on()
else:
led.off()
```
这块代码检查了`light`的值如果小于300就调用`GroveLED`类的`on`方法来发送一个数字值1到LED把它点亮。如果`light`值大于或等于300就调用`off`方法发送一个数字值0给LED把它关闭。
> 💁 这段代码需要放到while循环里面缩进到和`print('Light level:', light)`行一个水平。
> 💁 当发送数字值到执行器的时候0值就是0v1值就是设备的最大电压。对于插着Grove传感器和执行器的树莓派而言1的电压就是3.3V。
1. 从VS Code终端运行下面的命令来运行你的Python应用
```sh
python3 app.py
```
光照值在终端里输出。
```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. 遮挡或者揭开光照传感器会观察到光照等级等于300或更小时LED会点亮如果光照等级比300大LED就会关闭。
> 💁 如果LED没有点亮确保它是正确方向连接的而且旋转按钮是设置成全开的。
![连接到树莓派的LED随着光照等级改变点亮和关闭](../../../../images/pi-running-assignment-1-1.gif)
> 💁 你可以在[code-actuator/pi](../code-actuator/pi)文件夹里找到这份代码。
😀 你的夜灯程序就成功了!

@ -0,0 +1,439 @@
# আইওটি ডিভাইসকে ইন্টারনেটে সংযুক্তিকরণ
![A sketchnote overview of this lesson](../../../../sketchnotes/lesson-4.jpg)
> [Nitya Narasimhan](https://github.com/nitya) তৈরী করছেন এই স্কেচনোটটি। এটির বড় সংস্করণ দেখতে হলে ছবিটির উপর ক্লিক করতে হবে।
## লেকচার পূর্ববর্তী কুইজ
[লেকচার পূর্ববর্তী কুইজ](https://brave-island-0b7c7f50f.azurestaticapps.net/quiz/7)
## সূচনা
IoT শব্দে **I** হলো Internet - আইওটিতে "ইন্টারনেট" বলতে ক্লাউড এর মাধ্যমে সংযোগ এবং সেবা প্রদানের মাধ্যমে আইওটি যন্ত্রের বৈশিষ্ট্যসমূহ চালু করা, যন্ত্রের সাথে সংযুক্ত সেন্সর এর মাধ্যমে পরিমাপসমূহ সংগ্রহ করা এবং বার্তা প্রেরণের মাধ্যমে একচুয়েটরসমূহকে নিয়ন্ত্রণ করাকে বুঝায়। আইওটি যন্ত্রগুলি সাধারণত একটি স্ট্যান্ডার্ড কমিউনিকেশন প্রোটোকল ব্যবহার করে একটিমাত্র ক্লাউড আইওটি সেবাতে সংযুক্ত হয় এবং এই সেবাটি সব আইওটি এপ্লিকেশন এর সাথে সংযুক্ত থাকে যা কিনা যন্ত্রসমূহ থেকে প্রাপ্ত ডেটার মাধ্যমে এআই (কৃত্রিম বুদ্ধিমত্তা) সেবার সাহায্যে গুরুত্বপূর্ণ সিদ্ধান্ত নেওয়া থেকে শুরু করে ওয়েব এপস এর মাধ্যমে নিয়ন্ত্রণ করা বা প্রতিবেদনও তৈরি করে দিতে পারে।
> 🎓 সেন্সর এর মাধ্যমে তথ্য সংগ্রহ এবং সেই তথ্য ক্লাউডে প্রেরণ করাকে টেলিমেট্রি(Telemetry) বলে।
আইওটি যন্ত্রসমূহ ক্লাউড থেকে বার্তা গ্রহণ করতে সক্ষম। তবে এই বার্তাগুলোতে আদেশ থাকে - সেটি হল অভ্যন্তরীণভাবে কোনও কাজ সম্পন্ন করার নির্দেশনাবলী (যেমন রিবুট বা ফার্মওয়্যার আপডেট করা), অথবা একচুয়েটরকে ব্যবহার করা (যেমন একটি লাইট জ্বালানো)।
এই পাঠটিতে আইওটি যন্ত্রসমূহ কমিউনিকেশন প্রোটোকল ব্যবহার করে ক্লাউডে সংযুক্ত হওয়া এবং কি ধরনের তথ্য ক্লাউডে গ্রহণ বা প্রেরণ করে তা শিখবো। নিয়ন্ত্রিত ইন্টারনেট লাইটে সংযুক্ত করা এবং এলইডি নিয়ন্ত্রনের লজিক কোডটিকে চলমান 'সার্ভার'-এ নেওয়া, এই দুটি কাজ হাতে-কলমে শিখবো।
এ পাঠ হতে যা যা শিখবোঃ
* [কমিউনিকেশন প্রটোকলসমূহ](#কমিউনিকেশন-প্রটোকলসমূহ)
* [এমকিউটিটি (Message Queueing Telemetry Transport-MQTT)](#Message-Queueing-Telemetry-Transport-MQTT)
* [টেলিমেট্রি](#টেলিমেট্রি)
* [কমান্ডসমূহ](#কমান্ডসমূহ)
## কমিউনিকেশন প্রটোকলসমূহ
আইওটি যন্ত্রসমূহ কয়েকটি জনপ্রিয় কমিউনিকেশন প্রটোকল ব্যবহার করে ইন্টারনেটের সাথে সংযুক্ত হয়। সবচেয়ে জনপ্রিয় হচ্ছে কোন ধরনের সার্ভার বা Broker এর মাধ্যমে বার্তা প্রচার/সাবস্ক্রাইব করা। আইওটি যন্ত্রসমূহ এই ব্রোকারের সাথে সংযুক্ত হয়ে টেলিমেট্রি প্রচার করে এবং কমান্ডগুলোতে সাবস্ক্রাইব করে। ক্লাউড সেবাগুলোও এই ব্রোকারের সাথে সংযুক্ত হয়ে সকল টেলিমেট্রি বার্তাগুলোতে সাবস্ক্রাইব করে এবং কমান্ডগুলোকে হয় একটি নির্দিষ্ট ডিভাইসে না হয় অনেকগুলো ডিভাইসের একটি গ্রুপে প্রেরণ করে।
![আইওটি যন্ত্রসমূহ এই মধ্যস্থতাকারীর (Broker) সাথে সংযুক্ত হয়ে টেলিমেট্রি প্রচার করে এবং আদেশগুলোতে সাবস্ক্রাইব করে। ক্লাউড সেবাগুলোও এই মধ্যস্থতাকারীর সাথে সংযুক্ত হয়ে সকল টেলিমেট্রি বার্তাগুলোতে সাবস্ক্রাইব করে এবং কমান্ডগুলোকে একটি নির্দিষ্ট ডিভাইসে প্রচার করে।](../../../../images/pub-sub.png)
আইওটি ডিভাইসগুলোর জন্য MQTT হলো সবচেয়ে জনপ্রিয় কমিউনিকেশন প্রটোকল যা এই পাঠে অন্তর্ভুক্ত করা হয়েছে। অন্যান্য প্রটোকলের মধ্যে AMQP এবং HTTP/HTTPS অন্তর্ভুক্ত আছে।
## Message Queueing Telemetry Transport-MQTT
[MQTT](http://mqtt.org) হল লাইটওয়েট, ওপেন স্ট্যান্ডার্ড মেসেজিং প্রোটোকল যা ডিভাইসগুলোর মধ্যে বার্তা প্রেরণ করতে পারে। ১৫ বছর পরে ওপেন স্ট্যান্ডার্ড হিসাবে এটি আইবিএম দ্বারা প্রকাশিত হয় যা পূর্বে তেলের পাইপলাইনগুলি পর্যবেক্ষণ করার জন্য ১৯৯৯ সালে নকশা করা হয়েছিল ।
MQTT এর একটি ব্রোকার এবং একাধিক ক্লায়েন্ট রয়েছে। সমস্ত ক্লায়েন্ট ব্রোকারের সাথে সংযুক্ত হয় এবং ব্রোকার সংশ্লিষ্ট ক্লায়েন্টদের বার্তা প্রেরণ করে। বার্তাগুলো কোনো বিশেষ গ্রাহককে সরাসরি প্রেরণ না করে বরং নামকরণ করা টপিকগুলি ব্যবহার করে একটি নির্দিষ্ট পথে পাঠানো হয়। একটি ক্লায়েন্ট একটি টপিক প্রচার করতে পারে এবং যেকোনো ক্লায়েন্ট যে ঐ টপিকে সাবস্ক্রাইব করে তা সে সম্পর্কিত বার্তা গ্রহণ করে।
![IoT device publishing telemetry on the /telemetry topic, and the cloud service subscribing to that topic](../../../../images/mqtt.png)
✅ কিছু গবেষণা করি। যদি অনেকগুলো আইওটি ডিভাইস থাকে তাহলে কিভাবে নিশ্চিত হবো যে MQTT- ব্রোকার সবগুলো বার্তা নিয়ন্ত্রন করতে পারবে কিনা?
### আইওটি ডিভাইসটি MQTT-তে সংযুক্তিকরণ
ইন্টারনেটের মাধ্যমে নাইটলাইটকে নিয়ন্ত্রণ করার প্রথম ধাপ হচ্ছে সেটিকে MQTT- ব্রোকার এর সাথে সংযুক্ত করা।
#### কাজ
আইওটি ডিভাইসটি MQTT-ব্রোকার এ সংযুক্ত করা।
পাঠের এই অংশটিতে আইওটি নাইটলাইটিকে ইন্টারনেটে সংযুক্ত করি যাতে করে সেটিকে দূর থেকে নিয়ন্ত্রণ করা যায়। এই পরবর্তী পাঠে, আইওটি ডিভাইসটি MQTT-র মাধ্যমে একটি টেলিমেট্রি বার্তা লাইটের লেভেলসহ(সেন্সর এর ভ্যালু) পাবলিক MQTT ব্রোকারে পাঠাবে এবং সেটি কতিপয় সার্ভার দ্বারা নেওয়া হবে যেটাতে কোডটি লেখা হয়েছিলো। এই কোডটি লাইটের লেভেল/সেন্সর ভ্যালু যাচাই করবে এবং যাচাই করার পর একটি আদেশমূলক বার্তা আইওটি লাইটটিতে/ডিভাইসে পাঠাবে যাতে আদেশ হিসেবে বলা থাকবে যে এলইডিটি অন না অফ হবে।
বাস্তবিক ক্ষেত্রে এমন অবস্থা হতে পারে যেখানে অনেক লাইট সেন্সর রয়েছে (যেমন স্ট্যাডিয়াম) এবং সেই লাইটগুলো অন করার সিদ্ধান্ত নেওয়ার পূর্বে ওই একাধিক লাইট সেন্সর এর তথ্য সংগ্রহ করার প্রয়োজন হতে পারে। শুধুমাত্র একটি সেন্সর মেঘ বা পাখি দ্বারা আবৃত থাকে লাইটগুলি অন হওয়া থেকে বন্ধ রাখতে পারে, যদিও অন্য সেন্সরগুলি পর্যাপ্ত আলো শনাক্ত করেও।
✅ কমান্ড প্রেরণের আগে একাধিক সেন্সর এর তথ্য মূল্যায়নের জন্য অন্য কি পরিস্থিতিগুলো বিবেচিত হতে পারে?
এসাইনমেন্টের অংশ হিসেবে MQTT ব্রোকার সেটাপের এই জটিলতার সাথে মোকাবেলা করার চেয়ে বরং চাইলে সেটাপটি পাবলিক টেস্ট সার্ভার ব্যবহার করা যবে যেটি [Eclipse Mosquitto](https://www.mosquitto.org)(একটি ওপেন সোর্স MQTT ব্রোকার)-এ রান হবে। এই টেস্ট ব্রোকারটি [test.mosquitto.org](https://test.mosquitto.org)-এ পাওয়া যাবে যা জনসাধারনের জন্য উন্মুক্ত। MQTT ক্লায়েন্ট এবং সার্ভার এর জন্য এটি একটি অসাধারণ টুল কারণ এটিতে সেটাপ করতে কোনো একাউন্টের প্রয়োজন নেই।
> 💁 এই টেস্ট ব্রোকারটি উন্মুক্ত যা মোটেই সুরক্ষিত নয়। যে কেউ বুঝতে পারবে এতে কি পাবলিশ করা হয়েছে, তাই যে তথ্যগুলোতে গোপনীয় রাখা জরুরি সেগুলো এতে ব্যবহার না করার পরামর্শ রইল।
![A flow chart of the assignment showing light levels being read and checked, and the LED begin controlled](../../../../images/assignment-1-internet-flow.png)
ডিভাইসটি MQTT ব্রোকারে সংযুক্ত করতে সংশ্লিষ্ট ধাপগুলো অনুসরণ করিঃ
* [আরডুইনো Wio টার্মিনাল](wio-terminal-mqtt.bn.md)
* [সিংগেল বোর্ড কম্পিউটার - রাস্পবেরি পাই/ভার্চুয়াল আইওটি ডিভাইস](single-board-computer-mqtt.bn.md)
### MQTT এর আরো গভীরে
টপিকগুলোতে শ্রেণিবিন্যাস থাকতে পারে যাতে ক্লায়েন্টরা ওয়াইল্ডকার্ড ব্যবহার করে এই শ্রেণিবিন্যাসের বিভিন্ন স্তরে সাবস্ক্রাইব করতে পারে। যেমন, তাপমাত্রার টেলিমেট্রি বার্তাগুলো `/telemetry/temperature` এই টপিকে এবং আর্দ্রতার বার্তাগুলো `/telemetry/humidity` এই টপিকে পাঠানো, তারপর ক্লাউড এপটি `/telemetry/*` এই টপিকে সাবস্ক্রাইব করে তাপমাত্রা এবং আর্দ্রতা উভয়ের টেলিমেট্রি বার্তাগুলো গ্রহণ করবে।
বার্তা গ্রহণের নিশ্চয়তা প্রদান করতে বার্তাগুলো কোয়ালিটি অফ সার্ভিস(QoS) এর সাথে পাঠানো হয়।
* সর্বাধিক একবার বার্তা শুধুমাত্র একবারই পাঠানো হয় এবং ক্লায়েন্ট আর ব্রোকার বার্তাটি ডেলিভারীর প্রাপ্তি স্বীকার করতে কোনো অতিরিক্ত পদক্ষেপ নেয় না (fire and forget)।
* অন্তত একবার স্বীকারোক্তি গৃহীত না হওয়া পর্যন্ত বার্তা প্রেরক একাধিকবার বার্তা প্রেরণের চেষ্টা করেছিল (acknowledged delivery)।
* ঠিক একবার শুধু একটি বার্তা গৃহীত হয়েছে তা নিশ্চিত করতে প্রাপক এবং প্রেরক একটি দ্বি-স্তরের যোগাযোগ করে যাকে হ্যান্ডশেক এর সাথে তুলনা করা যায় (assured delivery)।
✅ কোন পরিস্থিতিতে fire and forget বার্তার পরেও একটি assured delivery এর বার্তা প্রয়োজন হতে পারে?
যদিও নামটি মেসেজ কিউয়িং (ইংরেজি প্রথম অক্ষরগুলো নিয়ে MQTT), এটি আসলে বার্তার সারিকে বুঝায় না। এর অর্থ হল যদি কোন ক্লায়েন্ট সংযোগ বিচ্ছিন্ন করে পুনরায় সংযোগ স্থাপন করার সময় QoS প্রসেস ব্যবহার করে ইতোমধ্যে প্রসেসকৃত বার্তাগুলো বাদে বিচ্ছিন্ন অবস্থায় প্রেরিত বার্তাগুলো গৃহীত হবে না। ওই বার্তাগুলোকে মনে রাখাতে একটি ফ্ল্যাগ সেট করা হয়। যদি এই ফ্ল্যাগ সেট করা থাকে তবে MQTT-ব্রোকার একটি টপিকে প্রেরিত সর্বশেষ বার্তাটি ওই ফ্ল্যাগসহিত জমা রাখবে এবং পরবর্তীতে কোনো ক্লায়েন্ট যদি এই টপিকে সাবস্ক্রাইব করে তাকে প্রেরণ করা হয়। এই পদ্ধতিতে ক্লায়েন্টগুলো সবর্দা সর্বশেষ বার্তাগুলো পেয়ে থাকে।
MQTT একটি এলাইভ(alive) ফাংশনকে সমর্থন করে এবং এই ফাংশনটি বার্তাগুলোর মধ্যে দীর্ঘ বিরতির সময় সংযোগটি চালু আছে কিনা তা পরীক্ষা করে।
> 🦟 [Eclipse Foundation এর Mosquitto-তে](https://mosquitto.org) একটি ফ্রী MQTT ব্রোকার রয়েছে যাতে MQTT-সম্পর্কিত পরীক্ষা করা যাবে, MQTT-ব্রোকার এর সাথে কোড টেস্ট করা যাবে যা এই [test.mosquitto.org](https://test.mosquitto.org) হোস্ট করা থাকে।
MQTT- সংযোগসমূহ পাবলিক ও উন্মুক্ত থাকতে পারে অথবা ইউজারনেইম, পাসওয়ার্ড এবং সার্টিফিকেট ব্যবহারের মাধ্যমে এনক্রিপটেড ও সুরক্ষিত থাকতে পারে।
> 💁 MQTT TCP/IP এর মাধ্যমে যোগাযোগ করে, এটি HTTP এর মতোই একটি নেটওয়ার্ক প্রোটকল তবে একটি ভিন্ন পোর্টবেইজড। ব্রাউজারে চলমান ওয়েব অ্যাপ্লিকেশনগুলির সাথে যোগাযোগের জন্য ওয়েবসকেটের পরিবর্তে বা ফায়ারওয়ালগুলি বা অন্যান্য নেটওয়ার্কিং রুলস যা স্ট্যান্ডার্ড সংযোগগুলিতে MQTT ব্লক করে এমন পরিস্থিতিতে MQTT ব্যবহার করা যাবে।
## টেলিমেট্রি
টেলিমেট্রি শব্দটি গ্রীক থেকে উদ্ভূত হয়েছিলো যার অর্থ দূরবর্তী থেকে পরিমাপ করা। টেলিমেট্রি হল সেন্সর থেকে ডেটা সংগ্রহ এবং সেই ডেটা ক্লাউডে প্রেরণ করা ।
> 💁 প্রাচীনতম টেলিমেট্রি ডিভাইসগুলি ফ্রান্সে ১৮৭৪ সালে উদ্ভাবিত হয়েছিল এবং Mont Blanc থেকে প্যারিসে রিয়েল-টাইম আবহাওয়া এবং তুষারের গভীরতা প্রেরণ করেছিল। এটি বাস্তবিক তারগুলি ব্যবহার করত কারণ ওয়্যারলেস প্রযুক্তিগুলি তখন ছিল না।
পাঠ 1 থেকে স্মার্ট থার্মোস্টেটের উদাহরণটি দেখি।
![একাধিক রুম সেন্সর ব্যবহার করে ইন্টারনেটে সংযুক্ত একটি থার্মোস্ট্যাট](../../../../images/telemetry.png)
টেলিমেট্রি সংগ্রহের জন্য থার্মোস্ট্যাট এর তাপমাত্রাভিত্তিক সেন্সর রয়েছে। এটিতে একটি তাপমাত্রাভিত্তিক সেন্সর বিল্টইন থাকে এবং ওয়ারলেস প্রোটোকল যেমন [ব্লুটুথ লো এনার্জি](https://wikipedia.org/wiki/Bluetooth_Low_Energy) (BLE) এর মাধ্যমে একাধিক তাপমাত্রাভিত্তিক সেন্সর এর সাথে সংযুক্ত হতে পারে।
উদাহরণস্বরূপ একটি টেলিমেট্রি ডেটা যা প্রেরণ করা হবে, তা হলো
| নাম | মান | বর্ণনা |
| ---- | ----- | ----------- |
| `thermostat_temperature` | 18°C | থার্মোস্ট্যাট এর বিল্ট-ইন তাপামাত্রাভিত্তিক সেন্সর দ্বারা তাপমাত্রা পরিমাপ করা। |
| `livingroom_temperature` | 19°C | দূরবর্তী তাপমাত্রাভিত্তিক সেন্সর(remote temperature sensor) দ্বারা তাপমাত্রা পরিমাপ করা হয় যেটিকে `livingroom` নামকরণ করা হয়েছে যাতে এটি যেই রুমে আছে সেই রুমকে শনাক্ত করতে পারে। |
| `bedroom_temperature` | 21°C | দূরবর্তী তাপমাত্রাভিত্তিক সেন্সর(remote temperature sensor) দ্বারা তাপমাত্রা পরিমাপ করা হয় যেটিকে ` bedroom ` নামকরণ করা হয়েছে যাতে এটি যেই রুমে আছে সেই রুমকে শনাক্ত করতে পারে। |
ক্লাউড সেবা এই টেলিমেট্রি ডেটা ব্যবহার করে তাপকে নিয়ন্ত্রণ করতে কী আদেশ পাঠাবে তার সিদ্ধান্ত নিতে পারে।
### টেলিমেট্রি আইওটি ডিভাইসে প্রেরণ
নাইটলাইটটিকে ইন্টারনেটের মাধ্যমে নিয়ন্ত্রণ করার পরবর্তী অংশটি হলো লাইট লেভেল টেলিমেট্রি MQTT- ব্রোকারের টেলিমেট্রি টপিকে পাঠানো।
#### কাজ
লাইট লেভেল টেলিমেট্রি MQTT- ব্রোকারে পাঠানো।
ডেটা JSON হিসাবে এনকোড করে পাঠানো হয় JSON হলো JavaScript Object Notation এর সংক্ষিপ্ত রূপ, যা কী/ভ্যালু পেয়ার ব্যবহার করে ডেটাকে এনকোডেড টেক্সট এ রূপান্তরের জন্য একটি স্ট্যান্ডার্ড ।
✅ JSON সম্পর্কে জ়েনে না থাকলে তা এই [JSON.org documentation](https://www.json.org/) থেকে শিখতে পারবো।
ডিভাইস থেকে MQTT-ব্রোকারের কাছে টেলিমেট্রি প্রেরণের জন্য নীচের পদক্ষেপটি অনুসরণ করিঃ
* [আরডুইনো Wio টার্মিনাল](wio-terminal-telemetry.bn.md)
* [সিংগেল বোর্ড কম্পিউটার - রাস্পবেরি পাই/ভার্চুয়াল আইওটি ডিভাইস](single-board-computer-telemetry.bn.md)
### MQTT ব্রোকার হতে টেলিমেট্রি গ্রহণ
টেলিমেট্রি পাঠানোর কোন অর্থ নেই যদি অন্য প্রান্তে এটিকে গ্রহণ করার মতো কিছু না থাকে। লাইট লেভেল টেলিমেট্রিটির ডেটা প্রক্রিয়া করার জন্য এটিকে কিছু গ্রাহকের এর প্রয়োজ়নীয়তা আছে। এই 'সার্ভার' কোডটি সেই ধরণের কোড যা বৃহত্তর আইওটি অ্যাপ্লিকেশনের অংশ হিসাবে একটি ক্লাউড সেবাতে স্থাপন করবো, তবে এখানে স্থানীয়ভাবে এই কোডটি লোকাল কম্পিউটারে চালাতে পারবো (বা আমাদের Pi-তে সরাসরি কোডিং করতে পারবো)। সার্ভার কোডে একটি পাইথন অ্যাপ থাকে যা MQTT-র মাধ্যমে লাইটে লেভেলগুলোর টেলিমেট্রি বার্তা গ্রহণ করতে পারে। এই পাঠের পরবর্তীতে, এটিতে কমান্ডের মেসেজ রিপ্লেতে পাঠাবো যাতে নির্দেশনা থাকবে যে এলইডি অন না অফ হবে।
✅ কিছু গবেষনা করিঃ MQTT বার্তাগুলোর কী হবে যদি কোনো গ্রাহক না থাকে?
#### পাইথন এবং ভিএস কোড ইন্সটল করি
লোকালি Python এবং VS Code ইনস্টল করা না থাকলে সার্ভারে কোড দেওয়ার জন্য দুইটিকেই ইনস্টল করবো। যদি ভার্চুয়াল ডিভাইস ব্যবহার করি বা রাস্পবেরি পাইতে কাজ করি তবে এই পদক্ষেপটি এড়িয়ে যেতে পারি ।
##### কাজ
Python এবং VS Code ইন্সটল করি।
1. পাইথন ইন্সটল করি। [Python downloads page](https://www.python.org/downloads/) থেকে পাইথনে সর্বশেষ ভার্সনটি নির্দেশনা মোতাবেক ইনস্টল করি।
1. Visual Studio Code (VS Code) ইন্সটল করি। আমরা এই ইডিটরটি আমাদের ভার্চুয়াল ডিভাইসে পাইথনে কোড করার জন্য ব্যবহার করবো। [VS Code documentation](https://code.visualstudio.com?WT.mc_id=academic-17441-jabenn) থেকে Visual Studio Code (VS Code) নির্দেশনাগুলো অনসুরণ করে Visual Studio Code (VS Code) ইন্সটল করি।
> 💁 এই পাঠের নির্দেশনাগুলো VS Code এর উপর ভিত্তি করে লেখা হলেও এই পাঠের জন্য আমরা আমাদের সুবিধামত টুল অর্থাৎ পাইথনবেইজ়ড যেকেনো আইডি বা ইডিটর ব্যবহার করতে পারি।
1. VS Code এর Pylance এক্সটেনশনটি ইন্সটল করি। পাইথন লেঙ্গুয়েজের সাপোর্টের জন্য এটি VS Code এর একটি এক্সটেনশন। এটি এক্সটেনশনটি VS Code-এ কিভাবে ইন্সটল করতে হয় [Pylance extension documentation](https://marketplace.visualstudio.com/items?itemName=ms-python.vscode-pylance&WT.mc_id=academic-17441-jabenn) থেকে দেখে নেই।
#### পাইথনের ভার্চুয়াল এনভায়রনমেন্ট কনফিগারেশন
পাইথনের অন্যতম শক্তিশালী ফিচারটি হল [পিপ প্যাকেজ](https://pypi.org) ইনস্টল করার ক্ষমতা এই কোডের প্যাকেজগুলি অন্যদের দ্বারা লেখা হয় যা পরবর্তীতে ইন্টারনেটে প্রকাশ করা হয়। কম্পিউটারে একটি কমান্ডের এর মাধ্যমে পিপ প্যাকেজ ইন্সটল করা যায়, তারপরে নির্দিষ্ট কোডটিতে সেই প্যাকেজটি ব্যবহার করতে পারবো। MQTT- এর মাধ্যমে যোগাযোগ করতে আমরা পিপ ব্যবহার করে প্যাকেজ ইন্সটল করব।
আমরা যখন কোনো প্যাকেজ ইন্সটল করি তখন তা পুরো কম্পিউটার জুড়ে থাকে এবং তা থেকে প্যাকেজ়ের ভার্সনজনিত সমস্যা দেখা দিতে পারে যেমন একটি অ্যাপ্লিকেশন যখন প্যাকেজ়ের একটি ভার্সনের উপর ভিত্তি করে চলে কিন্তু ভিন্ন এপ্লিকেশনের জন্য ওই একি প্যাকেজের নতুন ভার্সন ইন্সটল করলে আগের ভার্সনে ব্যাঘাত ঘটতে পারে। এই সমস্যা হতে উত্তরণের জন্য আমরা [Python virtual environment](https://docs.python.org/3/library/venv.html) ব্যবহার করবো এবং তাতে পাইথনের জন্য একটি ডেডিকেটেড ফোল্ডার থাকবে যাতে যখন আমরা আমাদের প্রয়োজনীয় পিপ প্যাকেজসমূহ ইন্সটল করলে তা এই ফোল্ডারে ইন্সটল হবে।
##### কাজ
পাইথনের ভার্চুয়াল এনভায়রনমেন্ট কনফিগারেশন এবং MQTT পিপ প্যাকেজ ইন্সটল।
1. টার্মিনাল বা কমান্ড লাইন হতে আমাদের পছন্দসই লোকেশনে ডিরেক্টরি তৈরি এবং নেবিগেইট করতে নিচের কমান্ডগুলো রান দিইঃ
```sh
mkdir nightlight-server
cd nightlight-server
```
1. ভার্চুয়াল এনভায়রনমেন্ট `.venv` ফোল্ডারে বানানোর জন্য নিম্নের কমান্ডটি রান করি।
```sh
python3 -m venv .venv
```
> 💁 যদি Python 2 এর সাথে Python 3(লেটেস্ট ভার্সন) ইন্সটল করা থাকে তবে ভার্চুয়াল এনভায়রনমেন্ট বানানোর জন্য সঠিকভাবে `python3`-কে কল করতে হবে। যদি Python 2 ইন্সটল করা থাকে তবে `python` কল করলে তা Python 3 এর পরিবর্তে Python 2-কে কল করবে।
1. ভার্চুয়াল এনভায়রনমেন্ট চালু করতে নিম্নের কমান্ড দিইঃ
* Windows-এ রান করতে নিম্নের কমান্ডটি দিইঃ
```cmd
.venv\Scripts\activate.bat
```
* macOS বা Linux এ রান করতে নিম্নের কমান্ডটি দিইঃ
```cmd
source ./.venv/bin/activate
```
1. ভার্চুয়াল এনভারনমেন্টটি একবার চালু হওয়ার পর ভার্চুয়াল এনভারনমেন্ট বানাতে পাইথনের যে ভার্সনটি ব্যবহৃত হয়েছিলো তা ডিফল্টভাবে `python` কমান্ডটি সেই ভার্সনটিকে রান করাবে। পাইথনে ভার্সন জানতে নিম্নের কমান্ডটি রান করবোঃ
```sh
python --version
```
আউটপুটটি নিম্নের মতো হবেঃ
```output
(.venv) ➜ nightlight-server python --version
Python 3.9.1
```
> 💁 পাইথনের ভার্সন ভিন্ন হতে পারে তবে ভার্সন ৩.৬ বা তারও বেশি হলে ভালো। যদি এই ভার্সন ইন্সটল না থাকে তবে এই ফোল্ডারটি ডিলিট করে পাইথনের নতুন ভার্সনটি ইন্সটল করে আবার চেষ্টা করি।
1. [Paho-MQTT](https://pypi.org/project/paho-mqtt/)(একটি জনপ্রিয় MQTT লাইব্রেরি) পিপ প্যাকেজটি ইন্সটল করতে নিম্নের কমান্ডটি রান করি।
```sh
pip install paho-mqtt
```
এই পিপ প্যাকেজটি শুধুমাত্র ভার্চুয়াল এনভায়রনমেন্টে ইন্সটল হবে।
#### সার্ভার কোডটি লিখি
এখন সার্ভার কোডটি পাইথনে লিখবো।
##### কাজ
সার্ভার কোডটি লিখি।
1. ভার্চুয়াল এনভায়রনমেন্টের ভিতরে `app.py` নামে একটি পাইথন ফাইল বানাতে টার্মিনাল বা কমান্ড লাইন হতে নিম্নের কমান্ডটি দিইঃ
* Windows-এ রান করতে নিম্নের কমান্ডটি দিইঃ
```cmd
type nul > app.py
```
* macOS বা Linux এ রান করতে নিম্নের কমান্ডটি দিইঃ
```cmd
touch app.py
```
1. কারেন্ট ফোল্ডারটি VS Code-এ ওপেন করিঃ
```sh
code .
```
1. যখন VS Code-টি ওপেন হবে তখন তা পাইথনের ভার্চুয়াল এনভায়রনমেন্টটিকে চালু করবে। এটি উপরে স্ট্যাটাস বারে দেখা যাবেঃ
![VS Code showing the selected virtual environment](../../../../images/vscode-virtual-env.png)
1. যদি VS Code স্টার্ট হওয়ার সময় VS Code টার্মিনালটি চালুরত অবস্থায় থাকে তবে ভার্চুয়াল এনভায়রনমেন্ট VS Code-এ একটিভেট হবে না। এর থেকে উত্তরণের সহজ উপায় হচ্ছে **Kill the active terminal instance** বাটনটিতে ক্লিক করে টার্মিনালটিকে বন্ধ করে দিবো।
![VS Code Kill the active terminal instance button](../../../../images/vscode-kill-terminal.png)
1. নতুন VS Code টার্মিনাল চালু করতে *Terminal -> New Terminal এ সিলেক্ট করবো বা `` CTRL+` `` প্রেস করবো। এই নতুন টার্মিনালটি একটি কল করে ভার্চুয়াল এনভায়রনমেন্টটি এক্টিভেট করবে যার ফলে এটি টার্মিনালে লোড হয়ে আসবে। ভার্চুয়াল এনভায়রনমেন্টের নামটি (`.venv`) প্রম্পটে দেখা যাবেঃ
```output
➜ nightlight source .venv/bin/activate
(.venv) ➜ nightlight
```
1. VS Code explorer থেকে `app.py` ফাইলটি ওপেন করি এবং নিম্নের কোডটি এড করিঃ
```python
import json
import time
import paho.mqtt.client as mqtt
id = '<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)
```
আমদের ডিভাইস বানানোর সময় যে ইউনিক আইডিটি ব্যবহার করেছিলাম তা ৬নং লাইনের `<ID>`-তে বসিয়ে দিই।
⚠️ এই আইডিটি **অব্যশই** আমাদের ডিভাইসে ব্যবহৃত একই আইডি হতে হবে নয়ত সার্ভার কোড সঠিক টপিক সাবস্ক্রাইব বা পাবলিশ কোনোটিই করবে না।
এই কোডটি একটি ইউনিক নামসহ একটি MQTT ক্লায়েন্ট তৈরি করে যা * test.mosquitto.org * ব্রোকারের সাথে সংযুক্ত হয়। পরবর্তীতে এটি একটি প্রসেসিং লুপ চালু করে যেকোনো সাবস্ক্রাইব টপিকের মেসেজ লিসেনিং এর জন্য ব্যাকগ্রাউন্ড থ্রেডে রান করে করে।
ক্লায়েন্ট পরবর্তীতে টেলিমেট্রি টপিকের মেসেজগুলিতে সাবস্ক্রাইব করে এবং একটি ফাংশন সংজ্ঞায়িত করে আর যখন মেসেজ গৃহীত হয় তখনই ফাংশনটিকে কল করা হয়। যখন একটি টেলেমেট্রি মেসেজ গৃহীত হয় তখনই `handle_telemetry` ফাংশনটি কল করা হয় এবং কনসোলে গৃহীত বার্তাটি প্রিন্ট হয়।
সবশেষে একটি ইনফিনিট লুপে অ্যাপ্লিকেশনটি রান হয়। ব্যাকগ্রাউন্ড থ্রেডে MQTT ক্লায়েন্ট বার্তাগুলোতে লিসেন করে এবং মেইন এপ্লিকেশনটি রান হওয়া অবস্থায় এটি সবসময় রান হয়।
1. পাইথন এপটি রান করতে VS Code টার্মিনাল হতে নিম্নের কোডটি রান করিঃ
```sh
python app.py
```
এপটি আইওটি ডিভাইসের মেসেজসমূহ লিসেন করতে শুরু করবে।
1. আমাদের অব্যশই নিশ্চিত হতে হবে যে ডিভাইসটি রান করছে কিনা এবং টেলিমেট্রি মেসেজ সেন্ড করছে কিনা। বাহ্যিক বা ভার্চুয়াল ডিভাইস হতে শনাক্তকৃত লাইট লেভেলটিকে এডজাস্ট করি। গৃহীত বার্তাসমূহ নিচের মতো টার্মিনালে প্রিন্ট হবে।
```output
(.venv) ➜ nightlight-server python app.py
Message received: {'light': 0}
Message received: {'light': 400}
```
প্রেরিত মেসেজ গ্রহণের জন্য নাইটলাইট ভার্চুয়াল এনভায়রনমেন্টে app.py ফাইলটিকে অবশ্যই রান অবস্থায় থাকতে হবে।
> 💁 কোডটি [code-server/server](code-server/server) ফোল্ডারে পাওয়া যাবে।
### টেলিমেট্রি কতবার পাঠানো উচিত?
টেলিমেট্রিতে একটি গুরুত্বপূর্ণ বিষয় হল কতবার ডেটা পরিমাপ এবং প্রেরণ করা উচিত? উত্তরটি হল, এটি পরিস্থিতিভেদে নির্ভরশীল। যেমনঃ আমরা যদি প্রায়ই পরিমাপ করি তবে পরিমাপ পরিবর্তনের প্রতি দ্রুত সারা দিতে পারবো কিন্তু আমরা যদি আরও পাওয়ার, ব্যান্ডউইথ, ডেটা ব্যাবহার করি তাহলে এইগুলো প্রসেস করার জন্য আরও ক্লাউড রিসোর্সের প্রয়োজন হবে যার ফলে আমাদের প্রায়ই যথেষ্ট পরিমাণে পরিমাপ করা প্রয়োজন তবে তা খুব বেশি নয়।
একটি থার্মোস্ট্যাট যদি কয়েক মিনিট পর পর তাপমাত্রা পরিমাপ করে তবে তা প্রয়োজনের অতিরিক্ত কারণ তাপমাত্রা প্রতিনিয়ত পরিবর্তিত হয় না। যদি আমরা দৈনিক একবার তাপমাত্রা পরিমাপ করি তবে ভরদুপুরে নাইটটাইমের তাপমাত্রায় আমাদের ঘরটিকে উত্তপ্ত করে বসবো। অপরপক্ষে আমরা যদি প্রতি সেকেন্ডে পরিমাপ করি তবে অপ্রয়োজনীয় সহস্রাধিক তাপমাত্রার পরিমাপের ডেটা তৈরি হবে যাতে ইউজারের ইন্টারনেট এবং ব্যান্ডউইথ বেশি ব্যবহৃত হবে (যা লিমিটেড ব্যান্ডউইথ প্ল্যানে চলা ইউজারদের সমস্যা হতে পারে) এবং আরও পাওয়ার ব্যবহার করবে যা ব্যাটারি চালিত ডিভাইসের জন্য সমস্যা হতে পারে (যেমনঃ রিমোট সেন্সর) যার ফলে ক্লাউড প্রোভাইডারে কম্পিউটিং রিসোর্সের প্রসেসিং এবং স্টোরিং এর ব্যয় বেড়ে যাবে।
যদি কোন ফ্যাক্টরিতে কোন মেসিনারি ডেটা পর্যবেক্ষণ করা হয় এবং যদি এই মেসিনটি নষ্ট হয় তবে বিপজ্জনক ক্ষতি হতে পারে তার সাথে কয়েক মিলিয়ন ডলারের রাজস্বও নষ্ট হতে পারে। তাই এমন পরিস্থিতে প্রতি সেকেন্ডে একাধিকবার পরিমাপ করা অবশ্যই যুক্তিযুক্ত। টেলিমেট্রিযেকোন যন্ত্র নষ্ট হওয়ার আগে সেটিকে বন্ধ এবং ঠিক করা প্রয়োজন তা ইন্ডিকেট করে দেয়, তাই টেলিমেট্রি মিস হওয়ার চেয়ে ব্যান্ডউইথ নষ্ট হওয়া ভাল।
> 💁 এই পরিস্থিতিতে,ইন্টারনেটের উপর নির্ভরতা হ্রাস করতে প্রথম টেলিমেট্রি প্রসেস করার জন্য একটি এজ(edge) ডিভাইস রাখা যেতে পারে।
### লস অফ কানেক্টিভিটি
ইন্টারনেট সংযোগসমূহ হতে পারে অনির্ভরযোগ্য,বিভ্রাটপূর্ণ । এই অবস্থায় আইওটি ডিভাইসের কি করা উচিত এটি কি ডেটাকে হারাতে দিবে নাকি কানেক্টিভিটি পুনরায় না আসা পর্যন্ত ডেটাকে স্টোর করে রাখবে? আবারো উত্তরটি হচ্ছে এটি পরিস্থিতিভেদে নির্ভরশীল।
একটি থার্মোস্ট্যাট এর নতুন তাপমাত্রা পরিমাপ করা মাত্রই আগের পরিমাপ করা ডেটাটি হারিয়ে যেতে পারে। ২০ মিনিট পূর্বে তাপমাত্রা ২০.৫°C ছিল বা এখন তাপমাত্রা ১৯°C তা নিয়ে হিটিং সিস্টেম পরোয়া করে না, বর্তমান মুহূর্তের তাপমাত্রাই নির্ধারণ করবে যে হিটিং সিস্টেমটি অন হবে নাকি অফ থাকবে।
মেশিনারির জন্য ডেটা রাখা যেতে পারে বিশেষত যদি এটি ট্রেন্ডস(trends) সন্ধানে ব্যবহৃত হয়। এমন কিছু মেশিন লার্নিং মডেল রয়েছে যা নির্ধারিত সময়ের মধ্যে(যেমন শেষ ঘন্টায়) ডেটা সন্ধান করে ডেটার স্ট্রিমসমূহে এনোম্যালি চিহ্নিত করে এনোম্যালাস ডেটা শনাক্ত করতে পারে। এটি প্রায়ই predictive maintenance এর জন্য ব্যবহৃত হয়, এমন কিছু লক্ষণের সন্ধান করে যাতে দ্রুত কোনও কিছু ভেঙে যাওয়ার আগেই এটি মেরামত বা রিপ্লেস করা যায় । এনোমলি ডিটেকশনের জন্য একটি মেশিনের প্রেরিত টেলিমেট্রিটির প্রতিটি বিটকে প্রসেস করা হয় তাই যখন আইওটি ডিভাইসটি পুনরায় ইন্টারনেটের সাথে সংযোগ স্থাপন করে তখন ইন্টারনেট আউটেজের সময় তৈরি হওয়া সমস্ত টেলিমেট্রি প্রেরণ করতে পারে।
আইওটি ডিভাইস ডিজাইনারদের বিবেচনা করা উচিত যাতে ইন্টারনেট আউটেজের সময় বা অবস্থানজনিত কারণে সিগন্যাল লসের সময় আইওটি ডিভাইস ব্যবহার করা যাবে কিনা। একটি স্মার্ট থার্মোস্ট্যাট যদি আউটেজের কারনে ক্লাউডে টেলিমেট্রি প্রেরণ করতে না পারে তবে হিটিং সিস্টেমকে কন্ট্রোল করতে তাতে অবশ্যই সীমিত সংখ্যক সিদ্ধান্ত নেওয়ার সক্ষমতা থাকতে হবে।
[![এই ফেরারীটি আচ্ছাদিত হয়ে আছে কারণ কেউ একজন আন্ডারগ্রাউন্ডে এটিকে আপগ্রেড করতে চেয়েছিল যেখানে কোনো সেল অপারেশন নেই ](../../../../images/bricked-car.png)](https://twitter.com/internetofshit/status/1315736960082808832)
লস অফ কানেক্টিভিটি MQTT-কতৃক সামালানোর জন্য প্রয়োজনে ডিভাইস এবং সার্ভার কোডকে মেসেজ ডেলিভারি নিশ্চিত করার দায়ভার গ্রহণ করতে হবে। উদারণস্বরূপ, একটি রিপ্লাই টপিকে অতিরিক্ত মেসেজসমূহের মাধ্যমে প্রেরিত সমস্ত মেসেজসমূহ প্রয়োজনে চাওয়া এবং তা যদি না হয় তবে সেগুলো ম্যানুয়ালি একটি সারিতে থাকবে যাতে পরবর্তী রিপ্লেতে দিবে।
## কমান্ডসমূহ
কমান্ডস হচ্ছে মেসেজ যা ক্লাউড দ্বারা কোন ডিভাইসে প্রেরণ করা হয় যাতে কিছু করার নির্দেশনা দেওয়া থাকে। বেশিরভাগক্ষেত্রে একচুয়েটরের আউটপুট সম্বলিত কিছু থাকে কিন্তু এতে ডিভাইসের নিজের জন্য কিছু নির্দেশনাও থাকতে পারে (যেমনঃ রিব্যুট করা) বা এক্সট্রা টেলিমেট্রি জড়ো করা এবং রেসপন্স হিসেবে কমান্ডকে রিটার্ন করা।
![ইন্টারনেটে সংযুক্ত একটি থার্মোস্ট্যাট কমান্ড রিসিভের মাধ্যমে হিটিং সিস্টেমকে চালু করছে](../../../../images/commands.png)
হিটিং সিস্টেম চালু করার জন্য একটি থার্মোস্ট্যাট ক্লাউ থেকে কমান্ড গ্রহণ করতে পারে। যদি ক্লাউড সার্ভিস সমস্ত সেন্সর হতে প্রাপ্ত টেলিমেট্রি ডাটার উপর ভিত্তি করে সিদ্ধান্ত নেয় যে হিটিং সিস্টেমটি চালু করা জরুরি তবে তা সে অনুযায়ী কমান্ড প্রেরণ করবে।
### কমান্ডসমূহ MQTT ব্রোকারে প্রেরণ
ইন্টারনেটের মাধ্যমে নাইটলাইটকে নিয়ন্ত্রনের পরবর্তী ধাপটি হলো সার্ভার কোড কতৃক আইওটি ডিভাইসে কমান্ড প্রেরণ করা যাতে লাইটের লেভেল উপলদ্ধি মাধ্যমে লাইটকে কন্ট্রোল করা যায়।
1. সার্ভার কোডটি VS Code এ ওপেন করি।
1. নিচের লাইনটি `client_telemetry_topic` ডিক্লেয়ারের পর এড করি যা নির্ধারণ করবে কোন টপিকে কমান্ড সেন্ড করবেঃ
```python
server_command_topic = id + '/commands'
```
1. নিচের কোডটি `handle_telemetry` ফাংশেন শেষে এড করিঃ
```python
command = { 'led_on' : payload['light'] < 300 }
print("Sending message:", command)
client.publish(server_command_topic, json.dumps(command))
```
এই কোডটি একটি JSON মেসেজ `led_on` এর ভ্যলুসহ কমান্ড টপিকে পাঠায় যা লাইটের ভ্যালু ৩০০ এর বেশি বা কমের উপর ভিত্তি করে তা ট্রু বা ফলস-এ সেট হয়। যদি লাইটের ভ্যালু (`led_on`<৩০০) ৩০০ এর কম হয় তবে ট্রু সেন্ড করা হয় যাতে এলইডি অন করার নির্দেশনা থাকে।
1. কোডটি পূর্বের মতো রান করি।
1. আমাদের বাহ্যিক বা ভার্চুয়াল ডিভাইসে কতৃক শনাক্তকৃত লাইটের লেভেল অনুসারে লেভেলটি এডজাস্ট করি। গ্রহীত মেসেজ এবং প্রেরিত কমান্ডগুলো টার্মিনালে আউটপুট হিসেবে বর্ণিত হবেঃ
```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}
```
> 💁 প্রতিটি সিংগেল টপিকে টেলিমেট্রি এবং কমান্ডসমূহ প্রেরণ করা হচ্ছে। যার অর্থ দাঁড়ায় একাধিক ডিভাইস থেকে টেলিমেট্রি একই টেলিমেট্রি টপিকের উপর প্রকাশিত হবে এবং একাধিক ডিভাইসের কমান্ডগুলিও একই কমান্ডের টপিকে প্রকাশিত হবে। যদি কোন নির্দিষ্ট ডিভাইসে কমান্ড প্রেরণ করতে চাই তবে একটি ইউনিক ডিভাইস আইডি নামকরণ (যেমনঃ `/commands/device1`, `/commands/device2`) করে একাধিক টপিক ব্যবহার করে পারবো। এইভাবে কোন ডিভাইস কেবল সেই এক ডিভাইসের জন্য বরাদ্দকৃত বার্তাগুলি লিসেন করতে পারে।
> 💁 আমরা [code-commands/server](code-commands/server) এই ফোল্ডারে কোডটি পাবো।
### আইওটি ডিভাইসে কমান্ডসমূহের পরিচালনা করা
এখনে যেহেতু সার্ভার হতে কমান্ডসমূহ প্রেরিত হচ্ছে সেহেতু আমরা আইওটি ডিভাইসকে পরিচালনা করার জন্য এবং এলইডিকে নিয়ন্ত্রণের জন্য তাতে কোড এড করতে পারবো।
MQTT ব্রোকার হতে কমান্ডসমূহ গ্রহণের জন্য নিচের পদক্ষেপগুলো অনুসরণ করিঃ
* [আরডুইনো Wio টার্মিনাল](wio-terminal-commands.bn.md)
* [সিংগেল বোর্ড কম্পিউটার - রাস্পবেরি পাই/ভার্চুয়াল আইওটি ডিভাইস](single-board-computer-commands.bn.md)
এই কোডটি লেখা এবং রান করা হয়ে গেলে আমরা লাইটের লেভেল চেঞ্জ করে এক্সপেরিমেন্ট করবো। লাইটের লেভেল চেঞ্জের মাধ্যমে এলইডিটিতে এবং সার্ভার আর ডিভাইসের আউটপুটটিতে লক্ষ্য রাখি।
### লস অফ কানেক্টিভিটি
যদি আইওটি ডিভাইসে কমান্ড প্রেরণের প্রয়োজন হয় কিন্তু ডিভাইসটি অফলাইনে থাকে তবে এমতাবস্থায় ক্লাউড সার্ভিসের কি করা উচিত? আবারও, উত্তরটি হলো তা নির্ভরশীল।
যদি লেটেস্ট কমান্ডটি তার পূর্বের কমান্ডটিকে ওভাররাইট করে তবে পূর্বের কমান্ডটি উপেক্ষিত হবে। যদি কোন ক্লাউড সার্ভিস প্রথমে হিটিং সিস্টেমটি চালু করার জন্য একটি কমান্ড পাঠায় তারপর হিটিং সিস্টেমটি বন্ধ করার জন্য দ্বিতীয় আরেকটি কমান্ড পাঠায় তবে অন কমান্ডটি অর্থাৎ ১ম কমান্ডটি উপেক্ষা করা হবে এবং তা রিসেন্ট হবে না।
যদি কমান্ডসমূহের ক্রমানুসারে প্রসেসের প্র্য়োজন হয় যেমন হতে পারে প্রথমে একটি রোবটের হাত উপরে উঠানো দ্বিতীয়ত সেটির গ্র্যাবার বন্ধ করা, তাই কানেক্টিভিটি পুনরায় চালু হলে কমান্ডসমূহকে নিয়মানুযায়ী প্রেরণ করা প্রয়োজন।
✅ কীভাবে ডিভাইস বা সার্ভার কোডটি নিশ্চিত হবে যে কমান্ডসমূহ সর্বদা প্রেরিত হবে এবং প্রয়োজন পরলে তা MQTT-র মাধ্যমে নিয়মানুযায়ী প্রকাশিত হবে?
---
## 🚀 চ্যালেঞ্জ
শেষ তিনটি পাঠ্যের মধ্যে চ্যালেঞ্জটি ছিল আমাদের বাড়ি, স্কুল বা কর্মক্ষেত্রে যতগুলো আইওটি ডিভাইস রয়েছে তার একটি তালিকা তৈরি করা এবং তারা মাইক্রোকন্ট্রোলার বা একক-বোর্ড কম্পিউটার বা উভয়ের মিশ্রণে নির্মিত কিনা তার সিদ্ধান্তে উপনিত হওয়া এবং তারা কী ধরনের সেন্সর ও একচুয়েটর ব্যবহার করছে তা নিয়ে চিন্তা করা।
চিন্তা করে দেখি যে এই ডিভাইসগুলো কী ধরনের মেসেজ প্রেরণ বা গ্রহণ করছে। কি ধরনের টেলিমেট্রি প্রেরণ করছে? কি মেসেজ বা কমান্ড রিসিভ করতে পারে? চিন্তা করে দেখি এগুলো কি সত্যিই সুরক্ষিত?
## লেকচার পরবর্তী কুইজ
[লেকচার পরবর্তী কুইজ](https://brave-island-0b7c7f50f.azurestaticapps.net/quiz/8)
## রিভিউ এবং স্ব-অধ্যয়ন
[MQTT Wikipedia page](https://wikipedia.org/wiki/MQTT) টি পড়ে MQTT সম্পর্কে আরো জানতে পারবো।
[Mosquitto](https://www.mosquitto.org) ব্যবহার করে MQTT ব্রোকার রান করতে ট্রাই করি এবং এটিকে আইওটি ডিভাইস ও সার্ভার কোডের সাথে সংযুক্ত করি।
> 💁 টিপ বাই ডিফল্ট Mosquitto কখনো anonymous কানেকশন অনুমোদন করে না (anonymous কানেকশনের অর্থ হচ্ছে ইউজারনেম এবং পাসওয়ার্ড ব্যাতীত কানেক্ট হওয়া) এবং যেই কম্পিউটারে এটি রান হচ্ছে সেই কম্পিউটার ব্যাতীত অন্য কানেকশন অনুমোদন করে না।
> এটিকে [`mosquitto.conf` config file](https://www.mosquitto.org/man/mosquitto-conf-5.html) এর মাধ্যমে ফিক্স করতে নিম্নের কমান্ডটি দিইঃ
>
> ```sh
> listener 1883 0.0.0.0
> allow_anonymous true
> ```
## এসাইনমেন্ট
[MQTT-এর সাথে অন্যান্য কমিউনিকেশন প্রটোকলের তুলনা করে পার্থক্য দাঁড় করানো](assignment.bn.md)

@ -0,0 +1,14 @@
# MQTT-এর সাথে অন্যান্য কমিউনিকেশন প্রটোকলের তুলনা করে পার্থক্য দাঁড় করানো
## নির্দেশনা
এই পাঠটিতে MQTT কমিউনিকেশন প্রোটোকল নিয়ে আলোচনা হয়েছে । অন্যান্য প্রোটোকলের মধ্যে AMQP এবং HTTP/HTTPS অন্তর্ভুক্ত রয়েছে।
AMQP এবং HTTP/HTTPS উভয়টি নিয়ে গবেষণা করতে হবে এবং MQTT এর সাথে তুলনা করে পার্থক্য দাঁড় করাতে হবে । যদি কানেকশনসমূহ চলে যায় তবে পাওয়ারের ব্যবহার, সিকউরিটি এবং মেসেজ পারসিসটেন্স নিয়ে চিন্তা করি ।
## এসাইনমেন্ট মূল্যায়ন মানদন্ড
| ক্রাইটেরিয়া | দৃষ্টান্তমূলক ব্যখ্যা (সর্বোত্তম) | পর্যাপ্ত ব্যখ্যা (মাঝারি) | আরো উন্নতির প্রয়োজন (নিম্ন) |
| -------- | --------- | -------- | ----------------- |
| AMQP এর সাথে MQTT তুলনা করা। | AMQP এর সাথে MQTT তুলনা করে পার্থক্য দাঁড় করাতে এবং পাওয়ার, সিক্যুরিটি এবং মেসেজ পারসিসটেন্স নিয়ে প্রতিবেদন তৈরি করতে সক্ষম হয়েছে। | AMQP এর সাথে MQTT তুলনা করে আংশিক পার্থক্য দাঁড় করাতে এবং পাওয়ার, সিক্যুরিটি এবং মেসেজ পারসিসটেন্স নিয়ে দুটি প্রতিবেদন তৈরি করতে সক্ষম হয়েছে। | AMQP এর সাথে MQTT তুলনা করে আংশিক পার্থক্য দাঁড় করাতে এবং পাওয়ার, সিক্যুরিটি এবং মেসেজ পারসিসটেন্স নিয়ে একটি প্রতিবেদন তৈরি করতে সক্ষম হয়েছে। |
| HTTP/HTTPS এর সাথে MQTT তুলনা করা। | HTTP/HTTPS এর সাথে MQTT তুলনা করে পার্থক্য দাঁড় করাতে এবং পাওয়ার, সিক্যুরিটি এবং মেসেজ পারসিসটেন্স নিয়ে প্রতিবেদন তৈরি করতে সক্ষম হয়েছে। | HTTP/HTTPS এর সাথে MQTT তুলনা করে আংশিক পার্থক্য দাঁড় করাতে এবং পাওয়ার, সিক্যুরিটি এবং মেসেজ পারসিসটেন্স নিয়ে দুটি প্রতিবেদন তৈরি করতে সক্ষম হয়েছে। | HTTP/HTTPS এর সাথে MQTT তুলনা করে আংশিক পার্থক্য দাঁড় করাতে এবং পাওয়ার, সিক্যুরিটি এবং মেসেজ পারসিসটেন্স নিয়ে একটি প্রতিবেদন তৈরি করতে সক্ষম হয়েছে। |

@ -1,9 +0,0 @@
# Dummy File
This file acts as a placeholder for the `translations` folder. <br>
**Please remove this file after adding the first translation**
For the instructions, follow the directives in the [translations guide](https://github.com/microsoft/IoT-For-Beginners/blob/main/TRANSLATIONS.md) .
## THANK YOU
We truly appreciate your efforts!

@ -0,0 +1,607 @@
# অ্যাপ্লিকেশন লজিককে ক্লাউডে স্থানান্তর
![A sketchnote overview of this lesson](../../../../sketchnotes/lesson-9.jpg)
> স্কেচনোটটি তৈরী করেছেন [Nitya Narasimhan](https://github.com/nitya). বড় সংস্করণে দেখার জন্য ছবিটিতে ক্লিক করতে হবে।
## লেকচার-পূর্ববর্তী কুইজ
[লেকচার-পূর্ববর্তী কুইজ](https://brave-island-0b7c7f50f.azurestaticapps.net/quiz/17)
## সূচনা
গত পাঠে আমরা শিখেছি কীভাবে ক্লাউড-ভিত্তিক আইওটি পরিষেবাতে আমাদের উদ্ভিদকে সংযুক্ত করতে হবে এবং মাটির আর্দ্রতা পর্যবেক্ষণ এবং রিলে নিয়ন্ত্রণ এর মতো কাজগুলো কীভাবে ক্লাউড থেকে করা যায়। এখন পরবর্তী পদক্ষেপটি হল সার্ভার কোডকে ক্লাউডে স্থানান্তর করা যা রিলে এর টাইমিং নিয়ন্ত্রণ করে। এই পাঠে আমরা সার্ভারবিহীন (serverless) ফাংশন দ্বারা এই কাজটি করতে শিখব।
এই লেসনে রয়েছেঃ
* [সার্ভারলেস বলতে কী বোঝায়?](#সার্ভারলেস-বলতে-কী-বোঝায়)
* [একটি সার্ভারলেস অ্যাপ্লিকেশন তৈরি](#একটি-সার্ভারলেস-অ্যাপ্লিকেশন-তৈরি-করা)
* [একটি IoT Hub ইভেন্ট ট্রিগার তৈরি](#একটি-আইওটি-হাব-ইভেন্ট-ট্রিগার-তৈরি-করা)
* [সার্ভারলেস কোড থেকে ডিরেক্ট মেথড রিকুয়েস্ট পাঠানো](#সার্ভারলেস-কোড-থেকে-ডিরেক্ট-মেথড-রিকুয়েস্ট-পাঠানো)
* [ক্লাউডে সার্ভারলেস কোড ডেপ্লয় করা](#ক্লাউডে-সার্ভারলেস-কোড-ডেপ্লয়-করা)
## সার্ভারলেস বলতে কী বোঝায়?
সার্ভারলেস বা সার্ভারবিহীন কম্পিউটিং বলতে বোঝানো হয় বিভিন্ন ধরণের ইভেন্টের প্রতিক্রিয়া হিসাবে ক্লাউডে চালিত কোডের ছোট ছোট ব্লক । ইভেন্ট ঘটলে কোড চালিত হয় এবং এটি ইভেন্ট সম্পর্কিত ডেটা পাস করে। এই ইভেন্টগুলি বিভিন্ন বিষয় সম্পর্কিত হতে পারে যেমন, ওয়েব রিকোয়েস্ট, সারিতে অপেক্ষারত বার্তাসমূহ, একটি ডাটাবেসে ডেটা পরিবর্তন করা বা আইওটি ডিভাইসগুলির মাধ্যমে আইওটি পরিষেবাতে বার্তা প্রেরণ ইত্যাদি।
![Events being sent from an IoT service to a serverless service, all being processed at the same time by multiple functions being run](../../../../images/iot-messages-to-serverless.png)
> 💁 যদি আগে 'ডাটাবেস ট্রিগার' ব্যবহারের অভিজ্ঞতা থাকে, তবে এটাকেও একই জিনিস হিসাবে ভাবা যায় যা কোন ইভেন্টের মাধ্যমে কোড ট্রিগার করার মাধ্যমে কাজ করছে, যেমন একটি সারি বা row যোগ করা ।
![When many events are sent at the same time, the serverless service scales up to run them all at the same time](../../../../images/serverless-scaling.png)
আমাদের কোডটি কেবল তখনই রান হয়, যখন ইভেন্টটি ঘটে ; অন্য সময় কোড সক্রিয় থাকেনা। ইভেন্টটি ঘটামাত্র কোডটি লোড হয় এবং তা চালানো হয়। এটি সার্ভারলেসকে খুব স্কেলেবল (scalable) করে তোলে - যদি একই সাথে অনেকগুলি ইভেন্ট ঘটে, তবে ক্লাউড সরবরাহকারী যতবার প্রয়োজন ততবার কোড চালাতে পারে। তবে এটির অনেক সুবিধা থাকলেও, এর নেতিবাচক দিকটি হল যদি আমাদেরকে ইভেন্টগুলির মধ্যে তথ্য আদান-প্রদানের দরকার হয়, তবে এটি ডাটাবেসের মতো কোথাও সংরক্ষণ করতে হবে।
আমাদের কোড একটি ফাংশন আকারে লেখা হয়েছে, যা প্যারামিটার হিসাবে ইভেন্টটির তথ্য গ্রহণ করে। এই সার্ভারলেস ফাংশনগুলি লিখতে আমরা অনেকগুলো প্রোগ্রামিং ভাষা ব্যবহার করতে পারি।
> 🎓 সার্ভারলেসকে অনেকসময় Functions as a service (FaaS) হিসাবেও উল্লেখ করা হয় কারণ প্রতিটি ইভেন্ট ট্রিগারকে কোড এ ফাংশন হিসাবে প্রয়োগ করা হয়।
নাম "সার্ভারলেস" হলেও, এটি আসলে সার্ভার ব্যবহার করে। নামকরণটি এমন হওয়ার পিছনে কারণ হল আমরা ডেভলাপার হিসাবে কোড চালানোর জন্য সার্ভার বিষয়ে কোন চিন্তাই করি না, আমাদের সকল মনোযোগ থাকে কোন ইভেন্টের প্রতিক্রিয়াতে কোডটি চালানো হচ্ছে কিনা সে বিষয়ে। ক্লাউড সরবরাহকারীর একটি সার্ভারলেস *রানটাইম* রয়েছে যা সার্ভার, নেটওয়ার্কিং, স্টোরেজ, সিপিইউ, মেমরি এবং কোড চালানোর জন্য প্রয়োজনীয় সমস্ত কিছুর ব্যবস্থা করে। এই মডেলটিতে সার্ভার নেই বলে, আমরা এই সার্ভিসের জন্য সার্ভার ব্যবস্থাপনার অর্থ প্রদান করতে পারব না। এর পরিবর্তে আমাদেরকে বরং কোডটির চলমান সময় এবং মেমরির ব্যবহারের পরিমাণের উপর অর্থ প্রদান করতে হবে।
> 💰 ক্লাউডে কোড কম খরচে রান করার সবচেয়ে ভালো উপায় হলো সার্ভারলেস। উদাহরণস্বরূপ, (এই লেসন লেখার সময়) যেকোন ক্লাউড সরবরাহকারী এই ফাংশনগুলিতে চার্জ শুরু করার আগে একমাসে 1000,000 বার রান করার সুযোগ দেয় এবং তারপরে তারা প্রতিটি 1,000,000 বার কোড এক্সেকিউট করার জন্য $0.20 চার্জ করে। যখন কোড চলছে না, তখন আমাদেরকে অর্থ প্রদান করতে হবেনা।
আইওটি ডেভলাপার হিসাবে সার্ভারলেস মডেলটি সর্বোত্তম। এখানে চাইলে আমরা এমন ফাংশন লিখতে পারি যা আমাদের ক্লাউড-হোস্টেড আইওটি পরিষেবাতে সংযুক্ত যেকোন আইওটি ডিভাইস থেকে প্রেরিত বার্তাগুলির সাথে যুক্ত থাকবে। আমাদের কোড এইসব প্রেরিত ম্যাসেজগুলোকে পরিচালনা করবে, তবে প্রয়োজন ব্যাতীত রান করবেনা।
✅ এমকিউটিটি-তে বার্তা গ্রহণের জন্য যে কোডটিকে সার্ভার কোড হিসাবে লিখেছি, সেটির দিকে আরেকবার লক্ষ্য করা যাক! কীভাবে এটি সার্ভারলেস ব্যবহার করে ক্লাউডে চলতে পারে? কীভাবে পরিবর্তন করলে, এই কোডটি সার্ভারলেস কম্পিউটিং সাপোর্ট করতে পারে?
> 💁 সার্ভারলেস মডেল কোড রান করার পাশপাশি কিছু বিষয়ে অন্যান্য ক্লাউড পরিষেবার দিকে যাচ্ছে। উদাহরণস্বরূপ, সার্ভারহীন ডাটাবেসগুলি ক্লাউডে পাওয়া যাচ্ছে যেখানে ডাটাবেসে পাঠানো রিকুয়েস্টের সংখ্যা অনুসারে ফী প্রদান করতে হবে, যেমন একটি query বা row যুক্ত করা, তবে সাধারণত কতটা কাজ করা হচ্ছে তার ভিত্তিতে মূল্য নির্ধারণ করা হয়। উদাহরণস্বরূপ, প্রাইমারি কী এর ভিত্তিতে একটি সারি সিলেক্ট করা হলে, তার খরচ অনেক কম হবে - অনেকগুলো টেবল যোগ করে একটি জটিল কাজ করার তুলনায়।
## একটি সার্ভারলেস অ্যাপ্লিকেশন তৈরি করা
মাইক্রোসফটের সার্ভারলেস অ্যাপ্লিকেশন কে বলা হয় Azure Function ।
![The Azure Functions logo](../../../../images/azure-functions-logo.png)
নীচের সংক্ষিপ্ত ভিডিওটিতে অ্যাজুর ফাংশনগুলির একটি ওভারভিউ রয়েছে
[![Azure Functions overview video](https://img.youtube.com/vi/8-jz5f_JyEQ/0.jpg)](https://www.youtube.com/watch?v=8-jz5f_JyEQ)
> 🎥 ভিডিও দেখতে উপরের ছবিতে ক্লিক করতে হবে
✅ এই পর্যায়ে একটু সময় নিয়ে কিছু পড়াশোনা করা উচিত। আর অ্যাজুর ফাংশন এর ব্যপারে জানতে হলে [Microsoft Azure Functions documentation](https://docs.microsoft.com/azure/azure-functions/functions-overview?WT.mc_id=academic-17441-jabenn) পড়া একটি ভালো উপায়।
অ্যাজুর ফাংশন লিখতে হলে, আমাদের পছন্দমতো কোন ল্যাংগুয়েজে অ্যাজুর ফাংশন এপ এ কাজ করা শুরু করতে হবে। Python, JavaScript, TypeScript, C#, F#, Java, এবং Powershell খুবসহজেই ব্যবহার করা যায়। এই অধ্যায়ে আমরা পাইথন ব্যবহার করা অ্যাজুর ফাংশন এপ লেখা শিখবো।
> 💁 অ্যাজুর ফাংশন আবার কাস্টম হ্যান্ডলারও সাপোর্ট করে, তাই যেকোন ভাষায় এমনকি COBOLএর মতো পুরনো ল্যাঙ্গুয়েজেও তা লেখা যায়, যদি HTTP রিকোয়েস্ট সাপোর্ট করে।
ফাংশন অ্যাপ্লিকেশনগুলিতে এক বা একাধিক *ট্রিগার* থাকে - এমন ক্রিয়াকলাপ যা ইভেন্টগুলিতে প্রতিক্রিয়া জানায়। আমাদের একটি ফাংশন অ্যাপ্লিকেশনের মধ্যে একাধিক ট্রিগার থাকতে পারে, সাধারণ একটি কনফিগারেশন নিয়েই। উদাহরণস্বরূপ, ফাংশন অ্যাপ্লিকেশনটির জন্য কনফিগারেশন ফাইলে আইওটি হাবের সংযোগের সকল তথ্য থাকতে পারে এবং অ্যাপ্লিকেশনটি্র সমস্ত ফাংশন এটি সংযোগ করতে এবং ইভেন্টগুলির তথ্য গ্রহণে এটি ব্যবহার করতে পারে
### কাজ - Azure Functions tooling ইন্সটল করা
অ্যাজুর ফাংশনগুলির একটি দুর্দান্ত বৈশিষ্ট্য হল এগুলি আমরা লোকালি চালাতে পারি। ক্লাউডের সমান রানটাইমে এটি আমাদের কম্পিউটারে চালানো যেতে পারে, যা আমাদেরকে আইওটি বার্তাগুলির প্রতিক্রিয়া জানায় এবং লোকালি চলতে পারে এমন কোড লেখার সুযোগ দেয়। এমনকি ইভেন্টগুলি হ্যান্ডেল হওয়ার সাথে সাথে আমরা নিজের কোডটি ডিবাগ করতে পারব। একবার কোড নিয়ে সন্তুষ্ট হলেই, এটি আমরা ক্লাউডে স্থাপন করতে পারবো।
Azure Functions tooling আমরা CLI এর মাধ্যমে ব্যবহার করতে পারি যাকে Azure Functions Core Tools ও বলা হয়।
1. Azure Functions Core Tools ইনস্টল করার জন্য [Azure Functions Core Tools documentation](https://docs.microsoft.com/azure/azure-functions/functions-run-local?WT.mc_id=academic-17441-jabenn) নির্দেশাবলী অনুসরণ করি।
1. VS Code এ Azure Functions extension ইন্সটল করতে হবে। এই এক্সটেনশনে মাধ্যমে Azure functions তৈরী, ডিবাগ এবং ডেপ্লয় করা যাবে। প্রয়োজনীয় নির্দেশনা [Azure Functions extension documentation](https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-azurefunctions&WT.mc_id=academic-17441-jabenn) এ রয়েছে।
আমরা যখন ক্লাউডে অ্যাজুর ফাংশন অ্যাপ্লিকেশন শুরু করবো, তখন অ্যাপ্লিকেশন ফাইল এবং লগ ফাইলের মতো জিনিসগুলি সেভ রাখতে খুব অল্প পরিমাণে ক্লাউড স্টোরেজ ব্যবহার করা দরকার। যখন লোকালি আমরা ফাংশন অ্যাপ্লিকেশন চালাই তখন আমাদেরকে ক্লাউড স্টোরেজের সাথে সংযোগ স্থাপন করতে হবে, তবে প্রকৃত ক্লাউডের স্টোরেজ ব্যবহারের পরিবর্তে একটি স্টোরেজ এমুলেটর ব্যবহার করতে হবে যেমন [Azurite](https://github.com/Azure/Azurite)। এটি লোকাল ভাবে চলে, তবে ক্লাউড স্টোরেজের মতো কাজ করে।
> 🎓 অ্যাজুরে, অ্যাজুর ফাংশনগুলি যে স্টোরেজ ব্যবহার করে তা একটি অ্যাজুর স্টোরেজ অ্যাকাউন্ট। এই অ্যাকাউন্টগুলি ফাইল, ব্লবস, টেবিলগুলিতে ডেটা সংরক্ষণ করতে পারে। এখানে চাইলেই অনেকগুলি অ্যাপ্লিকেশনের মধ্যে একটি স্টোরেজ অ্যাকাউন্ট ভাগ করা যায় যেমন একটি ফাংশন অ্যাপ এবং একটি ওয়েব অ্যাপ্লিকেশনে একই স্টোরেজ ব্যবহার করা।
1. Azurite হলো একটি Node.js এপ। তাই এটির জন্য আগে Node.js ইন্সটল করতে হবে [Node.js website](https://nodejs.org/)এ সকল নির্দেশনা আছে। ম্যাক ব্যবহারকারীরা [Homebrew](https://formulae.brew.sh/formula/node) থেকেও ইন্সটল করতে পারবে।
1. নিচের কমান্ড ব্যবহার করে Azurite ইন্সটল করি :
```sh
npm install -g azurite
```
1. `azurite` নামে ফোল্ডার খুলি, এটির ডেটা স্টোর করার জন্য
```sh
mkdir azurite
```
1. Azurite রান করি -
```sh
azurite --location azurite
```
Azurite স্টোরেজ ইম্যুলেটর launch হয়ে লোকাল ফাংশন রানটাইমের জন্য অপেক্ষা করবে
```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
```
### কাজ - একটি অ্যাজুর ফাংশন প্রজেক্ট তৈরি
Azure Functions CLI দ্বারা নতুন Functions app তৈরী করা যাবে
1. ফাংশন এপ এর জন্য ফোল্ডার খুলে সেখানে যাই, নাম দিই `soil-moisture-trigger`
```sh
mkdir soil-moisture-trigger
cd soil-moisture-trigger
```
1. ফোল্ডারে পাইথন ভার্চুয়াল এনভায়রনমেন্ট তৈরী করি
```sh
python3 -m venv .venv
```
1. ভার্চুয়াল এনভায়রনমেন্ট এক্টিভেট করি
* উইন্ডোজে:
```cmd
.venv\Scripts\activate.bat
```
* macOS বা Linux এ:
```cmd
source ./.venv/bin/activate
```
1. এই ফোল্ডারে Functions app তৈরীর জন্য নিম্নের কমান্ড রান করি:
```sh
func init --worker-runtime python soil-moisture-trigger
```
এটি বর্তমান ফোল্ডারের ভিতরে তিনটি ফাইল তৈরি করবে:
* `host.json` - এই JSON ডকুমেন্টে ফাংশন অ্যাপ্লিকেশনের জন্য সেটিংস রয়েছে। এই সেটিংস পরিবর্তন করতে হবে না।
* `local.settings.json` - এই JSON ডকুমেন্টে লোকালি চলাকালীন আমাদের অ্যাপ্লিকেশন যে সেটিংস ব্যবহার করবে সেগুলি আছে, যেমন আইওটি হাবের জন্য সংযোগ স্ট্রিং । এই সেটিংসটি কেবল লোকাল, এবং সোর্স কোড নিয়ন্ত্রণে যুক্ত করা উচিত নয়। আমরা যখন ক্লাউডে অ্যাপ স্থাপন করব তখন এই সেটিংসটি স্থাপন করা হবে না, এর পরিবর্তে আমাদের সেটিংস অ্যাপ্লিকেশন সেটিংস থেকে লোড হবে। এই পাঠের পরবর্তী অংশে বিষয়টি আলোচনা করা হবে।
* `requirements.txt` - এটি একটি [Pip requirements file](https://pip.pypa.io/en/stable/user_guide/#requirements-files) যা প্রয়োজনীয় পিপ ফাইলগুলো ধারণ করে।
1. এখানে `local.settings.json` ফাইলটির স্টোরেজ অ্যাকাউন্টের জন্য একটি সেটিংস রয়েছে যা অ্যাপ্লিকেশন ব্যবহার করবে। এটির ডিফল্ট হিসেবে একটি ফাঁকা সেটিং আছে, সুতরাং এটি সেট করা দরকার। Azurite স্থানীয় স্টোরেজ এমুলেটর সাথে সংযোগ করতে, এই মানটি নিম্নলিখিত ভাবে সেট করতে হবে:
```json
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
```
1. প্রয়োজনীয় ফাইলগুলি ব্যবহার করে পিপ প্যাকেজ ইনস্টল করতে হবে:
```sh
pip install -r requirements.txt
```
> 💁 প্রয়োজনীয় পিপ প্যাকেজগুলি এই ফাইলে থাকা দরকার, যাতে ফাংশন অ্যাপ্লিকেশনটি যখন ক্লাউডে স্থাপন করা হবে, তখন রানটাইম যেন এটি নিশ্চিত করতে পারে যে সঠিক প্যাকেজগুলি ইনস্টল হয়েছে।
1. সবকিছু সঠিকভাবে কাজ করছে তা পরীক্ষা করতে আমরা ফাংশন রানটাইম শুরু করতে পারি। এটি করার জন্য নিম্নলিখিত কমান্ডটি রান দিই:
```sh
func start
```
দেখা যাবে যে রানটাইম শুরু হয়েছে কিন্তু তা রিপোর্ট করবে যে এটি কোন জব ফাংশন (ট্রিগার) খুঁজে পায় নি।
```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.
```
> ⚠️ কোন ফায়ারওয়াল নোটিফিকেশন আসলে, একসেস দিতে হবে কারণ `func` এপ্লিকেশনটির এই নেটওয়ার্কে কাজ করতে হবে।
> ⚠️ ম্যাক-ওএস ব্যবহারকারীদের আউটপুটটিতে ওয়ার্নিং থাকতে পারে:
>
> ```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.
> ```
>
> যতক্ষণ ফাংশন অ্যাপ্লিকেশনটি সঠিকভাবে শুরু হচ্ছে এবং চলমান ফাংশনগুলির তালিকা ঠিকভাবে দেখাচ্ছে, ততক্ষণ এসব উপেক্ষা করা যায়। এখানে [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) তেও এমনই বলা হয়েছে।
1. এবার `ctrl+c` ব্যবহার করে Functions app বন্ধ করি।
1. VS Code এ বর্তমান ফোল্ডারটি ওপেন করি:
```sh
code .
```
ভিএস কোড আমাদের ফাংশন প্রজেক্ট সনাক্ত করে একটি নোটিফিকেশন দেখিয়ে বলবে:
```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?
```
![The notification](../../../../images/vscode-azure-functions-init-notification.png)
এখানে **Yes** সিলেক্ট করতে হবে।
1. ভিএস কোড টার্মিনালে ভার্চুয়াল এনভায়রনমেন্ট রান করছে - এটি নিশ্চিত করতে হবে
## একটি আইওটি হাব ইভেন্ট ট্রিগার তৈরি করা
ফাংশন অ্যাপ্লিকেশন হলো আমাদের সার্ভারলেস কোডের শেল। আইওটি হাব ইভেন্টগুলির প্রতিক্রিয়া জানাতে, এই অ্যাপ্লিকেশনটিতে একটি আইওটি হাব ট্রিগার যুক্ত করা যায়। এই ট্রিগারটি আইওটি হাবে আসা বার্তাপ্রবাহের সাথে সংযুক্ত থাকা দরকার এবং তাদের প্রতিক্রিয়া জানানোর সক্ষমতা অর্জন করতে হবে। নিয়মিতভাবে বার্তা পেতে আমাদের ট্রিগারটি আইওটি হাবে *event hub compatible endpoint* এর সাথে সংযোগ স্থাপন করা দরকার।
আইওটি হাবটি Azure Event Hubs নামে পরিচিত আরেকটি অ্যাজুর সার্ভিসের সাথে যুক্ত। ইভেন্ট হাবস এমন একটি পরিষেবা যা আমাদেরকে বার্তা প্রেরণ এবং গ্রহণ করতে দেয়, আইওটি হাবটি তখন আইওটি ডিভাইসের জন্য অতিরিক্ত বৈশিষ্ট্য যুক্ত করতে পারে। আইওটি হাব থেকে যেভাবে আমরা বার্তা গ্রহণ করেছি, ইভেন্ট হাবেও একদম একইভাবে ব্যবহার করা যায়।
✅ কিছু গবেষণা করা যাক: [Azure Event Hubs documentation](https://docs.microsoft.com/azure/event-hubs/event-hubs-about?WT.mc_id=academic-17441-jabenn) থেকে ইভেন্ট হাব সম্পর্কে একটি সামগ্রিক ধারণা লাভ করে, এটির সাধারণ পর্যায়ের বৈশিষ্ট্যগুলোকে আইওটি হাবের সাথে তুলনা করি।
আইওটি হাবের সাথে সংযোগ স্থাপনের জন্য যেকোন আইওটি ডিভাইসকে একটি গোপন কী ব্যবহার করতে হবে যা কেবলমাত্র অনুমোদিত ডিভাইসগুলি সংযোগ করতে পারে। বার্তাগুলি পড়ার জন্য সংযোগ করার সময়ও একই বিষয় প্রযোজ্য, আমাদের কোডটিতে আইওটি হাবের বিবরণ সহ একটি গোপন কী যুক্ত connection string প্রয়োজন হবে।
> 💁 আমরা ডিফল্ট যে connection string পাই, সেটিতে **iothubowner** এর পার্মিশন থাকে যা কোন কোডে থাকলে - সম্পূর্ণ আইওটি হাবে একসেস/অনুমতি প্রদান করে। এটিকে আসলে আমাদের প্রয়োজনীয় অনুমতিগুলির সর্বনিম্ন স্তরে অর্থাৎ কম পার্মিশনে রাখা উচিত। পরবর্তী পাঠে এটি নিয়ে বিষদ আলোচনা হবে।
ট্রিগারটি একবার সংযুক্ত হয়ে গেলেই, আইওটি হাবের কাছে প্রেরিত প্রতিটি বার্তার জন্য - ফাংশনের কোডটি কল করা হবে,তা সেই ম্যাসেজ যে ডিভাইস থেকেই প্রেরিত হোক না কেন।
### কাজ - Event Hub compatible endpoint connection string তৈরী
1. VS Code টার্মিনাল থেকে নিম্নের কমান্ড রান করি:
```sh
az iot hub connection-string show --default-eventhub \
--output table \
--hub-name <hub_name>
```
এখানে `<hub_name>` এর পরিবর্তে আমাদের ব্যবহৃত হাবের নামটি ব্যবহার করতে হবে।
1. এবার VS Code এ `local.settings.json` ফাইলটি ওপেন করে, `Values` অংশের নিম্নের অতিরিক্ত ভ্যালুগুলো যোগ করি:
```json
"IOT_HUB_CONNECTION_STRING": "<connection string>"
```
এখানে আগের স্টেপ থেকে পাওয়া ভ্যালু্টি `<connection string>` এর জায়গায় বসাই। JSON ফাইলটি সঠিকভাবে তৈরী করতে আমাদেরকে উপরের লাইনের পরে কমা যুক্ত করতে হবে।
### কাজ - ইভেন্ট ট্রিগার তৈরী
আমরা এখন ইভেন্ট ট্রিগার তৈরী করার কাজ শুরু করতে পারি।
1. এখন `soil-moisture-trigger` ফোল্ডার থেকে VS Code terminal চালু করে নিম্নের কমান্ড রান করি:
```sh
func new --name iot-hub-trigger --template "Azure Event Hub trigger"
```
এটি `iot-hub-trigger` নামে নতুন একটি ফাংশন তৈরী করবে। এই ট্রিগারটি Event Hub compatible endpoint এর সাথে সংযুক্ত হবে। এখন আমরা ইভেন্ট হাব ট্রিগার নিয়ে কাজ করতে পারবো।
এখন দেখা যাবে `soil-moisture-trigger` ফোল্ডারের ভেতরে `iot-hub-trigger` নামে আরেকটি ফোল্ডার তৈরী হবে যেটিতে ফাংশন রয়েছে। এই ফোল্ডারে নিম্নলিখিত ফাইলগুলো থাকবে:
* `__init__.py` - এই পাইথন ফাইলে ট্রিগার রয়েছে এবং এটিকে মডিউল হিসাবে ব্যবহারযোগ্য করার জন্য সাধারণ নীতি অনুসারে এভাবে নামকরণ করা হয়েছে।
এই ফাইলে অন্তর্ভুক্ত কোড:
```python
from typing import List
import logging
import azure.functions as func
def main(events: List[func.EventHubEvent]):
for event in events:
logging.info('Python EventHub trigger processed an event: %s',
event.get_body().decode('utf-8'))
```
এই ট্রিগারের মূল চাবিকাঠি রয়েছে `main` ফাংশনে । আইওটি হাব থেকে ইভেন্টের সাথে এই ফাংশনকেই কল করা হয়। ফাংশনটিতে `events` নামে একটি প্যারামিটার রয়েছে যেটিতে `EventHubEvent` লিস্ট রয়েছে। এই লিস্টের প্রতিটি ইভেন্ট মূলত আইওটি হাবে পাঠানো এক একটি ম্যাসেজ যাতে এনোটেশনের মত প্রপার্টিও অন্তর্ভূক্ত থাকে যেমনটা আমরা গত লেসনে দেখেছি।
এই ট্রিগারটি প্রতিটি ইভেন্ট একটি একটি করে নয়, বরং অনেকগুলো ইভেন্টের একটি লিস্ট একসাথে নিয়ে কাজ করে। যখন প্রথমবার ট্রিগার রান করা হয়, তখন এটি আইওটি হাবের অসমাপ্ত ইভেন্টগুলোর কাজ আগে সমাপ্ত করে। তারপর যদি খুব অল্প সময়ের ভেতরে হাবে অনেকগুলো ইভেন্ট পাঠানো না হয়, তাহলে এটি একটি ইভেন্ট সম্বলিত লিস্ট নিয়ে কাজ শুরু করে দিবে।
এই ফাংশন মূলত লিস্ট ধরে কাজ করে এবং ইভেন্টগুলো নথিবদ্ধ রাখে।
* `function.json` - এটিতে ট্রিগারের কনফিগারেশন থাকে যা মূলত `bindings` অংশে আমরা দেখি। বাইন্ডিং হলো মূলত Azure Functions এবং অন্যান্য Azure services এর মধ্যকার সংযোগ। এটিতে input binding থাকে, কোন একটি ইভেন্ট হাবের জন্য - যা ইভেন্ট হাবের সাথে সংযুক্ত হয় এবং ডেটা গ্রহণ করে।
> 💁 এছাড়াও আমরা আউটপুট বাইন্ডিং ব্যবহার করতে পারি যা কোন ফাংশনের আউটপুটকে আরেকটি ডিভাইসে প্রেরণ করতে পারে। যেমন, কোন ডেটাবেসের সাথে আউটপুট বাইন্ডিং যোগ করে ফাংশন দ্বারা আইওটি হাবের সাথে রিটার্ন করতে দিলে - সকল ডেটা স্বংক্রিয়ভাবেই সেই ডেটাবেস এ চলে আসবে।
✅ এবার কিছু গবেষণা করা যাক: বাইন্ডিংস নিয়ে [Azure Functions triggers and bindings concepts documentation](https://docs.microsoft.com/azure/azure-functions/functions-triggers-bindings?tabs=python&WT.mc_id=academic-17441-jabenn)পড়ে আরো জেনে নিই এই বিষয়ে ।
`bindings` অংশে এর কনফিগারেশনগুলো রয়েছে। এর গুরুত্বপূর্ণ কিছু ভ্যালু হলো :
* `"type": "eventHubTrigger"` - এটির অর্থ হলো ফাংশনকে ইভেন্ট হাব থেকে ইভেন্টের ডেটা গ্রহণ করতে হবে।
* `"name": "events"` - এই প্যারামিটারটি ইভেন্ট হাবের ইভেন্টের জন্য ব্যবহৃত হয়। এটি পাইথন কোডের `main` function এর সাথে প্যারামিটার মিলিয়ে কাজ করে।
* `"direction": "in"` - এটি ইনপুট বাইন্ডিং, যেখানে ইভেন্ট হাব থেকে ফাংশনে ডেটা আসে।
* `"connection": ""` - কানেকশন স্ট্রিং থেকে ডেটা গ্রহণের যে সেটিং - সেটির সংজ্ঞা নির্ধারণ করে। লোকালি রান করলে, সেটি `local.settings.json` ফাইল থেকে সেটিংস রীড করে।
> 💁 এই connection string কিন্তু `function.json` ফাইলে স্টোর করা যাবেনা, এটি সেটিংস থেকেই রীড করতে হবে। এটি এভাবে সাজানো হয়েছে যাতে আকস্মিকভাবে কানেকশন স্ট্রিং প্রকাশিত হয়ে না যায়।
1. `"connection"` এর ভ্যালু `function.json` ফাইল থেকে নিতে হবে যাতে নতুন ভ্যালুগুলো `local.settings.json` ফাইলে থাকে:
```json
"connection": "IOT_HUB_CONNECTION_STRING",
```
> 💁 মনে রাখতে হবে - এটি যেন সেটিংস এ পয়েন্ট করে, এবং কানেকশন স্ট্রিং যেন এখানে না থাকে।
### কাজ - ইভেন্ট ট্রিগার রান করা
1. এটা নিশ্চিত করতে হবে যে আমরা যেন আইওটি হাব ইভেন্ট মনিটরে রান না করি। এটি এবং ফাংশন এপ্লিকেশন যদি একসাথে রান করে, তবে ফাংশন এপ যথাযথভাবে ইভেন্টের সাথে সঠিকভাবে কানেক্ট হতে পারবেনা, ফলে ইভেন্টের ডেটাও ঠিকমতো পাওয়া যাবেনা।
> 💁 একাধিক এপ্লিকেশন এখানে বিভিন্ন *consumer groups* ব্যবহার করে আইওটি হাব এন্ডপয়েন্টের সাথে যুক্ত হবে। এই সংক্রান্তে আরো বিস্তারিত আমরা পরবর্তী একটি অধ্যায়ে জানবো।
1. Functions app রান করার জন্য, VS Code terminal থেকে নিম্নের কোডগুলো রান দিই
```sh
func start
```
ফাংশন এপ চালু হয়ে, `iot-hub-trigger` ফাংশনটি খুঁজে নিবে । তারপর এটি আগে থেকেই আইওটি হাবে আসা ইভেন্টসমূহ প্রসেস করবে।
```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: PartionId: 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)
```
এই ফাংশনের প্রতিটি কলে `Executing 'Functions.iot-hub-trigger'` অথবা `Executed 'Functions.iot-hub-trigger'` ব্লকগুলো আউটপুটে আসবে। এতে করে আমরা জানতে পারবো প্রতিটি ফাংশন কলে কতটি ম্যাসেজ প্রসেস করা হয়েছে।
> যদি নিচের এই এররটি আসে:
```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.
```
তাহলে, এটা দেখতে হবে যে Azurite চলছে কিনা এবং আমরা `local.settings.json`ফাইলে `AzureWebJobsStorage` কে `UseDevelopmentStorage=true` করেছি কিনা সেই বিষয়টিও আমাদের নিশ্চিত করতে হবে।
1. এখন আমাদেরকে আমাদের আইওটি ডিভাইস চলছে কিনা খেয়াল রাখটে হবে এবং দেখতে পাব যে ফাংশন এপ এ মাটির আর্দ্রতার নতুন মানগুলো দেখাচ্ছে।
1. Functions app বন্ধ করে তা Restart করি। দেখা যাবে এটি আর আগের ম্যাসেজগুলো প্রসেস করছেনা, কেবল নতুন ম্যাসেজগুলো নিয়েই কাজ করছে।
> 💁 VS Code থেকেই ফাংশন ডিবাগ করা যায়। প্রতিটি লাইনের শুরুতে বর্ডারের অংশে ক্লিক করে অথবা কার্সরকে কোন লাইনে রেখে তারপর *Run -> Toggle breakpoint* এ গিয়ে বা `F9` প্রেস করার মাধ্যমে ব্রেকপয়েন্ট সেট করা যায়। এছাড়াও ডিবাগার launch করার জন্য *Run -> Start debugging* এ গিয়ে বা `F5` প্রেস করে অথবা আমরা *Run and debug* এ গিয়ে **Start debugging** এ ক্লিক করতে হবে। এখান থেকে ইভেন্ট প্রসেসিং এর ডিটেইলস জানা যাবে।
## সার্ভারলেস কোড থেকে ডিরেক্ট মেথড রিকুয়েস্ট পাঠানো
এখন পর্যন্ত আমাদের ফাংশন অ্যাপ্লিকেশনটি আইওটি হাব থেকে ইভেন্ট হাবের সামঞ্জস্যপূর্ণ এন্ড পয়েন্টটি ব্যবহার করে ডেটা গ্রহণ করছে। আমাদেরকে এখন আইওটি ডিভাইসে কমান্ড প্রেরণ করতে হবে। এটি *রেজিস্ট্রি ম্যানেজার* এর মাধ্যমে আইওটি হাবের সাথে একটি আলাদা সংযোগ দ্বারা করা হয়। রেজিস্ট্রি ম্যানেজার এমন একটি ট্যুল যা আমাদেরকে আইওটি হাবের সাথে কী কী ডিভাইসগুলি নিবন্ধভুক্ত রয়েছে তা দেখতে এবং ডিভাইসগুলোর সাথে যোগাযোগ করার জন্য ক্লাউড থেকে ডিভাইসে ম্যাসেজ পাঠানোর সুযোগ দেয়। এক্ষেত্রে direct method requests বা ডিভাইস টুইন আপডেট করার মাধ্যমে তা করা হয়। এছাড়াও আমরা এটি দ্বারা আইওটি হাব থেকে আইওটি ডিভাইসগুলি নিবন্ধকরণ, আপডেট করতে বা ডিলিট করতে পারবো।
Registry Manager এর সাথে কানেক্ট করার জন্য Connection String দরকারঃ
### কাজ - Registry Manager এর জন্য connection string নেয়া
1. নিচের কমান্ড রান করি:
```sh
az iot hub connection-string show --policy-name service \
--output table \
--hub-name <hub_name>
```
এখানে `<hub_name>` এর জায়গায় আমাদের ব্যবহৃত নামটি বসাই।
*ServiceConnect* পলিসির `--policy-name service` প্যারামিটারের মাধ্যমে কানেকশন স্ট্রিং চাওয়া হয়েছে। আমরা যখন connection string এর রিকুয়েস্ট করি, পার্মিশনগুলো প্রয়োজনমতো ঠিক করতে পারবো। এখানে ServiceConnect পলিসি আইওটি ডিভাইসে কানেক্ট করে ম্যাসেজ পাঠানোর সুযোগ দেয়।
✅ কিছু গবেষণা করা যাক: [IoT Hub permissions documentation](https://docs.microsoft.com/azure/iot-hub/iot-hub-devguide-security#iot-hub-permissions?WT.mc_id=academic-17441-jabenn) থেকে বিভিন্ন পলিসি সম্পর্কে জানতে হবে।
1. VS Code এ `local.settings.json` ফাইলটি ওপেন করি। তারপর `Values` অংশে নিচের ব্যালুগুলো যোগ করি:
```json
"REGISTRY_MANAGER_CONNECTION_STRING": "<connection string>"
```
এখানে আগের স্টেপ থেকে পাওয়া ভ্যালু্টি `<connection string>` এর জায়গায় বসাই। JSON ফাইলটি সঠিকভাবে তৈরী করতে আমাদেরকে উপরের লাইনের পরে কমা যুক্ত করতে হবে।
### কাজ - ডিভাইসে direct method request পাঠানো
1. Registry Manager এর SDK সহজেই Pip package এর মাধ্যমে পাওয়া যাবে। `requirements.txt` ফাইলে নিচের লাইনগুলো যোগ করি প্যাকেজের ডিপেন্ডেন্সি এড করার জন্য:
```sh
azure-iot-hub
```
1. Pip package ইন্সটল করার জন্য এটি নিশ্চিত করতে হবে যে আমরা virtual environment এক্টিভেট করেই ভিএস কোডে কাজ করছি :
```sh
pip install -r requirements.txt
```
1. `__init__.py` ফাইলে নিচের ইম্পোর্টগুলো যুক্ত করি:
```python
import json
import os
from azure.iot.hub import IoTHubRegistryManager
from azure.iot.hub.models import CloudToDeviceMethod
```
এটি কিছু সিস্টেম লাইব্রেরি এবং Registry Manager সাথে ইন্টারঅ্যাক্ট করতে এবং direct method requests প্রেরণের জন্য আরো কিছু লাইব্রেরি ইম্পোর্ট করে।
1. `main` মেথড থেকে কোডগুলো সরিয়ে ফেলি, তবে মেথডটি রাখতে হবে।
1. যখন একাধিক বার্তা গৃহীত হয়, কেবলমাত্র শেষেরটিকেই এটি প্রসেস করে কারণ এটি হল বর্তমান সময়ে মাটির আর্দ্রতা। এটির আগে থেকে আসা বার্তাগুলি প্রক্রিয়া করা নিষ্প্রয়োজন। এক্ষন `events` প্যারামিটার থেকে সর্বেশেষ ম্যাসেজ পেতে হলে নিচের কোডগুলো যুক্ত করতে হবে:
```python
event = events[-1]
```
1. তারপর নিম্নের কোডগুলো যুক্ত করি:
```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}')
```
এই কোডটি আইওটি ডিভাইস থেকে আসা JSON ম্যাসেজের যে ইভেন্ট বডি রয়েছে তা সংগ্রহ করে।
তারপর এটি ম্যাসেজের সাথে আসা এনোটেশন থেকে ডিভাইস আইডি পেয়ে যায়। ইভেন্টের বডি তে টেলিমেট্রি হিসেবে আসা ম্যাসেজগুলো, `iothub_metadata` ডিকশনারি যেটিতে আবার প্রেরক (Sender) এর ডিভাইস আইডি এবং সময় উল্লেখিত থাকে।
সকল তথ্য সংরক্ষিত (logged) থাকে। Function app কে লোকালি রান করলে এই সংরক্ষণের বিষয়টি (logging) টার্মিনালে দেখা যাবে।
1. তারপর নিচের কোডগুলো যুক্ত করি:
```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='{}')
```
এই কোডটি ম্যাসেজ থেকে মাটির আর্দ্রতা পায়। তারপর এটি মাটির আর্দ্রতা চেক করে এবং আর্দ্রতার মানের উপর নির্ভর করে একটি helper class তৈরী করে direct method request পাঠানোর জন্য যেখানে `relay_on` বা `relay_off` করা যাবে। এটিতে payload এর প্রয়োজন নেই, তাই একটি ফাঁকা JSON document পাঠানো যাবে।
1. নিচের কোড যুক্ত করি:
```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)
```
এই কোডটি `local.settings.json` ফাইল থেকে `REGISTRY_MANAGER_CONNECTION_STRING` ওপেন করবে। এই ফাইলের ভ্যালুগুলো এনভায়রনমেন্ট ভ্যারিয়েবল হিসেবে প্রদর্শন করা হয় এবং এগুলো `os.environ` ফাংশন (সকল এনভায়রনমেন্ট ভ্যারিয়েবল ডিকশনারি) দ্বারা ব্যবহারযোগ্য করা যায় ।
> 💁 এই কোডটি ক্লাউডে চলতে থাকলে,`local.settings.json` এর ভ্যালুগুলো *Application Settings* হিসেবে পাঠানো হয় যা এনভায়রনমেন্ট ভ্যারিয়েবল থেকে ব্যবহার করা যায়।
কোডটি পরে সংযোগ স্ট্রিংটি ব্যবহার করে রেজিস্ট্রি ম্যানেজার হেল্পার ক্লাসের একটি পরিস্থিতি তৈরি করে।
1. নিম্নের কোড যোগ করি:
```python
registry_manager.invoke_device_method(device_id, direct_method)
logging.info('Direct method request sent!')
```
এই কোডটি রেজিস্ট্রি ম্যানেজারকে টেলিমেট্রি প্রেরণকারী ডিভাইসে direct method request প্রেরণ করার নির্দেশ দেয়।
> 💁 এমকিউটিটি ব্যবহার করে আমাদের পূর্ববর্তী পাঠগুলিতে তৈরি করা অ্যাপ্লিকেশনগুলির সংস্করণগুলিতে, রিলে নিয়ন্ত্রণ কমান্ডগুলি সমস্ত ডিভাইসে প্রেরণ করা হয়েছিল। কোড ধরে নিয়েছে যে আমাদের কেবল একটি ডিভাইস থাকবে। কোডটির এই সংস্করণটি কোন একটিমাত্র ডিভাইসে রিকুয়েস্ট প্রেরণ করে, তাই আমাদের যদি আর্দ্রতা সেন্সর এবং রিলে এর একাধিক সেটআপ থাকে, তবে এটি সঠিক ডিভাইসে সংযুক্ত হয়ে কাজ করবে।
1. Functions app রান করে এটি নিশ্চিত করতে হবে যে IoT device ডেটা পাঠাচ্ছে। আমরা দেখতে পাব যে ম্যাসেজগুলো প্রসেস হচ্ছে এবং ডিরেক্ট মেথড রিকুয়েস্ট পাঠানো হচ্ছে। সেন্সরটি নাড়ালেই আমরা ভ্যালু চেঞ্জ হতে দেখব এবং রিলে তেও এই পরিবর্তন আসবে।
> 💁 সকল কোড [code/functions](code/functions) ফোল্ডারে রয়েছে।
## ক্লাউডে সার্ভারলেস কোড ডেপ্লয় করা
আমাদের কোডটি এখন লোকালি কাজ করছে, তাই পরবর্তী পদক্ষেপে আমরা ক্লাউডে ফাংশন অ্যাপ স্থাপন করব।
### কাজ - ক্লাউড রিসোর্স তৈরী
আমাদের ফাংশন অ্যাপটি কে একটি Azure Functions App রিসোর্সে ডেপ্লয় করতে হবে,যা আমাদের আইওটি হাবে তৈরী করা রিসোর্স গ্রুপে থাকবে। এছাড়াও ইম্যুলেটেড এর পরিবর্তে আমাদের একটি স্টোরেজ একাউন্ট প্রয়োজন।
1. স্টোরেজ একাউন্ট তৈরীর জন্য নিম্নের কমান্ড রান দিই:
```sh
az storage account create --resource-group soil-moisture-sensor \
--sku Standard_LRS \
--name <storage_name>
```
এখানে `<storage_name>` এর জায়গায় আমাদের স্টোরেজ একাউন্টের নাম দিতে হবে। এটি গ্লোবালি ইউনিক হতে হবে কেননা এটি URL হিসেবেও ব্যবহৃত হবে। এটির নাম ২৪ ক্যারেক্টারের মধ্যে হতে হবে এবং এখানে ছোট হাতের (lower case) ইংরেজি বর্ণ এবং সংখ্যা ব্যবহার করা যাবে। নাম হিসেবে `sms` এর সাথে কোন সংখ্যা বা নাম লেখা যেতে পারে।
এখানে `--sku Standard_LRS` -ই মূল্যমান নির্ধারণ করে যা এক্ষেত্রে সর্বনিম্ন দামের জেনারেল পারপাস একাউন্ট সিলেক্ট করছে। এখানে কোন ফ্রী সার্ভিস নেই এবং আমাদেরকে ব্যবহার অনুসারে ফী দিতে হবে। তবে এখানে খরচ বেশ কম, সবথেকে দামি সার্ভিসও .০৫ মার্কিন ডলার প্রতি মাসে প্রতি গিগাবাইটের জন্য।
✅ মূল্যমানের ব্যপারে [Azure Storage Account pricing page](https://azure.microsoft.com/pricing/details/storage/?WT.mc_id=academic-17441-jabenn) থেকে বিস্তারিত জানা যাবে।
1. ফাংশন এপ তৈরীর জন্য নিম্নের কমান্ড রান করি:
```sh
az functionapp create --resource-group soil-moisture-sensor \
--runtime python \
--functions-version 3 \
--os-type Linux \
--consumption-plan-location <location> \
--storage-account <storage_name> \
--name <functions_app_name>
```
`<location>` এর স্থলে আগের লেসনে রিসোর্স গ্রুপ তৈরীর সময় যে লোকেশন ব্যবহার করেছি, তা দিতে হবে।
এছাড়াও `<storage_name>` এর জায়গায় আগের অংশে ব্যবহৃত নামটিই দিতে হবে।
তারপর `<functions_app_name>` এও একটি ইউনিক নাম দিতে হবে। এটি গ্লোবালি ইউনিক হতে হবে কেননা ফাংশন এপ একসেস করার জন্য URL এ এটি ব্যবহৃত হবে। এখানে `soil-moisture-sensor-` বা এই ধরণের কিছুর পরে কোন শব্দ বা নাম দেয়া যেতে পারে।
এখানে `--functions-version 3` এই অপশনটি ব্যবহার্য Azure Functions এর ভার্সন ঠিক করে। ভার্সন-৩ ই হলো সর্বশেষ সংস্করণ।
আর `--os-type Linux` Functions runtime কে এই ফাংশনগুলো হোস্ট করার জন্য OS হিসেবে Linux ব্যবহারের নির্দেশ দেয়। Function গুলো প্রোগ্রামিং ভাষার উপর ভিত্তি করে, Linux বা Windows এ হোস্ট করা যাবে। পাইথন ভাষার এপ্লিকেশন হলে, তা কেবল Linux এই রান করবে।
### কাজ - Application settings আপলোড করা
যখন আমরা ফাংশন এপ গুলো তৈরী করি, তখন `local.settings.json` ফাইলে আইওটি হাবের কানেকশন স্ট্রিংয়ের জন্য কিছু সেটিংস স্টোর হয়। এই সেটিংস গুলো Azure এ ফাংশন এপ এর এপ্লিকেশন সেটিং এও আসতে হবে যাতে আমাদের কোড তা ব্যবহার করতে পারে।
> 🎓 `local.settings.json` ফাইলটি কেবল লোকাল ডেভলাপমেন্ট সেটিংস এর জন্য যা সোর্স কোড কন্ট্রোলেও চেক করা হয়না। যখন আমরা পুরো কার্যক্রম ক্লাউডে আনি, তখন এপ্লিকেশন সেটিংসই ব্যবহৃত হয়। এগুলো কী/ভ্যালু পেয়ার হিসেবে ক্লাউডে থাকে যা এনভায়রনমেন্ট ভ্যারিয়েবল থেকেও গ্রহণ করা যায় কোডের মাধ্যমে অথবা রানটাইমে যখন আইওটি হাবের সাথে যুক্ত করা হয়,তখন।
1. নিচের কমান্ড রান করে, `IOT_HUB_CONNECTION_STRING` সেটিংসটি ফাংশন এপ এর এপ্লিকেশন সেটিং এ ঠিক করি:
```sh
az functionapp config appsettings set --resource-group soil-moisture-sensor \
--name <functions_app_name> \
--settings "IOT_HUB_CONNECTION_STRING=<connection string>"
```
এক্ষেত্রে `<functions_app_name>` এর জায়গায় আমাদের ব্যবহৃত নামটি দিতে হবে।
আর `<connection string>` এর স্থলাভিষিক্ত হবে `IOT_HUB_CONNECTION_STRING` এর ভ্যালু যা আমরা `local.settings.json` ফাইল থেকে পাব।
1. পূর্ববর্তী ধাপটি পুনরায় করি, তবে `REGISTRY_MANAGER_CONNECTION_STRING` ভ্যালু সেট করতে হবে `local.settings.json` ফাইলের ভিত্তিতে।
আমরা যখন এই আদেশগুলি পরিচালনা করি, তখন এগুলো ফাংশন অ্যাপ্লিকেশনের জন্য সমস্ত অ্যাপ্লিকেশন সেটিংসের একটি তালিকা আউটপুট হিসেবে প্রকাশ করে। আমাদের মানগুলি সঠিকভাবে সেট করা আছে কিনা তা পরীক্ষা করতে আমরা এই সুবিধা কাজে লাগাতে পারি।
> 💁 আমরা `AzureWebJobsStorage` তে আগে থেকেই ভ্যালু সেট করা দেখবো। এক্ষেত্রে `local.settings.json` ফাইলে যা লোকাল স্টোরেজ ইম্যুলেটর ব্যবহারের জন্য সেট করা হয়েছে। আমরা যখন ফাংশন অ্যাপ তৈরী করি, তখন এই স্টোরেজ একাউন্টটি প্যারামিটার হিসেবে পাস করা হয় যা অটোমেটিক্যালি সেটিংস এ চলে আসে।
### কাজ - ক্লাউডে ফাংশন অ্যাপ ডেপ্লয় করা
এখন যেহেতু আমাদের ফাংশন অ্যাপ রেডি রয়েছে, আমরা তা ক্লাউডে ডেপ্লয় করতে পারবো।
1. VS Code terminal এ নীচের কমান্ড রান করে Functions App পাবলিশ করি:
```sh
func azure functionapp publish <functions_app_name>
```
এক্ষেত্রে `<functions_app_name>` এর জায়গায় আমাদের ব্যবহৃত নামটি দিতে হবে।
কোডটি প্যাকেজ আকারে ফাংশন অ্যাপে প্রেরণ করা হবে, যেখানে এটি ডেপ্লয় এবং ব্যবহার করা শুরু করা হবে। প্রচুর কনসোল আউটপুট থাকবে, এটির ডেপ্লয়মেন্টের নিশ্চয়তা এবং ক্রিয়াকলাপগুলির একটি তালিকা দেখানো হবে। তবে এক্ষেত্রে তালিকায় কেবল ট্রিগার থাকবে।
```output
Deployment successful.
Remote build succeeded!
Syncing triggers...
Functions in soil-moisture-sensor:
iot-hub-trigger - [eventHubTrigger]
```
আমাদের আইওটি ডিভাইসটি চলছে কিনা তা আগে নিশ্চিত করি । সেন্সরটিকে বারবার মাটির অভ্যন্তরে এবং বাইরে সরিয়ে আর্দ্রতার স্তর পরিবর্তন করি। মাটির আর্দ্রতা পরিবর্তনের সাথে সাথে আমরা রিলেটি চালু এবং বন্ধ হতে দেখবো।
---
## 🚀 চ্যালেঞ্জ
পূর্ববর্তী পাঠে, রিলে চালু থাকা অবস্থায় এবং এটি বন্ধ হওয়ার পরে অল্প সময়ের জন্য - আমরা এমকিউটিটি বার্তাগুলি থেকে আনসাবস্ক্রাইব করে রিলে এর সময় ম্যানেজ করেছিলাম । আমরা এই পদ্ধতিটি এখানে ব্যবহার করতে পারব না - আইওটি হাব ট্রিগার আমরা আন-সাবস্ক্রাইব করতে পারব না।
আমাদের ফাংশন অ্যাপে এই সমস্যা মোকাবেলা করতে বিভিন্ন উপায় সম্পর্কে চিন্তা করি।
## লেকচার পরবর্তী কুইজ
[লেকচার পরবর্তী কুইজ](https://brave-island-0b7c7f50f.azurestaticapps.net/quiz/18)
## রিভিউ এবং স্ব-অধ্যয়ন
* সার্ভারলেস কম্পিউটিং নিয়ে [Serverless Computing page on Wikipedia](https://wikipedia.org/wiki/Serverless_computing) থেকে আরো জানা যাবে।
* উদাহরণসহ সার্ভারলেস নিয়ে আরো জানা যাবে [Go serverless for your IoT needs Azure blog post](https://azure.microsoft.com/blog/go-serverless-for-your-iot-needs/?WT.mc_id=academic-17441-jabenn) থেকে।
* Azure Functions নিয়ে [Azure Functions YouTube channel](https://www.youtube.com/c/AzureFunctions) থেকে আরো জানা যাবে।
## এসাইনমেন্ট
[ম্যানুয়াল রিলে কন্ট্রোল সংযোজন](assignment.bn.md)

@ -0,0 +1,57 @@
# ম্যানুয়াল রিলে কন্ট্রোল সংযোজন
## নির্দেশাবলি
এইচটিটিপি অনুরোধ সহ অনেকগুলি ভিন্ন উপায়ে সার্ভারলেস কোডকে ট্রিগার করা যায়। রিলে নিয়ন্ত্রণে ম্যানুয়াল ওভাররাইড যুক্ত করতে আমরা HTTP ট্রিগার ব্যবহার করতে পারি, কাউকে ওয়েব রিকুয়েস্ট দ্বারা রিলে চালু বা বন্ধ করার সুযোগ দিতে।
এই এসাইনমেন্টের জন্য, রিলে চালু এবং বন্ধ করতে ফাংশন অ্যাপটিতে দুটি এইচটিটিপি ট্রিগার যুক্ত করতে হবে। ডিভাইসে কমান্ড প্রেরণের জন্য আমরা এই পাঠটি থেকে যা শিখেছি তা ব্যবহার করেই এটি করতে পারবো।
কিছু হিন্টস:
* নিম্নলিখিত কমান্ডটি সহ আমাদের বিদ্যমান ফাংশন অ্যাপগুলিতে একটি HTTP ট্রিগার যুক্ত করতে পারি:
```sh
func new --name <trigger name> --template "HTTP trigger"
```
এখানে `<trigger name>` এর জায়গায় আমাদের ব্যবহৃত এইচটিটিপি ট্রিগারের নাম দিতে হবে। এখানে `relay_on` এবং `relay_off` এর মতো নাম দেয়া যায়।
* HTTP trigger এ একসেস কন্ট্রোল দেয়া যায়। এগুলো রান করার জন্য function-specific API key দরকার যা URL এর সাথে পাস করতে হবে। তবে এই এসাইনমেন্টের জন্য এই রেস্ট্রিকশন রিমুভ করে দেয়া যায় যাতে যে কেউই এই ফাংশন রান করতে পারে। এজন্য `authLevel` সেটিংসটি আপডেট করতে হবে `function.json` ফাইল থেকে :
```json
"authLevel": "anonymous"
```
> 💁 একসেস কন্ট্রোল নিয়ে আরো বিস্তারিত [Function access keys documentation](https://docs.microsoft.com/azure/azure-functions/functions-bindings-http-webhook-trigger?WT.mc_id=academic-17441-jabenn#authorization-keys) থেকে জানা যাবে।
* HTTP ট্রিগারগুলো বাই ডিফল্ট GET এবং POST রিকুয়েস্টগুলো সাপোর্ট করে। অর্থাৎ ওয়েব ব্রাউজার দ্বারাই কাজ করা যাবে - GET রিকুয়েস্ট দিয়ে।
লোকালি ফাংশন এপ রান করলে, ট্রিগার ইউআরএল পাওয়া যাবে:
```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
```
ইউআরএল টি ব্রাউজারে পেস্ট করে `return` এ প্রেস করতে হবে অথবা VS Code টার্মিনালে লিংকটি `Ctrl+click` (`Cmd+click` macOS এর জন্য) সিলেক্ট করলে ডিফল্ট ব্রাউজারে তা ওপেন হবে এবং ট্রিগার রান করবে।
> 💁 খেয়াল করা দরকার যে URL-টি তে `/api` রয়েছে - HTTP ট্রিগারগুলো বাই ডিফল্ট `api` সাবডোমেইনে থাকে।
* ফাংশন অ্যাপ ডেপ্লয় করলে, তখন এইচটিটিপি ট্রিগার URL হবে:
`https://<functions app name>.azurewebsites.net/api/<trigger name>`
যেখানে `<functions app name>` হলো আমাদের ফাংশন এপ এর নাম এবং `<trigger name>` হলো ট্রিগারের নাম।
## এসাইনমেন্ট মূল্যায়ন মানদন্ড
| ক্রাইটেরিয়া | দৃষ্টান্তমূলক (সর্বোত্তম) | পর্যাপ্ত (মাঝারি) | উন্নতি প্রয়োজন (নিম্নমান) |
| --------- | ------------------ | ------------- | --------------------- |
| HTTP ট্রিগার তৈরী | সঠিক নামকরণের মাধ্যমে ২টি ট্রিগার তৈরি করে রিলে অন/অফ করা হয়েছে | সঠিক নামকরণের মাধ্যমে ১টি ট্রিগার তৈরি করেছে | কোন ট্রিগার তৈরী করতে সমর্থ হয়নি |
| এইচটিটিপি ট্রিগারগুলি থেকে রিলে নিয়ন্ত্রণ করা | উভয় ট্রিগারকে আইওটি হাবের সাথে সংযুক্ত করতে এবং যথোপযুক্তভাবে রিলে নিয়ন্ত্রণ করতে সক্ষম হয়েছিল| কেবল ১টি ট্রিগারকে আইওটি হাবের সাথে সংযুক্ত করতে এবং যথোপযুক্তভাবে রিলে নিয়ন্ত্রণ করতে সক্ষম হয়েছিল | ট্রিগারকে আইওটি হাবের সাথে সংযুক্ত করতে সমর্থ হয়নি |
{"mode":"full","isActive":false}

@ -8,6 +8,10 @@
[![GitHub forks](https://img.shields.io/github/forks/microsoft/IoT-For-Beginners.svg?style=social&label=Fork)](https://GitHub.com/microsoft/IoT-For-Beginners/network/)
[![GitHub stars](https://img.shields.io/github/stars/microsoft/IoT-For-Beginners.svg?style=social&label=Star)](https://GitHub.com/microsoft/IoT-For-Beginners/stargazers/)
[![Bengali](https://img.shields.io/badge/-Bengali-blue)](translations/README.bn.md)
[![Chinese](https://img.shields.io/badge/-Chinese-yellow)](translations/README.zh-cn.md)
[![Turkish](https://img.shields.io/badge/-Turkish-darkgreen)](translations/README.tr.md)
# IoT for Beginners - A Curriculum
Azure Cloud Advocates at Microsoft are pleased to offer a 12-week, 24-lesson curriculum all about IoT basics. Each lesson includes pre- and post-lesson quizzes, written instructions to complete the lesson, a solution, an assignment and more. Our project-based pedagogy allows you to learn while building, a proven way for new skills to 'stick'.

@ -8,6 +8,11 @@ There are [**translations**](https://github.com/microsoft/IoT-For-Beginners/tree
Translated lessons should follow this naming convention:
When translating the initial Readme, link the other translations to your translated readme and link yours to the main English Readme by using Shields as shown:
```markdown
[![Bengali](https://img.shields.io/badge/-Bengali-blue)](translations/README.bn.md)
```
**README._[language]_.md**
where _[language]_ is a two letter language abbreviation following the ISO 639-1 standard (e.g. `README.es.md` for Spanish and `README.nl.md` for Dutch).

@ -6,7 +6,11 @@
[![GitHub watchers](https://img.shields.io/github/watchers/microsoft/IoT-For-Beginners.svg?style=social&label=Watch)](https://GitHub.com/microsoft/IoT-For-Beginners/watchers/)
[![GitHub forks](https://img.shields.io/github/forks/microsoft/IoT-For-Beginners.svg?style=social&label=Fork)](https://GitHub.com/microsoft/IoT-For-Beginners/network/)
[![GitHub stars](https://img.shields.io/github/stars/microsoft/IoT-For-Beginners.svg?style=social&label=Sta)](https://GitHub.com/microsoft/IoT-For-Beginners/stargazers/)
[![GitHub stars](https://img.shields.io/github/stars/microsoft/IoT-For-Beginners.svg?style=social&label=Star)](https://GitHub.com/microsoft/IoT-For-Beginners/stargazers/)
[![English](https://img.shields.io/badge/-English-red)](../README.md)
[![Chinese](https://img.shields.io/badge/-Chinese-yellow)](README.zh-cn.md)
[![Turkish](https://img.shields.io/badge/-Turkish-darkgreen)](README.tr.md)
# বিগিনারদের জন্য আইওটি - একটি সুবিন্যস্ত পাঠ্যক্রম
@ -22,11 +26,17 @@
**ধন্যবাদ জানাতে চাই আমাদের সেসকল [Microsoft Learn Student Ambassadors](https://studentambassadors.microsoft.com?WT.mc_id=academic-17441-jabenn)দের, যারা এই কারিক্যুলামটি রিভিউ এবং অনুবাদে কাজ করেছে - [Aditya Garg](https://github.com/AdityaGarg00),[Anurag Sharma](https://github.com/Anurag-0-1-A), [Arpita Das](https://github.com/Arpiiitaaa), [Aryan Jain](https://www.linkedin.com/in/aryan-jain-47a4a1145/), [Bhavesh Suneja](https://github.com/EliteWarrior315),[Faith Hunja](https://faithhunja.github.io/), [Lateefah Bello](https://www.linkedin.com/in/lateefah-bello/), [Manvi Jha](https://github.com/Severus-Matthew), [Mireille Tan](https://www.linkedin.com/in/mireille-tan-a4834819a/), [Mohammad Iftekher (Iftu) Ebne Jalal](https://github.com/Iftu119), [Priyanshu Srivastav](https://www.linkedin.com/in/priyanshu-srivastav-b067241ba), [Thanmai Gowducheruvu](https://github.com/innovation-platform), এবং [Zina Kamel](https://www.linkedin.com/in/zina-kamel/).**
পুরো টীমের সাথে পরিচিত হওয়া যাক !
[![Promo video](../images/iot-for-beginners.png)](https://youtu.be/-wippUJRi5k)
> 🎥 উপরের ছবিতে ক্লিক করলেই এই কারিক্যুলামে যারা কাজ করেছেন, তাদের সম্পর্কে জানা যাবে।
> **শিক্ষকবৃন্দ** , আপনারা যেন বেশ সহজেই এই কারিকুলাম ব্যবহার করতে পারেন তার জন্য, আমর একটি [গাইডলাইন](for-teachers.md) তৈরী করেছি যাতে আপনার জন্য প্রয়োজনীয় সকল নির্দেশনা রয়েছে। আপনি যদি নিজেই নিজের লেসন তৈরি করতে চান, তবে তার জন্যও আমরা একটি [লেসন টেম্পলেট](lesson-template/README.md) রেখেছি।
> **শিক্ষার্থীরা**, এই কোর্সটি নিজে ব্যবহার করতে চাইলে, পুরো রেপোসিটরি 'fork' করতে হবে এবং লেকচার-পূর্ববর্তী কুইজ দিয়ে শুরু করতে হবে। তারপরে লেকচারটি পড়ে এবং বাকি কাজগুলো বুঝে, নিজেই অনুশীলনগুলি সম্পূর্ণ করতে হবে। সমাধান কোডগুলো কপি না করে, বরং লেসনগুলি বোঝার মাধ্যমে প্রজেক্টগুলি তৈরি করার চেষ্টা করতে হবে। তবে হ্যাঁ, সল্যুশন কোডগুলো প্রতিটি প্রজেক্ট-ভিত্তিক লেসনের সমাধান ফোল্ডারে পাওয়া যাবে। আরেকটি পরামর্শ হলো বন্ধুদের সাথে একটি স্টাডি গ্রুপ গঠন করা এবং একসাথে লেসনগুলোর মধ্য দিয়ে যাওয়া। আরও বেশি শেখার জন্য, [Microsoft Learn](https://docs.microsoft.com/users/jimbobbennett/collections/ke2ehd351jopwr?WT.mc_id=academic-17441-jabenn) ব্যবহার করা যাবে।
[![Promo video](../images/iot-for-beginners.png)](https://youtube.com/watch?v=bccEMm8gRuc "Promo video")
[![Promo video](https://img.youtube.com/vi/bccEMm8gRuc/0.jpg)](https://youtube.com/watch?v=bccEMm8gRuc "Promo video")
> 🎥 উপরের ছবিতে ক্লিক করলেই এই পুরো কারিক্যুলামটি সম্পর্কে জানা যাবে।
@ -65,15 +75,15 @@
| | প্রজেক্ট | কনসেপ্ট | শিখনফল | লেসন/পাঠ্য |
| :-: | :----------: | :-------------: | ------------------- | :-----------: |
| 01 | [IoT যাত্রার সূচনা](./1-getting-started) | IoT পরিচিতি | প্রথম আইওটি ডিভাইস সেটআপ করার সময়ই আইওটি এর প্রাথমিক নীতিগুলি এবং আইওটি সল্যুশনের বেসিক বিষয়গুলো যেমনঃ সেন্সর এবং ক্লাউড সার্ভিস সংক্রান্ত বিষয়গুলো সম্পর্কে জ্ঞান অর্জন | [IoT পরিচিতি](./1-getting-started/lessons/1-introduction-to-iot/translations/README.bn.md) |
| 02 | [IoT যাত্রার সূচনা](./1-getting-started) | IoT এর আরো গভীরে| আইওটি সিস্টেমের উপাদানগুলির পাশাপাশি মাইক্রোকন্ট্রোলার এবং সিঙ্গেল-বোর্ড কম্পিউটার সম্পর্কে জ্ঞান অর্জন | [IoT এর আরো গভীরে](./1-getting-started/lessons/2-deeper-dive/translations/README.bn.md) |
| 03 | [IoT যাত্রার সূচনা](./1-getting-started) | সেন্সর এবং অ্যাকচুয়েটরের সাহায্যে বাহ্যিক জগতের সাথে যোগাযোগ| 'নাইটলাইট' প্রজেক্টটি করার সাথেই সমান্তরালে বাহ্যিক জগত থেকে ডেটা সংগ্রহ করার জন্য সেন্সর এবং প্রতিক্রিয়া জানাতে ব্যবহৃত অ্যাকচুয়েটর সম্পর্কে জ্ঞান অর্জন | [সেন্সর এবং অ্যাকচুয়েটরের সাহায্যে বাহ্যিক জগতের সাথে যোগাযোগ](./1-getting-started/lessons/3-sensors-and-actuators/translations/README.bn.md) |
| 04 | [IoT যাত্রার সূচনা](./1-getting-started) | আইওটি ডিভাইসকে ইন্টারনেটে সংযুক্ত করা | এমকিউটিটি ব্রোকারের সাথে নাইটলাইটটি সংযুক্ত করে বার্তাগুলি প্রেরণ এবং গ্রহণ করতে আইওটি ডিভাইসটিকে কীভাবে ইন্টারনেটে সংযুক্ত করতে হবে সেই সংক্রান্ত জ্ঞান অর্জন | [আইওটি ডিভাইসকে ইন্টারনেটে সংযুক্তকরণ ](./1-getting-started/lessons/4-connect-internet/translations/README.bn.md) |
| 05 | [ফার্ম](./2-farm) | আইওটি দ্বারা উদ্ভিদ বৃদ্ধির পূর্বাভাস | আইওটি ডিভাইস দ্বারা গৃহিত তাপমাত্রার ডেটা ব্যবহার করে কীভাবে উদ্ভিদ বৃদ্ধির পূর্বাভাস দেওয়া যায় তা শেখা | [আইওটি দ্বারা উদ্ভিদ বৃদ্ধির পূর্বাভাস](./2-farm/lessons/1-predict-plant-growth/translations/README.bn.md) |
| 06 | [ফার্ম](./2-farm) | মাটির আর্দ্রতা নির্ণয় | কীভাবে মাটির আর্দ্রতা সনাক্ত করা যায় এবং তা করতে মাটির আর্দ্রতা সেন্সরটি কীভাবে ক্যালিব্রেট করতে হবে তা শেখা | [মাটির আর্দ্রতা নির্ণয়](./2-farm/lessons/2-detect-soil-moisture/translations/README.bn.md) |
| 07 | [ফার্ম](./2-farm) | স্বয়ংক্রিয় সেচকার্য | রিলে এবং এমকিউটিটি ব্যবহার করে কীভাবে স্বয়ংক্রিয়ভাবে এবং নির্দিষ্ট সময়ে সেচ দেয়া যায় সে সংক্রান্ত জ্ঞান অর্জন | [স্বয়ংক্রিয় সেচকার্য](./2-farm/lessons/3-automated-plant-watering/translations/README.bn.md) |
| 08 | [ফার্ম](./2-farm) | উদ্ভিদকে ক্লাউডে সংযুক্ত করা | ক্লাউড এবং ক্লাউড-হোস্ট করা আইওটি পরিষেবাগুলি সম্পর্কে জ্ঞান অর্জন এবং কীভাবে আমাদের উদ্ভিদটিকে পাবলিক এমকিউটিটি ব্রোকারের পরিবর্তে ক্লাউডে সংযুক্ত করতে হবে তা শেখা | [উদ্ভিদকে ক্লাউডে সংযুক্ত করা](./2-farm/lessons/4-migrate-your-plant-to-the-cloud/translations/README.bn.md) |
| 09 | [ফার্ম](./2-farm) | Migrate your application logic to the cloud | ক্লাউডে কীভাবে অ্যাপ্লিকেশন লজিক লিখতে হবে যাতে তা আইওটি ম্যাসেজের প্রতিক্রিয়া জানাতে পারে তা শেখা| [Migrate your application logic to the cloud](./2-farm/lessons/5-migrate-application-to-the-cloud/README.md) |
| 01 | [IoT যাত্রার সূচনা](./1-getting-started) | IoT পরিচিতি | প্রথম আইওটি ডিভাইস সেটআপ করার সময়ই আইওটি এর প্রাথমিক নীতিগুলি এবং আইওটি সল্যুশনের বেসিক বিষয়গুলো যেমনঃ সেন্সর এবং ক্লাউড সার্ভিস সংক্রান্ত বিষয়গুলো সম্পর্কে জ্ঞান অর্জন | [IoT পরিচিতি](../1-getting-started/lessons/1-introduction-to-iot/translations/README.bn.md) |
| 02 | [IoT যাত্রার সূচনা](./1-getting-started) | IoT এর আরো গভীরে| আইওটি সিস্টেমের উপাদানগুলির পাশাপাশি মাইক্রোকন্ট্রোলার এবং সিঙ্গেল-বোর্ড কম্পিউটার সম্পর্কে জ্ঞান অর্জন | [IoT এর আরো গভীরে](../1-getting-started/lessons/2-deeper-dive/translations/README.bn.md) |
| 03 | [IoT যাত্রার সূচনা](./1-getting-started) | সেন্সর এবং অ্যাকচুয়েটরের সাহায্যে বাহ্যিক জগতের সাথে যোগাযোগ| 'নাইটলাইট' প্রজেক্টটি করার সাথেই সমান্তরালে বাহ্যিক জগত থেকে ডেটা সংগ্রহ করার জন্য সেন্সর এবং প্রতিক্রিয়া জানাতে ব্যবহৃত অ্যাকচুয়েটর সম্পর্কে জ্ঞান অর্জন | [সেন্সর এবং অ্যাকচুয়েটরের সাহায্যে বাহ্যিক জগতের সাথে যোগাযোগ](../1-getting-started/lessons/3-sensors-and-actuators/translations/README.bn.md) |
| 04 | [IoT যাত্রার সূচনা](./1-getting-started) | আইওটি ডিভাইসকে ইন্টারনেটে সংযুক্ত করা | এমকিউটিটি ব্রোকারের সাথে নাইটলাইটটি সংযুক্ত করে বার্তাগুলি প্রেরণ এবং গ্রহণ করতে আইওটি ডিভাইসটিকে কীভাবে ইন্টারনেটে সংযুক্ত করতে হবে সেই সংক্রান্ত জ্ঞান অর্জন | [আইওটি ডিভাইসকে ইন্টারনেটে সংযুক্তকরণ ](../1-getting-started/lessons/4-connect-internet/translations/README.bn.md) |
| 05 | [ফার্ম](./2-farm) | আইওটি দ্বারা উদ্ভিদ বৃদ্ধির পূর্বাভাস | আইওটি ডিভাইস দ্বারা গৃহিত তাপমাত্রার ডেটা ব্যবহার করে কীভাবে উদ্ভিদ বৃদ্ধির পূর্বাভাস দেওয়া যায় তা শেখা | [আইওটি দ্বারা উদ্ভিদ বৃদ্ধির পূর্বাভাস](../2-farm/lessons/1-predict-plant-growth/translations/README.bn.md) |
| 06 | [ফার্ম](./2-farm) | মাটির আর্দ্রতা নির্ণয় | কীভাবে মাটির আর্দ্রতা সনাক্ত করা যায় এবং তা করতে মাটির আর্দ্রতা সেন্সরটি কীভাবে ক্যালিব্রেট করতে হবে তা শেখা | [মাটির আর্দ্রতা নির্ণয়](../2-farm/lessons/2-detect-soil-moisture/translations/README.bn.md) |
| 07 | [ফার্ম](./2-farm) | স্বয়ংক্রিয় সেচকার্য | রিলে এবং এমকিউটিটি ব্যবহার করে কীভাবে স্বয়ংক্রিয়ভাবে এবং নির্দিষ্ট সময়ে সেচ দেয়া যায় সে সংক্রান্ত জ্ঞান অর্জন | [স্বয়ংক্রিয় সেচকার্য](../2-farm/lessons/3-automated-plant-watering/translations/README.bn.md) |
| 08 | [ফার্ম](./2-farm) | উদ্ভিদকে ক্লাউডে সংযুক্ত করা | ক্লাউড এবং ক্লাউড-হোস্ট করা আইওটি পরিষেবাগুলি সম্পর্কে জ্ঞান অর্জন এবং কীভাবে আমাদের উদ্ভিদটিকে পাবলিক এমকিউটিটি ব্রোকারের পরিবর্তে ক্লাউডে সংযুক্ত করতে হবে তা শেখা | [উদ্ভিদকে ক্লাউডে সংযুক্ত করা](../2-farm/lessons/4-migrate-your-plant-to-the-cloud/translations/README.bn.md) |
| 09 | [ফার্ম](./2-farm) | অ্যাপ্লিকেশন লজিককে ক্লাউডে স্থানান্তর | ক্লাউডে কীভাবে অ্যাপ্লিকেশন লজিক লিখতে হবে যাতে তা আইওটি ম্যাসেজের প্রতিক্রিয়া জানাতে পারে তা শেখা| [অ্যাপ্লিকেশন লজিককে ক্লাউডে স্থানান্তর](../2-farm/lessons/5-migrate-application-to-the-cloud/translations/README.bn.md) |
| 10 | [ফার্ম](./2-farm) | Keep your plant secure | আইওটি তে নিরাপত্তা সম্পর্কে জানা এবং Key ও Certificate এর সাহায্যে আমাদের উদ্ভিদটিকে কীভাবে সুরক্ষিত রাখা যায় তা শেখা | [Keep your plant secure](./2-farm/lessons/6-keep-your-plant-secure/README.md) |
| 11 | [পরিবহন](./3-transport) | Location tracking | আইওটি ডিভাইসে জিপিএস লোকেশন ট্র্যাকিং শেখা | [Location tracking](./3-transport/lessons/1-location-tracking/README.md) |
| 12 | [পরিবহন](./3-transport) | Store location data | পরবর্তী সময়ে বিশ্লেষণ বা চিত্রভিত্তিক ডেটা প্রদর্শন (Visualization) এর জন্য আইওটি ডেটা কীভাবে স্টোর করা যায় তা জানা | [Store location data](./3-transport/lessons/2-store-location-data/README.md) |

@ -8,6 +8,10 @@
[![GitHub forks](https://img.shields.io/github/forks/microsoft/IoT-For-Beginners.svg?style=social&label=Fork)](https://GitHub.com/microsoft/IoT-For-Beginners/network/)
[![GitHub stars](https://img.shields.io/github/stars/microsoft/IoT-For-Beginners.svg?style=social&label=Sta)](https://GitHub.com/microsoft/IoT-For-Beginners/stargazers/)
[![Bengali](https://img.shields.io/badge/-Bengali-blue)](README.bn.md)
[![English](https://img.shields.io/badge/-English-red)](../README.md)
[![Chinese](https://img.shields.io/badge/-Chinese-yellow)](README.zh-cn.md)
# Yeni Başlayanlar için IOT
Microsoft'tan Azure Cloud Advocates size IOT temelleri hakkında 12 haftalık 24 dersten oluşan programı zevkle sunar. Her ders ön-quiz, dersi tamamlamanız için talimatlar, bir çözüm, bir ödev ve ders sonrası quiz içerir. Proje tabanlı pedogojimiz öğrenirken bir şeyler oluşturmanıza izin verecek. Bu, ispanlanmıştır ki yeni becerileri adeta size "yapıştıracak".

@ -6,7 +6,11 @@
[![GitHub watchers](https://img.shields.io/github/watchers/microsoft/IoT-For-Beginners.svg?style=social&label=Watch)](https://GitHub.com/microsoft/IoT-For-Beginners/watchers/)
[![GitHub forks](https://img.shields.io/github/forks/microsoft/IoT-For-Beginners.svg?style=social&label=Fork)](https://GitHub.com/microsoft/IoT-For-Beginners/network/)
[![GitHub stars](https://img.shields.io/github/stars/microsoft/IoT-For-Beginners.svg?style=social&label=Sta)](https://GitHub.com/microsoft/IoT-For-Beginners/stargazers/)
[![GitHub stars](https://img.shields.io/github/stars/microsoft/IoT-For-Beginners.svg?style=social&label=Star)](https://GitHub.com/microsoft/IoT-For-Beginners/stargazers/)
[![Bengali](https://img.shields.io/badge/-Bengali-blue)](README.bn.md)
[![English](https://img.shields.io/badge/-English-red)](../README.md)
[![Turkish](https://img.shields.io/badge/-Turkish-darkgreen)](README.tr.md)
# 物联网IoT for Beginners 课程
@ -15,7 +19,7 @@ Microsoft 的 Azure Cloud 大使很高兴提供关于 IoT 基础一个12个星
这些项目囊括食物从农场到桌子的过程。这包括农业、物流、制造、零售和消费者——这些都是 IoT 设备的热门行业。
![课程的路线图;它在 24 课概括简介、农业
交通、处理、零售与烹饪](sketchnotes/Roadmap.jpg)
交通、处理、零售与烹饪](../sketchnotes/Roadmap.jpg)
> Sketchnote by [Nitya Narasimhan](https://github.com/nitya). 请点击图片查看原图。
@ -23,7 +27,7 @@ Microsoft 的 Azure Cloud 大使很高兴提供关于 IoT 基础一个12个星
**也感谢帮我们审查以及翻译这个课程的一组 [Microsoft Learn 学生大使](https://studentambassadors.microsoft.com?WT.mc_id=academic-17441-jabenn) [Aditya Garg](https://github.com/AdityaGarg00), [Anurag Sharma](https://github.com/Anurag-0-1-A), [Arpita Das](https://github.com/Arpiiitaaa), [Aryan Jain](https://www.linkedin.com/in/aryan-jain-47a4a1145/), [Bhavesh Suneja](https://github.com/EliteWarrior315), [Faith Hunja](https://faithhunja.github.io/), [Lateefah Bello](https://www.linkedin.com/in/lateefah-bello/), [Manvi Jha](https://github.com/Severus-Matthew), [Mireille Tan](https://www.linkedin.com/in/mireille-tan-a4834819a/), [Mohammad Iftekher (Iftu) Ebne Jalal](https://github.com/Iftu119), [Mohammad Zulfikar](https://github.com/mohzulfikar), [Priyanshu Srivastav](https://www.linkedin.com/in/priyanshu-srivastav-b067241ba), [Thanmai Gowducheruvu](https://github.com/innovation-platform), 和 [Zina Kamel](https://www.linkedin.com/in/zina-kamel/).**
> **老师们**,我们为这个课程的用法 [提供了一些意见](for-teachers.md)。如果你想自己创建课程,那我们也提供了一个[课程模板](lesson-template/README.md).
> **老师们**,我们为这个课程的用法 [提供了一些意见](../for-teachers.md)。如果你想自己创建课程,那我们也提供了一个[课程模板](lesson-template/README.md).
> **学生们** 为了自己学习这个课程,请复刻整个项目库,再自己完成练习,从课前知识测验开始,再阅读讲座,然后完成剩余的活动。尝试通过理解课程的内容来完成项目,而不要仅仅把代码答案抄下来;然而,在每个项目课程里,你都能从 /solutions 文件夹访问那些答案代码。另外一个办法是跟朋友成立学习小组,然后一起分析内容。想进一步研究,我们鼓励你查一查[Microsoft Learn](https://docs.microsoft.com/users/jimbobbennett/collections/ke2ehd351jopwr?WT.mc_id=academic-17441-jabenn)。
@ -44,9 +48,9 @@ Microsoft 的 Azure Cloud 大使很高兴提供关于 IoT 基础一个12个星
## 硬件
根据你自己的选择、知道或喜欢的编码语言、学习目标等,我们对于项目的 IoT 硬件有两个选择。我们也提供了一个“虚拟硬件”的版本,为无法拿到硬件或者想在买硬件之前学多一点儿东西的人。你能在[硬件页](./hardware.md)找到更多资料与“购物清单”它也包括来自我们朋友Seeed Studio完整套件的链接。
根据你自己的选择、知道或喜欢的编码语言、学习目标等,我们对于项目的 IoT 硬件有两个选择。我们也提供了一个“虚拟硬件”的版本,为无法拿到硬件或者想在买硬件之前学多一点儿东西的人。你能在[硬件页](../hardware.md)找到更多资料与“购物清单”它也包括来自我们朋友Seeed Studio完整套件的链接。
> 💁 找一下我们的[行为守则](CODE_OF_CONDUCT.md)、 [贡献](CONTRIBUTING.md)和 [翻译](TRANSLATIONS.md)的指导方针。 我们欢迎你的建设性反馈!
> 💁 找一下我们的[行为守则](../CODE_OF_CONDUCT.md)、 [贡献](../CONTRIBUTING.md)和 [翻译](../TRANSLATIONS.md)的指导方针。 我们欢迎你的建设性反馈!
## 每个课包括:
@ -68,30 +72,30 @@ Microsoft 的 Azure Cloud 大使很高兴提供关于 IoT 基础一个12个星
| | 项目 | 题目 | 学习目标 | 链接 |
| :-: | :----------: | :-------------: | ------------------- | :-----------: |
| 01 | [入门](./1-getting-started) | 物联网IoT简介 | 学会 IoT 的基本原则(例如:传感器和云服务),同时设置你的第一个 IoT 设备| [物联网IoT简介](./1-getting-started/lessons/1-introduction-to-iot/README.md) |
| 02 | [入门](./1-getting-started) | 深入了解物联网IoT | 深入了解 IoT 系统的不同部分,以及微控制器和单板机 | [深入了解物联网IoT](./1-getting-started/lessons/2-deeper-dive/README.md) |
| 03 | [入门](./1-getting-started) | 用传感器和执行器跟物质世界互相作用 | 学会传感器怎么从物质世界收集数据和执行器怎么发送反馈,同时创建一个夜灯 | [用传感器和执行器跟物质世界互相作用](./1-getting-started/lessons/3-sensors-and-actuators/README.md) |
| 04 | [入门](./1-getting-started) | 将你的设备连接到互联网 | 学会怎么把一个 IoT 设备连接到互联网将夜灯连接到MQTT 中转站让它发送和收到消息 | [将你的设备连接到互联网](./1-getting-started/lessons/4-connect-internet/README.md) |
| 05 | [农场](./2-farm) | 预测植物生长 | 学会怎么用 IoT 设备捕获的温度数据来预测植物生长 | [预测植物生长](./2-farm/lessons/1-predict-plant-growth/README.md) |
| 06 | [农场](./2-farm) | 检测土壤水分 | 学会怎么检测土壤水分以及校准土壤湿度传感器 | [检测土壤水分](./2-farm/lessons/2-detect-soil-moisture/README.md) |
| 07 | [农场](./2-farm) | 自动植物浇水 | 学会怎么用一个中继和 MQTT 为植物浇水使自动化和计时 | [自动植物浇水](./2-farm/lessons/3-automated-plant-watering/README.md) |
| 08 | [农场](./2-farm) | 将你的植物迁移到云端 | 了解云端和云端 IoT 服务与学会怎么把你的植物连接到它,而不是一个公共 MQTT中转站 | [将你的植物迁移到云端](./2-farm/lessons/4-migrate-your-plant-to-the-cloud/README.md) |
| 09 | [农场](./2-farm) | 将你的应用程序逻辑迁移到云端 | 学会怎么在云端写能够响应 IoT 消息的应用程序逻辑 | [将你的应用程序逻辑迁移到云端](./2-farm/lessons/5-migrate-application-to-the-cloud/README.md) |
| 10 | [农场](./2-farm) | 确保你的植物安全 | 了解 IoT 安全以及学会怎么用密钥和证书来确保你的植物安全 | [确保你的植物安全](./2-farm/lessons/6-keep-your-plant-secure/README.md) |
| 11 | [交通](./3-transport) | 位置追踪 | 了解 IoT 设备的 GPS位置追踪 | [位置追踪](./3-transport/lessons/1-location-tracking/README.md) |
| 12 | [交通](./3-transport) | 存储位置数据 | 学会怎么存储 IoT 数据,让你未来能可视化或分析它 | [存储位置数据](./3-transport/lessons/2-store-location-data/README.md) |
| 13 | [交通](./3-transport) | 可视化位置数据 | 学会在地图上可视化位置数据以及地图怎么用 2D 来代表 3D 的世界 | [可视化位置数据](./3-transport/lessons/3-visualize-location-data/README.md) |
| 14 | [交通](./3-transport) | 地理围栏 | 学会地理围栏是什么以及怎么用它们来通知当供应链的车辆快到目的地时 | [地理围栏](./3-transport/lessons/4-geofences/README.md) |
| 15 | [制造业](./4-manufacturing) | 训练水果质量检测器 | 学会怎么在云端上训练一个图片分类器来检测水果质量 | [训练水果质量检测器](./4-manufacturing/lessons/1-train-fruit-detector/README.md) |
| 16 | [制造业](./4-manufacturing) | 从 IoT 设备检查水果质量 | 学会怎么从一个 IoT 设备使用你的水果质量检测器 | [从 IoT 设备检查水果质量](./4-manufacturing/lessons/2-check-fruit-from-device/README.md) |
| 17 | [制造业](./4-manufacturing) | 在边缘上运行你的水果质量检测器 | 学会怎么在边缘上的 IoT 设备运行你的水果质量检测器 | [在边缘上运行你的水果质量检测器](./4-manufacturing/lessons/3-run-fruit-detector-edge/README.md) |
| 18 | [制造业](./4-manufacturing) | 从传感器触发水果质量检测 | 学会怎么从传感器触发水果质量检测 | [从传感器触发水果质量检测](./4-manufacturing/lessons/4-trigger-fruit-detector/README.md) |
| 19 | [零售](./5-retail) | 训练存货检测器 | 学会用对象检测来训练存货检测器让你在店里数存货 | [训练存货检测器](./5-retail/lessons/1-train-stock-detector/README.md) |
| 20 | [零售](./5-retail) | 从 IoT 设备检查存货 | 学会怎么用一个对象检测模型从 IoT 设备检查存货 | [从 IoT 设备检查存货](./5-retail/lessons/2-check-stock-device/README.md) |
| 21 | [消费者](./6-consumer) | 用 IoT 设备识别语音 | 学会怎么用 IoT 设备识别语音来创建一个智能计时器 | [用 IoT 设备识别语音](./6-consumer/lessons/1-speech-recognition/README.md) |
| 22 | [消费者](./6-consumer) | 理解语言 | 学会怎么理解向 IoT 设备说的语言 | [理解语言](./6-consumer/lessons/2-language-understanding/README.md) |
| 23 | [消费者](./6-consumer) | 设置计时器和提供口头反馈 | 学会怎么设置计时器和提供口头反馈当计时器被设置和当它完成的时候 | [设置计时器和提供口头反馈](./6-consumer/lessons/3-spoken-feedback/README.md) |
| 24 | [消费者](./6-consumer) | 支持多种语言 | 学会怎么支持多种语言,包括向智能计时器说的还有计时器回应的 | [支持多种语言](./6-consumer/lessons/4-multiple-language-support/README.md) |
| 01 | [入门](../1-getting-started) | 物联网IoT简介 | 学会 IoT 的基本原则(例如:传感器和云服务),同时设置你的第一个 IoT 设备| [物联网IoT简介](../1-getting-started/lessons/1-introduction-to-iot/README.md) |
| 02 | [入门](../1-getting-started) | 深入了解物联网IoT | 深入了解 IoT 系统的不同部分,以及微控制器和单板机 | [深入了解物联网IoT](../1-getting-started/lessons/2-deeper-dive/README.md) |
| 03 | [入门](../1-getting-started) | 用传感器和执行器跟物质世界互相作用 | 学会传感器怎么从物质世界收集数据和执行器怎么发送反馈,同时创建一个夜灯 | [用传感器和执行器跟物质世界互相作用](../1-getting-started/lessons/3-sensors-and-actuators/README.md) |
| 04 | [入门](../1-getting-started) | 将你的设备连接到互联网 | 学会怎么把一个 IoT 设备连接到互联网将夜灯连接到MQTT 中转站让它发送和收到消息 | [将你的设备连接到互联网](../1-getting-started/lessons/4-connect-internet/README.md) |
| 05 | [农场](../2-farm) | 预测植物生长 | 学会怎么用 IoT 设备捕获的温度数据来预测植物生长 | [预测植物生长](../2-farm/lessons/1-predict-plant-growth/README.md) |
| 06 | [农场](../2-farm) | 检测土壤水分 | 学会怎么检测土壤水分以及校准土壤湿度传感器 | [检测土壤水分](../2-farm/lessons/2-detect-soil-moisture/README.md) |
| 07 | [农场](../2-farm) | 自动植物浇水 | 学会怎么用一个中继和 MQTT 为植物浇水使自动化和计时 | [自动植物浇水](../2-farm/lessons/3-automated-plant-watering/README.md) |
| 08 | [农场](../2-farm) | 将你的植物迁移到云端 | 了解云端和云端 IoT 服务与学会怎么把你的植物连接到它,而不是一个公共 MQTT中转站 | [将你的植物迁移到云端](../2-farm/lessons/4-migrate-your-plant-to-the-cloud/README.md) |
| 09 | [农场](../2-farm) | 将你的应用程序逻辑迁移到云端 | 学会怎么在云端写能够响应 IoT 消息的应用程序逻辑 | [将你的应用程序逻辑迁移到云端](../2-farm/lessons/5-migrate-application-to-the-cloud/README.md) |
| 10 | [农场](../2-farm) | 确保你的植物安全 | 了解 IoT 安全以及学会怎么用密钥和证书来确保你的植物安全 | [确保你的植物安全](../2-farm/lessons/6-keep-your-plant-secure/README.md) |
| 11 | [交通](../3-transport) | 位置追踪 | 了解 IoT 设备的 GPS位置追踪 | [位置追踪](../3-transport/lessons/1-location-tracking/README.md) |
| 12 | [交通](../3-transport) | 存储位置数据 | 学会怎么存储 IoT 数据,让你未来能可视化或分析它 | [存储位置数据](../3-transport/lessons/2-store-location-data/README.md) |
| 13 | [交通](../3-transport) | 可视化位置数据 | 学会在地图上可视化位置数据以及地图怎么用 2D 来代表 3D 的世界 | [可视化位置数据](../3-transport/lessons/3-visualize-location-data/README.md) |
| 14 | [交通](../3-transport) | 地理围栏 | 学会地理围栏是什么以及怎么用它们来通知当供应链的车辆快到目的地时 | [地理围栏](../3-transport/lessons/4-geofences/README.md) |
| 15 | [制造业](../4-manufacturing) | 训练水果质量检测器 | 学会怎么在云端上训练一个图片分类器来检测水果质量 | [训练水果质量检测器](../4-manufacturing/lessons/1-train-fruit-detector/README.md) |
| 16 | [制造业](../4-manufacturing) | 从 IoT 设备检查水果质量 | 学会怎么从一个 IoT 设备使用你的水果质量检测器 | [从 IoT 设备检查水果质量](../4-manufacturing/lessons/2-check-fruit-from-device/README.md) |
| 17 | [制造业](../4-manufacturing) | 在边缘上运行你的水果质量检测器 | 学会怎么在边缘上的 IoT 设备运行你的水果质量检测器 | [在边缘上运行你的水果质量检测器](../4-manufacturing/lessons/3-run-fruit-detector-edge/README.md) |
| 18 | [制造业](../4-manufacturing) | 从传感器触发水果质量检测 | 学会怎么从传感器触发水果质量检测 | [从传感器触发水果质量检测](../4-manufacturing/lessons/4-trigger-fruit-detector/README.md) |
| 19 | [零售](../5-retail) | 训练存货检测器 | 学会用对象检测来训练存货检测器让你在店里数存货 | [训练存货检测器](../5-retail/lessons/1-train-stock-detector/README.md) |
| 20 | [零售](../5-retail) | 从 IoT 设备检查存货 | 学会怎么用一个对象检测模型从 IoT 设备检查存货 | [从 IoT 设备检查存货](../5-retail/lessons/2-check-stock-device/README.md) |
| 21 | [消费者](../6-consumer) | 用 IoT 设备识别语音 | 学会怎么用 IoT 设备识别语音来创建一个智能计时器 | [用 IoT 设备识别语音](../6-consumer/lessons/1-speech-recognition/README.md) |
| 22 | [消费者](../6-consumer) | 理解语言 | 学会怎么理解向 IoT 设备说的语言 | [理解语言](../6-consumer/lessons/2-language-understanding/README.md) |
| 23 | [消费者](../6-consumer) | 设置计时器和提供口头反馈 | 学会怎么设置计时器和提供口头反馈当计时器被设置和当它完成的时候 | [设置计时器和提供口头反馈](../6-consumer/lessons/3-spoken-feedback/README.md) |
| 24 | [消费者](../6-consumer) | 支持多种语言 | 学会怎么支持多种语言,包括向智能计时器说的还有计时器回应的 | [支持多种语言](../6-consumer/lessons/4-multiple-language-support/README.md) |
## 离线访问
@ -109,7 +113,7 @@ npm run convert
## 需要帮忙!
想贡献一个翻译?请阅读我们的[翻译指导方针](TRANSLATIONS.md) 以及在[其中一个翻译 issue](https://github.com/microsoft/IoT-For-Beginners/issues?q=is%3Aissue+is%3Aopen+label%3Atranslation) 添加输入。如果你想帮我们翻译成一个新语言,请举一个新 issue 用于跟踪。
想贡献一个翻译?请阅读我们的[翻译指导方针](../TRANSLATIONS.md) 以及在[其中一个翻译 issue](https://github.com/microsoft/IoT-For-Beginners/issues?q=is%3Aissue+is%3Aopen+label%3Atranslation) 添加输入。如果你想帮我们翻译成一个新语言,请举一个新 issue 用于跟踪。
## 其它课程
@ -120,4 +124,4 @@ npm run convert
## 图片属性
你能在[属性](./attributions.md)找到课程中所有需要的图片属性。
你能在[属性](../attributions.md)找到课程中所有需要的图片属性。

Loading…
Cancel
Save