Ver3.0 ๐ ๋ผ์ฆ๋ฒ ๋ฆฌํ์ด์ AWS IoT Core ์ฐ๋ ์๋ฒฝ ๊ฐ์ด๋ - ์ค์ ์์ค์ฝ๋๋ก ๋ฐฐ์ฐ๋ IoT ํด๋ผ์ฐ๋ ์ฐ๊ฒฐ

๐ ๋ผ์ฆ๋ฒ ๋ฆฌํ์ด์ AWS IoT Core ์ฐ๋ ์๋ฒฝ ๊ฐ์ด๋ - ์ค์ ์์ค์ฝ๋๋ก ๋ฐฐ์ฐ๋ IoT ํด๋ผ์ฐ๋ ์ฐ๊ฒฐ
์ด๋ณด์๋ ๋ฐ๋ผํ ์ ์๋ ๋จ๊ณ๋ณ ๊ตฌํ ๋ฐฉ๋ฒ
๐ฏ ์ ๋ผ์ฆ๋ฒ ๋ฆฌํ์ด์ AWS IoT Core๋ฅผ ์ฐ๋ํ ๊น?
์๋ ! ์ค๋์ ์ ๋ง ์ฌ๋ฏธ์๋ ์ฃผ์ ๋ฅผ ๊ฐ์ง๊ณ ์์ด. ๋ฐ๋ก ๋ผ์ฆ๋ฒ ๋ฆฌํ์ด์ AWS IoT Core๋ฅผ ์ฐ๋ํ๋ ๋ฐฉ๋ฒ์ด์ผ. ์์ฆ IoT(์ฌ๋ฌผ์ธํฐ๋ท) ํ๋ก์ ํธ๋ฅผ ํ๋ค ๋ณด๋ฉด ์ผ์ ๋ฐ์ดํฐ๋ฅผ ํด๋ผ์ฐ๋๋ก ๋ณด๋ด๊ณ , ์๊ฒฉ์ผ๋ก ๋๋ฐ์ด์ค๋ฅผ ์ ์ดํ๊ณ ์ถ์ ๋๊ฐ ๋ง์์? ๐ค
๋ผ์ฆ๋ฒ ๋ฆฌํ์ด๋ ์ ๋ ดํ๋ฉด์๋ ๊ฐ๋ ฅํ ์ฑ๊ธ๋ณด๋ ์ปดํจํฐ๊ณ , AWS IoT Core๋ ์๋ง์กด์ด ์ ๊ณตํ๋ ๊ด๋ฆฌํ ํด๋ผ์ฐ๋ ์๋น์ค์ผ. ์ด ๋์ ์ฐ๊ฒฐํ๋ฉด ์ ๋ง ๋ฉ์ง ์ผ๋ค์ ํ ์ ์์ด:
โจ ์ฐ๋ํ๋ฉด ํ ์ ์๋ ๊ฒ๋ค
โข ์ผ์ ๋ฐ์ดํฐ๋ฅผ ์ค์๊ฐ์ผ๋ก ํด๋ผ์ฐ๋์ ์ ์ก
โข ์ ์ธ๊ณ ์ด๋์๋ ๋๋ฐ์ด์ค ์๊ฒฉ ์ ์ด
โข ์์ง๋ ๋ฐ์ดํฐ๋ฅผ ๋ถ์ํ๊ณ ์๊ฐํ
โข ๋ค๋ฅธ AWS ์๋น์ค(Lambda, DynamoDB ๋ฑ)์ ์๋ ์ฐ๊ณ
โข ๋๋ฐ์ด์ค ์ํ ๋ชจ๋ํฐ๋ง ๋ฐ ์๋ฆผ ์ค์
ํนํ ์ฌ๋ฅ๋ท ๊ฐ์ ํ๋ซํผ์์ IoT ๊ด๋ จ ํ๋ก์ ํธ๋ฅผ ์๋ขฐ๋ฐ๊ฑฐ๋, ์์ ์ IoT ๊ฐ๋ฐ ์ฌ๋ฅ์ ๊ณต์ ํ๋ ค๋ ์ฌ๋๋ค์๊ฒ ์ด ๊ธฐ์ ์ ์ ๋ง ์ ์ฉํด. ์ค์ ๋ก ๋ง์ ๊ฐ๋ฐ์๋ค์ด ์ด๋ฐ ํด๋ผ์ฐ๋ ์ฐ๋ ๊ธฐ์ ์ ๋ฐฐ์ฐ๊ณ ์ถ์ด ํ๊ฑฐ๋ ! ๐ช
๐ ๏ธ ์ฌ์ ์ค๋น์ฌํญ
๋ณธ๊ฒฉ์ ์ผ๋ก ์ฝ๋๋ฅผ ์์ฑํ๊ธฐ ์ ์ ํ์ํ ๊ฒ๋ค์ ๋จผ์ ์ค๋นํด๋ณด์. ๊ฑฑ์ ๋ง, ํ๋ํ๋ ์ฐจ๊ทผ์ฐจ๊ทผ ์ค๋ช ํด์ค๊ฒ! ๐
1ํ๋์จ์ด ์ค๋น
โข ๋ผ์ฆ๋ฒ ๋ฆฌํ์ด (3 Model B ์ด์ ๊ถ์ฅ, 4๊ฐ ๋ ์ข์!)
โข MicroSD ์นด๋ (์ต์ 16GB, Class 10 ์ด์)
โข ์ ์ ์ด๋ํฐ (5V 2.5A ์ด์)
โข ์ธํฐ๋ท ์ฐ๊ฒฐ (WiFi ๋๋ ์ด๋๋ท)
2์ํํธ์จ์ด ์ค๋น
โข Raspberry Pi OS (Raspbian) ์ค์น
โข Python 3.7 ์ด์
โข AWS ๊ณ์ (ํ๋ฆฌํฐ์ด๋ก ์์ ๊ฐ๋ฅ!)
โข AWS CLI ์ค์น
3ํ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
โข AWSIoTPythonSDK
โข boto3 (AWS SDK for Python)
โข ๊ธฐํ ์ผ์ ๊ด๋ จ ๋ผ์ด๋ธ๋ฌ๋ฆฌ (ํ๋ก์ ํธ์ ๋ฐ๋ผ)
๐ก ํ: ๋ผ์ฆ๋ฒ ๋ฆฌํ์ด๋ฅผ ์ฒ์ ์ฌ์ฉํ๋ค๋ฉด, SSH๋ฅผ ํ์ฑํํด์ ์๊ฒฉ์ผ๋ก ์ ์ํ๋ ๊ฒ ํธํด. ๋ชจ๋ํฐ ์์ด๋ ์์ ํ ์ ์๊ฑฐ๋ !
โ๏ธ AWS IoT Core ์ค์ ํ๊ธฐ
์, ์ด์ AWS ์ฝ์์์ IoT Core๋ฅผ ์ค์ ํด๋ณผ ๊ฑฐ์ผ. ์ด ๋ถ๋ถ์ด ์ข ๋ณต์กํด ๋ณด์ผ ์ ์๋๋ฐ, ์ฒ์ฒํ ๋ฐ๋ผ์ค๋ฉด ๋ฌธ์ ์์ด! ๐
๐ Step 1: IoT Thing ์์ฑ
AWS IoT Core์์ "Thing"์ ์ค์ ๋ฌผ๋ฆฌ์ ๋๋ฐ์ด์ค๋ฅผ ๋ํ๋ด๋ ๊ฐ์ ๊ฐ์ฒด์ผ. ์ฐ๋ฆฌ์ ๋ผ์ฆ๋ฒ ๋ฆฌํ์ด๋ฅผ ๋ฑ๋กํ๋ ๊ฑฐ์ง.
AWS ์ฝ์์์ ์งํํ๋ ์์:
1. AWS Management Console ๋ก๊ทธ์ธ
2. IoT Core ์๋น์ค ๊ฒ์ ๋ฐ ์ ํ
3. ์ผ์ชฝ ๋ฉ๋ด์์ "๊ด๋ฆฌ" โ "์ฌ๋ฌผ" ํด๋ฆญ
4. "์ฌ๋ฌผ ์์ฑ" ๋ฒํผ ํด๋ฆญ
5. "๋จ์ผ ์ฌ๋ฌผ ์์ฑ" ์ ํ
6. ์ฌ๋ฌผ ์ด๋ฆ ์
๋ ฅ (์: MyRaspberryPi)
7. ๋ค์ ๋จ๊ณ๋ก ์งํ
๐ Step 2: ์ธ์ฆ์ ์์ฑ ๋ฐ ๋ค์ด๋ก๋
๋ณด์์ด ์ ๋ง ์ค์ํด! AWS IoT Core๋ X.509 ์ธ์ฆ์๋ฅผ ์ฌ์ฉํด์ ๋๋ฐ์ด์ค๋ฅผ ์ธ์ฆํด. ์ด ์ธ์ฆ์๋ค์ ๋ฐ๋์ ์์ ํ๊ฒ ๋ณด๊ดํด์ผ ํด.
โ ๏ธ ์ฃผ์์ฌํญ: ์ธ์ฆ์๋ ์์ฑ ์ ํ ๋ฒ๋ง ๋ค์ด๋ก๋ํ ์ ์์ด. ๋์ค์ ๋ค์ ๋ฐ์ ์ ์์ผ๋ ๊ผญ ๋ฐฑ์ ํด๋ฌ!
๋ค์ด๋ก๋ํด์ผ ํ ํ์ผ๋ค:
โข ๋๋ฐ์ด์ค ์ธ์ฆ์ (xxxxx-certificate.pem.crt)
โข ํ๋ผ์ด๋น ํค (xxxxx-private.pem.key)
โข ํผ๋ธ๋ฆญ ํค (xxxxx-public.pem.key)
โข ๋ฃจํธ CA ์ธ์ฆ์ (AmazonRootCA1.pem)
๐ Step 3: ์ ์ฑ (Policy) ์์ฑ ๋ฐ ์ฐ๊ฒฐ
์ ์ฑ ์ ๋๋ฐ์ด์ค๊ฐ AWS IoT Core์์ ๋ฌด์์ ํ ์ ์๋์ง ์ ์ํ๋ ๊ฑฐ์ผ. JSON ํ์์ผ๋ก ์์ฑ๋์ง.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"iot:Connect"
],
"Resource": "arn:aws:iot:ap-northeast-2:YOUR_ACCOUNT_ID:client/MyRaspberryPi"
},
{
"Effect": "Allow",
"Action": [
"iot:Publish",
"iot:Receive"
],
"Resource": "arn:aws:iot:ap-northeast-2:YOUR_ACCOUNT_ID:topic/*"
},
{
"Effect": "Allow",
"Action": [
"iot:Subscribe"
],
"Resource": "arn:aws:iot:ap-northeast-2:YOUR_ACCOUNT_ID:topicfilter/*"
}
]
}
์ด ์ ์ฑ ์ ๋๋ฐ์ด์ค๊ฐ:
โข IoT Core์ ์ฐ๊ฒฐํ ์ ์๊ณ (Connect)
โข ๋ชจ๋ ํ ํฝ์ ๋ฉ์์ง๋ฅผ ๋ฐํํ ์ ์๊ณ (Publish)
โข ๋ชจ๋ ํ ํฝ์ ๊ตฌ๋
ํ ์ ์๊ฒ (Subscribe) ํด์ค.
๐ก ๋ณด์ ํ: ์ค์ ํ๋ก๋์ ํ๊ฒฝ์์๋ ์์ผ๋์นด๋(*) ๋์ ๊ตฌ์ฒด์ ์ธ ํ ํฝ ์ด๋ฆ์ ์ง์ ํ๋ ๊ฒ ์ข์. ๋ณด์์ด ํจ์ฌ ๊ฐํ๋๊ฑฐ๋ !
๐ Step 4: ์๋ํฌ์ธํธ ํ์ธ
AWS IoT Core ์๋ํฌ์ธํธ๋ ๋๋ฐ์ด์ค๊ฐ ์ฐ๊ฒฐํ ์ฃผ์์ผ. ์ด๊ฑธ ํ์ธํ๋ ค๋ฉด:
1. IoT Core ์ฝ์์์ "์ค์ " ๋ฉ๋ด ํด๋ฆญ
2. "๋๋ฐ์ด์ค ๋ฐ์ดํฐ ์๋ํฌ์ธํธ" ํญ๋ชฉ ํ์ธ
3. ์ฃผ์๋ฅผ ๋ณต์ฌํด๋ฌ (์: xxxxx.iot.ap-northeast-2.amazonaws.com)
๐ ๋ผ์ฆ๋ฒ ๋ฆฌํ์ด ํ๊ฒฝ ์ค์
์ด์ ๋ผ์ฆ๋ฒ ๋ฆฌํ์ด์์ ์์ ํ ์ฐจ๋ก์ผ! SSH๋ก ์ ์ํ๋ค๋ฉด ํฐ๋ฏธ๋์์ ๋ค์ ๋ช ๋ น์ด๋ค์ ์คํํด๋ณด์. ๐ฅ๏ธ
ํจํค์ง ์ ๋ฐ์ดํธ ๋ฐ Python ์ค์น
# ์์คํ
ํจํค์ง ์
๋ฐ์ดํธ
sudo apt-get update
sudo apt-get upgrade -y
# Python3 ๋ฐ pip ์ค์น ํ์ธ
python3 --version
pip3 --version
# ํ์ํ ๊ฒฝ์ฐ pip ์
๊ทธ๋ ์ด๋
sudo pip3 install --upgrade pip
AWS IoT SDK ์ค์น
# AWS IoT Python SDK ์ค์น
pip3 install AWSIoTPythonSDK
# ์ถ๊ฐ๋ก ์ ์ฉํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค
pip3 install boto3
pip3 install paho-mqtt
์ธ์ฆ์ ํ์ผ ๋ฐฐ์น
์์ ๋ค์ด๋ก๋ํ ์ธ์ฆ์ ํ์ผ๋ค์ ๋ผ์ฆ๋ฒ ๋ฆฌํ์ด๋ก ์ฎ๊ฒจ์ผ ํด. ์ฌ๋ฌ ๋ฐฉ๋ฒ์ด ์๋๋ฐ, ๊ฐ์ฅ ๊ฐ๋จํ ๋ฐฉ๋ฒ์ SCP๋ฅผ ์ฌ์ฉํ๋ ๊ฑฐ์ผ.
# ๋ผ์ฆ๋ฒ ๋ฆฌํ์ด์ certs ๋๋ ํ ๋ฆฌ ์์ฑ
mkdir -p ~/aws-iot/certs
cd ~/aws-iot/certs
# ๋ก์ปฌ PC์์ SCP๋ก ํ์ผ ์ ์ก (๋ก์ปฌ PC ํฐ๋ฏธ๋์์ ์คํ)
scp /path/to/certificate.pem.crt pi@raspberrypi.local:~/aws-iot/certs/
scp /path/to/private.pem.key pi@raspberrypi.local:~/aws-iot/certs/
scp /path/to/AmazonRootCA1.pem pi@raspberrypi.local:~/aws-iot/certs/
# ํ์ผ ๊ถํ ์ค์ (๋ผ์ฆ๋ฒ ๋ฆฌํ์ด์์)
chmod 644 ~/aws-iot/certs/*.crt
chmod 600 ~/aws-iot/certs/*.key
๐ก ํ: ํ์ผ ๊ถํ ์ค์ ์ด ์ค์ํด! ํ๋ผ์ด๋น ํค๋ ์์ ์๋ง ์ฝ์ ์ ์๋๋ก 600์ผ๋ก ์ค์ ํด์ผ ๋ณด์์ด ์ ์ง๋ผ.
๐ป ์ค์ ์์ค์ฝ๋ - ๊ธฐ๋ณธ ์ฐ๊ฒฐ
๋๋์ด ์ฝ๋๋ฅผ ์์ฑํ ์๊ฐ์ด์ผ! ๋จผ์ ๊ฐ์ฅ ๊ธฐ๋ณธ์ ์ธ ์ฐ๊ฒฐ ์ฝ๋๋ถํฐ ์์ํด๋ณด์. ์ด ์ฝ๋๋ ๋ผ์ฆ๋ฒ ๋ฆฌํ์ด๋ฅผ AWS IoT Core์ ์ฐ๊ฒฐํ๊ณ , ๊ฐ๋จํ ๋ฉ์์ง๋ฅผ ๋ฐํํ๋ ์์ ์ผ. ๐
๐ basic_connection.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
AWS IoT Core ๊ธฐ๋ณธ ์ฐ๊ฒฐ ์์
๋ผ์ฆ๋ฒ ๋ฆฌํ์ด์์ AWS IoT Core์ ์ฐ๊ฒฐํ๊ณ ๋ฉ์์ง๋ฅผ ๋ฐํํฉ๋๋ค.
"""
from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTClient
import json
import time
import random
# AWS IoT Core ์ค์
IOT_ENDPOINT = "xxxxx.iot.ap-northeast-2.amazonaws.com" # ์ฌ๊ธฐ์ ์ค์ ์๋ํฌ์ธํธ ์
๋ ฅ
CLIENT_ID = "MyRaspberryPi"
TOPIC = "raspberry/data"
# ์ธ์ฆ์ ํ์ผ ๊ฒฝ๋ก
ROOT_CA = "/home/pi/aws-iot/certs/AmazonRootCA1.pem"
PRIVATE_KEY = "/home/pi/aws-iot/certs/private.pem.key"
CERTIFICATE = "/home/pi/aws-iot/certs/certificate.pem.crt"
def init_mqtt_client():
"""
MQTT ํด๋ผ์ด์ธํธ ์ด๊ธฐํ ๋ฐ ์ค์
"""
# MQTT ํด๋ผ์ด์ธํธ ์์ฑ
mqtt_client = AWSIoTMQTTClient(CLIENT_ID)
mqtt_client.configureEndpoint(IOT_ENDPOINT, 8883)
# ์ธ์ฆ์ ์ค์
mqtt_client.configureCredentials(ROOT_CA, PRIVATE_KEY, CERTIFICATE)
# MQTT ์ฐ๊ฒฐ ์ค์
mqtt_client.configureAutoReconnectBackoffTime(1, 32, 20)
mqtt_client.configureOfflinePublishQueueing(-1) # ๋ฌด์ ํ ํ์
mqtt_client.configureDrainingFrequency(2) # 2Hz๋ก ๋๋ ์ด๋
mqtt_client.configureConnectDisconnectTimeout(10) # 10์ด
mqtt_client.configureMQTTOperationTimeout(5) # 5์ด
return mqtt_client
def publish_message(client, topic, message):
"""
๋ฉ์์ง ๋ฐํ ํจ์
"""
try:
message_json = json.dumps(message)
client.publish(topic, message_json, 1)
print(f"โ
๋ฉ์์ง ๋ฐํ ์ฑ๊ณต: {message_json}")
return True
except Exception as e:
print(f"โ ๋ฉ์์ง ๋ฐํ ์คํจ: {str(e)}")
return False
def main():
"""
๋ฉ์ธ ์คํ ํจ์
"""
print("๐ AWS IoT Core ์ฐ๊ฒฐ ์์...")
# MQTT ํด๋ผ์ด์ธํธ ์ด๊ธฐํ
mqtt_client = init_mqtt_client()
# AWS IoT Core์ ์ฐ๊ฒฐ
try:
mqtt_client.connect()
print("โ
AWS IoT Core ์ฐ๊ฒฐ ์ฑ๊ณต!")
except Exception as e:
print(f"โ ์ฐ๊ฒฐ ์คํจ: {str(e)}")
return
# ๋ฉ์์ง ๋ฐํ ๋ฃจํ
message_count = 0
try:
while True:
message_count += 1
# ์ผ์ ๋ฐ์ดํฐ ์๋ฎฌ๋ ์ด์
(์ค์ ๋ก๋ ์ผ์์์ ์ฝ์ด์ด)
temperature = round(random.uniform(20.0, 30.0), 2)
humidity = round(random.uniform(40.0, 70.0), 2)
# ๋ฉ์์ง ์์ฑ
message = {
"device_id": CLIENT_ID,
"timestamp": int(time.time()),
"message_id": message_count,
"data": {
"temperature": temperature,
"humidity": humidity
}
}
# ๋ฉ์์ง ๋ฐํ
publish_message(mqtt_client, TOPIC, message)
# 5์ด ๋๊ธฐ
time.sleep(5)
except KeyboardInterrupt:
print("\nโน๏ธ ํ๋ก๊ทธ๋จ ์ข
๋ฃ ์ค...")
finally:
# ์ฐ๊ฒฐ ํด์
mqtt_client.disconnect()
print("๐ AWS IoT Core ์ฐ๊ฒฐ ํด์ ์๋ฃ")
if __name__ == "__main__":
main()
์ด ์ฝ๋์ ํต์ฌ ํฌ์ธํธ๋ฅผ ์ค๋ช ํด์ค๊ฒ:
๐ ์ฃผ์ ๊ตฌ์ฑ ์์
1. ํด๋ผ์ด์ธํธ ์ด๊ธฐํ: AWSIoTMQTTClient ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ ์๋ํฌ์ธํธ์ ์ธ์ฆ์๋ฅผ ์ค์ ํด.
2. ์ฐ๊ฒฐ ์ค์ : ์๋ ์ฌ์ฐ๊ฒฐ, ์คํ๋ผ์ธ ํ์ ๋ฑ ์์ ์ ์ธ ์ฐ๊ฒฐ์ ์ํ ์ค์ ๋ค์ด์ผ.
3. ๋ฉ์์ง ๋ฐํ: JSON ํ์์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ๊ตฌ์กฐํํด์ MQTT ํ ํฝ์ผ๋ก ๋ฐํํด.
4. ์๋ฌ ์ฒ๋ฆฌ: try-except ๋ธ๋ก์ผ๋ก ์์ ํ๊ฒ ์๋ฌ๋ฅผ ์ฒ๋ฆฌํด.
์คํ ๋ฐฉ๋ฒ
# ํ์ผ ์คํ ๊ถํ ๋ถ์ฌ
chmod +x basic_connection.py
# ํ๋ก๊ทธ๋จ ์คํ
python3 basic_connection.py
์ ์์ ์ผ๋ก ์คํ๋๋ฉด 5์ด๋ง๋ค ์จ๋์ ์ต๋ ๋ฐ์ดํฐ๊ฐ AWS IoT Core๋ก ์ ์ก๋ผ. AWS ์ฝ์์ "ํ ์คํธ" ๋ฉ๋ด์์ ํ ํฝ์ ๊ตฌ๋ ํ๋ฉด ์ค์๊ฐ์ผ๋ก ๋ฐ์ดํฐ๊ฐ ๋ค์ด์ค๋ ๊ฑธ ํ์ธํ ์ ์์ด! ๐
๐ก ๊ณ ๊ธ ๊ธฐ๋ฅ - ์๋ฐฉํฅ ํต์
์ด์ ์ข ๋ ์ฌ๋ฏธ์๋ ๊ฑธ ํด๋ณผ๊น? ๋จ์ํ ๋ฐ์ดํฐ๋ฅผ ๋ณด๋ด๊ธฐ๋ง ํ๋ ๊ฒ ์๋๋ผ, ํด๋ผ์ฐ๋์์ ๋ช ๋ น์ ๋ฐ์์ ๋ผ์ฆ๋ฒ ๋ฆฌํ์ด๋ฅผ ์ ์ดํ๋ ์๋ฐฉํฅ ํต์ ์ ๊ตฌํํด๋ณด์! ๐
๐ bidirectional_communication.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
AWS IoT Core ์๋ฐฉํฅ ํต์ ์์
๋ฉ์์ง๋ฅผ ๋ฐํํ๊ณ ๊ตฌ๋
ํ์ฌ ์๊ฒฉ ์ ์ด๋ฅผ ๊ตฌํํฉ๋๋ค.
"""
from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTClient
import json
import time
import random
import threading
# AWS IoT Core ์ค์
IOT_ENDPOINT = "xxxxx.iot.ap-northeast-2.amazonaws.com"
CLIENT_ID = "MyRaspberryPi"
PUBLISH_TOPIC = "raspberry/telemetry"
SUBSCRIBE_TOPIC = "raspberry/command"
# ์ธ์ฆ์ ํ์ผ ๊ฒฝ๋ก
ROOT_CA = "/home/pi/aws-iot/certs/AmazonRootCA1.pem"
PRIVATE_KEY = "/home/pi/aws-iot/certs/private.pem.key"
CERTIFICATE = "/home/pi/aws-iot/certs/certificate.pem.crt"
# ๋๋ฐ์ด์ค ์ํ
device_state = {
"led_status": "OFF",
"reporting_interval": 5,
"active": True
}
def custom_callback(client, userdata, message):
"""
๋ฉ์์ง ์์ ์ฝ๋ฐฑ ํจ์
ํด๋ผ์ฐ๋์์ ๋ช
๋ น์ ๋ฐ์ผ๋ฉด ์คํ๋ฉ๋๋ค.
"""
try:
payload = json.loads(message.payload.decode('utf-8'))
print(f"\n๐จ ๋ช
๋ น ์์ : {json.dumps(payload, indent=2)}")
# ๋ช
๋ น ํ์
์ ๋ฐ๋ผ ์ฒ๋ฆฌ
command_type = payload.get("command")
if command_type == "LED_CONTROL":
# LED ์ ์ด ๋ช
๋ น
led_action = payload.get("action")
if led_action in ["ON", "OFF"]:
device_state["led_status"] = led_action
print(f"๐ก LED ์ํ ๋ณ๊ฒฝ: {led_action}")
# ์ค์ ๋ก๋ GPIO๋ฅผ ์ ์ดํ๋ ์ฝ๋๊ฐ ๋ค์ด๊ฐ
# import RPi.GPIO as GPIO
# GPIO.output(LED_PIN, GPIO.HIGH if led_action == "ON" else GPIO.LOW)
elif command_type == "SET_INTERVAL":
# ๋ณด๊ณ ์ฃผ๊ธฐ ๋ณ๊ฒฝ ๋ช
๋ น
new_interval = payload.get("interval", 5)
if 1 <= new_interval <= 60:
device_state["reporting_interval"] = new_interval
print(f"โฑ๏ธ ๋ณด๊ณ ์ฃผ๊ธฐ ๋ณ๊ฒฝ: {new_interval}์ด")
elif command_type == "GET_STATUS":
# ์ํ ์กฐํ ๋ช
๋ น
print("๐ ํ์ฌ ์ํ ์ ์ก ์์ฒญ")
publish_status(client)
elif command_type == "REBOOT":
# ์ฌ๋ถํ
๋ช
๋ น
print("๐ ์ฌ๋ถํ
๋ช
๋ น ์์ ")
device_state["active"] = False
else:
print(f"โ ๏ธ ์ ์ ์๋ ๋ช
๋ น: {command_type}")
except Exception as e:
print(f"โ ์ฝ๋ฐฑ ์ฒ๋ฆฌ ์ค๋ฅ: {str(e)}")
def init_mqtt_client():
"""
MQTT ํด๋ผ์ด์ธํธ ์ด๊ธฐํ
"""
mqtt_client = AWSIoTMQTTClient(CLIENT_ID)
mqtt_client.configureEndpoint(IOT_ENDPOINT, 8883)
mqtt_client.configureCredentials(ROOT_CA, PRIVATE_KEY, CERTIFICATE)
# ์ฐ๊ฒฐ ์ค์
mqtt_client.configureAutoReconnectBackoffTime(1, 32, 20)
mqtt_client.configureOfflinePublishQueueing(-1)
mqtt_client.configureDrainingFrequency(2)
mqtt_client.configureConnectDisconnectTimeout(10)
mqtt_client.configureMQTTOperationTimeout(5)
return mqtt_client
def publish_telemetry(client):
"""
ํ
๋ ๋ฉํธ๋ฆฌ ๋ฐ์ดํฐ ๋ฐํ
"""
# ์ผ์ ๋ฐ์ดํฐ ์๋ฎฌ๋ ์ด์
temperature = round(random.uniform(20.0, 30.0), 2)
humidity = round(random.uniform(40.0, 70.0), 2)
cpu_temp = round(random.uniform(40.0, 60.0), 2)
message = {
"device_id": CLIENT_ID,
"timestamp": int(time.time()),
"telemetry": {
"temperature": temperature,
"humidity": humidity,
"cpu_temperature": cpu_temp
},
"state": {
"led_status": device_state["led_status"],
"reporting_interval": device_state["reporting_interval"]
}
}
try:
message_json = json.dumps(message)
client.publish(PUBLISH_TOPIC, message_json, 1)
print(f"๐ค ํ
๋ ๋ฉํธ๋ฆฌ ์ ์ก: ์จ๋={temperature}ยฐC, ์ต๋={humidity}%")
except Exception as e:
print(f"โ ์ ์ก ์คํจ: {str(e)}")
def publish_status(client):
"""
๋๋ฐ์ด์ค ์ํ ๋ฐํ
"""
status_message = {
"device_id": CLIENT_ID,
"timestamp": int(time.time()),
"type": "status_report",
"status": device_state
}
try:
client.publish(PUBLISH_TOPIC, json.dumps(status_message), 1)
print("๐ ์ํ ๋ณด๊ณ ์ ์ก ์๋ฃ")
except Exception as e:
print(f"โ ์ํ ์ ์ก ์คํจ: {str(e)}")
def main():
"""
๋ฉ์ธ ์คํ ํจ์
"""
print("๐ AWS IoT Core ์๋ฐฉํฅ ํต์ ์์...")
# MQTT ํด๋ผ์ด์ธํธ ์ด๊ธฐํ
mqtt_client = init_mqtt_client()
# ์ฐ๊ฒฐ
try:
mqtt_client.connect()
print("โ
AWS IoT Core ์ฐ๊ฒฐ ์ฑ๊ณต!")
except Exception as e:
print(f"โ ์ฐ๊ฒฐ ์คํจ: {str(e)}")
return
# ๋ช
๋ น ํ ํฝ ๊ตฌ๋
try:
mqtt_client.subscribe(SUBSCRIBE_TOPIC, 1, custom_callback)
print(f"โ
ํ ํฝ ๊ตฌ๋
์ฑ๊ณต: {SUBSCRIBE_TOPIC}")
except Exception as e:
print(f"โ ๊ตฌ๋
์คํจ: {str(e)}")
return
# ์ด๊ธฐ ์ํ ์ ์ก
time.sleep(2)
publish_status(mqtt_client)
# ๋ฉ์ธ ๋ฃจํ
try:
while device_state["active"]:
# ํ
๋ ๋ฉํธ๋ฆฌ ๋ฐ์ดํฐ ์ ์ก
publish_telemetry(mqtt_client)
# ์ค์ ๋ ์ฃผ๊ธฐ๋งํผ ๋๊ธฐ
time.sleep(device_state["reporting_interval"])
except KeyboardInterrupt:
print("\nโน๏ธ ํ๋ก๊ทธ๋จ ์ข
๋ฃ ์ค...")
finally:
mqtt_client.disconnect()
print("๐ AWS IoT Core ์ฐ๊ฒฐ ํด์ ์๋ฃ")
if __name__ == "__main__":
main()
์ด ์ฝ๋๋ ํจ์ฌ ๋ ๊ฐ๋ ฅํด! ๋ฌด์์ ํ ์ ์๋์ง ๋ณผ๊น? ๐ฏ
๐ฎ ๊ตฌํ๋ ๊ธฐ๋ฅ๋ค
โข ํ
๋ ๋ฉํธ๋ฆฌ ์ ์ก: ์ฃผ๊ธฐ์ ์ผ๋ก ์ผ์ ๋ฐ์ดํฐ๋ฅผ ํด๋ผ์ฐ๋๋ก ์ ์ก
โข ๋ช
๋ น ์์ : ํด๋ผ์ฐ๋์์ ๋ณด๋ธ ๋ช
๋ น์ ์ค์๊ฐ์ผ๋ก ๋ฐ์์ ์ฒ๋ฆฌ
โข LED ์ ์ด: ์๊ฒฉ์ผ๋ก LED๋ฅผ ์ผ๊ณ ๋ ์ ์์
โข ์ค์ ๋ณ๊ฒฝ: ๋ฐ์ดํฐ ์ ์ก ์ฃผ๊ธฐ๋ฅผ ๋์ ์ผ๋ก ์กฐ์
โข ์ํ ์กฐํ: ํ์ฌ ๋๋ฐ์ด์ค ์ํ๋ฅผ ์์ฒญํ๋ฉด ์ฆ์ ์๋ต
โข ์ฌ๋ถํ
: ์๊ฒฉ์ผ๋ก ํ๋ก๊ทธ๋จ์ ์ข
๋ฃํ ์ ์์
๋ช ๋ น ์ ์ก ํ ์คํธ
AWS IoT Core ์ฝ์์ "ํ ์คํธ" ๋ฉ๋ด์์ ๋ค์๊ณผ ๊ฐ์ ๋ช ๋ น์ ๋ณด๋ผ ์ ์์ด:
// LED ์ผ๊ธฐ
{
"command": "LED_CONTROL",
"action": "ON"
}
// ๋ณด๊ณ ์ฃผ๊ธฐ ๋ณ๊ฒฝ (10์ด๋ก)
{
"command": "SET_INTERVAL",
"interval": 10
}
// ์ํ ์กฐํ
{
"command": "GET_STATUS"
}
๐ง ์ค์ ์ผ์ ์ฐ๋ ์์
์ด๋ก ๋ง์ผ๋ก๋ ์ฌ๋ฏธ์์ง! ์ค์ ์ผ์๋ฅผ ์ฐ๊ฒฐํด์ ๋ฐ์ดํฐ๋ฅผ ์์งํ๋ ์ฝ๋๋ฅผ ๋ง๋ค์ด๋ณด์. DHT22 ์จ์ต๋ ์ผ์๋ฅผ ์๋ก ๋ค๊ฒ. ๐ก๏ธ
๐ sensor_integration.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
์ค์ ์ผ์ ์ฐ๋ ์์ (DHT22 ์จ์ต๋ ์ผ์)
"""
from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTClient
import json
import time
import sys
# DHT22 ์ผ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ (์ค์น ํ์: pip3 install Adafruit_DHT)
try:
import Adafruit_DHT
SENSOR_AVAILABLE = True
except ImportError:
print("โ ๏ธ Adafruit_DHT ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์์ต๋๋ค. ์๋ฎฌ๋ ์ด์
๋ชจ๋๋ก ์คํ๋ฉ๋๋ค.")
SENSOR_AVAILABLE = False
import random
# AWS IoT Core ์ค์
IOT_ENDPOINT = "xxxxx.iot.ap-northeast-2.amazonaws.com"
CLIENT_ID = "RaspberryPi_Sensor"
TOPIC = "home/environment"
# ์ธ์ฆ์ ํ์ผ ๊ฒฝ๋ก
ROOT_CA = "/home/pi/aws-iot/certs/AmazonRootCA1.pem"
PRIVATE_KEY = "/home/pi/aws-iot/certs/private.pem.key"
CERTIFICATE = "/home/pi/aws-iot/certs/certificate.pem.crt"
# ์ผ์ ์ค์
DHT_SENSOR = Adafruit_DHT.DHT22 if SENSOR_AVAILABLE else None
DHT_PIN = 4 # GPIO 4๋ฒ ํ
class SensorReader:
"""
์ผ์ ๋ฐ์ดํฐ ์ฝ๊ธฐ ํด๋์ค
"""
def __init__(self):
self.last_temperature = None
self.last_humidity = None
self.error_count = 0
def read_sensor(self):
"""
์ผ์์์ ๋ฐ์ดํฐ ์ฝ๊ธฐ
"""
if SENSOR_AVAILABLE:
try:
humidity, temperature = Adafruit_DHT.read_retry(DHT_SENSOR, DHT_PIN)
if humidity is not None and temperature is not None:
self.last_temperature = round(temperature, 2)
self.last_humidity = round(humidity, 2)
self.error_count = 0
return True
else:
self.error_count += 1
print(f"โ ๏ธ ์ผ์ ์ฝ๊ธฐ ์คํจ (์๋ {self.error_count}ํ)")
return False
except Exception as e:
self.error_count += 1
print(f"โ ์ผ์ ์ค๋ฅ: {str(e)}")
return False
else:
# ์๋ฎฌ๋ ์ด์
๋ชจ๋
self.last_temperature = round(random.uniform(20.0, 30.0), 2)
self.last_humidity = round(random.uniform(40.0, 70.0), 2)
return True
def get_data(self):
"""
๋ง์ง๋ง์ผ๋ก ์ฝ์ ๋ฐ์ดํฐ ๋ฐํ
"""
return {
"temperature": self.last_temperature,
"humidity": self.last_humidity
}
def is_healthy(self):
"""
์ผ์ ์ํ ํ์ธ
"""
return self.error_count < 5
def calculate_heat_index(temperature, humidity):
"""
์ฒด๊ฐ์จ๋(Heat Index) ๊ณ์ฐ
"""
if temperature < 27:
return temperature
# ๊ฐ๋จํ ์ฒด๊ฐ์จ๋ ๊ณต์
hi = -8.78469475556 + \
1.61139411 * temperature + \
2.33854883889 * humidity + \
-0.14611605 * temperature * humidity + \
-0.012308094 * temperature**2 + \
-0.0164248277778 * humidity**2 + \
0.002211732 * temperature**2 * humidity + \
0.00072546 * temperature * humidity**2 + \
-0.000003582 * temperature**2 * humidity**2
return round(hi, 2)
def init_mqtt_client():
"""
MQTT ํด๋ผ์ด์ธํธ ์ด๊ธฐํ
"""
mqtt_client = AWSIoTMQTTClient(CLIENT_ID)
mqtt_client.configureEndpoint(IOT_ENDPOINT, 8883)
mqtt_client.configureCredentials(ROOT_CA, PRIVATE_KEY, CERTIFICATE)
mqtt_client.configureAutoReconnectBackoffTime(1, 32, 20)
mqtt_client.configureOfflinePublishQueueing(-1)
mqtt_client.configureDrainingFrequency(2)
mqtt_client.configureConnectDisconnectTimeout(10)
mqtt_client.configureMQTTOperationTimeout(5)
return mqtt_client
def publish_sensor_data(client, sensor_reader):
"""
์ผ์ ๋ฐ์ดํฐ ๋ฐํ
"""
# ์ผ์ ์ฝ๊ธฐ
if not sensor_reader.read_sensor():
print("โ ๏ธ ์ผ์ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ ์ ์์ต๋๋ค.")
return False
# ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ
data = sensor_reader.get_data()
temperature = data["temperature"]
humidity = data["humidity"]
# ์ฒด๊ฐ์จ๋ ๊ณ์ฐ
heat_index = calculate_heat_index(temperature, humidity)
# ์พ์ ๋ ํ๋จ
comfort_level = "comfortable"
if temperature > 28 or temperature < 18:
comfort_level = "uncomfortable"
elif humidity > 70 or humidity < 30:
comfort_level = "uncomfortable"
# ๋ฉ์์ง ์์ฑ
message = {
"device_id": CLIENT_ID,
"timestamp": int(time.time()),
"location": "living_room",
"sensor_data": {
"temperature": temperature,
"humidity": humidity,
"heat_index": heat_index
},
"analysis": {
"comfort_level": comfort_level,
"sensor_health": "healthy" if sensor_reader.is_healthy() else "warning"
},
"metadata": {
"sensor_type": "DHT22",
"gpio_pin": DHT_PIN,
"simulation_mode": not SENSOR_AVAILABLE
}
}
try:
message_json = json.dumps(message, indent=2)
client.publish(TOPIC, message_json, 1)
print(f"\n๐ ์ผ์ ๋ฐ์ดํฐ ์ ์ก:")
print(f" ๐ก๏ธ ์จ๋: {temperature}ยฐC")
print(f" ๐ง ์ต๋: {humidity}%")
print(f" ๐ฅ ์ฒด๊ฐ์จ๋: {heat_index}ยฐC")
print(f" ๐ ์พ์ ๋: {comfort_level}")
return True
except Exception as e:
print(f"โ ๋ฐ์ดํฐ ์ ์ก ์คํจ: {str(e)}")
return False
def main():
"""
๋ฉ์ธ ์คํ ํจ์
"""
print("๐ก๏ธ ์ผ์ ๋ชจ๋ํฐ๋ง ์์คํ
์์...")
if not SENSOR_AVAILABLE:
print("โ ๏ธ ์๋ฎฌ๋ ์ด์
๋ชจ๋๋ก ์คํ๋ฉ๋๋ค.")
# ์ผ์ ๋ฆฌ๋ ์ด๊ธฐํ
sensor_reader = SensorReader()
# MQTT ํด๋ผ์ด์ธํธ ์ด๊ธฐํ
mqtt_client = init_mqtt_client()
# AWS IoT Core ์ฐ๊ฒฐ
try:
mqtt_client.connect()
print("โ
AWS IoT Core ์ฐ๊ฒฐ ์ฑ๊ณต!")
except Exception as e:
print(f"โ ์ฐ๊ฒฐ ์คํจ: {str(e)}")
return
# ๋ฉ์ธ ๋ฃจํ
consecutive_failures = 0
try:
while True:
# ์ผ์ ๋ฐ์ดํฐ ๋ฐํ
success = publish_sensor_data(mqtt_client, sensor_reader)
if success:
consecutive_failures = 0
else:
consecutive_failures += 1
# ์ฐ์ ์คํจ ์ ๊ฒฝ๊ณ
if consecutive_failures >= 3:
print("โ ๏ธ ์ฐ์ 3ํ ์คํจ! ์ผ์ ๋๋ ์ฐ๊ฒฐ์ ํ์ธํ์ธ์.")
# 30์ด ๋๊ธฐ
time.sleep(30)
except KeyboardInterrupt:
print("\nโน๏ธ ํ๋ก๊ทธ๋จ ์ข
๋ฃ ์ค...")
finally:
mqtt_client.disconnect()
print("๐ ๋ชจ๋ํฐ๋ง ์์คํ
์ข
๋ฃ")
if __name__ == "__main__":
main()
์ด ์ฝ๋๋ ์ค์ ํ๋ก๋์ ํ๊ฒฝ์์ ์ฌ์ฉํ ์ ์์ ์ ๋๋ก ์์ฑ๋๊ฐ ๋์! ํน์ง์ ์ดํด๋ณด์:
โจ ์ฃผ์ ํน์ง
โข ์ค์ ์ผ์ ์ง์: DHT22 ์ผ์์์ ์ค์ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ด์ด
โข ์๋ฎฌ๋ ์ด์
๋ชจ๋: ์ผ์๊ฐ ์์ด๋ ํ
์คํธ ๊ฐ๋ฅ
โข ์๋ฌ ์ฒ๋ฆฌ: ์ผ์ ์ฝ๊ธฐ ์คํจ ์ ์ฌ์๋ ๋ฐ ์นด์ดํ
โข ๋ฐ์ดํฐ ๋ถ์: ์ฒด๊ฐ์จ๋ ๊ณ์ฐ ๋ฐ ์พ์ ๋ ํ๋จ
โข ๋ฉํ๋ฐ์ดํฐ: ์ผ์ ํ์
, ์์น ๋ฑ ์ถ๊ฐ ์ ๋ณด ํฌํจ
โข ๊ฑด๊ฐ ์ฒดํฌ: ์ผ์ ์ํ๋ฅผ ๋ชจ๋ํฐ๋ง
๐ก ์ค์ ํ: ์ค์ ํ๊ฒฝ์์๋ ์ผ์ ์บ๋ฆฌ๋ธ๋ ์ด์ ์ด ์ค์ํด. DHT22๋ ยฑ2ยฐC, ยฑ5% ์ ๋์ ์ค์ฐจ๊ฐ ์์ผ๋ ์ฐธ๊ณ ํด!
๐จ AWS IoT Core ๊ท์น(Rules) ํ์ฉ
๋ฐ์ดํฐ๋ฅผ ๋ฐ๊ธฐ๋ง ํ๋ฉด ๋ญํด? AWS IoT Core์ ๊ท์น ์์ง์ ์ฌ์ฉํ๋ฉด ๋ค์ด์ค๋ ๋ฐ์ดํฐ๋ฅผ ์๋์ผ๋ก ์ฒ๋ฆฌํ ์ ์์ด! ์๋ฅผ ๋ค์ด ์จ๋๊ฐ ๋๋ฌด ๋์ผ๋ฉด ์๋ฆผ์ ๋ณด๋ด๊ฑฐ๋, ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฅํ๋ ๊ฑฐ์ง. ๐ฅ
๊ท์น ์์ฑ ์์
AWS ์ฝ์์์ IoT Core โ ์์ โ ๊ท์น โ ์์ฑ์ผ๋ก ๋ค์ด๊ฐ์ ๋ค์๊ณผ ๊ฐ์ด ์ค์ ํด:
๊ท์น 1: ๊ณ ์จ ์๋ฆผ
์จ๋๊ฐ 28๋๋ฅผ ์ด๊ณผํ๋ฉด SNS๋ก ์๋ฆผ ์ ์ก
-- SQL ์ฟผ๋ฆฌ
SELECT
device_id,
timestamp,
sensor_data.temperature as temperature,
sensor_data.humidity as humidity
FROM 'home/environment'
WHERE sensor_data.temperature > 28
์์ ์ผ๋ก SNS ์ฃผ์ ์ ๋ฉ์์ง ์ ์ก์ ์ ํํ๋ฉด ๋ผ.
๊ท์น 2: ๋ฐ์ดํฐ ์ ์ฅ
๋ชจ๋ ์ผ์ ๋ฐ์ดํฐ๋ฅผ DynamoDB์ ์ ์ฅ
-- SQL ์ฟผ๋ฆฌ
SELECT
device_id,
timestamp,
sensor_data,
analysis
FROM 'home/environment'
์์ ์ผ๋ก DynamoDB ํ ์ด๋ธ์ ๋ฉ์์ง ์ฝ์ ์ ์ ํํ๋ฉด ๋ผ.
Lambda ํจ์ ์ฐ๋
๋ ๋ณต์กํ ์ฒ๋ฆฌ๊ฐ ํ์ํ๋ฉด Lambda ํจ์๋ฅผ ์ฌ์ฉํ ์ ์์ด. ์๋ฅผ ๋ค์ด ๋ฐ์ดํฐ ๋ถ์, ์ธ๋ถ API ํธ์ถ, ๋ณต์กํ ๋น์ฆ๋์ค ๋ก์ง ๋ฑ์ ๊ตฌํํ ์ ์์ง.
# Lambda ํจ์ ์์ (Python 3.9)
import json
import boto3
from datetime import datetime
dynamodb = boto3.resource('dynamodb')
sns = boto3.client('sns')
def lambda_handler(event, context):
"""
IoT ๋ฐ์ดํฐ ์ฒ๋ฆฌ Lambda ํจ์
"""
print(f"์์ ๋ ์ด๋ฒคํธ: {json.dumps(event)}")
# ๋ฐ์ดํฐ ์ถ์ถ
device_id = event.get('device_id')
sensor_data = event.get('sensor_data', {})
temperature = sensor_data.get('temperature')
humidity = sensor_data.get('humidity')
# DynamoDB์ ์ ์ฅ
table = dynamodb.Table('IoTSensorData')
try:
table.put_item(
Item={
'device_id': device_id,
'timestamp': int(event.get('timestamp')),
'temperature': str(temperature),
'humidity': str(humidity),
'processed_at': datetime.now().isoformat()
}
)
print("โ
DynamoDB ์ ์ฅ ์ฑ๊ณต")
except Exception as e:
print(f"โ DynamoDB ์ ์ฅ ์คํจ: {str(e)}")
# ๊ณ ์จ ์๋ฆผ
if temperature and temperature > 30:
try:
sns.publish(
TopicArn='arn:aws:sns:ap-northeast-2:123456789:HighTemperatureAlert',
Subject='๐ฅ ๊ณ ์จ ๊ฒฝ๊ณ !',
Message=f'๋๋ฐ์ด์ค {device_id}์ ์จ๋๊ฐ {temperature}ยฐC์
๋๋ค!'
)
print("โ
SNS ์๋ฆผ ์ ์ก ์ฑ๊ณต")
except Exception as e:
print(f"โ SNS ์ ์ก ์คํจ: {str(e)}")
return {
'statusCode': 200,
'body': json.dumps('์ฒ๋ฆฌ ์๋ฃ')
}
๐ ๋ณด์ ๊ฐํ ํ
IoT ๋๋ฐ์ด์ค๋ ๋ณด์์ด ์ ๋ง ์ค์ํด! ํดํน๋นํ๋ฉด ํฐ์ผ๋๊ฑฐ๋ . ๋ช ๊ฐ์ง ๋ณด์ ๊ฐํ ๋ฐฉ๋ฒ์ ์๋ ค์ค๊ฒ. ๐ก๏ธ
1. ์ธ์ฆ์ ๊ด๋ฆฌ
โ ๏ธ ์ ๋ ํ์ง ๋ง์์ผ ํ ๊ฒ๋ค:
โข ์ธ์ฆ์๋ฅผ Git์ ์ปค๋ฐํ์ง ๋ง!
โข ํ๋ผ์ด๋น ํค๋ฅผ ํ๋ฌธ์ผ๋ก ์ ์ฅํ์ง ๋ง!
โข ์ธ์ฆ์๋ฅผ ์ด๋ฉ์ผ๋ก ์ ์กํ์ง ๋ง!
โข ๊ธฐ๋ณธ ๊ถํ(777)์ผ๋ก ๋์ง ๋ง!
โ ์ฌ๋ฐ๋ฅธ ๋ฐฉ๋ฒ:
โข ์ธ์ฆ์๋ ์ํธํ๋ ์ ์ฅ์์ ๋ณด๊ด
โข ํ์ผ ๊ถํ์ ์ต์ํ (600 ๋๋ 400)
โข ์ ๊ธฐ์ ์ผ๋ก ์ธ์ฆ์ ๋กํ
์ด์
โข ์ฌ์ฉํ์ง ์๋ ์ธ์ฆ์๋ ์ฆ์ ๋นํ์ฑํ
2. ์ ์ฑ ์ต์ ๊ถํ ์์น
๋๋ฐ์ด์ค์ ํ์ํ ์ต์ํ์ ๊ถํ๋ง ๋ถ์ฌํด์ผ ํด. ์๋ฅผ ๋ค์ด:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "iot:Connect",
"Resource": "arn:aws:iot:ap-northeast-2:ACCOUNT_ID:client/${iot:ClientId}"
},
{
"Effect": "Allow",
"Action": "iot:Publish",
"Resource": [
"arn:aws:iot:ap-northeast-2:ACCOUNT_ID:topic/home/environment",
"arn:aws:iot:ap-northeast-2:ACCOUNT_ID:topic/home/status"
]
},
{
"Effect": "Allow",
"Action": "iot:Subscribe",
"Resource": "arn:aws:iot:ap-northeast-2:ACCOUNT_ID:topicfilter/home/command/${iot:ClientId}"
},
{
"Effect": "Allow",
"Action": "iot:Receive",
"Resource": "arn:aws:iot:ap-northeast-2:ACCOUNT_ID:topic/home/command/${iot:ClientId}"
}
]
}
์ด๋ ๊ฒ ํ๋ฉด ํน์ ํ ํฝ์๋ง ์ ๊ทผํ ์ ์๊ณ , ์์ ์ ClientId์ ํด๋นํ๋ ๋ช ๋ น๋ง ๋ฐ์ ์ ์์ด.
3. ๋คํธ์ํฌ ๋ณด์
๐ ๋คํธ์ํฌ ๋ณด์ ์ฒดํฌ๋ฆฌ์คํธ
โ
TLS 1.2 ์ด์ ์ฌ์ฉ (AWS IoT Core๋ ๊ธฐ๋ณธ ์ง์)
โ
๋ฐฉํ๋ฒฝ์์ ํ์ํ ํฌํธ๋ง ์ด๊ธฐ (8883, 443)
โ
VPN ๋๋ ํ๋ผ์ด๋น ๋คํธ์ํฌ ์ฌ์ฉ ๊ณ ๋ ค
โ
์ ๊ธฐ์ ์ธ ๋ณด์ ์
๋ฐ์ดํธ ์ ์ฉ
โ
๋ถํ์ํ ์๋น์ค ๋นํ์ฑํ
4. ์ฝ๋ ๋ ๋ฒจ ๋ณด์
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
๋ณด์์ด ๊ฐํ๋ IoT ํด๋ผ์ด์ธํธ
"""
import os
import sys
from pathlib import Path
class SecureConfig:
"""
๋ณด์ ์ค์ ๊ด๋ฆฌ ํด๋์ค
"""
def __init__(self):
self.config_dir = Path.home() / '.aws-iot'
self.certs_dir = self.config_dir / 'certs'
def validate_certificates(self):
"""
์ธ์ฆ์ ํ์ผ ๊ฒ์ฆ
"""
required_files = [
'certificate.pem.crt',
'private.pem.key',
'AmazonRootCA1.pem'
]
for filename in required_files:
filepath = self.certs_dir / filename
# ํ์ผ ์กด์ฌ ํ์ธ
if not filepath.exists():
raise FileNotFoundError(f"์ธ์ฆ์ ํ์ผ์ด ์์ต๋๋ค: {filename}")
# ๊ถํ ํ์ธ (Unix ๊ณ์ด๋ง)
if sys.platform != 'win32':
stat_info = filepath.stat()
mode = oct(stat_info.st_mode)[-3:]
if filename.endswith('.key'):
# ํ๋ผ์ด๋น ํค๋ 600 ๋๋ 400์ด์ด์ผ ํจ
if mode not in ['600', '400']:
raise PermissionError(
f"ํ๋ผ์ด๋น ํค ๊ถํ์ด ์์ ํ์ง ์์ต๋๋ค: {mode}\n"
f"๋ค์ ๋ช
๋ น์ด๋ฅผ ์คํํ์ธ์: chmod 600 {filepath}"
)
print("โ
์ธ์ฆ์ ๊ฒ์ฆ ์๋ฃ")
return True
def get_cert_paths(self):
"""
์ธ์ฆ์ ๊ฒฝ๋ก ๋ฐํ
"""
return {
'root_ca': str(self.certs_dir / 'AmazonRootCA1.pem'),
'certificate': str(self.certs_dir / 'certificate.pem.crt'),
'private_key': str(self.certs_dir / 'private.pem.key')
}
# ์ฌ์ฉ ์์
if __name__ == "__main__":
config = SecureConfig()
try:
config.validate_certificates()
cert_paths = config.get_cert_paths()
print("์ธ์ฆ์ ๊ฒฝ๋ก:", cert_paths)
except Exception as e:
print(f"โ ๋ณด์ ๊ฒ์ฆ ์คํจ: {str(e)}")
sys.exit(1)
๐ ๋ชจ๋ํฐ๋ง ๋ฐ ๋๋ฒ๊น
๊ฐ๋ฐํ๋ค ๋ณด๋ฉด ๋ฌธ์ ๊ฐ ์๊ธฐ๊ธฐ ๋ง๋ จ์ด์ผ. ํจ๊ณผ์ ์ผ๋ก ๋๋ฒ๊น ํ๋ ๋ฐฉ๋ฒ์ ์์๋ณด์! ๐
CloudWatch ๋ก๊ทธ ํ์ฑํ
AWS IoT Core๋ CloudWatch Logs์ ํตํฉ๋์ด ์์ด. ๋ก๊น ์ ํ์ฑํํ๋ฉด ๋ชจ๋ ์ฐ๊ฒฐ, ๋ฐํ, ๊ตฌ๋ ์ด๋ฒคํธ๋ฅผ ์ถ์ ํ ์ ์์ด.
๋ก๊น ํ์ฑํ ๋ฐฉ๋ฒ:
1. IoT Core ์ฝ์ โ ์ค์
2. ๋ก๊ทธ ์น์
์์ "ํธ์ง" ํด๋ฆญ
3. ๋ก๊ทธ ์์ค ์ ํ (Debug, Info, Warn, Error)
4. IAM ์ญํ ์์ฑ ๋๋ ์ ํ
5. ์
๋ฐ์ดํธ ํด๋ฆญ
๋๋ฒ๊น ์ฉ ์ฝ๋
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
๋๋ฒ๊น
๊ธฐ๋ฅ์ด ๊ฐํ๋ IoT ํด๋ผ์ด์ธํธ
"""
import logging
import sys
from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTClient
# ๋ก๊น
์ค์
logging.basicConfig(
level=logging.DEBUG,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('iot_client.log'),
logging.StreamHandler(sys.stdout)
]
)
logger = logging.getLogger(__name__)
class DebugMQTTClient:
"""
๋๋ฒ๊น
๊ธฐ๋ฅ์ด ์ถ๊ฐ๋ MQTT ํด๋ผ์ด์ธํธ
"""
def __init__(self, client_id, endpoint):
self.client_id = client_id
self.endpoint = endpoint
self.client = None
self.connection_status = False
self.publish_count = 0
self.error_count = 0
def init_client(self, root_ca, private_key, certificate):
"""
ํด๋ผ์ด์ธํธ ์ด๊ธฐํ
"""
logger.info(f"ํด๋ผ์ด์ธํธ ์ด๊ธฐํ ์์: {self.client_id}")
try:
self.client = AWSIoTMQTTClient(self.client_id)
self.client.configureEndpoint(self.endpoint, 8883)
self.client.configureCredentials(root_ca, private_key, certificate)
# ๋๋ฒ๊ทธ ๋ก๊น
ํ์ฑํ
self.client.configureLogging(
AWSIoTPythonSDK.core.util.loggers.LOG_LEVEL_DEBUG,
'aws_iot_sdk.log'
)
logger.info("โ
ํด๋ผ์ด์ธํธ ์ด๊ธฐํ ์๋ฃ")
return True
except Exception as e:
logger.error(f"โ ํด๋ผ์ด์ธํธ ์ด๊ธฐํ ์คํจ: {str(e)}", exc_info=True)
return False
def connect(self):
"""
์ฐ๊ฒฐ ์๋
"""
logger.info(f"์ฐ๊ฒฐ ์๋: {self.endpoint}")
try:
self.client.connect()
self.connection_status = True
logger.info("โ
์ฐ๊ฒฐ ์ฑ๊ณต")
return True
except Exception as e:
self.connection_status = False
self.error_count += 1
logger.error(f"โ ์ฐ๊ฒฐ ์คํจ (์๋ {self.error_count}ํ): {str(e)}", exc_info=True)
return False
def publish(self, topic, payload, qos=1):
"""
๋ฉ์์ง ๋ฐํ
"""
if not self.connection_status:
logger.warning("โ ๏ธ ์ฐ๊ฒฐ๋์ง ์์ ์ํ์์ ๋ฐํ ์๋")
return False
try:
logger.debug(f"๋ฉ์์ง ๋ฐํ ์๋ - ํ ํฝ: {topic}, QoS: {qos}")
logger.debug(f"ํ์ด๋ก๋: {payload[:100]}...") # ์ฒ์ 100์๋ง ๋ก๊น
self.client.publish(topic, payload, qos)
self.publish_count += 1
logger.info(f"โ
๋ฉ์์ง ๋ฐํ ์ฑ๊ณต (์ด {self.publish_count}๊ฑด)")
return True
except Exception as e:
self.error_count += 1
logger.error(f"โ ๋ฉ์์ง ๋ฐํ ์คํจ: {str(e)}", exc_info=True)
return False
def get_stats(self):
"""
ํต๊ณ ์ ๋ณด ๋ฐํ
"""
return {
'client_id': self.client_id,
'connected': self.connection_status,
'publish_count': self.publish_count,
'error_count': self.error_count
}
# ์ฌ์ฉ ์์
if __name__ == "__main__":
client = DebugMQTTClient("TestDevice", "xxxxx.iot.ap-northeast-2.amazonaws.com")
if client.init_client(
"/path/to/root-ca.pem",
"/path/to/private.key",
"/path/to/certificate.crt"
):
if client.connect():
# ํ
์คํธ ๋ฉ์์ง ๋ฐํ
import json
test_message = json.dumps({"test": "data"})
client.publish("test/topic", test_message)
# ํต๊ณ ์ถ๋ ฅ
stats = client.get_stats()
logger.info(f"ํต๊ณ: {stats}")
์ผ๋ฐ์ ์ธ ๋ฌธ์ ํด๊ฒฐ
| ๋ฌธ์ | ์์ธ | ํด๊ฒฐ๋ฐฉ๋ฒ |
|---|---|---|
| ์ฐ๊ฒฐ ์คํจ | ์ธ์ฆ์ ์ค๋ฅ | ์ธ์ฆ์ ๊ฒฝ๋ก ๋ฐ ๊ถํ ํ์ธ |
| ๋ฐํ ์คํจ | ์ ์ฑ ๊ถํ ๋ถ์กฑ | IoT ์ ์ฑ ์์ Publish ๊ถํ ํ์ธ |
| ๋ฉ์์ง ๋ฏธ์์ | ๊ตฌ๋ ์คํจ | ํ ํฝ ์ด๋ฆ ๋ฐ Subscribe ๊ถํ ํ์ธ |
| ๊ฐํ์ ๋๊น | ๋คํธ์ํฌ ๋ถ์์ | ์๋ ์ฌ์ฐ๊ฒฐ ์ค์ ํ์ธ |
| ๋๋ฆฐ ์๋ต | QoS ์ค์ | QoS 0์ผ๋ก ๋ณ๊ฒฝ ๊ณ ๋ ค |
๐ ์ค์ ํ๋ก์ ํธ ์์ด๋์ด
์ด์ ๊ธฐ๋ณธ์ ๋ค ๋ฐฐ์ ์ผ๋, ์ค์ ๋ก ๋ง๋ค์ด๋ณผ ์ ์๋ ํ๋ก์ ํธ๋ค์ ์๊ฐํ ๊ฒ! ์ด๋ฐ ํ๋ก์ ํธ๋ค์ ํฌํธํด๋ฆฌ์ค๋ก๋ ์ข๊ณ , **์ฌ๋ฅ๋ท**์์ ์๋น์ค๋ก ์ ๊ณตํ ์๋ ์์ด. ๐ก
1์ค๋งํธ ํ ํ๊ฒฝ ๋ชจ๋ํฐ๋ง
โข ์ฌ๋ฌ ๋ฐฉ์ ์จ์ต๋๋ฅผ ์ค์๊ฐ ๋ชจ๋ํฐ๋ง
โข ๋ถ์พ์ง์๊ฐ ๋์ผ๋ฉด ์๋์ผ๋ก ์๋ฆผ
โข ์น ๋์๋ณด๋๋ก ์๊ฐํ
โข ์์ด์ปจ/๊ฐ์ต๊ธฐ ์๋ ์ ์ด
2์๋ฌผ ์๋ ๊ด๋ฆฌ ์์คํ
โข ํ ์ ์ต๋ ์ผ์๋ก ๋ฌผ ํ์ ์ฌ๋ถ ๊ฐ์ง
โข ์กฐ๋ ์ผ์๋ก ํ๋น ๋
ธ์ถ ์๊ฐ ์ธก์
โข ์๋ ๋ฌผ์ฃผ๊ธฐ ์์คํ
โข ์ฑ์ฅ ๋ฐ์ดํฐ ๋ถ์ ๋ฐ ๋ฆฌํฌํธ
3์๋์ง ์ฌ์ฉ๋ ๋ชจ๋ํฐ๋ง
โข ์ ๋ ฅ ์ฌ์ฉ๋ ์ค์๊ฐ ์ธก์
โข ์๊ฐ๋๋ณ ์ฌ์ฉ ํจํด ๋ถ์
โข ๋น์ฉ ์์ธก ๋ฐ ์ ์ฝ ํ ์ ๊ณต
โข ์ด์ ์ฌ์ฉ ํจํด ๊ฐ์ง ๋ฐ ์๋ฆผ
4๋ณด์ ์นด๋ฉ๋ผ ์์คํ
โข ๋์ ๊ฐ์ง ์ ์ฌ์ง ์ดฌ์
โข S3์ ์๋ ์
๋ก๋
โข Rekognition์ผ๋ก ์ผ๊ตด ์ธ์
โข ์ค์๊ฐ ์๋ฆผ ์ ์ก
5๋ฐ๋ ค๋๋ฌผ ๋ชจ๋ํฐ๋ง
โข ๊ธ์๊ธฐ ์๋ ์ ์ด
โข ํ๋๋ ์ถ์
โข ์จ๋/์ต๋ ๋ชจ๋ํฐ๋ง
โข ์๊ฒฉ ์นด๋ฉ๋ผ ํ์ธ
๐ฐ ๋น์ฉ ์ต์ ํ ํ
AWS๋ ํธ๋ฆฌํ์ง๋ง ๋น์ฉ์ด ๊ฑฑ์ ๋ ์ ์์ด. ํ๋ฆฌํฐ์ด๋ฅผ ์ต๋ํ ํ์ฉํ๊ณ ๋น์ฉ์ ์ ์ฝํ๋ ๋ฐฉ๋ฒ์ ์๋ ค์ค๊ฒ! ๐ธ
AWS IoT Core ํ๋ฆฌํฐ์ด
๐ ํ๋ฆฌํฐ์ด ํ๋ (๋งค์)
โข ์ฐ๊ฒฐ ์๊ฐ: 2,250,000๋ถ (์ฝ 1,562 ๋๋ฐ์ด์ค-์ผ)
โข ๋ฉ์์ง: 500,000๊ฑด
โข ๊ท์น ์์ง ์คํ: 250,000๊ฑด
โข Device Shadow ์์
: 225,000๊ฑด
๋น์ฉ ์ ๊ฐ ์ ๋ต
๐ก ์ค๋งํธํ ๋น์ฉ ์ ๊ฐ ๋ฐฉ๋ฒ:
1. ๋ฉ์์ง ๋น๋ ์กฐ์
โข ์ค์ํ์ง ์์ ๋ฐ์ดํฐ๋ ์ ์ก ์ฃผ๊ธฐ๋ฅผ ๋๋ ค
โข ๋ณํ๊ฐ ์์ ๋๋ง ์ ์ก (๋ธํ ์ ์ก)
โข ์ฌ๋ฌ ์ผ์ ๋ฐ์ดํฐ๋ฅผ ํ๋์ ๋ฉ์์ง๋ก ๋ฌถ์ด์ ์ ์ก
2. ์์ถ ์ฌ์ฉ
โข JSON ๋์ ๋ฐ์ด๋๋ฆฌ ํฌ๋งท ๊ณ ๋ ค
โข ๋ถํ์ํ ๋ฉํ๋ฐ์ดํฐ ์ ๊ฑฐ
โข gzip ์์ถ ํ์ฉ
3. ๋ก์ปฌ ์ฒ๋ฆฌ
โข ๊ฐ๋จํ ํํฐ๋ง์ ๋๋ฐ์ด์ค์์ ์ฒ๋ฆฌ
โข ์ด์๊ฐ๋ง ํด๋ผ์ฐ๋๋ก ์ ์ก
โข ๋ก์ปฌ ์บ์ฑ ํ์ฉ
๋น์ฉ ๋ชจ๋ํฐ๋ง ์ฝ๋
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
๋ฉ์์ง ์ ์ก ์ต์ ํ ์์
"""
import json
import time
from collections import deque
class OptimizedPublisher:
"""
๋น์ฉ ์ต์ ํ๋ ๋ฉ์์ง ๋ฐํ ํด๋์ค
"""
def __init__(self, client, topic):
self.client = client
self.topic = topic
self.last_values = {}
self.message_count = 0
self.bytes_sent = 0
self.history = deque(maxlen=100)
def should_publish(self, key, value, threshold=0.5):
"""
๊ฐ์ด ์ถฉ๋ถํ ๋ณ๊ฒฝ๋์๋์ง ํ์ธ (๋ธํ ์ ์ก)
"""
if key not in self.last_values:
return True
last_value = self.last_values[key]
change_percent = abs(value - last_value) / last_value * 100
return change_percent >= threshold
def publish_optimized(self, data):
"""
์ต์ ํ๋ ๋ฉ์์ง ๋ฐํ
"""
# ๋ณ๊ฒฝ๋ ๋ฐ์ดํฐ๋ง ํํฐ๋ง
filtered_data = {}
for key, value in data.items():
if self.should_publish(key, value):
filtered_data[key] = value
self.last_values[key] = value
# ๋ณ๊ฒฝ์ฌํญ์ด ์์ผ๋ฉด ๋ฐํํ์ง ์์
if not filtered_data:
print("๐ ๋ณ๊ฒฝ์ฌํญ ์์ - ๋ฉ์์ง ๋ฐํ ์๋ต")
return False
# ๋ฉ์์ง ์์ฑ (์ต์ํ๋ ํ์)
message = {
"t": int(time.time()), # timestamp ์ถ์ฝ
"d": filtered_data # data ์ถ์ฝ
}
message_json = json.dumps(message, separators=(',', ':')) # ๊ณต๋ฐฑ ์ ๊ฑฐ
message_size = len(message_json.encode('utf-8'))
# ํต๊ณ ์
๋ฐ์ดํธ
self.message_count += 1
self.bytes_sent += message_size
self.history.append({
'timestamp': time.time(),
'size': message_size,
'keys': list(filtered_data.keys())
})
# ๋ฐํ
self.client.publish(self.topic, message_json, 1)
print(f"๐ค ๋ฉ์์ง ๋ฐํ: {message_size} bytes")
return True
def get_statistics(self):
"""
ํต๊ณ ์ ๋ณด ๋ฐํ
"""
avg_size = self.bytes_sent / self.message_count if self.message_count > 0 else 0
return {
'total_messages': self.message_count,
'total_bytes': self.bytes_sent,
'average_size': round(avg_size, 2),
'estimated_monthly_messages': self.message_count * 30 * 24, # 1์๊ฐ ๊ธฐ์ค
'within_free_tier': self.message_count * 30 * 24 < 500000
}
# ์ฌ์ฉ ์์
if __name__ == "__main__":
# ๊ฐ์์ ํด๋ผ์ด์ธํธ (์ค์ ๋ก๋ MQTT ํด๋ผ์ด์ธํธ ์ฌ์ฉ)
class DummyClient:
def publish(self, topic, message, qos):
pass
client = DummyClient()
publisher = OptimizedPublisher(client, "sensor/data")
# ์๋ฎฌ๋ ์ด์
for i in range(10):
data = {
"temperature": 25.0 + (i % 3) * 0.1, # ์์ ๋ณํ
"humidity": 60.0 + (i % 5) * 2.0 # ํฐ ๋ณํ
}
publisher.publish_optimized(data)
time.sleep(1)
# ํต๊ณ ์ถ๋ ฅ
stats = publisher.get_statistics()
print(f"\n๐ ํต๊ณ:")
print(f" ์ด ๋ฉ์์ง: {stats['total_messages']}๊ฑด")
print(f" ์ด ๋ฐ์ดํฐ: {stats['total_bytes']} bytes")
print(f" ํ๊ท ํฌ๊ธฐ: {stats['average_size']} bytes")
print(f" ์ ์์: {stats['estimated_monthly_messages']}๊ฑด")
print(f" ํ๋ฆฌํฐ์ด: {'โ
๋ฒ์ ๋ด' if stats['within_free_tier'] else 'โ ์ด๊ณผ'}")
๐ ํ์ต ๋ฆฌ์์ค ๋ฐ ๋ค์ ๋จ๊ณ
์ฌ๊ธฐ๊น์ง ์๋ค๋ฉด ์ ๋ง ๋๋จํด! ํ์ง๋ง ๋ฐฐ์์๋ ๋์ด ์์ง. ๋ ๊น์ด ๊ณต๋ถํ๊ณ ์ถ๋ค๋ฉด ์ด๋ฐ ๊ฒ๋ค์ ์ดํด๋ด. ๐
๊ณต์ ๋ฌธ์
โข AWS IoT Core ๊ฐ๋ฐ์ ๊ฐ์ด๋: ๊ฐ์ฅ ์ ํํ๊ณ ์ต์ ์ ๋ณด
โข AWS IoT Python SDK: SDK ์์ธ ๋ฌธ์
โข MQTT ํ๋กํ ์ฝ ์คํ: MQTT 3.1.1 ํ์ค ๋ฌธ์
โข ๋ผ์ฆ๋ฒ ๋ฆฌํ์ด ๊ณต์ ๋ฌธ์: GPIO, ์ผ์ ์ฐ๋ ๋ฑ
์ถ๊ฐ๋ก ๋ฐฐ์ธ ๋งํ ๊ฒ๋ค
1AWS IoT Greengrass
์ฃ์ง ์ปดํจํ ์ ์ํ ์๋น์ค. ์คํ๋ผ์ธ์์๋ ์๋ํ๊ณ ๋ก์ปฌ์์ Lambda ํจ์๋ฅผ ์คํํ ์ ์์ด.
2Device Shadow
๋๋ฐ์ด์ค์ ์ํ๋ฅผ ํด๋ผ์ฐ๋์ ์ ์ฅํ๊ณ ๋๊ธฐํํ๋ ๊ธฐ๋ฅ. ์คํ๋ผ์ธ ๋๋ฐ์ด์ค ๊ด๋ฆฌ์ ์ ์ฉํด.
3Fleet Provisioning
๋๋์ ๋๋ฐ์ด์ค๋ฅผ ์๋์ผ๋ก ๋ฑ๋กํ๊ณ ์ธ์ฆ์๋ฅผ ๋ฐ๊ธํ๋ ๊ธฐ๋ฅ.
4Jobs
์ฌ๋ฌ ๋๋ฐ์ด์ค์ ํ์จ์ด ์ ๋ฐ์ดํธ๋ ์ค์ ๋ณ๊ฒฝ์ ๋ฐฐํฌํ๋ ๊ธฐ๋ฅ.
์ค์ ๊ฒฝํ ์๊ธฐ
์ด๋ก ๋ง์ผ๋ก๋ ๋ถ์กฑํด! ์ค์ ๋ก ํ๋ก์ ํธ๋ฅผ ๋ง๋ค์ด๋ณด๋ ๊ฒ ์ต๊ณ ์ ํ์ต ๋ฐฉ๋ฒ์ด์ผ. ์์ ๊ฒ๋ถํฐ ์์ํด์ ์ ์ ๋ณต์กํ ์์คํ ์ ๋ง๋ค์ด๋ด. ๊ทธ๋ฆฌ๊ณ ๋ง๋ ํ๋ก์ ํธ๋ฅผ GitHub์ ์ฌ๋ฆฌ๊ณ , ๋ธ๋ก๊ทธ์ ์ ๋ฆฌํ๋ฉด ํฌํธํด๋ฆฌ์ค๋ก๋ ํ์ฉํ ์ ์์ด! ๐ฏ
๐ก ์ปค๋ฆฌ์ด ํ: IoT์ ํด๋ผ์ฐ๋ ๊ธฐ์ ์ ์์ฆ ์ ๋ง ํซํด. ์ด๋ฐ ๊ธฐ์ ์ ์ตํ๋๋ฉด ์ทจ์ ์ด๋ ํ๋ฆฌ๋์ ํ๋์ ํฐ ๋์์ด ๋ผ. ํนํ ์ฌ๋ฅ๋ท ๊ฐ์ ํ๋ซํผ์์ IoT ์ปจ์คํ ์ด๋ ๊ฐ๋ฐ ์๋น์ค๋ฅผ ์ ๊ณตํ๋ฉด ์ข์ ์์ ์์ด ๋ ์ ์์ด!
๐ฌ ๋ง๋ฌด๋ฆฌํ๋ฉฐ
์! ์ ๋ง ๊ธด ์ฌ์ ์ด์์ง? ๐ ๋ผ์ฆ๋ฒ ๋ฆฌํ์ด์ AWS IoT Core๋ฅผ ์ฐ๋ํ๋ ๋ฐฉ๋ฒ๋ถํฐ ์ค์ ์ฝ๋, ๋ณด์, ์ต์ ํ๊น์ง ์ ๋ง ๋ง์ ๊ฑธ ๋ค๋ค์ด.
ํต์ฌ์ ์ ๋ฆฌํ์๋ฉด:
โจ ํต์ฌ ์์ฝ
โข ์ค์ : AWS IoT Core์์ Thing, ์ธ์ฆ์, ์ ์ฑ
์์ฑ
โข ์ฐ๊ฒฐ: MQTT ํ๋กํ ์ฝ๋ก ์์ ํ๊ฒ ์ฐ๊ฒฐ
โข ํต์ : ๋ฉ์์ง ๋ฐํ(Publish)๊ณผ ๊ตฌ๋
(Subscribe)์ผ๋ก ์๋ฐฉํฅ ํต์
โข ๋ณด์: ์ธ์ฆ์ ๊ด๋ฆฌ์ ์ต์ ๊ถํ ์์น ์ค์
โข ์ต์ ํ: ๋น์ฉ ์ ๊ฐ์ ์ํ ์ค๋งํธํ ๋ฉ์์ง ์ ์ก
โข ํ์ฅ: ๊ท์น, Lambda, ๋ค๋ฅธ AWS ์๋น์ค์ ์ฐ๋
์ฒ์์๋ ๋ณต์กํด ๋ณด์ผ ์ ์์ง๋ง, ํ๋์ฉ ๋ฐ๋ผํ๋ค ๋ณด๋ฉด ์ด๋์ ๋ฉ์ง IoT ์์คํ ์ ๋ง๋ค ์ ์์ ๊ฑฐ์ผ. ์ค์ํ ๊ฑด ์ง์ ํด๋ณด๋ ๊ฒ์ด์ผ! ์ฝ๋๋ฅผ ๋ณต์ฌํด์ ์คํํด๋ณด๊ณ , ์๋ฌ๊ฐ ๋๋ฉด ๋๋ฒ๊น ํ๊ณ , ์กฐ๊ธ์ฉ ์์ ํด๊ฐ๋ฉด์ ์์ ๋ง์ ํ๋ก์ ํธ๋ฅผ ๋ง๋ค์ด๋ด. ๐
ํน์ ๋งํ๋ ๋ถ๋ถ์ด ์๊ฑฐ๋ ๋ ๊ถ๊ธํ ๊ฒ ์๋ค๋ฉด, AWS ๊ณต์ ๋ฌธ์๋ ์ปค๋ฎค๋ํฐ๋ฅผ ํ์ฉํด๋ด. ๊ทธ๋ฆฌ๊ณ ์์ ์ด ๋ง๋ ํ๋ก์ ํธ๋ฅผ ๋ค๋ฅธ ์ฌ๋๋ค๊ณผ ๊ณต์ ํ๋ ๊ฒ๋ ์์ง ๋ง! ๊ฐ๋ฅด์น๋ ๊ฒ์ด ์ต๊ณ ์ ํ์ต ๋ฐฉ๋ฒ์ด๊ฑฐ๋ . ๐
์, ์ด์ ๋น์ ์ฐจ๋ก์ผ! ๋ผ์ฆ๋ฒ ๋ฆฌํ์ด๋ฅผ ๊บผ๋ด์ ๋ฉ์ง IoT ํ๋ก์ ํธ๋ฅผ ์์ํด๋ณด์. ํ์ดํ ! ๐ชโจ
๊ด๋ จ ํค์๋
๋๊ธ ์์ฑ
์ด ๊ธ์ ๋ํ ์ฌ๋ฌ๋ถ์ ์๊ฐ์ ๋ค๋ ค์ฃผ์ธ์
๋ก๊ทธ์ธ์ด ํ์ํฉ๋๋ค
๋๊ธ์ ์์ฑํ๋ ค๋ฉด ๋จผ์ ๋ก๊ทธ์ธํด์ฃผ์ธ์.
๋๊ธ 0
์ง์์ธ์ ์ฒ - ์ง์ ์ฌ์ฐ๊ถ ๋ณดํธ ๊ณ ์ง
์ง์ ์ฌ์ฐ๊ถ ๋ณดํธ ๊ณ ์ง
- ์ ์๊ถ ๋ฐ ์์ ๊ถ: ๋ณธ ์ปจํ ์ธ ๋ ์ฌ๋ฅ๋ท์ ๋ ์ AI ๊ธฐ์ ๋ก ์์ฑ๋์์ผ๋ฉฐ, ๋ํ๋ฏผ๊ตญ ์ ์๊ถ๋ฒ ๋ฐ ๊ตญ์ ์ ์๊ถ ํ์ฝ์ ์ํด ๋ณดํธ๋ฉ๋๋ค.
- AI ์์ฑ ์ปจํ ์ธ ์ ๋ฒ์ ์ง์: ๋ณธ AI ์์ฑ ์ปจํ ์ธ ๋ ์ฌ๋ฅ๋ท์ ์ง์ ์ฐฝ์๋ฌผ๋ก ์ธ์ ๋๋ฉฐ, ๊ด๋ จ ๋ฒ๊ท์ ๋ฐ๋ผ ์ ์๊ถ ๋ณดํธ๋ฅผ ๋ฐ์ต๋๋ค.
- ์ฌ์ฉ ์ ํ: ์ฌ๋ฅ๋ท์ ๋ช ์์ ์๋ฉด ๋์ ์์ด ๋ณธ ์ปจํ ์ธ ๋ฅผ ๋ณต์ , ์์ , ๋ฐฐํฌ, ๋๋ ์์ ์ ์ผ๋ก ํ์ฉํ๋ ํ์๋ ์๊ฒฉํ ๊ธ์ง๋ฉ๋๋ค.
- ๋ฐ์ดํฐ ์์ง ๊ธ์ง: ๋ณธ ์ปจํ ์ธ ์ ๋ํ ๋ฌด๋จ ์คํฌ๋ํ, ํฌ๋กค๋ง, ๋ฐ ์๋ํ๋ ๋ฐ์ดํฐ ์์ง์ ๋ฒ์ ์ ์ฌ์ ๋์์ด ๋ฉ๋๋ค.
- AI ํ์ต ์ ํ: ์ฌ๋ฅ๋ท์ AI ์์ฑ ์ปจํ ์ธ ๋ฅผ ํ AI ๋ชจ๋ธ ํ์ต์ ๋ฌด๋จ ์ฌ์ฉํ๋ ํ์๋ ๊ธ์ง๋๋ฉฐ, ์ด๋ ์ง์ ์ฌ์ฐ๊ถ ์นจํด๋ก ๊ฐ์ฃผ๋ฉ๋๋ค.
์์ง ๋๊ธ์ด ์์ต๋๋ค.