diff --git a/index.html b/index.html new file mode 100644 index 0000000..9dfdf3d --- /dev/null +++ b/index.html @@ -0,0 +1,65 @@ + + + + + Текущий статус печей + + + + + +
+
+
+ Диаграмма статуса печей +
+
+
+
+ Время клиента: +
+
+ Время сервера: +
+
+ Время синхр.: +
+ +
+ +
+ +
+ +
+
+ Выгрузка-загрузка, + Вакуумирование, + Токовая операция, + Охлаждение, + Разведение, + ВУР +
+
+ Приварка, + Плавка, + Оплав +
+
+ +
+ Тест +
+ + + + + + + +
+ + \ No newline at end of file diff --git a/scripts/index.js b/scripts/index.js new file mode 100644 index 0000000..2253e93 --- /dev/null +++ b/scripts/index.js @@ -0,0 +1,152 @@ +// Global Params +const htmlDateClient = document.getElementById("DateClient"); +const htmlDateServer = document.getElementById("DateServer"); +const htmlDateSynch = document.getElementById("DateSynch"); +const htmlErrMSG = document.getElementById("Error_Message"); +const canvas = document.getElementById("canvas"); +const ctx = canvas.getContext("2d"); +const update_button = document.getElementById("Update_Button"); + +const diagram = new Diagram(0.5, 0.5, canvas.width - 1, canvas.height - 1); +diagram.BuildDefault(); +diagram.Cycle(true); + +// Date formatting functions +const FNL = (a, b) => String(a).padStart(b, '0'); +const DateToString = (date) => `${date.getFullYear()}.${FNL(date.getMonth() + 1, 2)}.${FNL(date.getDate(), 2)} ${FNL(date.getHours(), 2)}:${FNL(date.getMinutes(), 2)}:${FNL(date.getSeconds(), 2)}`; + +let dateClient = null; +let dateServer = null; +let dateSynch = null; + +function PrintDateNow() { + const dn = new Date(); + if (dateServer && dateClient) { + dateServer.setMilliseconds(dateServer.getMilliseconds() + (dn - dateClient)); + } + dateClient = dn; + htmlDateClient.innerHTML = DateToString(dateClient); + if (dateServer) { + htmlDateServer.innerHTML = DateToString(dateServer); + } + if (dateSynch) { + htmlDateSynch.innerHTML = DateToString(dateSynch); + } + + setTimeout(PrintDateNow, 1000); +}; + +function updateDate(type, date) { + if (date instanceof Date) { + if (type === 'server') { + dateClient = null; + dateServer = date; + } else if (type === 'sync') { + dateSynch = date; + } + } else { + if (type === 'server') dateServer = null; + else if (type === 'synch') dateSynch = null; + } +}; + +function updateDateSynch(date) { + if (typeof date.getMonth === 'function') { + dateSynch = date; + } else + dateSynch = null; +}; + + +// Resize canvas +function Resize() { + const isWide = window.innerWidth > window.innerHeight; + canvas.height = isWide + ? window.innerHeight - 20 + - document.getElementById("First_Head").offsetHeight + - document.getElementById("Second_Head").offsetHeight + - document.getElementById("Third_Head").offsetHeight + : diagram.ProcCount() * 25; + canvas.width = document.getElementById("Canvas_Body").offsetWidth; + diagram.Rotate(!isWide); + diagram.RectParam(0.5, 0.5, canvas.width - 1, canvas.height - 1); + ctx.clearRect(0, 0, canvas.width, canvas.height); + diagram.Print(ctx); +}; + +window.addEventListener("load", Resize, false); +window.addEventListener("resize", Resize, false); + +// Autoprint diagram +function PrintCycle() { + diagram.Print(ctx); + setTimeout(PrintCycle, 1000); +}; +PrintCycle(); + +function handleError(message) { + htmlErrMSG.innerHTML = message; + $("#Error_Border").show(); + $("#Update_Button").show(); +}; + +// Update Status +async function UpdateStatus() { + try { + const response = await fetch('api/currcycles', { + method: 'POST' + }); + + if(!response.ok) { + throw new Error("Не удается установить соединение"); + } + + const data = await response.json(); + + if(!data.currTime) { + throw new Error("Ошибка в полученных данных: отсутствует время сервера"); + } + + updateDate('synch', new Date()); + updateDate('server', new Date(data.currTime)); + + if (!Array.isArray(data.data)) { + throw new Error("Ошибка в полученных данных: отсутствует массив данных"); + } + + const cycleMapping = { + 0: [0, -1], 1: [0, 1], 2: [1, 0], 5: [2, 0], 6: [3, 0], + 7: [4, 0], 8: [5, 3], 9: [6, 3], 10: [7, 3], 11: [8, 3], + 12: [9, 3], 14: [1, 1], 15: [2, 1], 16: [3, 1] + }; + + data.data.forEach(item => { + const idx = item.vdp - 1; + const [s, b] = cycleMapping[item.cycle] || [-1, -1]; + diagram.ChangeStatProc(idx, s, 0); + diagram.ChangeStatBlink(idx, b); + diagram.StartDate(idx, new Date(item.factStart)); + diagram.EndDate(idx, new Date(item.thinkEnd)); + }); + + diagram.Cycle(true); + diagram.Print(ctx); + } catch (error) { + handleError(error.message); + } finally { + setTimeout(UpdateStatus, 60 * 1000); + } +}; + +UpdateStatus(); + +function ConvDate(a) { + const [datePart, timePart] = a.split("T"); + const [year, month, day] = datePart.split("-"); + const [hours, minutes, seconds] = timePart.split(":"); + return new Date(year, month - 1, day, hours, minutes, seconds); +}; + +update_button.onclick = UpdateStatus; + +PrintDateNow(); diff --git a/scripts/test.js b/scripts/test.js index 8e9e7e3..5c0c491 100644 --- a/scripts/test.js +++ b/scripts/test.js @@ -266,7 +266,7 @@ but6.onclick = function () { function sendCycleData() { const url = `${window.location.origin}/api/currcycles`; fetch(url, { - method: 'POST', + method: 'POST' }) .then(response => { if (!response.ok) { diff --git a/styles/index.css b/styles/index.css new file mode 100644 index 0000000..db37901 --- /dev/null +++ b/styles/index.css @@ -0,0 +1,28 @@ +@media (min-width: 768px){ + #Main { + font-size: 25px; + } +} + +.fixed-button { + position: fixed; + bottom: 20px; + right: 20px; +} + +.alert { + display: none; +} + +.status-indicator { + display: inline-block; + margin: 0px 5px 0px 0px; + padding: 10px; +} + +.status-indicator-small { + display: inline-block; + height: 9px; + margin: 10px 5px 0px 0px; + padding: 0px 19px 0px 0px; +}