[Monitoring System] 7. Fast API ๋กœ ์ดํ‹€๋งŒ์— ๋ฐฑ์—”๋“œ ๊ตฌ์ถ•ํ•˜๊ธฐ(feat. Google Chart) (3) - ๋งˆ์นจ๋‚ด ๊ทธ๋ž˜ํ”„ ๊ทธ๋ฆฌ๊ธฐ ๅฎŒ

2023. 9. 25. 16:30ยท๐ŸŽผ Project/๐ŸงŠ Monitoring System
728x90
 

[Monitoring System] 5. Fast API ๋กœ ์ดํ‹€๋งŒ์— ๋ฐฑ์—”๋“œ ๊ตฌ์ถ•ํ•˜๊ธฐ(feat. SQLAlchemy, PostgreSQL) (1)

from sqlalchemy import Boolean, Column, ForeignKey, Integer, String, TIMESTAMP, Float from .base import Base ์ œ๋ชฉ์€ ๊ฑฐ์ฐฝํ•˜๊ฒŒ ์จ๋†จ์ง€๋งŒ ์•„์ฃผ ๊ฐ„๋‹จํ•œ ๋ฐฑ์—”๋“œ๋ฅผ ๊ตฌ์ถ•ํ•ด์„œ ๊ทธ๋ฆฌ ์˜ค๋ž˜๊ฑธ๋ฆฌ์ง€ ์•Š์•˜์„ ๋ฟ์ด๋‹ค^^. ์šฐ์„  ๋ฐฑ์—”๋“œ๋ฅผ

dnai-deny.tistory.com

 

[Monitoring System] 6. Fast API ๋กœ ์ดํ‹€๋งŒ์— ๋ฐฑ์—”๋“œ ๊ตฌ์ถ•ํ•˜๊ธฐ(feat. SQLAlchemy, PostgreSQL) (2) - MQTT ๋ฐ์ดํ„ฐ ์ 

2023.06.13 - [Project/Monitoring System] - [Monitoring System] 5. Fast API ๋กœ ์ดํ‹€๋งŒ์— ๋ฐฑ์—”๋“œ ๊ตฌ์ถ•ํ•˜๊ธฐ(feat. SQLAlchemy, PostgreSQL) (1) [Monitoring System] 5. Fast API ๋กœ ์ดํ‹€๋งŒ์— ๋ฐฑ์—”๋“œ ๊ตฌ์ถ•ํ•˜๊ธฐ(feat. SQLAlchemy, PostgreSQL) (1) f

dnai-deny.tistory.com

 

 

์ง€๋‚œ ํฌ์ŠคํŒ…์—์„œ ๋กœ๊ทธ์ธ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ๊นŒ์ง€ ํ•ด๋ดค๋‹ค. ์ด๋ฒˆ ์‹œ๊ฐ„์—๋Š” ๊ตฌ๊ธ€ ์ฐจํŠธ๋ฅผ ์ด์šฉํ•ด์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์‹œ๊ฐํ™”ํ•˜๊ณ , ์‹œ๊ฐํ™” ํŽ˜์ด์ง€๋ฅผ ๋กœ๊ทธ์ธํ•˜์ง€ ์•Š๊ณ ๋Š” ๋ณด์ด์ง€ ์•Š๋„๋ก ํ•ด๋ณด๋„๋ก ํ•˜๊ฒ ๋‹ค.

 

1. ํŽ˜์ด์ง€ ์—ด๋žŒ ๊ถŒํ•œ ํ™•์ธํ•˜๊ธฐ

๊ฐ€์žฅ ๋จผ์ €, ๋กœ๊ทธ์ธํ•˜์ง€ ์•Š๊ณ ๋Š” ๋Œ€์‹œ๋ณด๋“œ๋ฅผ ๋ชป๋ณด๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋กœ๊ทธ์ธ ์ •๋ณด๊ฐ€ ํ•„์š”ํ•˜๋‹ค. ์ง€๋‚œ ํฌ์ŠคํŒ…์—์„œ ๋กœ๊ทธ์ธ์— ์„ฑ๊ณตํ•˜๋ฉด access token์„ ๋ฐœ๊ธ‰ํ•œ ๊ฒƒ์„ ๊ธฐ์–ตํ•˜๊ณ  ์žˆ์„ ๊ฒƒ์ด๋‹ค. ์ด access token์„ ์ด์šฉํ•ด์„œ ํ˜„์žฌ access token์ด ์œ ํšจํ•œ์ง€ ํ™•์ธํ•œ ํ›„ ์œ ํšจํ•˜๋ฉด ํŽ˜์ด์ง€๋ฅผ ๋ณด์—ฌ์ฃผ๊ณ , ์•„๋‹ˆ๋ฉด ๋‹ค์‹œ ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€๋กœ ๋ณด๋‚ด์ฃผ๋ฉด ๋œ๋‹ค.

์ด์ œ ์‰ฝ๊ฒŒ ๋งํ•œ ๊ฑธ ๊ตฌํ˜„ํ•ด๋ณด์ž.

๋จผ์ €, access token์€ ์ฟ ํ‚ค ๋ฐ์ดํ„ฐ์— ํฌํ•จ๋˜์–ด ์žˆ๋‹ค. ajax jquery์—์„œ๋Š”

$.cookie("access_token")

์ด๋ ‡๊ฒŒ ๋ฐ›์•„์˜ฌ ์ˆ˜ ์žˆ๋‹ค. ์ด ๋‚ด์šฉ์„ header์— ๋„ฃ์–ด์„œ ์„œ๋ฒ„ ์ชฝ์œผ๋กœ ๋ณด๋‚ด์ค˜์•ผํ•˜๋Š”๋ฐ, ํ† ํฐ์ด jwt ํ˜น์€ OAuth์— ๊ด€ํ•œ ๋‚ด์šฉ์ด๋ผ๋ฉด ์•ž์— Bearer๋ผ๋Š” ํƒ€์ž…์„ ๋„ฃ์–ด์ฃผ์–ด์•ผํ•œ๋‹ค. ์ „์ฒด Ajax ํ•จ์ˆ˜๋ฅผ ์งœ๋ณด๋ฉด ์•„๋ž˜์™€ ๊ฐ™๋‹ค. ์ด ํ•จ์ˆ˜๋Š” ๋Œ€์‹œ๋ณด๋“œ ๋กœ๋“œ ์‹œ์— ์ž‘๋™ํ•ด์•ผํ•˜๋ฏ€๋กœ ๋‹น์—ฐํžˆ ๋Œ€์‹œ๋ณด๋“œ html ์•ˆ์— ์‚ฝ์ž…ํ•œ๋‹ค.

$(document).ready(function ($) {
      $.ajax({
        url: "<http://localhost:8000/me>",
        method: "GET",
        contentType: false,
        processData: false,
        headers: {
          "Content-Type": "application/x-www-form-urlencoded",
          Authorization: "Bearer" + $.cookie("access_token"), // token ์ „๋‹ฌ
        },
        success: function (response) {
          console.log("get Succeed!");
        },
        error: function (response) {
          alert(response.responseJSON.detail);
          location.href = "<http://localhost:8000/>"; // ๊ถŒํ•œ ์—†์œผ๋ฉด ๋กœ๊ทธ์ธ ํ™”๋ฉด์œผ๋กœ
        },
      });
    });

์ด์ œ "<http://localhost:8000/me>" ์— ๋Œ€ํ•œ ์„œ๋ฒ„ ์ชฝ ํ•จ์ˆ˜๋ฅผ ์งœ๋ณด์ž. ๋ฌด๋ ค ์„ธ ๊ฐ€์ง€ ํ•จ์ˆ˜๊ฐ€ ๋ฌผ๋ ค ์žˆ์œผ๋ฏ€๋กœ ์กฐ์‹ฌํ•ด์„œ ํ•˜๋‚˜์”ฉ ์ ‘๊ทผํ•ด๋ณด๊ธฐ๋กœ ํ•œ๋‹ค.

์ด์ „์— get_current_user ๋ผ๋Š” ํ•จ์ˆ˜๋ฅผ ์ž‘์„ฑํ–ˆ์œผ๋‹ˆ, ์ด๊ฑธ ๋ฐ”ํƒ•์œผ๋กœ ํ•œ ๋ฒˆ ์งœ๋ณด๋ ค๊ณ  ํ•œ๋‹ค. ์šฐ์„  ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ–ˆ์—ˆ๋Š”์ง€ ํ•œ ๋ฒˆ ํ™•์ธํ•ด๋ณด์ž.

async def get_current_user(token: str = Depends(get_token), db: Session = Depends(get_db)) -> models.User:
    try: 
        payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
        token_data = user_schema.TokenPayload(**payload)

        if datetime.fromtimestamp(token_data.exp) < datetime.now():
            raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Token Expired")
    except(jwt.JWTError, ValidationError):
        raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Could not validate credentials")
    
    user = user_crud.get_user_by_username(db=db, username=token_data.sub)

    if user is None:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Could not find user")
    
    return user

get_current_user ํ•จ์ˆ˜๋Š” token์„ ๋ฐ›์•„์„œ user๋ฅผ ๋Œ๋ ค์ฃผ๊ณ , token์ด ์œ ํšจํ•˜์ง€ ์•Š๊ฑฐ๋‚˜ ์œ ์ €๊ฐ€ ์—†์œผ๋ฉด exception์„ ์ผ์œผํ‚ค๋„๋ก ์ž‘์„ฑ๋˜์–ด ์žˆ๋‹ค. token: str = Depends(get_token) ๋ถ€๋ถ„์€ token์„ get_token ํ•จ์ˆ˜์˜ ๋ฆฌํ„ด๊ฐ’์œผ๋กœ ๊ฐ–๊ฒ ๋‹ค๋Š” ๋œป์ด๋‹ˆ get_token ํ•จ์ˆ˜๋„ ํ™•์ธํ•ด๋ณด์ž.

def get_token(authorization: str = Header(default=None)):
    print(authorization)
    return authorization[6:]

์ด ํ•จ์ˆ˜์—์„œ๋Š” token์„ Header์—์„œ ๋ฐ›์•„์™€์„œ ๋’ท์ฒ˜๋ฆฌ ํ›„์— ๋ฆฌํ„ดํ•œ๋‹ค. ๊ทธ๋ ‡๋‹ค๋Š” ๊ฒƒ์€, ์šฐ๋ฆฌ๊ฐ€ Ajax ํ•จ์ˆ˜๋กœ ์ž‘์„ฑํ•œ ๋ถ€๋ถ„์—์„œ

 			headers: {
          "Content-Type": "application/x-www-form-urlencoded",
          Authorization: "Bearer" + $.cookie("access_token"), // token ์ „๋‹ฌ
        }, 

์ด! ๋ถ€๋ถ„์˜ Authorization ์—์„œ ๊ฐ€์ ธ์˜จ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ๊ทธ๋Ÿผ ๋” ์ด์ƒ ์ถ”๊ฐ€์ ์œผ๋กœ ๊ตฌํ˜„ํ•  ๋ถ€๋ถ„์€ ์—†๋‹ค. ๋‹ค๋งŒ ์ด ์ƒ๊ด€๊ด€๊ณ„๋ฅผ ์•Œ๊ณ  ์žˆ์–ด์•ผ localhost:8000/me ์˜ ์ฒ˜๋ฆฌ ํ•จ์ˆ˜๋ฅผ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ด๊ฑธ ์–ด๋–ป๊ฒŒ ์ž‘์„ฑํ•  ๊ฑฐ๋ƒ๋ฉด

# user info
@app.get('/me')
async def get_me(user: models.User = Depends(utils.get_current_user)):
    return user

์ด๊ฒŒ ๋์ด๋‹ค. ์ฐจ๊ทผ์ฐจ๊ทผ ๋˜์งš์–ด๋ณด๋ฉด ์ง€๊ธˆ ์ž…๋ ฅ์œผ๋กœ user๊ฐ€ ๋“ค์–ด๊ฐ€๋Š”๋ฐ, get_current_user ์˜ ๋ฆฌํ„ด ๊ฐ’์— ๋”ฐ๋ฅธ๋‹ค. get_current_user์€ user๋ฅผ ์–ป๊ธฐ ์œ„ํ•ด์„œ get_token์„ ํ•„์ˆ˜์ ์œผ๋กœ ๋ถˆ๋Ÿฌ์„œ token์„ ์–ป์–ด์˜ค๊ณ , ์ด token์€? ์šฐ๋ฆฌ๊ฐ€ request์™€ ํ•จ๊ป˜ ์ „์†กํ•œ header์— ์žˆ๋‹ค. ๊ทธ๋Ÿฌ๋‹ˆ๊นŒ ์ด๋ ‡๊ฒŒ๋งŒ ํ•ด์ฃผ๋ฉด ๋์ด๋‹ค!

์ด์ œ ๊ตฌ๊ธ€ ์ฐจํŠธ๋ฅผ ๊ทธ๋ฆฌ๋Ÿฌ ๊ฐ€๋ณด์ž.

 

2. Google Chart ์ ์šฉํ•˜๊ธฐ

๊ตฌ๊ธ€ ์ฐจํŠธ ๊ณต์‹๋ฌธ์„œ๋Š” ์—ฌ๊ธฐ ์žˆ๋‹ค.

Google ์ฐจํŠธ ์‚ฌ์šฉ  |  Charts  |  Google for Developers

 

Google ์ฐจํŠธ ์‚ฌ์šฉ  |  Charts  |  Google for Developers

์ด ํŽ˜์ด์ง€๋Š” Cloud Translation API๋ฅผ ํ†ตํ•ด ๋ฒˆ์—ญ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. Switch to English ์˜๊ฒฌ ๋ณด๋‚ด๊ธฐ Google ์ฐจํŠธ ์‚ฌ์šฉ ์ปฌ๋ ‰์…˜์„ ์‚ฌ์šฉํ•ด ์ •๋ฆฌํ•˜๊ธฐ ๋‚ด ํ™˜๊ฒฝ์„ค์ •์„ ๊ธฐ์ค€์œผ๋กœ ์ฝ˜ํ…์ธ ๋ฅผ ์ €์žฅํ•˜๊ณ  ๋ถ„๋ฅ˜ํ•˜์„ธ์š”. Google ์ฐจํŠธ๋Š”

developers.google.com

๊ทธ ์ค‘์—์„œ๋„ ์ด ๋ชจ๋‹ˆํ„ฐ๋ง ์‹œ์Šคํ…œ์— ์ ํ•ฉํ•˜๊ฒ ๋‹ค ์‹ถ์€ ๊ฒƒ์ด ์˜์—ญ ์ฐจํŠธ๋ผ์„œ, ๊ทธ๊ฑธ ์‚ฌ์šฉํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ–ˆ๋‹ค. ์–ด๋А์ •๋„ ์‚ฌ์šฉ๋ฒ•์€ ์ œ๋„ˆ๋Ÿดํ•˜๊ณ  ๋ฐ์ดํ„ฐ ํƒ€์ž…๋งŒ ๋งž์ถฐ์ฃผ๋ฉด ๋˜๋ฏ€๋กœ ๊ฐ์ž ์•Œ๋งž๋Š” ์ฐจํŠธ๋ฅผ ์„ ํƒํ•˜๋ฉด ๋˜๊ฒ ๋‹ค.

์‹œ๊ฐํ™”: ์˜์—ญ ์ฐจํŠธ  |  Charts  |  Google for Developers

 

์‹œ๊ฐํ™”: ์˜์—ญ ์ฐจํŠธ  |  Charts  |  Google for Developers

์ด ํŽ˜์ด์ง€๋Š” Cloud Translation API๋ฅผ ํ†ตํ•ด ๋ฒˆ์—ญ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. Switch to English ์˜๊ฒฌ ๋ณด๋‚ด๊ธฐ ์‹œ๊ฐํ™”: ์˜์—ญ ์ฐจํŠธ ์ปฌ๋ ‰์…˜์„ ์‚ฌ์šฉํ•ด ์ •๋ฆฌํ•˜๊ธฐ ๋‚ด ํ™˜๊ฒฝ์„ค์ •์„ ๊ธฐ์ค€์œผ๋กœ ์ฝ˜ํ…์ธ ๋ฅผ ์ €์žฅํ•˜๊ณ  ๋ถ„๋ฅ˜ํ•˜์„ธ์š”. ๊ฐœ์š” SVG

developers.google.com

head ๋ถ€๋ถ„์— ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์„ ์žŠ์ง€ ๋ง์ž.

<script
  type="text/javascript"
  src="https://www.gstatic.com/charts/loader.js"
></script>

์ฐจํŠธ๋ฅผ ๊ทธ๋ฆด ๋•Œ๋Š” option์„ ์„ค์ •ํ•ด์•ผํ•œ๋‹ค. ๊ทธ๋ฆด ๋ฐ์ดํ„ฐ๊ฐ€ ํ•˜๋‚˜๋ผ๋ฉด ์ƒ๊ด€์—†์ง€๋งŒ, ์•„๋‹ˆ๋ผ๋ฉด option์„ ๋ฐ์ดํ„ฐ๋งˆ๋‹ค ์งœ์ฃผ๊ณ  ๋‚˜์ค‘์— ์‚ฝ์ž…ํ•˜๋Š” ๊ฒƒ์ด ํŽธํ•˜๋‹ค(๊ฐ์ฒด์ง€ํ–ฅ์˜ ์žฅ์  ๋ฐฑ๋ถ„ ์‚ด๋ฆฌ๊ธฐ ํ”„๋กœ์ ํŠธ).

A. PostgreSQL ๋ฐ์ดํ„ฐ๋ฅผ FastAPI๋กœ ๋ฐ›์•„์™€์„œ ๊ตฌ๊ธ€ ์ฐจํŠธ ๊ทธ๋ฆฌ๊ธฐ

option์— ๋“ค์–ด๊ฐ€์•ผํ•  ๊ฒƒ์€ ๋ฐ์ดํ„ฐ, ๋ฐ์ดํ„ฐ ์ด๋ฆ„(์ฐจํŠธ ํƒ€์ดํ‹€), document ์‹๋ณ„์ž, plotting option์ด๋‹ค. ์˜ˆ์‹œ๋ฅผ ํ•œ ๋ฒˆ ๋ณด์ž.

var chartOption = function (target, color, name, measure) {
      this.name = name; // ๋ฐ์ดํ„ฐ ์ด๋ฆ„(ํ‘œ ํƒ€์ดํ‹€)
      this.target = target; // document ์‹๋ณ„์ž
      this.data = null; // ๋ฐ์ดํ„ฐ
      this.chart = null;
      this.options = { // ์ฐจํŠธ plotting option
        legend: { position: "none" },
        colors: [color],
        title: name,
        titleTextStyle: {
          fontSize: 17,
          bold: true,
          italic: true,
        },
        hAxis: { textPosition: "none" },
        vAxis: { title: name + " " + measure },
      };
    };

์ด ํ”„๋กœ์ ํŠธ์˜ ๊ฒฝ์šฐ์—๋Š” ์ฐจํŠธ ์˜ต์…˜ ๊ฐ์ฒด๋„ ํ•จ์ˆ˜๋กœ ๊ตฌ์„ฑํ–ˆ๋Š”๋ฐ, ๋ฐ์ดํ„ฐ๊ฐ€ ๋‹น์žฅ ์—†๋Š” ์ด์œ ๋Š” ์„œ๋ฒ„์— ๋ฐ์ดํ„ฐ๋ฅผ ์š”์ฒญํ•ด์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์˜ต์…˜ ๊ฐ์ฒด๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ๋ถˆ๋ €๋‹ค.

var voltage_option = new chartOption(
      "voltage_chart", // document ํƒ€๊ฒŸ ์‹๋ณ„์ž
      "#8ECAE6", // color
      "voltage", // ์ด๋ฆ„
      "(V)" // measure(๋‹จ์œ„) 
    );

๊ทธ๋Ÿผ ์ด์ œ ์ฐจํŠธ๋ฅผ ๊ทธ๋ฆฌ๋Š” ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด์ฃผ์–ด์•ผํ•œ๋‹ค. ์ด ํ•จ์ˆ˜์—์„œ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๊ณ , ์ด ๋ฐ์ดํ„ฐ๋ฅผ ๊ตฌ๊ธ€ ์ฐจํŠธ๊ฐ€ ์›ํ•˜๋Š” ๋ฐฉ์‹๋Œ€๋กœ ์ ์žฌํ•ด์„œ ์ฐจํŠธ๋ฅผ ์ ์ ˆํ•œ ์œ„์น˜(document ํƒ€๊ฒŸ ์‹๋ณ„์ž๊ฐ€ ๋˜๊ฒ ๋‹ค)์— ๊ทธ๋ฆฌ๊ธฐ ๊นŒ์ง€ ํ•ด์ค˜์•ผํ•œ๋‹ค. ์ฝ”๋“œ๋กœ ๋ณด์ž.

function drawChart(option) {
  var o = option;
  var data = [];
  if (o != null) {
    if (o.chart == null && o.data == null) {
      o.data = new google.visualization.DataTable();
      o.data.addColumn("string", "time");
      o.data.addColumn("number", o.name);

๊ตฌ๊ธ€ ์ฐจํŠธ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ DataTable์ด๋ผ๋Š” ๋ฐ์ดํ„ฐ ํƒ€์ž…์œผ๋กœ ์ „๋‹ฌํ•ด์ฃผ๊ธฐ๋ฅผ ๋ฐ”๋ž€๋‹ค. pandas dataframe๊ณผ ๋น„์Šทํ•œ ํ˜•์‹์ด๋‹ค. ๋จผ์ € ๊ฐ์ž์˜ ๋ฐ์ดํ„ฐ์— ๋งž๋Š” column์„ ์„ ์–ธํ•ด์ค€๋‹ค. ๋‚˜๋Š” ๋ชจ๋“  ๋ฐ์ดํ„ฐ๊ฐ€ time๊ณผ data ๋”ฑ ๋‘ column์œผ๋กœ ํ˜•์„ฑ๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ ํƒ€์ž…์„ ์•Œ๋งž๊ฒŒ ์ง€์ •ํ•ด์„œ postgreSQL์˜ column๊ณผ ์ด๋ฆ„์„ ๋งž์ถฐ์ค€๋‹ค(์ค‘์š”!)

postgreSQL ์† ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ

$.ajax({
  url: "<http://localhost:8000/api/data/>" + o.name,
  method: "GET",
  async: false,
  success: function (response) {
    var degrees = response;
    if (degrees.length != 0) {
      degrees.forEach(function (el, index) {
        data.push([el["time"], el[o.name]]);
      });
    }
  },
  error: function (response) {
    data.push(["", 0]);
  },
});

๋‹ค์Œ์€ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์˜ค๋Š” ๋ถ€๋ถ„์ด๋‹ค. ์ด๋Š” ์˜ˆ์—์ „์— ๊ตฌํ˜„ํ•ด๋‘” ๋ฉ”์†Œ๋“œ๋ฅผ ์ด์šฉํ•ด์„œ ๊ฐ€์ ธ์™€์ค€๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ฐ€์ ธ์˜จ ๋ฐ์ดํ„ฐ๋ฅผ dataTable ํ˜•์‹์— ๋งž๊ฒŒ time, ๊ทธ๋ฆฌ๊ณ  data name์„ ํ™œ์šฉํ•ด์„œ ํ•˜๋‚˜์”ฉ pushํ•ด์„œ ์ƒˆ๋กœ์šด data๋ฅผ ๋งŒ๋“ค์–ด์ค€๋‹ค.

   	o.data.addRows(data);
    o.chart = new google.visualization.AreaChart(
      document.getElementById(o.target)
    );
  }
  o.chart.draw(o.data, o.options);
}

๊ทธ๋ฆฌ๊ณ  ๋ฏธ๋ฆฌ ์ •์˜ํ•ด๋’€๋˜ dataTable์— data๋ฅผ row๋กœ ์ถ”๊ฐ€ํ•ด์ฃผ๊ณ , ๋งˆ์นจ๋‚ด ์ฐจํŠธ๋ฅผ ์„ ์–ธํ•œ๋‹ค. target์œผ๋กœ ์ง€์ •ํ•œ id ์˜์—ญ์— ์ฐจํŠธ๋ฅผ ๋„ฃ์–ด์ฃผ๊ณ , ๋ฐ์ดํ„ฐ์™€ plotting option์„ ๋„ฃ์–ด์„œ draw ํ•ด์ฃผ๋ฉด ๋๋‚œ๋‹ค.

์ด์ œ ์ž‘์„ฑํ•œ ํ•จ์ˆ˜๋ฅผ ์ ์šฉํ•˜๋„๋ก ์งœ๋ณด์ž.

var voltage_option = new chartOption( // ์ฐจํŠธ ์˜ต์…˜ ์ง€์ •
  "voltage_chart",
  "#8ECAE6",
  "voltage",
  "(V)"
);
google.charts.load("current", { packages: ["corechart"] }); // ์ฐจํŠธ ๋กœ๋”ฉ
google.charts.setOnLoadCallback(function () { // load ๋˜๋ฉด draw
  drawChart(voltage_option);
});

์ฐจํŠธ ์˜ต์…˜์„ ์ง€์ •ํ•˜๊ณ , ๊ตฌ๊ธ€ ์ฐจํŠธ ๋กœ๋”ฉ์„ ์œ„ํ•ด์„œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋จผ์ € ๋กœ๋”ฉํ•ด์ค€๋‹ค. ๊ทธ๋ฆฌ๊ณ  callback ํ•จ์ˆ˜๋ฅผ ๋ถˆ๋Ÿฌ์„œ ์ •์˜ํ•œ draw chart ํ•จ์ˆ˜๋ฅผ ๋ถˆ๋Ÿฌ์ฃผ๊ธฐ๋งŒ ํ•˜๋ฉด ๋์ด๋‹ค.

์ด์ œ ๊ทธ๋ฆฌ๋Š” ๊ฑด ๋‹ค ๋๋‚ฌ๋‹ค!!!!!!!!!!!!!!!!!!!! ์ •๋ง ๋งˆ์ง€๋ง‰์œผ๋กœ ์ด ์‹œ์Šคํ…œ์€ ๋ชจ๋‹ˆํ„ฐ๋ง ์‹œ์Šคํ…œ์ด๊ธฐ ๋•Œ๋ฌธ์— ์ž๋™ ์—…๋ฐ์ดํŠธ ๊ธฐ๋Šฅ์ด ํ•„์š”ํ•˜๋‹ˆ ๊ทธ๊ฒƒ๋งŒ ๊ตฌํ˜„ํ•ด๋ณด๋„๋ก ํ•˜์ž. ๊ฐ„๋‹จํ•˜๋‹ค!

B. ๊ทธ๋ž˜ํ”„ ์‹ค์‹œ๊ฐ„ ์—…๋ฐ์ดํŠธ ํ•˜๊ธฐ

์ด๋ฅผ ์œ„ํ•ด์„œ๋Š” ๊ฐ„๋‹จํ•œ updateChart๋ผ๋Š” draw chart์™€ ์•„์ฃผ ์œ ์‚ฌํ•œ ํ•จ์ˆ˜ ํ•˜๋‚˜๋งŒ ์žˆ์œผ๋ฉด ๋œ๋‹ค. ์ด์ „๊นŒ์ง€ ์ ์žฌ๋˜์ง€ ์•Š์€ ๋ฐ์ดํ„ฐ๋งŒ ๋ถˆ๋Ÿฌ์™€์„œ ๋‹ค์‹œ drawChart๋ฅผ ๋ถˆ๋Ÿฌ์ฃผ๋Š” ๋†ˆ์ด๋‹ค. ๊ตฌํ˜„์„ ๋ณด์ž.

function updateChart(option) {
  var o = option;
// ํ•œ ๋ฒˆ์— ๋ณด์—ฌ์ฃผ๋Š” ๋ฐ์ดํ„ฐ ์–‘ ์ง€์ • - 15๊ฐœ ๋„˜์–ด๊ฐ€๋ฉด ์‚ญ์ œ
  o.data.removeRows(0, o.data.getNumberOfRows());

  $.ajax({
    url: "<http://localhost:8000/api/data/>" + o.name,
    method: "GET",
    async: false,
    success: function (response) {
      var degrees = response;
      var data = [];
      if (degrees.length != 0) {
        degrees.forEach(function (el, index) {
          data.push([el["time"], el[o.name]]);
        });
      }
      console.log(data);
      o.data.insertRows(o.data.getNumberOfRows(), data);
      drawChart(o);
    },
    error: function (response) {
      alert("Get data failed");
    },
  });
}

์ด ํ•จ์ˆ˜์—์„œ๋Š” ์ „์ฒด ๋ฐ์ดํ„ฐ๋ฅผ ์‚ญ์ œํ–ˆ๋‹ค๊ฐ€ ๋‹ค์‹œ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๋ฐฉ์‹์œผ๋กœ ์—…๋ฐ์ดํŠธ๋ฅผ ์ง„ํ–‰ํ•œ๋‹ค. ๋” ํšจ๊ณผ์ ์œผ๋กœ ์ž‘์„ฑํ•˜๋ ค๋ฉด ์ผ์ • ๊ฐฏ์ˆ˜ ์ด์ƒ์ด ๋˜๋ฉด ์•ž ๋ฐ์ดํ„ฐ๋ฅผ ์‚ญ์ œํ•˜๊ณ  ์ถ”๊ฐ€๋œ ๋ฐ์ดํ„ฐ๋Š” ์ธ๋ฑ์Šค๋ฅผ ์ „์—ญ๋ณ€์ˆ˜๋กœ ๊ด€๋ฆฌํ•ด์„œ append ํ•ด์ค„ ์ˆ˜๋„ ์žˆ๊ฒ ๋‹ค.

์ด๋ ‡๊ฒŒ ํ•จ์ˆ˜๋ฅผ ์ž‘์„ฑํ–ˆ์œผ๋ฉด ์ด์ œ interval์„ ์„ค์ •ํ•ด์„œ ์ผ์ • ์‹œ๊ฐ„๋งˆ๋‹ค ํ•จ์ˆ˜๋ฅผ ๋ถ€๋ฅด๋„๋ก ํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

setInterval(function () {
  updateChart(voltage_option);
  updateChart(energy_option);
  updateChart(current_option);
  updateChart(power_option);
  updateChart(pf_option);
}, 10000);

์ด๋ ‡๊ฒŒ ๋˜๋ฉด 10์ดˆ์— ํ•œ ๋ฒˆ์”ฉ ๋ฐ์ดํ„ฐ๊ฐ€ ์—…๋ฐ์ดํŠธ ๋œ๋‹ค.

์งœ์ž”! ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋์ด๋‹ค.

 

 

3. ๋งˆ๋ฌด๋ฆฌ

๋ชจ๋‹ˆํ„ฐ๋ง ํŽ˜์ด์ง€๋ฅผ ๋งŒ๋“œ๋Š” ๊ฐ„๋‹จํ•œ ํ”„๋กœ์ ํŠธ๋Š” ์—ฌ๊ธฐ์„œ ๋งˆ๋ฌด๋ฆฌ ํ•˜์˜€๋‹ค. ๋” ๋ณต์žกํ•˜๊ฒŒ ๋””๋ฒจ๋กญํ•  ์ˆ˜๋Š” ์žˆ์ง€๋งŒ ์ง€๊ธˆ ๋‹น์žฅ ํ•„์š”ํ•œ ์ˆ˜์ค€์€ ์•„๋‹ˆ๊ณ , ๋‚˜์ค‘์— ๋ฆฌํŒฉํ† ๋ง๋งŒ ์˜ˆ์˜๊ฒŒ ์ž˜ ํ•ด๋‘๋ฉด ๋‘๊ณ ๋‘๊ณ  ์“ธ๋งŒํ•œ ํ…œํ”Œ๋ฆฟ์ด ๋  ๊ฒƒ ๊ฐ™๋‹ค.

์‹ค์ œ ์‚ฐ์—… ํ˜„์žฅ์— ํˆฌ์ž…๋˜๋„๋ก ํ•˜๋ ค๋ฉด ๊ด€๋ฆฌ์ž ํŽ˜์ด์ง€๋‚˜ ์„ผ์„œ ์ œ์–ด ํŽ˜์ด์ง€ ๋“ฑ๋„ ์žˆ์–ด์•ผํ•˜๊ณ , ์ง€๊ธˆ๋ณด๋‹ค ๋ณต์žกํ•˜๊ณ  ๋””์ž์ธ๋œ UI๊ฐ€ ํ•„์š”ํ•˜๊ฒ ์ง€๋งŒ ๋‹น์ดˆ ๋ชฉํ‘œํ–ˆ๋˜ ์‹ค์‹œ๊ฐ„ ์„ผ์„œ ๋ฐ์ดํ„ฐ ๋ชจ๋‹ˆํ„ฐ๋ง์˜ ๋ชฉ์ ์€ ๋‹ฌ์„ฑํ–ˆ๋‹ค๊ณ  ๋ณผ ์ˆ˜ ์žˆ๊ฒ ๋‹ค.

Fast API, PostgreSQL, Jqeury๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋งŒ๋“  ์ด ํ…œํ”Œ๋ฆฟ์„ ์ˆ˜์ •ํ•ด์„œ ์ถ”ํ›„ Elastic Search , Logstash, Kibana์™€ ๋ถ™์—ฌ Personal Home ํ”„๋กœ์ ํŠธ๋ฅผ ์ด์–ด๊ฐ€๋ ค๊ณ  ํ•œ๋‹ค. ์ด ๋‚ด์šฉ์€ ๋‹ค๋ฅธ ์นดํ…Œ๊ณ ๋ฆฌ์—์„œ~!

์ƒ๊ฐํ–ˆ๋˜ ๊ฒƒ๋ณด๋‹ค ๋งŽ์€ ๋ถ„๋“ค์ด ์ด ์‹œ๋ฆฌ์ฆˆ๋ฅผ ์ฝ์–ด์ฃผ์…จ๋Š”๋ฐ, ๋ชจ๋‘๋“ค ์ด ๋ฌธ์„œ๊ฐ€ FastAPI ์ž…๋ฌธ์— ๋„์›€์ด ๋˜์…จ๊ธธ ๋ฐ”๋ž๋‹ˆ๋‹ค.

์ฝ์–ด์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!

 

728x90
์ €์ž‘์žํ‘œ์‹œ ๋น„์˜๋ฆฌ ๋ณ€๊ฒฝ๊ธˆ์ง€ (์ƒˆ์ฐฝ์—ด๋ฆผ)

'๐ŸŽผ Project > ๐ŸงŠ Monitoring System' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[Monitoring System] 6. Fast API ๋กœ ์ดํ‹€๋งŒ์— ๋ฐฑ์—”๋“œ ๊ตฌ์ถ•ํ•˜๊ธฐ(feat. SQLAlchemy, PostgreSQL) (2) - MQTT ๋ฐ์ดํ„ฐ ์ ์žฌ / ๋กœ๊ทธ์ธ ๊ธฐ๋Šฅ ๊ตฌํ˜„  (0) 2023.08.07
[Monitoring System] 5. Fast API ๋กœ ์ดํ‹€๋งŒ์— ๋ฐฑ์—”๋“œ ๊ตฌ์ถ•ํ•˜๊ธฐ(feat. SQLAlchemy, PostgreSQL) (1)  (0) 2023.06.13
[Monitoring System] 4.1 ์„ธ์ƒ์— ๋” ๋น ๋ฅธ ๋ฐฉ๋ฒ•์ด - pyqtgraph  (2) 2023.04.27
[Monitoring System] 4. UDP ํ†ต์‹ ์œผ๋กœ ์‹ค์‹œ๊ฐ„ ์ง„๋™ ๋ฐ์ดํ„ฐ FFT / STFT์‹œ๊ฐํ™”(numpy, tensorflow, pytorch)  (0) 2023.04.25
[Monitoring System] 3. UDP ํ†ต์‹ ์œผ๋กœ ์‹ค์‹œ๊ฐ„ ์ง„๋™ ๋ฐ์ดํ„ฐ Plotting(feat. matplotlib)  (0) 2023.04.19
'๐ŸŽผ Project/๐ŸงŠ Monitoring System' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€
  • [Monitoring System] 6. Fast API ๋กœ ์ดํ‹€๋งŒ์— ๋ฐฑ์—”๋“œ ๊ตฌ์ถ•ํ•˜๊ธฐ(feat. SQLAlchemy, PostgreSQL) (2) - MQTT ๋ฐ์ดํ„ฐ ์ ์žฌ / ๋กœ๊ทธ์ธ ๊ธฐ๋Šฅ ๊ตฌํ˜„
  • [Monitoring System] 5. Fast API ๋กœ ์ดํ‹€๋งŒ์— ๋ฐฑ์—”๋“œ ๊ตฌ์ถ•ํ•˜๊ธฐ(feat. SQLAlchemy, PostgreSQL) (1)
  • [Monitoring System] 4.1 ์„ธ์ƒ์— ๋” ๋น ๋ฅธ ๋ฐฉ๋ฒ•์ด - pyqtgraph
  • [Monitoring System] 4. UDP ํ†ต์‹ ์œผ๋กœ ์‹ค์‹œ๊ฐ„ ์ง„๋™ ๋ฐ์ดํ„ฐ FFT / STFT์‹œ๊ฐํ™”(numpy, tensorflow, pytorch)
darly213
darly213
ํ˜ธ๋ฝํ˜ธ๋ฝํ•˜์ง€ ์•Š์€ ๊ฐœ๋ฐœ์ž๊ฐ€ ๋˜์–ด๋ณด์ž
  • darly213
    ERROR DENY
    darly213
  • ์ „์ฒด
    ์˜ค๋Š˜
    ์–ด์ œ
    • ๋ถ„๋ฅ˜ ์ „์ฒด๋ณด๊ธฐ (97)
      • ๐Ÿฌ ML & Data (50)
        • ๐ŸŒŠ Computer Vision (2)
        • ๐Ÿ“ฎ Reinforcement Learning (12)
        • ๐Ÿ“˜ ๋…ผ๋ฌธ & ๋ชจ๋ธ ๋ฆฌ๋ทฐ (8)
        • ๐Ÿฆ„ ๋ผ์ดํŠธ ๋”ฅ๋Ÿฌ๋‹ (3)
        • โ” Q & etc. (5)
        • ๐ŸŽซ ๋ผ์ดํŠธ ๋จธ์‹ ๋Ÿฌ๋‹ (20)
      • ๐Ÿฅ Web (21)
        • โšก Back-end | FastAPI (2)
        • โ›… Back-end | Spring (5)
        • โ” Back-end | etc. (9)
        • ๐ŸŽจ Front-end (4)
      • ๐ŸŽผ Project (8)
        • ๐ŸงŠ Monitoring System (8)
      • ๐Ÿˆ Algorithm (0)
      • ๐Ÿ”ฎ CS (2)
      • ๐Ÿณ Docker & Kubernetes (3)
      • ๐ŸŒˆ DEEEEEBUG (2)
      • ๐ŸŒ  etc. (8)
      • ๐Ÿ˜ผ ์‚ฌ๋‹ด (1)
  • ๋ธ”๋กœ๊ทธ ๋ฉ”๋‰ด

    • ํ™ˆ
    • ๋ฐฉ๋ช…๋ก
    • GitHub
    • Notion
    • LinkedIn
  • ๋งํฌ

    • Github
    • Notion
  • ๊ณต์ง€์‚ฌํ•ญ

    • Contact ME!
  • 250x250
  • hELLOยท Designed By์ •์ƒ์šฐ.v4.10.3
darly213
[Monitoring System] 7. Fast API ๋กœ ์ดํ‹€๋งŒ์— ๋ฐฑ์—”๋“œ ๊ตฌ์ถ•ํ•˜๊ธฐ(feat. Google Chart) (3) - ๋งˆ์นจ๋‚ด ๊ทธ๋ž˜ํ”„ ๊ทธ๋ฆฌ๊ธฐ ๅฎŒ
์ƒ๋‹จ์œผ๋กœ

ํ‹ฐ์Šคํ† ๋ฆฌํˆด๋ฐ”