이정민

lib

const mysql = require('mysql');
const DB_option = require('../keys/db_option');
module.exports = mysql.createConnection(DB_option);
{
"weather": {
"minutely": [
{
"station": {
"longitude": "127.1164",
"latitude": "37.2772",
"name": "기흥구",
"id": "371",
"type": "KMA"
},
"wind": {
"wdir": "189.50",
"wspd": "2.20"
},
"precipitation": {
"sinceOntime": "0.00",
"type": "0"
},
"sky": {
"code": "SKY_A07",
"name": "흐림"
},
"rain": {
"sinceOntime": "0.00",
"sinceMidnight": "",
"last10min": "0.00",
"last15min": "0.00",
"last30min": "0.00",
"last1hour": "0.00",
"last6hour": "0.50",
"last12hour": "0.50",
"last24hour": "0.50"
},
"temperature": {
"tc": "5.90",
"tmax": "7.00",
"tmin": "-1.00"
},
"humidity": "",
"pressure": {
"surface": "",
"seaLevel": ""
},
"lightning": "0",
"timeObservation": "2018-12-06 14:14:00"
}
]
},
"common": {
"alertYn": "Y",
"stormYn": "N"
},
"result": {
"code": 9200,
"requestUrl": "/weather/current/minutely?appKey=key&lat=37.239795&lon=127.083240",
"message": "성공"
}
},
{
"weather": {
"wIndex": {
"uvindex": [
{
"grid": {
"city": "경기도",
"county": "수원시",
"village": ""
},
"day00": {
"imageUrl": "http://files.weatherplanet.co.kr/weather/01_FCT/INDEX1/20181209/FCT_IDX_A07_1_2018120906_00D.gif",
"index": "20.00",
"comment": "자외선 걱정 없어요"
},
"day01": {
"imageUrl": "http://files.weatherplanet.co.kr/weather/01_FCT/INDEX1/20181209/FCT_IDX_A07_1_2018120906_01D.gif",
"index": "20.00",
"comment": "자외선 걱정 없어요"
},
"day02": {
"imageUrl": "http://files.weatherplanet.co.kr/weather/01_FCT/INDEX1/20181209/FCT_IDX_A07_1_2018120906_02D.gif",
"index": "10.00",
"comment": "자외선 없는 날입니다"
}
}
],
"timeRelease": "2018-12-09 06:00:00"
}
},
"common": {
"alertYn": "Y",
"stormYn": "N"
},
"result": {
"code": 9200,
"requestUrl": "/weather/index/uv?appKey=c13b1a68-ef31-4131-a1b7-4069c263f82d&version=1&lat=37.239795&lon=127.083240",
"message": "성공"
}
}{
"weather": {
"wIndex": {
"thIndex": [
{
"grid": {
"city": "경기",
"county": "용인시 기흥구",
"village": "상갈동"
},
"forecast": {
"timeRelease": "2018-12-09 14:00:00",
"index43hour": "37.85",
"index4hour": "38.40",
"index7hour": "34.36",
"index10hour": "31.08",
"index13hour": "31.08",
"index16hour": "27.60",
"index19hour": "35.76",
"index22hour": "44.84",
"index25hour": "47.47",
"index28hour": "42.45",
"index31hour": "39.37",
"index34hour": "37.85",
"index37hour": "36.54",
"index40hour": "35.73",
"index46hour": "42.99",
"index49hour": "39.12",
"index52hour": "37.79",
"index55hour": "37.13",
"index58hour": "36.29",
"index61hour": "",
"index64hour": "",
"index67hour": ""
},
"current": {
"timeRelease": "2018-12-09 14:00:00",
"index": "40.49"
}
}
]
}
},
"common": {
"alertYn": "Y",
"stormYn": "N"
},
"result": {
"code": 9200,
"requestUrl": "/weather/index/th?appKey=c13b1a68-ef31-4131-a1b7-4069c263f82d&version=1&lat=37.239795&lon=127.083240",
"message": "성공"
}
}
{
"weather": {
"wIndex": {
"heatIndex": [
{
"grid": {
"city": "경기",
"county": "용인시 기흥구",
"village": "상갈동"
},
"forecast": {
"timeRelease": "2018-12-09 14:00:00",
"index4hour": "37.28",
"index7hour": "70.81",
"index10hour": "91.57",
"index13hour": "91.57",
"index16hour": "110.30",
"index19hour": "71.89",
"index22hour": "36.40",
"index25hour": "27.82",
"index28hour": "50.39",
"index31hour": "61.62",
"index34hour": "71.05",
"index37hour": "75.20",
"index40hour": "79.01",
"index43hour": "71.05",
"index46hour": "52.61",
"index49hour": "67.96",
"index52hour": "69.50",
"index55hour": "69.08",
"index58hour": "74.43",
"index61hour": "",
"index64hour": "",
"index67hour": ""
},
"current": {
"timeRelease": "2018-12-09 14:00:00",
"index": "32.79"
}
}
]
}
},
"common": {
"alertYn": "Y",
"stormYn": "N"
},
"result": {
"code": 9200,
"requestUrl": "/weather/index/heat?appKey=c13b1a68-ef31-4131-a1b7-4069c263f82d&version=1&lat=37.239795&lon=127.083240",
"message": "성공"
}
}
{
"weather": {
"wIndex": {
"wctIndex": [
{
"grid": {
"city": "경기",
"county": "용인시 기흥구",
"village": "상갈동"
},
"forecast": {
"timeRelease": "2018-12-09 14:00:00",
"index43hour": "-2.17",
"index4hour": "-8.15",
"index7hour": "-6.55",
"index10hour": "-7.00",
"index13hour": "-7.63",
"index16hour": "-9.08",
"index19hour": "-4.71",
"index22hour": "1.18",
"index25hour": "1.53",
"index28hour": "-0.47",
"index31hour": "-3.76",
"index34hour": "-2.37",
"index37hour": "-4.67",
"index40hour": "-4.38",
"index46hour": "-0.67",
"index49hour": "-1.18",
"index52hour": "-2.14",
"index55hour": "-1.65",
"index58hour": "-4.23",
"index61hour": "",
"index64hour": "",
"index67hour": ""
},
"current": {
"timeRelease": "2018-12-09 14:00:00",
"index": "-6.22"
}
}
]
}
},
"common": {
"alertYn": "Y",
"stormYn": "N"
},
"result": {
"code": 9200,
"requestUrl": "/weather/index/wct?appKey=c13b1a68-ef31-4131-a1b7-4069c263f82d&version=1&lat=37.239795&lon=127.083240",
"message": "성공"
}
}
\ No newline at end of file
const db = require('./db.js');
const secret_key = require('../keys/api_option').key;
const requesting = require('request');
const lat = "37.239795";
const lon = "127.083240";
module.exports = (server, app) => {
const io = require('socket.io')(server, {
transports: ['websocket'] // websocket 사용시 polling 사용을 배제하고 안정적인 websocket만 사용함
});
//명시적 형 선언
let Current_Weather = {};
let Sensible_T = {};
let Heat_index = {};
let Discomport_index = {};
let Ultra_Violet_index = {};
let sending_to_client_info = {};
let client_send = {};
let client_name = "";
let client_birth ;
let Destiny;
let sql;
let info = {}
const req_API = (when, what) => {
//async await 사용하기 위하여 promise 사용
return new Promise((resolve, reject) => {
requesting.get({
// api를 요청할 주소 -- 시크릿키,위도,경도 입력
url: `https://api2.sktelecom.com/weather/${when}/${what}?appKey=${secret_key}&lat=${lat}&lon=${lon}`,
json: true
},
//api에게 응답 받았을때 실행되는 callback function
function (err, api_res, api_body) {
//err 존재시 promise reject 호출
if (err) reject(err);
// api의 response이 있을경우 promise resolve 호출
if (api_res) {
console.log("calling api");
resolve(api_body);
}
});
})
}
const API_bundle = async () => {
try {
Current_Weather = await req_API("current", "minutely"); //현재날씨 (분별)
Sensible_T = await req_API("index", "wct"); //체감온도
Heat_index = await req_API("index", "heat"); //열지수
Discomport_index = await req_API("index", "th"); //불쾌지수
Ultra_Violet_index = await req_API("index", "uv"); //자외선지수
info = {
heat: Heat_index.weather.wIndex.heatIndex[0].current.index, //열지수
sensible_temperature: Sensible_T.weather.wIndex.wctIndex[0].current.index, //체감온도
discomport: Discomport_index.weather.wIndex.thIndex[0].current.index, //불쾌지수
UV: Ultra_Violet_index.weather.wIndex.uvindex[0].day01.index, //자외선지수
windspd: Current_Weather.weather.minutely[0].wind.wspd, //바람 속도
sky: Current_Weather.weather.minutely[0].sky.code, //하늘 상태
rain: Current_Weather.weather.minutely[0].rain.last24hour, //강수량
current_temperature: Current_Weather.weather.minutely[0].temperature.tc, //현재 온도
lightning: Current_Weather.weather.minutely[0].lightning, //현재 낙뢰
warning: Current_Weather.common.alertYn, //현재 특보 유무
typhoon: Current_Weather.common.stormYn, //현재 태풍
time: Current_Weather.weather.minutely[0].timeObservation, // 불러온 시각
death_prob: 0 //확률
}
console.log("API INFO \n", info);
// ------------------------------ death_prob 정의 ------------------------------
info.death_prob += info.sky.substr(5) * 1 //하늘 상태에 따라 확률 증가
if (info.lightning === 1) //낙뢰시에 확률 증가
info.death_prob += 1.5;
if (info.typhoon === "Y") //태풍시에 확률 증가
info.death_prob += 1.5;
if (info.warning === "Y") // 특보 발령시 확률 증가
info.death_prob += 1
//죽을 확률 계산(내맘대로 커스텀)
info.death_prob = (
(info.heat / 50) + (Math.abs(info.sensible_temperature - 15) / 10) + (info.discomport / 10) + (info.UV / 10)
+ info.windspd*1 + (info.rain / 10) + (Math.abs(info.current_temperature - 15) / 10)
);
//이벤트 기반으로 일정 시간 간격으로 클라이언트에게 보낼 정보
client_send = {
time: info.time,
wind: info.windspd,
temperature: info.current_temperature,
rain: info.rain,
death: info.death_prob
};
function getRandom_add_prob(min, max) {
return Math.random() * (max - min) + min;
}
// 심장이 크게 뛰며 확률이 증가하거나 감소 할 수 있음
Math.random() * 2 >= 1 ? client_send.death += getRandom_add_prob(0,5) : client_send.death -= getRandom_add_prob(0,5) ;
//운명의 장난으로 죽을 확률이 증가하거나 감소함
const rand = Math.floor(Math.random() * 6) //생년월일 중 한자리 뽑음
Destiny=client_birth.charAt(rand)/3; //명시적 형 변환
if(Destiny==0)Destiny=1; //사용자 잘못 입력했을때 예외처리
Math.random() * 2 >= 1 ? client_send.death += Destiny : client_send.death -= Destiny ;
//만약 날이 너무 안좋아서 확률이 100을 넘긴다면 100으로 예외처리
if (client_send.death >= 100) {
client_send.death = 100;
}
console.log("client send data \n",client_send)
app.get("socket").emit("weatherInfo_minutely_send_to_client", client_send); // 클라이언트에게 정보 담아서 이벤트 발산
console.log("emit");
//db에 저장
sql = "INSERT INTO weatherInfo (time,wind,temperature,rain,prob) VALUES (?,?,?,?,?)";
db.query(sql, [client_send.time, client_send.wind, client_send.temperature, client_send.rain, client_send.death], (err, result) => {
if (err) console.log(err);
})
} catch (err) { //promise err or try err catch
console.log("================Error Occured !!================\n", err);
}
}
let call_interval;
const Start_Interval = (second, CALL) => {
CALL(); //처음 불러올때 한번 호출하고
call_interval = setInterval(CALL, second * 1000); //그 후에 1분마다 호출
}
io.on('connection', (socket) => { //프론트와 소켓 연결시 이벤트 루프 동작
app.set("socket", socket);
socket.on("connection", (client_data) => {
console.log("SOCKET CONNECTED");
client_name = client_data.name;
client_birth = client_data.birth;
Start_Interval(60, API_bundle); //소켓 연결후 interval 활성화하여 1분마다 API 호출
});
socket.on('disconnect', (reason) => {
console.log("disconnected");
clearInterval(call_interval); //연결 종료시 interval 해제
})
})
}