ESP32 AWS IoT Core 이상 온도 감지 파이프라인 구축 배경 및 필요성
ESP32 마이크로컨트롤러 환경에서 센서 데이터를 주기적으로 서버로 수집할 때, 모든 데이터를 클라우드 백엔드로 직접 전송하거나 처리하면 서버 컴퓨팅 리소스 및 네트워크 비용이 크게 증가합니다. 특히 실시간 환경 모니터링 시스템에서는 정상 범위의 온도 데이터보다 특정 임계값을 초과하는 이상 상태 데이터에 신속하게 대응하는 것이 핵심입니다.
AWS IoT Core와 Rules Engine을 활용하면 디바이스에서 수신된 MQTT 패킷을 클라우드 게이트웨이 입구에서 SQL 쿼리로 즉시 필터링할 수 있습니다. 조건에 부합하는 이벤트 데이터만 AWS Lambda로 직접 전달하여 Amazon SNS 알림을 발송함으로써, 백엔드 서버 부하를 줄이고 효율적인 이벤트 기반 아키텍처를 구축할 수 있습니다.
ESP32 AWS IoT Core 및 Lambda SNS 연동 핵심 요약
- AWS IoT Rules Engine SQL 필터링 : SELECT * FROM 'esp32/temperature' WHERE temperature > 30 쿼리를 적용하여 임계값을 초과하는 MQTT 메시지만 선별 라우팅합니다.
- AWS Lambda Direct Trigger 페이로드 파싱 : Rules Engine이 직접 호출하는 Lambda의 event 객체는 SQS 메세지 래핑 없이 필터링된 JSON 데이터 자체이므로 event.get('temperature') 방식으로 즉시 파싱합니다.
- ESP32 ESP-IDF esp_mqtt_client 통신 : TLS v1.2 mTLS 기반 안전한 MQTT 통신을 수행하고 JSON 페이로드를 전송하여 이상 감지 알림 파이프라인을 완성합니다.
ESP32 ESP-IDF 및 AWS IoT Core Rules Engine 상세 동작 원리 및 구현
AWS IoT Core 기반 이벤트 라우팅 아키텍처 구성 요소
AWS IoT Core 환경에서 데이터 처리 파이프라인을 구성하는 주요 구성 요소는 다음과 같습니다.
| 구성 요소 | 역할 및 기능 설명 | 주요 설정 및 API |
|---|---|---|
| ESP32 디바이스 | 온도 센서 데이터 측정 및 MQTT Topic 발행 | esp_mqtt_client_publish(), TLS v1.2 mTLS 인증 |
| AWS IoT Rules Engine | MQTT 메시지 패킷 디코딩 및 SQL 조건부 필터링 | SELECT * FROM 'esp32/temperature' WHERE temperature > 30 |
| AWS Lambda | 필터링된 JSON 이벤트를 직접 전달받아 비즈니스 로직 실행 | sns_client.publish(), lambda_handler(event, context) |
| Amazon SNS | Lambda에서 전달받은 메시지를 이메일 또는 SMS로 발송 | Publish API, Topic ARN 연결 |
AWS Lambda 직접 트리거 이벤트 구조 및 Python 핸들러 오류 수정
기존 Lambda 작성 방식 중 SQS 레코드 형식(event['Records'])을 순회하는 방식은 Rules Engine에서 Lambda를 직접(Direct Invoke) 트리거할 때 KeyError를 발생시킵니다. Rules Engine이 Lambda를 호출할 때 전달되는 event 파라미터는 SQL 쿼리의 실행 결과인 JSON 디셔너리 객체 자체입니다.
올바른 Python 3.x boto3 Lambda 핸들러 코드는 다음과 같습니다.
import json
import boto3
sns_client = boto3.client('sns')
SNS_TOPIC_ARN = "arn:aws:sns:us-east-1:123456789012:TemperatureAlertTopic"
def lambda_handler(event, context):
# Log incoming event payload from AWS IoT Rules Engine
print("Received IoT event:", json.dumps(event))
# Parse temperature directly from event object
temperature = event.get('temperature', 0)
if temperature > 30:
message = f"Alert: High temperature detected! Current value: {temperature}'C"
# Publish message to Amazon SNS
sns_client.publish(
TopicArn=SNS_TOPIC_ARN,
Message=message,
Subject="AWS IoT Temperature Alert"
)
print(f"SNS notification sent successfully for temperature: {temperature}")
return {
'statusCode': 200,
'body': json.dumps('IoT event processed successfully')
}
ESP32 ESP-IDF esp_mqtt_client 기반 MQTT 데이터 발행 구현
ESP32 하드웨어 단에서는 ESP-IDF의 esp_mqtt_client 및 cJSON 라이브러리를 사용하여 안전하게 AWS IoT Core endpoint로 온도 데이터를 전송합니다.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "mqtt_client.h"
#include "cJSON.h"
static const char *TAG = "ESP32_TEMP_PUBLISHER";
#define AWS_IOT_ENDPOINT "https://your-aws-iot-endpoint.amazonaws.com"
#define TOPIC "esp32/temperature"
extern const uint8_t aws_root_ca_pem_start[] asm("_binary_aws_root_ca_pem_start");
extern const uint8_t certificate_pem_crt_start[] asm("_binary_certificate_pem_crt_start");
extern const uint8_t private_pem_key_start[] asm("_binary_private_pem_key_start");
static void publish_temperature_task(void *pvParameters) {
esp_mqtt_client_handle_t client = (esp_mqtt_client_handle_t)pvParameters;
while (1) {
// Generate dummy temperature data
float temperature = 25.0f + (rand() % 100) / 10.0f;
cJSON *root = cJSON_CreateObject();
cJSON_AddNumberToObject(root, "temperature", temperature);
char *payload = cJSON_PrintUnformatted(root);
if (payload != NULL) {
int msg_id = esp_mqtt_client_publish(client, TOPIC, payload, 0, 1, 0);
ESP_LOGI(TAG, "Published message ID: %d, Payload: %s", msg_id, payload);
cJSON_free(payload);
}
cJSON_Delete(root);
vTaskDelay(pdMS_TO_TICKS(5000));
}
}
ESP32 AWS IoT Core 개발 및 디버깅 팁
- AWS IoT Console MQTT Test Client 활용 : AWS IoT Core 콘솔의 MQTT Test Client에서 esp32/temperature 토픽을 구독하면 ESP32 패킷의 정상 전송 여부를 실시간으로 모니터링할 수 있습니다.
- AWS CloudWatch Logs 로그 레벨 설정 : AWS IoT Core 설정에서 CloudWatch Logs 레벨을 INFO 또는 ERROR로 지정하여 Rules Engine의 SQL 파싱 결과 및 Lambda 호출 실패 이력을 정밀하게 디버깅하세요.
- Republish 및 Error Action 구성 : Rules Engine의 Error Action에 Republish 액션(esp32/error)을 지정하여 규칙 평가 실패 시 원인이 되는 메시지를 유실 없이 수집할 수 있습니다.
ESP32 AWS IoT Core 연동 시 흔히 하는 실수 및 트러블슈팅
1. AWS Lambda Resource-Based Policy (호출 권한) 누락
- 원인 : IAM Role 설정과 별개로 AWS Lambda 함수 자체의 리소스 기반 정책에 AWS IoT 서비스(iot.amazonaws.com)의 lambda:InvokeFunction 호출 허용 권한이 등록되어 있지 않은 경우 AccessDeniedException 오류가 발생합니다.
- 해결책 : AWS CLI 명령어를 사용해 Lambda 함수에 AWS IoT Core의 호출 권한을 명시적으로 부여합니다.
aws lambda add-permission --function-name YourLambdaFunction --statement-id iot-events --action lambda:InvokeFunction --principal iot.amazonaws.com
2. JSON Payload 데이터 타입 불일치 (String vs Number)
- 원인 : ESP32에서 JSON 생성 시 온도 값을 문자열("30.5")로 전송하면 Rules Engine의 SQL 조건문 WHERE temperature > 30 비교 평가 시 Type Mismatch로 인해 필터링 조건문이 올바르게 동작하지 않습니다.
- 해결책 : cJSON 라이브러리의 cJSON_AddNumberToObject() 함수를 사용하여 부동 소수점/정수형 타입으로 패킷을 구성하거나 SQL 문에서 CAST(temperature AS DECIMAL) 함수를 통해 명시적 타입 변환을 수행하세요.
ESP32 AWS IoT Core 및 Lambda 연동 시스템 구축 결론
ESP32와 AWS IoT Core Rules Engine, Lambda, SNS를 연동하면 Edge 디바이스의 데이터 전송 효율을 극대화하고 이상 상태 발생 시 즉각적인 대응 시스템을 구축할 수 있습니다. Rules Engine의 SQL 기반 데이터 필터링과 올바른 Lambda 핸들러 구성을 통해 확장성 높고 안정적인 IoT 이벤트 기반 아키텍처를 개발할 수 있습니다.