<?php
// =============================================================
// [1. 초기 세팅 & 무기 장착]
// =============================================================
chdir(dirname(__FILE__));
// ★ CLI 환경에서 DOCUMENT_ROOT 강제 지정
if (empty($_SERVER['DOCUMENT_ROOT'])) {
$_SERVER['DOCUMENT_ROOT'] = '/home/www';
}
// ★ 데몬 상태 기록 함수 로드
include_once('./db_record.php');
try {
if (!file_exists('./upbit_api.class.php')) {
throw new Exception("upbit_api.class.php 파일을 찾을 수 없습니다.");
}
include_once('./upbit_api.class.php');
require_once $_SERVER['DOCUMENT_ROOT'].'/DB/key_upbit_trade.php';
$upbit_access = $UPBIT_ACCESS_KEY;
$upbit_secret = $UPBIT_SECRET_KEY;
if (empty($upbit_access) || empty($upbit_secret)) {
throw new Exception("키 파일은 있는데 내용이 비어있습니다.");
}
$upbit = new Upbit($upbit_access, $upbit_secret);
} catch (Throwable $e) {
echo "[" . date('Y-m-d H:i:s') . "] 초기 세팅 에러: " . $e->getMessage() . "\n";
exit;
}
// =============================================================
// [2. 무한 씹질 루프 (감시 시작)]
// =============================================================
$done_memory = [];
$last_cleanup_min = ''; // ★ 메모리 정리 기준 분
$pdo_gnu = null;
$db_upbit = null;
echo "[" . date('Y-m-d H:i:s') . "] 데몬 정상 가동 시작...\n";
while (true) {
try {
// ★ [좀비 치료제] 그누보드 연결 없으면 새로 개통
if (!$pdo_gnu) {
$pdo_gnu = require $_SERVER['DOCUMENT_ROOT'].'/DB/db_gnu.php';
}
// ★ [좀비 치료제] 업비트 시세 DB 연결 없으면 새로 개통
if (!$db_upbit) {
require $_SERVER['DOCUMENT_ROOT'].'/DB/db_upbit.php';
$db_upbit = $db_upbit ?? null;
}
$now_dt = new DateTime();
$current_ymdhi = $now_dt->format('Y-m-d H:i');
$current_hi = $now_dt->format('H:i');
$current_m = (int)$now_dt->format('H') * 60 + (int)$now_dt->format('i');
// ★ [heartbeat] 분이 바뀔 때만 기록
static $last_heartbeat_min = '';
if ($current_ymdhi !== $last_heartbeat_min) {
record_daemon($db_upbit, 'RUNNING', 'heartbeat');
$last_heartbeat_min = $current_ymdhi;
// ★ [메모리 정리] 분이 바뀔 때만 이전 분 키 제거
foreach ($done_memory as $k => $v) {
if (strpos($k, $current_ymdhi) === false) {
unset($done_memory[$k]);
}
}
$last_cleanup_min = $current_ymdhi;
}
$stmt = $pdo_gnu->query("SELECT * FROM g5_write_daemon_day_upbit WHERE x2_run = '1'");
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($rows as $row) {
// ★ [몸통 중복 가드] Y-m-d H:i 기준 같은 분에 1번만 실행
$memory_key = $row['wr_id'] . '_' . $current_ymdhi;
if (isset($done_memory[$memory_key])) continue;
$is_execute = false;
$target_file = '';
// [조건 A] x2_all_day_1~10 동적 체크 (켜진 1개만 사용)
for ($i = 1; $i <= 10; $i++) {
if (empty($row["x2_all_day_{$i}"])) continue;
$interval_key = ($i === 1) ? 'x2_interval' : "x2_interval_{$i}";
$interval_min = (int)($row[$interval_key] ?? 0);
if ($interval_min > 0 && ($current_m % $interval_min) == 0) {
$is_execute = true;
$target_file = "day_time_code_{$i}.php";
}
break;
}
// [조건 B] 아무것도 없으면 지정시간 타격기
if (!$target_file) {
$target_hi = sprintf("%02d:%02d", $row['x2_hour'], $row['x2_min']);
if ($current_hi == $target_hi) {
$is_execute = true;
$target_file = 'day_target_code.php';
}
}
// [실행] 조건 맞으면 타격기 호출
if ($is_execute && $target_file != '') {
if (file_exists($target_file)) {
include $target_file;
$done_memory[$memory_key] = true;
usleep(200000);
} else {
echo "오류: 실행 파일($target_file)이 없습니다.\n";
}
}
}
} catch (Throwable $e) {
record_daemon($db_upbit, 'ERROR', "err=" . $e->getMessage());
$pdo_gnu = null;
$db_upbit = null;
}
usleep(31000000); // 31초 대기 (변경 가능)
}
?>