337 lines
9.8 KiB
Python
337 lines
9.8 KiB
Python
#!/usr/bin/env python3
|
|
|
|
import sys
|
|
import socket
|
|
import json
|
|
|
|
# from PyQt6.QtCore import QLine
|
|
from PyQt6.QtWidgets import QApplication, QMainWindow, QPushButton, QLabel, QFrame, \
|
|
QVBoxLayout, QWidget, QButtonGroup, QStatusBar, QComboBox, QMenu, QSystemTrayIcon
|
|
from PyQt6.QtGui import QPixmap, QIcon, QAction
|
|
|
|
WAL_HOST = '10.0.1.11'
|
|
WAL_PORT = 9000
|
|
|
|
MODES = {
|
|
"off": 0,
|
|
"red": 1,
|
|
"green": 2,
|
|
"blue": 3,
|
|
"white": 4,
|
|
"orange": 5,
|
|
}
|
|
|
|
SPECIAL_MODES = {
|
|
"cyclone": 11,
|
|
"police": 12,
|
|
}
|
|
|
|
CUSTOM_MODES = {
|
|
"solid": 21,
|
|
"twinkle": 22,
|
|
"fade": 23,
|
|
}
|
|
|
|
PALLETE = {
|
|
"black": 0x000000,
|
|
"aliceblue": 0xF0F8FF,
|
|
"amethyst": 0x9966CC,
|
|
"antiquewhite": 0xFAEBD7,
|
|
"aqua": 0x00FFFF,
|
|
"aquamarine": 0x7FFFD4,
|
|
"azure": 0xF0FFFF,
|
|
"beige": 0xF5F5DC,
|
|
"bisque": 0xFFE4C4,
|
|
"blanchedalmond": 0xFFEBCD,
|
|
"blue": 0x0000FF,
|
|
"blueviolet": 0x8A2BE2,
|
|
"brown": 0xA52A2A,
|
|
"burlywood": 0xDEB887,
|
|
"cadetblue": 0x5F9EA0,
|
|
"chartreuse": 0x7FFF00,
|
|
"chocolate": 0xD2691E,
|
|
"coral": 0xFF7F50,
|
|
"cornflowerblue": 0x6495ED,
|
|
"cornsilk": 0xFFF8DC,
|
|
"crimson": 0xDC143C,
|
|
"cyan": 0x00FFFF,
|
|
"darkblue": 0x00008B,
|
|
"darkcyan": 0x008B8B,
|
|
"darkgoldenrod": 0xB8860B,
|
|
"darkgray": 0xA9A9A9,
|
|
"darkgreen": 0x006400,
|
|
"darkkhaki": 0xBDB76B,
|
|
"darkmagenta": 0x8B008B,
|
|
"darkolivegreen": 0x556B2F,
|
|
"darkorange": 0xFF8C00,
|
|
"darkorchid": 0x9932CC,
|
|
"darkred": 0x8B0000,
|
|
"darksalmon": 0xE9967A,
|
|
"darkseagreen": 0x8FBC8F,
|
|
"darkslateblue": 0x483D8B,
|
|
"darkslategray": 0x2F4F4F,
|
|
"darkturquoise": 0x00CED1,
|
|
"darkviolet": 0x9400D3,
|
|
"deeppink": 0xFF1493,
|
|
"deepskyblue": 0x00BFFF,
|
|
"dimgray": 0x696969,
|
|
"dodgerblue": 0x1E90FF,
|
|
"firebrick": 0xB22222,
|
|
"floralwhite": 0xFFFAF0,
|
|
"forestgreen": 0x228B22,
|
|
"fuchsia": 0xFF00FF,
|
|
"gainsboro": 0xDCDCDC,
|
|
"ghostwhite": 0xF8F8FF,
|
|
"gold": 0xFFD700,
|
|
"goldenrod": 0xDAA520,
|
|
"gray": 0x808080,
|
|
"green": 0x008000,
|
|
"greenyellow": 0xADFF2F,
|
|
"honeydew": 0xF0FFF0,
|
|
"hotpink": 0xFF69B4,
|
|
"indianred": 0xCD5C5C,
|
|
"indigo": 0x4B0082,
|
|
"ivory": 0xFFFFF0,
|
|
"khaki": 0xF0E68C,
|
|
"lavender": 0xE6E6FA,
|
|
"lavenderblush": 0xFFF0F5,
|
|
"lawngreen": 0x7CFC00,
|
|
"lemonchiffon": 0xFFFACD,
|
|
"lightblue": 0xADD8E6,
|
|
"lightcoral": 0xF08080,
|
|
"lightcyan": 0xE0FFFF,
|
|
"lightgoldenrodyellow": 0xFAFAD2,
|
|
"lightgreen": 0x90EE90,
|
|
"lightgrey": 0xD3D3D3,
|
|
"lightpink": 0xFFB6C1,
|
|
"lightsalmon": 0xFFA07A,
|
|
"lightseagreen": 0x20B2AA,
|
|
"lightskyblue": 0x87CEFA,
|
|
"lightslategray": 0x778899,
|
|
"lightsteelblue": 0xB0C4DE,
|
|
"lightyellow": 0xFFFFE0,
|
|
"lime": 0x00FF00,
|
|
"limegreen": 0x32CD32,
|
|
"linen": 0xFAF0E6,
|
|
"magenta": 0xFF00FF,
|
|
"maroon": 0x800000,
|
|
"mediumaquamarine": 0x66CDAA,
|
|
"mediumblue": 0x0000CD,
|
|
"mediumorchid": 0xBA55D3,
|
|
"mediumpurple": 0x9370DB,
|
|
"mediumseagreen": 0x3CB371,
|
|
"mediumslateblue": 0x7B68EE,
|
|
"mediumspringgreen": 0x00FA9A,
|
|
"mediumturquoise": 0x48D1CC,
|
|
"mediumvioletred": 0xC71585,
|
|
"midnightblue": 0x191970,
|
|
"mintcream": 0xF5FFFA,
|
|
"mistyrose": 0xFFE4E1,
|
|
"moccasin": 0xFFE4B5,
|
|
"navajowhite": 0xFFDEAD,
|
|
"navy": 0x000080,
|
|
"oldlace": 0xFDF5E6,
|
|
"olive": 0x808000,
|
|
"olivedrab": 0x6B8E23,
|
|
"orange": 0xFFA500,
|
|
"orangered": 0xFF4500,
|
|
"orchid": 0xDA70D6,
|
|
"palegoldenrod": 0xEEE8AA,
|
|
"palegreen": 0x98FB98,
|
|
"paleturquoise": 0xAFEEEE,
|
|
"paleVioletred": 0xDB7093,
|
|
"papayawhip": 0xFFEFD5,
|
|
"peachpuff": 0xFFDAB9,
|
|
"peru": 0xCD853F,
|
|
"pink": 0xFFC0CB,
|
|
"plaid": 0xCC5533,
|
|
"plum": 0xDDA0DD,
|
|
"powderblue": 0xB0E0E6,
|
|
"purple": 0x800080,
|
|
"red": 0xFF0000,
|
|
"rosybrown": 0xBC8F8F,
|
|
"royalblue": 0x4169E1,
|
|
"saddlebrown": 0x8B4513,
|
|
"salmon": 0xFA8072,
|
|
"sandybrown": 0xF4A460,
|
|
"seagreen": 0x2E8B57,
|
|
"seashell": 0xFFF5EE,
|
|
"sienna": 0xA0522D,
|
|
"silver": 0xC0C0C0,
|
|
"skyblue": 0x87CEEB,
|
|
"slateblue": 0x6A5ACD,
|
|
"slategray": 0x708090,
|
|
"snow": 0xFFFAFA,
|
|
"springgreen": 0x00FF7F,
|
|
"steelblue": 0x4682B4,
|
|
"tan": 0xD2B48C,
|
|
"teal": 0x008080,
|
|
"thistle": 0xD8BFD8,
|
|
"tomato": 0xFF6347,
|
|
"turquoise": 0x40E0D0,
|
|
"violet": 0xEE82EE,
|
|
"wheat": 0xF5DEB3,
|
|
"white": 0xFFFFFF,
|
|
"whitesmoke": 0xF5F5F5,
|
|
"yellow": 0xFFFF00,
|
|
"yellowgreen": 0x9ACD32,
|
|
}
|
|
|
|
|
|
class WaaaghLampGUI(QMainWindow):
|
|
def __init__(self):
|
|
# super().__init__()
|
|
super(WaaaghLampGUI, self).__init__()
|
|
|
|
self.setWindowIcon(QIcon("res/waaagh_icon.png"))
|
|
|
|
self.state = {
|
|
"mode": 0,
|
|
"color": 0,
|
|
}
|
|
|
|
self.setWindowTitle("WaaaghLamp GUI")
|
|
self.setFixedSize(250, 450)
|
|
|
|
# Установка иконки в трей
|
|
self.tray_icon = QSystemTrayIcon(self)
|
|
self.tray_icon.setIcon(QIcon("res/waaagh_icon.png"))
|
|
self.tray_menu = QMenu()
|
|
self.tray_icon.activated.connect(self.showMaximized)
|
|
|
|
# Создание действий для меню трея
|
|
minimize_action = QAction("Свернуть", self)
|
|
minimize_action.triggered.connect(self.showMinimized)
|
|
self.tray_menu.addAction(minimize_action)
|
|
|
|
exit_action = QAction("Выход", self)
|
|
exit_action.triggered.connect(self.close)
|
|
self.tray_menu.addAction(exit_action)
|
|
|
|
# Привязка меню к иконке трея
|
|
self.tray_icon.setContextMenu(self.tray_menu)
|
|
self.tray_icon.show()
|
|
|
|
self.mode_button_group = QButtonGroup()
|
|
self.status_bar = QStatusBar()
|
|
self.status_line = QLabel()
|
|
self.status_bar.addWidget(self.status_line)
|
|
|
|
self.main_layout = QVBoxLayout()
|
|
self.add_mode_buttons(self.main_layout, MODES, self.set_mode)
|
|
splitter1 = QFrame()
|
|
splitter1.setFrameShape(QFrame.Shape.HLine)
|
|
splitter1.setFrameShadow(QFrame.Shadow.Sunken)
|
|
self.main_layout.addWidget(splitter1)
|
|
|
|
self.add_mode_buttons(self.main_layout, SPECIAL_MODES, self.set_mode)
|
|
splitter2 = QFrame()
|
|
splitter2.setFrameShape(QFrame.Shape.HLine)
|
|
splitter2.setFrameShadow(QFrame.Shadow.Sunken)
|
|
self.main_layout.addWidget(splitter2)
|
|
|
|
self.pallete_list = QComboBox()
|
|
self.populate_pallete_list()
|
|
self.pallete_list.currentTextChanged.connect(self.set_custom_mode)
|
|
self.main_layout.addWidget(self.pallete_list)
|
|
|
|
self.custom_modes_layout = QVBoxLayout()
|
|
self.custom_modes_layout.setDirection(QVBoxLayout.Direction.LeftToRight)
|
|
self.add_mode_buttons(self.custom_modes_layout, CUSTOM_MODES, self.set_custom_mode)
|
|
self.main_layout.addLayout(self.custom_modes_layout)
|
|
splitter3 = QFrame()
|
|
splitter3.setFrameShape(QFrame.Shape.HLine)
|
|
splitter3.setFrameShadow(QFrame.Shadow.Sunken)
|
|
self.main_layout.addWidget(splitter3)
|
|
|
|
self.exit_button = QPushButton("Exit")
|
|
self.exit_button.clicked.connect(self.close)
|
|
self.main_layout.addWidget(self.exit_button)
|
|
|
|
container = QWidget()
|
|
container.setLayout(self.main_layout)
|
|
|
|
self.setCentralWidget(container)
|
|
self.setStatusBar(self.status_bar)
|
|
# self.setMinimumSize()
|
|
# self.setFixedWidth(self.width())
|
|
# self.setFixedHeight(self.height())
|
|
|
|
def populate_pallete_list(self):
|
|
for color in PALLETE.keys():
|
|
pixmap = QPixmap(16, 16)
|
|
pixmap.fill(PALLETE[color])
|
|
icon = QIcon(pixmap)
|
|
self.pallete_list.addItem(icon, color)
|
|
|
|
def add_mode_buttons(self, layout, modes, function=None):
|
|
for mode in modes.keys():
|
|
new_button = QPushButton(mode.capitalize())
|
|
new_button.setCheckable(True)
|
|
if new_button.text().lower() == "off":
|
|
new_button.setChecked(True)
|
|
new_button.clicked.connect(function)
|
|
self.mode_button_group.addButton(new_button, modes[mode])
|
|
layout.addWidget(new_button)
|
|
|
|
def set_mode(self):
|
|
print(self.mode_button_group.checkedId())
|
|
self.status_line.text = self.mode_button_group.checkedId()
|
|
self.send_message(self.mode_button_group.checkedId())
|
|
|
|
def parse_state(self):
|
|
pass
|
|
|
|
def set_custom_mode(self):
|
|
print(self.mode_button_group.checkedId())
|
|
self.status_line.text = self.mode_button_group.checkedId()
|
|
self.send_message(self.mode_button_group.checkedId(), PALLETE[self.pallete_list.currentText()])
|
|
|
|
def send_message(self, mode, color=0x000000):
|
|
def print_message(message):
|
|
print(message)
|
|
self.status_line.setText(message)
|
|
|
|
message = {
|
|
"mode": mode,
|
|
"color": color,
|
|
}
|
|
|
|
try:
|
|
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
s.connect((WAL_HOST, WAL_PORT))
|
|
s.settimeout(5)
|
|
s.send(json.dumps(message).encode('utf-8'))
|
|
except Exception as e:
|
|
print_message(f"ERROR: {e}")
|
|
|
|
data = ""
|
|
try:
|
|
data = s.recv(1024)
|
|
except Exception as e:
|
|
print_message(f"ERROR: {e}")
|
|
|
|
if data != "":
|
|
try:
|
|
self.state = json.loads(data.decode())
|
|
recieved_mode = self.state["mode"]
|
|
recieved_color = self.state["color"]
|
|
if recieved_mode == mode and recieved_color == color:
|
|
print_message(f"Mode {mode} with color {color}")
|
|
else:
|
|
print_message(f"ERROR: Wrong answer from lamp")
|
|
except Exception as e:
|
|
print_message(f"ERROR: {e}")
|
|
|
|
s.close()
|
|
|
|
def close(self, event):
|
|
print("Bye!")
|
|
QApplication.quit()
|
|
|
|
if __name__ == "__main__":
|
|
app = QApplication(sys.argv)
|
|
mainWindow = WaaaghLampGUI()
|
|
mainWindow.show()
|
|
sys.exit(app.exec())
|