198 lines
7.3 KiB
Python
198 lines
7.3 KiB
Python
import json
|
|
import bluetooth
|
|
import threading
|
|
from kivy.config import Config
|
|
import time
|
|
import sys
|
|
|
|
# Kivy 앱 설정
|
|
Config.set('graphics', 'fullscreen', '1')
|
|
Config.set('graphics', 'borderless', '1')
|
|
Config.set('graphics', 'resizable', '0')
|
|
Config.set('graphics', 'width', '480')
|
|
Config.set('graphics', 'height', '320')
|
|
Config.set('graphics', 'show_cursor', '0')
|
|
|
|
SERVER_MAC = '8C:E9:EE:C9:33:4D'
|
|
PORT = 5
|
|
|
|
from kivy.app import App
|
|
from kivy.uix.boxlayout import BoxLayout
|
|
from kivy.uix.gridlayout import GridLayout
|
|
from kivy.uix.label import Label
|
|
from kivy.uix.image import Image
|
|
from kivy.uix.behaviors import ButtonBehavior
|
|
from kivy.uix.button import Button
|
|
from kivy.core.window import Window
|
|
from kivy.graphics import Color, RoundedRectangle, Line
|
|
from kivy.clock import Clock
|
|
|
|
class DashboardApp(App):
|
|
def __init__(self, **kwargs):
|
|
super().__init__(**kwargs)
|
|
self.theme_mode = 'dark' # 기본 테마
|
|
|
|
def build(self):
|
|
self.client_sock = None
|
|
self.is_connected = False
|
|
self.status_label = Label(text="Connecting...", font_size=20, color=(1, 1, 0, 1))
|
|
|
|
root = BoxLayout(orientation='vertical', padding=10)
|
|
|
|
# 타이틀 바 + 테마 버튼
|
|
title_bar = BoxLayout(orientation='horizontal', size_hint_y=None, height=40)
|
|
|
|
self.title_label = Label(text="MK's GalaxyBook5 Stream Deck", font_size=25, halign='left', valign='middle')
|
|
theme_btn = Button(text='dark', size_hint_x=None, width=60)
|
|
theme_btn.bind(on_press=self.toggle_theme)
|
|
|
|
title_bar.add_widget(self.title_label)
|
|
title_bar.add_widget(theme_btn)
|
|
root.add_widget(title_bar)
|
|
|
|
grid = GridLayout(cols=4, rows=2, spacing=10, padding=5)
|
|
|
|
try:
|
|
with open("cmders.json", "r", encoding="utf-8") as f:
|
|
self.cmders = json.load(f)
|
|
except FileNotFoundError:
|
|
self.cmders = []
|
|
print("cmders.json 파일을 찾을 수 없습니다. 기본값으로 실행합니다.")
|
|
|
|
for item in self.cmders:
|
|
icon_path = item["icons_path"] if item["icons_path"] else "icons/default.png"
|
|
cmd = item["cmd"]
|
|
btn = IconButton(icon_path=icon_path, cmd=cmd, app_instance=self)
|
|
grid.add_widget(btn)
|
|
|
|
root.add_widget(grid)
|
|
|
|
self.status_label.text = "Attempting to connect..."
|
|
self.status_label.size_hint_y = None
|
|
self.status_label.height = 30
|
|
root.add_widget(self.status_label)
|
|
|
|
print("[DEBUG] 초기 연결 시도 시작...")
|
|
self.connect_scheduled_event = Clock.schedule_once(self.connect_to_server, 1)
|
|
|
|
self.apply_theme() # 초기 테마 적용
|
|
return root
|
|
|
|
def toggle_theme(self, instance):
|
|
self.theme_mode = 'dark' if self.theme_mode == 'light' else 'light'
|
|
instance.text = 'Light' if self.theme_mode == 'light' else 'Dark'
|
|
print(f"[DEBUG] 테마 변경됨: {self.theme_mode}")
|
|
self.apply_theme()
|
|
|
|
def apply_theme(self):
|
|
if self.theme_mode == 'dark':
|
|
Window.clearcolor = (0.1, 0.1, 0.1, 1)
|
|
self.status_label.color = (0.8, 0.8, 0.2, 1)
|
|
self.title_label.color = (1, 1, 1, 1) # 밝은 글씨
|
|
else:
|
|
Window.clearcolor = (1, 1, 1, 1)
|
|
self.status_label.color = (0.2, 0.2, 0.2, 1)
|
|
self.title_label.color = (0, 0, 0, 1) # 어두운 글씨
|
|
|
|
def connect_to_server(self, dt=0):
|
|
if self.client_sock:
|
|
self.client_sock.close()
|
|
self.client_sock = None
|
|
|
|
self.is_connected = False
|
|
self.update_status_label("Connecting...")
|
|
print(f"[DEBUG] 연결 시도: MAC={SERVER_MAC}, PORT={PORT}")
|
|
|
|
try:
|
|
self.client_sock = bluetooth.BluetoothSocket(bluetooth.RFCOMM)
|
|
self.client_sock.connect((SERVER_MAC, PORT))
|
|
self.is_connected = True
|
|
self.update_status_label("Connected!")
|
|
print("[DEBUG] 연결 성공!")
|
|
Clock.schedule_interval(self.get_system_status, 5)
|
|
|
|
except bluetooth.btcommon.BluetoothError as e:
|
|
self.update_status_label(f"Connection Failed: {e}")
|
|
print(f"[DEBUG] 연결 실패: {e}. 5초 후 재시도...")
|
|
if self.client_sock:
|
|
self.client_sock.close()
|
|
self.client_sock = None
|
|
Clock.schedule_once(self.connect_to_server, 5)
|
|
|
|
def get_system_status(self, dt):
|
|
if not self.is_connected or not self.client_sock:
|
|
print("[DEBUG] 연결이 끊어져 상태 업데이트 중단.")
|
|
Clock.unschedule(self.get_system_status)
|
|
self.connect_to_server()
|
|
return
|
|
|
|
try:
|
|
self.client_sock.send("get_status".encode('utf-8'))
|
|
data = self.client_sock.recv(1024)
|
|
status_text = data.decode('utf-8')
|
|
self.update_status_label(status_text)
|
|
|
|
except bluetooth.btcommon.BluetoothError as e:
|
|
self.is_connected = False
|
|
self.update_status_label(f"Connection Lost: {e}")
|
|
print(f"[DEBUG] 통신 오류: {e}. 재연결 시도...")
|
|
Clock.unschedule(self.get_system_status)
|
|
self.connect_to_server()
|
|
|
|
def update_status_label(self, text):
|
|
self.status_label.text = text
|
|
if "Connected" in text or "CPU" in text:
|
|
self.status_label.color = (0, 1, 0, 1)
|
|
else:
|
|
self.status_label.color = (1, 0, 0, 1)
|
|
|
|
def send_command(self, command):
|
|
if not self.is_connected or not self.client_sock:
|
|
self.update_status_label("Not connected. Cannot send command.")
|
|
print("Not connected to server.")
|
|
return
|
|
|
|
try:
|
|
print(f"[DEBUG] '{command}' 명령 전송 시도...")
|
|
self.client_sock.send(command.encode('utf-8'))
|
|
data = self.client_sock.recv(1024)
|
|
response_text = data.decode('utf-8')
|
|
self.update_status_label(f"Response: {response_text}")
|
|
print(f"[DEBUG] 서버 응답: {response_text}")
|
|
|
|
except bluetooth.btcommon.BluetoothError as e:
|
|
self.is_connected = False
|
|
self.update_status_label(f"Send failed: {e}")
|
|
print(f"[DEBUG] 전송 오류: {e}. 연결 끊김...")
|
|
Clock.unschedule(self.get_system_status)
|
|
self.connect_to_server()
|
|
|
|
class IconButton(ButtonBehavior, BoxLayout):
|
|
def __init__(self, icon_path, cmd, app_instance, **kwargs):
|
|
super().__init__(orientation='vertical', **kwargs)
|
|
self.cmd = cmd
|
|
self.app_instance = app_instance
|
|
|
|
with self.canvas.before:
|
|
Color(0.5, 0.5, 0.5, 1)
|
|
self.rect = RoundedRectangle(radius=[20], pos=self.pos, size=self.size)
|
|
|
|
with self.canvas.after:
|
|
Color(0.6, 0.6, 0.6, 1)
|
|
self.border = Line(rectangle=(self.x, self.y, self.width, self.height), width=1)
|
|
|
|
self.bind(pos=self.update_graphics, size=self.update_graphics)
|
|
self.add_widget(Image(source=icon_path, size_hint=(1, 1), allow_stretch=True, keep_ratio=False))
|
|
|
|
def update_graphics(self, *args):
|
|
self.rect.pos = self.pos
|
|
self.rect.size = self.size
|
|
self.border.rectangle = (self.x, self.y, self.width, self.height)
|
|
|
|
def on_press(self):
|
|
print(f"[DEBUG] 버튼 클릭됨: {self.cmd}")
|
|
self.app_instance.send_command(self.cmd)
|
|
|
|
if __name__ == "__main__":
|
|
DashboardApp().run()
|