작업 조건 분석 기능 개발

This commit is contained in:
정영민
2025-03-10 16:42:23 +09:00
parent 840638c6e3
commit f2029fd8c9
2988 changed files with 569938 additions and 2342 deletions

View File

@@ -0,0 +1,127 @@
using CHN;
using System;
using UnityEngine;
using UnityEngine.EventSystems;
public class UIDraggerEventArg : EventArgs
{
private Vector3 pos;
public Vector3 Pos { get => pos; }
public UIDraggerEventArg(Vector3 pos)
{
this.pos = pos;
}
}
public class Dragger : UnityEngine.MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
public static string PathPrefab = "UI/UIDragger";
public RectTransform rect;
[Header("Resources")]
private RectTransform dragArea;
private RectTransform dragObject;
[Header("Settings")]
private bool topOnDrag = true;
public bool dashBoardDrag;
private Vector2 originalLocalPointerPosition;
private Vector3 originalPanelLocalPosition;
public EventHandler<UIDraggerEventArg> OnCommand { get; set; }
public Action onBeginDrag;
private float yMinHeight;
public void SetDrag(RectTransform parent)
{
if (dragArea == null)
{
try
{
var canvas = transform.GetComponentInParent<Canvas>();
dragArea = canvas.GetComponent<RectTransform>();
}
catch { Debug.LogWarning("<b>[Movable Window]</b> Drag Area has not been assigned."); }
}
rect = GetComponent<RectTransform>();
var toptoolbar = FindObjectOfType<Panel_TopToolBar>();
var topbarrect = toptoolbar.GetComponent<RectTransform>();
yMinHeight = topbarrect.sizeDelta.y;
baseSibling = DragObjectInternal.transform.GetSiblingIndex();
dragObject = parent;
}
void OnDestroy()
{
if (OnCommand != null) OnCommand = null;
}
private RectTransform DragObjectInternal
{
get
{
if (dragObject == null) { return (transform.parent as RectTransform); }
else { return dragObject; }
}
}
private RectTransform DragAreaInternal
{
get
{
if (dragArea == null)
{
RectTransform canvas = transform as RectTransform;
while (canvas.parent != null && canvas.parent is RectTransform) { canvas = canvas.parent as RectTransform; }
return canvas;
}
else { return dragArea; }
}
}
private int baseSibling;
public void OnBeginDrag(PointerEventData data)
{
if (!Input.GetMouseButton(0))
return;
originalPanelLocalPosition = DragObjectInternal.localPosition;
RectTransformUtility.ScreenPointToLocalPointInRectangle(DragAreaInternal, data.position, data.pressEventCamera, out originalLocalPointerPosition);
if (topOnDrag == true) { DragObjectInternal.transform.SetAsLastSibling(); }
}
public void OnDrag(PointerEventData data)
{
if (!Input.GetMouseButton(0))
return;
Vector2 localPointerPosition;
if (RectTransformUtility.ScreenPointToLocalPointInRectangle(DragAreaInternal, data.position, data.pressEventCamera, out localPointerPosition))
{
Vector3 offsetToOriginal = localPointerPosition - originalLocalPointerPosition;
DragObjectInternal.localPosition = originalPanelLocalPosition + offsetToOriginal;
}
ClampToArea();
}
private void ClampToArea()
{
Vector3 pos = DragObjectInternal.localPosition;
Vector3 minPosition = DragAreaInternal.rect.min - DragObjectInternal.rect.min;
Vector3 maxPosition = DragAreaInternal.rect.max - DragObjectInternal.rect.max;
pos.x = Mathf.Clamp(DragObjectInternal.localPosition.x, minPosition.x, maxPosition.x);
pos.y = Mathf.Clamp(DragObjectInternal.localPosition.y, minPosition.y, maxPosition.y - yMinHeight);
DragObjectInternal.localPosition = pos;
}
public void OnEndDrag(PointerEventData eventData)
{
if (!dashBoardDrag)
DragObjectInternal.transform.SetSiblingIndex(baseSibling);
if (OnCommand != null) OnCommand(this, new UIDraggerEventArg(DragObjectInternal.anchoredPosition));
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 39ca07fff5ce32c47b031fa8b6db989d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -7,6 +7,7 @@ using Newtonsoft.Json;
using System.Text;
using WI;
using System.Linq;
using UnityEngine.Networking;
/// <summary>
/// Option.ini
@@ -53,6 +54,8 @@ namespace CHN
public class HTTPRequester : Protocol, ISingle, IOptionable
{
public Action<MachineKPIData> onMachineKPIData;
public Action<WorkConditionFacilityData> onWorkConditionsfacilityData;
public Action<WorkConditionsData> onSendWorkConditionsData;
[OptionSection]
string httpSetting;
@@ -63,9 +66,23 @@ namespace CHN
[OptionKey]
string kpiAPI = "/api/usp_ppmr020/list/facilityKpi";
public string testAPIKey = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MywiZW1haWwiOiJ1dmMiLCJncm91cElkIjoyLCJncm91cENvZGUiOiJjaHVuaWxlbmciLCJyb2xlIjoiVGVuYW50QWRtaW4iLCJuYW1lIjoi7Jyg67mE7JSoIiwibGljZW5zZSI6ImJ1c2luZXNzIiwicGhvbmUiOiIiLCJpYXQiOjE3NDA1MzY0NzUsImV4cCI6NDg5NDEzNjQ3NX0.hr4D0bOA4K09Vhp12itiJgd-nVDQ3VZO8D7MVP5Ltw0";
public string testHttpServer = "http://106.247.236.204:8863";
public string facilityAPI = "/api/workConditionAnalysis/facilityCode";
public string workingConditionsAPI = "/api/workConditionAnalysis/analyze";
public string workingTimeAPI = "/api/workTimeAnalysis/analyze";
public string startDate;
public string endDate;
public WorkConditionFacilityData workConditionFacilityData;
public WorkConditionsData workConditionsData;
public void Start()
{
HTTPConnect();
StartCoroutine(HTTPWebRequest());
}
public void HTTPConnect()
{
@@ -110,7 +127,71 @@ namespace CHN
break;
}
}
IEnumerator HTTPWebRequest()
{
var path = testHttpServer + facilityAPI;
var query = $"?startDate={startDate}&endDate={endDate}";
string url = path + query;
UnityWebRequest www = UnityWebRequest.Get(url);
www.SetRequestHeader("access-token", testAPIKey);
yield return www.SendWebRequest();
if (www.error == null)
{
var payload = Encoding.UTF8.GetString(www.downloadHandler.data);
var response = JsonConvert.DeserializeObject<WorkConditionFacilityData>(payload);
workConditionFacilityData = response;
onWorkConditionsfacilityData?.Invoke(workConditionFacilityData);
}
else
{
Debug.Log(www.error);
}
}
public void SearchWorkConditions(string startDate, string endDate, string MCHCD, string WO)
{
var WorkConditionRequest = new WorkConditionsRequestBody
{
startDate = startDate,
endDate = endDate,
MCHCD = MCHCD,
WO = WO
};
var path = testHttpServer + workingConditionsAPI;
var json = JsonUtility.ToJson(WorkConditionRequest);
StopAllCoroutines();
StartCoroutine(WorkConditionsPost(path, json));
}
IEnumerator WorkConditionsPost(string url, string jsonData)
{
var request = new UnityWebRequest(url, "POST");
byte[] bodyRaw = new UTF8Encoding().GetBytes(jsonData);
request.uploadHandler = new UploadHandlerRaw(bodyRaw);
request.downloadHandler = new DownloadHandlerBuffer();
request.SetRequestHeader("access-token", apiKey);
request.SetRequestHeader("Content-Type", "application/json");
yield return request.SendWebRequest();
if (request.result == UnityWebRequest.Result.Success)
{
var payload = Encoding.UTF8.GetString(request.downloadHandler.data);
var response = JsonConvert.DeserializeObject<WorkConditionsData>(payload);
workConditionsData = response;
onSendWorkConditionsData?.Invoke(workConditionsData);
}
}
}
}

View File

@@ -0,0 +1,149 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using WI;
using System.Windows.Forms;
using RenderHeads.Media.AVProMovieCapture;
using System.IO;
public class Panel_ToolBar : PanelBase
{
private UnityEngine.UI.Button Button_TopView;
private UnityEngine.UI.Button Button_QuarterView;
private UnityEngine.UI.Button Button_SholuderView;
private UnityEngine.UI.Button Button_DashBoard;
private UnityEngine.UI.Button Button_CustomView;
private UnityEngine.UI.Button Button_Minimap;
private UnityEngine.UI.Button Button_Record;
private UnityEngine.UI.Image Image_Record_Play;
private UnityEngine.UI.Button Button_Capture;
private UnityEngine.UI.Button Button_InnerWall;
private CaptureBase capture;
private SaveFileDialog record_saveFileDialog;
private SaveFileDialog capture_saveFileDialog;
public override void AfterAwake()
{
Button_TopView.onClick.AddListener(OnClickTopView);
Button_QuarterView.onClick.AddListener(OnClickQuaterView);
Button_SholuderView.onClick.AddListener(OnClickShoulderView);
Button_DashBoard.onClick.AddListener(OnClickDashBoard);
Button_CustomView.onClick.AddListener(OnClickCustomView);
Button_Minimap.onClick.AddListener(OnClickMinimap);
Button_Record.onClick.AddListener(OnClickRecord);
Button_Capture.onClick.AddListener(OnClickCapture);
Button_InnerWall.onClick.AddListener(OnClickInnerWall);
RecordSetting();
CaptureSetting();
}
private void RecordSetting()
{
record_saveFileDialog = new();
var filePath = Path.GetFullPath(System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyVideos));
record_saveFileDialog.InitialDirectory = filePath;
record_saveFileDialog.Filter = "mp4 files (*.mp4) |*.mp4|All files (*.*)|*.*";
capture = GameObject.FindObjectOfType<CaptureBase>();
capture.CameraRenderResolution = CaptureBase.Resolution.Custom;
capture.CompletedFileWritingAction += OnCompleted;
}
private void CaptureSetting()
{
capture_saveFileDialog = new();
var filePath = Path.GetFullPath(System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyPictures));
capture_saveFileDialog.InitialDirectory = filePath;
capture_saveFileDialog.Filter = "jpg files (*.jpg) |*.jpg|png files (*.png) |*.jpg|All files (*.*)|*.*";
}
private void OnCompleted(FileWritingHandler handler)
{
var path = handler.FinalPath;
if (record_saveFileDialog.ShowDialog() == DialogResult.OK)
{
File.Move(path, record_saveFileDialog.FileName);
}
else
{
File.Delete(path);
}
}
private void OnClickInnerWall()
{
Debug.Log("³»º®");
}
private void OnClickCapture()
{
if (record_saveFileDialog.ShowDialog() == DialogResult.OK)
{
ScreenCapture.CaptureScreenshot(record_saveFileDialog.FileName);
}
}
private bool isRecordClick = false;
private void OnClickRecord()
{
isRecordClick = !isRecordClick;
if (isRecordClick)
{
StartCoroutine(PlayRecord());
capture.CameraRenderCustomResolution = new Vector2(UnityEngine.Screen.width, UnityEngine.Screen.height);
capture.StartCapture();
}
else
{
StopAllCoroutines();
capture.StopCapture();
}
}
IEnumerator PlayRecord()
{
this.Image_Record_Play.gameObject.SetActive(false);
//Button_Record.image.color = isRecordClick ? ColorUtil.FromHex("#32A3FF") : ColorUtil.FromHex("FFFFFF");
while (isRecordClick)
{
this.Image_Record_Play.gameObject.SetActive(true);
yield return new WaitForSeconds(0.5f);
this.Image_Record_Play.gameObject.SetActive(false);
yield return new WaitForSeconds(0.5f);
}
}
private void OnClickMinimap()
{
Debug.Log("MiniMap");
}
private void OnClickCustomView()
{
Debug.Log("CustomView");
}
private void OnClickDashBoard()
{
Debug.Log("DashBorad");
}
private void OnClickShoulderView()
{
Debug.Log("ShoulderView");
}
private void OnClickQuaterView()
{
Debug.Log("QuaterView");
}
private void OnClickTopView()
{
Debug.Log("TopView");
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 24c56e9c31ced0840b50aeeb35b59a66
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,19 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using WI;
using TMPro;
public class UI_DateTime : UIBase
{
public TMP_Text dateTime;
public override void AfterAwake()
{
dateTime = GetComponent<TMP_Text>();
}
public void SetDateTime(string time)
{
dateTime.SetText(time);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d7e5d91679fa05f4c8840de56676fa6f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,93 @@
using ChartAndGraph;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.EventSystems;
using WI;
using TMPro;
using static ChartAndGraph.GraphChartBase;
public class UI_GraphChart : UIBase, IPointerClickHandler
{
public GraphChart Graph;
public UI_DateTime prf_dateTime;
public RectTransform Content_DateTime;
private UI_GraphChartData chartDetailData;
public int index;
public string graphName;
public bool isMainChart;
public Action<string> onClickChart;
private List<float> graphChartData = new List<float>();
private List<string> graphDateTimeData = new List<string>();
private TextMeshProUGUI MinValue;
private TextMeshProUGUI MaxValue;
private TextMeshProUGUI AveValue;
private float min;
private float max;
private float ave;
public override void AfterAwake()
{
Graph = GetComponentInChildren<GraphChart>();
prf_dateTime = Resources.Load<UI_DateTime>("Prefabs/UI/PRF_UI_DateTime");
chartDetailData = FindSingle<UI_GraphChartData>();
}
public void OnPointerClick(PointerEventData eventData)
{
if (!isMainChart)
{
onClickChart?.Invoke(graphName);
}
}
public void OnClickItem(GraphEventArgs args)
{
chartDetailData.SetData(graphName, graphChartData[args.Index], graphDateTimeData[args.Index], args.Position);
}
public void SetChartLabels(List<string> labels)
{
for (int i = 0; i < labels.Count; i++)
{
var date = Instantiate(prf_dateTime, Content_DateTime);
date.SetDateTime(labels[i]);
}
}
public void SetChartData(string graphName, GraphChartData graphData)
{
this.graphName = graphName;
min = graphData.chartData.Min();
max = graphData.chartData.Max();
ave = graphData.chartData.Average();
AveValue.SetText(ave.ToString());
if (isMainChart)
{
MinValue.SetText(min.ToString());
MaxValue.SetText(max.ToString());
}
Graph.DataSource.VerticalViewSize = max * 2f;
Graph.DataSource.ClearCategory("WorkConditionsData");
Graph.DataSource.StartBatch();
for (int i = 0; i < graphData.chartData.Count; i++)
{
Graph.DataSource.AddPointToCategory("WorkConditionsData", i, graphData.chartData[i]);
graphChartData.Add(graphData.chartData[i]);
graphDateTimeData.Add(graphData.timeData[i]);
}
Graph.DataSource.EndBatch();
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6e7b0485edaec6a4eaab98d7e6f019e5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,56 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
using WI;
using UnityEngine.EventSystems;
public class UI_GraphChartData : UIBase, ISingle
{
public TextMeshProUGUI DataName;
public TextMeshProUGUI DataValue;
public TextMeshProUGUI DateTime;
public Vector3 offset;
private OrbitalController orbitalController;
public override void AfterAwake()
{
orbitalController = FindSingle<OrbitalController>();
SetActive(false);
}
public void SetData(string dataName, float dataValue, string dateTime, Vector3 pos)
{
ShowUINextToClickedUI();
DataName.SetText(dataName);
DateTime.SetText(dateTime);
float truncatedFloat = Mathf.Floor(dataValue * 10f) / 10f;
DataValue.SetText(truncatedFloat.ToString());
}
void ShowUINextToClickedUI()
{
RectTransform parentRectTransform = rectTransform.parent.GetComponent<RectTransform>();
Vector2 localPoint;
RectTransformUtility.ScreenPointToLocalPointInRectangle(parentRectTransform, Input.mousePosition, null, out localPoint);
rectTransform.localPosition = new Vector2(localPoint.x + offset.x, localPoint.y + offset.y);
gameObject.SetActive(true);
}
void Update()
{
if (Input.GetMouseButtonDown(0))
{
if (EventSystem.current.currentSelectedGameObject != null)
return;
SetActive(false);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 173ce0d43071d3b4bb732f6c28a6bd4c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,143 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using WI;
using System.Linq;
using System;
public class GraphChartData
{
public List<string> timeData = new();
public List<float> chartData = new();
public GraphChartData()
{
}
public GraphChartData(GraphChartData sampleGraph)
{
timeData = sampleGraph.timeData;
chartData = sampleGraph.chartData;
}
}
public class WorkConditionsManager : MonoBehaviour, ISingle
{
public Dictionary<string, GraphChartData> graphDatas = new Dictionary<string, GraphChartData>();
public Dictionary<string, GraphChartData> mainChartDatas = new Dictionary<string, GraphChartData>();
public Dictionary<string, GraphChartData> subChartDatas = new Dictionary<string, GraphChartData>();
public List<float> originPeakData = new();
public List<float> originTemperatureData = new();
public List<float> originHumidityData = new();
public List<float> originCycleTimeData = new();
public List<string> mainChartLabels = new List<string>();
public List<string> originChartLabels = new List<string>();
public int targetCount;
public Action<WorkConditionsData> onCompleteLoadData;
public Action<List<string>> onSendChartLabels;
public Action<Dictionary<string, GraphChartData>> onSendMainChartData;
public Action<Dictionary<string, GraphChartData>> onSendSubChartData;
public void SetWorkConditionsData(WorkConditionsData workConditionsData)
{
SetGraphChartData(workConditionsData);
}
public void SetGraphChartData(WorkConditionsData workConditionsData)
{
graphDatas.Clear();
mainChartLabels.Clear();
foreach (var row in workConditionsData.data.rows)
{
originPeakData.Add(ConvertStringToInt(row.C027));
originTemperatureData.Add(ConvertStringToInt(row.TEMP01));
originHumidityData.Add(ConvertStringToInt(row.HUMI01));
originCycleTimeData.Add(ConvertStringToInt(row.C045));
originChartLabels.Add(row._time);
}
graphDatas.Add("보압 (Peak)", DownSampleToFixedCount(originPeakData, originChartLabels, targetCount));
graphDatas.Add("주변 온도", DownSampleToFixedCount(originTemperatureData, originChartLabels, targetCount));
graphDatas.Add("주변 습도", DownSampleToFixedCount(originHumidityData, originChartLabels, targetCount));
graphDatas.Add("싸이클 타임", DownSampleToFixedCount(originCycleTimeData, originChartLabels, targetCount));
mainChartLabels.AddRange(DownSampleToFixedCount(originChartLabels, 5));
onSendChartLabels?.Invoke(mainChartLabels);
onCompleteLoadData?.Invoke(workConditionsData);
}
private int ConvertStringToInt(string stringData)
{
int.TryParse(stringData, out var result);
return result;
}
public void ChangeMainChartData(string dataName)
{
subChartDatas.Clear();
mainChartDatas.Clear();
foreach (var graphDataName in graphDatas.Keys)
{
if(graphDataName == dataName)
{
mainChartDatas.Add(graphDataName, graphDatas[graphDataName]);
}
else
{
subChartDatas.Add(graphDataName, graphDatas[graphDataName]);
}
}
onSendMainChartData?.Invoke(mainChartDatas);
onSendSubChartData?.Invoke(subChartDatas);
}
private GraphChartData DownSampleToFixedCount(List<float> chartData, List<string> dateTime, int targetCount)
{
var sampleGraph = new GraphChartData();
double interval = (double)chartData.Count / targetCount;
if (chartData.Count <= targetCount || targetCount <= 0)
{
sampleGraph.chartData.AddRange(chartData);
sampleGraph.timeData.AddRange(dateTime);
return new GraphChartData(sampleGraph);
}
for (int i = 0; i < targetCount; i++)
{
int index = (int)Math.Round(i * interval);
if (index >= chartData.Count)
{
index = chartData.Count - 1;
}
sampleGraph.chartData.Add(chartData[index]);
sampleGraph.timeData.Add(dateTime[index]);
}
return new GraphChartData(sampleGraph);
}
private List<string> DownSampleToFixedCount(List<string> dateTime, int targetCount)
{
List<string> sampledData = new List<string>();
double interval = (double)dateTime.Count / targetCount;
if (dateTime.Count <= targetCount || targetCount <= 0)
{
return new List<string>(dateTime);
}
for (int i = 0; i < targetCount; i++)
{
int index = (int)Math.Round(i * interval);
if (index >= dateTime.Count)
{
index = dateTime.Count - 1;
}
sampledData.Add(dateTime[index]);
}
return sampledData;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 99fc881999396514c939b9b44f527ab8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -34,7 +34,8 @@ public class WorkTime
public string WO;
public string _measurement;
public string C027;
public string C037;
public string C045;
public string HUMI01;
public string TEMP01;
public string C046;
public string CYCLETIME;
}