Этап 2+4: internal/api/handler/iot_device_handler.go
- MQTTAuth: POST /internal/mqtt/auth (без JWT, для EMQX)
- CreateIoTDevice, ListIoTDevices, GetIoTDevice (c password), DeleteIoTDevice, UpdateIoTDevice
- crypto/subtle.ConstantTimeCompare против timing attacks
Этап 4: internal/api/router.go
- /v1/namespaces/{ns}/iot/devices CRUD
- /internal/mqtt/auth (без JWT middleware)
Этап 3: deployments/k8s/emqx.yaml
- EMQX 5.5.1, emqx.conf (HOCON) с HTTP auth backend
- Сервис exposure: 1883 (MQTT), 8083 (WS), 18083 (Dashboard)
Этап 3: iot/cmd/mqtt-bridge/main.go
- paho.mqtt.golang: подписка на +/telemetry/+
- amqp091-go: publish в iot.{namespace}.telemetry
- deployments/k8s/iot-mqtt-bridge.yaml
Этап 7: examples/IOT/ — E2E demo (main.tf, handler.py, README.md)
go.mod: добавлен github.com/eclipse/paho.mqtt.golang v1.5.1
go build ./... — ошибок нет
58 lines
2.0 KiB
Python
58 lines
2.0 KiB
Python
"""
|
|
Создано: 2026-04-04
|
|
handler.py — обработчик IoT-телеметрии для демонстрации IoT MVP.
|
|
|
|
Вызывается event-dispatcher при каждом MQTT сообщении от устройства.
|
|
Входящий event.body содержит JSON сформированный mqtt-bridge:
|
|
{
|
|
"namespace": "sless-abc123",
|
|
"device_id": "temp-sensor-01",
|
|
"topic": "sless-abc123/telemetry/temp-sensor-01",
|
|
"payload": {"temperature": 22.5, "humidity": 65},
|
|
"received_at": "2026-04-04T12:00:00Z"
|
|
}
|
|
"""
|
|
|
|
import json
|
|
import os
|
|
|
|
|
|
def handle(event, context):
|
|
"""Обработчик телеметрии IoT-устройства.
|
|
|
|
Логирует данные и возвращает подтверждение.
|
|
В реальном сценарии здесь: сохранение в БД, алертинг, управляющие команды.
|
|
"""
|
|
log_level = os.getenv("LOG_LEVEL", "INFO")
|
|
|
|
try:
|
|
body = json.loads(event.get("body", "{}"))
|
|
except json.JSONDecodeError as e:
|
|
return {
|
|
"statusCode": 400,
|
|
"body": json.dumps({"error": f"invalid JSON: {e}"})
|
|
}
|
|
|
|
namespace = body.get("namespace", "unknown")
|
|
device_id = body.get("device_id", "unknown")
|
|
payload = body.get("payload", {})
|
|
received_at = body.get("received_at", "")
|
|
|
|
if log_level == "INFO":
|
|
print(f"[IoT] namespace={namespace} device={device_id} at={received_at}")
|
|
print(f"[IoT] payload={json.dumps(payload)}")
|
|
|
|
# Здесь добавить бизнес-логику:
|
|
# - Запись в PostgreSQL (через POSTGRES_DSN из env)
|
|
# - Проверка порогов и алертинг
|
|
# - Публикация управляющей команды обратно на устройство
|
|
|
|
return {
|
|
"statusCode": 200,
|
|
"body": json.dumps({
|
|
"processed": True,
|
|
"device_id": device_id,
|
|
"namespace": namespace,
|
|
})
|
|
}
|