solorpower_crawler/crawlers/cmsolar_old.py

320 lines
11 KiB
Python

# ==========================================
# crawlers/cmsolar.py - CMSolar 크롤러 (10호기)
# ==========================================
import requests
from .base import create_session
def fetch_data(plant_info):
"""
CMSolar 발전소 데이터 수집
"""
plant_id = plant_info.get('id', 'cmsolar-10')
auth = plant_info.get('auth', {})
system = plant_info.get('system', {})
company_name = plant_info.get('company_name', '태양과바람')
plant_name = plant_info.get('name', '10호기')
login_id = auth.get('login_id', '')
login_pw = auth.get('login_pw', '')
site_no = auth.get('site_no', '')
base_url = system.get('base_url', '')
session = create_session()
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/143.0.0.0 Safari/537.36',
'Referer': f'{base_url}/plant/index.php'
}
# 1. 로그인
try:
login_data = {'id': login_id, 'pw': login_pw, 'commit': 'Login'}
session.post(f"{base_url}/login_ok.php", data=login_data, headers=headers)
except:
return []
# 2. 사이트 선택
try:
session.get(f"{base_url}/change.php?site={site_no}", headers=headers)
except:
return []
# 3. 데이터 요청
target_url = f"{base_url}/plant/sub/idx_ok.php?mode=getPlant"
try:
res = session.get(target_url, headers=headers)
res.encoding = 'utf-8'
data = res.json()
plant_data = data[0]['plant']
# 단위 변환 (W -> kW, Wh -> kWh)
curr_kw = float(plant_data.get('now', 0)) / 1000
today_kwh = float(plant_data.get('today', 0)) / 1000
is_error = int(plant_data.get('inv_error', 0))
status = "🟢 정상" if is_error == 0 else "🔴 점검/고장"
print(f" [CMSolar] {plant_name} 수집 완료: {round(curr_kw, 2)} kW")
return [{
'id': plant_id,
'name': f'{company_name} {plant_name}',
'kw': round(curr_kw, 2),
'today': round(today_kwh, 2),
'status': status
}]
except Exception as e:
print(f"{plant_name} 에러: {e}")
return []
def fetch_history_daily(plant_info, start_date, end_date):
"""
CMSolar 발전소의 일별 과거 데이터 수집
"""
from datetime import datetime, timedelta
from .base import safe_float
results = []
plant_id = plant_info.get('id', 'cmsolar-10')
auth = plant_info.get('auth', {})
system = plant_info.get('system', {})
plant_name = plant_info.get('name', '10호기')
login_id = auth.get('login_id', '')
login_pw = auth.get('login_pw', '')
site_no = auth.get('site_no', '')
base_url = system.get('base_url', '')
session = create_session()
print(f"\n{'='*60}")
print(f"[CMSolar Daily] {plant_name} ({start_date} ~ {end_date})")
print(f"{'='*60}")
headers = {
'User-Agent': 'Mozilla/5.0',
'Referer': f'{base_url}/plant/index.php'
}
try:
login_data = {'id': login_id, 'pw': login_pw, 'commit': 'Login'}
session.post(f"{base_url}/login_ok.php", data=login_data, headers=headers)
session.get(f"{base_url}/change.php?site={site_no}", headers=headers)
print(" ✓ Login successful")
except Exception as e:
print(f" ✗ Login failed: {e}")
return results
current_date = datetime.strptime(start_date, '%Y-%m-%d')
end_dt = datetime.strptime(end_date, '%Y-%m-%d')
while current_date <= end_dt:
date_str = current_date.strftime('%Y-%m-%d')
# 일별 데이터 엔드포인트 (추정)
daily_url = f"{base_url}/plant/sub/daily_data.php?date={date_str}"
try:
res = session.get(daily_url, headers=headers, timeout=10)
res.encoding = 'utf-8'
if res.status_code == 200:
data = res.json()
daily_kwh = safe_float(data.get('today', data.get('daily', 0))) / 1000.0
results.append({
'plant_id': plant_id,
'date': date_str,
'generation_kwh': daily_kwh
})
print(f"{date_str}: {daily_kwh}kWh")
except Exception as e:
print(f"{date_str}: {e}")
current_date += timedelta(days=1)
print(f"[Total] Collected {len(results)} daily records\n")
return results
def fetch_history_monthly(plant_info, start_month, end_month):
"""
CMSolar 발전소의 월별 과거 데이터 수집
"""
from datetime import datetime
from dateutil.relativedelta import relativedelta
from .base import safe_float
results = []
plant_id = plant_info.get('id', 'cmsolar-10')
auth = plant_info.get('auth', {})
system = plant_info.get('system', {})
plant_name = plant_info.get('name', '10호기')
login_id = auth.get('login_id', '')
login_pw = auth.get('login_pw', '')
site_no = auth.get('site_no', '')
base_url = system.get('base_url', '')
session = create_session()
print(f"\n{'='*60}")
print(f"[CMSolar Monthly] {plant_name} ({start_month} ~ {end_month})")
print(f"{'='*60}")
headers = {
'User-Agent': 'Mozilla/5.0',
'Referer': f'{base_url}/plant/index.php'
}
try:
login_data = {'id': login_id, 'pw': login_pw, 'commit': 'Login'}
session.post(f"{base_url}/login_ok.php", data=login_data, headers=headers)
session.get(f"{base_url}/change.php?site={site_no}", headers=headers)
print(" ✓ Login successful")
except Exception as e:
print(f" ✗ Login failed: {e}")
return results
current_month = datetime.strptime(start_month, '%Y-%m')
end_month_dt = datetime.strptime(end_month, '%Y-%m')
while current_month <= end_month_dt:
month_str = current_month.strftime('%Y-%m')
# 월별 데이터 엔드포인트 (추정)
monthly_url = f"{base_url}/plant/sub/monthly_data.php?month={month_str}"
try:
res = session.get(monthly_url, headers=headers, timeout=10)
res.encoding = 'utf-8'
if res.status_code == 200:
data = res.json()
monthly_kwh = safe_float(data.get('month', data.get('monthly', 0))) / 1000.0
results.append({
'plant_id': plant_id,
'month': month_str,
'generation_kwh': monthly_kwh
})
print(f"{month_str}: {monthly_kwh}kWh")
except Exception as e:
print(f"{month_str}: {e}")
current_month += relativedelta(months=1)
print(f"[Total] Collected {len(results)} monthly records\n")
return results
def fetch_history_hourly(plant_info, start_date, end_date):
"""
CMSolar 발전소의 시간대별 과거 데이터 수집
Args:
plant_info: dict, 발전소 정보
start_date: str, 시작일 (YYYY-MM-DD)
end_date: str, 종료일 (YYYY-MM-DD)
Returns:
list: 시간대별 데이터 레코드
"""
from datetime import datetime, timedelta
from .base import safe_float
results = []
# 설정 추출
plant_id = plant_info.get('id', 'cmsolar-10')
auth = plant_info.get('auth', {})
system = plant_info.get('system', {})
plant_name = plant_info.get('name', '10호기')
login_id = auth.get('login_id', '')
login_pw = auth.get('login_pw', '')
site_no = auth.get('site_no', '')
base_url = system.get('base_url', '')
session = create_session()
print(f"\n{'='*60}")
print(f"[CMSolar History] {plant_name} ({start_date} ~ {end_date})")
print(f"{'='*60}")
# 로그인
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/143.0.0.0 Safari/537.36',
'Referer': f'{base_url}/plant/index.php'
}
try:
login_data = {'id': login_id, 'pw': login_pw, 'commit': 'Login'}
session.post(f"{base_url}/login_ok.php", data=login_data, headers=headers)
# 사이트 선택
session.get(f"{base_url}/change.php?site={site_no}", headers=headers)
print(f" ✓ Login successful")
except Exception as e:
print(f" ✗ Login failed: {e}")
return results
# 날짜 범위 반복
current_date = datetime.strptime(start_date, '%Y-%m-%d')
end_dt = datetime.strptime(end_date, '%Y-%m-%d')
while current_date <= end_dt:
date_str = current_date.strftime('%Y-%m-%d')
print(f"\n[Processing Date] {date_str}")
# 시간대별 데이터 엔드포인트 (추정)
hourly_url = f"{base_url}/plant/sub/hourly_data.php?site={site_no}&date={date_str}"
try:
res = session.get(hourly_url, headers=headers, timeout=10)
res.encoding = 'utf-8'
if res.status_code == 200:
data = res.json()
hourly_data = data if isinstance(data, list) else data.get('hourly', [])
if hourly_data and len(hourly_data) > 0:
print(f" ✓ Found {len(hourly_data)} hourly records")
for item in hourly_data:
hour = str(item.get('hour', item.get('time', '00'))).zfill(2)
generation_wh = safe_float(item.get('energy', item.get('now', 0)))
generation_kwh = generation_wh / 1000.0 if generation_wh > 1000 else generation_wh
current_kw = safe_float(item.get('power', 0)) / 1000.0
timestamp = f"{date_str} {hour}:00:00"
results.append({
'plant_id': plant_id,
'timestamp': timestamp,
'generation_kwh': generation_kwh,
'current_kw': current_kw
})
else:
print(f" ⚠ No hourly data for {date_str}")
else:
print(f" ✗ HTTP {res.status_code}")
except Exception as e:
print(f" ✗ Error: {e}")
# 다음 날짜로
current_date += timedelta(days=1)
print(f"\n{'='*60}")
print(f"[Total] Collected {len(results)} hourly records")
print(f"{'='*60}\n")
return results