গত পাঠে কীভাবে অবস্থানের ডেটা ক্যাপচার করতে একটি জিপিএস সেন্সর ব্যবহার করতে হয় তা আমরা শিখেছিলাম। খাদ্যসামগ্রীতে ভর্তি একটি ট্রাকের অবস্থান এবং এটির যাত্রার জন্য এই ডেটাটি ব্যবহার করতে, এটি ক্লাউডে আইওটি সার্ভিসে প্রেরণ করতে হবে এবং তারপরে কোথাও সংরক্ষণ করা দরকার।
এই পাঠে আইওটি ডেটা সঞ্চয় করার বিভিন্ন উপায় সম্পর্কে আমরা শিখব এবং সার্ভারলেস কোড ব্যবহার করে কীভাবে আইওটি পরিষেবা থেকে ডেটা সংরক্ষণ করা যায় তাও শিখতে পারবো।
এই পাঠে আমরা দেখবো:
* [কাঠামোগত এবং কাঠামোবিহীন ডেটা](#কাঠামোগত-এবং-কাঠামোবিহীন-ডেটা)
* [GPS ডেটা IoT Hub এ প্রেরণ](#send-gps-data-to-an-iot-hub)
* [Hot, Warm, এবং Cold Path](#Hot-Warm-এবং-Cold-Path)
* [সার্ভারবিহীন কোড ব্যবহার করে জিপিএস ইভেন্টগুলি পরিচালনা](#সার্ভারবিহীন-কোড-ব্যবহার-করে-জিপিএস-ইভেন্টগুলি-পরিচালনা)
কম্পিউটার সিস্টেমগুলি ডেটা নিয়ে কাজ করে এবং এই ডেটা বিভিন্ন আকার এবং ধরণের হয়ে থাকে। এটি একক সংখ্যা থেকে শুরু করে প্রচুর পরিমাণে টেক্সট, ভিডিও, চিত্র বা আইওটি ডেটা হতে পারে। ডেটা সাধারণত দুই ভাগে বিভক্ত করা যায় - *কাঠামোগত* ডেটা এবং *কাঠামোবিহীন* ডেটা।
* **কাঠামোগত ডেটা (Structured Data)** হল এমন ধরণের ডেটা যা একটি সংজ্ঞায়িত, অনমনীয় কাঠামোযুক্ত, যা পরিবর্তিত হয়না এবং সাধারণত টেবিল আকারে সাজানো যায় এবং অন্যান্য ডেটার সাথে কোনোভাবে সম্পর্কিত করা যায়। একটি উদাহরণ হল কোনো ব্যক্তির নাম, জন্ম তারিখ এবং ঠিকানা সহ বিশদ বিবরণ।
* **কাঠামোবিহীন ডেটা (Unstructured Data)** হল একটি অসংজ্ঞায়িত, নমনীয় কাঠামোযুক্ত ডেটা, যা ঘন ঘন কাঠামো পরিবর্তন করতে পারে। একটি উদাহরণ হলো - লিখিত নথি বা স্প্রেডশিট ।
✅ আর কী কী উদাহরণ আমরা কাঠামোগত এবং কাঠামোবিহীন ডেটাতে ভাবতে পারি তা চিন্তা করি।
> 💁 এছাড়াও আধা-কাঠামোগত (Semi-Structured) ডেটা রয়েছে যা কাঠামোগত, তবে তথ্যের নির্দিষ্ট টেবিল আকারে সাজানো যায়না ।
আইওটি ডেটা সাধারণত কাঠামোবিহীন ডেটা (Unstructured Data) হিসাবে বিবেচিত হয়।
কল্পনা করি আমরা একটি বড় বাণিজ্যিক খামারের জন্য যানবাহনের বহরে আইওটি ডিভাইস যুক্ত করেছি। বিভিন্ন ধরণের গাড়ির জন্য বিভিন্ন ডিভাইস ব্যবহার করার দরকার হতে পারে। উদাহরণস্বরূপ:
* ট্রাক্টরের জন্য জিপিএস ডেটা দরকার হতে পারে এটি নিশ্চিত করার জন্য যে তারা সঠিক খামারে বা ক্ষেতে কাজ করছে
* চালকরা নিরাপদে গাড়ি চালাচ্ছে কিনা, ড্রাইভারের পরিচয় নিশ্চিতকরণ এবং কতক্ষণ কাজ করছে তা নিশ্চিত করার জন্য খাদ্যসামগ্রী পরিবহনের ট্রাকগুলিতে জিপিএস ডেটার পাশাপাশি গতিসংক্রান্ত ডেটাও প্রয়োজন।
* রেফ্রিজারেটেড ট্রাকের জন্য তাপমাত্রার তথ্য খুব গুরুত্বপূর্ণ যাতে খাবার খুব গরম বা ঠান্ডা না হয় এবং পরিবহণের সময় তা নষ্ট না হয়।
এই ডেটা পরিবর্তিত হতে পারে। উদাহরণস্বরূপ, যদি আইওটি ডিভাইসটি একটি ট্রাকের ক্যাবে থাকে, তবে ট্রেলার পরিবর্তনের সাথে সাথে ডেটাও পরিবর্তিত হতে পারে, উদাহরণস্বরূপ যখন একটি রেফ্রিজারেটেড ট্রেলার ব্যবহার করা হবে, তখনই শুধু তাপমাত্রার ডেটা প্রেরণ করা হবে।
✅ আর কোন কোন আইওটি ডেটা গ্রহণ যেতে পারে? ট্রাকগুলি যে ধরণের বোঝা বহন করতে পারে সে সম্পর্কে একটু চিন্তা করি এবং সেইসাথে রক্ষণাবেক্ষণের ডেটা সম্পর্কেও ভাবা যেতে পারে।
এই তথ্য যানবাহনের উপর নির্ভর করে পরিবর্তিত হয়, কিন্তু এসব তথ্যাবলি আসলে প্রক্রিয়াকরণের জন্য একই IoT সার্ভিসে পাঠানো হয়। আইওটি সার্ভিসটিকে এই কাঠামোবিহীন ডেটা প্রক্রিয়া করতে পারতে হবে, এটিকে এমনভাবে সংরক্ষণ করতে হবে যা এটি অনুসন্ধান বা বিশ্লেষণের অনুমতি দেয় আবার এই ডেটা বিভিন্ন কাঠামোর সাথেও যেন কাজ করতে পারে।
### SQL এবং NoSQL স্টোরেজ
ডেটাবেসগুলি এমন পরিষেবা যা ডেটা সংরক্ষণ এবং কুয়েরি করার সুযোগ দেয়। ডাটাবেস দুই প্রকার হয় - SQL এবং NoSQL
#### SQL databases
প্রথমদিকের ডাটাবেসগুলো ছিল রিলেশনাল ডাটাবেস ম্যানেজমেন্ট সিস্টেমস (আরডিবিএমএস), বা রিলেশনাল ডাটাবেস। স্ট্রাকচার্ড ক্যোয়ারী ল্যাঙ্গুয়েজ (এসকিউএল) এখানে ডেটা যোগ, অপসারণ, আপডেট বা কোয়েরি করার জন্য তাদের সাথে ইন্টারঅ্যাক্ট করার পরে এটি এসকিউএল ডেটাবেস নামেও পরিচি্তি লাভ করে। এই ডাটাবেসগুলো একটি স্কিমা নিয়ে গঠিত যা স্প্রেডশীটের মতই ডেটা টেবিলের একটি সু-সংজ্ঞায়িত সেট। প্রতিটি টেবিলে একাধিক নামযুক্ত কলাম রয়েছে। যখন ডেটা যোগ বা insert করা, টেবিলে একটি সারি যোগ করা, প্রতিটি কলামে মান রাখা - এসব করা যায়। এটি ডেটাগুলিকে একটি অত্যন্ত কঠোর কাঠামোর মধ্যে রাখে - যদিও কলামগুলি আমরা চাইলে খালি রাখতে পারি, তবে একটি নতুন কলাম যুক্ত করতে চাইলে অবশ্যই বিদ্যমান সারির (ROW) মানগুলি পূরণ করতে হবে। এই ডেটাবেসগুলি রিলেশনাল - তাই এখানে একটি টেবিলের অন্যটির সাথে সম্পর্ক থাকতে পারে।
![A relational database with the ID of the User table relating to the user ID column of the purchases table, and the ID of the products table relating to the product ID of the purchases table](../../../../images/sql-database.png)
উদাহরণস্বরূপ, যদি কোন একটি টেবিলে আমরা কোনো ব্যবহারকারীর ব্যক্তিগত বিবরণ সংরক্ষণ করি, তাহলে প্রতি ব্যবহারকারীর জন্য অভ্যন্তরীণ স্বতন্ত্র (UNIQUE) আইডি থাকবে যা ব্যবহারকারীর নাম এবং ঠিকানা সম্বলিত সারিতে ব্যবহৃত হয়। আমরা যদি সেই ব্যবহারকারী সম্পর্কে অন্যান্য বিবরণ যেমন তাদের ক্রয় তালিকা অন্য টেবিলে সংরক্ষণ করতে চাই, তাহলে সেই ব্যবহারকারীর আইডির জন্য আমাদের নতুন টেবিলে একটি কলাম থাকবে। যখন আমরা কোন ব্যবহারকারী্র তথ্য খুঁজবো, আমরা তাদের আইডি ব্যবহার করে তাদের ব্যক্তিগত তথ্য এক টেবিল থেকে এবং অন্য টেবিল থেকে তাদের কেনাকাটার সকল তথ্য পেয়ে যাব।
এসকিউএল ডেটাবেসগুলি কাঠামোগত ডেটা সংরক্ষণের জন্য এবং স্কিমার সাথে সামঞ্জস্য রাখার জন্য আদর্শ।
✅ এসকিউএল ব্যবহারের অভিজ্ঞতা না থাকলে [SQL page - Wikipedia](https://wikipedia.org/wiki/SQL) থেকে বিস্তারিত জানতে পারবো।
কিছু বহুল পরিচিত এসকিউএল ডেটাবেস হলো Microsoft SQL Server, MySQL এবং PostgreSQL ।
✅ কিছু গবেষণা করা যাক: এসকিউএল ডেটাবেস এবং এদের কর্মপরিধি সম্পর্কে জ্ঞান অর্জন করি।
#### NoSQL ডেটাবেস
NoSQL ডেটাবসেসের নামের আগে NO বা 'না' রাখার কারণই হলো তাদের সেই সুগঠিত কাঠামো নেই। তারা 'ডকুমেন্ট ডেটাবেস' নামেও পরিচিত কারণ তারা ডকুমেন্টের মতো অসংগঠিত ডেটা সংরক্ষণ করতে পারে।
> 💁 এক্ষেত্রে জেনে রাখা ভালো যে কিছু NoSQL ডেটাবেসে আমরা SQL এর মত করে কুয়েরি করতে পারবো।
![Documents in folders in a NoSQL database](../../../../images/noqsl-database.png)
NoSQL ডাটাবেসের একটি পূর্বনির্ধারিত স্কিমা নেই যা ডেটা কিভাবে সংরক্ষণ করা হয় তা সীমাবদ্ধ করবে, বরং এর পরিবর্তে আমরা সাধারণত JSON ডকুমেন্ট ব্যবহার করে যেকোনো অবিক্রিত ডেটা সন্নিবেশ করতে পারি। এই ডকুমেন্টগুলো আমাদের কম্পিউটারের ফাইলের মতো ফোল্ডারে সংগঠিত হতে পারে। প্রতিটি ডকুমেন্টে ভিন্ন ভিন্ন ফিল্ড থাকতে পারে - উদাহরণস্বরূপ, যদি আমরা আমাদের খামারের যানবাহন থেকে আইওটি ডেটা সংরক্ষণ করি, কারও কারও জন্য অ্যাকসিলরোমিটার এবং গতির ডেটার ফিল্ড থাকতে পারে, অন্যদের ট্রেলারে তাপমাত্রার ফিল্ড থাকতে পারে। যদি আমরা একটি নতুন ধরণের ট্রাক যোগ করতে চাই, যেমন একটি বিল্ট-ইন স্কেল যুক্ত গাড়ি যা এতে থাকা ওজন ট্র্যাক করতে পারে, তাহলে আমাদের IoT ডিভাইসটি এই নতুন ফিল্ডটি যোগ করতে পারে এবং এটি ডাটাবেসের কোন পরিবর্তন ছাড়াই সংরক্ষণ করা যাবে।
কিছু সুপরিচিত NoSQL database হলো Azure CosmosDB, MongoDB এবং CouchDB ।
✅ একটু গবেষণা করা যাক: নোএসকিউএল ডেটাবেস এবং এদের কর্মপরিধি সম্পর্কে জ্ঞান অর্জন করি।
এই পাঠে, আমরা আইওটি ডেটা সঞ্চয় (Store) করতে NoSQL স্টোরেজ ব্যবহার করব।
## GPS ডেটা IoT Hub এ প্রেরণ
গত পাঠে আমরা আমাদের আইওটি ডিভাইসের সাথে সংযুক্ত একটি জিপিএস সেন্সর থেকে জিপিএস ডেটা ক্যাপচার করেছি। এই আইওটি ডেটা ক্লাউডে সংরক্ষণ করতে, তা একটি আইওটি পরিষেবাতে পাঠাতে হবে। এবারও আমরা Azure IoT Hub ব্যবহার করব, একই IoT ক্লাউড পরিষেবা যা আমরা আগের প্রজেক্টে ব্যবহার করেছিলাম।
![Sending GPS telemetry from an IoT device to IoT Hub](../../../../images/gps-telemetry-iot-hub.png)
### কাজ - GPS ডেটা IoT Hub এ প্রেরণ
1. নতুন একটি আইওটি হাব খুলতে হবে free tier এর ।
> ⚠️ এক্ষেত্রে [প্রজেক্ট-২ লেসন-৪ থেকে আইওটি হাব তৈরীর নির্দেশাবলি অনুসরণ করা যাবে](../../../../2-farm/lessons/4-migrate-your-plant-to-the-cloud/README.md#create-an-iot-service-in-the-cloud) প্রয়োজনবোধে।
নতুন একটি Resource Group খোলার বিষয়টি মনে রাখতে হবে, যেটির নাম `gps-sensor` দেয়া যায় নতুন IoT Hub এর জন্য একটি ইউনিক নাম যেমন `gps-sensor-<your name>` দেয়া যেতে পারে।
> 💁 যদি পূর্ববর্তী প্রজেক্টে ব্যবহৃত আইওটি হাব থাকে, সেটিও পুনরায় ব্যবহার করা যাবে। এক্ষেত্রে আইওটি হাব এবং রিসোর্স গ্রুপের নাম সঠিকভাবে ব্যবহার করতে হবে সার্ভিস তৈরির সময়।
1. হাবে একটি নতুন ডিভাইস যোগ করি এবং `gps-sensor` নাম দিই। কানেকশন স্ট্রিং টি নোট রাখি
1. আগের ধাপ থেকে ডিভাইস সংযোগ স্ট্রিং ব্যবহার করে নতুন আইওটি হাব -এ জিপিএস ডেটা পাঠাতে ডিভাইস কোড আপডেট করতে হবে।
> ⚠️ এক্ষেত্রে [প্রজেক্ট-২ লেসন-৪ থেকে আইওটি সার্ভিসের সাথে ডিভাইস সংযোজনের নির্দেশাবলি ](../../../../2-farm/lessons/4-migrate-your-plant-to-the-cloud/README.md#connect-your-device-to-the-iot-service) অনুসরণ করা যাবে।
1. যখন জিপিএস ডেটা প্রেরণ করব, তখন এটি নিম্নলিখিত বিন্যাসে JSON হিসাবে করতে হবে:
```json
{
"gps" :
{
"lat" : <latitude>,
"lon" : <longitude>
}
}
```
1. প্রতি মিনিটে জিপিএস ডেটা পাঠাতে হবে যাতে দৈনিক ম্যাসেজ ব্যবহার এর লিমিট শেষ না হয়।
আমরা যদি Wio টার্মিনাল ব্যবহার কর্রি, তাহলে সমস্ত প্রয়োজনীয় লাইব্রেরি যোগ করতে হবে এবং একটি NTP সার্ভার ব্যবহার করে সময় নির্ধারণ করার প্রয়োজন হবে। গত পাঠ থেকে বিদ্যমান কোড ব্যবহার করে , আমাদের কোডটি দ্বারা নিশ্চিত করতে হবে যে এটি জিপিএস লোকেশন পাঠানোর আগে সিরিয়াল পোর্ট থেকে সমস্ত ডেটা পড়েছে। JSON ডকুমেন্ট তৈরি করতে নিম্নলিখিত কোডটি ব্যবহার করি:
```cpp
DynamicJsonDocument doc(1024);
doc["gps"]["lat"] = gps.location.lat();
doc["gps"]["lon"] = gps.location.lng();
```
ভার্চুয়াল আইওটি ডিভাইস ব্যবহার করলে, এটির জন্য প্রয়োজনীয় সমস্ত লাইব্রেরি ইনস্টল করার বিষয়টি মনে রাখতে হবে।
রাস্পবেরি পাই এবং ভার্চুয়াল আইওটি উভয় ডিভাইসের জন্য, অক্ষাংশ এবং দ্রাঘিমাংশের মানগুলি পেতে গত পাঠ থেকে বিদ্যমান কোডটি ব্যবহার করে নিম্নলিখিত কোড সহ তাদের সঠিক JSON ফর্ম্যাটে পাঠাতে হবে:
> 💁 প্রয়োজনীয় সকল কোড [code/wio-terminal](code/wio-terminal), [code/pi](code/pi) বা [code/virtual-device](code/virtual-device) ফোল্ডারে পাওয়া যাবে ।
Run your device code and ensure messages are flowing into IoT Hub using the `az iot hub monitor-events` CLI command.
ডিভাইস কোডটি রান করে নিশ্চিত করতে হবে যে বার্তাগুলি আইওটি হাবের মধ্যে প্রবাহিত হচ্ছে `az iot hub monitor-events` এর মাধ্যমে, সিএলআই কমান্ড ব্যবহার করে।
## Hot, Warm, এবং Cold Path
একটি IoT ডিভাইস থেকে ক্লাউডে প্রবাহিত ডেটা সবসময় রিয়েল টাইমে প্রসেস করা হয় না। কিছু ডেটা রিয়েল টাইম প্রক্রিয়াকরণের প্রয়োজন হয়, কিছু ডেটা অল্প কিছুক্ষণ পরে প্রক্রিয়া করা যায়, এবং অন্যান্য ডেটা অনেক পরে প্রক্রিয়া করলেও হয়। বিভিন্ন সময়ে ডেটা প্রক্রিয়া করে এমন বিভিন্ন পরিষেবাতে তথ্য প্রবাহকে Hot, Warm এবং Cold Path বলা হয়।
### Hot Path
হট পাথ (Hot Path) এমন ডেটা বোঝায় যা রিয়েল টাইমে বা রিয়েল টাইমের কাছাকাছি সময়েই প্রক্রিয়াকরণের প্রয়োজন হয়। এলার্ট দেয়ার জন্য যেমন - যে কোনও গাড়ি একটি ডিপোর কাছে আসছে অথবা একটি রেফ্রিজারেটেড ট্রাকের তাপমাত্রা খুব বেশি এমন পরিস্থিতির মোকাবেলা করতে সতর্কতার জন্য হট পাথ ডেটা ব্যবহার করা হয়।
হট পাথ ডেটা ব্যবহার করার জন্য, ক্লাউড পরিষেবাগুলি কোড পাওয়ার সাথে সাথে আমাদের ইভেন্টগুলিতে সাড়া দেবে।
### Warm path
উষ্ণ পথ (Warm path) বলতে এমন তথ্যকে বোঝায় যা প্রাপ্তির পরে অল্প কিছুক্ষণ সময় নিয়ে প্রক্রিয়া করা যায়, উদাহরণস্বরূপ রিপোর্টিং বা স্বল্পমেয়াদী বিশ্লেষণ। আগের দিনের সংগৃহীত ডেটা ব্যবহার করে গাড়ির মাইলেজের দৈনিক রিপোর্টের জন্য এই ধরণের পদ্ধতি ব্যবহার করা হয়।
ক্লাউড সার্ভিসের মাধ্যমে এই ডেটা এমনভাবে স্টোর করা হয় যাতে দ্রুত অ্যাক্সেস করা যায়।
### Cold path
ঠান্ডা পথ (Cold path) বলতে ঐতিহাসিক তথ্য বোঝায়, দীর্ঘমেয়াদে তথ্য সংরক্ষণ করে যখনই প্রয়োজন হয় তখন বিশ্লেষণ করা হবে। উদাহরণস্বরূপ, যানবাহনের বার্ষিক মাইলেজ রিপোর্ট পেতে ঠান্ডা পথ ব্যবহার করা যায় অথবা জ্বালানি খরচ কমানোর জন্য সবচেয়ে অনুকূল রুট খুঁজে বের করার জন্য রুট বিশ্লেষণ চালাতেও এটি ব্যবহার করা যায় ।
কোল্ড পাথ ডেটা সাধারণত data warehouse এ সংরক্ষিত হয় - ডেটাগুলির বড় পরিমাণে সংরক্ষণের জন্য ডিজাইন করা ডেটাবেস যা কখনও পরিবর্তন হবে না এবং দ্রুত এবং সহজেই কুয়েরি করা যাবে। সাধারণত ক্লাউড অ্যাপ্লিকেশনে নিয়মিতভাবে প্রতিদিন, সপ্তাহ বা মাসে একটি নিয়মিত সময়ে চলবে উষ্ণ পথের স্টোরেজ থেকে ওয়্যারহাউসে এই ডেটা স্থানান্তর করার কাজ।
✅ এই পাঠগুলিতে আমরা এখন পর্যন্ত যে ডেটা ক্যাপচার করেছি সে সম্পর্কে চিন্তা করি। এগুলো কি hot, warm নাকি cold path এর তথ্য?
## সার্ভারবিহীন কোড ব্যবহার করে জিপিএস ইভেন্টগুলি পরিচালনা
একবার আমাদের আইওটি হাবের মধ্যে ডেটা প্রবাহিত হয়ে গেলে, ইভেন্ট-হাব সামঞ্জস্যপূর্ণ এন্ডপয়েন্টে প্রকাশিত ইভেন্টগুলি শোনার জন্য কিছু সার্ভারলেস কোড লিখতে পারবো। এটি উষ্ণ পথে ডেটা সংরক্ষণ করা হবে এবং পরবর্তী পাঠে যাত্রার প্রতিবেদন তৈরী করার জন্য ব্যবহার করা হবে।
![Sending GPS telemetry from an IoT device to IoT Hub, then to Azure Functions via an event hub trigger](../../../../images/gps-telemetry-iot-hub-functions.png)
### কাজ - সার্ভারবিহীন কোড ব্যবহার করে জিপিএস ইভেন্টগুলি পরিচালনা
1. Azure Functions CLI ব্যবহার করে একটি Azure Functions অ্যাপ তৈরি করি। পাইথন রানটাইম ব্যবহার করি এবং এটি একটি ফোল্ডারে তৈরি করি যার নাম `gps-trigger` এবং ফাংশন অ্যাপ প্রজেক্টের নামের জন্য একই নাম ব্যবহার করতে হবে। Virtual environment তৈরীর বিষয়টি নিশ্চিত করতে হবে।
> ⚠️ এক্ষেত্রে [প্রজেক্ট-২ লেসন-৫ থেকে আইওটি সার্ভিসের সাথে সার্ভারলেস এপ্লিকেশন তৈরীর নির্দেশাবলি](../../../../2-farm/lessons/5-migrate-application-to-the-cloud/README.md#create-a-serverless-application) অনুসরণ করা যাবে।
1. Add an IoT Hub event trigger that uses the IoT Hub's Event Hub compatible endpoint.
> ⚠️ এক্ষেত্রে [প্রজেক্ট-২ লেসন-৫ থেকে আইওটি হাব ইভেন্ট ট্রিগার তৈরীর নির্দেশাবলি](../../../../2-farm/lessons/5-migrate-application-to-the-cloud/README.md#create-an-iot-hub-event-trigger) অনুসরণ করা যাবে।
1. ইভেন্ট হাব সামঞ্জস্যপূর্ণ এন্ডপয়েন্ট সংযোগ স্ট্রিং সেট করতে হবে `local.settings.json` ফাইলে এবং `function.json` ফাইলের জন্য সেই এন্ট্রির KEY ব্যবহার করতে হবে।
1. এক্ষেত্রে Azurite app ব্যবহার করতে হবে local storage emulator হিসেবে।
1. জিপিএস ডিভাইস থেকে ইভেন্ট গ্রহণ করছে কিনা তা নিশ্চিত করতে ফাংশন অ্যাপটি চালাতে হবে। এখান থেকেই নিশ্চিত করা যাবে যে আইওটি ডিভাইসটি চলছে এবং জিপিএস ডেটা পাঠাচ্ছে।
Azure স্টোরেজ অ্যাকাউন্ট একটি সাধারণ উদ্দেশ্যে (General Purpose) ব্যবহৃত স্টোরেজ পরিষেবা যা বিভিন্ন উপায়ে ডেটা সংরক্ষণ করতে পারে। আমরা ব্লব হিসাবে, সারিতে, টেবিলে বা ফাইল হিসাবে ডেটা সংরক্ষণ করতে পারি।
### Blob storage
*ব্লব* মানে হলো বাইনারি বড় বস্তু (binary large objects) তবে যেকোন কাঠামোবিহীন ডেটার জন্য এই শব্দ ব্যবহৃত হয়। আইওটি ডেটা ধারণকারী JSON ডকুমেন্ট থেকে শুরু করে ইমেজ এবং মুভি ফাইলগুলিতেও ব্লব স্টোরেজে যেকোন ডেটা সংরক্ষণ করা যায়। ব্লব স্টোরেজে *কনটেইনার* এর ধারণা রয়েছে, এগুলো নামযুক্ত বাকেট/পাত্র যার মধ্যে ডেটা সংরক্ষণ করা যায়, একটি রিলেশনাল ডাটাবেজে টেবিলের মতো। এই পাত্রে ব্লব সংরক্ষণের জন্য এক বা একাধিক ফোল্ডার থাকতে পারে এবং প্রতিটি ফোল্ডারে অন্যান্য ফোল্ডার থাকতে পারে, যেভাবে কম্পিউটারের হার্ডডিস্কে ফাইল সংরক্ষণ করা হয়।
IoT ডেটা সংরক্ষণ করতে আমরা এই পাঠে ব্লব স্টোরেজ ব্যবহার করব।
✅ কিছু গবেষণা করা যাক:[Azure Blob Storage](https://docs.microsoft.com/azure/storage/blobs/storage-blobs-overview?WT.mc_id=academic-17441-jabenn) সম্পর্কে পড়ে আরো বিস্তারিত জানার চেষ্টা করি।
### Table storage
টেবিল স্টোরেজ আমাদের আধা কাঠামোগত ডেটা সংরক্ষণ করতে দেয়। টেবিল স্টোরেজ আসলে একটি NoSQL ডাটাবেস, তাই টেবিলের একটি সংজ্ঞায়িত সেট প্রয়োজন হয় না, কিন্তু এটি এক বা একাধিক টেবিলে ডেটা সংরক্ষণ করার জন্য ডিজাইন করা হয়েছে, প্রতিটি সারির সংজ্ঞা দিতে অনন্য কী (unique key) দিয়ে।
✅ কিছু গবেষণা করা যাক: [Azure Table Storage](https://docs.microsoft.com/azure/storage/tables/table-storage-overview?WT.mc_id=academic-17441-jabenn) সম্পর্কে পড়ে আরো বিস্তারিত জানার চেষ্টা করি।
### Queue storage
কিউ স্টোরেজ একটি সারিতে 64KB আকারের বার্তা সংরক্ষণ করতে দেয়। আমরা সারির পিছনের দিকে বার্তা যোগ করতে পা্রি এবং সেগুলি আবার সামনে থেকে পড়তে পারি। Queue এখানে বার্তাগুলিকে অনির্দিষ্টকালের জন্য সংরক্ষণ করে যতক্ষণ স্টোরেজ স্পেস রয়েছে, তাই এটি বার্তাগুলিকে দীর্ঘমেয়াদী সংরক্ষণ করতে দেয়। তারপর যখন প্রয়োজন হয় তা ব্যবহার করা যায়। উদাহরণস্বরূপ, যদি জিপিএস ডেটা প্রসেস করার জন্য একটি মাসিক কাজ চালাতে হয়, তাহলে প্রতিদিন এটিকে এক মাসের জন্য সারিতে যোগ করতে পারবো, তারপর মাসের শেষে সারির সব বার্তা একসাথে প্রক্রিয়া করতে পারবো।
✅ কিছু গবেষণা করা যাক: [Azure Queue Storage](https://docs.microsoft.com/azure/storage/queues/storage-queues-introduction?WT.mc_id=academic-17441-jabenn) সম্পর্কে পড়ে আরো বিস্তারিত জানার চেষ্টা করি।
### File storage
ফাইল স্টোরেজ হল ক্লাউডে ফাইলের স্টোরেজ এবং যে কোনও অ্যাপ বা ডিভাইস স্বীকৃত স্ট্যান্ডার্ড প্রোটোকল ব্যবহার করে সংযোগ করতে পারে। আমরা ফাইল স্টোরেজে আমাদের তথ্য রাখতে পারি, তারপরে পিসি বা ম্যাকের ড্রাইভ হিসাবে মাউন্ট করা যায়।
✅ কিছু গবেষণা করা যাক: [Azure File Storage](https://docs.microsoft.com/azure/storage/files/storage-files-introduction?WT.mc_id=academic-17441-jabenn) সম্পর্কে পড়ে আরো বিস্তারিত জানার চেষ্টা করি।
## সার্ভারবিহীন কোডকে স্টোরেজে সংযুক্তকরণ
আইওটি হাব থেকে বার্তাগুলি সঞ্চয় করতে আমাদের ফাংশন অ্যাপটিকে এখন ব্লব স্টোরেজের সাথে সংযুক্ত করতে হবে। এটি করার 2 টি উপায় রয়েছে:
* ফাংশন কোডের ভিতরে, আমাদের ব্লব স্টোরেজ Python SDK ব্যবহার করে ব্লব স্টোরেজে সংযোগ করতে হবে এবং ডেটা ব্লব হিসাবে রাখতে হবে।
* আমাদের একটি আউটপুট ফাংশন বাইন্ডিং ব্যবহার করতে হবে ফাংশনের রিটার্ন ভ্যালু ব্লোব স্টোরেজে বাইন্ড করতে এবং এক্ষেত্রে ব্লবটি স্বয়ংক্রিয়ভাবে সংরক্ষণ করতে হবে।
এই পাঠে, আমরা ব্লব স্টোরেজের সাথে কীভাবে যোগাযোগ করতে হয় তা দেখতে Python SDK ব্যবহার করব।
![Sending GPS telemetry from an IoT device to IoT Hub, then to Azure Functions via an event hub trigger, then saving it to blob storage](../../../../images/save-telemetry-to-storage-from-functions.png)
নিম্নলিখিত ফরম্যাটে ডেটা একটি JSON ব্লব হিসাবে সংরক্ষণ করা হবে:
```json
{
"device_id": <device_id>,
"timestamp" : <time>,
"gps" :
{
"lat" : <latitude>,
"lon" : <longitude>
}
}
```
### কাজ - সার্ভারবিহীন কোডকে স্টোরেজে সংযুক্তকরণ
1. একটি Azure স্টোরেজ অ্যাকাউন্ট তৈরি করে এমন একটি নাম দিই `gps<your name>`.
> ⚠️ এক্ষেত্রে [প্রজেক্ট-২ লেসন-৫ থেকে স্টোরেজ একাউন্ট তৈরীর নির্দেশাবলি](../../../../2-farm/lessons/5-migrate-application-to-the-cloud/README.md#task---create-the-cloud-resources) অনুসরণ করা যাবে।
যদি এখনও পূর্ববর্তী প্রজেক্টে্র স্টোরেজ অ্যাকাউন্ট থাকে,এটি পুনরায় ব্যবহার করা যাবে।
> 💁 এই পাঠে আমরা আমাদের Azure Functions অ্যাপটি স্থাপন করতে একই স্টোরেজ অ্যাকাউন্ট ব্যবহার করতে পারব।
1. স্টোরেজ অ্যাকাউন্টের জন্য সংযোগ স্ট্রিং পেতে নিম্নলিখিত কমান্ডটি চালাই:
```sh
az storage account show-connection-string --output table \
--name <storage_name>
```
এক্ষেত্রে `<storage_name>` এর পরিবর্তে আগের ধাপে আমাদের ব্যবহৃত স্টোরেজ এর নামটি বসাতে হবে।
1.`local.settings.json` ফাইলে স্টোরেজ একাউন্টের কানেকশন জন্য নতুন এন্ট্রি দিতে হবে, আগের ধাপের ভ্যালু ব্যবহার করে। এটির নাম দিই `STORAGE_CONNECTION_STRING` ।
1. এরপর `requirements.txt` এ স্টোরেজ পিপ প্যাকেজ ইন্সটল করার জন্য নিম্নের অংশ যোগ করি
```sh
azure-storage-blob
```
ভার্চুয়াল এনভায়রনমেন্টে এই ফাইল থেকে প্যাকেজ ইনস্টল করতে হবে।
> যদি কোন এরর থাকে, তাহলে আমাদের আমাদের ভার্চুয়াল পরিবেশে আমাদের পিপ সংস্করণটি নিম্নোক্ত কমান্ড দিয়ে সর্বশেষ সংস্করণে আপগ্রেড করা উচিত, তারপর আবার চেষ্টা করতে হবে:
>
> ```sh
> pip install --upgrade pip
> ```
1. এখানে `__init__.py` ফাইলে `iot-hub-trigger` এ নিম্নের ইম্পোর্ট স্টেটমেন্ট দিতে হবেঃ
```python
import json
import os
import uuid
from azure.storage.blob import BlobServiceClient, PublicAccess
```
JSON পড়তে এবং লিখতে `json` সিস্টেম মডিউল ব্যবহার করা হবে,`os` সিস্টেম মডিউলটি সংযোগ স্ট্রিং পড়ার জন্য ব্যবহার করা হবে, `uuid` সিস্টেম মডিউলটি GPS পড়ার জন্য একটি অনন্য আইডি তৈরি করতে ব্যবহৃত হবে।
আর `azure.storage.blob` প্যাকেজটিতে Python SDK রয়েছে blob storage এর সাথে কাজ করার জন্য।
1. এখন `main` মেথডের আগেই,নিম্নলিখিত হে্লপার ফাংশন যোগ করি:
পাইথন ব্লব এসডিকে তে যদি কোন কন্টেইনার না থাকে তবে একটি কন্টেইনার তৈরি করার জন্য কোন সহায়ক পদ্ধতি নেই। এই কোডটি `local.settings.json` ফাইল থেকে সংযোগ স্ট্রিং লোড করবে (অথবা অ্যাপ্লিকেশন সেটিংস যা ক্লাউডে রয়েছে তা থেকে ), তারপর ব্লব স্টোরেজ অ্যাকাউন্টের সাথে ইন্টারঅ্যাক্ট করার জন্য এটি থেকে একটি` BlobServiceClient` ক্লাস তৈরি করতে হবে। এটি ব্লব স্টোরেজ অ্যাকাউন্টের জন্য সমস্ত পাত্রে লুপ করে, প্রদত্ত নামের সাথে মিলিয়ে সন্ধান করে - যদি এটি একটি খুঁজে পায় তবে এটি একটি 'কনটেইনার ক্লায়েন্ট' ক্লাস ফিরিয়ে দেবে যা ব্লব তৈরি করতে কন্টেইনারের সাথে যোগাযোগ করতে পারে। যদি এটি খুঁজে না পায়, তাহলে কন্টেইনার তৈরি করা হয় এবং নতুন পাত্রে ক্লায়েন্ট রিটার্ন করা হয়।
যখন নতুন কন্টেইনার তৈরি করা হয়, তখন এতে থাকা ব্লবগুলি কুয়েরি করার জন্য সর্বজনীন অ্যাক্সেস দেওয়া হয়। এটি একটি মানচিত্রে জিপিএস ডেটা প্রদর্শন করার জন্য পরবর্তী পাঠে ব্যবহার করা হবে।
1. এই কোডের সাহায্যে আমরা প্রতিটি ইভেন্ট সংরক্ষণ করতে চাই (যা মাটির আর্দ্রতা সংরক্ষণের মত নয়), তাই লগিং স্টেটমেন্টের নীচে `মেইন` ফাংশনে `for event in events:` ল্যুপে নিম্নের কোড যোগ করি:
এই কোডটি ইভেন্ট মেটাডেটা থেকে ডিভাইস আইডি পায়, তারপর এটি একটি ব্লব নাম তৈরি করতে ব্যবহার করে। ব্লবগুলি ফোল্ডারে সংরক্ষণ করা যেতে পারে এবং ফোল্ডারের নামের জন্য ডিভাইস আইডি ব্যবহার করা হবে, তাই প্রতিটি ডিভাইসে তার সমস্ত জিপিএস ইভেন্ট একটি ফোল্ডারে থাকবে। ব্লব নামটি এই ফোল্ডার, এর পরে একটি ডকুমেন্টের নাম, ফরওয়ার্ড স্ল্যাশ দিয়ে আলাদা, লিনাক্স এবং ম্যাকওএস পাথের মতো (উইন্ডোজের মতোই, তবে উইন্ডোজ ব্যাক স্ল্যাশ ব্যবহার করে)। ডকুমেন্টের নাম হল একটি ইউনিক আইডি যা পাইথন `uuid` মডিউল ব্যবহার করে তৈরি করা হয়, যার ফাইল টাইপ `json` থাকে।
যেমন, `gps-sensor` ডিভাইস ID এর জন্য, ব্লবের নাম হতে পারে`gps-sensor/a9487ac2-b9cf-11eb-b5cd-1e00621e3648.json` ।
এরপর `get_or_create_container` হেল্পার ক্লাস ব্যবহার করে, এই কোডটি কন্টেইনার ক্লায়েন্ট পায় এরপর blob name ব্যবহার করে ব্লব ক্লায়েন্ট অবজেক্ট পায়। এই ব্লব ক্লায়েন্টগুলো বিদ্যমান ব্লব, অথবা এই ক্ষেত্রে, নতুন ব্লবকে রেফার করতে পারে।
এটি ব্লবের বডি তৈরি করে যাতে ব্লব স্টোরেজে লেখা হবে। এটি একটি JSON ডকুমেন্ট যা ডিভাইসের আইডি, টেলিমেট্রি আইওটি হাব -এ পাঠানোর সময় এবং জিপিএস টেলিমেট্রি থেকে সমন্বয় করে।
> 💁 বার্তা প্রেরণ এর সময় জানার জন্য বর্তমান সময় ব্যবহার না করে বরং এই ম্যাসেজগুলোর enqueued time বিবেচনায় নেয়া গুরুত্বপূর্ণ। ফাংশন অ্যাপ চালু না থাকলে এটি গৃহিত হওয়ার আগে কিছুক্ষণের জন্য আইওটি হাবে থাকতে পারে।
1. এবার নীচের কোড যোগ করি:
```python
logging.info(f'Writing blob to {blob_name} - {blob_body}')
> 💁 সতর্ক থাকতে হবে যে আমরা একই সময়ে IoT Hub ইভেন্ট মনিটরটি চালাচ্ছি না।
> 💁 সকল কোড [code/functions](code/functions) ফোল্ডারে রয়েছে।
### কাজ - আপলোড করা ব্লব যাচাইকরণ
1. তৈরি ব্লবগুলি দেখতে, আমরা [Azure Storage Explorer](https://azure.microsoft.com/features/storage-explorer/?WT.mc_id=academic-17441-jabenn),একটি ফ্রি টুল যা স্টোরেজ অ্যাকাউন্টগুলি দেখতে এবং পরিচালনা করতে দেয় তা ব্যবহার করতে পারি অথবা সরাসরি CLI থেকেও কাজ করা যায়।
1. CLI ব্যবহার করার জন্য প্রথমে একটি অ্যাকাউন্ট কী (KEY) প্রয়োজন হবে। এই কী পেতে নিম্নলিখিত কমান্ডটি চালাই:
```sh
az storage account keys list --output table \
--account-name <storage_name>
```
`<storage_name>` এর স্থলে আমাদের ব্যবহৃত স্টোরেজের নামটিই দিতে হবে।
`key1` এর ভ্যালু কপি করে রাখি।
1. কন্টেইনারে ব্লবগুলি তালিকাভুক্ত করতে নিম্নলিখিত কমান্ডটি চালাইঃ
```sh
az storage blob list --container-name gps-data \
--output table \
--account-name <storage_name> \
--account-key <key1>
```
`<storage_name>` এর স্থলে আমাদের ব্যবহৃত স্টোরেজের নামটিই দিতে হবে এবং `<key1>` এর জায়গায় আগের ধাপে কপি করা মানটি বসাতে হবে।
এটি সমস্ত ব্লবগুলি তালিকাভুক্ত করবে:
```output
Name Blob Type Blob Tier Length Content Type Last Modified Snapshot
gps-sensor/1810d55e-b9cf-11eb-9f5b-1e00621e3648.json BlockBlob Hot 45 application/octet-stream 2021-05-21T00:54:27+00:00
gps-sensor/18293e46-b9cf-11eb-9f5b-1e00621e3648.json BlockBlob Hot 45 application/octet-stream 2021-05-21T00:54:28+00:00
gps-sensor/1844549c-b9cf-11eb-9f5b-1e00621e3648.json BlockBlob Hot 45 application/octet-stream 2021-05-21T00:54:28+00:00
gps-sensor/1894d714-b9cf-11eb-9f5b-1e00621e3648.json BlockBlob Hot 45 application/octet-stream 2021-05-21T00:54:28+00:00
```
1. নিম্নলিখিত কমান্ড ব্যবহার করে একটি ব্লব ডাউনলোড করি:
```sh
az storage blob download --container-name gps-data \
--account-name <storage_name> \
--account-key <key1> \
--name <blob_name> \
--file <file_name>
```
`<storage_name>` এর স্থলে আমাদের ব্যবহৃত স্টোরেজের নামটিই দিতে হবে এবং `<key1>` এর জায়গায় আগের ধাপে কপি করা মানটি বসাতে হবে।
আর `<blob_name>` এর পরিবর্তে কাজের পূর্ববর্তী ধাপের `Name` কলামের আউটপুটটি বসাই ফোল্ডারের নাম সহ। এক্ষেত্রে ব্লব সংরক্ষণ করতে `<file_name>` এর জায়গায় একটি লোকাল ফাইলের জন্য নাম দিই।
একবার ডাউনলোড হয়ে গেলে, আমরা VS কোডে JSON ফাইলটি খুলতে পারব এবং আমরা জিপিএস অবস্থানের বিবরণ সহ ব্লব দেখতে পাব:
এখন যেহেতু ফাংশন অ্যাপটি কাজ করছে, আমরা এটিকে ক্লাউডে ডেপ্লয় করতে পারি।
1. আগে তৈরি করা স্টোরেজ অ্যাকাউন্ট ব্যবহার করে নতুন Azure ফাংশন অ্যাপ তৈরি করা যাক। এটির নাম দিই `gps-sensor-` এবং এর শেষে কোন ইউনিক নাম বা সংখ্যা যোগ করে দিই।
> ⚠️ এক্ষেত্রে [প্রজেক্ট-২ লেসন-৫ থেকে ফাংশন ডেপ্লয় করার নির্দেশাবলি](../../../../2-farm/lessons/5-migrate-application-to-the-cloud/README.md#task---create-the-cloud-resources) অনুসরণ করা যাবে।
1.`IOT_HUB_CONNECTION_STRING` এবং `STORAGE_CONNECTION_STRING` ভ্যালুগুলো এপ্লিকেশন সেটিংস এ আপলোড করি।
> ⚠️ এক্ষেত্রে [প্রজেক্ট-২ লেসন-৫ থেকে এপ্লিকেশন সেটিংস আপলোড করার নির্দেশাবলি](../../../../2-farm/lessons/5-migrate-application-to-the-cloud/README.md#task---upload-your-application-settings) অনুসরণ করা যাবে।
1. ্লোকাল ফাংশন এপ কে ক্লাউডে ডেপ্লয় করি।
> ⚠️ এক্ষেত্রে [প্রজেক্ট-২ লেসন-৫ থেকে ফাংশন এপ কে ক্লাউডে ডেপ্লয় করার নির্দেশাবলি](../../../../2-farm/lessons/5-migrate-application-to-the-cloud/README.md#task---deploy-your-functions-app-to-the-cloud) অনুসরণ করা যাবে।
---
## 🚀 চ্যালেঞ্জ
জিপিএস ডেটা পুরোপুরি সঠিক নয়, এবং সনাক্ত করা অবস্থানগুলি কয়েক মিটার পর্যন্ত ভুল হতে পারে, আর টানেল এবং লম্বা ভবনের এলাকায় তা আরো বেশি হয়ে থাকে।
স্যাটেলাইট নেভিগেশন কীভাবে এটি কাটিয়ে উঠতে পারে সে সম্পর্কে চিন্তা করি। আমাদের sat-nav এর কোন ডেটা আছে যা এটি আমাদেরকে অবস্থানে্র ব্যাপারে আরও ভাল ভবিষ্যদ্বাণী করতে দেয়?
* কাঠামোগত ডেটা এর ব্যাপারে [Data model - Wikipedia](https://wikipedia.org/wiki/Data_model) থেকে পড়তে পারি।
* Semi-structured ডেটা এর ব্যাপারে [Semi-structured data - Wikipedia](https://wikipedia.org/wiki/Semi-structured_data) থেকে পড়তে পারি।
* কাঠামোবিহীন ডেটা এর ব্যাপারে [Unstructured data - Wikipedia](https://wikipedia.org/wiki/Unstructured_data) থেকে পড়তে পারি।
* Azure Storage এবং বিভিন্ন ধরণের স্টোরেজ সম্পর্কে [Azure Storage documentation](https://docs.microsoft.com/azure/storage/?WT.mc_id=academic-17441-jabenn) থেকে পড়তে পারি।