249 lines
12 KiB
C#
249 lines
12 KiB
C#
#nullable enable
|
|
using Best.HTTP;
|
|
using Cysharp.Threading.Tasks;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Threading.Tasks;
|
|
using UnityEngine;
|
|
using UVC.Data.Core;
|
|
using UVC.Data.Http;
|
|
using UVC.Factory.Playback.UI;
|
|
using UVC.Util;
|
|
namespace UVC.Factory.Playback
|
|
{
|
|
public class PlaybackService
|
|
{
|
|
#region Singleton
|
|
private static readonly PlaybackService instance = new PlaybackService(new PlaybackRepository());
|
|
public static PlaybackService Instance => instance;
|
|
static PlaybackService() { }
|
|
#endregion
|
|
|
|
public static readonly string PlaybackFolderPath = Path.Combine(Application.persistentDataPath, "playback");//streamingAssetsPath, "playback"); appData 폴더로 변경
|
|
|
|
private readonly PlaybackRepository repository;
|
|
|
|
private string date;
|
|
private string time;
|
|
private string fileName;
|
|
|
|
public Action OnExitPlayback;
|
|
|
|
private float timeScale = 1.0f;
|
|
public float TimeScale
|
|
{
|
|
get => timeScale;
|
|
internal set
|
|
{
|
|
if (value < 1f) value = 1f;
|
|
if (timeScale != value)
|
|
{
|
|
timeScale = value;
|
|
//Time.timeScale = timeScale;
|
|
OnChangeTimeScale?.Invoke(timeScale);
|
|
}
|
|
}
|
|
}
|
|
|
|
public Action<float> OnChangeTimeScale;
|
|
|
|
public PlaybackService(PlaybackRepository repository)
|
|
{
|
|
this.repository = repository;
|
|
}
|
|
|
|
public async UniTask<Dictionary<string, Dictionary<string, string>>?> RequestDataAsync()
|
|
{
|
|
Dictionary<string, Dictionary<string, string>>? data = await repository.RequestPlaybackDateList();
|
|
return data;
|
|
}
|
|
|
|
public async UniTask DispatchBaseInfoData(string date, string time, string fileName, string minute = "00", string second = "00")
|
|
{
|
|
await UniTask.RunOnThreadPool(async () =>
|
|
{
|
|
//헝가리 시간임
|
|
this.date = date;
|
|
this.time = time;
|
|
this.fileName = fileName;
|
|
DateTime dateTime = DateTimeUtil.UtcParse($"{date}T{int.Parse(time).ToString("00")}:{minute}:{second}.000Z");
|
|
string formatTime = DateTimeUtil.FormatTime(dateTime);
|
|
//baseInfo 가져오기
|
|
List <PlaybackSQLiteDataEntity> list = await repository.SelectBySecondBaseInfo(date, fileName, formatTime);
|
|
if (list.Count > 0)
|
|
{
|
|
HttpRequestConfig httpRequestConfig = new HttpRequestConfig("");
|
|
httpRequestConfig.SetUpdatedDataOnly(true);
|
|
httpRequestConfig.SetSplitResponseByKey(true);
|
|
httpRequestConfig.AddSplitConfig("AGV", DataMapperValidator.Get("AGV"));
|
|
httpRequestConfig.AddSplitConfig("ALARM", DataMapperValidator.Get("ALARM"));
|
|
foreach (var item in list)
|
|
{
|
|
HttpDataProcessor.ProcessSplitResponse(httpRequestConfig, item.data);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="second">0 ~ 3600</param>
|
|
public async UniTask DispatchRealTimeData(int second, int speed)
|
|
{
|
|
await UniTask.RunOnThreadPool(async () =>
|
|
{
|
|
int newSecond = second;
|
|
if (newSecond > 36000) newSecond = 36000;
|
|
//utc 시간으로 변환
|
|
DateTime dateTime = DateTimeUtil.UtcParse($"{date}T{int.Parse(time).ToString("00")}:00:00.000Z").AddSeconds(newSecond);//.Add(-DateTimeUtil.UtcKoreaGap);
|
|
string formatTime = DateTimeUtil.FormatTime(dateTime);
|
|
|
|
List<PlaybackSQLiteDataEntity> list = await repository.SelectBySecondAsync(date, fileName, formatTime, 1);
|
|
//Debug.Log($"DispatchRealTimeData {date} {time} {formatTime} {newSecond} {list.Count}");
|
|
if (list.Count > 0)
|
|
{
|
|
HttpRequestConfig httpRequestConfig = new HttpRequestConfig("");
|
|
httpRequestConfig.SetUpdatedDataOnly(true);
|
|
httpRequestConfig.SetSplitResponseByKey(true);
|
|
httpRequestConfig.AddSplitConfig("AGV", DataMapperValidator.Get("AGV"));
|
|
httpRequestConfig.AddSplitConfig("ALARM", DataMapperValidator.Get("ALARM"));
|
|
foreach (var item in list)
|
|
{
|
|
HttpDataProcessor.ProcessSplitResponse(httpRequestConfig, item.data);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
public async Task StartAsync(UIPlaybackListItemData data)
|
|
{
|
|
timeScale = 1.0f; //기본 시간 스케일 설정
|
|
UIPlayback.Instance.Show();
|
|
await UIPlayback.Instance.SetData(data.date, data.time, data.sqlFileName);
|
|
}
|
|
|
|
public void Exit()
|
|
{
|
|
OnExitPlayback?.Invoke();
|
|
}
|
|
|
|
public HTTPRequest? ReadyData(string date, string time, string fileName, Action<long, long, float> OnProgress, Action<string> OnComplete)
|
|
{
|
|
//date : "2024-12-05"
|
|
//fileName : "2024-12-05_0.sqlite.7z"
|
|
string playbackPath = PlaybackService.PlaybackFolderPath;
|
|
string tempPath = Path.Combine(playbackPath, "temp");//한국 시간으로 변경하기 때문에 임시 폴더 만들어서 압축 해제 후 이동
|
|
string datePath = Path.Combine(playbackPath, date);
|
|
var fileNameArr = fileName.Split(".");
|
|
string zipFilePath = Path.Combine(datePath, fileName);
|
|
string sqlFilePath = Path.Combine(datePath, fileNameArr[0] + ".sqlite");
|
|
|
|
DateTime utcDateTime = DateTimeUtil.Parse(fileNameArr[0], "yyyy-MM-dd_H");//.Add(-DateTimeUtil.UtcKoreaGap);
|
|
string utcDatePath = Path.Combine(playbackPath, utcDateTime.ToString("yyyy-MM-dd"));
|
|
string utcFileName = utcDateTime.ToString("yyyy-MM-dd_H") + "." + fileNameArr[1] + "." + fileNameArr[2];
|
|
var utcFileNameArr = utcFileName.Split(".");
|
|
string utcZipFilePath = Path.Combine(tempPath, utcFileName);
|
|
string utcSqlFilePath = Path.Combine(tempPath, utcFileNameArr[0] + ".sqlite");
|
|
if (!Directory.Exists(playbackPath)) Directory.CreateDirectory(playbackPath);
|
|
if (!Directory.Exists(datePath)) Directory.CreateDirectory(datePath);
|
|
if (!Directory.Exists(utcDatePath)) Directory.CreateDirectory(utcDatePath);
|
|
if (!Directory.Exists(tempPath)) Directory.CreateDirectory(tempPath);
|
|
if (File.Exists(sqlFilePath))
|
|
{
|
|
Debug.Log($"ONREADY SQP FILE");
|
|
if (OnProgress != null) OnProgress.Invoke(100, 100, 1.0f);
|
|
if (OnComplete != null) OnComplete.Invoke(null);
|
|
return null;
|
|
}
|
|
else
|
|
{
|
|
long downloadTotal = 0;
|
|
return repository.DownloadPlaybackData(utcFileName, utcZipFilePath,
|
|
(long progress, long length) =>
|
|
{
|
|
float percent = (float)progress / (float)length;
|
|
Debug.Log($"DownloadPlaybackData OnProgress:{percent}");
|
|
if (OnProgress != null) OnProgress.Invoke(progress, length, percent / 2);
|
|
downloadTotal = length;
|
|
}, async () =>
|
|
{
|
|
await UniTask.Delay(500);
|
|
Debug.Log($"DownloadPlaybackData OnComplete");
|
|
if (File.Exists(utcZipFilePath))
|
|
{
|
|
if (OnProgress != null) OnProgress.Invoke(50, 100, 0.5f);
|
|
//압축해제 후
|
|
var zipper = new Zipper();
|
|
|
|
string errorMessage = await zipper.Decompress(utcZipFilePath, tempPath, (long read, long total, float percent) =>
|
|
{
|
|
if (OnProgress != null)
|
|
{
|
|
bool isComplte = false;
|
|
float percentRate = 0.5f + percent / 2;
|
|
if (percentRate > 0.99)
|
|
{
|
|
percentRate = 0.99f;
|
|
isComplte = true;
|
|
}
|
|
OnProgress.Invoke(downloadTotal + read, downloadTotal + total, 0.5f + percent / 2);
|
|
if (isComplte)
|
|
{
|
|
Debug.Log($" DownloadReadData :{downloadTotal + read} , DownloadTotalData :{downloadTotal + total} ,DownloadPlaybackData OnProgress:{percent}");
|
|
}
|
|
}
|
|
});
|
|
Debug.Log($"zipper1 errorMessage:{errorMessage} utcSqlFilePath:{utcSqlFilePath} sqlFilePath:{sqlFilePath} utcZipFilePath:{utcZipFilePath}");
|
|
|
|
////파일 접근 문제면 2회 0.5초 후에 다시 실행.
|
|
//if (errorMessage == "Could not open input(7z) file")
|
|
//{
|
|
// await UniTask.Delay(500);
|
|
// errorMessage = await zipper.Decompress(utcZipFilePath, tempPath, (long read, long total, float percent) =>
|
|
// {
|
|
// if (OnProgress != null) OnProgress.Invoke(downloadTotal + read, downloadTotal + total, 0.5f + percent / 2);
|
|
// });
|
|
// Debug.Log($"zipper2 errorMessage:{errorMessage} utcSqlFilePath:{utcSqlFilePath} sqlFilePath:{sqlFilePath} utcZipFilePath:{utcZipFilePath}");
|
|
//}
|
|
|
|
//if (errorMessage == "Could not open input(7z) file")
|
|
//{
|
|
// await UniTask.Delay(500);
|
|
// errorMessage = await zipper.Decompress(utcZipFilePath, tempPath, (long read, long total, float percent) =>
|
|
// {
|
|
// if (OnProgress != null) OnProgress.Invoke(downloadTotal + read, downloadTotal + total, 0.5f + percent / 2);
|
|
// });
|
|
// Debug.Log($"zipper3 errorMessage:{errorMessage} utcSqlFilePath:{utcSqlFilePath} sqlFilePath:{sqlFilePath} utcZipFilePath:{utcZipFilePath}");
|
|
//}
|
|
|
|
await UniTask.RunOnThreadPool(() =>
|
|
{
|
|
//압축해제 한 파일 이동
|
|
if (File.Exists(utcSqlFilePath))
|
|
{
|
|
//동일한 파일명이 있을경우 제거후 다시
|
|
File.Copy(utcSqlFilePath, sqlFilePath);
|
|
File.Delete(utcSqlFilePath);
|
|
}
|
|
|
|
//zip 파일 삭제
|
|
File.Delete(utcZipFilePath);
|
|
});
|
|
|
|
if (OnComplete != null) OnComplete.Invoke(errorMessage);
|
|
}
|
|
},
|
|
(string? error) =>
|
|
{
|
|
Debug.Log($"DownloadPlaybackData OnError:{error}");
|
|
if (OnComplete != null) OnComplete.Invoke(error);
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
}
|