initial repo
This commit is contained in:
parent
0d120ec466
commit
537540ccae
|
@ -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.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
|
@ -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+0,datetime的时间是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)
|
|
@ -0,0 +1,5 @@
|
||||||
|
numpy==1.24.4
|
||||||
|
pandas==1.2.4
|
||||||
|
logzero==1.7.0
|
||||||
|
flask==2.3.3
|
||||||
|
jieba==0.42.1
|
|
@ -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)
|
|
@ -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)
|
Loading…
Reference in New Issue