cleanup and files added
This commit is contained in:
748
qt_app_pyside1/ui/tabs/smart_intersection_tab.py
Normal file
748
qt_app_pyside1/ui/tabs/smart_intersection_tab.py
Normal file
@@ -0,0 +1,748 @@
|
||||
"""
|
||||
Smart Intersection Tab - IoT integration and traffic control management
|
||||
"""
|
||||
|
||||
from PySide6.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QGridLayout,
|
||||
QGroupBox, QLabel, QPushButton, QComboBox,
|
||||
QSlider, QProgressBar, QFrame, QSplitter,
|
||||
QScrollArea, QCheckBox, QSpinBox, QTabWidget,
|
||||
QTableWidget, QTableWidgetItem, QTextEdit,
|
||||
QDateTimeEdit, QHeaderView)
|
||||
from PySide6.QtCore import Qt, Signal, QTimer, QDateTime
|
||||
from PySide6.QtGui import QFont, QColor, QPainter, QPen, QBrush
|
||||
import json
|
||||
|
||||
class TrafficLightController(QWidget):
|
||||
"""Traffic light control widget"""
|
||||
|
||||
light_changed = Signal(str, str) # intersection_id, new_state
|
||||
|
||||
def __init__(self, intersection_id="intersection_1", parent=None):
|
||||
super().__init__(parent)
|
||||
|
||||
self.intersection_id = intersection_id
|
||||
self.current_state = "auto"
|
||||
self.current_phase = "green_ns" # north-south green
|
||||
|
||||
self._setup_ui()
|
||||
|
||||
def _setup_ui(self):
|
||||
"""Setup traffic light control UI"""
|
||||
layout = QVBoxLayout(self)
|
||||
|
||||
# Header
|
||||
header = QLabel(f"🚦 {self.intersection_id.replace('_', ' ').title()}")
|
||||
header.setFont(QFont("Segoe UI", 10, QFont.Bold))
|
||||
header.setAlignment(Qt.AlignCenter)
|
||||
layout.addWidget(header)
|
||||
|
||||
# Traffic light visualization
|
||||
lights_frame = QFrame()
|
||||
lights_frame.setFixedSize(120, 200)
|
||||
lights_frame.setStyleSheet("""
|
||||
QFrame {
|
||||
background-color: #2c3e50;
|
||||
border: 2px solid #34495e;
|
||||
border-radius: 8px;
|
||||
}
|
||||
""")
|
||||
|
||||
lights_layout = QVBoxLayout(lights_frame)
|
||||
lights_layout.setSpacing(5)
|
||||
lights_layout.setContentsMargins(10, 10, 10, 10)
|
||||
|
||||
# North-South lights
|
||||
ns_label = QLabel("N-S")
|
||||
ns_label.setStyleSheet("color: white; font-size: 8pt;")
|
||||
ns_label.setAlignment(Qt.AlignCenter)
|
||||
lights_layout.addWidget(ns_label)
|
||||
|
||||
self.ns_red = self._create_light_indicator("red", False)
|
||||
self.ns_yellow = self._create_light_indicator("yellow", False)
|
||||
self.ns_green = self._create_light_indicator("green", True)
|
||||
|
||||
lights_layout.addWidget(self.ns_red)
|
||||
lights_layout.addWidget(self.ns_yellow)
|
||||
lights_layout.addWidget(self.ns_green)
|
||||
|
||||
# East-West lights
|
||||
ew_label = QLabel("E-W")
|
||||
ew_label.setStyleSheet("color: white; font-size: 8pt;")
|
||||
ew_label.setAlignment(Qt.AlignCenter)
|
||||
lights_layout.addWidget(ew_label)
|
||||
|
||||
self.ew_red = self._create_light_indicator("red", True)
|
||||
self.ew_yellow = self._create_light_indicator("yellow", False)
|
||||
self.ew_green = self._create_light_indicator("green", False)
|
||||
|
||||
lights_layout.addWidget(self.ew_red)
|
||||
lights_layout.addWidget(self.ew_yellow)
|
||||
lights_layout.addWidget(self.ew_green)
|
||||
|
||||
layout.addWidget(lights_frame, 0, Qt.AlignCenter)
|
||||
|
||||
# Control buttons
|
||||
controls_layout = QVBoxLayout()
|
||||
|
||||
self.auto_btn = QPushButton("🤖 Auto")
|
||||
self.auto_btn.setCheckable(True)
|
||||
self.auto_btn.setChecked(True)
|
||||
self.auto_btn.clicked.connect(lambda: self._set_mode("auto"))
|
||||
controls_layout.addWidget(self.auto_btn)
|
||||
|
||||
self.manual_btn = QPushButton("👤 Manual")
|
||||
self.manual_btn.setCheckable(True)
|
||||
self.manual_btn.clicked.connect(lambda: self._set_mode("manual"))
|
||||
controls_layout.addWidget(self.manual_btn)
|
||||
|
||||
self.emergency_btn = QPushButton("🚨 Emergency")
|
||||
self.emergency_btn.setStyleSheet("""
|
||||
QPushButton {
|
||||
background-color: #e74c3c;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
}
|
||||
QPushButton:hover {
|
||||
background-color: #c0392b;
|
||||
}
|
||||
""")
|
||||
self.emergency_btn.clicked.connect(lambda: self._set_mode("emergency"))
|
||||
controls_layout.addWidget(self.emergency_btn)
|
||||
|
||||
layout.addLayout(controls_layout)
|
||||
|
||||
# Status
|
||||
self.status_label = QLabel("Status: Auto Mode")
|
||||
self.status_label.setStyleSheet("font-size: 8pt; color: #27ae60;")
|
||||
self.status_label.setAlignment(Qt.AlignCenter)
|
||||
layout.addWidget(self.status_label)
|
||||
|
||||
def _create_light_indicator(self, color, active=False):
|
||||
"""Create a traffic light indicator"""
|
||||
light = QLabel()
|
||||
light.setFixedSize(20, 20)
|
||||
light.setStyleSheet(f"""
|
||||
QLabel {{
|
||||
background-color: {'#' + color if active else '#2c3e50'};
|
||||
border: 1px solid #34495e;
|
||||
border-radius: 10px;
|
||||
opacity: {'1.0' if active else '0.3'};
|
||||
}}
|
||||
""")
|
||||
return light
|
||||
|
||||
def _set_mode(self, mode):
|
||||
"""Set traffic light control mode"""
|
||||
self.current_state = mode
|
||||
|
||||
# Update button states
|
||||
self.auto_btn.setChecked(mode == "auto")
|
||||
self.manual_btn.setChecked(mode == "manual")
|
||||
|
||||
# Update status
|
||||
status_colors = {
|
||||
"auto": "#27ae60",
|
||||
"manual": "#f39c12",
|
||||
"emergency": "#e74c3c"
|
||||
}
|
||||
|
||||
self.status_label.setText(f"Status: {mode.title()} Mode")
|
||||
self.status_label.setStyleSheet(f"font-size: 8pt; color: {status_colors.get(mode, '#95a5a6')};")
|
||||
|
||||
# Emit signal
|
||||
self.light_changed.emit(self.intersection_id, mode)
|
||||
|
||||
print(f"🚦 {self.intersection_id} set to {mode} mode")
|
||||
|
||||
class IoTDeviceWidget(QFrame):
|
||||
"""IoT device status widget"""
|
||||
|
||||
def __init__(self, device_id, device_type, status="online", parent=None):
|
||||
super().__init__(parent)
|
||||
|
||||
self.device_id = device_id
|
||||
self.device_type = device_type
|
||||
self.status = status
|
||||
|
||||
self.setFixedSize(150, 80)
|
||||
self._setup_ui()
|
||||
self._apply_style()
|
||||
|
||||
def _setup_ui(self):
|
||||
"""Setup IoT device widget UI"""
|
||||
layout = QVBoxLayout(self)
|
||||
layout.setContentsMargins(8, 6, 8, 6)
|
||||
|
||||
# Device header
|
||||
header_layout = QHBoxLayout()
|
||||
|
||||
# Device icon
|
||||
icons = {
|
||||
"camera": "📷",
|
||||
"sensor": "📡",
|
||||
"controller": "🎛️",
|
||||
"display": "📺",
|
||||
"gateway": "🌐"
|
||||
}
|
||||
|
||||
icon_label = QLabel(icons.get(self.device_type, "📟"))
|
||||
icon_label.setFont(QFont("Arial", 14))
|
||||
header_layout.addWidget(icon_label)
|
||||
|
||||
# Device name
|
||||
name_label = QLabel(self.device_id.replace('_', ' ').title())
|
||||
name_label.setFont(QFont("Segoe UI", 8, QFont.Bold))
|
||||
header_layout.addWidget(name_label)
|
||||
|
||||
header_layout.addStretch()
|
||||
|
||||
# Status indicator
|
||||
self.status_indicator = QLabel("●")
|
||||
self.status_indicator.setFont(QFont("Arial", 10))
|
||||
header_layout.addWidget(self.status_indicator)
|
||||
|
||||
layout.addLayout(header_layout)
|
||||
|
||||
# Device info
|
||||
info_layout = QVBoxLayout()
|
||||
|
||||
type_label = QLabel(f"Type: {self.device_type.title()}")
|
||||
type_label.setFont(QFont("Segoe UI", 7))
|
||||
info_layout.addWidget(type_label)
|
||||
|
||||
self.status_label = QLabel(f"Status: {self.status.title()}")
|
||||
self.status_label.setFont(QFont("Segoe UI", 7))
|
||||
info_layout.addWidget(self.status_label)
|
||||
|
||||
layout.addLayout(info_layout)
|
||||
|
||||
self._update_status_display()
|
||||
|
||||
def _apply_style(self):
|
||||
"""Apply device widget styling"""
|
||||
self.setStyleSheet("""
|
||||
QFrame {
|
||||
background-color: white;
|
||||
border: 1px solid #e1e8ed;
|
||||
border-radius: 6px;
|
||||
margin: 2px;
|
||||
}
|
||||
QFrame:hover {
|
||||
border-color: #3498db;
|
||||
}
|
||||
""")
|
||||
|
||||
def _update_status_display(self):
|
||||
"""Update status indicator colors"""
|
||||
colors = {
|
||||
"online": "#27ae60",
|
||||
"offline": "#e74c3c",
|
||||
"warning": "#f39c12",
|
||||
"error": "#c0392b"
|
||||
}
|
||||
|
||||
color = colors.get(self.status, "#95a5a6")
|
||||
self.status_indicator.setStyleSheet(f"color: {color};")
|
||||
self.status_label.setText(f"Status: {self.status.title()}")
|
||||
|
||||
def set_status(self, status):
|
||||
"""Update device status"""
|
||||
self.status = status
|
||||
self._update_status_display()
|
||||
|
||||
class SmartIntersectionTab(QWidget):
|
||||
"""
|
||||
Smart Intersection Tab for IoT integration and traffic control
|
||||
|
||||
Features:
|
||||
- Traffic light control and monitoring
|
||||
- IoT device management
|
||||
- Real-time traffic flow optimization
|
||||
- Emergency response coordination
|
||||
- Data analytics and reporting
|
||||
- System integration dashboard
|
||||
"""
|
||||
|
||||
# Signals
|
||||
traffic_control_changed = Signal(dict)
|
||||
iot_device_updated = Signal(str, str)
|
||||
emergency_activated = Signal(str)
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
|
||||
self.iot_devices = {}
|
||||
self.traffic_controllers = {}
|
||||
self.intersection_data = {}
|
||||
|
||||
self._setup_ui()
|
||||
|
||||
# Timer for real-time updates
|
||||
self.update_timer = QTimer()
|
||||
self.update_timer.timeout.connect(self._update_intersection_data)
|
||||
self.update_timer.start(2000) # Update every 2 seconds
|
||||
|
||||
print("🌉 Smart Intersection Tab initialized")
|
||||
|
||||
def _setup_ui(self):
|
||||
"""Setup the smart intersection UI"""
|
||||
layout = QVBoxLayout(self)
|
||||
|
||||
# Header with system overview
|
||||
header = self._create_header()
|
||||
layout.addWidget(header)
|
||||
|
||||
# Main content splitter
|
||||
main_splitter = QSplitter(Qt.Horizontal)
|
||||
layout.addWidget(main_splitter)
|
||||
|
||||
# Left panel - Traffic control
|
||||
left_panel = self._create_traffic_control_panel()
|
||||
main_splitter.addWidget(left_panel)
|
||||
|
||||
# Right panel - IoT devices and analytics
|
||||
right_panel = self._create_iot_panel()
|
||||
main_splitter.addWidget(right_panel)
|
||||
|
||||
# Set splitter proportions
|
||||
main_splitter.setSizes([500, 500])
|
||||
|
||||
def _create_header(self):
|
||||
"""Create header with intersection overview"""
|
||||
header = QFrame()
|
||||
header.setFixedHeight(80)
|
||||
header.setStyleSheet("""
|
||||
QFrame {
|
||||
background-color: #16a085;
|
||||
border-radius: 8px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
""")
|
||||
|
||||
layout = QHBoxLayout(header)
|
||||
layout.setContentsMargins(20, 10, 20, 10)
|
||||
|
||||
# Title section
|
||||
title_layout = QVBoxLayout()
|
||||
|
||||
title = QLabel("🌉 Smart Intersection Control Center")
|
||||
title.setFont(QFont("Segoe UI", 16, QFont.Bold))
|
||||
title.setStyleSheet("color: white;")
|
||||
title_layout.addWidget(title)
|
||||
|
||||
subtitle = QLabel("Real-time traffic optimization and IoT device management")
|
||||
subtitle.setFont(QFont("Segoe UI", 9))
|
||||
subtitle.setStyleSheet("color: #ecf0f1;")
|
||||
title_layout.addWidget(subtitle)
|
||||
|
||||
layout.addLayout(title_layout)
|
||||
|
||||
layout.addStretch()
|
||||
|
||||
# Statistics cards
|
||||
stats_layout = QHBoxLayout()
|
||||
|
||||
# Active intersections
|
||||
intersections_card = self._create_header_card("Active Intersections", "4", "#27ae60")
|
||||
stats_layout.addWidget(intersections_card)
|
||||
|
||||
# IoT devices
|
||||
devices_card = self._create_header_card("IoT Devices", "12", "#3498db")
|
||||
stats_layout.addWidget(devices_card)
|
||||
|
||||
# Traffic efficiency
|
||||
efficiency_card = self._create_header_card("Traffic Efficiency", "87%", "#f39c12")
|
||||
stats_layout.addWidget(efficiency_card)
|
||||
|
||||
layout.addLayout(stats_layout)
|
||||
|
||||
return header
|
||||
|
||||
def _create_header_card(self, title, value, color):
|
||||
"""Create a header statistics card"""
|
||||
card = QFrame()
|
||||
card.setFixedSize(120, 50)
|
||||
card.setStyleSheet(f"""
|
||||
QFrame {{
|
||||
background-color: {color};
|
||||
border-radius: 6px;
|
||||
margin: 2px;
|
||||
}}
|
||||
""")
|
||||
|
||||
layout = QVBoxLayout(card)
|
||||
layout.setContentsMargins(8, 4, 8, 4)
|
||||
|
||||
value_label = QLabel(value)
|
||||
value_label.setFont(QFont("Segoe UI", 14, QFont.Bold))
|
||||
value_label.setStyleSheet("color: white;")
|
||||
value_label.setAlignment(Qt.AlignCenter)
|
||||
layout.addWidget(value_label)
|
||||
|
||||
title_label = QLabel(title)
|
||||
title_label.setFont(QFont("Segoe UI", 7))
|
||||
title_label.setStyleSheet("color: white;")
|
||||
title_label.setAlignment(Qt.AlignCenter)
|
||||
layout.addWidget(title_label)
|
||||
|
||||
return card
|
||||
|
||||
def _create_traffic_control_panel(self):
|
||||
"""Create traffic control panel"""
|
||||
panel = QFrame()
|
||||
layout = QVBoxLayout(panel)
|
||||
|
||||
# Traffic control section
|
||||
control_group = QGroupBox("Traffic Light Control")
|
||||
control_layout = QVBoxLayout(control_group)
|
||||
|
||||
# Intersection controllers grid
|
||||
controllers_scroll = QScrollArea()
|
||||
controllers_widget = QWidget()
|
||||
controllers_layout = QGridLayout(controllers_widget)
|
||||
|
||||
# Create traffic light controllers
|
||||
intersections = [
|
||||
"main_oak", "5th_pine", "broadway_2nd", "market_1st"
|
||||
]
|
||||
|
||||
for i, intersection_id in enumerate(intersections):
|
||||
controller = TrafficLightController(intersection_id)
|
||||
controller.light_changed.connect(self._on_traffic_control_changed)
|
||||
self.traffic_controllers[intersection_id] = controller
|
||||
controllers_layout.addWidget(controller, i // 2, i % 2)
|
||||
|
||||
controllers_scroll.setWidget(controllers_widget)
|
||||
controllers_scroll.setMaximumHeight(450)
|
||||
control_layout.addWidget(controllers_scroll)
|
||||
|
||||
layout.addWidget(control_group)
|
||||
|
||||
# Global controls
|
||||
global_controls = self._create_global_controls()
|
||||
layout.addWidget(global_controls)
|
||||
|
||||
return panel
|
||||
|
||||
def _create_global_controls(self):
|
||||
"""Create global traffic control section"""
|
||||
section = QGroupBox("Global Controls")
|
||||
layout = QVBoxLayout(section)
|
||||
|
||||
# Emergency controls
|
||||
emergency_layout = QHBoxLayout()
|
||||
|
||||
emergency_all_btn = QPushButton("🚨 Emergency All")
|
||||
emergency_all_btn.setStyleSheet("""
|
||||
QPushButton {
|
||||
background-color: #e74c3c;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
padding: 8px;
|
||||
}
|
||||
QPushButton:hover {
|
||||
background-color: #c0392b;
|
||||
}
|
||||
""")
|
||||
emergency_all_btn.clicked.connect(self._emergency_all_intersections)
|
||||
emergency_layout.addWidget(emergency_all_btn)
|
||||
|
||||
clear_emergency_btn = QPushButton("✅ Clear Emergency")
|
||||
clear_emergency_btn.setStyleSheet("""
|
||||
QPushButton {
|
||||
background-color: #27ae60;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
padding: 8px;
|
||||
}
|
||||
QPushButton:hover {
|
||||
background-color: #229954;
|
||||
}
|
||||
""")
|
||||
clear_emergency_btn.clicked.connect(self._clear_emergency_all)
|
||||
emergency_layout.addWidget(clear_emergency_btn)
|
||||
|
||||
layout.addLayout(emergency_layout)
|
||||
|
||||
# Traffic optimization
|
||||
optimization_layout = QHBoxLayout()
|
||||
|
||||
self.adaptive_cb = QCheckBox("Adaptive Traffic Control")
|
||||
self.adaptive_cb.setChecked(True)
|
||||
self.adaptive_cb.toggled.connect(self._toggle_adaptive_control)
|
||||
optimization_layout.addWidget(self.adaptive_cb)
|
||||
|
||||
optimize_btn = QPushButton("🔄 Optimize Flow")
|
||||
optimize_btn.clicked.connect(self._optimize_traffic_flow)
|
||||
optimization_layout.addWidget(optimize_btn)
|
||||
|
||||
layout.addLayout(optimization_layout)
|
||||
|
||||
return section
|
||||
|
||||
def _create_iot_panel(self):
|
||||
"""Create IoT devices and analytics panel"""
|
||||
panel = QFrame()
|
||||
layout = QVBoxLayout(panel)
|
||||
|
||||
# IoT devices section
|
||||
iot_group = QGroupBox("IoT Device Network")
|
||||
iot_layout = QVBoxLayout(iot_group)
|
||||
|
||||
# Device grid
|
||||
devices_scroll = QScrollArea()
|
||||
devices_widget = QWidget()
|
||||
self.devices_layout = QGridLayout(devices_widget)
|
||||
|
||||
# Create sample IoT devices
|
||||
devices_data = [
|
||||
("camera_001", "camera", "online"),
|
||||
("sensor_002", "sensor", "online"),
|
||||
("controller_003", "controller", "online"),
|
||||
("display_004", "display", "warning"),
|
||||
("gateway_005", "gateway", "online"),
|
||||
("sensor_006", "sensor", "offline"),
|
||||
("camera_007", "camera", "online"),
|
||||
("controller_008", "controller", "error"),
|
||||
]
|
||||
|
||||
for i, (device_id, device_type, status) in enumerate(devices_data):
|
||||
device_widget = IoTDeviceWidget(device_id, device_type, status)
|
||||
self.iot_devices[device_id] = device_widget
|
||||
self.devices_layout.addWidget(device_widget, i // 3, i % 3)
|
||||
|
||||
devices_scroll.setWidget(devices_widget)
|
||||
devices_scroll.setMaximumHeight(200)
|
||||
iot_layout.addWidget(devices_scroll)
|
||||
|
||||
# Device controls
|
||||
device_controls = QHBoxLayout()
|
||||
|
||||
refresh_devices_btn = QPushButton("🔄 Refresh")
|
||||
refresh_devices_btn.clicked.connect(self._refresh_devices)
|
||||
device_controls.addWidget(refresh_devices_btn)
|
||||
|
||||
add_device_btn = QPushButton("➕ Add Device")
|
||||
add_device_btn.clicked.connect(self._add_device)
|
||||
device_controls.addWidget(add_device_btn)
|
||||
|
||||
device_controls.addStretch()
|
||||
|
||||
iot_layout.addLayout(device_controls)
|
||||
|
||||
layout.addWidget(iot_group)
|
||||
|
||||
# Analytics section
|
||||
analytics_group = self._create_analytics_section()
|
||||
layout.addWidget(analytics_group)
|
||||
|
||||
return panel
|
||||
|
||||
def _create_analytics_section(self):
|
||||
"""Create analytics and reporting section"""
|
||||
section = QGroupBox("Traffic Analytics")
|
||||
layout = QVBoxLayout(section)
|
||||
|
||||
# Analytics tabs
|
||||
analytics_tabs = QTabWidget()
|
||||
|
||||
# Real-time tab
|
||||
realtime_tab = QWidget()
|
||||
realtime_layout = QVBoxLayout(realtime_tab)
|
||||
|
||||
# Real-time metrics
|
||||
metrics_layout = QGridLayout()
|
||||
|
||||
metrics_layout.addWidget(QLabel("Current Traffic Volume:"), 0, 0)
|
||||
self.volume_label = QLabel("Medium")
|
||||
metrics_layout.addWidget(self.volume_label, 0, 1)
|
||||
|
||||
metrics_layout.addWidget(QLabel("Average Wait Time:"), 1, 0)
|
||||
self.wait_time_label = QLabel("45 seconds")
|
||||
metrics_layout.addWidget(self.wait_time_label, 1, 1)
|
||||
|
||||
metrics_layout.addWidget(QLabel("Traffic Efficiency:"), 2, 0)
|
||||
self.efficiency_label = QLabel("87%")
|
||||
metrics_layout.addWidget(self.efficiency_label, 2, 1)
|
||||
|
||||
metrics_layout.addWidget(QLabel("Active Violations:"), 3, 0)
|
||||
self.violations_label = QLabel("3")
|
||||
metrics_layout.addWidget(self.violations_label, 3, 1)
|
||||
|
||||
realtime_layout.addLayout(metrics_layout)
|
||||
|
||||
# Traffic flow visualization (placeholder)
|
||||
flow_frame = QFrame()
|
||||
flow_frame.setFixedHeight(100)
|
||||
flow_frame.setStyleSheet("""
|
||||
QFrame {
|
||||
background-color: #ecf0f1;
|
||||
border: 1px solid #bdc3c7;
|
||||
border-radius: 4px;
|
||||
}
|
||||
""")
|
||||
|
||||
flow_layout = QVBoxLayout(flow_frame)
|
||||
flow_label = QLabel("Traffic Flow Visualization\n(Real-time heatmap)")
|
||||
flow_label.setAlignment(Qt.AlignCenter)
|
||||
flow_label.setStyleSheet("color: #7f8c8d;")
|
||||
flow_layout.addWidget(flow_label)
|
||||
|
||||
realtime_layout.addWidget(flow_frame)
|
||||
|
||||
analytics_tabs.addTab(realtime_tab, "📊 Real-time")
|
||||
|
||||
# Historical tab
|
||||
historical_tab = QWidget()
|
||||
historical_layout = QVBoxLayout(historical_tab)
|
||||
|
||||
# Time range selector
|
||||
range_layout = QHBoxLayout()
|
||||
range_layout.addWidget(QLabel("Time Range:"))
|
||||
|
||||
time_range_combo = QComboBox()
|
||||
time_range_combo.addItems(["Last Hour", "Last 24 Hours", "Last Week", "Last Month"])
|
||||
range_layout.addWidget(time_range_combo)
|
||||
|
||||
range_layout.addStretch()
|
||||
|
||||
export_btn = QPushButton("📤 Export Report")
|
||||
export_btn.clicked.connect(self._export_analytics)
|
||||
range_layout.addWidget(export_btn)
|
||||
|
||||
historical_layout.addLayout(range_layout)
|
||||
|
||||
# Historical data display (placeholder)
|
||||
historical_frame = QFrame()
|
||||
historical_frame.setFixedHeight(120)
|
||||
historical_frame.setStyleSheet("""
|
||||
QFrame {
|
||||
background-color: #ecf0f1;
|
||||
border: 1px solid #bdc3c7;
|
||||
border-radius: 4px;
|
||||
}
|
||||
""")
|
||||
|
||||
historical_layout_frame = QVBoxLayout(historical_frame)
|
||||
historical_label = QLabel("Historical Traffic Patterns\n(Charts and trends)")
|
||||
historical_label.setAlignment(Qt.AlignCenter)
|
||||
historical_label.setStyleSheet("color: #7f8c8d;")
|
||||
historical_layout_frame.addWidget(historical_label)
|
||||
|
||||
historical_layout.addWidget(historical_frame)
|
||||
|
||||
analytics_tabs.addTab(historical_tab, "📈 Historical")
|
||||
|
||||
layout.addWidget(analytics_tabs)
|
||||
|
||||
return section
|
||||
|
||||
def _on_traffic_control_changed(self, intersection_id, mode):
|
||||
"""Handle traffic control changes"""
|
||||
control_data = {
|
||||
'intersection': intersection_id,
|
||||
'mode': mode,
|
||||
'timestamp': QDateTime.currentDateTime().toString()
|
||||
}
|
||||
|
||||
self.traffic_control_changed.emit(control_data)
|
||||
print(f"🌉 Traffic control changed: {intersection_id} -> {mode}")
|
||||
|
||||
def _emergency_all_intersections(self):
|
||||
"""Activate emergency mode for all intersections"""
|
||||
for controller in self.traffic_controllers.values():
|
||||
controller._set_mode("emergency")
|
||||
|
||||
self.emergency_activated.emit("all_intersections")
|
||||
print("🌉 Emergency mode activated for all intersections")
|
||||
|
||||
def _clear_emergency_all(self):
|
||||
"""Clear emergency mode for all intersections"""
|
||||
for controller in self.traffic_controllers.values():
|
||||
controller._set_mode("auto")
|
||||
|
||||
print("🌉 Emergency mode cleared for all intersections")
|
||||
|
||||
def _toggle_adaptive_control(self, enabled):
|
||||
"""Toggle adaptive traffic control"""
|
||||
status = "enabled" if enabled else "disabled"
|
||||
print(f"🌉 Adaptive traffic control {status}")
|
||||
|
||||
def _optimize_traffic_flow(self):
|
||||
"""Optimize traffic flow patterns"""
|
||||
print("🌉 Optimizing traffic flow patterns")
|
||||
|
||||
# Simulate optimization results
|
||||
self.efficiency_label.setText("92%")
|
||||
self.wait_time_label.setText("38 seconds")
|
||||
|
||||
def _refresh_devices(self):
|
||||
"""Refresh IoT device status"""
|
||||
import random
|
||||
|
||||
statuses = ["online", "offline", "warning", "error"]
|
||||
|
||||
for device in self.iot_devices.values():
|
||||
# Randomly update some device statuses
|
||||
if random.random() < 0.3: # 30% chance to change status
|
||||
new_status = random.choice(statuses)
|
||||
device.set_status(new_status)
|
||||
|
||||
print("🌉 IoT devices refreshed")
|
||||
|
||||
def _add_device(self):
|
||||
"""Add new IoT device"""
|
||||
# Simulate adding a new device
|
||||
device_count = len(self.iot_devices) + 1
|
||||
device_id = f"device_{device_count:03d}"
|
||||
device_type = "sensor"
|
||||
|
||||
device_widget = IoTDeviceWidget(device_id, device_type, "online")
|
||||
self.iot_devices[device_id] = device_widget
|
||||
|
||||
# Add to grid
|
||||
row = (len(self.iot_devices) - 1) // 3
|
||||
col = (len(self.iot_devices) - 1) % 3
|
||||
self.devices_layout.addWidget(device_widget, row, col)
|
||||
|
||||
print(f"🌉 Added new IoT device: {device_id}")
|
||||
|
||||
def _export_analytics(self):
|
||||
"""Export traffic analytics"""
|
||||
print("🌉 Exporting traffic analytics")
|
||||
|
||||
def _update_intersection_data(self):
|
||||
"""Update real-time intersection data"""
|
||||
import random
|
||||
|
||||
# Simulate real-time data updates
|
||||
volumes = ["Low", "Medium", "High"]
|
||||
self.volume_label.setText(random.choice(volumes))
|
||||
|
||||
wait_time = random.randint(30, 60)
|
||||
self.wait_time_label.setText(f"{wait_time} seconds")
|
||||
|
||||
efficiency = random.randint(80, 95)
|
||||
self.efficiency_label.setText(f"{efficiency}%")
|
||||
|
||||
violations = random.randint(0, 5)
|
||||
self.violations_label.setText(str(violations))
|
||||
|
||||
def set_intersection_mode(self, intersection_id, mode):
|
||||
"""Set mode for specific intersection"""
|
||||
if intersection_id in self.traffic_controllers:
|
||||
self.traffic_controllers[intersection_id]._set_mode(mode)
|
||||
|
||||
def get_system_status(self):
|
||||
"""Get current system status"""
|
||||
online_devices = sum(1 for device in self.iot_devices.values()
|
||||
if device.status == "online")
|
||||
total_devices = len(self.iot_devices)
|
||||
|
||||
return {
|
||||
'intersections': len(self.traffic_controllers),
|
||||
'devices_online': online_devices,
|
||||
'devices_total': total_devices,
|
||||
'traffic_efficiency': self.efficiency_label.text(),
|
||||
'adaptive_control': self.adaptive_cb.isChecked()
|
||||
}
|
||||
Reference in New Issue
Block a user