#!/usr/bin/env python
# -*- coding: utf-8 -*-
# time: 2023/6/16 10:15
# file: calculate.py
# author: David
# company: shenyang JY
import requests
import json, time, datetime

url = 'http://49.4.78.194:17160/apiCalculate/calculate'
'''
准确率接口使用手顺：
①入口方法为 calculate_acc
② 按照参数传传值
data含有C_TIME时间、realValue实际功率、ableValue可用功率（没有数值用实际功率替代）、forecastAbleValue预测功率
opt为包含场站必要信息的字典，字段为：cap装机容量 province省份 formulaType公式类型 electricType电站类型 stationCode场站编码
具体介绍参考接口文档
③公式计算分为按天和按点两种，指定好opt.formulaType，即可设置公式类型，再在求取的每天或每个点的结果上进行平均，结果返回
'''


def wrap_json(df, opt):
    """
    包装json
    :param df: 列名为 C_TIME realValue ableValue forecastAbleValue的DataFrame
    :param opt: 参数字典
    :return: json列表
    """
    d = opt.formulaType.split('_')[0]
    jata, dfs = [], []
    if d == 'POINT':
        df['time'] = df['C_TIME'].apply(datetime_to_timestamp)
        for i, row in df.iterrows():
            dfs.append(row.to_frame().T)
    elif d == 'DAY':
        df['time'] = df['C_TIME'].apply(datetime_to_timestamp)
        df['C_TIME'] = df['C_TIME'].dt.strftime('%y%m%d')   # 转换成年月日
        for i, group in df.groupby('C_TIME'):
            dfs.append(group)
    outter_dict = {"electricCapacity": str(opt.cap), "province": opt.province, "formulaType": opt.formulaType, "electricType":opt.electricType, "stationCode": opt.stationCode}
    timestamp = int(time.mktime(datetime.datetime.now().timetuple()) * 1000 + datetime.datetime.now().microsecond / 1000.0)
    inner_dict = {"genTime": str(timestamp)+"L", "capacity": str(opt.cap), "openCapacity": str(opt.cap)}
    for df in dfs:
        calculationInfoList = df.iloc[:, 1:].to_json(orient='records')
        outter_dict['calculationInfoList'] = [dict(calculation, **inner_dict) for calculation in eval(calculationInfoList)]
        jata.append(json.dumps(outter_dict))
    return jata


def send_reqest(url, jata):
    """
    发送请求
    :param url: 请求地址
    :param jata: Json数据
    :return: 准确率
    """
    headers = {
        'content-type': 'application/json;charset=UTF-8',
        "Authorization": "dXNlcjoxMjM0NTY="
    }
    acc, number = 0, 0
    for i in range(len(jata)):
        res = requests.post(url, headers=headers, data=jata[i])
        if res.json()['code'] == '500':
            print("没通过考核标准")
            continue
        number += 1
        acc += float(res.json()['data'][:-1])
    acc /= number
    return acc


def calculate_acc(data, opt):
    """
    准确率调用接口计算
    :param data: 列名为 C_TIME realValue ableValue forecastAbleValue的DataFrame
    :param opt: 参数字段
    :return: 计算结果
    """
    jata = wrap_json(data, opt)
    acc = send_reqest(url=url, jata=jata)
    return acc


def datetime_to_timestamp(dt):
    return int(round(time.mktime(dt.timetuple()))*1000)