initial repo

This commit is contained in:
赵敬皓 2023-08-23 16:00:06 +08:00
parent 0d120ec466
commit 537540ccae
10 changed files with 2037 additions and 0 deletions

10
Dockerfile Normal file
View File

@ -0,0 +1,10 @@
FROM python:3.8
WORKDIR /app
ADD ./ /app/
RUN pip install --upgrade pip -i https://pypi.douban.com/simple/ --no-cache-dir
RUN pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple --no-cache-dir
CMD ["python3", "run.py"]

Binary file not shown.

Binary file not shown.

1
config/angle.json Normal file

File diff suppressed because one or more lines are too long

Binary file not shown.

1825
download.ipynb Normal file

File diff suppressed because one or more lines are too long

99
download.py Normal file
View File

@ -0,0 +1,99 @@
import datetime as dt
import os
import wget
import pygrib as pg
import numpy as np
import pandas as pd
from logzero import logger
import shutil
import sys
def check_newest_date()->str:
"""_summary_
检查GFS下最新的文件返回time字符串"YYYY-mm-DD HH:00:00"(整点更新)
Returns:
str: _description_
"""
pass
def fetch_files(now:str):
"""_summary_
Args:
now (str): 时间戳"YYYY-mm-dd HH:MM:SS"
Returns:
list: np.array: 返回时间跨度
"""
if now is None:
now = dt.datetime.now()
else:
now = dt.datetime.strptime(now, "%Y-$m-%d %H:%M:%S")
logger.info(now)
hour = now.hour - 8 # GFS是UTC+0datetime的时间是UTC+8, 所以要取一下值
logger.info(f"对应的UTC+0 时间:{hour}")
today = dt.date.today()
yesterday = today - dt.timedelta(days=1)
today_str = dt.datetime.strftime(today, "%Y%m%d")
yesterday_str = dt.datetime.strftime(yesterday, "%Y%m%d")
if hour <= 6:
logger.info("UTC+0 7点以前取前一天最后一次更新的结果")
start_date = dt.datetime(yesterday.year, yesterday.month, yesterday.day, 19, 0, 0)
if not os.path.exists(f'./data/{yesterday_str}'):
os.mkdir(f'./data/{yesterday_str}')
date = yesterday_str
for h in range(1, 5 * 24+1):
h_str = "{:03d}".format(h)
url = f"https://nomads.ncep.noaa.gov/cgi-bin/filter_gfs_0p25_1hr.pl?dir=%2Fgfs.{date}%2F18%2Fatmos&file=gfs.t18z.pgrb2.0p25.f{h_str}&var_DSWRF=on&lev_surface=on"
logger.info(url)
out_path = f"./data/{date}/gfs.t18z.pgrb2.0p25.f{h_str}"
if not os.path.exists(out_path):
wget.download(url, out=out_path)
logger.info(f"download file {out_path} finished")
else:
logger.info("UTC+0 7点以后调用, 则取今天00点的预测结果")
if not os.path.exists(f'./data/{today_str}'):
os.mkdir(f'./data/{today_str}')
start_date = dt.datetime(today.year, today.month, today.day, 1, 0, 0)
date = today_str
for h in range(1, 5 * 24+1):
h_str = "{:03d}".format(h)
url = f"https://nomads.ncep.noaa.gov/cgi-bin/filter_gfs_0p25_1hr.pl?dir=%2Fgfs.{date}%2F00%2Fatmos&file=gfs.t00z.pgrb2.0p25.f{h_str}&var_DSWRF=on&lev_surface=on"
logger.info(url)
out_path = f"./data/{date}/gfs.t18z.pgrb2.0p25.f{h_str}"
if not os.path.exists(out_path):
wget.download(url, out=out_path)
logger.info(f"download file {out_path} finished")
end_date = start_date + dt.timedelta(hours=120)
time_range = pd.date_range(start_date+dt.timedelta(hours=8), end_date+dt.timedelta(hours=8), freq='H').astype(str).to_list()
return time_range, date
def trans_data(date:str) -> np.array:
file_path = f"./data/{date}/"
files = [f"{file_path}/{x}" for x in os.listdir(file_path) if x.startswith('gfs')]
pred = list()
for file in files:
data = pg.open(file)
try:
grb = data.select(name="Downward short-wave radiation flux")[0]
values = grb.values
except Exception as e:
logger.info(f"error occurs when read {file}, {e}")
values = np.full([721, 1440], np.nan)
finally:
pred.append(values)
data.close()
rst = np.asarray(pred).tolist()
# np.save(f"./data/{date}.npy", rst)
# TODO: 在这里添加写入数据库的代码
shutil.rmtree(f"./data/{date}/")
return rst
if __name__ == '__main__':
time_range, date = fetch_files(None)
rst = trans_data(date)

5
requirements.txt Normal file
View File

@ -0,0 +1,5 @@
numpy==1.24.4
pandas==1.2.4
logzero==1.7.0
flask==2.3.3
jieba==0.42.1

58
run.py Normal file
View File

@ -0,0 +1,58 @@
# -*-coding:utf-8-*-
import os
os.environ['CUDA_VISIBLE_DEVICES'] = '-1'
import json
from flask import Flask, request, make_response
from logzero import logger
current_path = os.path.dirname(os.path.abspath(__file__)) # for local
# current_path = "/app" # for docker
logger.info(f"{current_path}")
from tools import cal_generation, cal_angle, load_config
app = Flask(__name__)
angle_config = load_config(f"{current_path}/config/angle.json")
@app.route('/angle/', methods=["POST"])
def get_angle_info():
resp_info = dict()
if request.method == "POST":
prov = request.json.get('province')
city = request.json.get('city')
logger.info(f"{prov}-{city}")
try:
best_angle = cal_angle(prov, city)
resp_info["code"] = 200
resp_info["data"] = best_angle
except Exception as e:
resp_info["code"] = 406
resp_info["data"] = str(e)
resp = make_response(json.dumps(resp_info))
resp.status_code = 200
return resp
@app.route('/power/', methods=["POST"])
def get_power():
resp_info = dict()
if request.method == "POST":
prov = request.json.get('province')
city = request.json.get('city')
cap = request.json.get('capacity')
angle = request.json.get('angle')
dhi_list = request.json.get('dhi')
try:
best_angle = cal_angle(prov, city)
power_trend = cal_generation(cap, angle, best_angle, dhi_list)
resp_info["code"] = 200
resp_info["data"] = power_trend
except Exception as e:
resp_info["code"] = 406
resp_info["data"] = str(e)
resp = make_response(json.dumps(resp_info))
resp.status_code = 200
return resp
if __name__ == '__main__':
app.run(port=9515, host="0.0.0.0", debug=False)

39
tools.py Normal file
View File

@ -0,0 +1,39 @@
# -*-utf8-*-
import numpy as np
import jieba
import json
import math
def load_config(path):
with open(path, 'r', encoding='utf-8') as fr:
config = json.load(fr)
return config
def cal_angle(prov:str, city:str, angle_config:dict):
"""_summary_
Args:
prov (str): 直辖市自治区特别行政区
city (str): 地级市地区自治州
angle_config (dict): _description_
Returns:
_type_: _description_
"""
prov_values = angle_config.get(prov)
if not prov_values:
return False
city = [x for x in jieba.lcut(city, cut_all=True)]
city_values = prov_values.get(city)
if not prov_values:
values = np.mean(list(prov_values.values), axis=0)
else:
values = city_values
return values
def cal_generation(cap: [int, float], angle, best_angle, dhi_list):
"""_summary_
G = Y * cos(|x - y|)* 0.9 * GHI
"""
dhi_list = np.asarray(dhi_list)
return list(cap * math.cos(math.radians(abs(angle - best_angle))) * dhi_list)