---
# System prepended metadata

title: 總務處 API 介接

---

# 總務處 API 介接
## Introduction
- 首先要把開發環境建立起來，一開始應該會碰後端的部分，所以主要先把 Node.js (後端語言環境), Postgres (資料庫)和一些環境變數(`.env`)內設定好，然後在 Postgres 中創建對應的資料表 (Table)，這部分就要去看一下如何在 Postgres 中 `CREATE TABLE`，然後可以先根據 API 回傳的資料內容決定哪些資料要存。
- 大致流程會是:
    - 建立環境 (建議先照學長之前寫的 README 去建立看看，有遇到不懂或錯誤再問)
    - 初始化資料庫 (包括新建的 Table)
    - 撰寫介接 IPCS 資料的程式 (下面有之前寫過的程式碼，但比較醜，有時間可以做分層)

## API
1. 區間資料: https://scplus.df.r.appspot.com/v1/getData/dateRange?serial_id=device_COOKAS&startDate=yyyy-mm-dd&endDate=yyyy-mm-dd
2. 即時資料: https://scplus.df.r.appspot.com/v1/getData/latest?serial_id=device_COOKAS
> P.S. 可以下載 [Postman](https://www.postman.com/) 這套 API 測試工具做測試

## Environment 設定
### Backend
#### Configure environment variables according to `.env`
1. Run Powershell as administrator:
    - `git clone https://github.com/rajivharris/Set-PsEnv`
    - `Install-Module -Name Set-PsEnv` : Agree with both following questions.
    - `Set-Psenv -?`

2. Edit `.env` file with custom setting, and under `/server`:
    - `set-psenv`
    - `ls env:` : check the variable in this session.
    - **Notice that environment variables use this way to set up only survive in this session, which means if closing terminal, the variables are not available anymore.**

#### Packages (pip, arcpy)
```
C:\"Program Files"\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\Scripts\pip.exe install psycopg2
C:\"Program Files"\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\Scripts\pip.exe install python-dotenv
```

#### Deploy
* `npm run-script build` : Generate `/build` folder according to `/src`.
* `npm start`: Start the server.

### Frontend
#### Environment
* npm@6.12.0
* ReactJS@17
* react-bootstrap@1.4.3
* esri/react-arcgis@5.1.0
* Ogre service : transfer geojson to shapefile

#### Deploy (better with NVM installed)
* In root
  * `npm install -g npm@6.12.0` if necessary.
  * `npm install`
  * `npm run build`
  * `npm start`

#### Trouble shooting
* If there is error with `Node Sass`:
  * `npm uninstall node-sass`
  * `npm i -D sass`
  * `npm start`
* [Reference](https://stackoverflow.com/questions/70281346/node-js-sass-version-7-0-0-is-incompatible-with-4-0-0-5-0-0-6-0-0)


## Node.js (Backend)
### Create table
- Install Postgres version 12.

### Fetch data from IPCS
- Under `/src/util`: create `fetchIpcs.js`
```javascript
import axios from 'axios';
import schedule from 'node-schedule';
import * as path from 'path';
import logger from '../logger';

const pool = require('./pool');

const serial_id = "device_COOKAS";
const date = new Date() - 1;
const [t] = new Date(date).toISOString().split('T');
const api_url = `https://scplus.df.r.appspot.com/v1/getData/dateRange?serial_id=${serial_id}&startDate=${t}&endDate=${t}`;

const errorLog = (message) => {
  logger.error(`[Fetch Data From ${api_url}] ${message}`);
};

const infoLog = (message) => {
  logger.info(`[Fetch Data From ${api_url}] ${message}`);
};

const fetchIpcsData = async () => {
  try {
    // 定期執行排程工作
    schedule.scheduleJob('21 20 * * *', () => {
      axios
        .get(api_url)
        .then(async response => {
          let data = await response.data;
          let arr = JSON.parse(JSON.stringify(data));
          console.log(arr);
          let obj = arr.data;

          for (let i = 0; i < 1440; i++) {
            if (obj[i] !== undefined) {
              console.log(obj[i]);
              var tmp = new Date(obj[i].timestamp);
              var c = tmp.getTime();
              c += 28800000; // 8 hours
              var tmp2 = new Date(c);
              obj[i].timestamp = tmp2;

              pool.query(
                `INSERT INTO device_COOKAS
                  (hum, kpa, rad, rain, temp, wd, ws, ts) 
                  VALUES ($1, $2, $3, $4, $5, $6, $7, $8)`, [
                    obj[i].hum,
                    obj[i].kpa,
                    obj[i].rad,
                    obj[i].rain,
                    obj[i].temp,
                    obj[i].wd,
                    obj[i].ws,
                    obj[i].timestamp,
                  ]
              );

            } else {
              infoLog(`獲取IPCS資料失敗`);
            }
          }
        })
    })
  } catch (err) {
    errorLog(`${err} / @fetchData`);
  }
};

export const fetchIpcs = async () => {
  try {
    await fetchIpcsData();

    return;
  } catch (err) {
    errorLog(`${err} / @fetchData`);
  }
};
```
