ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [기업협업 회고] 기능 구현에 대한 회고 - 실시간 CCTV 영상을 활용한 공정 모니터링 시스템
    회고록 2022. 9. 12. 00:02

    드디어 위코드에서의 3개월이 끝났다.

    쉼 없이 달려온 3개월... 주말에는 쉬어도 되는데 노트북이 내 옆에 없으면 불안해서 항상 가지고 다녔다..

    그 정도로 정말 열과 성을 다하여 3개월을 임했던 것 같다.

    이번에는 위코드에서의 마지막 프로젝트! 3개월 차 프로젝트에 대한 회고를 작성해보려고 한다.


    위코드는 3개월 차에 기업협업을 나간다.

    나는 백엔드2명, 프론트2명(나 포함) 총 4명이 함께 기업협업을 나갔는데 '무스마'라는 회사에 가게 됐다.

     

    '무스마'는 건설산업의 안전과 생산성, 효율성 향상을 목표로

    industrial IoT 분야에서 다수의 대기업, 중소기업 고객을 확보하고 있는 IoT Solution 회사이다.

     

    이에 내가 맡은 업무는

    실시간 CCTV 영상을 활용한 공정 모니터링 시스템

    이었다.

     

    작업은 백엔드2명, 프론트2명이 8월 16일 ~ 9월 7일, 약 3주간 진행했고

    기술스택은 아래와 같다.

    FE Specification : JavaScript 사용
    React: React js v18
    상태관리 : mobx v6, mobx-react-lite v3
    라우팅 : react-router-dom v6
    CSS : Tailwind CSS v3
    국제화 : i18next v21

    아래는 완성본이다!

    이 중에서 나는 중장비 통계 페이지, 중장비 리스트 페이지, 중장비 디테일 페이지, 구역별 공정률 페이지, 구역 디테일 페이지를 맡았다.

    같이 했던 프론트 동기가 늪 같은 네브바와 메인 페이지에서 나오지 못하여 대부분의 페이지를 담당하게 되었다.

    메인 페이지 / 중장비 통계 페이지 / 중장비 리스트 페이지 / 중장비 디테일 페이지 / 구역별 공정률 페이지 / 구역 리스트 페이지 / 구역 디테일 페이지


    < 도대체 이게 뭘까? - RTSP, Mobx, Tailwind CSS,  i18next >

    실시간 CCTV 영상 스트리밍 하고, 실시간으로 영상 분석하고, 데이터를 시각화하고, 공정 모니터링 등 정보를 제공해야 한다는데..

    실시간 CCTV 영상..??? 공정 모니터링 시스템...??? 처음에 감이 전혀 잡히질 않았다.

    - RTSP (Real Time Streaming Protocol)

    먼저, 실시간 CCTV 영상을 스트리밍 하기 위해서는 RTSP라는 Real Time Streaming Protocol를 공부해야 했다.

    RTSP는 실시간 스트리밍 프로토콜로 실시간으로 음성이나 동영상을 송수신하는 통신 규약이다.

    동영상이나 음악 따위를 전부 다 다운로드한 뒤에 재생하는 것이 아니라 수신하면서 재생하는 것이다.

    ex) 인터넷 생중계(아프리카, 다음팟 등), 저장된 미디어 스트리밍 서비스(유튜브, 인터넷 음악 듣기 서비스), 실시간 멀티미디어(인터넷전화, 화상회의)

    RTSP는 무스마에서도 현재 진행 중인 프로젝트라 정확한 정답을 알려주시지는 못하는 상황이었다.

    우리가 구글링 하고 공부하여 동영상을 재생시켜야 했다.

    https://jeongeuni.tistory.com/57

     

    [기업협업 1주차] mac ffmpeg 설치하는 법 / RTSP(동영상 실시간 스트리밍 프로토콜)

    기업협업 첫주차...... 다음주부터 본격 업무 들어갈 것 같고 이번주에는 공부를 많이 해둬야한다. 기술스택이 많이 다르기 때문이다... * 기업협업 기술스택 FE Specification : typescript or javascrip 사용

    jeongeuni.tistory.com

    내가 포스팅한 이 글을 보면 초반에 삽질을 많이 한 것을 볼 수 있다..ㅎㅎ

    결국은 https://yeolceo.tistory.com/71 이 블로그를 보고 streamedian 사이트의 rtsp 기술을 참조하여 동영상을 재생시켰다.

    그래서 이렇게 실시간 CCTV 영상을 재생시킬 수 있었다. 프론트엔드지만 백엔드의 일을 한 것처럼 서버를 다뤄봐서 인상 깊다!


    - 처음 듣는 기술스택!  =>  Mobx, Tailwind CSS, i18next  => 새로운 기술스택이 생겨서 뿌듯하다 : )

    위코드에서 이제 막 react, styled-component에 익숙해졌는데 무스마에 오니 mobx, tailwind css를 이용하여 개발해야 했다.

    초반 일주일은 아직 기획이 나오지 않기도 했고 기술에 대해 공부하는 시간을 가졌다.

    여기서 또 느낀 것 => 이래서 개발자는 계속 공부한다는 거구나!

    공부해서 바로 프로젝트에 녹여낼 수 있을지 걱정했지만 역시 하면 된다.

    일 / 주 / 월 버튼을 mobx로 훌륭히 관리해냈다!

    import { observable } from 'mobx';
    
    export const timeStore = observable({
      equipTime: 'daily',
      ProgressTime: 'weekly',
    
      onChangeEquipTime(e) {
        this.equipTime = e.target.name;
      },
    
      onChangeProgressTime(e) {
        this.ProgressTime = e.target.name;
      },
    });

    Mobx로 상태 관리의 맛을 봤다.  새로운 기술스택이 생겨서 뿌듯하다 : )

    이제 Redux 공부하러 가야지.. 총총총....


    < 내가 구현한 기능 - 중장비 통계 페이지,  중장비 리스트 페이지,  중장비 디테일 페이지, 구역별 공정률 페이지, 구역 디테일 페이지 >

    - 1.  Recharts, MUI 라이브러리 정 복 ! 🌟

    차례대로 장비 통계 페이지, 장비 리스트 페이지, 구역별 공정률 페이지이다.

    pie chart, bar chart, line chart 등 여러 chart들이 있고 select box, table이 있다.

    Recharts로 여러 chart들을 ,  MUI로 select box, table을 구현했다.

     

    둘 다 처음 사용해보는 라이브러리였지만 훌륭히 활용하여 내가 원하는 형태로 구현할 수 있었는데

    stackoverflow의 여러 예시들과 각 라이브러리의 공식문서를 열심히 본 것이 큰 도움이 되었다.

    또한 라이브러리에 어떤 데이터 형식이 들어가야 하는지 확인한 후 Backend와 소통을 미리 그리고 많이 한 것도 빠른 구현에 큰 도움이 되었다.

    예를 들어 line chart는

    [
        {
            "day": 23,
            "progress": 5
        },
        {
            "day": 24,
            "progress": 9
        },
        {
            "day": 25,
            "progress": 13
        }
    ]

    이렇게 배열 안의 객체 형식으로 데이터가 들어가게 되는데 이 형식으로 API를 줄 수 있냐고

    Backend가 API를 만들기 전에 요청하였고 이에 순탄히 프로젝트가 진행될 수 있었다. 

    이제 처음 사용해보는 라이브러리여도 어떻게 하면 더 빠르게 그리고 잘 활용할 수 있을지 알 것 같다  : )

     

    MUI는 커스텀하는데 시간을 많이 할애했는데 그 부분은 까먹기 전에 블로그에 정리했다..ㅎㅎ

    https://jeongeuni.tistory.com/59

     

    [MUI Table Custom] 내가 원하는 테이블로 커스텀하기, 앞으로 자주보자 MUI Table!!!!

    위의 테이블은 완성본이다. 라이브러리를 가져와서 쓰는 거는 너무 편리하고 좋지만 레이아웃 커스텀하기 너무 복잡하다!! 테이블에 border, border-radious, width, height 등 내가 원하는 모양으로 바꾸

    jeongeuni.tistory.com


    - 2.  장비 통계 페이지 - 실시간으로 바뀌는 데이터 만지기

    중장비 통계 페이지는 중장비를 운송장비(트럭만), 작업장비(나머지)로 분류하고 일 / 주 / 월 단위로 가동률을 통계 내어 보여주는 페이지다.

    👉 실시간으로 바뀌는 데이터 만지기

    이 페이지를 작업하면서 인상 깊었던 기능은 실시간으로 바뀌는 데이터를 만져야 했던 것이다.

    예를 들어 장비가 4개였다가 갑자기 2개가 되고, 2개였다가 갑자기 3개가 되는.. 말 그래도 실시간으로 데이터에 접근해야 한다.

    그래서 위코드에서 프로젝트할 때는 고정되어 있는 데이터를 만졌는데

    무스마에서는 데이터가 실시간으로 바뀌어서 처음에 당황했다.

    데이터에 접근하면 데이터가 있다가 없어지는 경우가 생겨 오류가 났기 때문이다.

    왜 안되지 왜 안되지 하고 삽질하다가

    const EQUIPINFO_DATA = [
        Object.keys(equipData).map((data, index) => {
          return { id: index + 1, sort: data };
        }),
      ];

    Backend에게 받은 데이터로 상수 데이터를 만들고 

     

    EQUIPINFO_DATA[0].map(({ id, sort }) => {
        return (
          <div className="h-full pr-2 pl-2" key={id}>
            <div className="flex justify-center align-middle relative text-2xl font-bold top-[131px]">
              {!rateData[sort]
                ? 'NO DATA'
                : `${Math.floor(rateData[sort] * 100)}%`}
            </div>
            <div className="flex justify-center">
              <EquipAnalysisPieChart
                key={id}
                equipData={equipData}
                sort={sort}
              />
            </div>
            <div className="flex pt-3 justify-center text-3xl font-bold">
              {sort}
            </div>
          </div>
        );
    })}

    그 상수 데이터를 활용하여 구현해 낼 수 있었다.


    - 3. 중장비 리스트 페이지 :  확장성 고려한 로직 구현하기

    👉 확장성 고려한 로직 구현하기  =>  하드코딩 NO!

    지금은 관측되는 중장비가 4개이고 구역도 한정되었지만 후에 공사가 커지면 중장비가 추가될거고 구역도 확장될 것이다.

    즉, 확장성을 고려하여 로직을 구현해야 했다. 하드코딩을 하면 안된다.

    나는 이 프로젝트를 하면서 이때가지 하드코딩이 뭔지, 왜 하면 안 되는지 이 단순한 개념이 잡혀있지 않다는 것을 알았다.

    사수님에게 시연할 때 테이블에 보이는 구역은 5개인데 셀렉트 드롭다운에는 왜 구역이 4개밖에 없냐는 질문을 받고

    "아 그렇네요! 지금 5개 넣어놨는데 4개로 수정해놓겠습니다!" 했는데 그때그때 체크하고 데이터 바꾸는 건 하드코딩이라며 알려주셨다. 

    나는 

    <MenuItem value="">전체</MenuItem>
    <MenuItem value="">A구역</MenuItem>
    <MenuItem value="">B구역</MenuItem>
    <MenuItem value="">C구역</MenuItem>
    <MenuItem value="">D구역</MenuItem>

    이렇게 데이터를 하나하나 박아놨었다... 그때 '아.... 이게 하드코딩이구나....' 하고 깨달은 것이다.

    const menuItemType = [...new Set(list.map(data => data.equipment_type))];
    const menuItemArea = [...new Set(list.map(data => data.equipment_area))];

    그래서 이렇게 Set객체를 활용해서 select box의 리스트를 구현하는 걸로 수정했다.


    - 4. 구역별 공정률 페이지 :  간단한 레이아웃 변경 but 프론트에게는 복잡한 일, 그래도 구현한다!!

    주별, 월별에 따라 구역별로 공정률이 얼마나 진행됐는지 볼 수 있는 페이지이다.

    이 페이지, 그리고 이 그래프.. 정말 간단해 보이지만 2-3일을 고민하게 한 작업이 있다.

    바로 여기 라인 그래프를 그릴 때 x좌표(일별)에서 0 ~ 5 부분이 한 줄로 찍- 이어지고 5부터 그래프가 시작하는 것을 볼 수 있다.

    원래는 0 ~ 5 부분이 없고 바로 시작했는데 오늘이 5일이라면 점하나 만 찍히는 이상한 그래프가 그려져서 

    그래프에 수정이 생기게 된 것이다.

    요청이 들어왔을 땐 금방 할 수 있는 것처럼 보였지만 stackoverflow, 공식문서, 다수의 블로그도 찾아보았지만 답이 없었다.

    Backene에게 받은 데이터 앞에 임의로 데이터를 넣어야 했다. 

     

    이에 utils의 functions폴더에

    export function customizeLine(LineData, value) {
      LineData.unshift({ day: null, progress: value });
      return LineData;
    }

    함수를 하나 만들어놓고 이 함수를 저 line chart를 구현해야 하는 페이지에서 import 하여 사용했다.

    const getProgressData = async () => {
        const res = await fetch(`${API.PROGRESS}${timeStore.ProgressTime}`).then(
          res => res.json()
        );
        Object.keys(res.results).map(area =>
          customizeLine(res.results[area], res.results[area][0].progress)
        );
        setAreaData(res.results);
      };

    이렇게 fetch 받아온 공정률 Line Chart 데이터 배열 맨 앞에 객체 하나를 추가하여 

    최종 공정률 Line Chart 데이터 배열을 만들어 줌으로써 해결할 수 있었다.


    - 5. 구역 디테일 페이지 : google map 구현기

    구역의 실제 위치를 지도에 마스킹하고 구역 내 카메라 위치도 표시하여 보여주는 구역 디테일 페이지!

    위코드에서 동기들이 google map을 하다가 너무 어렵고 복잡하여 kakao map으로 변경하여 구현했었는데

    그런데 내가 이제 google map과 붙어야 할 차례가 왔다.

    구글맵 구현기는 블로그 글을 따로 썼다  : )

    https://jeongeuni.tistory.com/60

     

    [react-google-maps/api] 구글맵 사용하기, marker, circle, env

    이번 기업협업을 하면서 처음으로 구글맵을 사용해봤다. 위코드에서 부트캠프할 때 구글맵을 하다가 어려워서 카카오맵으로 간 동기들을 보았기 때문에 걱정을 좀 했지만 다행히 구글맵을 깊

    jeongeuni.tistory.com


    프로젝트를 하며 늘 느끼는 거지만 구현하지 못할 것 같은 것도 결국은 다 구현해냈다.

    항상 느낀점이 많은 프로젝트라 후기가 좀 길었지만 그만큼 뿌듯했다.

    한 번 더 성장했다. 더 성장하고 싶다!!

    댓글

Designed by Tistory.