# Auto-sync hang ngay - chay tu Task Scheduler. # Sync hom qua + hom nay tu Hikvision -> DB. # Retry tu dong neu device offline (thiet bi co the dang reboot). # Log: logs\auto_sync.log $ErrorActionPreference = 'Continue' $logDir = Join-Path $PSScriptRoot 'logs' $logFile = Join-Path $logDir 'auto_sync.log' if (-not (Test-Path $logDir)) { New-Item -ItemType Directory -Path $logDir | Out-Null } function Log($msg) { $line = "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] $msg" Add-Content -Path $logFile -Value $line -Encoding UTF8 } function Invoke-SyncRange($from, $to) { Log "" Log "=== AUTO SYNC start ($from -> $to) ===" # Goi POST /api/sync try { $body = "{`"from`":`"$from`",`"to`":`"$to`"}" $r = Invoke-RestMethod -Uri 'http://127.0.0.1:5000/api/sync' ` -Method POST -ContentType 'application/json' -Body $body -TimeoutSec 30 Log "Sync started: $($r | ConvertTo-Json -Compress)" } catch { $code = $null if ($_.Exception.Response) { $code = $_.Exception.Response.StatusCode.value__ } Log "ERROR starting sync (HTTP $code): $($_.Exception.Message)" return $null } # Poll status toi da 5 phut $timeout = 300; $elapsed = 0 do { Start-Sleep -Seconds 5; $elapsed += 5 try { $st = Invoke-RestMethod -Uri 'http://127.0.0.1:5000/api/sync/status' -TimeoutSec 10 } catch { Log "ERROR polling status: $($_.Exception.Message)" return $null } if (-not $st.running) { $res = $st.result if ($res -and $res.message) { Log ("DONE: total={0} new={1} sessions={2} posts={3} msg='{4}'" -f ` $res.total, $res.new, $res.sessions, $res.posts, $res.message) } elseif ($res -and $res.error) { Log "DONE with error: $($res.error)" } else { Log "DONE (no result detail)" } Log "=== AUTO SYNC end (took $elapsed seconds) ===" return $res } } while ($elapsed -lt $timeout) Log "TIMEOUT after $timeout seconds - server van running" Log "=== AUTO SYNC end (TIMEOUT) ===" return $null } function Test-DeviceOffline($res) { if ($res -eq $null) { return $true } $msg = [string]($res.message) return ($msg -like "*Pre-sync check failed*") -or ($msg -like "*Connection error*") -or ($msg -like "*timed out*") } # === MAIN === $today = Get-Date -Format 'yyyy-MM-dd' $yesterday = (Get-Date).AddDays(-1).ToString('yyyy-MM-dd') # Sync hom qua + hom nay (catch-up neu toi qua device offline) $result = Invoke-SyncRange $yesterday $today # Neu device offline: cho 20 phut roi thu lai # (Hikvision co the dang tu khoi dong lai - thuong mat 5-10 phut) if (Test-DeviceOffline $result) { Log "RETRY: Device khong phan hoi. Cho 20 phut roi thu lai..." Start-Sleep -Seconds 1200 $result2 = Invoke-SyncRange $yesterday $today if (Test-DeviceOffline $result2) { Log "RETRY FAILED: Device van khong phan hoi sau 20 phut. Can kiem tra thu cong." exit 3 } } exit 0