from sqlalchemy import Boolean, Column, ForeignKey, Integer, String, TIMESTAMP, Float
from .base import Base
์ ๋ชฉ์ ๊ฑฐ์ฐฝํ๊ฒ ์จ๋จ์ง๋ง ์์ฃผ ๊ฐ๋จํ ๋ฐฑ์๋๋ฅผ ๊ตฌ์ถํด์ ๊ทธ๋ฆฌ ์ค๋๊ฑธ๋ฆฌ์ง ์์์ ๋ฟ์ด๋ค^^.
์ฐ์ ๋ฐฑ์๋๋ฅผ ํด๋ณด๋ ๊ฒ ์์ฒด๊ฐ ์ด๋ฒ์ด ์ฒ์์ด๊ณ , ํ์์ ์ํด์ ํ์ํ ๋ถ๋ถ๋ง ๊ณต๋ถํด์ ํ๋ฅ๋ฅ ๋ง๋ค์ด์ ๋ค์ ์กฐ์กํ ์ ์์ผ๋ ์ด์จ๋ ๋ชจ๋ํฐ๋ง ์์คํ ์์ฒด๋ ์ ๋์ํ๊ณ ์์ผ๋ ํธ์คํ ๋ง ๋ฐ๋ก ํด์ฃผ๋ฉด ๋น์ฅ ์ธ ์ ์๋ค. Python์ผ๋ก ์์ฑ๋์ด ์์ด์ Python์ ๋ ธ์์ธ ๋์๊ฒ๋ ์์ฃผ ํธํ ํ๋ก๊ทธ๋๋ฐ์ด์๋ ๊ฒ๋ ํ ๋ชซํ๋ค.
0. Fast API ์์ต์
Fast API ๊ณต์๋ฌธ์๋ก ๊ณต๋ถํ๋ ์๊ฐ์ ํ๋ฃจ ๊ฐ์ง๊ณ ์ดํ๋์ ๊ฐ๋ฐ์ ํ๋ค. ์๋ ๋ ๊ธ ์ฐธ๊ณ . ํํ ๋ฆฌ์ผ์ด ์์ด๋ก ๋์ด์์ด์ ํ๊ตญ์ด๋ก ์ด์คํ๊ฒ๋๋ง ๋ฒ์ญํ๊ณ ์ ๋ฆฌํด๋์๋ค.
https://dnai-deny.tistory.com/59
https://dnai-deny.tistory.com/60
1. ๊ตฌ์กฐ ๊ตฌ์ํ๊ธฐ
๊ฒ์ผ๋ก ๋๋ฌ๋๋ ๊ตฌ์กฐ๋ ์๋์ ๊ฐ๋ค. ์ค์ ๋ก ๊ตฌํํด์ผํ๋ ๋ถ๋ถ์ Data ์ ๊ฒฝ์ฐ CRUD(Create, Read, Update, Delete)๋ฅผ ๊ตฌํํด์ผํ๊ธฐ ๋๋ฌธ์ ์ข ๋ ๋ง๋ค.
A. Data Table
Monitoring System์ ๋น๊ต์ ๊ฐ๋จํ ๊ตฌ์กฐ๋ฅผ ๊ฐ์ง๊ณ ์๋ค. ์ด ๋ชจ๋ํฐ๋ง ์์คํ ์ ์์๋ก ๋ฐ์์์ผ์ MQTT๋ฅผ ํตํด ๋ฐ์์ค๋ ์จ๋ ๋ฐ์ดํฐ๋ฅผ ์ค์๊ฐ์ผ๋ก ๊ฐฑ์ ํ์ฌ ์๊ฐํํ๋ ๊ฒ์ ๋ชฉํ๋ก ํ๊ณ ์์ผ๋ฏ๋ก, ์ด ์ธ ๊ฐ์ง์ ๋ฐ์ดํฐ ํ ์ด๋ธ์ด ํ์ํ๋ค. ์ด ๋ฐ์ดํฐ ์ข ๋ฅ์ ๋ฐ๋ผ ํ๋ก์ ํธ ๊ตฌ์กฐ๋ฅผ ๋ณ๊ฒฝํ ๊ฒ์ด๋ค.
์ด์ ๊น์ง์ ์ง๋ ๋ฐ์ดํฐ ๋ชจ๋ํฐ๋ง ์์คํ ์ ํน์ํ ๊ฒฝ์ฐ๋ก, ์น ์๋ฒ๋ฅผ ํตํ๋ ๊ฒฝ์ฐ ๊ทธ ์ ๋๋ก ๊ณ ์์ ๋ฐ์ดํฐ ํต์ ์ ๋ถ๊ฐ๋ฅํ๋ค. ๋ฐ๋ผ์ ๋ฐ์ดํฐ๋ฅผ ์จ๋ ๋ฐ์ดํฐ๋ก ๋ณ๊ฒฝํ์๋ค๋ ์ ์ ์ฐธ๊ณ ๋ฐ๋๋ค.
- User
- ๋ก๊ทธ์ธ / ๊ฐ์
- ์ฌ์ฉ์์ ๊ถํ์ ๋ฐ๋ผ ๋ชจ๋ํฐ๋ง ํ์ด์ง ์ ๊ทผ ๊ถํ ์ ์ด
- Sensor
- ํ์ฌ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์ค๊ณ ์๋ ์ผ์์ ์ข ๋ฅ
- ์ผ์ ์ ๋ณด
- ์ผ์ ๊ด๋ฆฌ์
- Degree
- ์จ๋ ๋ฐ์ดํฐ
- ๋ฐ์ดํฐ๋ฅผ ์ทจ๋ํ๊ณ ์๋ ์ผ์ ์ ๋ณด
B. Pages
์ดํ์ ๋ ๋ง์ ํ์ด์ง๊ฐ ํ์ํ ์๋ ์์ผ๋, ํ์ฌ ํ์ํ ํ์ด์ง๋ ์ด ์ธ ๊ฐ์ง์ด๋ค.
- ํ์๊ฐ์ ํ์ด์ง
- ๋ก๊ทธ์ธ ํ์ด์ง
- ๋ชจ๋ํฐ๋ง ํ์ด์ง
์ด ์ค ํ์๊ฐ์ ๋ฐ ๋ชจ๋ํฐ๋ง ํ์ด์ง๋ bootstrap ํ ํ๋ฆฟ์ ์ฌ์ฉํ๊ธฐ๋ก ํ๋ค. ํ์๊ฐ CSS๋ ์ฌ์ด๊ฐ ์ ์ข๋ค. ๋ชจ๋ํฐ๋ง ํ์ด์ง๋ ์ง๊ธ์ ๊ฐ๋จํ ๊ทธ๋ํ ํ๋ ๊ทธ๋ฆฌ๋ ์ ๋๊ฐ ๋ชฉํ์ด๋ฏ๋ก, ๊ตฌ๊ธ ๊ทธ๋ํ api๋ฅผ ์ฌ์ฉํด์ ๊ทธ๋ฆฌ๊ธฐ๋ก ํ๋ค. ์๋ฌดํผ ์ด๊ฑด ์ข ๋ ๋์ค ์๊ธฐ๋ค.
๋ก๊ทธ์ธ ํ์ด์ง์์๋ ์์ด๋์ ๋น๋ฐ๋ฒํธ๋ฅผ ์ ๋ ฅ๋ฐ๊ณ , DB์ User Table์์ ์ผ์นํ๋ ์ ๋ณด๊ฐ ์๋์ง ํ์ธํด์ ๋ก๊ทธ์ธ์ ํ์ฉํ๊ฑฐ๋ ์ฐจ๋จํ๋ค. ๋ง์ผ ์ ๋ณด๊ฐ ์๋ค๋ฉด ํ์๊ฐ์ ์ ํ์ฌ DB์ ์ ๋ณด๋ฅผ ์ถ๊ฐํ๋ค.
๋ชจ๋ํฐ๋ง ํ์ด์ง์์๋ ํ์ฌ ์์ง๋๊ณ ์๋ ์จ๋ ๋ฐ์ดํฐ๋ฅผ plotํ๋ ๊ฒ์ด ๋ชฉํ์ด๋ค.
2. ๊ฐ๋ฐํ๊ฒฝ ๊ตฌ์ฑ
vscode ๋ฑ ์ฝ๋ ํธ์ง๊ธฐ์ postgreSQL์ด ํ์ํ๋ค. postgreSQL๊ณผ vscode๋ ์๋ ๋งํฌ์์ ์ค์น ๊ฐ๋ฅํ๋ค. python์ด ์๋ค๋ฉด ์ด๊ฒ๋ ์ค์นํ์. python 3.11...์ด ์ธ์ ๋ฆด๋ฆฌ์ฆ๋์ง? ํ์๋ ํ์ด์ฌ ์ ๋ฐ์ดํธ๋ฅผ ํ์ง ์์๊ธฐ ๋๋ฌธ์ ์ฌ์ ํ 3.8์ด๋ค. ์ ์ ํ ๋๋ฌด ์ค๋๋์ง ์์ ๋ฒ์ ์ผ๋ก ํ๋ฉด ๋๊ฒ ๋ค.
vscode์ ํฐ๋ฏธ๋์์ fastapi๋ฅผ ์ค์นํ๋ค.
!pip install fastapi
์ค๋น๋ ๋๋ฌ๋ค.
์ ์๋๋ฌ๋ค.
!pip install sqlalchemy pydantic typing_extension uvicorn
DB ์ฐ๊ฒฐ์ ์ํด SQLAlchemy๋ผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ, fastapi ํ์ฉ์ ์ํด pydantic๊ณผ typing_extension๋ ์์ผ๋ฉด ์ค์นํด์ฃผ๊ณ , ์๋ฒ๋ฅผ ๋ผ์ด๋ธ๋ก ๋์๋ณด๊ธฐ ์ํด์ uvicorn๋ ์ค์นํ๋ค. ์ง์ง ๋๋ฌ๋ค. ํ์ํ ๊ฒ ์๊ฐ๋๋ฉด ๊ทธ๋ ๊น์์ฃผ๋๋ก ํ๊ฒ ๋ค.
3. api ํ์ด์ง ๋ง๋ค๊ธฐ
๋ผ์ฐํธ ์ฃผ์์ ์ ๊ทผํด์ ๋ฐ์ดํฐ๋ฅผ ์ฝ๊ณ , ๊ฒ์ํ๊ณ , ์ญ์ ํ๊ณ ์์ ํ ์ ์์ผ๋ฏ๋ก ์ฐ์์์ ๋ฐ๋ผ์ ๋ผ์ฐํธ๋ฅผ ๋๋ ์ฃผ๋ ๊ฒ์ด ์ข๋ค. ์ฝ๋์ ์ผ๋ก ๋ถ๋ฆฌ๋ ๋ถ๋์ด ๋์ด๋ฌ์ ๋ ํ๊ณ , ์ฐ์ ์ ๋ฉ์ธ์ api ๋ค์ ์ฝ๊ณ ์ฐ๊ณ ํ๋ ๋ถ๋ถ์ ๋จผ์ ๋ง๋ค์ด๋ณด์.
- main.py
from fastapi import FastAPI
app = FastAPI()
# api section
@app.get('/api/')
def root():
return {"message": "This is backend side API section."}
uvicorn main:app --reload
์ด๋ ๊ฒ ์คํํ๋ฉด http://127.0.0.1/8000/api ์ฃผ์์์ message json์ ๋ง๋๋ณผ ์ ์๋ค.
๊ทธ๋ผ ๊ณง์ฅ ์์์ ์ด์ผ๊ธฐํ๋ ์ธ ๊ฐ์ง ๋ฐ์ดํฐ, User, Sensor, Degree ๋ฐ์ดํฐ๋ฅผ ๋ง๋ค์ด๋ณด๋๋ก ํ์. ๊ฐ์ฅ ๋จผ์ ํด์ผํ ๊ฒ์ PostgreSQL๊ณผ ์ฐ๊ฒฐํ๋ ๊ฒ์ด๋ค. PostgreSQL ํด๋ผ์ด์ธํธ(pg Admin ์ด๋ผ๋ ์ด๋ฆ์ด๋ค)์ ๋ค์ด๊ฐ์ ๊ธฐ๋ณธ์ ๋ณด๋ฅผ ๋ฑ๋กํ๋ค๋ฉด, ์ ์๋ฒ๋ฅผ ๋ง๋ค์ด์ ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์์ฑํ๋ค. databases์์ ์ฐํด๋ฆญํ๊ณ createํ๋ฉด ์๋์ ๊ฐ์ ์ฐฝ์ด ๋ฌ๋ค. ์ด๋ฆ์ ์ ๋นํ ๋ฑ๋กํ๋ค.
๊ทธ๋ฆฌ๊ณ ๋์ ๋ค์ vscode๋ก ๋์์์, SQLAlchemy engine์ ์ ์ธํด์ฃผ์. core ํด๋ ํ์์ base.py ํ์ผ์ ์๋ก ๋ง๋ค์ด ์ ๋ฃ์ด์ฃผ์๋ค.
a. ๋ฐ์ดํฐํ ์ด๋ธ ๊ธฐ๋ณธ ๊ตฌ์กฐ ๋ง๋ค๊ธฐ
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
SQLALCHEMY_DATABASE_URL = "postgresql://{server_username}:{server_password}@localhost:5432/{database_name}"
engine = create_engine(SQLALCHEMY_DATABASE_URL)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
๋น์ฅ ์ดํดํ ํ์๋ ์๋ค. ๊ทธ๋ผ ๋ฐ๋ก ์ธ ๊ฐ์ง ๋ฐ์ดํฐ์ ๋ํ ํ ์ด๋ธ ๊ตฌ์กฐ๋ฅผ ๋ง๋ค์ด๋ณด์
PostgreSQL์ ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ด๋ฏ๋ก ํ ์ด๋ธ์ ์ ์คํ๊ฒ ๊ตฌ์ฑํด์ผํ์ง๋ง(์ด๋ค DB๋ ์ ๊ทธ๋ฌ๊ฒ ๋๋ง์) ์ด๋ฒ์๋ ๋ค๋ฃฐ ๋ฐ์ดํฐ๊ฐ ์ ๊ณ ์๋ก ๊ด๊ณ๋ ๋ช ํํ๋ฏ๋ก ๋น ๋ฅด๊ฒ ์์ฑํด๋ณด๊ฒ ๋ค.
1. User
from sqlalchemy import Boolean, Column, ForeignKey, Integer, String, TIMESTAMP, Float
from sqlalchemy.orm import relationship
from .base import Base
class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True, index=True)
username = Column(String, index=True)
email = Column(String, unique=True, index=True)
password = Column(String, index=True)
disabled = Column(Boolean, index=True, default=False)
sensors = relationship("Sensor", back_populates="owner")
- id๊ฐ ๋ํ ํค๋ก ์ค์ ๋์ด ์๋ค.
- email์ ์ค๋ณต๋ ์ ์๋ค
- disabled(๋นํ์ฑํ)์ ๊ธฐ๋ณธ ๊ฐ์ False์ด๋ค.
2. Sensor & Degree
class Sensor(Base):
__tablename__ = "sensors"
id = Column(Integer, primary_key=True, index=True)
administer_id = Column(Integer, ForeignKey("users.id"))
owner = relationship("User", back_populates="sensors")
degrees = relationship("Degree", back_populates="sensor")
class Degree(Base):
__tablename__ = "degrees"
id = Column(Integer, primary_key=True, index=True)
time = Column(TIMESTAMP, index=True)
degree = Column(Float, index=True)
sensor_id = Column(Integer, ForeignKey("sensors.id"))
sensor = relationship("Sensor", back_populates="degrees")
- Sensor์ administer_id์ Degree์ sensor_id๋ ๊ฐ๊ฐ ๋ค๋ฅธ ํ ์ด๋ธ์ ํ column์ ์ฐธ์กฐํ๊ณ ์๋ค. ์ด๋ฅผ ์ธ๋ถํค(Foreign key)๋ผ๊ณ ํ๋๋ฐ, FastAPI์ SQLAlchemy์์๋ ์์ ๊ฐ์ด ํํํด์ค๋ค.
- User์ sensors, Sensor์ degrees์ Degree์ sensor์ relationship์ด๋ผ๋ ํญ๋ชฉ์ด ์๋ค. ์ด๋ ๋ฐ์ดํฐ ํ ์ด๋ธ๊ฐ์ ๊ด๊ณ๋ฅผ ํ์ํ๋ ๊ฒ์ด๋ค.
b. ์คํค๋ง ๋ง๋ค๊ธฐ
๊ฐ์ ๋ป ๊ฐ์ง๋ง, ์ข ๋ ๋ถ๋ฆฌํด์ ์ฐ๋ฆฌ๊ฐ fastapi ์์์ ์ฌ์ฉํ ์ ์๋ ํํ๋ฅผ ๋ง๋ค์ด์ค ๊ฒ์ด๋ค. ์๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ํ ์ด๋ธ์ ํ์ฑํ๋ ๋จ๊ณ์ ๊ฐ๊น๊ณ , ์ง๊ธ๋ถํฐ๋ FastAPI์์ ํธ์ถํด์ ์์ฑํ๊ณ ๋ถ๋ฌ์ค๊ณ ์ญ์ ํ ๊ตฌ์กฐ๋ฅผ ์์ฑํ๋ ๊ฒ์ด๋ค.
1. User
from typing import List, Union
from pandas import Timestamp
from pydantic import BaseModel
# user
class UserBase(BaseModel):
username: str
email: str = None
class UserCreate(UserBase):
password: str
class User(UserBase):
id: int
sensors: List[Sensor] = []
disable: bool = False
class Config:
orm_mode = True
- ํ๋์ ํ ์ด๋ธ ๋น ์ธ ๊ฐ์ ์คํค๋ง๋ก ๋๋์๋ค. ์ฒซ๋ฒ์งธ, Base๋ pydantic์ BaseModel์ ์์๋ฐ์ username, email์ ๊ธฐ๋ณธ ์ ๋ณด๋ฅผ ์ ์ธํด์ฃผ์๋ค.
- ๋ ๋ฒ์งธ Create์์๋ ๊ธฐ๋ณธ ์ ๋ณด์ ํ ์ด๋ธ ์์ฑ์ ์ํด ๋ฐ๋์ ํ์ํ ์์๋ฅผ ์ถ๊ฐํด์ฃผ์๋ค.
- ์ธ ๋ฒ์งธ ์์ฑ๋ ํด๋ ์ค์์๋ ์์ ๊ตฌ์กฐ๋ฅผ ๋ง๋ค ๋ ํ์ํ๋ ๋ชจ๋ ์์๋ค์ ์ถ๊ฐํด์ฃผ์๋ค.
- ๋ง์ง๋ง์ password๋ฅผ ๋๋ฌ๋ด์ง ์๋๋ก ์ค์ ํ๋ค. ๋์ค์ ํด์ฌ ๋ฐฉ์์ผ๋ก ๋ณด์์ ์กฐ๊ธ์ด๋๋ง! ์ถ๊ฐํ ๋ค์ ์์ ํ๋๋ก ํ๊ฒ ๋ค.
class Config:
orm_mode = True
์ด pydantic์ orm_mode๋ฅผ True๋ก ๋ง๋ค์ด์ฃผ๋ฉด, User๋ผ๋ ๊ฐ์ฒด๋ฅผ ๋ถ๋ ์ ๋ ๋ฐํํ์ ๋ง๋ค์ด์ ์ ๋ณด๋ฅผ ๋ณด์ฌ์ค๋ค.
2. Sensor
# sensor
class SensorBase(BaseModel):
administer_id : int
class SensorCreate(SensorBase):
pass
class Sensor(SensorBase):
id : int
degrees : List[Degree] = []
class Config:
orm_mode = True
- ์ผ์๋ ์์ฑํ ๋ ๊ธฐ๋ณธ ์ ๋ณด์์ ์ถ๊ฐํด์ผํ ๊ฒ์ด ๋ณ๋๋ก ์์ง ์๋ค.
3. Degree
class DegreeBase(BaseModel):
time: Timestamp
degree: float
sensor_id: int
class DegreeCreate(DegreeBase):
pass
class Degree(DegreeBase):
id: int
class Config:
orm_mode = True
- ์จ๋ ๋ฐ์ดํฐ๋ ์์ฑํ ๋ ๊ธฐ๋ณธ ์ ๋ณด์์ ์ถ๊ฐํด์ผํ ๊ฒ์ด ๋ณ๋๋ก ์์ง ์๋ค.
4. ์ ๋ง๋ค์ด์ก๋๊ฐ ํ ์คํธํ๊ธฐ
ํ ์คํธ๋ฅผ ์ํด์๋ ์ฐ์ main ํ์ผ์ ๋๊ฐ์ง๋ฅผ ์ถ๊ฐํด์ผํ๋ค.
from core import models
models.Base.metadata.create_all(bind=engine)
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
models.Base.metadata.create_all(bind=engine)์ ์ฐ๋ฆฌ๊ฐ models์ ๋ง๋ค์ด๋์ ํ ์ด๋ธ ๊ตฌ์กฐ๋ฅผ ๊ทธ๋๋ก ์์ฑํ๋ค๋ ๋ป์ด๋ค. uvicorn์ผ๋ก ์คํํ๊ณ ๋๋ฉด table๋ค์ด ์๊ธด ๊ฒ์ ํ์ธํ ์ ์๋ค.
get_db ํจ์๋ db session ์ ํธ์ถํ๋ค. ์ผ์ข ์ db ์ ๊ทผ ๊ถํ์ด๋ผ๊ณ ์๊ฐํ๋ฉด ๋ ๊ฒ ๊ฐ๋ค.
๊ทธ๋ฆฌ๊ณ ํ ์คํธ๋ฅผ ์ํด์ ์ ์ ๋ฅผ ์ถ๊ฐํ๊ณ ์ฝ์ด์ค๋ ํจ์๋ฅผ ๋ ๊ฐ ๋ฃ์๋ค.
@app.get('/api/users')
def get_users(skip: int = 0, limit: int = 100, db = Depends(get_db)):
# db์ User table์์ [skip : limit] ๊น์ง์ ๋ฆฌ์คํธ
return db.query(models.User).offset(skip).limit(limit).all()
@app.get('/api/createuser')
def creat_user(username: str, password: str, email: str, db = Depends(get_db)): # ๋์ค์ User Create ๊ฐ์ฒด๋ก ๋ฐ์์ค๋๋ก ์์
# User ๊ฐ์ฒด ์์ฑ
db_user = models.User(username=username, password=password, email=email)
# db์ ์ถ๊ฐ
db.add(db_user)
# ๋ฐ์
db.commit()
# ์๋ก๊ณ ์นจ
db.refresh(db_user)
return db_user
์ด์ ์ฃผ์์ฐฝ์ ํตํด์ ์ ์ ๋ฅผ ๋ง๋ค์ด๋ณผ ์ ์๋ค.
http://localhost:8000/api/createuser/?username=dnai&password=1234&email=dmelli0505@gmail.com
์๋๋ get์ด ์๋ post๋ก ์ ๋ฌํ์ง๋ง, ์ฐ๋ฆฌ๋ form ํํ๊ฐ ์๋๋ผ ์ผ๋ฐ ์ฟผ๋ฆฌ ๋งค๊ฐ๋ณ์๋ก ์ผ๋จ ๋ฃ์ด์ ํ ์คํธ ํด๋ณด๋ ๊ฒ์ด ๋ชฉํ์ด๋ฏ๋ก ์์ ๊ฐ์ด get์ ์ฌ์ฉํด์ ์์ ํจ์๋ฅผ ๊ตฌ์ฑํ๋ค.
์ด์ postgreSQL์์ ์ฟผ๋ฆฌ๋ฌธ์ผ๋ก users ํ ์ด๋ธ์ ๋ณด๋ฉด ์ ์ถ๊ฐ๋ ๊ฒ์ ํ์ธํ ์ ์๋ค!
http://localhost:8000/api/users ๋ก ์ ์ํ๋ฉด ๋ฐฉ๊ธ ์ถ๊ฐํ ์ ์ ๋ฅผ ํ์ธํ ์ ์๋ค.
๋ด์ฉ์ด ์ ๋ฒ ๊ธธ์ด์ก์ผ๋ฏ๋ก ๋ค์ ๋ฒ์๋ sensor ๋ฐ์ดํฐ๋ฅผ ํ๋ ์ถ๊ฐํ๊ณ , ์ด์ ์ ๊ตฌํํด๋ mqtt๋ฅผ ํ์ฉํด ์จ๋ ๋ฐ์ดํฐ๋ฅผ ์์งํด ๋ฃ๊ณ ๋ฐ์ดํฐ๊ฐ ๊ผฌ์ด์ง๋ ์๋์ง ํ์ธํด๋ณด๋ ์๊ฐ์ ๊ฐ๋๋ก ํ๊ฒ ๋ค.
https://dnai-deny.tistory.com/62
ํ๋ ธ๊ฑฐ๋ ์ด์ํ ์ ์ด ์์ผ๋ฉด ๋๊ธ๋ก ์๋ ค์ฃผ์๊ธธ ๋ฐ๋๋๋ค!
+) ๋ค์ ํฌ์คํ ์ด ๋์์ต๋๋ค.