250 lines
8.5 KiB
Python
250 lines
8.5 KiB
Python
#!/usr/bin/env python
|
|
# -*- coding: utf-8 -*-
|
|
"""
|
|
데이터 검증 스크립트
|
|
각 발전소별로 특정 날짜/월/연도의 실제 데이터를 조회하여 검증
|
|
"""
|
|
|
|
from datetime import datetime
|
|
from crawlers import nrems, hyundai, kremc, sun_wms, cmsolar
|
|
from config import SYSTEM_CONSTANTS
|
|
|
|
|
|
def format_hourly_data(data, date_str, plant_name):
|
|
"""시간별 데이터 포맷팅"""
|
|
print(f"\n{'='*80}")
|
|
print(f"[{plant_name}] 시간별 데이터: {date_str}")
|
|
print(f"{'='*80}")
|
|
|
|
if not data:
|
|
print(" ❌ 데이터 없음")
|
|
return
|
|
|
|
# 시간별로 그룹화
|
|
hourly_dict = {}
|
|
for record in data:
|
|
timestamp = record.get('timestamp', '')
|
|
if timestamp.startswith(date_str):
|
|
hour = timestamp.split(' ')[1][:2] if ' ' in timestamp else '00'
|
|
kwh = record.get('generation_kwh', 0)
|
|
if hour not in hourly_dict:
|
|
hourly_dict[hour] = 0
|
|
hourly_dict[hour] += kwh
|
|
|
|
if not hourly_dict:
|
|
print(" ❌ 해당 날짜 데이터 없음")
|
|
return
|
|
|
|
print(f" 총 {len(hourly_dict)}시간 데이터")
|
|
print(f"\n {'시간':<8} {'발전량(kWh)':<15}")
|
|
print(f" {'-'*25}")
|
|
|
|
total = 0
|
|
for hour in sorted(hourly_dict.keys()):
|
|
kwh = hourly_dict[hour]
|
|
total += kwh
|
|
print(f" {hour}:00 {kwh:>10.2f}")
|
|
|
|
print(f" {'-'*25}")
|
|
print(f" {'합계':<8} {total:>10.2f}")
|
|
|
|
|
|
def format_daily_data(data, year_month, plant_name):
|
|
"""일별 데이터 포맷팅"""
|
|
print(f"\n{'='*80}")
|
|
print(f"[{plant_name}] 일별 데이터: {year_month}")
|
|
print(f"{'='*80}")
|
|
|
|
if not data:
|
|
print(" ❌ 데이터 없음")
|
|
return
|
|
|
|
# 해당 월의 데이터만 필터링
|
|
monthly_data = [d for d in data if d.get('date', '').startswith(year_month)]
|
|
|
|
if not monthly_data:
|
|
print(" ❌ 해당 월 데이터 없음")
|
|
return
|
|
|
|
print(f" 총 {len(monthly_data)}일 데이터")
|
|
print(f"\n {'날짜':<15} {'발전량(kWh)':<15}")
|
|
print(f" {'-'*30}")
|
|
|
|
total = 0
|
|
for record in sorted(monthly_data, key=lambda x: x.get('date', '')):
|
|
date = record.get('date', '')
|
|
kwh = record.get('generation_kwh', 0)
|
|
total += kwh
|
|
print(f" {date:<15} {kwh:>10.2f}")
|
|
|
|
print(f" {'-'*30}")
|
|
print(f" {'합계':<15} {total:>10.2f}")
|
|
|
|
|
|
def format_monthly_data(data, year, plant_name):
|
|
"""월별 데이터 포맷팅"""
|
|
print(f"\n{'='*80}")
|
|
print(f"[{plant_name}] 월별 데이터: {year}년")
|
|
print(f"{'='*80}")
|
|
|
|
if not data:
|
|
print(" ❌ 데이터 없음")
|
|
return
|
|
|
|
# 해당 연도의 데이터만 필터링
|
|
yearly_data = [d for d in data if d.get('month', '').startswith(year)]
|
|
|
|
if not yearly_data:
|
|
print(" ❌ 해당 연도 데이터 없음")
|
|
return
|
|
|
|
print(f" 총 {len(yearly_data)}개월 데이터")
|
|
print(f"\n {'월':<10} {'발전량(kWh)':<15}")
|
|
print(f" {'-'*25}")
|
|
|
|
total = 0
|
|
for record in sorted(yearly_data, key=lambda x: x.get('month', '')):
|
|
month = record.get('month', '')
|
|
kwh = record.get('generation_kwh', 0)
|
|
total += kwh
|
|
print(f" {month:<10} {kwh:>10.2f}")
|
|
|
|
print(f" {'-'*25}")
|
|
print(f" {'합계':<10} {total:>10.2f}")
|
|
if len(yearly_data) > 0:
|
|
print(f" {'평균':<10} {total/len(yearly_data):>10.2f}")
|
|
|
|
|
|
def verify_plant(plant_config, crawler_module):
|
|
"""개별 발전소 데이터 검증"""
|
|
plant_name = plant_config['name']
|
|
|
|
print(f"\n{'#'*80}")
|
|
print(f"# {plant_name}")
|
|
print(f"{'#'*80}")
|
|
|
|
try:
|
|
# 1. 시간별 데이터: 2025-05-10, 2024-10-20
|
|
print(f"\n[1/6] 시간별 데이터 수집 중...")
|
|
|
|
hourly_2025 = crawler_module.fetch_history_hourly(plant_config, '2025-05-10', '2025-05-10')
|
|
format_hourly_data(hourly_2025, '2025-05-10', plant_name)
|
|
|
|
hourly_2024 = crawler_module.fetch_history_hourly(plant_config, '2024-10-20', '2024-10-20')
|
|
format_hourly_data(hourly_2024, '2024-10-20', plant_name)
|
|
|
|
# 2. 일별 데이터: 2025-05, 2024-07
|
|
print(f"\n[2/6] 일별 데이터 수집 중...")
|
|
|
|
daily_2025 = crawler_module.fetch_history_daily(plant_config, '2025-05-01', '2025-05-31')
|
|
format_daily_data(daily_2025, '2025-05', plant_name)
|
|
|
|
daily_2024 = crawler_module.fetch_history_daily(plant_config, '2024-07-01', '2024-07-31')
|
|
format_daily_data(daily_2024, '2024-07', plant_name)
|
|
|
|
# 3. 월별 데이터: 2024년, 2025년
|
|
print(f"\n[3/6] 월별 데이터 수집 중...")
|
|
|
|
monthly_2025 = crawler_module.fetch_history_monthly(plant_config, '2025-01', '2025-12')
|
|
format_monthly_data(monthly_2025, '2025', plant_name)
|
|
|
|
monthly_2024 = crawler_module.fetch_history_monthly(plant_config, '2024-01', '2024-12')
|
|
format_monthly_data(monthly_2024, '2024', plant_name)
|
|
|
|
print(f"\n>>> {plant_name} 검증 완료")
|
|
|
|
except Exception as e:
|
|
print(f"\n ❌ 오류 발생: {str(e)}")
|
|
import traceback
|
|
traceback.print_exc()
|
|
|
|
|
|
def main():
|
|
"""메인 함수"""
|
|
print("\n" + "="*80)
|
|
print(">>> 발전소 데이터 검증 스크립트 <<<")
|
|
print("="*80)
|
|
print(f"검증 일시: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
|
|
print("\n[검증 대상]")
|
|
print(" - 시간별: 2025-05-10, 2024-10-20")
|
|
print(" - 일별: 2025년 5월, 2024년 7월")
|
|
print(" - 월별: 2025년, 2024년")
|
|
|
|
# 테스트 대상 발전소 설정
|
|
test_plants = [
|
|
# NREMS 1,2호기 (분리)
|
|
({'id': 'nrems-01', 'name': '1호기', 'type': 'nrems',
|
|
'auth': {'pscode': 'duce2023072288'},
|
|
'options': {'is_split': True, 'unit_id': 1},
|
|
'system': SYSTEM_CONSTANTS['nrems']}, nrems),
|
|
|
|
({'id': 'nrems-02', 'name': '2호기', 'type': 'nrems',
|
|
'auth': {'pscode': 'duce2023072288'},
|
|
'options': {'is_split': True, 'unit_id': 2},
|
|
'system': SYSTEM_CONSTANTS['nrems']}, nrems),
|
|
|
|
# NREMS 3호기
|
|
({'id': 'nrems-03', 'name': '3호기', 'type': 'nrems',
|
|
'auth': {'pscode': 'dc2023121086'},
|
|
'options': {},
|
|
'system': SYSTEM_CONSTANTS['nrems']}, nrems),
|
|
|
|
# NREMS 4호기
|
|
({'id': 'nrems-04', 'name': '4호기', 'type': 'nrems',
|
|
'auth': {'pscode': 'duce2023072269'},
|
|
'options': {},
|
|
'system': SYSTEM_CONSTANTS['nrems']}, nrems),
|
|
|
|
# NREMS 9호기
|
|
({'id': 'nrems-09', 'name': '9호기', 'type': 'nrems',
|
|
'auth': {'pscode': 'a2020061008'},
|
|
'options': {},
|
|
'system': SYSTEM_CONSTANTS['nrems']}, nrems),
|
|
|
|
# KREMC 5호기
|
|
({'id': 'kremc-05', 'name': '5호기', 'type': 'kremc',
|
|
'auth': {'user_id': '서대문도서관', 'password': 'sunhope5!'},
|
|
'options': {'cid': '10013000376', 'cityProvCode': '11', 'rgnCode': '11410',
|
|
'dongCode': '1141011700', 'enso_type_code': '15001'},
|
|
'system': SYSTEM_CONSTANTS['kremc']}, kremc),
|
|
|
|
# Sun-WMS 6호기
|
|
({'id': 'sunwms-06', 'name': '6호기', 'type': 'sun_wms',
|
|
'auth': {'payload_id': 'kc0fXUW0LUm2wZa+2NQI0Q==', 'payload_pw': 'PGXjU6ib2mKYwtrh2i3fIQ=='},
|
|
'options': {},
|
|
'system': SYSTEM_CONSTANTS['sun_wms']}, sun_wms),
|
|
|
|
# Hyundai 8호기
|
|
({'id': 'hyundai-08', 'name': '8호기', 'type': 'hyundai',
|
|
'auth': {'user_id': 'epecoop', 'password': 'sunhope0419', 'site_id': 'M0494'},
|
|
'options': {},
|
|
'system': SYSTEM_CONSTANTS['hyundai']}, hyundai),
|
|
|
|
# CMSolar 10호기
|
|
({'id': 'cmsolar-10', 'name': '10호기', 'type': 'cmsolar',
|
|
'auth': {'login_id': 'smart3131', 'password': 'ehdrb!123', 'site_no': '834'},
|
|
'options': {},
|
|
'system': SYSTEM_CONSTANTS['cmsolar']}, cmsolar),
|
|
]
|
|
|
|
# 각 발전소 검증
|
|
for plant_config, crawler_module in test_plants:
|
|
try:
|
|
verify_plant(plant_config, crawler_module)
|
|
except KeyboardInterrupt:
|
|
print("\n\n⚠️ 사용자 중단")
|
|
break
|
|
except Exception as e:
|
|
print(f"\n❌ {plant_config['name']} 검증 실패: {str(e)}")
|
|
import traceback
|
|
traceback.print_exc()
|
|
continue
|
|
|
|
print("\n" + "="*80)
|
|
print(">>> 데이터 검증 완료 <<<")
|
|
print("="*80)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|