def __init__(self, env, *args, **kwargs): super(ClearLWTDialog, self).__init__(*args, **kwargs) self.setWindowTitle("Clear obsolete retained LWTs") self.setMinimumSize(QSize(320, 480)) self.env = env vl = VLayout() sel_btns = QDialogButtonBox() sel_btns.setCenterButtons(True) btnSelAll = sel_btns.addButton("Select all", QDialogButtonBox.ActionRole) btnSelNone = sel_btns.addButton("Select none", QDialogButtonBox.ActionRole) self.lw = QListWidget() for lwt in self.env.lwts: itm = QListWidgetItem(lwt) itm.setCheckState(Qt.Unchecked) self.lw.addItem(itm) btnSelAll.clicked.connect(lambda: self.select(Qt.Checked)) btnSelNone.clicked.connect(lambda: self.select(Qt.Unchecked)) btns = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Close) btns.accepted.connect(self.accept) btns.rejected.connect(self.reject) vl.addWidgets([sel_btns, self.lw, btns]) self.setLayout(vl)
def __init__(self, device, *args, **kwargs): super(GPIODialog, self).__init__(*args, **kwargs) self.setWindowTitle("GPIO [{}]".format(device.p['FriendlyName1'])) self.setMinimumWidth(300) self.device = device self.gb = {} btns = QDialogButtonBox(QDialogButtonBox.Close) btns.rejected.connect(self.reject) gbxGPIO = QGroupBox("Select GPIO") fl = QFormLayout() if self.device.gpio: btns.addButton(QDialogButtonBox.Save) btns.accepted.connect(self.accept) for gp_name, gp_id in self.device.gpio.items(): gb = DictComboBox(self.device.gpios) gb.setCurrentText(self.device.gpios[gp_id]) self.gb[gp_name] = gb fl.addRow(gp_name, gb) else: fl.addWidget(QLabel("No configurable GPIOs")) gbxGPIO.setLayout(fl) vl = VLayout() vl.addWidgets([gbxGPIO, btns]) self.setLayout(vl)
def __init__(self, *args, **kwargs): super(PrefsDialog, self).__init__(*args, **kwargs) self.setWindowTitle("Preferences") # self.setMinimumSize(QSize(300, 200)) self.settings = QSettings("{}/TDM/tdm.cfg".format(QDir.homePath()), QSettings.IniFormat) self.devices_short_version = self.settings.value( "devices_short_version", True, bool) self.console_word_wrap = self.settings.value("console_word_wrap", True, bool) self.console_font_size = self.settings.value("console_font_size", 9, int) vl = VLayout() gbDevices = QGroupBox("Device list") fl_dev = QFormLayout() self.cbDevShortVersion = QCheckBox() self.cbDevShortVersion.setChecked(self.devices_short_version) fl_dev.addRow("Show short Tasmota version", self.cbDevShortVersion) fl_dev.setAlignment(self.cbDevShortVersion, Qt.AlignTop | Qt.AlignRight) gbDevices.setLayout(fl_dev) gbConsole = QGroupBox("Console") fl_cons = QFormLayout() self.cbConsWW = QCheckBox() self.cbConsWW.setChecked(self.console_word_wrap) self.sbConsFontSize = SpinBox(minimum=9, maximum=100) self.sbConsFontSize.setValue(self.console_font_size) gbConsole.setLayout(fl_cons) fl_cons.addRow("Word wrap", self.cbConsWW) fl_cons.addRow("Font size", self.sbConsFontSize) fl_cons.setAlignment(self.cbConsWW, Qt.AlignTop | Qt.AlignRight) fl_cons.setAlignment(self.sbConsFontSize, Qt.AlignTop | Qt.AlignRight) btns = QDialogButtonBox(QDialogButtonBox.Save | QDialogButtonBox.Close) btns.accepted.connect(self.accept) btns.rejected.connect(self.reject) vl.addWidgets([gbDevices, gbConsole, btns]) self.setLayout(vl)
def __init__(self, device, *args, **kwargs): super(TemplateDialog, self).__init__(*args, **kwargs) self.setWindowTitle("Template [{}]".format(device.p['FriendlyName1'])) self.setMinimumWidth(300) self.device = device self.gb = {} gpios = {"255": "User"} gpios.update(self.device.gpios) btns = QDialogButtonBox(QDialogButtonBox.Cancel) btns.rejected.connect(self.reject) gbxTmpl = QGroupBox("Configure template") fl = QFormLayout() if self.device.p['Template']: btns.addButton(QDialogButtonBox.Save) btns.accepted.connect(self.accept) tpl = self.device.p['Template'] print(tpl) self.leName = QLineEdit() self.leName.setMaxLength(14) self.leName.setText(tpl['NAME']) fl.addRow("Name", self.leName) self.gbxBase = DictComboBox(self.device.modules) self.gbxBase.setCurrentText(self.device.modules[str(tpl['BASE'])]) fl.addRow("Based on", self.gbxBase) for i, g in enumerate( [0, 1, 2, 3, 4, 5, 9, 10, 12, 13, 14, 15, 16]): gbx = DictComboBox(gpios) gbx.setCurrentText(gpios.get(str(tpl['GPIO'][i]))) fl.addRow( "<font color='{}'>GPIO{}</font>".format( 'red' if g in [9, 10] else 'black', g), gbx) self.gb[i] = gbx self.gbxADC = DictComboBox(template_adc) fl.addRow("ADC0", self.gbxADC) else: fl.addWidget( QLabel( "Templates not supported.\nUpgrade firmware to versions above 6.5" )) gbxTmpl.setLayout(fl) vl = VLayout() vl.addWidgets([gbxTmpl, btns]) self.setLayout(vl)
def __init__(self, device, *args, **kwargs): super(LightDialog, self).__init__(*args, **kwargs) self.setWindowTitle("Light settings [{}]".format( device.p['FriendlyName1'])) self.setMinimumWidth(300) self.device = device self.setoption_list = [68, 15, 16, 17, 20] self.setoption_widgets = {} vl = VLayout() vl_so = VLayout(0, 0) for so in self.setoption_list: cw = Command("SetOption{}".format(so), setoptions[str(so)], self.device.setoption(so)) vl_so.addWidget(cw) self.setoption_widgets[so] = cw tabs = QTabWidget() tab_so = QWidget() tab_so.setLayout(vl_so) tabs.addTab(tab_so, "SetOptions") vl.addWidget(tabs) btns = QDialogButtonBox(QDialogButtonBox.Save | QDialogButtonBox.Close) btns.accepted.connect(self.accept) btns.rejected.connect(self.reject) self.setLayout(vl)
def __init__(self, parent, topic, *args, **kwargs): super(DevicesConfigWidget, self).__init__(*args, **kwargs) self.settings = QSettings() self.topic = topic self.full_topic = self.settings.value( 'Devices/{}/full_topic'.format(topic)) self.friendly_name = self.settings.value( 'Devices/{}/friendly_name'.format(topic)) self.cmnd_topic = self.full_topic.replace("%topic%", self.topic).replace( "%prefix%", 'cmnd') self.tele_topic = self.full_topic.replace( "%topic%", self.topic).replace("%prefix%", 'tele') + "+" self.stat_topic = self.full_topic.replace( "%topic%", self.topic).replace("%prefix%", 'stat') + "+" self.setWindowTitle(self.friendly_name) self.mqtt = MqttClient() self.module = None self.modules = [] self.gpios = [] self.supported_gpios = [] self.current_gpios = {} self.setLayout(VLayout(margin=[0, 6, 0, 0], spacing=3)) self.build_detail_row() self.build_tabs() self.create_timers()
def openWebUI(self): self.device_username = self.settings.value("device_username", "", str) self.device_password = self.settings.value("device_password", "", str) if self.device and self.device.p.get('IPAddress'): url = QUrl("http://{}:{}@{}".format( self.device_username, \ urllib.parse.quote(self.device_password),self.device.p['IPAddress'])) try: webui = QWebEngineView() webui.load(url) frm_webui = QFrame() frm_webui.setWindowTitle("WebUI [{}]".format( self.device.p['FriendlyName1'])) frm_webui.setFrameShape(QFrame.StyledPanel) frm_webui.setLayout(VLayout(0)) frm_webui.layout().addWidget(webui) frm_webui.destroyed.connect(self.updateMDI) self.mdi.addSubWindow(frm_webui) self.mdi.setViewMode(QMdiArea.TabbedView) frm_webui.setWindowState(Qt.WindowMaximized) except NameError: QDesktopServices.openUrl(url)
def __init__(self, device, *args, **kwargs): super(ModuleDialog, self).__init__(*args, **kwargs) self.setWindowTitle("Module [{}]".format(device.name)) self.setMinimumWidth(300) self.device = device btns = QDialogButtonBox(QDialogButtonBox.Save | QDialogButtonBox.Close) btns.accepted.connect(self.accept) btns.rejected.connect(self.reject) gbxModules = GroupBoxV("Select Module") self.gb = DictComboBox(self.device.modules) self.gb.setCurrentText(self.device.modules[str(self.device.p['Module'])]) gbxModules.addWidget(self.gb) vl = VLayout() vl.addWidgets([gbxModules, btns]) self.setLayout(vl)
def tabModule(self): module = QWidget() module.setLayout(HLayout()) self.gbModule = GroupBoxH("Module") self.cbModule = QComboBox() self.pbModuleSet = QPushButton("Save and close (device will restart)") self.gbModule.addWidgets([self.cbModule, self.pbModuleSet]) self.pbModuleSet.clicked.connect(self.saveModule) self.gbGPIO = QGroupBox("GPIO") fl_gpio = QFormLayout() pbGPIOSet = QPushButton("Save and close (device will restart)") fl_gpio.addWidget(pbGPIOSet) pbGPIOSet.clicked.connect(self.saveGPIOs) self.gbGPIO.setLayout(fl_gpio) mg_vl = VLayout([0, 0, 3, 0]) mg_vl.addWidgets([self.gbModule, self.gbGPIO]) mg_vl.setStretch(0, 1) mg_vl.setStretch(1, 3) self.gbFirmware = GroupBoxV("Firmware", margin=[3, 0, 0, 0]) lb = QLabel("Feature under development.") lb.setAlignment(Qt.AlignCenter) lb.setEnabled(False) self.gbFirmware.addWidget(lb) module.layout().addLayout(mg_vl) module.layout().addWidget(self.gbFirmware) return module
def __init__(self, device, *args, **kwargs): super(SetOptionsDialog, self).__init__(*args, **kwargs) self.setWindowTitle("SetOptions [{}]".format(device.p['FriendlyName1'])) self.setMinimumWidth(300) self.device = device self.gbs = [] vl = VLayout() for i, so in setoptions.items(): gb = GroupBoxV("SetOption{}".format(i)) cb = DictComboBox(so['parameters']) gb.addWidgets([QLabel(so['description']), cb]) vl.addWidget(gb) # self.gb = DictComboBox(self.device.modules) # self.gb.setCurrentText(self.device.modules[str(self.device.p['Module'])]) # gbxModules.addWidget(self.gb) btns = QDialogButtonBox(QDialogButtonBox.Save | QDialogButtonBox.Close) btns.accepted.connect(self.accept) btns.rejected.connect(self.reject) vl.addWidget(btns) self.setLayout(vl)
def __init__(self, parent, *args, **kwargs): super(DevicesListWidget, self).__init__(*args, **kwargs) self.setWindowTitle("Devices list") self.setWindowState(Qt.WindowMaximized) self.setLayout(VLayout(margin=0, spacing=0)) self.mqtt = parent.mqtt self.mdi = parent.mdi self.idx = None self.nam = QNetworkAccessManager() self.backup = bytes() self.settings = QSettings("{}/TDM/tdm.cfg".format(QDir.homePath()), QSettings.IniFormat) self.hidden_columns = self.settings.value("hidden_columns", [1, 2]) self.tb = Toolbar(Qt.Horizontal, 16, Qt.ToolButtonTextBesideIcon) self.tb.addAction(QIcon("GUI/icons/add.png"), "Add", self.device_add) self.layout().addWidget(self.tb) self.device_list = TableView() self.model = parent.device_model self.telemetry_model = parent.telemetry_model self.sorted_device_model = QSortFilterProxyModel() self.sorted_device_model.setSourceModel(parent.device_model) self.device_list.setModel(self.sorted_device_model) self.device_list.setupColumns(columns, self.hidden_columns) self.device_list.setSortingEnabled(True) self.device_list.setWordWrap(True) self.device_list.setItemDelegate(DeviceDelegate()) self.device_list.sortByColumn(DevMdl.TOPIC, Qt.AscendingOrder) self.device_list.setContextMenuPolicy(Qt.CustomContextMenu) self.layout().addWidget(self.device_list) self.device_list.clicked.connect(self.select_device) self.device_list.doubleClicked.connect(self.device_config) self.device_list.customContextMenuRequested.connect( self.show_list_ctx_menu) self.device_list.horizontalHeader().setContextMenuPolicy( Qt.CustomContextMenu) self.device_list.horizontalHeader().customContextMenuRequested.connect( self.show_header_ctx_menu) self.ctx_menu = QMenu() self.ctx_menu_relays = None self.create_actions() self.build_header_ctx_menu()
def __init__(self, devices): super().__init__() self.setWindowFlags(Qt.Tool) self.setMinimumSize(QSize(640, 480)) self.devices = devices self.command = "" vl = VLayout() gbxDevice = GroupBoxV("Commands history for:") gbDevice = QComboBox() gbDevice.addItems([d.p['FriendlyName1'] for d in devices]) gbxDevice.addWidget(gbDevice) self.lwCommands = QListWidget() vl.addWidgets([ gbxDevice, self.lwCommands, QLabel("Double-click a command to use it, ESC to close.") ]) self.setLayout(vl) gbDevice.currentIndexChanged.connect(self.load_history) self.lwCommands.doubleClicked.connect(self.select_command)
def __init__(self, *args, **kwargs): super(BrokerDialog, self).__init__(*args, **kwargs) self.setWindowTitle("MQTT Broker") self.settings = QSettings("{}/TDM/tdm.cfg".format(QDir.homePath()), QSettings.IniFormat) gbHost = QGroupBox("Hostname and port") hfl = QFormLayout() self.hostname = QLineEdit() self.hostname.setText(self.settings.value("hostname", "localhost")) self.port = SpinBox(maximum=65535) self.port.setValue(self.settings.value("port", 1883, int)) hfl.addRow("Hostname", self.hostname) hfl.addRow("Port", self.port) gbHost.setLayout(hfl) gbLogin = QGroupBox("Credentials [optional]") lfl = QFormLayout() self.username = QLineEdit() self.username.setText(self.settings.value("username", "")) self.password = QLineEdit() self.password.setEchoMode(QLineEdit.PasswordEchoOnEdit) self.password.setText(self.settings.value("password", "")) lfl.addRow("Username", self.username) lfl.addRow("Password", self.password) gbLogin.setLayout(lfl) gbClientId = QGroupBox("Client ID [optional]") cfl = QFormLayout() self.clientId = QLineEdit() self.clientId.setText( self.settings.value("client_id", "tdm-" + self.random_generator())) cfl.addRow("Client ID", self.clientId) gbClientId.setLayout(cfl) self.cbConnectStartup = QCheckBox("Connect on startup") self.cbConnectStartup.setChecked( self.settings.value("connect_on_startup", False, bool)) hlBtn = HLayout() btnSave = QPushButton("Save") btnCancel = QPushButton("Cancel") hlBtn.addWidgets([btnSave, btnCancel]) vl = VLayout() vl.addWidgets([gbHost, gbLogin, self.cbConnectStartup]) vl.addLayout(hlBtn) self.setLayout(vl) btnSave.clicked.connect(self.accept) btnCancel.clicked.connect(self.reject)
def __init__(self, parent, topic, *args, **kwargs): super(DevicesConfigWidget, self).__init__(*args, **kwargs) self.settings = QSettings("{}/TDM/tdm.cfg".format(QDir.homePath()), QSettings.IniFormat) self.topic = topic self.full_topic = self.settings.value( 'Devices/{}/full_topic'.format(topic)) self.friendly_name = self.settings.value( 'Devices/{}/friendly_name'.format(topic)) self.cmnd_topic = self.full_topic.replace("%topic%", self.topic).replace( "%prefix%", 'cmnd') self.tele_topic = self.full_topic.replace( "%topic%", self.topic).replace("%prefix%", 'tele') + "+" self.stat_topic = self.full_topic.replace( "%topic%", self.topic).replace("%prefix%", 'stat') + "+" self.setWindowTitle(self.friendly_name) self.mqtt = MqttClient() self.module = None self.modules = [] self.gpios = [] self.supported_gpios = [] self.gpio_cb = [] self.timers = False self.setLayout(VLayout(margin=[0, 6, 0, 0], spacing=3)) self.lbModule = QLabel("Connecting...") fnt = self.lbModule.font() fnt.setPointSize(14) fnt.setBold(True) self.lbModule.setFont(fnt) self.lbModule.setAlignment(Qt.AlignCenter) self.lbModule.setMaximumHeight(25) self.layout().addWidget(self.lbModule) self.build_tabs() self.create_timers()
def __init__(self, *args, **kwargs): super(PatternsDialog, self).__init__(*args, **kwargs) self.setMinimumHeight(400) self.setMinimumWidth(400) self.setWindowTitle("Autodiscovery patterns") self.settings = QSettings("{}/TDM/tdm.cfg".format(QDir.homePath()), QSettings.IniFormat) self.settings.beginGroup("Patterns") vl = VLayout() cols = ["Pattern"] self.tw = QTableWidget(0, 1) self.tw.setHorizontalHeaderLabels(cols) self.tw.verticalHeader().hide() self.tw.horizontalHeader().setSectionResizeMode(0, QHeaderView.Stretch) for k in self.settings.childKeys(): row = self.tw.rowCount() self.tw.insertRow(row) self.tw.setItem(row, 0, QTableWidgetItem(self.settings.value(k))) vl.addWidgets([ QLabel( "Add your modified FullTopic patterns to enable auto-discovery of such devices\n" "Patterns MUST include %prefix%, %topic% and trailing /\n" "Default Tasmota FullTopics are built-in\n\n" "You have to reconnect to your Broker after topic changes."), self.tw ]) hl_btns = HLayout([0, 3, 0, 3]) btnAdd = QPushButton("Add") btnDel = QPushButton("Delete") btnCancel = QPushButton("Cancel") btnSave = QPushButton("Save") hl_btns.addWidgets([btnAdd, btnDel, btnSave, btnCancel]) hl_btns.insertStretch(2) vl.addLayout(hl_btns) self.setLayout(vl) self.idx = None self.tw.clicked.connect(self.select) btnAdd.clicked.connect(self.add) btnDel.clicked.connect(self.delete) btnSave.clicked.connect(self.accept) btnCancel.clicked.connect(self.reject)
def openWebUI(self): if self.device and self.device.p.get('IPAddress'): url = QUrl("http://{}".format(self.device.p['IPAddress'])) try: webui = QWebEngineView() webui.load(url) frm_webui = QFrame() frm_webui.setWindowTitle("WebUI [{}]".format(self.device.p['FriendlyName1'])) frm_webui.setFrameShape(QFrame.StyledPanel) frm_webui.setLayout(VLayout(0)) frm_webui.layout().addWidget(webui) frm_webui.destroyed.connect(self.updateMDI) self.mdi.addSubWindow(frm_webui) self.mdi.setViewMode(QMdiArea.TabbedView) frm_webui.setWindowState(Qt.WindowMaximized) except NameError: QDesktopServices.openUrl(QUrl("http://{}".format(self.device.p['IPAddress'])))
def __init__(self, *args, **kwargs): super(BSSIdDialog, self).__init__(*args, **kwargs) self.setMinimumHeight(400) self.setMinimumWidth(400) self.setWindowTitle("BSSId aliases") self.settings = QSettings("{}/TDM/tdm.cfg".format(QDir.homePath()), QSettings.IniFormat) self.settings.beginGroup("BSSId") vl = VLayout() cols = ["BSSId", "Alias"] self.tw = QTableWidget(0, 2) self.tw.setHorizontalHeaderLabels(cols) self.tw.verticalHeader().hide() for c in range(2): self.tw.horizontalHeader().setSectionResizeMode( c, QHeaderView.Stretch) for k in self.settings.childKeys(): row = self.tw.rowCount() self.tw.insertRow(row) self.tw.setItem(row, 0, QTableWidgetItem(k)) self.tw.setItem(row, 1, QTableWidgetItem(self.settings.value(k))) vl.addWidget(self.tw) hl_btns = HLayout([0, 3, 0, 3]) btnAdd = QPushButton("Add") btnDel = QPushButton("Delete") btnCancel = QPushButton("Cancel") btnSave = QPushButton("Save") hl_btns.addWidgets([btnAdd, btnDel, btnSave, btnCancel]) hl_btns.insertStretch(2) vl.addLayout(hl_btns) self.setLayout(vl) self.idx = None self.tw.clicked.connect(self.select) btnAdd.clicked.connect(self.add) btnDel.clicked.connect(self.delete) btnSave.clicked.connect(self.accept) btnCancel.clicked.connect(self.reject)
def __init__(self, model, row, *args, **kwargs): super(DeviceEditDialog, self).__init__(*args, **kwargs) self.setMinimumWidth(400) self.setWindowTitle("Edit device") self.settings = QSettings() self.settings.beginGroup("Devices") self.mapper = QDataWidgetMapper() self.mapper.setModel(model) self.mapper.setSubmitPolicy(QDataWidgetMapper.ManualSubmit) vl = VLayout() gbTopic = QGroupBox("MQTT Topic") self.topic = QLineEdit() self.topic.setPlaceholderText("unique name of your device") self.mapper.addMapping(self.topic, DevMdl.TOPIC) self.full_topic = QLineEdit() self.full_topic.setPlaceholderText("must contain %prefix% and %topic%") self.mapper.addMapping(self.full_topic, DevMdl.FULL_TOPIC) tfl = QFormLayout() tfl.addRow("Topic", self.topic) tfl.addRow("Full topic", self.full_topic) gbTopic.setLayout(tfl) btnSave = QPushButton("Save") btnCancel = QPushButton("Cancel") hl_btns = HLayout() hl_btns.addStretch(1) hl_btns.addWidgets([btnSave, btnCancel]) vl.addWidgets([gbTopic]) vl.addLayout(hl_btns) self.setLayout(vl) self.mapper.setCurrentIndex(row) btnSave.clicked.connect(self.accept) btnCancel.clicked.connect(self.reject)
def __init__(self, *args, **kwargs): super(BrokerDialog, self).__init__(*args, **kwargs) self.setWindowTitle("MQTT Broker") self.settings = QSettings() gbHost = QGroupBox("Hostname and port") hfl = QFormLayout() self.hostname = QLineEdit() self.hostname.setText(self.settings.value("hostname", "localhost")) self.port = SpinBox(maximum=65535) self.port.setValue(self.settings.value("port", 1883, int)) hfl.addRow("Hostname", self.hostname) hfl.addRow("Port", self.port) gbHost.setLayout(hfl) gbLogin = QGroupBox("Credentials [optional]") lfl = QFormLayout() self.username = QLineEdit() self.username.setText(self.settings.value("username", "")) self.password = QLineEdit() self.password.setEchoMode(QLineEdit.PasswordEchoOnEdit) self.password.setText(self.settings.value("password", "")) lfl.addRow("Username", self.username) lfl.addRow("Password", self.password) gbLogin.setLayout(lfl) hlBtn = HLayout() btnSave = QPushButton("Save") btnCancel = QPushButton("Cancel") hlBtn.addWidgets([btnSave, btnCancel]) vl = VLayout() vl.addWidgets([gbHost, gbLogin]) vl.addLayout(hlBtn) self.setLayout(vl) btnSave.clicked.connect(self.accept) btnCancel.clicked.connect(self.reject)
def __init__(self, device, *args, **kwargs): super(RulesWidget, self).__init__(*args, **kwargs) self.device = device self.setWindowTitle("Rules [{}]".format( self.device.p['FriendlyName1'])) self.poll_timer = QTimer() self.poll_timer.timeout.connect(self.poll) self.poll_timer.start(1000) self.vars = [''] * 5 self.var = None self.mems = [''] * 5 self.mem = None self.rts = [0] * 8 self.rt = None fnt_mono = QFont("asd") fnt_mono.setStyleHint(QFont.TypeWriter) tb = Toolbar(iconsize=24, label_position=Qt.ToolButtonTextBesideIcon) vl = VLayout(margin=0, spacing=0) self.cbRule = QComboBox() self.cbRule.setMinimumWidth(100) self.cbRule.addItems(["Rule{}".format(nr + 1) for nr in range(3)]) self.cbRule.currentTextChanged.connect(self.load_rule) tb.addWidget(self.cbRule) self.actEnabled = CheckableAction(QIcon("GUI/icons/off.png"), "Enabled") self.actEnabled.triggered.connect(self.toggle_rule) self.actOnce = CheckableAction(QIcon("GUI/icons/once.png"), "Once") self.actOnce.triggered.connect(self.toggle_once) self.actStopOnError = CheckableAction(QIcon("GUI/icons/stop.png"), "Stop on error") self.actStopOnError.triggered.connect(self.toggle_stop) tb.addActions([self.actEnabled, self.actOnce, self.actStopOnError]) self.cbRule.setFixedHeight( tb.widgetForAction(self.actEnabled).height() + 1) self.actUpload = tb.addAction(QIcon("GUI/icons/upload.png"), "Upload") self.actUpload.triggered.connect(self.upload_rule) # tb.addSeparator() # self.actLoad = tb.addAction(QIcon("GUI/icons/open.png"), "Load...") # self.actSave = tb.addAction(QIcon("GUI/icons/save.png"), "Save...") tb.addSpacer() self.counter = QLabel("Remaining: 511") tb.addWidget(self.counter) vl.addWidget(tb) hl = HLayout(margin=[3, 0, 0, 0]) self.gbTriggers = GroupBoxV("Triggers") self.triggers = QListWidget() self.triggers.setAlternatingRowColors(True) self.gbTriggers.addWidget(self.triggers) self.gbEditor = GroupBoxV("Rule editor") self.editor = QPlainTextEdit() self.editor.setFont(fnt_mono) self.editor.setPlaceholderText("loading...") self.editor.textChanged.connect(self.update_counter) self.gbEditor.addWidget(self.editor) # hl.addWidgets([self.gbTriggers, self.gbEditor]) hl.addWidget(self.gbEditor) self.rules_hl = RuleHighLighter(self.editor.document()) vl_helpers = VLayout(margin=[0, 0, 3, 0]) ###### Polling self.gbPolling = GroupBoxH("Automatic polling") self.pbPollVars = QPushButton("VARs") self.pbPollVars.setCheckable(True) self.pbPollMems = QPushButton("MEMs") self.pbPollMems.setCheckable(True) self.pbPollRTs = QPushButton("RuleTimers") self.pbPollRTs.setCheckable(True) self.gbPolling.addWidgets( [self.pbPollVars, self.pbPollMems, self.pbPollRTs]) ###### VARS # self.gbVars = GroupBoxV("VARs") self.lwVars = QListWidget() self.lwVars.setAlternatingRowColors(True) self.lwVars.addItems( ["VAR{}: loading...".format(i) for i in range(1, 6)]) self.lwVars.clicked.connect(self.select_var) self.lwVars.doubleClicked.connect(self.set_var) # self.gbVars.addWidget(self.lwVars) ###### MEMS # self.gbMems = GroupBoxV("MEMs") self.lwMems = QListWidget() self.lwMems.setAlternatingRowColors(True) self.lwMems.addItems( ["MEM{}: loading...".format(i) for i in range(1, 6)]) self.lwMems.clicked.connect(self.select_mem) self.lwMems.doubleClicked.connect(self.set_mem) # self.gbMems.addWidget(self.lwMems) ###### RuleTimers # self.gbRTs = GroupBoxV("Rule timers") self.lwRTs = QListWidget() self.lwRTs.setAlternatingRowColors(True) self.lwRTs.addItems( ["RuleTimer{}: loading...".format(i) for i in range(1, 9)]) self.lwRTs.clicked.connect(self.select_rt) self.lwRTs.doubleClicked.connect(self.set_rt) # self.gbRTs.addWidget(self.lwRTs) # vl_helpers.addWidgets([self.gbPolling, self.gbVars, self.gbMems, self.gbRTs]) vl_helpers.addWidgets( [self.gbPolling, self.lwVars, self.lwMems, self.lwRTs]) hl.addLayout(vl_helpers) hl.setStretch(0, 3) hl.setStretch(1, 1) # hl.setStretch(2, 1) vl.addLayout(hl) self.setLayout(vl)
def __init__(self, device, *args, **kwargs): super().__init__() self.setAllowedAreas(Qt.BottomDockWidgetArea) self.setWindowTitle("Console [{}]".format(device.p["FriendlyName1"])) self.device = device w = QWidget() vl = VLayout() self.console = QPlainTextEdit() self.console.setTabChangesFocus(True) fnt_mono = QFont("asd") fnt_mono.setStyleHint(QFont.TypeWriter) self.console.setFont(fnt_mono) self.console.setReadOnly(True) self.console_hl = JSONHighLighter(self.console.document()) hl_command_mqttlog = HLayout(0) self.command = QLineEdit() self.command.setFont(fnt_mono) self.command.setPlaceholderText( "Type the command and press ENTER to send.") self.command.returnPressed.connect(self.command_enter) self.command.textChanged.connect(self.command_changed) self.command.installEventFilter(self) command_cpl = QCompleter(sorted(commands)) command_cpl.setCaseSensitivity(Qt.CaseInsensitive) command_cpl.setCompletionMode(QCompleter.UnfilteredPopupCompletion) self.command.setCompleter(command_cpl) # command_cpl.popup().installEventFilter(self) command_cpl.activated.connect(self.command.clear, Qt.QueuedConnection) self.cbMQTTLog = QComboBox() self.cbMQTTLog.addItems([ "Disabled", "Error", "Error/Info (default)", "Error/Info/Debug", "Error/Info/More debug", "All" ]) mqttlog = self.device.p.get("MqttLog", -1) if mqttlog != -1: self.cbMQTTLog.setCurrentIndex(int(mqttlog)) else: self.cbMQTTLog.setEnabled(False) self.cbMQTTLog.currentIndexChanged.connect(self.change_mqttlog) hl_command_mqttlog.addWidgets( [self.command, QLabel("MQTT Log level"), self.cbMQTTLog]) vl.addWidget(self.console) vl.addLayout(hl_command_mqttlog) w.setLayout(vl) self.setWidget(w)
def __init__(self, device, *args, **kwargs): super().__init__() self.setAllowedAreas(Qt.BottomDockWidgetArea) self.setWindowTitle("Console [{}]".format(device.name)) self.device = device self.settings = QSettings("{}/TDM/tdm.cfg".format(QDir.homePath()), QSettings.IniFormat) console_font_size = self.settings.value("console_font_size", 9, int) console_font.setPointSize(console_font_size) console_word_wrap = self.settings.value("console_word_wrap", True, bool) w = QWidget() vl = VLayout() self.console = QPlainTextEdit() self.console.setTabChangesFocus(True) self.console.setWordWrapMode(console_word_wrap) self.console.setReadOnly(True) self.console.setFont(console_font) self.console_hl = JSONHighLighter(self.console.document()) hl_command_mqttlog = HLayout(0) self.command = QLineEdit() self.command.setFont(console_font) self.command.setPlaceholderText( "Type the command and press ENTER to send.") self.command.returnPressed.connect(self.command_enter) self.command.textChanged.connect(self.command_changed) self.command.installEventFilter(self) command_cpl = QCompleter(sorted(commands)) command_cpl.setCaseSensitivity(Qt.CaseInsensitive) command_cpl.setCompletionMode(QCompleter.UnfilteredPopupCompletion) self.command.setCompleter(command_cpl) # command_cpl.popup().installEventFilter(self) command_cpl.activated.connect(self.command.clear, Qt.QueuedConnection) pbSave = QPushButton(QIcon("GUI/icons/save.png"), "") pbSave.setFlat(True) pbSave.setToolTip("Save console") pbSave.clicked.connect(self.save_console) pbClear = QPushButton(QIcon("GUI/icons/clear.png"), "") pbClear.setFlat(True) pbClear.setToolTip("Clear console") pbClear.clicked.connect(self.clear_console) self.cbMQTTLog = QComboBox() self.cbMQTTLog.addItems([ "Disabled", "Error", "Error/Info (default)", "Error/Info/Debug", "Error/Info/More debug", "All" ]) mqttlog = self.device.p.get("MqttLog", -1) if mqttlog != -1: self.cbMQTTLog.setCurrentIndex(int(mqttlog)) else: self.cbMQTTLog.setEnabled(False) self.cbMQTTLog.currentIndexChanged.connect(self.change_mqttlog) hl_command_mqttlog.addWidgets([ self.command, pbSave, pbClear, QLabel("MQTT Log level"), self.cbMQTTLog ]) vl.addWidget(self.console) vl.addLayout(hl_command_mqttlog) w.setLayout(vl) self.setWidget(w)
def __init__(self, device, *args, **kwargs): super(ButtonsDialog, self).__init__(*args, **kwargs) self.setWindowTitle("Buttons settings [{}]".format(device.name)) self.setMinimumWidth(300) self.device = device self.commands_list = ["ButtonDebounce", "ButtonRetain"] self.command_widgets = {} self.setoption_list = [11, 13, 32, 40, 61] self.setoption_widgets = {} vl = VLayout() vl_cmd = VLayout(0, 0) for cmd in self.commands_list: cw = Command(cmd, commands[cmd], self.device.p.get(cmd)) vl_cmd.addWidget(cw) self.command_widgets[cmd] = cw vl_cmd.addStretch(1) vl_so = VLayout(0, 0) for so in self.setoption_list: cw = Command("SetOption{}".format(so), setoptions[str(so)], self.device.setoption(so)) vl_so.addWidget(cw) self.setoption_widgets[so] = cw tabs = QTabWidget() tab_cm = QWidget() tab_cm.setLayout(vl_cmd) tabs.addTab(tab_cm, "Settings") tab_so = QWidget() tab_so.setLayout(vl_so) tabs.addTab(tab_so, "SetOptions") vl.addWidget(tabs) btns = QDialogButtonBox(QDialogButtonBox.Save | QDialogButtonBox.Close) btns.accepted.connect(self.accept) btns.rejected.connect(self.reject) vl.addWidgets([ HTMLLabel( "<a href={}/Buttons-and-Switches>Buttons and Switches</a>". format(docs_url)), btns ]) self.setLayout(vl)
def __init__(self, device, *args, **kwargs): super(TimersDialog, self).__init__(*args, **kwargs) self.device = device self.timers = {} self.setWindowTitle("Timers [{}]".format( self.device.p['FriendlyName1'])) vl = VLayout() self.gbTimers = GroupBoxV("Enabled", spacing=5) self.gbTimers.setCheckable(True) self.gbTimers.toggled.connect(self.toggleTimers) self.cbTimer = QComboBox() self.cbTimer.addItems(["Timer{}".format(nr + 1) for nr in range(16)]) self.cbTimer.currentTextChanged.connect(self.loadTimer) hl_tmr_arm_rpt = HLayout(0) self.cbTimerArm = QCheckBox("Arm") self.cbTimerArm.clicked.connect(lambda x: self.describeTimer()) self.cbTimerRpt = QCheckBox("Repeat") self.cbTimerRpt.clicked.connect(lambda x: self.describeTimer()) hl_tmr_arm_rpt.addWidgets([self.cbTimerArm, self.cbTimerRpt]) hl_tmr_out_act = HLayout(0) self.cbxTimerOut = QComboBox() self.cbxTimerOut.addItems(self.device.power().keys()) self.cbxTimerOut.currentIndexChanged.connect( lambda x: self.describeTimer()) self.cbxTimerAction = QComboBox() self.cbxTimerAction.addItems(["Off", "On", "Toggle", "Rule"]) self.cbxTimerAction.currentIndexChanged.connect( lambda x: self.describeTimer()) hl_tmr_out_act.addWidgets([self.cbxTimerOut, self.cbxTimerAction]) self.TimerMode = QButtonGroup() rbTime = QRadioButton("Time") rbSunrise = QRadioButton("Sunrise ({})".format( self.device.p['Sunrise'])) rbSunset = QRadioButton("Sunset ({})".format(self.device.p['Sunset'])) self.TimerMode.addButton(rbTime, 0) self.TimerMode.addButton(rbSunrise, 1) self.TimerMode.addButton(rbSunset, 2) self.TimerMode.buttonClicked.connect(lambda x: self.describeTimer()) gbTimerMode = GroupBoxH("Mode") gbTimerMode.addWidgets(self.TimerMode.buttons()) hl_tmr_time = HLayout(0) self.cbxTimerPM = QComboBox() self.cbxTimerPM.addItems(["+", "-"]) self.cbxTimerPM.currentIndexChanged.connect( lambda x: self.describeTimer()) self.TimerMode.buttonClicked[int].connect( lambda x: self.cbxTimerPM.setEnabled(x != 0)) self.teTimerTime = QTimeEdit() self.teTimerTime.setButtonSymbols(QTimeEdit.NoButtons) self.teTimerTime.setAlignment(Qt.AlignCenter) self.teTimerTime.timeChanged.connect(lambda x: self.describeTimer()) lbWnd = QLabel("Window:") lbWnd.setAlignment(Qt.AlignVCenter | Qt.AlignRight) self.cbxTimerWnd = QComboBox() self.cbxTimerWnd.addItems([str(x).zfill(2) for x in range(0, 16)]) self.cbxTimerWnd.currentIndexChanged.connect( lambda x: self.describeTimer()) hl_tmr_days = HLayout(0) self.TimerWeekday = QButtonGroup() self.TimerWeekday.setExclusive(False) for i, wd in enumerate( ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]): cb = QCheckBox(wd) cb.clicked.connect(lambda x: self.describeTimer()) hl_tmr_days.addWidget(cb) self.TimerWeekday.addButton(cb, i) gbTimerDesc = GroupBoxV("Timer description", 5) gbTimerDesc.setMinimumHeight(200) self.lbTimerDesc = QLabel() self.lbTimerDesc.setAlignment(Qt.AlignCenter) self.lbTimerDesc.setWordWrap(True) gbTimerDesc.layout().addWidget(self.lbTimerDesc) hl_tmr_time.addWidgets( [self.cbxTimerPM, self.teTimerTime, lbWnd, self.cbxTimerWnd]) self.gbTimers.layout().addWidget(self.cbTimer) self.gbTimers.layout().addLayout(hl_tmr_arm_rpt) self.gbTimers.layout().addLayout(hl_tmr_out_act) self.gbTimers.layout().addWidget(gbTimerMode) self.gbTimers.layout().addLayout(hl_tmr_time) self.gbTimers.layout().addLayout(hl_tmr_days) btns = QDialogButtonBox(QDialogButtonBox.Save | QDialogButtonBox.Close) reload = btns.addButton("Reload", QDialogButtonBox.ResetRole) btns.accepted.connect(self.saveTimer) btns.rejected.connect(self.reject) reload.clicked.connect( lambda: self.loadTimer(self.cbTimer.currentText())) vl.addWidgets([self.gbTimers, gbTimerDesc, btns]) self.setLayout(vl)
def __init__(self, device, *args, **kwargs): super(PowerDialog, self).__init__(*args, **kwargs) self.setWindowTitle("Power settings [{}]".format( device.p['FriendlyName1'])) self.setMinimumWidth(300) self.device = device self.commands_list = [ "BlinkCount", "BlinkTime", "PowerOnState", "PowerRetain" ] self.command_widgets = {} self.setoption_list = [0, 26, 63] self.setoption_widgets = {} vl = VLayout() vl_cmd = VLayout(0, 0) for cmd in self.commands_list: cw = Command(cmd, commands[cmd], self.device.p.get(cmd)) vl_cmd.addWidget(cw) self.command_widgets[cmd] = cw self.ci = Interlock( "Interlock", commands["Interlock"], { "Interlock": self.device.p.get("Interlock", "OFF"), "Groups": self.device.p.get("Groups", "") }) vl_cmd.addWidget(self.ci) self.cpt = PulseTime("PulseTime", commands["PulseTime"], self.device.pulsetime()) vl_cmd.addWidget(self.cpt) vl_cmd.addStretch(1) vl_so = VLayout(0, 0) for so in self.setoption_list: cw = Command("SetOption{}".format(so), setoptions[str(so)], self.device.setoption(so)) vl_so.addWidget(cw) self.setoption_widgets[so] = cw vl_so.addStretch(1) tabs = QTabWidget() tab_cm = QWidget() tab_cm.setLayout(vl_cmd) tabs.addTab(tab_cm, "Settings") tab_so = QWidget() tab_so.setLayout(vl_so) tabs.addTab(tab_so, "SetOptions") vl.addWidget(tabs) btns = QDialogButtonBox(QDialogButtonBox.Save | QDialogButtonBox.Close) btns.accepted.connect(self.accept) btns.rejected.connect(self.reject) vl.addWidgets([ HTMLLabel( "<a href=https://github.com/arendst/Sonoff-Tasmota/wiki/Buttons-and-Switches>Buttons and Switches</a>" ), btns ]) self.setLayout(vl)
def tabRules(self): rules = QWidget() rules.setLayout(VLayout()) hl = HLayout(0) vl_l = VLayout(0) self.rg = RuleGroupBox(rules, "Rule editor") self.rg.setFlat(True) self.rg.cbRule.currentIndexChanged.connect(self.loadRule) vl_l.addWidget(self.rg) gRT = GroupBoxH("Rule timers") vl_RT_func = VLayout(margin=[0, 0, 3, 0]) self.pbRTPoll = QPushButton("Poll") self.pbRTPoll.setCheckable(True) self.pbRTSet = QPushButton("Set") vl_RT_func.addWidgets([self.pbRTPoll, self.pbRTSet]) vl_RT_func.addStretch(1) gRT.layout().addLayout(vl_RT_func) self.twRT = QTableWidget(1, 8) self.twRT.setHorizontalHeaderLabels( ["T{}".format(i) for i in range(1, 9)]) for c in range(8): self.twRT.horizontalHeader().setSectionResizeMode( c, QHeaderView.Stretch) self.twRT.setCellWidget(0, c, SpinBox(minimum=0, maximum=32766)) self.twRT.verticalHeader().hide() self.twRT.verticalHeader().setDefaultSectionSize( self.twRT.horizontalHeader().height() * 2 + 1) self.twRT.setMaximumHeight(self.twRT.horizontalHeader().height() + self.twRT.rowHeight(0)) gRT.layout().addWidget(self.twRT) gVM = GroupBoxH("VAR/MEM") vl_VM_func = VLayout(margin=[3, 0, 0, 0]) self.pbVMPoll = QPushButton("Poll") self.pbVMPoll.setCheckable(True) self.pbVMSet = QPushButton("Set") vl_VM_func.addWidgets([self.pbVMPoll, self.pbVMSet]) vl_VM_func.addStretch(1) gVM.layout().addLayout(vl_VM_func) self.twVM = QTableWidget(2, 5) self.twVM.setHorizontalHeaderLabels( ["{}".format(i) for i in range(1, 9)]) self.twVM.setVerticalHeaderLabels(["VAR", "MEM"]) self.twVM.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) for c in range(5): self.twVM.horizontalHeader().setSectionResizeMode( c, QHeaderView.Stretch) for r in range(2): for c in range(5): self.twVM.setCellWidget(r, c, QLineEdit()) self.twVM.verticalHeader().setDefaultSectionSize( self.twVM.horizontalHeader().height()) self.twVM.setMaximumHeight(self.twVM.horizontalHeader().height() + self.twVM.rowHeight(0) * 2) gVM.layout().addWidget(self.twVM) hl_rt_vm = HLayout(0) hl_rt_vm.addWidgets([gRT, gVM]) hl.addLayout(vl_l) vl_r = VLayout(0) self.gbTimers = GroupBoxV("Timers", spacing=5) self.gbTimers.setCheckable(True) self.gbTimers.setChecked(False) self.gbTimers.toggled.connect(self.toggleTimers) self.cbTimer = QComboBox() self.cbTimer.addItems(["Timer{}".format(nr + 1) for nr in range(16)]) self.cbTimer.currentIndexChanged.connect(self.loadTimer) hl_tmr_arm_rpt = HLayout(0) self.cbTimerArm = QCheckBox("Arm") self.cbTimerArm.clicked.connect(lambda x: self.describeTimer()) self.cbTimerRpt = QCheckBox("Repeat") self.cbTimerRpt.clicked.connect(lambda x: self.describeTimer()) hl_tmr_arm_rpt.addWidgets([self.cbTimerArm, self.cbTimerRpt]) hl_tmr_out_act = HLayout(0) self.cbxTimerOut = QComboBox() self.cbxTimerOut.currentIndexChanged.connect( lambda x: self.describeTimer()) self.cbxTimerAction = QComboBox() self.cbxTimerAction.addItems(["Off", "On", "Toggle", "Rule"]) self.cbxTimerAction.currentIndexChanged.connect( lambda x: self.describeTimer()) hl_tmr_out_act.addWidgets([self.cbxTimerOut, self.cbxTimerAction]) self.TimerMode = QButtonGroup() rbTime = QRadioButton("Time") rbSunrise = QRadioButton("Sunrise ({})") rbSunset = QRadioButton("Sunset ({})") self.TimerMode.addButton(rbTime, 0) self.TimerMode.addButton(rbSunrise, 1) self.TimerMode.addButton(rbSunset, 2) self.TimerMode.buttonClicked.connect(lambda x: self.describeTimer()) gbTimerMode = GroupBoxH("Mode") gbTimerMode.addWidgets(self.TimerMode.buttons()) hl_tmr_time = HLayout(0) self.cbxTimerPM = QComboBox() self.cbxTimerPM.addItems(["+", "-"]) self.cbxTimerPM.currentIndexChanged.connect( lambda x: self.describeTimer()) self.TimerMode.buttonClicked[int].connect( lambda x: self.cbxTimerPM.setEnabled(x != 0)) self.teTimerTime = QTimeEdit() self.teTimerTime.setButtonSymbols(QTimeEdit.NoButtons) self.teTimerTime.setAlignment(Qt.AlignCenter) self.teTimerTime.timeChanged.connect(lambda x: self.describeTimer()) lbWnd = QLabel("Window:") lbWnd.setAlignment(Qt.AlignVCenter | Qt.AlignRight) self.cbxTimerWnd = QComboBox() self.cbxTimerWnd.addItems([str(x).zfill(2) for x in range(0, 16)]) self.cbxTimerWnd.currentIndexChanged.connect( lambda x: self.describeTimer()) hl_tmr_days = HLayout(0) self.TimerWeekday = QButtonGroup() self.TimerWeekday.setExclusive(False) for i, wd in enumerate( ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]): cb = QCheckBox(wd) cb.clicked.connect(lambda x: self.describeTimer()) hl_tmr_days.addWidget(cb) self.TimerWeekday.addButton(cb, i) gbTimerDesc = GroupBoxV("Timer description", 5) gbTimerDesc.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding) self.lbTimerDesc = QLabel() self.lbTimerDesc.setAlignment(Qt.AlignCenter) self.lbTimerDesc.setWordWrap(True) gbTimerDesc.layout().addWidget(self.lbTimerDesc) hl_tmr_btns = HLayout(0) btnCopyTrigger = QPushButton("Copy trigger") btnTimerSave = QPushButton("Save") hl_tmr_btns.addWidgets([btnCopyTrigger, btnTimerSave]) hl_tmr_btns.insertStretch(1) btnTimerSave.clicked.connect(self.saveTimer) btnCopyTrigger.clicked.connect(self.copyTrigger) hl_tmr_time.addWidgets( [self.cbxTimerPM, self.teTimerTime, lbWnd, self.cbxTimerWnd]) self.gbTimers.layout().addWidget(self.cbTimer) self.gbTimers.layout().addLayout(hl_tmr_arm_rpt) self.gbTimers.layout().addLayout(hl_tmr_out_act) self.gbTimers.layout().addWidget(gbTimerMode) self.gbTimers.layout().addLayout(hl_tmr_time) self.gbTimers.layout().addLayout(hl_tmr_days) self.gbTimers.layout().addWidget(gbTimerDesc) self.gbTimers.layout().addLayout(hl_tmr_btns) vl_r.addWidget(self.gbTimers) hl.addLayout(vl_r) hl.setStretch(0, 2) hl.setStretch(1, 1) rules.layout().addLayout(hl) rules.layout().addLayout(hl_rt_vm) rules.layout().setStretch(0, 3) rules.layout().setStretch(1, 0) return rules
def __init__(self, device, *args, **kwargs): super(SwitchesDialog, self).__init__(*args, **kwargs) self.setWindowTitle("Switches settings [{}]".format( device.p['FriendlyName1'])) self.setMinimumWidth(300) self.device = device self.commands_list = ["SwitchDebounce", "SwitchRetain"] self.command_widgets = {} self.setoption_list = [32] self.setoption_widgets = {} vl = VLayout() vl_cmd = VLayout(0, 0) for cmd in self.commands_list: cw = Command(cmd, commands[cmd], self.device.p.get(cmd)) vl_cmd.addWidget(cw) self.command_widgets[cmd] = cw self.sm = CommandMultiSelect("SwitchMode", commands["SwitchMode"], self.device.p.get("SwitchMode")) vl_cmd.addWidget(self.sm) vl_cmd.addStretch(1) vl_so = VLayout(0, 0) for so in self.setoption_list: cw = Command("SetOption{}".format(so), setoptions[str(so)], self.device.setoption(so)) vl_so.addWidget(cw) self.setoption_widgets[so] = cw vl_so.addStretch(1) tabs = QTabWidget() tab_cm = QWidget() tab_cm.setLayout(vl_cmd) tabs.addTab(tab_cm, "Settings") tab_so = QWidget() tab_so.setLayout(vl_so) tabs.addTab(tab_so, "SetOptions") vl.addWidget(tabs) btns = QDialogButtonBox(QDialogButtonBox.Save | QDialogButtonBox.Close) btns.accepted.connect(self.accept) btns.rejected.connect(self.reject) vl.addWidgets([ HTMLLabel( "<a href=https://github.com/arendst/Sonoff-Tasmota/wiki/Buttons-and-Switches>Buttons and Switches</a>" ), btns ]) self.setLayout(vl)
def tabRules(self): rules = QWidget() rules.setLayout(VLayout()) for r in range(3): rg = RuleGroupBox(rules, "Rule buffer {}".format(r + 1)) rg.pbLoad.clicked.connect(lambda x, r=r + 1: self.loadRule(r)) self.rule_grps.append(rg) rules.layout().addWidget(rg) rules.layout().setStretch(r, 1) gRT = GroupBoxH("Rule timers") vl_RT_func = VLayout(margin=[0, 0, 3, 0]) self.pbRTPoll = QPushButton("Poll") self.pbRTPoll.setCheckable(True) self.pbRTSet = QPushButton("Set") vl_RT_func.addWidgets([self.pbRTPoll, self.pbRTSet]) vl_RT_func.addStretch(1) gRT.layout().addLayout(vl_RT_func) self.twRT = QTableWidget(1, 8) self.twRT.setHorizontalHeaderLabels( ["T{}".format(i) for i in range(1, 9)]) for c in range(8): self.twRT.horizontalHeader().setSectionResizeMode( c, QHeaderView.Stretch) self.twRT.setCellWidget(0, c, SpinBox(minimum=0, maximum=32766)) self.twRT.verticalHeader().hide() self.twRT.verticalHeader().setDefaultSectionSize( self.twRT.horizontalHeader().height() * 2 + 1) self.twRT.setMaximumHeight(self.twRT.horizontalHeader().height() + self.twRT.rowHeight(0)) gRT.layout().addWidget(self.twRT) gVM = GroupBoxH("VAR/MEM") vl_VM_func = VLayout(margin=[3, 0, 0, 0]) self.pbVMPoll = QPushButton("Poll") self.pbVMPoll.setCheckable(True) self.pbVMSet = QPushButton("Set") vl_VM_func.addWidgets([self.pbVMPoll, self.pbVMSet]) vl_VM_func.addStretch(1) gVM.layout().addLayout(vl_VM_func) self.twVM = QTableWidget(2, 5) self.twVM.setHorizontalHeaderLabels( ["{}".format(i) for i in range(1, 9)]) self.twVM.setVerticalHeaderLabels(["VAR", "MEM"]) self.twVM.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) for c in range(5): self.twVM.horizontalHeader().setSectionResizeMode( c, QHeaderView.Stretch) for r in range(2): for c in range(5): self.twVM.setCellWidget(r, c, QLineEdit()) self.twVM.verticalHeader().setDefaultSectionSize( self.twVM.horizontalHeader().height()) self.twVM.setMaximumHeight(self.twVM.horizontalHeader().height() + self.twVM.rowHeight(0) * 2) gVM.layout().addWidget(self.twVM) hl_rt_vm = HLayout() hl_rt_vm.addWidgets([gRT, gVM]) rules.layout().addLayout(hl_rt_vm) rules.layout().setStretch(3, 0) return rules
def __init__(self, parent, *args, **kwargs): super(ListWidget, self).__init__(*args, **kwargs) self.setWindowTitle("Devices list") self.setWindowState(Qt.WindowMaximized) self.setLayout(VLayout(margin=0, spacing=0)) self.mqtt = parent.mqtt self.env = parent.env self.device = None self.idx = None self.nam = QNetworkAccessManager() self.backup = bytes() self.settings = QSettings("{}/TDM/tdm.cfg".format(QDir.homePath()), QSettings.IniFormat) views_order = self.settings.value("views_order", []) self.views = {} self.settings.beginGroup("Views") views = self.settings.childKeys() if views and views_order: for view in views_order.split(";"): view_list = self.settings.value(view).split(";") self.views[view] = base_view + view_list else: self.views = default_views self.settings.endGroup() self.tb = Toolbar(Qt.Horizontal, 24, Qt.ToolButtonTextBesideIcon) self.tb_relays = Toolbar(Qt.Horizontal, 24, Qt.ToolButtonIconOnly) # self.tb_filter = Toolbar(Qt.Horizontal, 24, Qt.ToolButtonTextBesideIcon) self.tb_views = Toolbar(Qt.Horizontal, 24, Qt.ToolButtonTextBesideIcon) self.pwm_sliders = [] self.layout().addWidget(self.tb) self.layout().addWidget(self.tb_relays) # self.layout().addWidget(self.tb_filter) self.device_list = TableView() self.device_list.setIconSize(QSize(24, 24)) self.model = parent.device_model self.model.setupColumns(self.views["Home"]) self.sorted_device_model = QSortFilterProxyModel() self.sorted_device_model.setFilterCaseSensitivity(Qt.CaseInsensitive) self.sorted_device_model.setSourceModel(parent.device_model) self.sorted_device_model.setSortRole(Qt.InitialSortOrderRole) self.sorted_device_model.setFilterKeyColumn(-1) self.device_list.setModel(self.sorted_device_model) self.device_list.setupView(self.views["Home"]) self.device_list.setSortingEnabled(True) self.device_list.setWordWrap(True) self.device_list.setItemDelegate(DeviceDelegate()) self.device_list.sortByColumn(self.model.columnIndex("FriendlyName"), Qt.AscendingOrder) self.device_list.setContextMenuPolicy(Qt.CustomContextMenu) self.device_list.verticalHeader().setSectionResizeMode(QHeaderView.ResizeToContents) self.layout().addWidget(self.device_list) self.layout().addWidget(self.tb_views) self.device_list.clicked.connect(self.select_device) self.device_list.customContextMenuRequested.connect(self.show_list_ctx_menu) self.ctx_menu = QMenu() self.ctx_menu_relays = None self.create_actions() self.create_view_buttons() # self.create_view_filter() self.device_list.doubleClicked.connect(lambda: self.openConsole.emit())
def tabInformation(self): info = QWidget() vl = VLayout() self.program_model = QStandardItemModel() for d in [ "Program version", "Build date & time", "Core/SDK version", "Flash write count", "Boot count", "Restart reason", "Friendly Name 1", "Friendly Name 2", "Friendly Name 3", "Friendly Name 4" ]: k = QStandardItem(d) k.setEditable(False) v = QStandardItem() v.setTextAlignment(Qt.AlignVCenter | Qt.AlignRight) v.setEditable(False) self.program_model.appendRow([k, v]) gbPrgm = GroupBoxH("Program") gbPrgm.setFlat(True) tvPrgm = QTreeView() tvPrgm.setHeaderHidden(True) tvPrgm.setRootIsDecorated(False) tvPrgm.setModel(self.program_model) tvPrgm.resizeColumnToContents(0) gbPrgm.addWidget(tvPrgm) self.esp_model = QStandardItemModel() for d in [ "ESP Chip Id", "Flash Chip Id", "Flash Size", "Program Flash Size", "Program Size", "Free Program Space", "Free Memory" ]: k = QStandardItem(d) k.setEditable(False) v = QStandardItem() v.setTextAlignment(Qt.AlignVCenter | Qt.AlignRight) v.setEditable(False) self.esp_model.appendRow([k, v]) gbESP = GroupBoxH("ESP") gbESP.setFlat(True) tvESP = QTreeView() tvESP.setHeaderHidden(True) tvESP.setRootIsDecorated(False) tvESP.setModel(self.esp_model) tvESP.resizeColumnToContents(0) gbESP.addWidget(tvESP) # self.emul_model = QStandardItemModel() # for d in ["Emulation", "mDNS Discovery"]: # k = QStandardItem(d) # k.setEditable(False) # v = QStandardItem() # v.setTextAlignment(Qt.AlignVCenter | Qt.AlignRight) # v.setEditable(False) # self.emul_model.appendRow([k, v]) # # gbEmul = GroupBoxH("Emulation") # gbEmul.setFlat(True) # tvEmul = QTreeView() # tvEmul.setHeaderHidden(True) # tvEmul.setRootIsDecorated(False) # tvEmul.setModel(self.emul_model) # tvEmul.resizeColumnToContents(0) # gbEmul.addWidget(tvEmul) self.wifi_model = QStandardItemModel() for d in [ "AP1 SSId (RSSI)", "Hostname", "IP Address", "Gateway", "Subnet Mask", "DNS Server", "MAC Address" ]: k = QStandardItem(d) k.setEditable(False) v = QStandardItem() v.setTextAlignment(Qt.AlignVCenter | Qt.AlignRight) v.setEditable(False) self.wifi_model.appendRow([k, v]) gbWifi = GroupBoxH("Wifi") gbWifi.setFlat(True) tvWifi = QTreeView() tvWifi.setHeaderHidden(True) tvWifi.setRootIsDecorated(False) tvWifi.setModel(self.wifi_model) tvWifi.resizeColumnToContents(0) gbWifi.addWidget(tvWifi) self.mqtt_model = QStandardItemModel() for d in [ "MQTT Host", "MQTT Port", "MQTT User", "MQTT Client", "MQTT Topic", "MQTT Group Topic", "MQTT Full Topic", "MQTT Fallback Topic" ]: k = QStandardItem(d) k.setEditable(False) v = QStandardItem() v.setTextAlignment(Qt.AlignVCenter | Qt.AlignRight) v.setEditable(False) self.mqtt_model.appendRow([k, v]) gbMQTT = GroupBoxH("MQTT") gbMQTT.setFlat(True) tvMQTT = QTreeView() tvMQTT.setHeaderHidden(True) tvMQTT.setRootIsDecorated(False) tvMQTT.setModel(self.mqtt_model) tvMQTT.resizeColumnToContents(0) gbMQTT.addWidget(tvMQTT) hl = HLayout(0) vl_lc = VLayout(0, 3) vl_rc = VLayout(0, 3) vl_lc.addWidgets([gbPrgm, gbESP]) vl_rc.addWidgets([gbWifi, gbMQTT]) vl_rc.setStretch(0, 2) vl_rc.setStretch(1, 2) vl_rc.setStretch(2, 1) hl.addLayout(vl_lc) hl.addLayout(vl_rc) vl.addLayout(hl) info.setLayout(vl) return info