first commit
This commit is contained in:
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
.venv/
|
||||||
|
venv/
|
||||||
|
.env
|
||||||
BIN
SDK/jakaAPI.dll
Normal file
BIN
SDK/jakaAPI.dll
Normal file
Binary file not shown.
BIN
SDK/jakaAPI.exp
Normal file
BIN
SDK/jakaAPI.exp
Normal file
Binary file not shown.
BIN
SDK/jakaAPI.lib
Normal file
BIN
SDK/jakaAPI.lib
Normal file
Binary file not shown.
BIN
SDK/jkrc.exp
Normal file
BIN
SDK/jkrc.exp
Normal file
Binary file not shown.
BIN
SDK/jkrc.lib
Normal file
BIN
SDK/jkrc.lib
Normal file
Binary file not shown.
BIN
SDK/jkrc.pyd
Normal file
BIN
SDK/jkrc.pyd
Normal file
Binary file not shown.
3257
api_routes.py
Normal file
3257
api_routes.py
Normal file
File diff suppressed because it is too large
Load Diff
113
app.py
Normal file
113
app.py
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
from flask import Flask, render_template, request, jsonify
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
from api_routes import api_routes
|
||||||
|
import webview
|
||||||
|
from waitress import serve
|
||||||
|
|
||||||
|
if getattr(sys, 'frozen', False):
|
||||||
|
template_folder = os.path.join(sys._MEIPASS, 'templates')
|
||||||
|
app = Flask(__name__, template_folder=template_folder, static_url_path='/static')
|
||||||
|
else:
|
||||||
|
app = Flask(__name__, static_url_path='/static')
|
||||||
|
|
||||||
|
|
||||||
|
#app = Flask(__name__, static_url_path='/static')
|
||||||
|
app.register_blueprint(api_routes) # 분리된 API 라우트 등록
|
||||||
|
|
||||||
|
@app.route('/')
|
||||||
|
def index():
|
||||||
|
return render_template('layer.html')
|
||||||
|
|
||||||
|
@app.route('/progress')
|
||||||
|
def progess():
|
||||||
|
return render_template('progress.html')
|
||||||
|
|
||||||
|
@app.route('/oneLineProgress')
|
||||||
|
def oneLineProgess():
|
||||||
|
return render_template('oneLineProgress.html')
|
||||||
|
|
||||||
|
# 종료 함수
|
||||||
|
def shutdown_waitress_server():
|
||||||
|
print("Shutting down the server...")
|
||||||
|
os._exit(0)
|
||||||
|
|
||||||
|
def destroy(window):
|
||||||
|
print('Destroying window..')
|
||||||
|
window.destroy()
|
||||||
|
print('Destroyed!')
|
||||||
|
|
||||||
|
@app.route('/shutdown', methods=['POST'])
|
||||||
|
def shutdown():
|
||||||
|
destroy(test)
|
||||||
|
shutdown_waitress_server()
|
||||||
|
return 'Server shutting down'
|
||||||
|
|
||||||
|
port=5000
|
||||||
|
|
||||||
|
# if __name__ == "__main__":
|
||||||
|
# app.run(port=port, debug=True)
|
||||||
|
|
||||||
|
test = webview.create_window('Palletizing', app)
|
||||||
|
if __name__ == "__main__":
|
||||||
|
webview.start()
|
||||||
|
serve(app, host="0.0.0.0", port=port)
|
||||||
|
|
||||||
|
|
||||||
|
# from flask import Flask, render_template, request
|
||||||
|
# import sys
|
||||||
|
# import os
|
||||||
|
# from api_routes import api_routes
|
||||||
|
# import webview
|
||||||
|
# from waitress import serve
|
||||||
|
# import threading
|
||||||
|
|
||||||
|
# # Flask 애플리케이션 설정
|
||||||
|
# if getattr(sys, 'frozen', False):
|
||||||
|
# template_folder = os.path.join(sys._MEIPASS, 'templates')
|
||||||
|
# app = Flask(__name__, template_folder=template_folder, static_url_path='/static')
|
||||||
|
# else:
|
||||||
|
# app = Flask(__name__, static_url_path='/static')
|
||||||
|
|
||||||
|
# app.register_blueprint(api_routes)
|
||||||
|
|
||||||
|
# @app.route('/')
|
||||||
|
# def index():
|
||||||
|
# return render_template('layer.html')
|
||||||
|
|
||||||
|
# @app.route('/progress')
|
||||||
|
# def progress():
|
||||||
|
# return render_template('progress.html')
|
||||||
|
|
||||||
|
# @app.route('/oneLineProgress')
|
||||||
|
# def oneLineProgress():
|
||||||
|
# return render_template('oneLineProgress.html')
|
||||||
|
|
||||||
|
# # 종료 함수
|
||||||
|
# def shutdown_server():
|
||||||
|
# print("Shutting down the server...")
|
||||||
|
# os._exit(0)
|
||||||
|
|
||||||
|
# # 종료 라우트 설정
|
||||||
|
# @app.route('/shutdown', methods=['POST'])
|
||||||
|
# def shutdown():
|
||||||
|
# print("Shutdown request received.")
|
||||||
|
# destroy(test) # Webview 윈도우 종료
|
||||||
|
# shutdown_server() # Waitress 서버와 프로그램 종료
|
||||||
|
# return 'Server shutting down...'
|
||||||
|
|
||||||
|
# # Webview 윈도우 종료 함수
|
||||||
|
# def destroy(window):
|
||||||
|
# print('Destroying window..')
|
||||||
|
# window.destroy()
|
||||||
|
# print('Destroyed!')
|
||||||
|
|
||||||
|
# # 서버 실행
|
||||||
|
# port = 5000
|
||||||
|
# test = webview.create_window('Palletizing', app)
|
||||||
|
|
||||||
|
# if __name__ == "__main__":
|
||||||
|
# # Webview와 Waitress 서버를 별도 스레드로 실행
|
||||||
|
# server_thread = threading.Thread(target=lambda: serve(app, host="0.0.0.0", port=port))
|
||||||
|
# server_thread.start()
|
||||||
|
# webview.start()
|
||||||
133
socket_test.py
Normal file
133
socket_test.py
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
# import socket
|
||||||
|
# import time
|
||||||
|
|
||||||
|
# def handle_client(client_socket, client_address):
|
||||||
|
# print(f"Connected by {client_address}")
|
||||||
|
|
||||||
|
# with client_socket:
|
||||||
|
# while True:
|
||||||
|
# try:
|
||||||
|
# recv_data = client_socket.recv(1024).decode()
|
||||||
|
|
||||||
|
# if not recv_data:
|
||||||
|
# print(f"Connection closed by {client_address}")
|
||||||
|
# break
|
||||||
|
|
||||||
|
# print(f"Received from {client_address}: {recv_data}")
|
||||||
|
|
||||||
|
# if recv_data == 'get <socket_num>':
|
||||||
|
# send_data = '<socket_num><2>'
|
||||||
|
# client_socket.send(send_data.encode())
|
||||||
|
|
||||||
|
# if recv_data == 'get <socket_str>':
|
||||||
|
# send_data = '<socket_str><"b">'
|
||||||
|
# client_socket.send(send_data.encode())
|
||||||
|
|
||||||
|
# if recv_data == 'get <socket_arr>':
|
||||||
|
# send_data = '<socket_arr><[1,1,1,1,1,1]>'
|
||||||
|
# client_socket.send(send_data.encode())
|
||||||
|
|
||||||
|
# if recv_data == 'get #real#6#':
|
||||||
|
# send_data = '[2,2,2,2,2,2]'
|
||||||
|
# client_socket.send(send_data.encode())
|
||||||
|
|
||||||
|
# if recv_data == 'palletType':
|
||||||
|
# send_data = '<palletType><1>'
|
||||||
|
# client_socket.send(send_data.encode())
|
||||||
|
|
||||||
|
# except ConnectionResetError as e:
|
||||||
|
# print(f"Connection closed by {client_address}")
|
||||||
|
# break
|
||||||
|
|
||||||
|
# def start_server(host='0.0.0.0', port=12345):
|
||||||
|
# server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
|
# server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||||
|
# server_socket.bind((host, port))
|
||||||
|
# server_socket.listen()
|
||||||
|
# server_socket.settimeout(1)
|
||||||
|
# print(f"Server listening on {host}:{port}")
|
||||||
|
|
||||||
|
# try:
|
||||||
|
# while True:
|
||||||
|
# try:
|
||||||
|
# client_socket, client_address = server_socket.accept()
|
||||||
|
# handle_client(client_socket, client_address)
|
||||||
|
|
||||||
|
# except socket.timeout:
|
||||||
|
# continue
|
||||||
|
# except KeyboardInterrupt:
|
||||||
|
# print("Server shutting down...")
|
||||||
|
# finally:
|
||||||
|
# server_socket.close()
|
||||||
|
|
||||||
|
# if __name__ == "__main__":
|
||||||
|
# start_server()
|
||||||
|
import socket
|
||||||
|
import time
|
||||||
|
|
||||||
|
def handle_client(client_socket, client_address):
|
||||||
|
print(f"Connected by {client_address}")
|
||||||
|
|
||||||
|
with client_socket:
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
recv_data = client_socket.recv(1024).decode()
|
||||||
|
|
||||||
|
if not recv_data:
|
||||||
|
print(f"Connection closed by {client_address}")
|
||||||
|
return False # 클라이언트 종료 신호 반환
|
||||||
|
|
||||||
|
print(f"Received from {client_address}: {recv_data}")
|
||||||
|
|
||||||
|
if recv_data == 'get <socket_num>':
|
||||||
|
send_data = '<socket_num><2>'
|
||||||
|
client_socket.send(send_data.encode())
|
||||||
|
|
||||||
|
if recv_data == 'get <socket_str>':
|
||||||
|
send_data = '<socket_str><"b">'
|
||||||
|
client_socket.send(send_data.encode())
|
||||||
|
|
||||||
|
if recv_data == 'get <socket_arr>':
|
||||||
|
send_data = '<socket_arr><[1,1,1,1,1,1]>'
|
||||||
|
client_socket.send(send_data.encode())
|
||||||
|
|
||||||
|
if recv_data == 'get #real#6#':
|
||||||
|
send_data = '[2,2,2,2,2,2]'
|
||||||
|
client_socket.send(send_data.encode())
|
||||||
|
|
||||||
|
if recv_data == 'palletType':
|
||||||
|
send_data = '<palletType><1>'
|
||||||
|
client_socket.send(send_data.encode())
|
||||||
|
|
||||||
|
except ConnectionResetError:
|
||||||
|
print(f"Connection closed by {client_address}")
|
||||||
|
return False # 클라이언트 종료 신호 반환
|
||||||
|
return True # 클라이언트 정상 처리 완료 신호 반환
|
||||||
|
|
||||||
|
|
||||||
|
def start_server(host='0.0.0.0', port=12345):
|
||||||
|
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
|
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||||
|
server_socket.bind((host, port))
|
||||||
|
server_socket.listen()
|
||||||
|
server_socket.settimeout(1)
|
||||||
|
print(f"Server listening on {host}:{port}")
|
||||||
|
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
client_socket, client_address = server_socket.accept()
|
||||||
|
connection_active = handle_client(client_socket, client_address)
|
||||||
|
if not connection_active:
|
||||||
|
print("Client disconnected. Shutting down server...")
|
||||||
|
break # 루프 종료
|
||||||
|
except socket.timeout:
|
||||||
|
continue
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print("Server shutting down...")
|
||||||
|
finally:
|
||||||
|
server_socket.close()
|
||||||
|
print("Server socket closed.")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
start_server()
|
||||||
258
static/css/layer.css
Normal file
258
static/css/layer.css
Normal file
@@ -0,0 +1,258 @@
|
|||||||
|
.container {
|
||||||
|
margin: 20px;
|
||||||
|
border: solid 1px black;
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1.5fr 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.leftContainer {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
border: solid 1px black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.leftbuttonBox {
|
||||||
|
margin-top: 20px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.leftContainer button {
|
||||||
|
margin-top: 20px;
|
||||||
|
width: 200px;
|
||||||
|
height: 72px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.leftContainer button.selected {
|
||||||
|
color: rgb(54, 54, 54);
|
||||||
|
background-color: rgb(61, 230, 69);
|
||||||
|
}
|
||||||
|
|
||||||
|
.middleContainer {
|
||||||
|
display: grid;
|
||||||
|
grid-template-rows: auto;
|
||||||
|
border: solid 1px black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.middleBoxContainer {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.buttonBox {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
margin-top: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.buttonBox button {
|
||||||
|
padding: 15px 20px;
|
||||||
|
font-size: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.buttonWithImage {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.buttonWithImage img {
|
||||||
|
width: 140px;
|
||||||
|
height: 140px;
|
||||||
|
margin-right: 10px;
|
||||||
|
margin-left: 17px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.buttonBox button.selected {
|
||||||
|
color: rgb(54, 54, 54);
|
||||||
|
background-color: rgb(61, 230, 69);
|
||||||
|
}
|
||||||
|
|
||||||
|
.rightContainer {
|
||||||
|
display: grid;
|
||||||
|
grid-template-rows: 60px 60px 238px 60px 60px;
|
||||||
|
border: solid 1px black;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
margin: 0 20px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
padding: 10px 20px;
|
||||||
|
font-size: 32px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: rgb(54, 54, 54);
|
||||||
|
background-color: #3396ff;
|
||||||
|
border: solid 2px black;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:hover {
|
||||||
|
background-color: #0056b3;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sendPaletteInfo {
|
||||||
|
margin: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 72px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
background-color: #3396ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#startRobotButton {
|
||||||
|
margin: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 72px;
|
||||||
|
margin-bottom: 55px;
|
||||||
|
margin-top: 10px;
|
||||||
|
padding: 10px 15px;
|
||||||
|
background-color: #3396ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#startRobotButton:disabled {
|
||||||
|
background-color: gray;
|
||||||
|
color: white;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
#woodenFlatPallet:disabled {
|
||||||
|
background-color: gray;
|
||||||
|
color: white;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
#exitAppButton {
|
||||||
|
margin: 0;
|
||||||
|
width: 100%;
|
||||||
|
color: rgb(54, 54, 54);
|
||||||
|
background-color: rgb(252, 101, 101);
|
||||||
|
padding: 10px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#resetButton {
|
||||||
|
margin: 0;
|
||||||
|
width: 100%;
|
||||||
|
color: rgb(54, 54, 54);
|
||||||
|
background-color: rgb(252, 169, 101);
|
||||||
|
padding: 10px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#bookHeight {
|
||||||
|
width: 100px;
|
||||||
|
height: 40px;
|
||||||
|
margin-top: 10px;
|
||||||
|
padding: 10px;
|
||||||
|
font-size: 19px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#palletHeight {
|
||||||
|
width: 180px;
|
||||||
|
height: 40px;
|
||||||
|
margin-top: 10px;
|
||||||
|
padding: 10px;
|
||||||
|
font-size: 19px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inputContainer {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inputBox {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
width: 60px;
|
||||||
|
height: 40px;
|
||||||
|
margin-top: 10px;
|
||||||
|
padding: 10px;
|
||||||
|
font-size: 19px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#bookHeight::placeholder,
|
||||||
|
#palletHeight::placeholder {
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
#bookHeightTitle,
|
||||||
|
#palletHeightTitle {
|
||||||
|
margin-top: 20px;
|
||||||
|
font-size: 19px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
html, body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
#alert {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-color: rgba(0, 0, 0, 0.3);
|
||||||
|
position: absolute;
|
||||||
|
justify-content: center;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#alertBox{
|
||||||
|
width: 80%;
|
||||||
|
height: 50%;
|
||||||
|
background-color: white;
|
||||||
|
display: flex;
|
||||||
|
align-self: center;
|
||||||
|
border-radius: 10px;
|
||||||
|
border:2px solid black;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
#loader {
|
||||||
|
border: 16px solid #f3f3f3; /* Light gray */
|
||||||
|
border-top: 16px solid #3498db; /* Blue */
|
||||||
|
border-radius: 50%;
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
animation: spin 1s linear infinite;
|
||||||
|
margin: 10px auto; /* Center the loader */
|
||||||
|
}
|
||||||
|
|
||||||
|
#alert_msg {
|
||||||
|
font-size: 32px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: rgb(54, 54, 54);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes spin {
|
||||||
|
0% { transform: rotate(0deg); }
|
||||||
|
100% { transform: rotate(360deg); }
|
||||||
|
}
|
||||||
249
static/css/oneLineProgress.css
Normal file
249
static/css/oneLineProgress.css
Normal file
@@ -0,0 +1,249 @@
|
|||||||
|
.container {
|
||||||
|
margin: 20px;
|
||||||
|
border: solid 1px black;
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 2fr 1.5fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.leftContainer {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
border: solid 1px black;
|
||||||
|
min-height: 90vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gridContainer {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
gap: 10px;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 380px;
|
||||||
|
margin: 0 auto;
|
||||||
|
margin-top: 0px;
|
||||||
|
}
|
||||||
|
.gridItem {
|
||||||
|
width: 180px;
|
||||||
|
height: 120px;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 45px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
.gridItem.selected {
|
||||||
|
background-color: #34b800;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.gridItem.disabled {
|
||||||
|
pointer-events: none;
|
||||||
|
opacity: 0.5; /* 비활성화 상태를 시각적으로 나타내기 위해 투명도를 줄입니다 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.buttonContainer {
|
||||||
|
margin-top: 10px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.buttonContainer button {
|
||||||
|
width: 330px;
|
||||||
|
height: 72px;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.buttonContainer button:disabled {
|
||||||
|
background-color: gray;
|
||||||
|
color: white;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rightContainer {
|
||||||
|
border: solid 1px black;
|
||||||
|
display: grid;
|
||||||
|
grid-template-rows: repeat(4, 60px);
|
||||||
|
}
|
||||||
|
|
||||||
|
#finishAction {
|
||||||
|
margin: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 70px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#terminateAction {
|
||||||
|
margin: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 70px;
|
||||||
|
background-color: #ff3c00;
|
||||||
|
}
|
||||||
|
|
||||||
|
#currentLayerIndexDisplay {
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 23px;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
margin: 0 20px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
padding: 10px 20px;
|
||||||
|
font-size: 37px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: rgb(54, 54, 54);
|
||||||
|
background-color: #3396ff;
|
||||||
|
border: solid 20x black;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
#exitAppButton {
|
||||||
|
width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
height: 60px;
|
||||||
|
border-radius: 0px;
|
||||||
|
color: rgb(54, 54, 54);
|
||||||
|
background-color: rgb(252, 101, 101);
|
||||||
|
font-size: 22px;
|
||||||
|
border: solid 1px black;
|
||||||
|
}
|
||||||
|
.buttonBox {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.buttonBox button {
|
||||||
|
margin: 0;
|
||||||
|
height: 60px;
|
||||||
|
width: 50%;
|
||||||
|
border-radius: 0px;
|
||||||
|
font-size: 22px;
|
||||||
|
border: solid 1px black;
|
||||||
|
}
|
||||||
|
|
||||||
|
#stackerStartButton,
|
||||||
|
#upDownOnButton,
|
||||||
|
#leftRightOnButton {
|
||||||
|
color: rgb(54, 54, 54);
|
||||||
|
background-color: rgb(61, 230, 69);
|
||||||
|
}
|
||||||
|
|
||||||
|
#stackerStopButton,
|
||||||
|
#upDownOffButton,
|
||||||
|
#leftRightOffButton {
|
||||||
|
color: rgb(54, 54, 54);
|
||||||
|
background-color: rgb(252, 169, 101);
|
||||||
|
}
|
||||||
|
|
||||||
|
.inputContainer {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: end;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inputBox {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
width: 60px;
|
||||||
|
height: 35px;
|
||||||
|
margin-top: 10px;
|
||||||
|
padding: 10px;
|
||||||
|
font-size: 19px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
font-size: 21px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
#bookHeight {
|
||||||
|
width: 100px;
|
||||||
|
height: 35px;
|
||||||
|
margin-top: 10px;
|
||||||
|
padding: 10px;
|
||||||
|
font-size: 19px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#bookHeight::placeholder {
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
#bookHeightTitle {
|
||||||
|
margin-top: 10px;
|
||||||
|
font-size: 19px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* 팝업을 화면 중앙에 표시하기 위한 스타일 */
|
||||||
|
#bookCountPopup {
|
||||||
|
display: none; /* 기본적으로 보이지 않음 */
|
||||||
|
position: fixed;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%); /* 창을 중앙에 위치하게 함 */
|
||||||
|
width: 300px;
|
||||||
|
padding: 20px;
|
||||||
|
background-color: white;
|
||||||
|
box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.2);
|
||||||
|
border-radius: 8px;
|
||||||
|
z-index: 1001;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 배경을 어둡게 처리 */
|
||||||
|
#popupOverlay {
|
||||||
|
display: none; /* 기본적으로 보이지 않음 */
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 제출 버튼 스타일 */
|
||||||
|
#submitBookCount {
|
||||||
|
margin-top: 15px;
|
||||||
|
padding: 10px 20px;
|
||||||
|
background-color: #4CAF50;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 5px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
#submitBookCount:hover {
|
||||||
|
background-color: #45a049;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 입력 필드 스타일 */
|
||||||
|
#bookCountInput {
|
||||||
|
margin-top: 10px;
|
||||||
|
padding: 8px;
|
||||||
|
width: 80%;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
109
static/css/progress.css
Normal file
109
static/css/progress.css
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
.container {
|
||||||
|
margin: 0;
|
||||||
|
margin: 20px;
|
||||||
|
border: solid 1px black;
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 2fr 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.leftContainer {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
min-height: 90vh;
|
||||||
|
border: solid 1px black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rightContainer {
|
||||||
|
border: solid 1px black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.msg {
|
||||||
|
margin-top: 70px;
|
||||||
|
font-size: 45px;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
#finishAction {
|
||||||
|
margin-top: 20px;
|
||||||
|
width: 343px;
|
||||||
|
height: 74px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#terminateAction {
|
||||||
|
margin-top: 25px;
|
||||||
|
width: 343px;
|
||||||
|
height: 74px;
|
||||||
|
background-color: rgb(252, 101, 101);
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
margin: 0 20px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
padding: 10px 20px;
|
||||||
|
font-size: 38px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: rgb(54, 54, 54);
|
||||||
|
background-color: #3396ff;
|
||||||
|
border: solid 2px black;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-size: 30px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
font-size: 30px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rightContainer {
|
||||||
|
display: grid;
|
||||||
|
grid-template-rows: repeat(4, 60px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.buttonBox {
|
||||||
|
display: flex;
|
||||||
|
height: 70px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#exitAppButton {
|
||||||
|
width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
height: 60px;
|
||||||
|
border-radius: 0px;
|
||||||
|
color: rgb(54, 54, 54);
|
||||||
|
background-color: rgb(252, 101, 101);
|
||||||
|
font-size: 22px;
|
||||||
|
border: solid 1px black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.buttonBox button {
|
||||||
|
margin: 0;
|
||||||
|
height: 60px;
|
||||||
|
width: 16vw;
|
||||||
|
border-radius: 0px;
|
||||||
|
font-size: 22px;
|
||||||
|
border: solid 1px black;
|
||||||
|
}
|
||||||
|
|
||||||
|
#stackerStartButton,
|
||||||
|
#upDownOnButton,
|
||||||
|
#leftRightOnButton {
|
||||||
|
color: rgb(54, 54, 54);
|
||||||
|
background-color: rgb(61, 230, 69);
|
||||||
|
}
|
||||||
|
|
||||||
|
#stackerStopButton,
|
||||||
|
#upDownOffButton,
|
||||||
|
#leftRightOffButton {
|
||||||
|
color: rgb(54, 54, 54);
|
||||||
|
background-color: rgb(252, 169, 101);
|
||||||
|
}
|
||||||
BIN
static/img/iron_wheel_pallet.png
Normal file
BIN
static/img/iron_wheel_pallet.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 104 KiB |
BIN
static/img/wooden_flat_pallet.png
Normal file
BIN
static/img/wooden_flat_pallet.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 80 KiB |
BIN
static/img/wooden_wheel_pallet.png
Normal file
BIN
static/img/wooden_wheel_pallet.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 85 KiB |
275
static/js/layer.js
Normal file
275
static/js/layer.js
Normal file
@@ -0,0 +1,275 @@
|
|||||||
|
const bookCenterPosition_Wheel = [
|
||||||
|
{ x: 450.5, y: 105 },
|
||||||
|
{ x: 450.5, y: 320 },
|
||||||
|
{ x: 148.5, y: 105 },
|
||||||
|
{ x: 148.5, y: 320 },
|
||||||
|
];
|
||||||
|
const bookCenterPosition_Flat = [
|
||||||
|
{ x: 750, y: 148.5 },
|
||||||
|
{ x: 535, y: 148.5 },
|
||||||
|
{ x: 320, y: 148.5 },
|
||||||
|
{ x: 105, y: 148.5 },
|
||||||
|
{ x: 750, y: 450.5 },
|
||||||
|
{ x: 535, y: 450.5 },
|
||||||
|
{ x: 320, y: 450.5 },
|
||||||
|
{ x: 105, y: 450.5 },
|
||||||
|
];
|
||||||
|
|
||||||
|
const woodenWheelPallet = {
|
||||||
|
palletWidth: 620,
|
||||||
|
palletLength: 442,
|
||||||
|
palletHeight: 653,
|
||||||
|
bookCenterPosition_Wheel,
|
||||||
|
};
|
||||||
|
const ironWheelPallet = {
|
||||||
|
palletWidth: 620,
|
||||||
|
palletLength: 442,
|
||||||
|
palletHeight: 633,
|
||||||
|
bookCenterPosition_Wheel,
|
||||||
|
};
|
||||||
|
const woodenFlatPallet = {
|
||||||
|
palletWidth: 878,
|
||||||
|
palletLength: 638,
|
||||||
|
palletHeight: 148,
|
||||||
|
bookCenterPosition_Flat,
|
||||||
|
};
|
||||||
|
|
||||||
|
const pallets = {
|
||||||
|
woodenWheelPallet,
|
||||||
|
ironWheelPallet,
|
||||||
|
woodenFlatPallet,
|
||||||
|
};
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
|
const sendPaletteInfoButton = document.getElementById('sendPaletteInfo');
|
||||||
|
const startRobotMove = document.getElementById('startRobotButton');
|
||||||
|
const resetButton = document.getElementById('resetButton');
|
||||||
|
const exitAppButton = document.getElementById('exitAppButton');
|
||||||
|
const palletHeightInput = document.getElementById('palletHeight');
|
||||||
|
const palletHeightTitle = document.getElementById('palletHeightTitle');
|
||||||
|
|
||||||
|
const stackingButtons = document.querySelectorAll('.leftbuttonBox button');
|
||||||
|
let stackingSelected = false;
|
||||||
|
|
||||||
|
const palletButtons = document.querySelectorAll('.buttonBox button');
|
||||||
|
let selectedPalletId = null;
|
||||||
|
|
||||||
|
const woodenFlatPalletButton = document.getElementById('woodenFlatPallet');
|
||||||
|
|
||||||
|
let isStartclicked = false;
|
||||||
|
|
||||||
|
function customAlert(msg) {
|
||||||
|
const alert = document.getElementById('alert');
|
||||||
|
const text = document.getElementById('alert_msg');
|
||||||
|
if (msg) {
|
||||||
|
alert.style.display = 'flex';
|
||||||
|
text.innerText = msg;
|
||||||
|
} else {
|
||||||
|
alert.style.display = 'none';
|
||||||
|
text.innerText = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function logAction(message) {
|
||||||
|
fetch('/writelog', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'text/plain',
|
||||||
|
},
|
||||||
|
body: message,
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Failed to write log.');
|
||||||
|
}
|
||||||
|
return response.text();
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
console.log(`Log result: ${data}`);
|
||||||
|
})
|
||||||
|
.catch((error) => console.error('Error writing log:', error));
|
||||||
|
}
|
||||||
|
|
||||||
|
stackingButtons.forEach((button) => {
|
||||||
|
button.addEventListener('click', () => {
|
||||||
|
stackingButtons.forEach((btn) => btn.classList.remove('selected'));
|
||||||
|
button.classList.add('selected');
|
||||||
|
stackingSelected = true;
|
||||||
|
stackingButtons.forEach((btn) => btn.classList.remove('disabled'));
|
||||||
|
|
||||||
|
// pallet 버튼의 선택 상태를 해제
|
||||||
|
palletButtons.forEach((btn) => {
|
||||||
|
btn.classList.remove('selected');
|
||||||
|
btn.disabled = false; // pallet 버튼을 활성화 상태로 되돌림
|
||||||
|
});
|
||||||
|
selectedPalletId = null;
|
||||||
|
sendPaletteInfoButton.disabled = true;
|
||||||
|
|
||||||
|
if (button.id === 'oneLineButton') {
|
||||||
|
woodenFlatPalletButton.classList.add('disabled');
|
||||||
|
woodenFlatPalletButton.disabled = true;
|
||||||
|
palletHeightInput.style.display = 'none';
|
||||||
|
palletHeightTitle.style.display = 'none';
|
||||||
|
} else if (button.id === 'normalButton') {
|
||||||
|
woodenFlatPalletButton.classList.remove('disabled');
|
||||||
|
woodenFlatPalletButton.disabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
logAction(`FE : Stacking button ${button.id} clicked - layer.js`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
palletButtons.forEach((button) => {
|
||||||
|
button.addEventListener('click', () => {
|
||||||
|
if (!stackingSelected) {
|
||||||
|
alert('⛔ 쌓기 버튼을 먼저 선택해주세요!');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
palletButtons.forEach((btn) => btn.classList.remove('selected'));
|
||||||
|
button.classList.add('selected');
|
||||||
|
selectedPalletId = button.id;
|
||||||
|
sendPaletteInfoButton.disabled = false;
|
||||||
|
|
||||||
|
if (selectedPalletId === 'woodenFlatPallet') {
|
||||||
|
palletHeightInput.style.display = 'block';
|
||||||
|
palletHeightTitle.style.display = 'block';
|
||||||
|
} else {
|
||||||
|
palletHeightInput.style.display = 'none';
|
||||||
|
palletHeightTitle.style.display = 'none';
|
||||||
|
}
|
||||||
|
|
||||||
|
logAction(`FE : Pallet button ${button.id} clicked - layer.js`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
sendPaletteInfoButton.addEventListener('click', function () {
|
||||||
|
let palletHeight = pallets[selectedPalletId].palletHeight; // 기본 높이를 사용
|
||||||
|
if (selectedPalletId === 'woodenFlatPallet') {
|
||||||
|
palletHeight = parseFloat(palletHeightInput.value);
|
||||||
|
if (isNaN(palletHeight) || palletHeight <= 0) {
|
||||||
|
alert('⛔ 유효한 팔레트 높이를 입력해주세요!');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selectedPalletId) {
|
||||||
|
const selectedPallet = pallets[selectedPalletId];
|
||||||
|
selectedPallet.palletHeight = palletHeight; // update the pallet height
|
||||||
|
|
||||||
|
fetch('/update_pallet', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify(selectedPallet),
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Failed to send palette info.');
|
||||||
|
}
|
||||||
|
return response.text();
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
if (data == 'Success') {
|
||||||
|
startRobotMove.disabled = false;
|
||||||
|
sendPaletteInfoButton.style.backgroundColor = '#34b800';
|
||||||
|
isStartclicked = false;
|
||||||
|
logAction('FE : update_pallet api sent successfully - layer.js');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((error) => console.error('Error sending palette info:', error));
|
||||||
|
} else {
|
||||||
|
alert('⛔ 팔레트를 선택해주세요!');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
startRobotMove.addEventListener('click', function () {
|
||||||
|
logAction('FE : startRobotMove button clicked - layer.js');
|
||||||
|
|
||||||
|
if (selectedPalletId) {
|
||||||
|
let confirmResult = confirm('로봇 동작을 시작하시겠습니까?');
|
||||||
|
if (confirmResult && isStartclicked == false) {
|
||||||
|
isStartclicked = true;
|
||||||
|
|
||||||
|
const selectedPallet = pallets[selectedPalletId];
|
||||||
|
|
||||||
|
const selectedStackingButton = document.querySelector(
|
||||||
|
'.leftbuttonBox .selected'
|
||||||
|
);
|
||||||
|
|
||||||
|
let btnId = '';
|
||||||
|
|
||||||
|
if (selectedStackingButton.id === 'normalButton') {
|
||||||
|
btnId = 'normalButton';
|
||||||
|
window.location.href = '/progress';
|
||||||
|
} else if (selectedStackingButton.id === 'oneLineButton') {
|
||||||
|
btnId = 'oneLineButton';
|
||||||
|
window.location.href = '/oneLineProgress';
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = { selectedPallet, btnId, selectedPalletId };
|
||||||
|
customAlert('로봇 동작을 시작합니다...');
|
||||||
|
|
||||||
|
fetch('/robot_start', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify(data),
|
||||||
|
})
|
||||||
|
// 지금 현재 상황 (2024.10.10 문제점 : .then아래로 안내려옴 문제 해결 필요 시급)
|
||||||
|
.then((response) => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Failed to send palette info.');
|
||||||
|
}
|
||||||
|
return response.text();
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
console.log(data);
|
||||||
|
logAction(
|
||||||
|
'FE : robot_start function(server) finish successfully - layer.js'
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.catch((error) =>
|
||||||
|
console.error('Error sending palette info:', error)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
alert('⛔ 팔레트를 선택해주세요!');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
resetButton.addEventListener('click', function () {
|
||||||
|
fetch('/reset_data', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ message: 'Reset button clicked' }),
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Failed to send reset data.');
|
||||||
|
}
|
||||||
|
return response.text();
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
if (data == 'Success') {
|
||||||
|
logAction('FE : reset_data api sent successfully - layer.js');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((error) => console.error('Error sending reset data:', error));
|
||||||
|
});
|
||||||
|
|
||||||
|
exitAppButton.addEventListener('click', function () {
|
||||||
|
fetch('/shutdown', {
|
||||||
|
method: 'POST',
|
||||||
|
})
|
||||||
|
.then((response) => response.text())
|
||||||
|
.then((data) => {
|
||||||
|
console.log(data);
|
||||||
|
logAction('FE : shutdown api sent successfully - layer.js');
|
||||||
|
})
|
||||||
|
.catch((error) => console.error('Error shutting down:', error));
|
||||||
|
});
|
||||||
|
});
|
||||||
418
static/js/oneLineProgress.js
Normal file
418
static/js/oneLineProgress.js
Normal file
@@ -0,0 +1,418 @@
|
|||||||
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
|
const terminateAction = document.getElementById('terminateAction');
|
||||||
|
const finishAction = document.getElementById('finishAction');
|
||||||
|
|
||||||
|
const gridItems = document.querySelectorAll('.gridItem');
|
||||||
|
const runButton = document.getElementById('run');
|
||||||
|
const stopButton = document.getElementById('stop');
|
||||||
|
|
||||||
|
const exitAppButton = document.getElementById('exitAppButton');
|
||||||
|
|
||||||
|
const stackerStartButton = document.getElementById('stackerStartButton');
|
||||||
|
const stackerStopButton = document.getElementById('stackerStopButton');
|
||||||
|
|
||||||
|
const upDownOnButton = document.getElementById('upDownOnButton');
|
||||||
|
const upDownOffButton = document.getElementById('upDownOffButton');
|
||||||
|
|
||||||
|
const leftRightOnButton = document.getElementById('leftRightOnButton');
|
||||||
|
const leftRightOffButton = document.getElementById('leftRightOffButton');
|
||||||
|
|
||||||
|
let selectedGridId = null; // 선택된 그리드 ID
|
||||||
|
let intervalId = null; // setInterval ID
|
||||||
|
let isRunning = false; // 한줄쌓기 실행 상태
|
||||||
|
|
||||||
|
// 초기 상태 설정
|
||||||
|
stopButton.disabled = true;
|
||||||
|
runButton.disabled = true;
|
||||||
|
|
||||||
|
function logAction(message) {
|
||||||
|
fetch('/writelog', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'text/plain',
|
||||||
|
},
|
||||||
|
body: message,
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Failed to write log.');
|
||||||
|
}
|
||||||
|
return response.text();
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
console.log(`Log result: ${data}`);
|
||||||
|
})
|
||||||
|
.catch((error) => console.error('Error writing log:', error));
|
||||||
|
}
|
||||||
|
|
||||||
|
// JSON 파일에서 데이터 로드
|
||||||
|
function fetchJsonData() {
|
||||||
|
fetch('/static/json/oneLine.json')
|
||||||
|
.then((response) => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Network response was not ok');
|
||||||
|
}
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
updateGridStatus(data);
|
||||||
|
})
|
||||||
|
.catch((error) => console.error('Error loading JSON:', error));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 초기 데이터 로드
|
||||||
|
fetchJsonData();
|
||||||
|
|
||||||
|
// 그리드 상태 업데이트 함수
|
||||||
|
function updateGridStatus(data) {
|
||||||
|
const grids = ['grid1', 'grid2', 'grid3', 'grid4'];
|
||||||
|
|
||||||
|
// 그리드 비활성화 초기화
|
||||||
|
gridItems.forEach((item) => item.classList.remove('disabled'));
|
||||||
|
|
||||||
|
grids.forEach((grid) => {
|
||||||
|
if (data[grid].currentLayerHeight > 720) {
|
||||||
|
document.getElementById(grid).classList.add('disabled');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (data.grid4.currentLayerHeight > data.grid2.currentLayerHeight) {
|
||||||
|
document.getElementById('grid2').classList.add('disabled');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.grid3.currentLayerHeight > data.grid1.currentLayerHeight) {
|
||||||
|
document.getElementById('grid1').classList.add('disabled');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 선택된 그리드의 currentLayerIndex 출력
|
||||||
|
if (selectedGridId) {
|
||||||
|
const selectedGridData = data[selectedGridId];
|
||||||
|
document.getElementById(
|
||||||
|
'currentLayerIndexDisplay'
|
||||||
|
).textContent = `현재 쌓고 있는 단 : ${
|
||||||
|
selectedGridData.currentLayerIndex + 1
|
||||||
|
}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 한줄쌓기 실행 중인 경우 그리드 비활성화 유지
|
||||||
|
if (isRunning) {
|
||||||
|
toggleGridItems(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 그리드 아이템 클릭 핸들러
|
||||||
|
function handleGridItemClick(event) {
|
||||||
|
const item = event.currentTarget;
|
||||||
|
if (item.classList.contains('disabled')) {
|
||||||
|
return; // 클릭 이벤트 무시
|
||||||
|
}
|
||||||
|
gridItems.forEach((btn) => btn.classList.remove('selected'));
|
||||||
|
item.classList.add('selected');
|
||||||
|
selectedGridId = item.id;
|
||||||
|
checkRunButtonState();
|
||||||
|
}
|
||||||
|
|
||||||
|
gridItems.forEach((item) => {
|
||||||
|
item.addEventListener('click', handleGridItemClick);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 한줄쌓기 실행 버튼 클릭 핸들러
|
||||||
|
runButton.addEventListener('click', function () {
|
||||||
|
runButton.disabled = true;
|
||||||
|
stopButton.disabled = false;
|
||||||
|
isRunning = true;
|
||||||
|
toggleGridItems(true);
|
||||||
|
|
||||||
|
intervalId = setInterval(fetchJsonData, 5000);
|
||||||
|
|
||||||
|
fetch('/one_line_run', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
message: 'one_line_run',
|
||||||
|
gridId: selectedGridId, // 선택된 그리드 아이템의 ID 전송
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('one_line_run failed.');
|
||||||
|
}
|
||||||
|
return response.text();
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
console.log(data);
|
||||||
|
logAction(
|
||||||
|
'FE : one_line_run api sent successfully - oneLineProgress.js'
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.catch((error) =>
|
||||||
|
console.error('Error sending one_line_run action:', error)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 한줄쌓기 멈춤 버튼 클릭 핸들러
|
||||||
|
stopButton.addEventListener('click', function () {
|
||||||
|
runButton.disabled = false;
|
||||||
|
stopButton.disabled = true;
|
||||||
|
isRunning = false;
|
||||||
|
toggleGridItems(false);
|
||||||
|
clearGridSelection();
|
||||||
|
|
||||||
|
// JSON 데이터 주기적으로 가져오기 중지
|
||||||
|
clearInterval(intervalId);
|
||||||
|
|
||||||
|
// 멈춤 버튼 클릭 시 JSON 데이터 다시 로드
|
||||||
|
fetchJsonData();
|
||||||
|
|
||||||
|
fetch('/one_line_stop', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ message: 'one_line_stop' }),
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('one_line_stop failed.');
|
||||||
|
}
|
||||||
|
return response.text();
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
console.log(data);
|
||||||
|
logAction(
|
||||||
|
'FE : one_line_stop api sent successfully - oneLineProgress.js'
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.catch((error) =>
|
||||||
|
console.error('Error sending one_line_stop action:', error)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 한줄쌓기 실행 버튼 활성화 여부 확인 함수
|
||||||
|
function checkRunButtonState() {
|
||||||
|
const anyGridSelected = Array.from(gridItems).some((item) =>
|
||||||
|
item.classList.contains('selected')
|
||||||
|
);
|
||||||
|
|
||||||
|
runButton.disabled = !anyGridSelected;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 그리드 아이템 활성화/비활성화 함수
|
||||||
|
function toggleGridItems(disable) {
|
||||||
|
gridItems.forEach((item) => item.classList.toggle('disabled', disable));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 그리드 아이템 선택 해제 함수
|
||||||
|
function clearGridSelection() {
|
||||||
|
gridItems.forEach((item) => item.classList.remove('selected'));
|
||||||
|
checkRunButtonState(); // 선택 해제 후 버튼 상태 재확인
|
||||||
|
}
|
||||||
|
|
||||||
|
finishAction.addEventListener('click', function () {
|
||||||
|
finishAction.disabled = true;
|
||||||
|
fetch('/robot_immediately_take_book', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
immediately_take_book: 'robot_immediately_take_book',
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('immediately_take_book failed.');
|
||||||
|
}
|
||||||
|
return response.text();
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
console.log(data);
|
||||||
|
logAction(
|
||||||
|
'FE : robot_immediately_take_book api sent successfully - oneLineProgress.js'
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.catch((error) =>
|
||||||
|
console.error('Error Sending robot finish action:', error)
|
||||||
|
)
|
||||||
|
.finally(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
finishAction.disabled = false;
|
||||||
|
}, 10000);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
terminateAction.addEventListener('click', function () {
|
||||||
|
fetch('/robot_finish_action', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ action: 'robot_finish_action' }),
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Failed to send robot finish action.');
|
||||||
|
}
|
||||||
|
return response.text();
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
console.log(data);
|
||||||
|
logAction(
|
||||||
|
'FE : terminateAction api sent successfully - oneLineProgress.js'
|
||||||
|
);
|
||||||
|
|
||||||
|
window.location.href = '/';
|
||||||
|
})
|
||||||
|
.catch((error) =>
|
||||||
|
console.error('Error sending robot finish action:', error)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
exitAppButton.addEventListener('click', function () {
|
||||||
|
fetch('/shutdown', {
|
||||||
|
method: 'POST',
|
||||||
|
})
|
||||||
|
.then((response) => response.text())
|
||||||
|
.then((data) => {
|
||||||
|
console.log(data);
|
||||||
|
logAction('FE : shutdown api sent successfully - oneLineProgress.js');
|
||||||
|
})
|
||||||
|
.catch((error) => console.error('Error shutting down:', error));
|
||||||
|
});
|
||||||
|
|
||||||
|
stackerStartButton.addEventListener('click', function () {
|
||||||
|
fetch('/stacker_start', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ action: 'stacker_start' }),
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Failed to send stacker start.');
|
||||||
|
}
|
||||||
|
return response.text();
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
console.log(data);
|
||||||
|
logAction(
|
||||||
|
'FE : stacker_start api sent successfully - oneLineProgress.js'
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.catch((error) => console.error('Error sending stacker start:', error));
|
||||||
|
});
|
||||||
|
|
||||||
|
stackerStopButton.addEventListener('click', function () {
|
||||||
|
fetch('/stacker_stop', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ action: 'stacker_stop' }),
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Failed to send stacker stop.');
|
||||||
|
}
|
||||||
|
return response.text();
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
console.log(data);
|
||||||
|
logAction(
|
||||||
|
'FE : stacker_stop api sent successfully - oneLineProgress.js'
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.catch((error) => console.error('Error sending stacker stop:', error));
|
||||||
|
});
|
||||||
|
|
||||||
|
upDownOnButton.addEventListener('click', function () {
|
||||||
|
fetch('/updown_on', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ action: 'updown_on' }),
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Failed to send updown on');
|
||||||
|
}
|
||||||
|
return response.text();
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
console.log(data);
|
||||||
|
logAction('FE : updown_on api sent successfully - oneLineProgress.js');
|
||||||
|
})
|
||||||
|
.catch((error) => console.error('Error sending updown on:', error));
|
||||||
|
});
|
||||||
|
|
||||||
|
upDownOffButton.addEventListener('click', function () {
|
||||||
|
fetch('/updown_off', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ action: 'updown_off' }),
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Failed to send updown off');
|
||||||
|
}
|
||||||
|
return response.text();
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
console.log(data);
|
||||||
|
logAction('FE : updown_off api sent successfully - oneLineProgress.js');
|
||||||
|
})
|
||||||
|
.catch((error) => console.error('Error sending updown off:', error));
|
||||||
|
});
|
||||||
|
|
||||||
|
leftRightOnButton.addEventListener('click', function () {
|
||||||
|
fetch('/leftright_on', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ action: 'leftright_on' }),
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Failed to send leftright on');
|
||||||
|
}
|
||||||
|
return response.text();
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
console.log(data);
|
||||||
|
logAction(
|
||||||
|
'FE : leftright_on api sent successfully - oneLineProgress.js'
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.catch((error) => console.error('Error sending leftright on:', error));
|
||||||
|
});
|
||||||
|
|
||||||
|
leftRightOffButton.addEventListener('click', function () {
|
||||||
|
fetch('/leftright_off', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ action: 'leftright_off' }),
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Failed to send leftright off');
|
||||||
|
}
|
||||||
|
return response.text();
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
console.log(data);
|
||||||
|
logAction(
|
||||||
|
'FE : leftright_off api sent successfully - oneLineProgress.js'
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.catch((error) => console.error('Error sending leftright off:', error));
|
||||||
|
});
|
||||||
|
});
|
||||||
255
static/js/progress.js
Normal file
255
static/js/progress.js
Normal file
@@ -0,0 +1,255 @@
|
|||||||
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
|
const terminateAction = document.getElementById('terminateAction');
|
||||||
|
const finishAction = document.getElementById('finishAction');
|
||||||
|
const exitAppButton = document.getElementById('exitAppButton');
|
||||||
|
|
||||||
|
const stackerStartButton = document.getElementById('stackerStartButton');
|
||||||
|
const stackerStopButton = document.getElementById('stackerStopButton');
|
||||||
|
const upDownOnButton = document.getElementById('upDownOnButton');
|
||||||
|
const upDownOffButton = document.getElementById('upDownOffButton');
|
||||||
|
const leftRightOnButton = document.getElementById('leftRightOnButton');
|
||||||
|
const leftRightOffButton = document.getElementById('leftRightOffButton');
|
||||||
|
|
||||||
|
function logAction(message) {
|
||||||
|
fetch('/writelog', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'text/plain',
|
||||||
|
},
|
||||||
|
body: message,
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Failed to write log.');
|
||||||
|
}
|
||||||
|
return response.text();
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
console.log(`Log result: ${data}`);
|
||||||
|
})
|
||||||
|
.catch((error) => console.error('Error writing log:', error));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 인덱스 표시 업데이트 함수
|
||||||
|
function updateIndexDisplay() {
|
||||||
|
fetch('/static/json/cache.json')
|
||||||
|
.then((response) => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Network response was not ok');
|
||||||
|
}
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
document.getElementById('currentDataIndex').textContent =
|
||||||
|
data.currentDataIndex + 1;
|
||||||
|
document.getElementById('currentLayerIndex').textContent =
|
||||||
|
data.currentLayerIndex + 1;
|
||||||
|
console.log(data.currentDataIndex, data.currentLayerIndex);
|
||||||
|
})
|
||||||
|
.catch((error) => console.error('Error loading cache.json:', error));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 페이지 로드 시 초기 인덱스 표시 업데이트
|
||||||
|
updateIndexDisplay();
|
||||||
|
|
||||||
|
// 일정 시간마다 인덱스 표시 업데이트
|
||||||
|
intervalId = setInterval(updateIndexDisplay, 5000); // 5초마다 업데이트
|
||||||
|
|
||||||
|
finishAction.addEventListener('click', function () {
|
||||||
|
finishAction.disabled = true;
|
||||||
|
fetch('/robot_immediately_take_book', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
immediately_take_book: 'robot_immediately_take_book',
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('immediately_take_book failed.');
|
||||||
|
}
|
||||||
|
return response.text();
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
console.log(data);
|
||||||
|
logAction(
|
||||||
|
'FE : robot_immediately_take_book api sent successfully - progress.js'
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.catch((error) =>
|
||||||
|
console.error('Error Sending robot finish action:', error)
|
||||||
|
).finally(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
finishAction.disabled = false;
|
||||||
|
}, 10000);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
terminateAction.addEventListener('click', function () {
|
||||||
|
fetch('/robot_finish_action', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ action: 'robot_finish_action' }),
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Failed to send robot finish action.');
|
||||||
|
}
|
||||||
|
return response.text();
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
console.log(data);
|
||||||
|
clearInterval(intervalId);
|
||||||
|
logAction(
|
||||||
|
'FE : robot_finish_action api sent successfully - progress.js'
|
||||||
|
);
|
||||||
|
|
||||||
|
window.location.href = '/';
|
||||||
|
})
|
||||||
|
.catch((error) =>
|
||||||
|
console.error('Error sending robot finish action:', error)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
exitAppButton.addEventListener('click', function () {
|
||||||
|
fetch('/shutdown', {
|
||||||
|
method: 'POST',
|
||||||
|
})
|
||||||
|
.then((response) => response.text())
|
||||||
|
.then((data) => {
|
||||||
|
console.log(data);
|
||||||
|
logAction('FE : shutdown api sent successfully - progress.js');
|
||||||
|
})
|
||||||
|
.catch((error) => console.error('Error shutting down:', error));
|
||||||
|
});
|
||||||
|
|
||||||
|
stackerStartButton.addEventListener('click', function () {
|
||||||
|
fetch('/stacker_start', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ action: 'stacker_start' }),
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Failed to send stacker start.');
|
||||||
|
}
|
||||||
|
return response.text();
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
console.log(data);
|
||||||
|
logAction('FE : stacker_start api sent successfully - progress.js');
|
||||||
|
})
|
||||||
|
.catch((error) => console.error('Error sending stacker start:', error));
|
||||||
|
});
|
||||||
|
|
||||||
|
stackerStopButton.addEventListener('click', function () {
|
||||||
|
fetch('/stacker_stop', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ action: 'stacker_stop' }),
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Failed to send stacker stop.');
|
||||||
|
}
|
||||||
|
return response.text();
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
console.log(data);
|
||||||
|
logAction('FE : stacker_stop api sent successfully - progress.js');
|
||||||
|
})
|
||||||
|
.catch((error) => console.error('Error sending stacker stop:', error));
|
||||||
|
});
|
||||||
|
|
||||||
|
upDownOnButton.addEventListener('click', function () {
|
||||||
|
fetch('/updown_on', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ action: 'updown_on' }),
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Failed to send updown on');
|
||||||
|
}
|
||||||
|
return response.text();
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
console.log(data);
|
||||||
|
logAction('FE : updown_on api sent successfully - progress.js');
|
||||||
|
})
|
||||||
|
.catch((error) => console.error('Error sending updown on:', error));
|
||||||
|
});
|
||||||
|
|
||||||
|
upDownOffButton.addEventListener('click', function () {
|
||||||
|
fetch('/updown_off', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ action: 'updown_off' }),
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Failed to send updown off');
|
||||||
|
}
|
||||||
|
return response.text();
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
console.log(data);
|
||||||
|
logAction('FE : updown_off api sent successfully - progress.js');
|
||||||
|
})
|
||||||
|
.catch((error) => console.error('Error sending updown off:', error));
|
||||||
|
});
|
||||||
|
|
||||||
|
leftRightOnButton.addEventListener('click', function () {
|
||||||
|
fetch('/leftright_on', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ action: 'leftright_on' }),
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Failed to send leftright on');
|
||||||
|
}
|
||||||
|
return response.text();
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
console.log(data);
|
||||||
|
logAction('FE : leftright_on api sent successfully - progress.js');
|
||||||
|
})
|
||||||
|
.catch((error) => console.error('Error sending leftright on:', error));
|
||||||
|
});
|
||||||
|
|
||||||
|
leftRightOffButton.addEventListener('click', function () {
|
||||||
|
fetch('/leftright_off', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ action: 'leftright_off' }),
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Failed to send leftright off');
|
||||||
|
}
|
||||||
|
return response.text();
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
console.log(data);
|
||||||
|
logAction('FE : leftright_off api sent successfully - progress.js');
|
||||||
|
})
|
||||||
|
.catch((error) => console.error('Error sending leftright off:', error));
|
||||||
|
});
|
||||||
|
});
|
||||||
5
static/json/cache.json
Normal file
5
static/json/cache.json
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"currentDataIndex": 0,
|
||||||
|
"currentLayerIndex": 0,
|
||||||
|
"currentLayerHeight": 0
|
||||||
|
}
|
||||||
3
static/json/height.json
Normal file
3
static/json/height.json
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"measuredHeight": 0
|
||||||
|
}
|
||||||
22
static/json/oneLine.json
Normal file
22
static/json/oneLine.json
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"grid1": {
|
||||||
|
"currentDataIndex": 0,
|
||||||
|
"currentLayerIndex": 0,
|
||||||
|
"currentLayerHeight": 0
|
||||||
|
},
|
||||||
|
"grid2": {
|
||||||
|
"currentDataIndex": 1,
|
||||||
|
"currentLayerIndex": 0,
|
||||||
|
"currentLayerHeight": 0
|
||||||
|
},
|
||||||
|
"grid3": {
|
||||||
|
"currentDataIndex": 2,
|
||||||
|
"currentLayerIndex": 0,
|
||||||
|
"currentLayerHeight": 0
|
||||||
|
},
|
||||||
|
"grid4": {
|
||||||
|
"currentDataIndex": 3,
|
||||||
|
"currentLayerIndex": 0,
|
||||||
|
"currentLayerHeight": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
86
templates/layer.html
Normal file
86
templates/layer.html
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>레이어 관리</title>
|
||||||
|
<link rel="stylesheet" href="../static/css/layer.css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="alert">
|
||||||
|
<div id="alertBox">
|
||||||
|
<div id="loader"></div>
|
||||||
|
<span id="alert_msg"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="container">
|
||||||
|
<main>
|
||||||
|
<div class="leftContainer">
|
||||||
|
<div class="leftbuttonBox">
|
||||||
|
<button id="normalButton">일반 쌓기</button>
|
||||||
|
<button id="oneLineButton">한줄 쌓기</button>
|
||||||
|
<div class="inputContainer">
|
||||||
|
<div id="palletHeightTitle" style="display: none">
|
||||||
|
납작 팔레트 높이
|
||||||
|
</div>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
id="palletHeight"
|
||||||
|
placeholder="mm"
|
||||||
|
style="display: none"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div id="palletHeightTitle" style="display: none">
|
||||||
|
팔레트 높이
|
||||||
|
</div>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
id="palletHeight"
|
||||||
|
placeholder="mm"
|
||||||
|
style="display: none"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middleContainer">
|
||||||
|
<div class="middleBoxContainer">
|
||||||
|
<div class="buttonBox">
|
||||||
|
<div class="buttonWithImage">
|
||||||
|
<img
|
||||||
|
src="../static/img/wooden_wheel_pallet.png"
|
||||||
|
alt="나무 바퀴 팔레트"
|
||||||
|
/>
|
||||||
|
<button id="woodenWheelPallet">나무 바퀴</button>
|
||||||
|
</div>
|
||||||
|
<div class="buttonWithImage">
|
||||||
|
<img
|
||||||
|
src="../static/img/iron_wheel_pallet.png"
|
||||||
|
alt="철제 바퀴 팔레트"
|
||||||
|
/>
|
||||||
|
<button id="ironWheelPallet">철제 바퀴</button>
|
||||||
|
</div>
|
||||||
|
<div class="buttonWithImage">
|
||||||
|
<img
|
||||||
|
src="../static/img/wooden_flat_pallet.png"
|
||||||
|
alt="나무 납작 팔레트"
|
||||||
|
/>
|
||||||
|
<button id="woodenFlatPallet">나무 납작</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="rightContainer">
|
||||||
|
<button id="exitAppButton">앱 종료</button>
|
||||||
|
<button id="resetButton">데이터 초기화</button>
|
||||||
|
<div></div>
|
||||||
|
<button id="sendPaletteInfo">데이터 저장</button>
|
||||||
|
<button id="startRobotButton" disabled>로봇 동작 시작</button>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="../static/js/layer.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
55
templates/oneLineProgress.html
Normal file
55
templates/oneLineProgress.html
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>로봇 동작 중</title>
|
||||||
|
<link rel="stylesheet" href="../static/css/oneLineProgress.css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<main>
|
||||||
|
<div class="leftContainer">
|
||||||
|
<div class="gridContainer">
|
||||||
|
<div class="gridItem" id="grid2">2</div>
|
||||||
|
<div class="gridItem" id="grid4">4</div>
|
||||||
|
<div class="gridItem" id="grid1">1</div>
|
||||||
|
<div class="gridItem" id="grid3">3</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="buttonContainer">
|
||||||
|
<div id="currentLayerIndexDisplay">현재 쌓고 있는 단 :</div>
|
||||||
|
<button id="run">한줄 쌓기 실행</button>
|
||||||
|
<button id="stop">한줄 쌓기 멈춤</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="rightContainer">
|
||||||
|
<div class="buttonBox">
|
||||||
|
<button id="exitAppButton">앱 종료</button>
|
||||||
|
</div>
|
||||||
|
<div class="buttonBox">
|
||||||
|
<button id="stackerStartButton">스태커 시작</button>
|
||||||
|
<button id="stackerStopButton">스태커 정지</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="buttonBox">
|
||||||
|
<button id="upDownOnButton">올림</button>
|
||||||
|
<button id="upDownOffButton">내림</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="buttonBox">
|
||||||
|
<button id="leftRightOnButton">닫힘</button>
|
||||||
|
<button id="leftRightOffButton">열림</button>
|
||||||
|
</div>
|
||||||
|
<div class="inputContainer">
|
||||||
|
<button id="finishAction">바로 책 집어가기</button>
|
||||||
|
<button id="terminateAction">로봇 동작 종료</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
<script src="../static/js/oneLineProgress.js"></script>
|
||||||
|
</html>
|
||||||
51
templates/progress.html
Normal file
51
templates/progress.html
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>로봇 동작 중</title>
|
||||||
|
<link rel="stylesheet" href="../static/css/progress.css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<main>
|
||||||
|
<div class="leftContainer">
|
||||||
|
<div class="msg">로봇이 움직이는 중입니다.</div>
|
||||||
|
|
||||||
|
<div id="indexDisplay">
|
||||||
|
<p>
|
||||||
|
현재 <span id="currentLayerIndex">0</span>단
|
||||||
|
<span id="currentDataIndex">0</span>위치
|
||||||
|
</p>
|
||||||
|
<!-- <P>책 높이 : <span id="currentSensorHeight">0</span></P> -->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button id="finishAction">바로 책 집어가기</button>
|
||||||
|
<button id="terminateAction">로봇 동작 종료</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="rightContainer">
|
||||||
|
<div class="buttonBox">
|
||||||
|
<button id="exitAppButton">앱 종료</button>
|
||||||
|
</div>
|
||||||
|
<div class="buttonBox">
|
||||||
|
<button id="stackerStartButton">스태커 시작</button>
|
||||||
|
<button id="stackerStopButton">스태커 정지</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="buttonBox">
|
||||||
|
<button id="upDownOnButton">올림</button>
|
||||||
|
<button id="upDownOffButton">내림</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="buttonBox">
|
||||||
|
<button id="leftRightOnButton">닫힘</button>
|
||||||
|
<button id="leftRightOffButton">열림</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
<script src="../static/js/progress.js"></script>
|
||||||
|
</html>
|
||||||
Reference in New Issue
Block a user