초기화

This commit is contained in:
2026-07-15 18:37:19 +09:00
commit 94abc5461d
1268 changed files with 380198 additions and 0 deletions
+365
View File
@@ -0,0 +1,365 @@
import mysql.connector
from database.connection import get_db_connection
import logging
import json
# 설비 추가
def add_equipment_to_db(equip_data):
try:
with get_db_connection() as conn:
with conn.cursor(dictionary=True) as cursor:
# DB 테이블에 만약 equipment_type 컬럼이 추가되었는지 파악
# 없을 경우 기본값을 채워 안전하게 동작
sql = """
INSERT INTO equipment (name, yarn_bobbin_count, dryer_type, power_consumption, max_cutting_speed, max_feed_speed)
VALUES (%s, %s, %s, %s, %s, %s)
"""
cursor.execute(sql, (
equip_data.get('name'),
equip_data.get('yarn_bobbin_count'),
equip_data.get('dryer_type'),
equip_data.get('power_consumption'),
equip_data.get('max_cutting_speed'),
equip_data.get('max_feed_speed')
))
conn.commit()
new_equipment_id = cursor.lastrowid
if new_equipment_id:
init_status_sql = "INSERT INTO machine_status (equipment_id, device_state, sync_state) VALUES (%s, %s, %s)"
cursor.execute(init_status_sql, (new_equipment_id, "OFFLINE", "IDLE"))
conn.commit()
return new_equipment_id
except mysql.connector.Error as err:
logging.error(f"Error adding equipment: {err}")
return None
# 설비 수정
def update_equipment_in_db(equip_data):
try:
with get_db_connection() as conn:
with conn.cursor(dictionary=True) as cursor:
sql = """
UPDATE equipment SET
name = %s,
yarn_bobbin_count = %s,
dryer_type = %s,
power_consumption = %s,
max_cutting_speed = %s,
max_feed_speed = %s
WHERE id = %s
"""
cursor.execute(sql, (
equip_data.get('name'),
equip_data.get('yarn_bobbin_count'),
equip_data.get('dryer_type'),
equip_data.get('power_consumption'),
equip_data.get('max_cutting_speed'),
equip_data.get('max_feed_speed'),
equip_data.get('id')
))
conn.commit()
return True
except mysql.connector.Error as err:
logging.error(f"Error updating equipment: {err}")
return False
# 설비 삭제
def delete_equipment_from_db(equipment_id):
try:
with get_db_connection() as conn:
with conn.cursor(dictionary=True) as cursor:
cursor.execute("DELETE FROM machine_status WHERE equipment_id = %s", (equipment_id,))
cursor.execute("DELETE FROM plan_assignments WHERE equipment_id = %s", (equipment_id,))
cursor.execute("DELETE FROM equipment WHERE id = %s", (equipment_id,))
conn.commit()
return True
except mysql.connector.Error as err:
logging.error(f"Error deleting equipment: {err}")
return False
# 모든 설비 목록 조회
def get_all_equipment_from_db():
# --- DEBUG LOG ---
print("[DB DEBUG] get_all_equipment_from_db function starts.")
# -----------------
try:
with get_db_connection() as conn:
with conn.cursor(dictionary=True) as cursor:
# machine_status 테이블과 JOIN하여 실시간 장치 상태(device_state)를 함께 조회
sql = """
SELECT e.*, ms.device_state
FROM equipment e
LEFT JOIN machine_status ms ON e.id = ms.equipment_id
"""
cursor.execute(sql)
results = cursor.fetchall()
# --- DEBUG LOG ---
print(f"[DB DEBUG] Query executed. Raw rows fetched: {len(results)}")
# -----------------
for r in results:
# device_state가 'ONLINE'이면 is_online을 True로 설정
r['is_online'] = (r.get('device_state') == 'ONLINE')
if 'equipment_type' not in r or not r['equipment_type']:
r['equipment_type'] = 'CC_MC_TYPE_A'
# 프론트엔드가 카드를 렌더링할 때 요구하는 필수 필드 보완 (방어 코드)
if 'type' not in r or not r['type']:
r['type'] = 'cutter'
if 'ip_address' not in r or not r['ip_address']:
r['ip_address'] = '127.0.0.1'
if 'line_prefix' not in r or not r['line_prefix']:
r['line_prefix'] = 'line1'
return results
except mysql.connector.Error as err:
logging.error(f"Error getting all equipment: {err}")
# --- DEBUG LOG ---
print(f"[DB DEBUG] Error fetching equipment: {err}")
# -----------------
return []
# 특정 설비 상세 정보 조회
def get_equipment_details_from_db(equipment_id):
try:
with get_db_connection() as conn:
with conn.cursor(dictionary=True) as cursor:
cursor.execute("SELECT * FROM equipment WHERE id = %s", (equipment_id,))
equipment_data = cursor.fetchone()
if not equipment_data:
return None
if 'equipment_type' not in equipment_data:
equipment_data['equipment_type'] = 'CC_MC_TYPE_A'
return {
"equipment": equipment_data
}
except mysql.connector.Error as err:
logging.error(f"Error getting equipment details: {err}")
return None
# 실시간 설비 상태 DB에 저장/업데이트 (UPSERT)
def save_to_db(data):
try:
with get_db_connection() as conn:
with conn.cursor(dictionary=True) as cursor:
sql = """
INSERT INTO machine_status (
equipment_id, timestamp, device_state, operation_mode,
yarn_sensors, dryer_states, temperatures, pump_states,
cutting_motor_is_running, cutting_motor_value,
transfer_motor_is_running, transfer_motor_value,
fan_state, door_sensors, water_level_sensor
) VALUES (
%(equipment_id)s, %(timestamp)s, %(device_state)s, %(operation_mode)s,
%(yarn_sensors)s, %(dryer_states)s, %(temperatures)s, %(pump_states)s,
%(cutting_motor_is_running)s, %(cutting_motor_value)s,
%(transfer_motor_is_running)s, %(transfer_motor_value)s,
%(fan_state)s, %(door_sensors)s, %(water_level_sensor)s
)
ON DUPLICATE KEY UPDATE
timestamp = VALUES(timestamp),
device_state = VALUES(device_state),
operation_mode = VALUES(operation_mode),
yarn_sensors = VALUES(yarn_sensors),
dryer_states = VALUES(dryer_states),
temperatures = VALUES(temperatures),
pump_states = VALUES(pump_states),
cutting_motor_is_running = VALUES(cutting_motor_is_running),
cutting_motor_value = VALUES(cutting_motor_value),
transfer_motor_is_running = VALUES(transfer_motor_is_running),
transfer_motor_value = VALUES(transfer_motor_value),
fan_state = VALUES(fan_state),
door_sensors = VALUES(door_sensors),
water_level_sensor = VALUES(water_level_sensor)
"""
params = data.copy()
for key, value in params.items():
if isinstance(value, list) or isinstance(value, dict):
params[key] = json.dumps(value)
cursor.execute(sql, params)
conn.commit()
logging.info(f"Successfully saved status for equipment_id: {data['equipment_id']}")
return True
except mysql.connector.Error as err:
logging.error(f"DB Error in save_to_db: {err}")
return False
except Exception as e:
logging.error(f"An unexpected error occurred in save_to_db: {e}")
return False
# 모든 설비의 현재 상태를 설비 정보와 JOIN하여 조회
def get_all_machine_statuses_joined():
try:
with get_db_connection() as conn:
with conn.cursor(dictionary=True) as cursor:
sql = """
SELECT
e.id as equipment_id,
e.name,
ms.timestamp,
ms.device_state,
ms.d_read_g0,
ms.d_read_g1,
ms.d_read_g2
FROM equipment e
LEFT JOIN machine_status ms ON e.id = ms.equipment_id
ORDER BY e.id
"""
cursor.execute(sql)
results = cursor.fetchall()
for r in results:
if 'equipment_type' not in r:
r['equipment_type'] = 'CC_MC_TYPE_A'
return results
except mysql.connector.Error as err:
logging.error(f"Error in get_all_machine_statuses_joined: {err}")
return []
# 특정 설비의 상세 상태를 설비 정보와 JOIN하여 조회
def get_machine_status_detail_joined(equipment_id):
try:
with get_db_connection() as conn:
with conn.cursor(dictionary=True) as cursor:
sql = """
SELECT
e.*,
ms.timestamp,
ms.device_state,
ms.sync_state,
ms.m_read_raw,
ms.m_write_raw,
ms.d_read_g0, ms.d_read_g1, ms.d_read_g2, ms.d_read_g3, ms.d_read_g4,
ms.d_read_g5, ms.d_read_g6, ms.d_read_g7, ms.d_read_g8, ms.d_read_g9,
ms.d_write_g0, ms.d_write_g1, ms.d_write_g2, ms.d_write_g3
FROM equipment e
LEFT JOIN machine_status ms ON e.id = ms.equipment_id
WHERE e.id = %s
"""
cursor.execute(sql, (equipment_id,))
result = cursor.fetchone()
if result:
if 'equipment_type' not in result:
result['equipment_type'] = 'CC_MC_TYPE_A'
# JSON 컬럼 자동 파싱 처리
for key in ["m_read_raw", "m_write_raw"]:
val = result.get(key)
if isinstance(val, str):
try:
result[key] = json.loads(val)
except json.JSONDecodeError:
logging.warning(f"Could not decode JSON for key {key}: {val}")
return result
except mysql.connector.Error as err:
logging.error(f"Error in get_machine_status_detail_joined: {err}")
return None
def update_m_write_in_db(equipment_id: int, payload: list):
"""M영역 쓰기 설정값을 machine_status의 m_write_raw JSON에 병합 업데이트합니다."""
try:
with get_db_connection() as conn:
with conn.cursor(dictionary=True) as cursor:
# 기존 데이터 가져오기
cursor.execute("SELECT m_write_raw FROM machine_status WHERE equipment_id = %s", (equipment_id,))
row = cursor.fetchone()
m_write = {}
if row and row.get("m_write_raw"):
try:
m_write = json.loads(row["m_write_raw"])
except:
pass
# 새로운 값 병합
for item in payload:
if len(item) >= 2:
bit_id = str(item[0])
val = int(item[1])
m_write[bit_id] = val
# 업데이트 수행
sql = "UPDATE machine_status SET m_write_raw = %s WHERE equipment_id = %s"
cursor.execute(sql, (json.dumps(m_write), equipment_id))
conn.commit()
return True
except Exception as e:
logging.error(f"Error in update_m_write_in_db: {e}")
return False
def update_d_write_in_db(equipment_id: int, payload: list):
"""D영역 쓰기 설정값을 machine_status의 d_write_g0~g3 개별 컬럼에 업데이트합니다."""
try:
with get_db_connection() as conn:
with conn.cursor() as cursor:
for item in payload:
if len(item) >= 2:
group_id = int(item[0])
val = float(item[1])
if 0 <= group_id <= 3:
sql = f"UPDATE machine_status SET d_write_g{group_id} = %s WHERE equipment_id = %s"
cursor.execute(sql, (val, equipment_id))
conn.commit()
return True
except Exception as e:
logging.error(f"Error in update_d_write_in_db: {e}")
return False
def save_control_command(equipment_id: int, command_id: str, cmd_type: str, requested_value: list, status: str):
"""제어 명령 요청을 생성하여 control_commands 테이블에 기록합니다."""
try:
with get_db_connection() as conn:
with conn.cursor() as cursor:
sql = """
INSERT INTO control_commands (equipment_id, command_id, type, requested_value, command_status)
VALUES (%s, %s, %s, %s, %s)
"""
cursor.execute(sql, (equipment_id, command_id, cmd_type, json.dumps(requested_value), status))
conn.commit()
return True
except Exception as e:
logging.error(f"Error in save_control_command: {e}")
return False
def update_control_command_status(command_id: str, status: str, applied_value: list = None):
"""수신된 ACK 신호나 타임아웃에 기반하여 제어 명령 상태를 업데이트합니다."""
try:
with get_db_connection() as conn:
with conn.cursor() as cursor:
if applied_value is not None:
sql = """
UPDATE control_commands
SET command_status = %s, applied_value = %s, applied_at = CURRENT_TIMESTAMP
WHERE command_id = %s
"""
cursor.execute(sql, (status, json.dumps(applied_value), command_id))
elif status == "PLC_APPLIED":
sql = """
UPDATE control_commands
SET command_status = %s, applied_value = requested_value,
applied_at = CURRENT_TIMESTAMP
WHERE command_id = %s
"""
cursor.execute(sql, (status, command_id))
elif status in ("FAILED", "TIMEOUT"):
sql = """
UPDATE control_commands
SET command_status = %s, applied_at = CURRENT_TIMESTAMP
WHERE command_id = %s
"""
cursor.execute(sql, (status, command_id))
else:
cursor.execute(
"UPDATE control_commands SET command_status = %s WHERE command_id = %s",
(status, command_id)
)
conn.commit()
return True
except Exception as e:
logging.error(f"Error in update_control_command_status: {e}")
return False