"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getInverterSummaryBetweenDate = exports.getAllInverterHistoriesByDate = exports.getInverterHistoriesByDate = exports.getInverterDetailByPowerPlantIdAndInverterId = exports.getInverterSubQuery = exports.getInverterSummaryYearlyByPowerPlantId = exports.getInverterSummaryMonthlyByPowerPlantId = exports.getInverterSummaryDailyByPowerPlantId = exports.getInverterSeperateYearlyByPowerPlantId = exports.getInverterSeperateMonthlyByPowerPlantId = exports.getInverterSeperateyDailyByPowerPlantId = exports.getInverterInfosByPowerPlantId = exports.getInverterSummaryByPowerPlantId = exports.getInverterRtuBindingListByPowerPlantId = exports.getInverterStatusByPowerPlantId = void 0;
const tslib_1 = require("tslib");
const shell_1 = require("@things-factory/shell");
const dataset_1 = require("@things-factory/dataset");
const inverter_status_1 = require("@esome-dev/inverter/dist-server/service/inverter-status/inverter-status");
const sunflow_entity_1 = require("@esome-dev/sunflow-entity");
const moment_1 = tslib_1.__importDefault(require("moment"));
const getInverterStatusByPowerPlantId = async (powerPlantId) => {
    const inverters = await (0, shell_1.getRepository)(inverter_status_1.InverterStatus)
        .createQueryBuilder('inverter')
        .select('*')
        .addSelect('ivt_id', 'ivtId')
        .addSelect('collected_at', 'collectedAt')
        .addSelect("CASE WHEN (DATE_PART('hour', NOW() + INTERVAL '9 hour') NOT BETWEEN 6 AND 20) THEN 'F' WHEN collected_at < NOW() - INTERVAL '1 hour' THEN 'T' ELSE 'F' END", 'isNoSignal') // 1시간 (한국 타임존 9시간 포함해서 10시간) 이상된 인버터 시간은 통신장애 (6~21시는 해가 없으므로 정상)
        .where('inverter.domain_id = :powerPlantId', { powerPlantId })
        .orderBy('inverter.ivt_id', 'ASC')
        .getRawMany();
    return inverters;
};
exports.getInverterStatusByPowerPlantId = getInverterStatusByPowerPlantId;
const getInverterRtuBindingListByPowerPlantId = async (powerPlantId) => {
    const inverters = await (0, shell_1.getRepository)(dataset_1.DataSensor)
        .createQueryBuilder('ds')
        .where('ds.domain_id = :powerPlantId', { powerPlantId })
        .orderBy('ds.name', 'ASC')
        .getMany();
    return inverters;
};
exports.getInverterRtuBindingListByPowerPlantId = getInverterRtuBindingListByPowerPlantId;
const getInverterSummaryByPowerPlantId = async (powerPlantId) => {
    const inverter = await (0, shell_1.getRepository)(dataset_1.DataSensor)
        .createQueryBuilder('ds')
        .select('ds.domain_id', 'powerPlantId')
        .addSelect('COUNT(*)', 'inverterCount')
        .addSelect('SUM(ds.capacity)', 'capacity')
        .addSelect("STRING_AGG(ds.name, ', ')", 'modelNames')
        .where('ds.domain_id = :powerPlantId', { powerPlantId })
        .groupBy('ds.domain_id')
        .getRawOne();
    return {
        id: powerPlantId,
        inverterCount: inverter.inverterCount,
        capacity: inverter.capacity,
        modelNames: inverter.modelNames
    };
};
exports.getInverterSummaryByPowerPlantId = getInverterSummaryByPowerPlantId;
const getInverterInfosByPowerPlantId = async (powerPlantId) => {
    const inverter = await (0, shell_1.getRepository)(inverter_status_1.InverterStatus)
        .createQueryBuilder('i_s')
        .select('i_s.ivt_id as no')
        .addSelect('ds.description', 'description')
        .addSelect('ds.capacity', 'capacity')
        .leftJoin(dataset_1.DataSensor, 'ds', "CONCAT(i_s.rtu_id, '-', ivt_id) = ds.device_id")
        .where('i_s.domain_id = :powerPlantId', { powerPlantId })
        .orderBy('i_s.ivt_id', 'ASC')
        .getRawMany();
    return inverter;
};
exports.getInverterInfosByPowerPlantId = getInverterInfosByPowerPlantId;
// 인버터 데이터, 일별
const getInverterSeperateyDailyByPowerPlantId = async (powerPlantId, date) => {
    const powerPlant = await (0, shell_1.getRepository)(shell_1.Domain).findOneBy({ id: powerPlantId });
    date = sunflow_entity_1.IS_DEV ? sunflow_entity_1.DEV_TODAY : date;
    const innerSubQuery = (0, exports.getInverterSubQuery)(powerPlantId, date, date)
        .addSelect('ds.period', 'period')
        .addGroupBy('ds.period');
    // 인버터 서브쿼리로 Diff 구하기
    const outerSubQuery = (0, shell_1.getDataSource)()
        .createQueryBuilder()
        .select('sub.date', 'date')
        .addSelect('sub.inverter_no', 'inverter_no')
        .addSelect('sub.period', 'period')
        .addSelect('GREATEST(sub.max_value - LAG(sub.max_value, 1, 0) OVER (PARTITION BY sub.inverter_no ORDER BY sub.date), 0) ', 'diff')
        .from('(' + innerSubQuery.getQuery() + ')', 'sub')
        .setParameters(innerSubQuery.getParameters());
    // Diff 합계 구하기
    const result = await (0, shell_1.getDataSource)()
        .createQueryBuilder()
        .select('sub_2.inverter_no', 'no')
        .addSelect('sub_2.period', 'date')
        .addSelect('SUM(sub_2.diff)', 'value')
        .addSelect(`SUM(sub_2.diff / ${powerPlant?.attributes?.capacity || 1})`, 'generationTime')
        .from('(' + outerSubQuery.getQuery() + ')', 'sub_2')
        .setParameters(outerSubQuery.getParameters())
        .groupBy('sub_2.inverter_no')
        .addGroupBy('sub_2.period')
        .orderBy('sub_2.inverter_no', 'ASC')
        .addOrderBy('sub_2.period', 'ASC')
        .getRawMany();
    return result;
};
exports.getInverterSeperateyDailyByPowerPlantId = getInverterSeperateyDailyByPowerPlantId;
// 인버터 월별 데이터, 일별
const getInverterSeperateMonthlyByPowerPlantId = async (powerPlantId, yearMonth) => {
    const powerPlant = await (0, shell_1.getRepository)(shell_1.Domain).findOneBy({ id: powerPlantId });
    // 내부 서브쿼리: key_02, date 별로 최대 ACC_P 값을 계산
    const startDate = (0, moment_1.default)(yearMonth, 'YYYY-MM').startOf('month').format('YYYY-MM-DD');
    const endDate = (0, moment_1.default)(yearMonth, 'YYYY-MM').endOf('month').format('YYYY-MM-DD');
    const subQuery = (0, exports.getInverterSubQuery)(powerPlantId, startDate, endDate);
    // 외부 쿼리: 서브쿼리 결과를 날짜별로 그룹화하여 max_value의 합을 구함
    const result = await (0, shell_1.getDataSource)()
        .createQueryBuilder()
        .select('sub.inverter_no', 'no')
        .addSelect('sub.date', 'date')
        .addSelect('SUM(sub.max_value)', 'value')
        .addSelect(`SUM(sub.max_value / ${powerPlant?.attributes?.capacity || 1})`, 'generationTime')
        .from('(' + subQuery.getQuery() + ')', 'sub')
        .setParameters(subQuery.getParameters())
        .groupBy('sub.inverter_no')
        .addGroupBy('sub.date')
        .orderBy('sub.inverter_no', 'ASC')
        .addOrderBy('sub.date', 'ASC')
        .getRawMany();
    return result;
};
exports.getInverterSeperateMonthlyByPowerPlantId = getInverterSeperateMonthlyByPowerPlantId;
// 인버터 연간 데이터, 일별
const getInverterSeperateYearlyByPowerPlantId = async (powerPlantId, year) => {
    const powerPlant = await (0, shell_1.getRepository)(shell_1.Domain).findOneBy({ id: powerPlantId });
    // 내부 서브쿼리: key_02, date 별로 최대 ACC_P 값을 계산
    const startDate = (0, moment_1.default)(year, 'YYYY').startOf('year').format('YYYY-MM-DD');
    const endDate = (0, moment_1.default)(year, 'YYYY').endOf('year').format('YYYY-MM-DD');
    const subQuery = (0, exports.getInverterSubQuery)(powerPlantId, startDate, endDate);
    // 외부 쿼리: 서브쿼리 결과를 'yyyy-mm'으로 그룹화하여 max_value의 합을 구함
    const result = await (0, shell_1.getDataSource)()
        .createQueryBuilder()
        .select('sub.inverter_no', 'no')
        .addSelect("TO_CHAR(sub.date::date, 'YYYY-MM')", 'date')
        .addSelect('SUM(sub.max_value)', 'value')
        .addSelect(`SUM(sub.max_value / ${powerPlant?.attributes?.capacity || 1})`, 'generationTime')
        .from('(' + subQuery.getQuery() + ')', 'sub')
        .setParameters(subQuery.getParameters())
        .groupBy('sub.inverter_no')
        .addGroupBy("TO_CHAR(sub.date::date, 'YYYY-MM')")
        .orderBy('sub.inverter_no', 'ASC')
        .addOrderBy("TO_CHAR(sub.date::date, 'YYYY-MM')", 'ASC')
        .getRawMany();
    return result;
};
exports.getInverterSeperateYearlyByPowerPlantId = getInverterSeperateYearlyByPowerPlantId;
// 인버터 일별 데이터 (1시간 단위 데이터)
const getInverterSummaryDailyByPowerPlantId = async (powerPlantId, fromDate, toDate = '') => {
    const powerPlant = await (0, shell_1.getRepository)(shell_1.Domain).findOneBy({ id: powerPlantId });
    toDate = toDate ? toDate : fromDate;
    if (sunflow_entity_1.IS_DEV && !toDate) {
        fromDate = sunflow_entity_1.DEV_TODAY;
        toDate = sunflow_entity_1.DEV_TODAY;
    }
    const innerSubQuery = (0, exports.getInverterSubQuery)(powerPlantId, fromDate, toDate)
        .addSelect('ds.period', 'period')
        .addSelect('MAX(ds.created_at)', 'created_at')
        .addGroupBy('ds.period');
    // 인버터 서브쿼리로 Diff 구하기
    const outerSubQuery = (0, shell_1.getDataSource)()
        .createQueryBuilder()
        .select('sub.date', 'date')
        .addSelect('sub.inverter_no', 'inverter_no')
        .addSelect('sub.period', 'period')
        .addSelect('GREATEST(sub.max_value - LAG(sub.max_value, 1, 0) OVER (PARTITION BY sub.inverter_no ORDER BY sub.date), 0) ', 'diff')
        .addSelect('sub.created_at', 'created_at')
        .from('(' + innerSubQuery.getQuery() + ')', 'sub')
        .setParameters(innerSubQuery.getParameters());
    // Diff 합계 구하기
    const result = await (0, shell_1.getDataSource)()
        .createQueryBuilder()
        .select('sub_2.period', 'period')
        .addSelect('SUM(sub_2.diff)', 'value')
        .addSelect(`SUM(sub_2.diff / ${powerPlant?.attributes?.capacity || 1})`, 'generationTime')
        .addSelect('sub_2.date', 'date')
        .addSelect('MAX(sub_2.created_at)', 'createdAt')
        .from('(' + outerSubQuery.getQuery() + ')', 'sub_2')
        .setParameters(outerSubQuery.getParameters())
        .groupBy('sub_2.date')
        .addGroupBy('sub_2.period')
        .orderBy('sub_2.date', 'ASC')
        .addOrderBy('sub_2.period', 'ASC')
        .getRawMany();
    return result;
};
exports.getInverterSummaryDailyByPowerPlantId = getInverterSummaryDailyByPowerPlantId;
// 인버터 월별 데이터 (1일 단위 데이터)
const getInverterSummaryMonthlyByPowerPlantId = async (powerPlantId, month) => {
    const powerPlant = await (0, shell_1.getRepository)(shell_1.Domain).findOneBy({ id: powerPlantId });
    // 내부 서브쿼리: key_02, date 별로 최대 ACC_P 값을 계산
    const startDate = (0, moment_1.default)(month, 'YYYY-MM').startOf('month').format('YYYY-MM-DD');
    const endDate = (0, moment_1.default)(month, 'YYYY-MM').endOf('month').format('YYYY-MM-DD');
    const subQuery = (0, exports.getInverterSubQuery)(powerPlantId, startDate, endDate);
    // 외부 쿼리: 서브쿼리 결과를 날짜별로 그룹화하여 max_value의 합을 구함
    const result = await (0, shell_1.getDataSource)()
        .createQueryBuilder()
        .select('sub.date', 'date')
        .addSelect('SUM(sub.max_value)', 'value')
        .addSelect(`SUM(sub.max_value / ${powerPlant?.attributes?.capacity || 1})`, 'generationTime')
        .from('(' + subQuery.getQuery() + ')', 'sub')
        .setParameters(subQuery.getParameters())
        .groupBy('sub.date')
        .orderBy('sub.date', 'ASC')
        .getRawMany();
    return result;
};
exports.getInverterSummaryMonthlyByPowerPlantId = getInverterSummaryMonthlyByPowerPlantId;
// 인버터 연간 데이터 (1일 단위 데이터)
const getInverterSummaryYearlyByPowerPlantId = async (powerPlantId, year) => {
    const powerPlant = await (0, shell_1.getRepository)(shell_1.Domain).findOneBy({ id: powerPlantId });
    // 내부 서브쿼리: key_02, date 별로 최대 ACC_P 값을 계산
    const startDate = (0, moment_1.default)(year, 'YYYY').startOf('year').format('YYYY-MM-DD');
    const endDate = (0, moment_1.default)(year, 'YYYY').endOf('year').format('YYYY-MM-DD');
    const subQuery = (0, exports.getInverterSubQuery)(powerPlantId, startDate, endDate);
    // 외부 쿼리: 서브쿼리 결과를 'yyyy-mm'으로 그룹화하여 max_value의 합을 구함
    const result = await (0, shell_1.getDataSource)()
        .createQueryBuilder()
        .select("TO_CHAR(sub.date::date, 'YYYY-MM')", 'date')
        .addSelect('SUM(sub.max_value)', 'value')
        .addSelect(`SUM(sub.max_value / ${powerPlant?.attributes?.capacity || 1})`, 'generationTime')
        .from('(' + subQuery.getQuery() + ')', 'sub')
        .setParameters(subQuery.getParameters())
        .groupBy("TO_CHAR(sub.date::date, 'YYYY-MM')")
        .orderBy("TO_CHAR(sub.date::date, 'YYYY-MM')", 'ASC')
        .getRawMany();
    return result;
};
exports.getInverterSummaryYearlyByPowerPlantId = getInverterSummaryYearlyByPowerPlantId;
// 인버터의 시간대별 아이디별 최대 ACC_P 값
const getInverterSubQuery = (powerPlantId, fromDate, toDate) => {
    return (0, shell_1.getRepository)(dataset_1.DataSummary)
        .createQueryBuilder('ds')
        .select('ds.key_02', 'inverter_no')
        .addSelect('ds.date', 'date')
        .addSelect('MAX(data_03)', 'max_value')
        .where('ds.name = :name', { name: '인버터' })
        .andWhere('ds.domain_id = :domainId', { domainId: powerPlantId })
        .andWhere('ds.date >= :fromDate', { fromDate })
        .andWhere('ds.date <= :toDate', { toDate })
        .andWhere('ds.data_03 > 0')
        .groupBy('ds.date')
        .addGroupBy('ds.key_02');
};
exports.getInverterSubQuery = getInverterSubQuery;
const getInverterDetailByPowerPlantIdAndInverterId = async (powerPlantId, inverterId, collectedAt) => {
    const result = await (0, shell_1.getRepository)(dataset_1.DataSample)
        .createQueryBuilder()
        .select('key_02', 'no') // 인버터 번호
        .addSelect('data', 'data') // 인버터 설명
        .where('collected_at = :collectedAt', { collectedAt })
        .andWhere('key_02 = :inverterId', { inverterId })
        .andWhere('domain_id = :powerPlantId', { powerPlantId })
        .limit(1)
        .getRawOne();
    return result;
};
exports.getInverterDetailByPowerPlantIdAndInverterId = getInverterDetailByPowerPlantIdAndInverterId;
const getInverterHistoriesByDate = async (powerPlantId, inverterId, dateType, date, page, limit) => {
    const queryBuilder = (0, shell_1.getRepository)(dataset_1.DataSample)
        .createQueryBuilder('ds')
        .select('key_02', 'no') // 인버터 번호
        .addSelect('data', 'data') // 인버터 설명
        .addSelect('collected_at', 'collectedAt')
        .andWhere('key_02 = :inverterId', { inverterId })
        .andWhere('domain_id = :powerPlantId', { powerPlantId })
        .andWhere('name = :name', { name: '인버터' })
        .andWhere("DATE_PART('hour', collected_at + INTERVAL '9 hour') BETWEEN 6 AND 20")
        .orderBy('collected_at', 'DESC')
        .limit(limit)
        .offset((page - 1) * limit);
    if (dateType === 'daily') {
        queryBuilder.andWhere('work_date = :workDate', { workDate: date });
    }
    else if (dateType === 'monthly') {
        queryBuilder.andWhere('work_date >= :fromDate', {
            fromDate: (0, moment_1.default)(date).startOf('month').format('YYYY-MM-DD')
        });
        queryBuilder.andWhere('work_date < :toDate', {
            toDate: (0, moment_1.default)(date).endOf('month').format('YYYY-MM-DD')
        });
    }
    else if (dateType === 'yearly') {
        queryBuilder.andWhere('work_date >= :fromDate', {
            fromDate: (0, moment_1.default)(date).startOf('year').format('YYYY-MM-DD')
        });
        queryBuilder.andWhere('work_date < :toDate', {
            toDate: (0, moment_1.default)(date).endOf('year').format('YYYY-MM-DD')
        });
    }
    const items = await queryBuilder.getRawMany();
    const total = await queryBuilder.getCount();
    return { items, total };
};
exports.getInverterHistoriesByDate = getInverterHistoriesByDate;
const getAllInverterHistoriesByDate = async (powerPlantId, date) => {
    const queryBuilder = (0, shell_1.getRepository)(dataset_1.DataSample)
        .createQueryBuilder('ds')
        .select('key_02', 'no') // 인버터 번호
        .addSelect('data', 'data') // 인버터 설명
        .addSelect('collected_at', 'collectedAt')
        .andWhere('domain_id = :powerPlantId', { powerPlantId })
        .andWhere('name = :name', { name: '인버터' })
        .andWhere('work_date = :workDate', { workDate: date })
        .orderBy('collected_at', 'DESC')
        .addOrderBy('key_02', 'ASC');
    return await queryBuilder.getRawMany();
};
exports.getAllInverterHistoriesByDate = getAllInverterHistoriesByDate;
// 인버터 일별 합계 데이터
const getInverterSummaryBetweenDate = async (powerPlantId, startDate, endDate) => {
    const powerPlant = await (0, shell_1.getRepository)(shell_1.Domain).findOneBy({ id: powerPlantId });
    // 내부 서브쿼리: key_02, date 별로 최대 ACC_P 값을 계산
    const subQuery = (0, exports.getInverterSubQuery)(powerPlantId, startDate, endDate);
    // 외부 쿼리: 서브쿼리 결과를 일별로 그룹화하여 max_value의 합을 구함
    const result = await (0, shell_1.getDataSource)()
        .createQueryBuilder()
        .select('sub.date', 'date')
        .addSelect(`SUM(sub.max_value / ${powerPlant?.attributes?.capacity || 1})`, 'generationTime')
        .from('(' + subQuery.getQuery() + ')', 'sub')
        .setParameters(subQuery.getParameters())
        .groupBy('sub.date')
        .getRawMany();
    return result;
};
exports.getInverterSummaryBetweenDate = getInverterSummaryBetweenDate;
//# sourceMappingURL=eaas-inverter-model.js.map