Beispiel #1
0
    def applyFilterSettings(self, name):

        if name == self._observation:
            reg = QSettings()
            reg.beginGroup(self._session)
            reg.beginGroup(self._observation)
            self._displayFormat = reg.value(
                "display", int(TopicDisplay.EMPHASIZEDCORRESPONDENT), type=int)
            self._filter1 = reg.value("filter 1", '')
            self._filter2 = reg.value("filter 2", '')
            self._filter3 = reg.value("filter 1", '')
            self._filter4 = reg.value("filter 4", '')
            self._bufferSize = reg.value("buffer size", 50000, type=int)
            self._hiddenCorrespondents = []
            if "Hidden correspondents" in reg.childGroups():
                reg.beginGroup("Hidden correspondents")
                for p in reg.childKeys():
                    self._hiddenCorrespondents.append(p.replace('\\', '/'))
                reg.endGroup()
            self._hiddenTopics = []
            if "Hidden topics" in reg.childGroups():
                reg.beginGroup("Hidden topics")
                for t in reg.childKeys():
                    self._hiddenTopics.append(t.replace('\\', '/'))
                reg.endGroup()
            reg.endGroup()
            reg.endGroup()
Beispiel #2
0
class qTorObject(object):
    """
    The configuration of the machine's qBittorrent with a human-readable data structure
    """
    def __init__(self, path: str):
        if not isfile(path):
            raise FileNotFoundError(
                f"The configuration file {sp(path)[-1]} does not exist.")
        self.settings = QSettings(path, QSettings.IniFormat)
        self._data = {}  # type: dict
        self._goDeep(self._data)

    def _goDeep(self, conf: dict) -> dict:
        for key in self.settings.childKeys():
            conf[key] = self.settings.value(key)
        if self.settings.childGroups():
            for group in self.settings.childGroups():
                self.settings.beginGroup(group)
                conf[group] = {}
                self._goDeep(conf[group])
                self.settings.endGroup()
        else:
            pass
        return conf

    @property
    def data(self) -> dict:
        return self._data
Beispiel #3
0
 def loadClueAlbum(self, filename):
     # keys with ',' are read as list and will be joined back
     if os.path.isfile(filename):
         album = QSettings(filename, QSettings.IniFormat)
         album.setIniCodec("UTF-8");
         for group in album.childGroups():
             album.beginGroup(group)
             key = group
             if not 'fr' in album.childKeys():
                 self._logger.warning(
                     "{} [{}] : {}".format(self.tr("Clue"), group, self.tr("ignored because 'fr' is missing")))
                 continue
             if not 'en' in album.childKeys():
                 self._logger.warning(
                     "{} [{}] : {}".format(self.tr("Clue"), group, self.tr("ignored because 'en' is missing")))
                 continue
             try:
                 title = album.value('en')
                 if '|' in title:
                     en = re.compile(r'\s*\|\s*').split(title)
                 else:
                     en = (title, '')
                 text = album.value('fr')
                 if '|' in text:
                     fr = re.compile(r'\s*\|\s*').split(text)
                 else:
                     fr = (text, '')
                 self._clues[key] = Clue(title, fr, en)
             except:
                 self._logger.warning("{} {}".format(self.tr("Failed to load clue : "), key))
             album.endGroup()
Beispiel #4
0
def get_record_list(friend_id):
    record = []
    if not os.path.exists(GlobalVariable.RecordDataDirectory + friend_id +
                          ".ini"):
        return None
    mem_file = QSettings(
        GlobalVariable.RecordDataDirectory + friend_id + ".ini",
        QSettings.IniFormat)
    child = mem_file.childGroups()
    for msg_id in child:
        mem_file.beginGroup(msg_id)
        temp = Record.get_record_object("text")
        temp.Time = mem_file.value("Time")
        temp.MsgId = msg_id
        if mem_file.value("ISend") == "1":
            temp.Sender = get_local_id()
        else:
            temp.Sender = mem_file.value("Sender")
        temp.Content = mem_file.value("Content")
        record.append(temp)
        mem_file.endGroup()
    del mem_file
    cmpfun = operator.attrgetter('Time')
    record.sort(key=cmpfun)
    return record
 def getServers(self):
     """
     Gets all servers from QSettings
     """
     settings = QSettings()
     settings.beginGroup('PostgreSQL/connections/')
     currentConnections = settings.childGroups()
     settings.endGroup()
     return currentConnections
    def apply(self):

        reg = QSettings()

        if self._mqttPortInput.text().isdecimal():
            port = int(self._mqttPortInput.text())
        else:
            port = 1883

        try:
            port_in_reg = reg.value("port", 1883, type=int)
        except:
            port_in_reg = 1883

        reg.beginGroup(self._session)
        self._logger.info(self.tr("Current session : ") + self._session)
        self._logger.info("{0} : {1} -> {2}".format(
            self.tr("Apply settings for server host"),
            reg.value("host", 'localhost'),
            self._mqttServerInput.text().replace('/', '')))
        self._logger.info("{0} : {1} -> {2}".format(
            self.tr("Apply settings for server port"), str(port_in_reg),
            str(port)))
        self._logger.info("{0} : {1} -> {2}".format(
            self.tr("Apply settings for room topic"),
            reg.value("root topic", ''), self._mqttTopicInput.text()))
        reg.endGroup()

        reg.beginGroup(self._session)
        reg.setValue("host", self._mqttServerInput.text().replace('/', ''))
        reg.setValue("port", port)
        reg.setValue("root topic", self._mqttTopicInput.text())
        reg.endGroup()
        reg.sync()

        new_session = self._sessionNameInput.text().strip()
        if new_session and new_session != self._session:
            reg_from = QSettings()
            reg_from.beginGroup(self._session)
            reg_to = QSettings()
            reg_to.beginGroup(new_session)
            for k in reg_from.childKeys():
                reg_to.setValue(k, reg_from.value(k))
            for g in reg_from.childGroups():
                reg_from.beginGroup(g)
                reg_to.beginGroup(g)
                for k in reg_from.childKeys():
                    reg_to.setValue(k, reg_from.value(k))
                reg_from.endGroup()
                reg_to.endGroup()
            reg_from.endGroup()
            reg_to.endGroup()
            reg.setValue("current session", new_session)
            Timer(0, self.reloadSession.emit).start()

        self.accept()
Beispiel #7
0
    def addDisplay(self, title=None):

        if not title:
            if self._countUntitledDisplay:
                title = "{0} ({1})".format(self.tr("New observation"),
                                           self._countUntitledDisplay)
            else:
                title = self.tr("New observation")
            self._countUntitledDisplay = self._countUntitledDisplay + 1
            reg = QSettings()
            reg.beginGroup(self._session)
            if title not in reg.childGroups():
                reg.beginGroup(title)
                reg.setValue("display",
                             int(TopicDisplay.EMPHASIZEDCORRESPONDENT))
                reg.endGroup()
            reg.endGroup()
            reg.sync()

        root_observation = not len(self._displays)

        new_display = ObserverDisplayWidget(title,
                                            self._logger,
                                            self._session,
                                            self._mqttServerHost,
                                            self._mqttServerPort,
                                            self._mqttRootTopic,
                                            remove=not root_observation,
                                            filter=not root_observation)

        new_display.addObservation.connect(self.addDisplay)
        new_display.delObservation.connect(self.removeCurrentDisplay)
        self.newFilterSettingsApplied.connect(new_display.applyFilterSettings)

        self._displays.append(new_display)
        self._tabWidget.addTab(new_display, title)

        self.resetDisplays.connect(new_display.reset)
        self.messageReceived.connect(new_display.processMessage)
        new_display.newFilterSettings.connect(self.applyFilterSettings)
        new_display.resetWills.connect(self.applyResetWills)

        self._tabWidget.setCurrentWidget(new_display)

        self._logger.info("{0} : {1}".format(self.tr("Added observation"),
                                             title))

        dspmsg = ''
        for d in self._displays:
            if dspmsg:
                dspmsg += ' | '
            else:
                dspmsg = 'Displays : '
            dspmsg += d.title()
        self._logger.debug(dspmsg)
Beispiel #8
0
    def updateLocationsTable(self):
        self.locationsTable.setUpdatesEnabled(False)
        self.locationsTable.setRowCount(0)

        for i in range(2):
            if i == 0:
                if self.scope() == QSettings.SystemScope:
                    continue

                actualScope = QSettings.UserScope
            else:
                actualScope = QSettings.SystemScope

            for j in range(2):
                if j == 0:
                    if not self.application():
                        continue

                    actualApplication = self.application()
                else:
                    actualApplication = ""

                settings = QSettings(
                    self.format(), actualScope, self.organization(), actualApplication
                )

                row = self.locationsTable.rowCount()
                self.locationsTable.setRowCount(row + 1)

                item0 = QTableWidgetItem()
                item0.setText(settings.fileName())

                item1 = QTableWidgetItem()
                disable = not (settings.childKeys() or settings.childGroups())

                if row == 0:
                    if settings.isWritable():
                        item1.setText("Read-write")
                        disable = False
                    else:
                        item1.setText("Read-only")
                    self.buttonBox.button(QDialogButtonBox.Ok).setDisabled(disable)
                else:
                    item1.setText("Read-only fallback")

                if disable:
                    item0.setFlags(item0.flags() & ~Qt.ItemIsEnabled)
                    item1.setFlags(item1.flags() & ~Qt.ItemIsEnabled)

                self.locationsTable.setItem(row, 0, item0)
                self.locationsTable.setItem(row, 1, item1)

        self.locationsTable.setUpdatesEnabled(True)
Beispiel #9
0
    def updateLocationsTable(self):
        self.locationsTable.setUpdatesEnabled(False)
        self.locationsTable.setRowCount(0)

        for i in range(2):
            if i == 0:
                if self.scope() == QSettings.SystemScope:
                    continue

                actualScope = QSettings.UserScope
            else:
                actualScope = QSettings.SystemScope

            for j in range(2):
                if j == 0:
                    if not self.application():
                        continue

                    actualApplication = self.application()
                else:
                    actualApplication = ''

                settings = QSettings(self.format(), actualScope,
                        self.organization(), actualApplication)

                row = self.locationsTable.rowCount()
                self.locationsTable.setRowCount(row + 1)

                item0 = QTableWidgetItem()
                item0.setText(settings.fileName())

                item1 = QTableWidgetItem()
                disable = not (settings.childKeys() or settings.childGroups())

                if row == 0:
                    if settings.isWritable():
                        item1.setText("Read-write")
                        disable = False
                    else:
                        item1.setText("Read-only")
                    self.buttonBox.button(QDialogButtonBox.Ok).setDisabled(disable)
                else:
                    item1.setText("Read-only fallback")

                if disable:
                    item0.setFlags(item0.flags() & ~Qt.ItemIsEnabled)
                    item1.setFlags(item1.flags() & ~Qt.ItemIsEnabled)

                self.locationsTable.setItem(row, 0, item0)
                self.locationsTable.setItem(row, 1, item1)

        self.locationsTable.setUpdatesEnabled(True)
Beispiel #10
0
 def showEvent(self, event: QtGui.QShowEvent) -> None:
     domains = []
     setting = QSettings()
     # MacOS: ~/Library/Preferences/QCoreApplication.organizationDomain().QCoreApplication.applicationName().plist
     # Linux: ~/.config/QCoreApplication.organizationName()/QCoreApplication.applicationName().conf
     # print(f"Setting storage: {setting.fileName()}")
     if "domains" in setting.childGroups():
         setting.beginGroup("domains")
         domains = setting.childKeys()
         setting.endGroup()
     if not domains:
         domains = configurations.get("domains")
     self.ui.textEdit.setPlainText(f"{os.linesep}".join(list(domains)))
Beispiel #11
0
    def load_from_qsetting(self,
                           setting_class: str) -> Dict[str, PrintSetting]:
        settings = QSettings()
        settings.beginGroup(setting_class)

        ls_setting_dict = OrderedDict()
        for setting_name in settings.childGroups():
            settings.beginGroup(setting_name)
            q_path = '%s/%s' % (setting_class, setting_name)
            process_type = settings.value('process', type=str)
            setting_dict = {}
            for param in settings.childGroups():
                settings.beginGroup(param)
                param_type = settings.value('type', type=str)
                entry_obj = MAP_TYPE[param_type]
                entry_inst = entry_obj(param, parent_key=setting_name)

                if setting_class == SettingTypeKey.printer.value:
                    entry_inst.update_val.connect(self.printer_update_cb)
                elif setting_class == SettingTypeKey.printhead.value:
                    entry_inst.update_val.connect(self.printhead_update_cb)
                elif setting_class == SettingTypeKey.print_param.value:
                    entry_inst.update_val.connect(self.print_param_update_cb)
                else:
                    raise ValueError('unknown setting class {%s}' %
                                     (setting_class))

                entry_inst.load_entry(q_path)
                setting_dict[param] = entry_inst
                settings.endGroup()
            settings.endGroup()

            ls_setting_dict[setting_name] = SETTING_TYPE_MAP[setting_class][
                process_type](**setting_dict)
            self.add_setting_signal.emit(setting_class, setting_name)
        settings.endGroup()

        return ls_setting_dict
Beispiel #12
0
 def findkey_from_interface(interface_name):
     """
     通过网络接口名字查找注册表位置
     :param interface_name:string 网络接口
     :return:QSettings 注册表对象
     """
     logging.debug("查找接口名为{0}的注册表对象".format(interface_name))
     #key_str="HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}"
     key_str = "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}"
     key = QSettings(key_str, QSettings.NativeFormat)
     dev_reg = None
     for x in key.childGroups():
         key_str2 = key_str + "\\" + x
         key2 = QSettings(key_str2, QSettings.NativeFormat)
         if key2.value("DriverDesc", "-1") == interface_name:
             dev_reg = key2
             logging.debug("成功查找到{0}的注册表对象\n地址为:{1}".format(
                 interface_name, dev_reg.fileName()))
     return dev_reg
Beispiel #13
0
    def onBrowseConnection(self):
        s = QSettings()
        base = "/PostgreSQL/connections"
        s.beginGroup("/PostgreSQL/connections")
        children = s.childGroups()
        connections = {}
        map = {
            "dbname": "database",
            "host": "host",
            "port": "port",
            "service": "service",
            "password": "******",
            "user": "******",
            "sslmode": "sslmode"
        }
        for g in children:
            s.beginGroup(g)
            cstring = ""
            for k, v in map.items():
                # Strings attributes.
                if s.value(v) and k != "sslmode":
                    cstring += k + "=" + s.value(v) + " "

                # Enum attributes (Ssl mode).
                elif s.value(v) and k == "sslmode":
                    mode = self.sslModeToString(s.value(v))
                    if mode != "":
                        cstring += k + "=" + mode + " "

            connections[g] = cstring
            s.endGroup()

        menu = QMenu(self)
        for k in sorted(connections.keys()):
            menu.addAction(k)

        def onMenu(action):
            self.dbConnectionText.setText(connections[action.text()])
            self.reloadBtn.click()

        menu.triggered.connect(onMenu)
        menu.exec_(self.dbConnectionBtn.mapToGlobal(QPoint(0, 0)))
Beispiel #14
0
    def initDatabaseConenctionsList(self):
        QgsMessageLog.logMessage('Init Connections List')

        self.dockwidget.connectionsComboBox.clear()

        s = QSettings()
        s.beginGroup("PostgreSQL/connections")

        keys = s.childGroups()

        if (len(keys) == 0):
            QgsMessageLog.logMessage("No database connections found",
                                     self.pluginName)
            return ()

        for key in keys:
            self.dockwidget.connectionsComboBox.addItem(str(key))
            QgsMessageLog.logMessage(key,  self.pluginName)

        s.endGroup()

        # Use the first connection to connect to the database
        self.onConnectDatabase(keys[0])
Beispiel #15
0
    def _buildUi(self):
        self._options = {}
        if os.path.isfile('definitions.ini'):
            definitions = QSettings('definitions.ini', QSettings.IniFormat)
            for group in definitions.childGroups():
                definitions.beginGroup(group)
                if group == "options":
                    for key in definitions.childKeys():
                        self._options[key] = definitions.value(key)
                definitions.endGroup()

        main_layout = QVBoxLayout()
        main_layout.setSpacing(12)

        self._led = LedWidget(self.tr("Props name"), QSize(40, 20))
        self._led.setRedAsBold(True)
        self._led.setRedAsRed(True)
        self._led.switchOn('gray')

        settings_button = QPushButton()
        settings_button.setIcon(QIcon("./images/settings.svg"))
        settings_button.setFlat(True)
        settings_button.setToolTip(self.tr("Configuration"))
        settings_button.setIconSize(QSize(16, 16))
        settings_button.setFixedSize(QSize(24, 24))

        header_layout = QHBoxLayout()
        header_layout.addWidget(self._led)
        header_layout.addWidget(settings_button, Qt.AlignRight)
        main_layout.addLayout(header_layout)

        main_layout.addStretch(0)

        self.setLayout(main_layout)

        settings_button.pressed.connect(self.settings)
        self.switchLed.connect(self._led.switchOn)
Beispiel #16
0
class MainWindow(QMainWindow):
    def __init__(self, *args, **kwargs):
        super(MainWindow, self).__init__(*args, **kwargs)
        self._version = __version__
        self.setWindowIcon(QIcon(":/logo.png"))
        self.setWindowTitle("Tasmota Device Manager {}".format(self._version))

        self.unknown = []
        self.env = TasmotaEnvironment()
        self.device = None

        self.topics = []
        self.mqtt_queue = []
        self.fulltopic_queue = []

        # ensure TDM directory exists in the user directory
        if not os.path.isdir("{}/TDM".format(QDir.homePath())):
            os.mkdir("{}/TDM".format(QDir.homePath()))

        self.settings = QSettings("{}/TDM/tdm.cfg".format(QDir.homePath()),
                                  QSettings.IniFormat)
        self.devices = QSettings("{}/TDM/devices.cfg".format(QDir.homePath()),
                                 QSettings.IniFormat)
        self.setMinimumSize(QSize(1000, 600))

        # configure logging
        logging.basicConfig(filename="{}/TDM/tdm.log".format(QDir.homePath()),
                            level=self.settings.value("loglevel", "INFO"),
                            datefmt="%Y-%m-%d %H:%M:%S",
                            format='%(asctime)s [%(levelname)s] %(message)s')
        logging.info("### TDM START ###")

        # load devices from the devices file, create TasmotaDevices and add the to the envvironment
        for mac in self.devices.childGroups():
            self.devices.beginGroup(mac)
            device = TasmotaDevice(self.devices.value("topic"),
                                   self.devices.value("full_topic"),
                                   self.devices.value("friendly_name"))
            device.debug = self.devices.value("debug", False, bool)
            device.p['Mac'] = mac.replace("-", ":")
            device.env = self.env
            self.env.devices.append(device)

            # load device command history
            self.devices.beginGroup("history")
            for k in self.devices.childKeys():
                device.history.append(self.devices.value(k))
            self.devices.endGroup()

            self.devices.endGroup()

        self.device_model = TasmotaDevicesModel(self.env)

        self.setup_mqtt()
        self.setup_main_layout()
        self.add_devices_tab()
        self.build_mainmenu()
        # self.build_toolbars()
        self.setStatusBar(QStatusBar())

        pbSubs = QPushButton("Show subscriptions")
        pbSubs.setFlat(True)
        pbSubs.clicked.connect(self.showSubs)
        self.statusBar().addPermanentWidget(pbSubs)

        self.queue_timer = QTimer()
        self.queue_timer.timeout.connect(self.mqtt_publish_queue)
        self.queue_timer.start(250)

        self.auto_timer = QTimer()
        self.auto_timer.timeout.connect(self.auto_telemetry)

        self.load_window_state()

        if self.settings.value("connect_on_startup", False, bool):
            self.actToggleConnect.trigger()

        self.tele_docks = {}
        self.consoles = []

    def setup_main_layout(self):
        self.mdi = QMdiArea()
        self.mdi.setActivationOrder(QMdiArea.ActivationHistoryOrder)
        self.mdi.setTabsClosable(True)
        self.setCentralWidget(self.mdi)

    def setup_mqtt(self):
        self.mqtt = MqttClient()
        self.mqtt.connecting.connect(self.mqtt_connecting)
        self.mqtt.connected.connect(self.mqtt_connected)
        self.mqtt.disconnected.connect(self.mqtt_disconnected)
        self.mqtt.connectError.connect(self.mqtt_connectError)
        self.mqtt.messageSignal.connect(self.mqtt_message)

    def add_devices_tab(self):
        self.devices_list = ListWidget(self)
        sub = self.mdi.addSubWindow(self.devices_list)
        sub.setWindowState(Qt.WindowMaximized)
        self.devices_list.deviceSelected.connect(self.selectDevice)
        self.devices_list.openConsole.connect(self.openConsole)
        self.devices_list.openRulesEditor.connect(self.openRulesEditor)
        self.devices_list.openTelemetry.connect(self.openTelemetry)
        self.devices_list.openWebUI.connect(self.openWebUI)

    def load_window_state(self):
        wndGeometry = self.settings.value('window_geometry')
        if wndGeometry:
            self.restoreGeometry(wndGeometry)

    def build_mainmenu(self):
        mMQTT = self.menuBar().addMenu("MQTT")
        self.actToggleConnect = QAction(QIcon(":/disconnect.png"), "Connect")
        self.actToggleConnect.setCheckable(True)
        self.actToggleConnect.toggled.connect(self.toggle_connect)
        mMQTT.addAction(self.actToggleConnect)

        mMQTT.addAction(QIcon(), "Broker", self.setup_broker)
        mMQTT.addAction(QIcon(), "Autodiscovery patterns", self.patterns)

        mMQTT.addSeparator()
        mMQTT.addAction(QIcon(), "Clear obsolete retained LWTs",
                        self.clear_LWT)

        mMQTT.addSeparator()
        mMQTT.addAction(QIcon(), "Auto telemetry period",
                        self.auto_telemetry_period)

        self.actToggleAutoUpdate = QAction(QIcon(":/auto_telemetry.png"),
                                           "Auto telemetry")
        self.actToggleAutoUpdate.setCheckable(True)
        self.actToggleAutoUpdate.toggled.connect(self.toggle_autoupdate)
        mMQTT.addAction(self.actToggleAutoUpdate)

        mSettings = self.menuBar().addMenu("Settings")
        mSettings.addAction(QIcon(), "BSSId aliases", self.bssid)
        mSettings.addSeparator()
        mSettings.addAction(QIcon(), "Preferences", self.prefs)

        # mExport = self.menuBar().addMenu("Export")
        # mExport.addAction(QIcon(), "OpenHAB", self.openhab)

    def build_toolbars(self):
        main_toolbar = Toolbar(orientation=Qt.Horizontal,
                               iconsize=24,
                               label_position=Qt.ToolButtonTextBesideIcon)
        main_toolbar.setObjectName("main_toolbar")

    def initial_query(self, device, queued=False):
        for c in initial_commands():
            cmd, payload = c
            cmd = device.cmnd_topic(cmd)

            if queued:
                self.mqtt_queue.append([cmd, payload])
            else:
                self.mqtt.publish(cmd, payload, 1)

    def setup_broker(self):
        brokers_dlg = BrokerDialog()
        if brokers_dlg.exec_(
        ) == QDialog.Accepted and self.mqtt.state == self.mqtt.Connected:
            self.mqtt.disconnect()

    def toggle_autoupdate(self, state):
        if state == True:
            if self.mqtt.state == self.mqtt.Connected:
                for d in self.env.devices:
                    self.mqtt.publish(d.cmnd_topic('STATUS'), payload=8)
            self.auto_timer.setInterval(
                self.settings.value("autotelemetry", 5000, int))
            self.auto_timer.start()
        else:
            self.auto_timer.stop()

    def toggle_connect(self, state):
        if state and self.mqtt.state == self.mqtt.Disconnected:
            self.broker_hostname = self.settings.value('hostname', 'localhost')
            self.broker_port = self.settings.value('port', 1883, int)
            self.broker_username = self.settings.value('username')
            self.broker_password = self.settings.value('password')

            self.mqtt.hostname = self.broker_hostname
            self.mqtt.port = self.broker_port

            if self.broker_username:
                self.mqtt.setAuth(self.broker_username, self.broker_password)
            self.mqtt.connectToHost()
        elif not state and self.mqtt.state == self.mqtt.Connected:
            self.mqtt_disconnect()

    def auto_telemetry(self):
        if self.mqtt.state == self.mqtt.Connected:
            for d in self.env.devices:
                self.mqtt.publish(d.cmnd_topic('STATUS'), payload=8)

    def mqtt_connect(self):
        self.broker_hostname = self.settings.value('hostname', 'localhost')
        self.broker_port = self.settings.value('port', 1883, int)
        self.broker_username = self.settings.value('username')
        self.broker_password = self.settings.value('password')

        self.mqtt.hostname = self.broker_hostname
        self.mqtt.port = self.broker_port

        if self.broker_username:
            self.mqtt.setAuth(self.broker_username, self.broker_password)

        if self.mqtt.state == self.mqtt.Disconnected:
            self.mqtt.connectToHost()

    def mqtt_disconnect(self):
        self.mqtt.disconnectFromHost()

    def mqtt_connecting(self):
        self.statusBar().showMessage("Connecting to broker")

    def mqtt_connected(self):
        self.actToggleConnect.setIcon(QIcon(":/connect.png"))
        self.actToggleConnect.setText("Disconnect")
        self.statusBar().showMessage("Connected to {}:{} as {}".format(
            self.broker_hostname, self.broker_port,
            self.broker_username if self.broker_username else '[anonymous]'))

        self.mqtt_subscribe()

    def mqtt_subscribe(self):
        # clear old topics
        self.topics.clear()
        custom_patterns.clear()

        # load custom autodiscovery patterns
        self.settings.beginGroup("Patterns")
        for k in self.settings.childKeys():
            custom_patterns.append(self.settings.value(k))
        self.settings.endGroup()

        # expand fulltopic patterns to subscribable topics
        for pat in default_patterns:  # tasmota default and SO19
            self.topics += expand_fulltopic(pat)

        # check if custom patterns can be matched by default patterns
        for pat in custom_patterns:
            if pat.startswith("%prefix%") or pat.split('/')[1] == "%prefix%":
                continue  # do nothing, default subcriptions will match this topic
            else:
                self.topics += expand_fulltopic(pat)

        for d in self.env.devices:
            # if device has a non-standard pattern, check if the pattern is found in the custom patterns
            if not d.is_default() and d.p['FullTopic'] not in custom_patterns:
                # if pattern is not found then add the device topics to subscription list.
                # if the pattern is found, it will be matched without implicit subscription
                self.topics += expand_fulltopic(d.p['FullTopic'])

        # passing a list of tuples as recommended by paho
        self.mqtt.subscribe([(topic, 0) for topic in self.topics])

    @pyqtSlot(str, str)
    def mqtt_publish(self, t, p):
        self.mqtt.publish(t, p)

    def mqtt_publish_queue(self):
        for q in self.mqtt_queue:
            t, p = q
            self.mqtt.publish(t, p)
            self.mqtt_queue.pop(self.mqtt_queue.index(q))

    def mqtt_disconnected(self):
        self.actToggleConnect.setIcon(QIcon(":/disconnect.png"))
        self.actToggleConnect.setText("Connect")
        self.statusBar().showMessage("Disconnected")

    def mqtt_connectError(self, rc):
        reason = {
            1: "Incorrect protocol version",
            2: "Invalid client identifier",
            3: "Server unavailable",
            4: "Bad username or password",
            5: "Not authorized",
        }
        self.statusBar().showMessage("Connection error: {}".format(reason[rc]))
        self.actToggleConnect.setChecked(False)

    def mqtt_message(self, topic, msg):
        # try to find a device by matching known FullTopics against the MQTT topic of the message
        device = self.env.find_device(topic)
        if device:
            if topic.endswith("LWT"):
                if not msg:
                    msg = "Offline"
                device.update_property("LWT", msg)

                if msg == 'Online':
                    # known device came online, query initial state
                    self.initial_query(device, True)

            else:
                # forward the message for processing
                device.parse_message(topic, msg)
                if device.debug:
                    logging.debug("MQTT: %s %s", topic, msg)

        else:  # unknown device, start autodiscovery process
            if topic.endswith("LWT"):
                self.env.lwts.append(topic)
                logging.info("DISCOVERY: LWT from an unknown device %s", topic)

                # STAGE 1
                # load default and user-provided FullTopic patterns and for all the patterns,
                # try matching the LWT topic (it follows the device's FullTopic syntax

                for p in default_patterns + custom_patterns:
                    match = re.fullmatch(
                        p.replace("%topic%", "(?P<topic>.*?)").replace(
                            "%prefix%", "(?P<prefix>.*?)") + ".*$", topic)
                    if match:
                        # assume that the matched topic is the one configured in device settings
                        possible_topic = match.groupdict().get('topic')
                        if possible_topic not in ('tele', 'stat'):
                            # if the assumed topic is different from tele or stat, there is a chance that it's a valid topic
                            # query the assumed device for its FullTopic. False positives won't reply.
                            possible_topic_cmnd = p.replace(
                                "%prefix%", "cmnd").replace(
                                    "%topic%", possible_topic) + "FullTopic"
                            logging.debug(
                                "DISCOVERY: Asking an unknown device for FullTopic at %s",
                                possible_topic_cmnd)
                            self.mqtt_queue.append([possible_topic_cmnd, ""])

            elif topic.endswith("RESULT") or topic.endswith(
                    "FULLTOPIC"):  # reply from an unknown device
                # STAGE 2
                full_topic = loads(msg).get('FullTopic')
                if full_topic:
                    # the device replies with its FullTopic
                    # here the Topic is extracted using the returned FullTopic, identifying the device
                    parsed = parse_topic(full_topic, topic)
                    if parsed:
                        # got a match, we query the device's MAC address in case it's a known device that had its topic changed
                        logging.debug(
                            "DISCOVERY: topic %s is matched by fulltopic %s",
                            topic, full_topic)

                        d = self.env.find_device(topic=parsed['topic'])
                        if d:
                            d.update_property("FullTopic", full_topic)
                        else:
                            logging.info(
                                "DISCOVERY: Discovered topic=%s with fulltopic=%s",
                                parsed['topic'], full_topic)
                            d = TasmotaDevice(parsed['topic'], full_topic)
                            self.env.devices.append(d)
                            self.device_model.addDevice(d)
                            logging.debug(
                                "DISCOVERY: Sending initial query to topic %s",
                                parsed['topic'])
                            self.initial_query(d, True)
                            self.env.lwts.remove(d.tele_topic("LWT"))
                        d.update_property("LWT", "Online")

    def export(self):
        fname, _ = QFileDialog.getSaveFileName(self,
                                               "Export device list as...",
                                               directory=QDir.homePath(),
                                               filter="CSV files (*.csv)")
        if fname:
            if not fname.endswith(".csv"):
                fname += ".csv"

            with open(fname, "w", encoding='utf8') as f:
                column_titles = [
                    'mac', 'topic', 'friendly_name', 'full_topic',
                    'cmnd_topic', 'stat_topic', 'tele_topic', 'module',
                    'module_id', 'firmware', 'core'
                ]
                c = csv.writer(f)
                c.writerow(column_titles)

                for r in range(self.device_model.rowCount()):
                    d = self.device_model.index(r, 0)
                    c.writerow([
                        self.device_model.mac(d),
                        self.device_model.topic(d),
                        self.device_model.friendly_name(d),
                        self.device_model.fullTopic(d),
                        self.device_model.commandTopic(d),
                        self.device_model.statTopic(d),
                        self.device_model.teleTopic(d),
                        # modules.get(self.device_model.module(d)),
                        self.device_model.module(d),
                        self.device_model.firmware(d),
                        self.device_model.core(d)
                    ])

    def bssid(self):
        BSSIdDialog().exec_()

    def patterns(self):
        PatternsDialog().exec_()

    # def openhab(self):
    #     OpenHABDialog(self.env).exec_()

    def showSubs(self):
        QMessageBox.information(self, "Subscriptions",
                                "\n".join(sorted(self.topics)))

    def clear_LWT(self):
        dlg = ClearLWTDialog(self.env)
        if dlg.exec_() == ClearLWTDialog.Accepted:
            for row in range(dlg.lw.count()):
                itm = dlg.lw.item(row)
                if itm.checkState() == Qt.Checked:
                    topic = itm.text()
                    self.mqtt.publish(topic, retain=True)
                    self.env.lwts.remove(topic)
                    logging.info("MQTT: Cleared %s", topic)

    def prefs(self):
        dlg = PrefsDialog()
        if dlg.exec_() == QDialog.Accepted:
            update_devices = False

            devices_short_version = self.settings.value(
                "devices_short_version", True, bool)
            if devices_short_version != dlg.cbDevShortVersion.isChecked():
                update_devices = True
                self.settings.setValue("devices_short_version",
                                       dlg.cbDevShortVersion.isChecked())

            update_consoles = False

            console_font_size = self.settings.value("console_font_size", 9)
            if console_font_size != dlg.sbConsFontSize.value():
                update_consoles = True
                self.settings.setValue("console_font_size",
                                       dlg.sbConsFontSize.value())

            console_word_wrap = self.settings.value("console_word_wrap", True,
                                                    bool)
            if console_word_wrap != dlg.cbConsWW.isChecked():
                update_consoles = True
                self.settings.setValue("console_word_wrap",
                                       dlg.cbConsWW.isChecked())

            if update_consoles:
                for c in self.consoles:
                    c.console.setWordWrapMode(dlg.cbConsWW.isChecked())
                    new_font = QFont(c.console.font())
                    new_font.setPointSize(dlg.sbConsFontSize.value())
                    c.console.setFont(new_font)

        self.settings.sync()

    def auto_telemetry_period(self):
        curr_val = self.settings.value("autotelemetry", 5000, int)
        period, ok = QInputDialog.getInt(
            self, "Set AutoTelemetry period",
            "Values under 5000ms may cause increased ESP LoadAvg", curr_val,
            1000)
        if ok:
            self.settings.setValue("autotelemetry", period)
            self.settings.sync()

    @pyqtSlot(TasmotaDevice)
    def selectDevice(self, d):
        self.device = d

    @pyqtSlot()
    def openTelemetry(self):
        if self.device:
            tele_widget = TelemetryWidget(self.device)
            self.addDockWidget(Qt.RightDockWidgetArea, tele_widget)
            self.mqtt_publish(self.device.cmnd_topic('STATUS'), "8")

    @pyqtSlot()
    def openConsole(self):
        if self.device:
            console_widget = ConsoleWidget(self.device)
            self.mqtt.messageSignal.connect(console_widget.consoleAppend)
            console_widget.sendCommand.connect(self.mqtt.publish)
            self.addDockWidget(Qt.BottomDockWidgetArea, console_widget)
            console_widget.command.setFocus()
            self.consoles.append(console_widget)

    @pyqtSlot()
    def openRulesEditor(self):
        if self.device:
            rules = RulesWidget(self.device)
            self.mqtt.messageSignal.connect(rules.parseMessage)
            rules.sendCommand.connect(self.mqtt_publish)
            self.mdi.setViewMode(QMdiArea.TabbedView)
            self.mdi.addSubWindow(rules)
            rules.setWindowState(Qt.WindowMaximized)
            rules.destroyed.connect(self.updateMDI)
            self.mqtt_queue.append((self.device.cmnd_topic("ruletimer"), ""))
            self.mqtt_queue.append((self.device.cmnd_topic("rule1"), ""))
            self.mqtt_queue.append((self.device.cmnd_topic("Var"), ""))
            self.mqtt_queue.append((self.device.cmnd_topic("Mem"), ""))

    @pyqtSlot()
    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 updateMDI(self):
        if len(self.mdi.subWindowList()) == 1:
            self.mdi.setViewMode(QMdiArea.SubWindowView)
            self.devices_list.setWindowState(Qt.WindowMaximized)

    def closeEvent(self, e):
        self.settings.setValue("version", self._version)
        self.settings.setValue("window_geometry", self.saveGeometry())
        self.settings.setValue("views_order",
                               ";".join(self.devices_list.views.keys()))

        self.settings.beginGroup("Views")
        for view, items in self.devices_list.views.items():
            self.settings.setValue(view, ";".join(items[1:]))
        self.settings.endGroup()

        self.settings.sync()

        for d in self.env.devices:
            mac = d.p.get('Mac')
            topic = d.p['Topic']
            full_topic = d.p['FullTopic']
            friendly_name = d.p['FriendlyName1']

            if mac:
                self.devices.beginGroup(mac.replace(":", "-"))
                self.devices.setValue("topic", topic)
                self.devices.setValue("full_topic", full_topic)
                self.devices.setValue("friendly_name", friendly_name)

                for i, h in enumerate(d.history):
                    self.devices.setValue("history/{}".format(i), h)
                self.devices.endGroup()
        self.devices.sync()

        e.accept()
Beispiel #17
0
class Config(QObject):
    "Configuration provider for the whole program, wapper for QSettings"

    row_height_changed = pyqtSignal(int)

    def __init__(self, log=None):
        super().__init__()
        if log:
            self.log = log.getChild('Conf')
            self.log.setLevel(30)
        else:
            self.log = logging.getLogger()
            self.log.setLevel(99)
        self.log.debug('Initializing')
        self.qsettings = QSettings()
        self.qsettings.setIniCodec('UTF-8')

        self.options = None
        self.option_spec = self.load_option_spec()
        self.options = self.load_options()
        self.full_name = "{} {}".format(QCoreApplication.applicationName(),
                                        QCoreApplication.applicationVersion())

        # options that need fast access are also definded as attributes, which
        # are updated by calling update_attributes()
        # (on paper it's 4 times faster, but i don't think it matters in my case)
        self.logger_table_font = None
        self.logger_table_font_size = None
        self.loop_event_delay = None
        self.benchmark_interval = None

        self.update_attributes()

    def __getitem__(self, name):
        # self.log.debug('Getting "{}"'.format(name))
        value = self.options.get(name, None)
        if value is None:
            raise Exception('No option with name "{}"'.format(name))
        # self.log.debug('Returning "{}"'.format(value))
        return value

    def __setitem__(self, name, value):
        # self.log.debug('Setting "{}"'.format(name))
        if name not in self.options:
            raise Exception('No option with name "{}"'.format(name))
        self.options[name] = value

    def set_option(self, name, value):
        self[name] = value

    @staticmethod
    def get_resource_path(name, directory='ui'):
        data_dir = resource_filename('cutelog', directory)
        path = os.path.join(data_dir, name)
        if not os.path.exists(path):
            raise FileNotFoundError(
                'Resource file not found in this path: "{}"'.format(path))
        return path

    def get_ui_qfile(self, name):
        file = QFile(':/ui/{}'.format(name))
        if not file.exists():
            raise FileNotFoundError(
                'ui file not found: ":/ui/{}"'.format(name))
        file.open(QFile.ReadOnly)
        return file

    @property
    def listen_address(self):
        host = self.options.get('listen_host', None)
        port = self.options.get('listen_port', None)
        if host is None or port is None:
            raise Exception(
                'Listen host or port not in options: "{}:{}"'.format(
                    host, port))
        return (host, port)

    def load_option_spec(self):
        option_spec = []
        for spec in OPTION_SPEC:
            option = Option(*spec)
            option_spec.append(option)
        return option_spec

    def load_options(self):
        self.log.debug('Loading options')
        options = {}
        self.qsettings.beginGroup('Configuration')
        for option in self.option_spec:
            value = self.qsettings.value(option.name, option.default)
            if option.type == bool:
                value = str(value).lower(
                )  # needed because QSettings stores bools as strings
                value = True if value == "true" or value is True else False
            else:
                value = option.type(value)
            options[option.name] = value
        self.qsettings.endGroup()
        return options

    def update_options(self, new_options, save=True):
        self.options.update(new_options)
        if save:
            self.save_options()
        self.update_attributes(new_options)

    def update_attributes(self, options=None):
        "Updates fast attributes and everything else outside of self.options"
        if options:
            # here will be things that only need to be updated when they actually changed
            new_row_height = options.get('logger_row_height',
                                         self.options['logger_row_height'])
            if new_row_height != self.options['logger_row_height']:
                self.row_height_changed.emit(new_row_height)
        else:
            options = self.options

        self.loop_event_delay = options.get('loop_event_delay',
                                            self.loop_event_delay)
        self.benchmark_interval = options.get('benchmark_interval',
                                              self.benchmark_interval)
        self.logger_table_font = options.get('logger_table_font',
                                             self.logger_table_font)
        self.logger_table_font_size = options.get('logger_table_font_size',
                                                  self.logger_table_font_size)
        self.set_logging_level(
            options.get('console_logging_level', ROOT_LOG.level))

    def save_options(self):
        self.log.debug('Saving options')
        self.qsettings.beginGroup('Configuration')
        for option in self.option_spec:
            self.qsettings.setValue(option.name, self.options[option.name])
        self.qsettings.endGroup()
        self.sync()

    def sync(self):
        self.log.debug('Syncing QSettings')
        self.qsettings.sync()

    def set_settings_value(self, name, value):
        self.qsettings.beginGroup('Configuration')
        self.qsettings.setValue(name, value)
        self.qsettings.endGroup()

    def set_logging_level(self, level):
        global ROOT_LOG
        ROOT_LOG.setLevel(level)
        self.log.setLevel(level)

    # def save_levels_preset(self, levels, preset_name):
    #     pass

    def get_header_presets(self):
        self.qsettings.beginGroup('Header_Presets')
        result = self.qsettings.childGroups()
        self.qsettings.endGroup()
        return result

    def save_header_preset(self, name, columns):
        self.log.debug('Saving header preset "{}"'.format(name))
        s = self.qsettings
        s.beginGroup('Header_Presets')
        s.beginWriteArray(name, len(columns))
        for i, col in enumerate(columns):
            s.setArrayIndex(i)
            s.setValue('column', col.dump_to_string())
        s.endArray()
        s.endGroup()

    def load_header_preset(self, name):
        from .logger_table_header import Column
        self.log.debug('Loading header preset "{}"'.format(name))
        s = self.qsettings
        result = []
        if name not in self.get_header_presets():
            return None
        s.beginGroup('Header_Presets')
        size = s.beginReadArray(name)
        for i in range(size):
            s.setArrayIndex(i)
            new_column = Column(load=s.value('column'))
            result.append(new_column)
        s.endArray()
        s.endGroup()
        return result

    def save_geometry(self, geometry):
        s = self.qsettings
        s.beginGroup('Geometry')
        s.setValue('Main_Window_Geometry', geometry)
        s.endGroup()
        self.sync()

    def load_geometry(self):
        s = self.qsettings
        s.beginGroup('Geometry')
        geometry = s.value('Main_Window_Geometry')
        s.endGroup()
        return geometry
Beispiel #18
0
    def _buildUi(self):
        self._clues = {}
        self._selectionComboBox = None
        self.loadLanguage()
        self.loadClueAlbum('clue-album.ini')

        if self._clues:
            self._selectionComboBox = QComboBox()
            self._selectionComboBox.addItem(self.tr("Load clue..."), None)
            for k in self._clues:
                clue = self._clues[k]
                self._selectionComboBox.addItem(clue.title, k)

        self._options = {}
        if os.path.isfile('definitions.ini'):
            definitions = QSettings('definitions.ini', QSettings.IniFormat)
            for group in definitions.childGroups():
                definitions.beginGroup(group)
                if group == "options":
                    for key in definitions.childKeys():
                        self._options[key] = definitions.value(key)
                definitions.endGroup()

        main_layout = QVBoxLayout()
        main_layout.setSpacing(12)

        self._led = LedWidget(self.tr("Raspberry Teletext"), QSize(40, 20))
        self._led.setRedAsBold(True)
        self._led.setRedAsRed(True)
        self._led.switchOn('gray')

        settings_button = QPushButton()
        settings_button.setIcon(QIcon("./settings.svg"))
        settings_button.setFlat(True)
        settings_button.setToolTip(self.tr("Effects and language"))
        settings_button.setIconSize(QSize(16, 16))
        settings_button.setFixedSize(QSize(24, 24))

        header_layout = QHBoxLayout()
        header_layout.addWidget(self._led)
        header_layout.addWidget(settings_button, Qt.AlignRight)
        main_layout.addLayout(header_layout)

        stop_button = QPushButton()
        stop_button.setIcon(QIcon("./cancel.svg"))
        stop_button.setFlat(True)
        stop_button.setToolTip(self.tr("Clear TV screen"))
        stop_button.setIconSize(QSize(16, 16))
        stop_button.setFixedSize(QSize(24, 24))

        if 'tv-screen-width' in self._options and 'tv-screen-height' in self._options:
            hint = QSize(int(self._options['tv-screen-width']), int(self._options['tv-screen-height']))
            # self._tvScreen = TvScreenLabel(self.tr("<div align=center>Display on TV</div>"), hint)
            self._tvScreen = TvScreenLabel('', hint)
            policy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        else:
            # self._tvScreen = TvScreenLabel(self.tr("<div align=center>Display on TV</div>"))
            self._tvScreen = TvScreenLabel('')
            policy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
        policy.setHeightForWidth(True)
        self._tvScreen.setSizePolicy(policy)

        display_layout = QHBoxLayout()
        display_layout.addWidget(self._tvScreen)
        display_layout.addStretch()
        display_layout.addWidget(stop_button, Qt.AlignRight)
        main_layout.addLayout(display_layout)

        if self._selectionComboBox:
            main_layout.addWidget(self._selectionComboBox)

        self._editor = QPlainTextEdit()
        self._editor.setFrameShape(QFrame.NoFrame)
        self._editor.setCursorWidth(8)
        main_layout.addWidget(self._editor)

        clear_button = QPushButton(self.tr("Erase draft"))
        clear_button.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Fixed)

        send_button = QPushButton(self.tr("Display on TV"))
        send_button.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Fixed)

        button_layout = QHBoxLayout()
        button_layout.addWidget(send_button)
        button_layout.addWidget(clear_button)
        main_layout.addLayout(button_layout)

        self.setLayout(main_layout)

        settings_button.pressed.connect(self.settings)
        stop_button.pressed.connect(self.stop)
        clear_button.pressed.connect(self.erase)
        send_button.pressed.connect(self.send)
        self.switchLed.connect(self._led.switchOn)
        if self._selectionComboBox:
            self._selectionComboBox.activated.connect(self.selectClue)

        self._editor.setFocusPolicy(Qt.StrongFocus)
        self._editor.setFocus(Qt.OtherFocusReason)
class ini_setting:
    """
    class for managing .ini file and project defaults
    """
    release_mode = False

    def __init__(self, file_name, model):
        """
        constructor: read setting values into a QSetting object
        Args:
            file_name: ini file name
        """
        self.file_name = file_name
        self.model = model
        self.error_msg = ""
        self.groups_with_values = {} # all values read
        self.groups = {} # group names and key names
        self.config = None
        try:
            self.config = QSettings(QSettings.IniFormat, QSettings.UserScope, "EPA", self.model, None)
            if (not os.path.isfile(self.file_name) and file_name):
                from shutil import copyfile
                copyfile(self.config.fileName(), file_name)
                # self.create_ini_file(file_name)
            else:
                self.file_name = self.config.fileName()
            self.build_setting_map()
            print("Read project settings from " + self.file_name)
        except Exception as exINI:
            self.config = None
            self.error_msg = "Reading Error" + ":\n" + str(exINI)

    def create_ini_file(self, file_name):
        """
        Specify .ini file path after instantiation
        if setting is not yet instantiated:
            a new setting is instantiated
            if the new setting has no key:
                a new ini file is created
        Args:
            file_name: the full path to an ini file
        Returns: True if successful; False if failed
        """
        if os.path.isfile(self.file_name): return False
        if self.config is None:
            try:
                self.config = QSettings(file_name, QSettings.IniFormat)
                if len(self.config.allKeys()) == 0:
                    # this is a brand new ini file
                    self.config.setValue("Model/Name", self.model)
                    self.config.sync()
                    print("created ini file: " + file_name)
                else:
                    print("Read settings from ini file: " + file_name)
                self.file_name = file_name
                return True
            except Exception as exINI:
                self.config = None
                self.error_msg = "Reading Error" + ":\n" + str(exINI)
                return False

    def get_setting_value(self, group, key):
        """
        Get the value of a ini setting, assuming all settings are grouped
        Args:
            group: the string name of a group or section
            key: the string name of a key
        Returns:
            a list of two elements, first being the value, second being the value type
        """
        rval = [None, None]
        if len(self.groups) == 0:
            return rval
        if not group in self.groups:
            return rval

        self.config.beginGroup(group)
        qvar = self.config.value(key)
        if qvar is None:
            self.config.endGroup()
            return rval
        str_val = str(qvar)
        if len(str_val) > 0:
            tval, tval_is_good = ParseData.intTryParse(str_val)
            if tval_is_good:
                rval[0] = tval
                rval[1] = "integer"
                self.config.endGroup()
                return rval
            tval, tval_is_good = ParseData.floatTryParse(str_val)
            if tval_is_good:
                rval[0] = tval
                rval[1] = "float"
                self.config.endGroup()
                return rval
            rval[0] = str_val
            rval[1] = "string"
            self.config.endGroup()
            return rval
        elif str_val == "":
            rval[0] = ""
            rval[1] = "string"
        else:
            str_list = qvar.toStringList().join(",")
            if len(str_list) > 0:
                rval[0] = str_list.strip(",").split(",")
                rval[1] = "stringlist"
                self.config.endGroup()
                return rval

        self.config.endGroup()
        return rval

    def build_setting_map(self):
        """
        Build a setting group-key-value mapping dictionary as below:
        self.groups_with_values
        [group_name] -> [key_name] -> [value, value_type]

        Also create group dictionary keyed on group name, pointing to its list of keys
        so we can get setting values on a as needed basis
        self.groups
        [group_name] -> [key names]
        """
        self.groups.clear()
        self.groups_with_values.clear()
        for group in self.config.childGroups():
            self.config.beginGroup(group)
            self.groups_with_values[group] = {}
            self.groups[group] = []
            for key in self.config.childKeys():
                self.groups[group].append(key)
                val, vtype = self.get_setting_value(group, key)
                self.groups_with_values[group][key] = val
                # print group + "::" + key + "::" + self.config.value(key).toString()
            self.config.endGroup()

    def read_ini_file_cp(self):
        self.config.read(self.file_name)
        for section in self.config.sections():
            dict1 = self.config_section_map(section)
            pass
        pass

    def config_section_map(self, section):
        dict1 = {}
        for option in self.config.options(section):
            try:
                dict1[option] = self.config.get(section, option)
                if dict1[option] == -1:
                    print ("skip: %s" % option)
                pass
            except:
                print ("exception on %s!" % option)
                dict1[option] = None
        return dict1
Beispiel #20
0
class rheasDialog(QtWidgets.QDialog, FORM_CLASS):
    def __init__(self, parent=None):
        """Constructor."""
        super(rheasDialog, self).__init__(parent)
        # Set up the user interface from Designer.
        # After setupUI you can access any designer object by doing
        # self.<objectname>, and you can use autoconnect slots - see
        # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html
        # #widgets-and-dialogs-with-auto-connect
        self.setupUi(self)
        self.schema.currentIndexChanged.connect(self.refreshTables)
        self.database.currentIndexChanged.connect(self.refreshSchemas)
        self.render.clicked.connect(self.loadRaster)
        self.addDatabases()
        self.addSchemas()
        self.addTables()

    def addDatabases(self):
        """Add available database connections."""
        self.settings = QSettings()
        self.settings.beginGroup('/PostgreSQL/connections/')
        connections = self.settings.childGroups()
        self.settings.endGroup()
        for conn in connections:
            self.database.addItem(conn)
            
    def getConnectionParameters(self):
        """Get database connection information."""
        conn = self.database.itemText(self.database.currentIndex())
        self.settings.beginGroup('PostgreSQL/connections')
        dbname = self.settings.value("{0}/database".format(conn))
        host = self.settings.value("{0}/host".format(conn))
        port = self.settings.value("{0}/port".format(conn))
        username = self.settings.value("{0}/username".format(conn))
        password = self.settings.value("{0}/password".format(conn))
        self.settings.endGroup()
        return dbname, host, port, username, password

    def addSchemas(self):
        """Add available schemas from database."""
        dbname, host, port, username, password = self.getConnectionParameters()
        db = pg.connect(dbname=dbname, host=host, port=port, user=username, password=password)
        cur = db.cursor()
        sql = "select schema_name from information_schema.schemata"
        cur.execute(sql)
        results = cur.fetchall()
        for r in results:
            name = r[0]
            if not name.startswith("pg_"):
                self.schema.addItem(name)
        cur.close()
        db.close()

    @pyqtSlot()
    def refreshSchemas(self):
        """Refresh list of schemas when database changes."""
        self.schema.clear()
        self.addSchemas()
        
    @pyqtSlot()
    def refreshTables(self):
        """Refresh list of tables when selected schema changes."""
        self.table.clear()
        self.addTables()

    @pyqtSlot()
    def loadRaster(self):
        """Load rasters when button is clicked."""
        dbname, host, port, username, password = self.getConnectionParameters()
        schema = self.schema.itemText(self.schema.currentIndex())
        table = self.table.itemText(self.table.currentIndex())
        startdate = self.startdate.date()
        enddate = self.enddate.date()
        dates = [startdate]
        while dates[-1] < enddate:
            dates.append(dates[-1].addDays(1))
        for dt in dates:
            connString = "PG: dbname={3} host={4} user={5} password={6} port={7} mode=2 schema={0} column=rast table={1} where='fdate=date\\'{2}\\''".format(schema, table, dt.toString("yyyy-M-d"), dbname, host, username, password, port)
            layer = QgsRasterLayer(connString, "{0}".format(dt.toString("yyyy-M-d")))
            if layer.isValid():
                layer.setContrastEnhancement(QgsContrastEnhancement.StretchToMinimumMaximum)
            root = QgsProject.instance().layerTreeRoot()
            group = root.findGroup(schema)
            if group is None:
                group = root.addGroup(schema)
            QgsProject.instance().addMapLayer(layer, False)
            group.insertChildNode(0, QgsLayerTreeLayer(layer))

    def addTables(self):
        """Add available tables contained in selected schema."""
        dbname, host, port, username, password = self.getConnectionParameters()
        db = pg.connect(dbname=dbname, host=host, port=port, user=username, password=password)
        cur = db.cursor()
        idx = self.schema.currentIndex()
        schema = self.schema.itemText(idx)
        sql = "select table_name from information_schema.tables where table_schema='{0}'".format(schema)
        cur.execute(sql)
        results = cur.fetchall()
        for r in results:
            name = r[0]
            self.table.addItem(name)
        cur.close()
        db.close()
Beispiel #21
0
class TasmotaDevicesModel(QAbstractTableModel):
    def __init__(self, *args, **kwargs):
        super(TasmotaDevicesModel, self).__init__(*args, **kwargs)
        self.settings = QSettings()
        self.settings.beginGroup("Devices")
        self._devices = []

        for d in self.settings.childGroups():
            self.loadDevice(d, self.settings.value("{}/full_topic".format(d)),
                            self.settings.value("{}/friendly_name".format(d)))

        self.settings.endGroup()

    def addDevice(self, topic, full_topic, lwt="undefined"):
        rc = self.rowCount()
        self.beginInsertRows(QModelIndex(), rc, rc)
        self._devices.append([lwt, topic, full_topic, topic] +
                             ([''] * (len(columns) - 4)))
        self.settings.beginGroup("Devices")
        self.settings.setValue("{}/full_topic".format(topic), full_topic)
        self.settings.setValue("{}/friendly_name".format(topic), full_topic)
        self.settings.endGroup()
        self.endInsertRows()
        return self.index(rc, 0)

    def loadDevice(self, topic, full_topic, friendly_name="", lwt="undefined"):
        rc = self.rowCount()
        self.beginInsertRows(QModelIndex(), rc, rc)
        self._devices.append([
            lwt, topic, full_topic, friendly_name if friendly_name else topic
        ] + ([''] * (len(columns) - 4)))
        self.endInsertRows()
        return True

    def findDevice(self, topic):
        split_topic = topic.split('/')
        possible_topic = split_topic[1]

        if possible_topic in ('tele', 'stat'):
            possible_topic = split_topic[0]

        for i, d in enumerate(self._devices):
            full_topic = d[DevMdl.FULL_TOPIC] + "(?P<reply>.*)"
            full_topic = full_topic.replace("%topic%", "(?P<topic>.*?)")
            full_topic = full_topic.replace("%prefix%", "(?P<prefix>.*?)")
            match = re.fullmatch(full_topic, topic)

            if match:
                found = match.groupdict()
                if found['topic'] == d[DevMdl.TOPIC]:
                    found.update({'index': self.index(i, DevMdl.LWT)})
                    return found_obj(found)

        return found_obj({
            'index': QModelIndex(),
            'topic': possible_topic,
            'reply': split_topic[-1]
        })

    def columnCount(self, parent=None):
        return len(columns)

    def rowCount(self, parent=None):
        return len(self._devices)

    def insertRows(self, pos, rows, parent=QModelIndex()):
        self.beginInsertRows(parent, pos, pos + rows - 1)
        for i in range(rows):
            self._devices.append(['undefined'] + ([''] * (len(columns) - 1)))
        self.endInsertRows()
        return True

    def removeRows(self, pos, rows, parent=QModelIndex()):
        if pos + rows <= self.rowCount():
            self.beginRemoveRows(parent, pos, pos + rows - 1)
            for r in range(rows):
                d = self._devices[pos][DevMdl.TOPIC]
                self.settings.beginGroup("Devices")
                if d in self.settings.childGroups():
                    self.settings.remove(d)
                self.settings.endGroup()
                self._devices.pop(pos + r)
            self.endRemoveRows()
            return True
        return False

    def headerData(self, col, orientation, role=Qt.DisplayRole):
        if orientation == Qt.Horizontal and role == Qt.DisplayRole:
            if col <= len(columns):
                return columns[col][0]
            else:
                return ''

    def data(self, idx, role=Qt.DisplayRole):
        if idx.isValid():
            row = idx.row()
            col = idx.column()

            if role in (Qt.DisplayRole, Qt.EditRole):
                val = self._devices[row][col]
                if val and col == DevMdl.UPTIME:
                    if val.startswith("0T"):
                        val = val.replace('0T', '')
                    return val.replace('T', 'd ')

                elif val and col == DevMdl.MODULE:
                    return modules.get(val, 'Unknown')

                elif val and col == DevMdl.FIRMWARE:
                    return val.replace('(', ' (')

                elif col == DevMdl.LOADAVG:
                    if val:
                        return val
                    return "n/a" if self._devices[row][
                        DevMdl.LWT] == 'online' else ''

                elif col == DevMdl.BSSID:
                    alias = self.settings.value("BSSID/{}".format(val))
                    if alias:
                        return alias

                return self._devices[row][col]

            elif role == Qt.TextAlignmentRole:
                if col in (DevMdl.RSSI, DevMdl.MAC, DevMdl.IP, DevMdl.SSID,
                           DevMdl.BSSID, DevMdl.CHANNEL, DevMdl.POWER,
                           DevMdl.LOADAVG, DevMdl.CORE, DevMdl.TELEPERIOD):
                    return Qt.AlignCenter

                elif col == DevMdl.UPTIME:
                    return Qt.AlignRight | Qt.AlignVCenter

                elif col == DevMdl.RESTART_REASON:
                    return Qt.AlignLeft | Qt.AlignVCenter | Qt.TextWordWrap

            elif role == Qt.BackgroundColorRole and col == DevMdl.RSSI:
                rssi = self._devices[row][DevMdl.RSSI]
                if rssi:
                    rssi = int(rssi)
                    if rssi < 50:
                        return QColor("#ef4522")
                    elif rssi > 75:
                        return QColor("#7eca27")
                    else:
                        return QColor("#fcdd0f")

            elif role == Qt.ToolTipRole:
                if col == DevMdl.FIRMWARE:
                    return self._devices[row][DevMdl.FIRMWARE]

                elif col == DevMdl.FRIENDLY_NAME:
                    return "Topic: {}\nFull topic: {}".format(
                        self._devices[row][DevMdl.TOPIC],
                        self._devices[row][DevMdl.FULL_TOPIC])

    def setData(self, idx, val, role=Qt.EditRole):
        row = idx.row()
        col = idx.column()

        if role == Qt.EditRole:
            dev = self._devices[row][DevMdl.TOPIC]
            old_val = self._devices[row][col]
            if val != old_val:
                self.settings.beginGroup("Devices")
                if col == DevMdl.FRIENDLY_NAME:
                    self.settings.setValue("{}/friendly_name".format(dev), val)
                elif col == DevMdl.FULL_TOPIC:
                    self.settings.setValue("{}/full_topic".format(dev), val)
                self.settings.endGroup()
                self._devices[row][col] = val
                self.dataChanged.emit(idx, idx)
                self.settings.sync()
                return True
        return False

    def flags(self, idx):
        return Qt.ItemIsSelectable | Qt.ItemIsEnabled

    def updateValue(self, idx, column, val):
        if idx.isValid():
            row = idx.row()
            idx = self.index(row, column)
            self.setData(idx, val)

    def topic(self, idx):
        if idx.isValid():
            row = idx.row()
            return self._devices[row][DevMdl.TOPIC]
        return None

    def friendly_name(self, idx):
        if idx.isValid():
            row = idx.row()
            return self._devices[row][DevMdl.FRIENDLY_NAME]
        return None

    def commandTopic(self, idx):
        if idx.isValid():
            row = idx.row()
            return self._devices[row][DevMdl.FULL_TOPIC].replace(
                "%prefix%", "cmnd").replace("%topic%",
                                            self._devices[row][DevMdl.TOPIC])
        return None

    def statTopic(self, idx):
        if idx.isValid():
            row = idx.row()
            return self._devices[row][DevMdl.FULL_TOPIC].replace(
                "%prefix%", "stat").replace("%topic%",
                                            self._devices[row][DevMdl.TOPIC])
        return None

    def teleTopic(self, idx):
        if idx.isValid():
            row = idx.row()
            return self._devices[row][DevMdl.FULL_TOPIC].replace(
                "%prefix%", "tele").replace("%topic%",
                                            self._devices[row][DevMdl.TOPIC])
        return None

    def isDefaultTemplate(self, idx):
        if idx.isValid():
            return self._devices[idx.row()][DevMdl.FULL_TOPIC] in [
                "%prefix%/%topic%/", "%topic%/%prefix%/"
            ]

    def bssid(self, idx):
        if idx.isValid():
            row = idx.row()
            return self._devices[row][DevMdl.BSSID]
        return None

    def power(self, idx):
        if idx.isValid():
            row = idx.row()
            return self._devices[row][DevMdl.POWER]
        return None

    def refreshBSSID(self):
        first = self.index(0, DevMdl.BSSID)
        last = self.index(self.rowCount(), DevMdl.BSSID)
        self.dataChanged.emit(first, last)
    def __init__(self, logger, session):

        super(ObserverSettingsDialog, self).__init__()

        self._logger = logger
        self._session = session

        self._count = QLabel()
        self._countLeftEstimated = QLabel()
        self._metersLeftEstimated = QLabel()

        self.setWindowFlags(self.windowFlags()
                            & ~Qt.WindowContextHelpButtonHint)
        self.setWindowTitle(self.tr("Observer settings"))
        self.setWindowIcon(QIcon(':/settings.svg'))

        self._mqttServerInput = QLineEdit()
        self._mqttPortInput = QLineEdit()
        self._mqttTopicInput = QLineEdit()
        self._sessionNameInput = QLineEdit()
        self._retrieveComboBox = QComboBox()
        self._deleteComboBox = QComboBox()

        self.buildUi()

        reg = QSettings()

        self._sessionNameInput.setText(self._session)

        try:
            port = reg.value("port", 1883, type=int)
        except:
            port = 1883

        reg.beginGroup(self._session)
        self._mqttServerInput.setText(reg.value("host", 'localhost'))
        self._mqttPortInput.setText(str(port))
        self._mqttTopicInput.setText(reg.value("root topic", ''))
        reg.endGroup()

        retrieveable = []
        for session in reg.childGroups():
            if session != self._session:
                retrieveable.append(session)

        if retrieveable:
            self._retrieveComboBox.addItem(
                self.tr("Select session to retrieve..."), '')
            for i in retrieveable:
                self._retrieveComboBox.addItem(i, i)
        else:
            self._retrieveComboBox.addItem(self.tr("No session to retrieve"),
                                           '')
            self._retrieveComboBox.setDisabled(True)

        deleteable = []
        for session in reg.childGroups():
            if session != 'Default session' and session != self._session:
                deleteable.append(session)

        if deleteable:
            self._deleteComboBox.addItem(
                self.tr("Select session to delete..."), '')
            for i in deleteable:
                self._deleteComboBox.addItem(i, i)
        else:
            self._deleteComboBox.addItem(self.tr("No session to delete"), '')
            self._deleteComboBox.setDisabled(True)

        self._retrieveComboBox.currentIndexChanged.connect(
            self.retrieveSession)
        self._deleteComboBox.currentIndexChanged.connect(self.deleteSession)
def get_mssql_connections():
    """ Read PostgreSQL connection names from QSettings stored by QGIS
    """
    settings = QSettings()
    settings.beginGroup(u"/MSSQL/connections/")
    return settings.childGroups()
Beispiel #24
0
    def __init__(self,
                 title,
                 logger,
                 session,
                 server,
                 port,
                 topic,
                 remove=True,
                 filter=True):

        super(ObserverDisplayWidget, self).__init__()

        self._observation = title

        self._displayFormat = int(TopicDisplay.EMPHASIZEDCORRESPONDENT)
        self._filter1 = None
        self._filter2 = None
        self._filter3 = None
        self._filter4 = None
        self._hiddenCorrespondents = []
        self._hiddenTopics = []
        self._logger = logger
        self._session = session

        self._mqttServerHost = server
        self._mqttServerPort = port
        self._mqttTopicRoot = topic

        self._bufferSize = 50000
        self._correspondents = []
        self._topics = []

        self._mainDisplay = QTextEdit()

        main_layout = QVBoxLayout()
        main_layout.setSpacing(12)

        self._mainDisplay.setFrameShape(QFrame.NoFrame)
        self._mainDisplay.setLineWrapMode(QTextEdit.NoWrap)
        self._mainDisplay.setReadOnly(True)
        main_layout.addWidget(self._mainDisplay)

        button_layout = QHBoxLayout()

        clear_button = QPushButton(self.tr("Erase"))
        button_layout.addWidget(clear_button)

        if filter:
            filter_button = QPushButton(self.tr("Observation..."))
            button_layout.addWidget(filter_button)
            filter_button.pressed.connect(self.filterSettings)
        else:
            clear_wills_button = QPushButton(self.tr("Wills..."))
            button_layout.addWidget(clear_wills_button)
            clear_wills_button.pressed.connect(self.clearWillselection)

        if remove:
            del_tab_button = QPushButton()
            del_tab_button.setIcon(QIcon(":/trash.svg"))
            del_tab_button.setFlat(True)
            del_tab_button.setToolTip(self.tr("Delete this observation"))
            del_tab_button.setIconSize(QSize(16, 16))
            del_tab_button.setFixedSize(QSize(24, 24))
            button_layout.addWidget(del_tab_button)
            del_tab_button.pressed.connect(self.delObservation)

        add_tab_button = QPushButton()
        add_tab_button.setIcon(QIcon(":/add.svg"))
        add_tab_button.setFlat(True)
        add_tab_button.setToolTip(self.tr("Add new observation"))
        add_tab_button.setIconSize(QSize(16, 16))
        add_tab_button.setFixedSize(QSize(24, 24))
        button_layout.addStretch(1)
        button_layout.addWidget(add_tab_button, Qt.AlignRight)
        main_layout.addLayout(button_layout)

        self.setLayout(main_layout)

        clear_button.pressed.connect(self.erase)
        add_tab_button.pressed.connect(self.addObservation)

        self._mainDisplay.setStyleSheet(
            "font-family:monospace,courier new,courier; white-space:pre; color:black;"
        )

        reg = QSettings()
        reg.beginGroup(self._session)
        reg.beginGroup(self._observation)
        self._displayFormat = reg.value(
            "display", int(TopicDisplay.EMPHASIZEDCORRESPONDENT), type=int)
        self._filter1 = reg.value("filter 1", '')
        self._filter2 = reg.value("filter 2", '')
        self._filter3 = reg.value("filter 1", '')
        self._filter4 = reg.value("filter 4", '')
        self._bufferSize = reg.value("buffer size", 50000, type=int)
        if "Hidden correspondents" in reg.childGroups():
            reg.beginGroup("Hidden correspondents")
            for p in reg.childKeys():
                self._hiddenCorrespondents.append(p.replace('\\', '/'))
            reg.endGroup()
        if "Hidden topics" in reg.childGroups():
            reg.beginGroup("Hidden topics")
            for t in reg.childKeys():
                self._hiddenTopics.append(t.replace('\\', '/'))
            reg.endGroup()
        reg.endGroup()
        reg.endGroup()
Beispiel #25
0
    def __init__(self, client, logger):

        super(ObserverWindow, self).__init__()

        self._connectionState = None

        self._countUntitledDisplay = 0
        self._displays = []
        self._session = 'Default session'
        self._host = 'localhost'
        self._port = 1883
        self._rootTopic = ''
        self._logger = logger

        self._logger.info(self.tr("Started"))

        reg = QSettings()

        if "current session" in reg.childKeys() and reg.value(
                "current session", '').strip() and reg.value(
                    "current session", '').strip() in reg.childGroups():
            self._session = reg.value("current session")

        self._logger.info(self.tr("Current session : ") + self._session)

        if self._session not in reg.childGroups():
            reg.beginGroup(self._session)
            reg.setValue("host", self._host)
            reg.setValue("port", self._port)
            reg.setValue("root topic", self._rootTopic)
            reg.endGroup()
        else:
            reg.beginGroup(self._session)
            self._host = reg.value("host", 'localhost')
            try:
                self._port = reg.value("port", 1883, type=int)
            except:
                pass
            self._rootTopic = reg.value("root topic", '')
            reg.endGroup()

        if "current session" in reg.childKeys() and not reg.value(
                "current session", '') in reg.childGroups():
            reg.remove("current session")

        self._mqttSwitchingConnection = False

        self._mqttClient = client
        self._mqttServerHost = self._host
        self._mqttServerPort = self._port
        self._mqttRootTopic = self._rootTopic
        self._mqttSubTopic = '#'

        if self._rootTopic:
            self._mqttSubTopic = self._rootTopic + '/#'

        QApplication.desktop().screenCountChanged.connect(self.restoreWindow)
        QApplication.desktop().resized.connect(self.restoreWindow)

        self.setWindowTitle(self._session)
        self.setWindowIcon(QIcon(':/view-eye.svg'))

        self._tabWidget = QTabWidget()
        self._cloudLabel = QLabel()
        self._connectionStateLabel = QLabel()

        self.builUi()

        reg.beginGroup(self._session)
        inbox = reg.value("param inbox", 'inbox')
        outbox = reg.value("param outbox", 'outbox')
        regexInbox = reg.value("regex inbox",
                               r'^%ROOT%/(?P<correspondent>.+)/%INBOX%$')
        regexOutbox = reg.value("regex outbox",
                                r'^%ROOT%/(?P<correspondent>.+)/%OUTBOX%$')
        regexDefault = reg.value("regex default",
                                 r'.*/(?P<correspondent>[^/]+)/[^/]+$')
        reg.endGroup()

        regexInbox = regexInbox.replace("%ROOT%", self._rootTopic).replace(
            "%INBOX%", inbox)
        regexOutbox = regexOutbox.replace("%ROOT%", self._rootTopic).replace(
            "%OUTBOX%", outbox)

        self._topicRegexInbox = None
        try:
            self._topicRegexInbox = re.compile(regexInbox)
        except Exception as e:
            self._logger.error(self.tr("Failed to compile inbox regex"))
            self._logger.debug(e)

        self._topicRegexOutbox = None
        try:
            self._topicRegexOutbox = re.compile(regexOutbox)
        except Exception as e:
            self._logger.error(self.tr("Failed to compile outbox regex"))
            self._logger.debug(e)

        self._topicRegexDefault = None
        try:
            self._topicRegexDefault = re.compile(regexDefault)
        except Exception as e:
            self._logger.error(
                self.tr("Failed to compile topic default regex"))
            self._logger.debug(e)

        self.addDisplay(self.tr("All messsages"))

        reg.beginGroup(self._session)
        for i in reg.childGroups():
            self.addDisplay(i)
        reg.endGroup()

        self.changeConnectionState(ConnectionState.DISCONNECTED)

        self._logger.info("{0} : {1}".format(self.tr("MQTT server host"),
                                             self._mqttServerHost))
        self._logger.info("{0} : {1}".format(self.tr("MQTT server port"),
                                             self._mqttServerPort))
        self._logger.info("{0} : {1}".format(
            self.tr("MQTT clientid"),
            self._mqttClient._client_id.decode("latin1")))

        Timer(0, self.layoutLoadSettings).start()
        Timer(0, self.start).start()
Beispiel #26
0
class TasmotaDevicesModel(QAbstractTableModel):
    def __init__(self, tasmota_env):
        super().__init__()
        self.settings = QSettings("{}/TDM/tdm.cfg".format(QDir.homePath()),
                                  QSettings.IniFormat)
        self.devices = QSettings("{}/TDM/devices.cfg".format(QDir.homePath()),
                                 QSettings.IniFormat)
        self.tasmota_env = tasmota_env
        self.columns = []

        self.devices_short_version = self.settings.value(
            "devices_short_version", True, bool)

        for d in self.tasmota_env.devices:
            d.property_changed = self.notify_change
            d.module_changed = self.module_change

    def setupColumns(self, columns):
        self.beginResetModel()
        self.columns = columns
        self.endResetModel()

    def deviceAtRow(self, row):
        if len(self.tasmota_env.devices) > 0:
            return self.tasmota_env.devices[row]
        return None

    def notify_change(self, d, key):
        row = self.tasmota_env.devices.index(d)
        if key.startswith("POWER") and "Power" in self.columns:
            power_idx = self.columns.index("Power")
            idx = self.index(row, power_idx)
            self.dataChanged.emit(idx, idx)

        elif key in ("RSSI", "LWT"):
            fname_idx = self.columns.index("FriendlyName")
            idx = self.index(row, fname_idx)
            self.dataChanged.emit(idx, idx)

        elif key in self.columns:
            col = self.columns.index(key)
            idx = self.index(row, col)
            self.dataChanged.emit(idx, idx)

    def module_change(self, d):
        self.notify_change(d, "Module")

    def columnCount(self, parent=None):
        return len(self.columns)

    def rowCount(self, parent=None):
        return len(self.tasmota_env.devices)

    def flags(self, idx):
        return Qt.ItemIsSelectable | Qt.ItemIsEnabled

    def headerData(self, col, orientation, role=Qt.DisplayRole):
        if orientation == Qt.Horizontal and role == Qt.DisplayRole:
            return self.columns[col]

    def data(self, idx, role=Qt.DisplayRole):
        if idx.isValid():
            row = idx.row()
            col = idx.column()
            col_name = self.columns[col]
            d = self.tasmota_env.devices[row]

            if role in [Qt.DisplayRole, Qt.EditRole]:
                val = d.p.get(col_name, "")

                if col_name == "FriendlyName":
                    val = d.p.get("FriendlyName1", d.p['Topic'])

                elif col_name == "Module":
                    if val == 0:
                        return d.p['Template'].get(
                            'NAME', "Fetching template name...")
                    else:
                        return d.module()

                elif col_name == "Version" and val:
                    if self.devices_short_version and "(" in val:
                        return val[0:val.index("(")]
                    return val.replace("(", " (")

                elif col_name in ("Uptime", "Downtime") and val:
                    val = str(val)
                    if val.startswith("0T"):
                        val = val.replace('0T', '')
                    val = val.replace('T', 'd ')

                elif col_name == "Core" and val:
                    return val.replace('_', '.')

                elif col_name == "Time" and val:
                    return val.replace('T', ' ')

                elif col_name == "Power":
                    return d.power()

                elif col_name == "Color":
                    return d.color()

                elif col_name == "CommandTopic":
                    return d.cmnd_topic()

                elif col_name == "StatTopic":
                    return d.stat_topic()

                elif col_name == "TeleTopic":
                    return d.tele_topic()

                elif col_name == "FallbackTopic":
                    return "cmnd/{}_fb/".format(d.p.get('MqttClient'))

                elif col_name == "BSSId":
                    alias = self.settings.value("BSSId/{}".format(val))
                    if alias:
                        return alias

                elif col_name == "RSSI":
                    val = int(d.p.get("RSSI", 0))
                    return val

                return val

            elif role == LWTRole:
                val = d.p.get('LWT', 'Offline')
                return val

            elif role == RestartReasonRole:
                val = d.p.get('RestartReason')
                return val

            elif role == RSSIRole:
                val = int(d.p.get('RSSI', 0))
                return val

            elif role == FirmwareRole:
                val = d.p.get('Version', "")
                return val

            elif role == Qt.TextAlignmentRole:
                # Left-aligned columns
                if col_name in ("FriendlyName", "Module", "RestartReason",
                                "OtaUrl",
                                "Hostname") or col_name.endswith("Topic"):
                    return Qt.AlignLeft | Qt.AlignVCenter | Qt.TextWordWrap

                # Right-aligned columns
                elif col_name in ("Uptime"):
                    return Qt.AlignRight | Qt.AlignVCenter

                else:
                    return Qt.AlignCenter

            elif role == Qt.DecorationRole and col_name == "FriendlyName":
                if d.p['LWT'] == "Online":
                    rssi = int(d.p.get("RSSI", 0))

                    if rssi > 0 and rssi < 50:
                        return QIcon(":/status_low.png")

                    elif rssi < 75:
                        return QIcon(":/status_medium.png")

                    elif rssi >= 75:
                        return QIcon(":/status_high.png")

                return QIcon(":/status_offline.png")

            elif role == Qt.InitialSortOrderRole:
                if col_name in ("Uptime", "Downtime"):
                    val = d.p.get(col_name, "")
                    if val:
                        d, hms = val.split("T")
                        h, m, s = hms.split(":")
                        return int(
                            s) + int(m) * 60 + int(h) * 3600 + int(d) * 86400
                else:
                    return idx.data()

            elif role == Qt.ToolTipRole:
                if col_name == "Version":
                    val = d.p.get('Version')
                    if val:
                        return val[val.index("(") + 1:val.index(")")]
                    return ""

                elif col_name == "BSSId":
                    return d.p.get('BSSId')

                elif col_name == "FriendlyName":
                    fns = [d.p['FriendlyName1']]

                    for i in range(2, 5):
                        fn = d.p.get("FriendlyName{}".format(i))
                        if fn:
                            fns.append(fn)
                    return "\n".join(fns)

    def addDevice(self, device):
        self.beginInsertRows(QModelIndex(), 0, 0)
        device.property_changed = self.notify_change
        device.module_changed = self.module_change
        self.endInsertRows()

    def removeRows(self, pos, rows, parent=QModelIndex()):
        if pos + rows <= self.rowCount():
            self.beginRemoveRows(parent, pos, pos + rows - 1)
            device = self.deviceAtRow(pos)
            self.tasmota_env.devices.pop(
                self.tasmota_env.devices.index(device))

            topic = device.p['Topic']
            self.settings.beginGroup("Devices")
            if topic in self.settings.childGroups():
                self.settings.remove(topic)
            self.settings.endGroup()

            self.endRemoveRows()
            return True
        return False

    def deleteDevice(self, idx):
        row = idx.row()
        mac = self.deviceAtRow(row).p['Mac'].replace(":", "-")
        self.devices.remove(mac)
        self.devices.sync()
        self.removeRows(row, 1)

    def columnIndex(self, column):
        return self.columns.index(column)
Beispiel #27
0
    def set_database_connection(self, connection=None, crs=None):
        """ Create a database connection
        """
        # fetch settings
        settings_plugin = QSettings()
        settings_postgis = QSettings()
        settings_plugin.beginGroup('CoGo Plugin')
        settings_postgis.beginGroup('PostgreSQL/connections')
        self.connection = connection
        if not bool(self.connection):
            # fetch pre-chosen database connection
            self.connection = settings_plugin.value("DatabaseConnection", None)
        # check if still exists
        if bool(self.connection):
            if self.connection not in settings_postgis.childGroups():
                settings_plugin.setValue("DatabaseConnection", "")
                self.connection = None
        # fetch from user if necessary
        if not bool(self.connection):
            dialog = DatabaseConnectionDialog()
            dialog.show()
            if bool(dialog.exec_()):
                self.connection = dialog.get_database_connection()
                if dialog.get_crs():
                    self.crs = QgsCoordinateReferenceSystem(
                        dialog.get_crs().get('auth_id'))
                settings_plugin.setValue("DatabaseConnection", self.connection)
        # validate database connection
        if bool(self.connection):
            db_service = settings_postgis.value(self.connection + '/service')
            db_host = settings_postgis.value(self.connection + '/host')
            db_port = settings_postgis.value(self.connection + '/port')
            db_name = settings_postgis.value(self.connection + '/database')
            db_username = settings_postgis.value(self.connection + '/username')
            db_password = settings_postgis.value(self.connection + '/password')

            max_attempts = 3
            self.uri = QgsDataSourceUri()
            self.uri.setConnection(db_host, db_port, db_name, db_username,
                                   db_password)

            if db_username and db_password:
                for i in range(max_attempts):
                    error_message = self.connect_to_db(db_service, db_host,
                                                       db_port, db_name,
                                                       db_username,
                                                       db_password)
                    if error_message:
                        ok, db_username, db_password = (
                            QgsCredentials.instance().get(
                                self.uri.connectionInfo(), db_username,
                                db_password, error_message))
                        if not ok:
                            break
                    else:
                        break

            else:
                msg = "Please enter the username and password."
                for i in range(max_attempts):
                    ok, db_username, db_password = (
                        QgsCredentials.instance().get(
                            self.uri.connectionInfo(), db_username,
                            db_password, msg))
                    if not ok:
                        break
                    error_message = self.connect_to_db(db_service, db_host,
                                                       db_port, db_name,
                                                       db_username,
                                                       db_password)
                    if not error_message:
                        break

        settings_plugin.endGroup()
        settings_postgis.endGroup()
Beispiel #28
0
class TasmotaDevicesTree(QAbstractItemModel):
    def __init__(self, root=Node(""), parent=None):
        super(TasmotaDevicesTree, self).__init__(parent)
        self._rootNode = root

        self.devices = {}

        self.settings = QSettings()
        self.settings.beginGroup("Devices")

        for d in self.settings.childGroups():
            self.devices[d] = self.addDevice(
                TasmotaDevice,
                self.settings.value("{}/friendly_name".format(d), d))

    def rowCount(self, parent=QModelIndex()):
        if not parent.isValid():
            parentNode = self._rootNode
        else:
            parentNode = parent.internalPointer()

        return parentNode.childCount()

    def columnCount(self, parent):
        return 2

    def data(self, index, role):

        if not index.isValid():
            return None

        node = index.internalPointer()

        if role == Qt.DisplayRole:
            if index.column() == 0:
                return node.name()
            elif index.column() == 1:
                return node.value()

        elif role == Qt.DecorationRole:
            if index.column() == 0:
                typeInfo = node.typeInfo()

                if typeInfo:
                    return QIcon("GUI/icons/{}.png".format(typeInfo))

        elif role == Qt.TextAlignmentRole:
            if index.column() == 1:
                return Qt.AlignVCenter | Qt.AlignRight

    def get_device_by_topic(self, topic):
        for i in range(self._rootNode.childCount()):
            d = self._rootNode.child(i)
            if d.name() == topic:
                return self.index(d.row(), 0, QModelIndex())
            return None

    def setData(self, index, value, role=Qt.EditRole):

        if index.isValid():
            if role == Qt.EditRole:
                node = index.internalPointer()
                node.setValue(value)
                self.dataChanged.emit(index, index, [Qt.DisplayRole])
                return True
        return False

    def setDeviceFriendlyName(self, index, value, role=Qt.EditRole):
        if index.isValid():
            if role == Qt.EditRole:
                node = index.internalPointer()
                if value != node.friendlyName():
                    node.setFriendlyName(value)
                    self.dataChanged.emit(index, index, [Qt.DisplayRole])
                    return True
        return False

    def setDeviceName(self, index, value, role=Qt.EditRole):
        if index.isValid():
            if role == Qt.EditRole:
                node = index.internalPointer()
                node.setName(value)
                self.dataChanged.emit(index, index, [Qt.DisplayRole])
                return True
        return False

    def headerData(self, section, orientation, role):
        if role == Qt.DisplayRole:
            if section == 0:
                return "Device"
            else:
                return "Value"

    def flags(self, index):
        return Qt.ItemIsEnabled | Qt.ItemIsSelectable

    def parent(self, index):

        node = self.getNode(index)
        parentNode = node.parent()

        if parentNode == self._rootNode:
            return QModelIndex()

        return self.createIndex(parentNode.row(), 0, parentNode)

    def index(self, row, column, parent):

        parentNode = self.getNode(parent)

        childItem = parentNode.child(row)

        if childItem:
            return self.createIndex(row, column, childItem)
        else:
            return QModelIndex()

    def getNode(self, index):
        if index.isValid():
            node = index.internalPointer()
            if node:
                return node

        return self._rootNode

    def insertRows(self, position, rows, parent=QModelIndex()):

        parentNode = self.getNode(parent)

        self.beginInsertRows(parent, position, position + rows - 1)

        for row in range(rows):
            childCount = parentNode.childCount()
            childNode = Node("untitled" + str(childCount))
            success = parentNode.insertChild(childCount, childNode)

        self.endInsertRows()

        return success

    def addDevice(self, device_type, name, parent=QModelIndex()):
        rc = self.rowCount(parent)
        parentNode = self.getNode(parent)

        device = device_type(name)
        self.beginInsertRows(parent, rc, rc + 1)
        parentNode.insertChild(rc, device)
        dev_idx = self.index(rc, 0, parent)
        self.endInsertRows()

        parentNode.devices()[name] = dev_idx

        self.beginInsertRows(dev_idx, 0, len(device.provides()))
        for p in device.provides().keys():
            cc = device.childCount()
            device.insertChild(cc, node_map[p](name=p))
            device.provides()[p] = self.index(cc, 1, dev_idx)
        self.endInsertRows()

        return dev_idx

    def removeRows(self, position, rows, parent=QModelIndex()):

        parentNode = self.getNode(parent)
        self.beginRemoveRows(parent, position, position + rows - 1)

        for row in range(rows):
            success = parentNode.removeChild(position)

        self.endRemoveRows()

        return success
Beispiel #29
0
class frmAccess(QDialog, Ui_frmAccess):
    databaseCreated = pyqtSignal(ConnectionQt)

    def __init__(self, module, settingsSection, settings=None, parent=None):
        QDialog.__init__(self, parent)
        if settings == None:
            self.settings = QSettings()
        else:
            self.settings = settings
        self.settingsSection = settingsSection
        self.module = module

        self.setModal(True)
        self.setupUi(self)
        self.setResources()
        self.resize(
            self.settings.value(self.settingsSection + "/qdialog_size",
                                QSize(200, 60)))
        self.parent = parent

        self.languages = TranslationLanguageManager()
        self.languages.load_all()
        self.languages.selected = self.languages.find_by_id(
            self.settings.value(self.settingsSection + "/language", "en"))
        self.languages.qcombobox(self.cmbLanguages, self.languages.selected)

        self.con = ConnectionQt()  #Pointer to connection

        self.setTitle(self.tr("Log in PostreSQL database"))

        self.cmbProfiles_update()
        current_profile = self.settings.value(
            self.settingsSection + "/current_profile", "")
        if current_profile == "":
            self.txtDB.setText(
                self.settings.value(self.settingsSection + "/db", ""))
            self.txtPort.setText(
                self.settings.value(self.settingsSection + "/port", "5432"))
            self.txtUser.setText(
                self.settings.value(self.settingsSection + "/user",
                                    "postgres"))
            self.txtServer.setText(
                self.settings.value(self.settingsSection + "/server",
                                    "127.0.0.1"))
        else:
            self.cmbProfiles.setCurrentText(current_profile)

    ## Reimplements QDialog.exec_ method to make an autologin if PGPASSWORD environment variable is detected.
    def exec_(self):
        try:
            self.password = environ['PGPASSWORD']
            debug("Password automatically set from environment variable")
            self.txtPass.setText(self.password)
            self.cmdYN.accepted.emit()
        except:
            self.txtPass.setFocus()
            QDialog.exec_(self)
        self.settings.setValue(self.settingsSection + "/qdialog_size",
                               self.size())
        self.settings.sync()

    def setResources(self,
                     pixmap=":/reusingcode/frmaccess_pixmap.png",
                     icon=":/reusingcode/frmaccess_icon.png",
                     database_new=":/reusingcode/database_new.png",
                     profile_new=":/reusingcode/profile_new.png",
                     profile_update=":/reusingcode/profile_update.png",
                     profile_delete=":/reusingcode/button_cancel.png"):
        self.lblPixmap.setPixmap(QPixmap(pixmap))
        self.setWindowIcon(QIcon(icon))
        self.cmdDatabaseNew.setIcon(QIcon(database_new))
        self.cmdProfileNew.setIcon(QIcon(profile_new))
        self.cmdProfileUpdate.setIcon(QIcon(profile_update))
        self.cmdProfileDelete.setIcon(QIcon(profile_delete))

    def setTitle(self, text):
        self.setWindowTitle(text)

    def setLabel(self, text):
        self.lbl.setText(text)

    def setLanguagesVisible(self, boolean):
        if boolean == False:
            self.lblLanguage.hide()
            self.cmbLanguages.hide()

    def setProfilesVisible(self, boolean):
        if boolean == False:
            self.lineProfile.hide()
            self.lblProfile.hide()
            self.cmbProfiles.hide()
            self.cmdProfileNew.hide()
            self.cmdProfileUpdate.hide()
            self.cmdProfileDelete.hide()

    @pyqtSlot(int)
    def on_cmbLanguages_currentIndexChanged(self, stri):
        self.languages.selected = self.languages.find_by_id(
            self.cmbLanguages.itemData(self.cmbLanguages.currentIndex()))
        self.settings.setValue(self.settingsSection + "/language",
                               self.languages.selected.id)
        self.languages.cambiar(self.languages.selected.id, self.module)
        self.retranslateUi(self)

    @pyqtSlot(str)
    def on_cmbProfiles_currentTextChanged(self, stri):
        self.txtDB.setText(
            self.settings.value(
                self.settingsSection + "_profile_" +
                self.cmbProfiles.currentText() + "/db", "xulpymoney"))
        self.txtPort.setText(
            self.settings.value(
                self.settingsSection + "_profile_" +
                self.cmbProfiles.currentText() + "/port", "5432"))
        self.txtUser.setText(
            self.settings.value(
                self.settingsSection + "_profile_" +
                self.cmbProfiles.currentText() + "/user", "postgres"))
        self.txtServer.setText(
            self.settings.value(
                self.settingsSection + "_profile_" +
                self.cmbProfiles.currentText() + "/server", "127.0.0.1"))

    def __save_current_profile(self):
        if self.cmbProfiles.currentText() == "":
            self.settings.setValue(self.settingsSection + "/db",
                                   self.txtDB.text())
            self.settings.setValue(self.settingsSection + "/port",
                                   self.txtPort.text())
            self.settings.setValue(self.settingsSection + "/user",
                                   self.txtUser.text())
            self.settings.setValue(self.settingsSection + "/server",
                                   self.txtServer.text())
            self.settings.setValue(
                self.settingsSection + "/language",
                self.cmbLanguages.itemData(self.cmbLanguages.currentIndex()))
            self.settings.setValue(self.settingsSection + "/current_profile",
                                   "")
        else:
            self.settings.setValue(
                self.settingsSection + "_profile_" +
                self.cmbProfiles.currentText() + "/db", self.txtDB.text())
            self.settings.setValue(
                self.settingsSection + "_profile_" +
                self.cmbProfiles.currentText() + "/port", self.txtPort.text())
            self.settings.setValue(
                self.settingsSection + "_profile_" +
                self.cmbProfiles.currentText() + "/user", self.txtUser.text())
            self.settings.setValue(
                self.settingsSection + "_profile_" +
                self.cmbProfiles.currentText() + "/server",
                self.txtServer.text())
            self.settings.setValue(
                self.settingsSection + "_profile_" +
                self.cmbProfiles.currentText() + "/language",
                self.cmbLanguages.itemData(self.cmbLanguages.currentIndex()))
            self.settings.setValue(self.settingsSection + "/current_profile",
                                   self.cmbProfiles.currentText())
        self.settings.sync()

    @pyqtSlot()
    def on_cmdYN_accepted(self):
        self.__save_current_profile()
        self.con.init__create(self.txtUser.text(), self.txtPass.text(),
                              self.txtServer.text(), self.txtPort.text(),
                              self.txtDB.text())
        self.con.connect()
        if self.con.is_active():
            self.accept()
        else:
            qmessagebox(
                self.tr("Error conecting to {} database in {} server").format(
                    self.con.db, self.con.server))

    @pyqtSlot()
    def on_cmdYN_rejected(self):
        self.reject()

    def on_cmdProfileNew_released(self):
        name = qinputbox_string(self.tr("Profile name"))
        self.cmbProfiles.addItem(name)
        self.settings.setValue(self.settingsSection + "/db", self.txtDB.text())

    def on_cmdProfileUpdate_released(self):
        before = self.cmbProfiles.currentText()
        after = qinputbox_string(self.tr("Profile name"))
        self.cmbProfiles.setItemText(self.cmbProfiles.currentIndex(), after)
        self.settings.remove(self.settingsSection + "_profile_" + before)
        self.__save_current_profile()

    def on_cmdProfileDelete_released(self):
        self.settings.remove(self.settingsSection + "_profile_" +
                             self.cmbProfiles.currentText())
        self.settings.setValue(self.settingsSection + "/current_profile", "")
        self.cmbProfiles_update()

    ## @return List of string with profile names
    def __list_of_profiles(self):
        r = []
        for group in self.settings.childGroups():
            if group.startswith(self.settingsSection + "_profile_"):
                r.append(group.replace(self.settingsSection + "_profile_", ""))
        print(r)
        return r

    def cmbProfiles_update(self, selected=None):
        profiles = self.__list_of_profiles()
        self.cmbProfiles.blockSignals(True)
        self.cmbProfiles.clear()
        for profile in profiles:
            self.cmbProfiles.addItem(profile)

        #Force without signals to be in -1. There were problems when 0 is selected, becouse it didn't emit anything
        self.cmbProfiles.setCurrentIndex(-1)
        if selected is None:
            self.cmbProfiles.blockSignals(False)
        else:
            self.cmbProfiles.blockSignals(False)
            self.cmbProfiles.setCurrentIndex(
                self.cmbProfiles.findData(selected.id))

    def on_cmdDatabaseNew_released(self):
        respuesta = QMessageBox.warning(
            self, self.windowTitle(),
            self.tr("Do you want to create {} database in {}?".format(
                self.txtDB.text(), self.cmbLanguages.currentText())),
            QMessageBox.Ok | QMessageBox.Cancel)
        if respuesta == QMessageBox.Ok:
            admin_pg = AdminPG(self.txtUser.text(), self.txtPass.text(),
                               self.txtServer.text(), self.txtPort.text())

            if admin_pg.db_exists(self.txtDB.text()) == True:
                qmessagebox(self.tr("Xulpymoney database already exists"))
                return

            if admin_pg.create_db(self.txtDB.text()) == False:
                qmessagebox(self.newdb.error)
            else:
                self.__save_current_profile()
                self.con = admin_pg.connect_to_database(self.txtDB.text(),
                                                        connectionqt=True)
                if self.con.is_active():
                    self.databaseCreated.emit(self.con)
                    self.accept()
                else:
                    qmessagebox(
                        self.
                        tr("Error conecting to {} database in {} server, after creating database"
                           ).format(self.con.db, self.con.server))
Beispiel #30
0
    def reload(self):

        reg = QSettings()

        if "current session" in reg.childKeys() and reg.value(
                "current session", '').strip() and reg.value(
                    "current session", '').strip() in reg.childGroups():
            self._session = reg.value("current session")

        self._logger.info(self.tr("Current session : ") + self._session)

        self.setWindowTitle(self._session)

        if self._session not in reg.childGroups():
            reg.beginGroup(self._session)
            reg.setValue("host", self._host)
            reg.setValue("port", self._port)
            reg.setValue("root topic", self._rootTopic)
            reg.endGroup()
        else:
            reg.beginGroup(self._session)
            self._host = reg.value("host", 'localhost')
            try:
                self._port = reg.value("port", 1883, type=int)
            except:
                pass
            self._rootTopic = reg.value("root topic", '')
            reg.endGroup()

        if "current session" in reg.childKeys() and not reg.value(
                "current session", '') in reg.childGroups():
            reg.remove("current session")

        self._mqttSwitchingConnection = False
        self._mqttSwitchingSubscription = False

        if self._host != self._mqttServerHost or self._port != self._mqttServerPort:
            self._mqttSwitchingConnection = True
        elif self._rootTopic != self._mqttRootTopic:
            self._mqttSwitchingSubscription = True

        self._mqttServerHost = self._host
        self._mqttServerPort = self._port
        self._mqttRootTopic = self._rootTopic
        self._mqttSubTopic = '#'

        if self._rootTopic:
            self._mqttSubTopic = self._rootTopic + '/#'

        reg.beginGroup(self._session)
        inbox = reg.value("param inbox", 'inbox')
        outbox = reg.value("param outbox", 'outbox')
        regexInbox = reg.value("regex inbox",
                               r'^%ROOT%/(?P<correspondent>.+)/%INBOX%$')
        regexOutbox = reg.value("regex outbox",
                                r'^%ROOT%/(?P<correspondent>.+)/%OUTBOX%$')
        regexDefault = reg.value("regex default",
                                 r'.*/(?P<correspondent>[^/]+)/[^/]+$')
        reg.endGroup()

        regexInbox = regexInbox.replace("%ROOT%", self._rootTopic).replace(
            "%INBOX%", inbox)
        regexOutbox = regexOutbox.replace("%ROOT%", self._rootTopic).replace(
            "%OUTBOX%", outbox)

        self._topicRegexInbox = None
        try:
            self._topicRegexInbox = re.compile(regexInbox)
        except Exception as e:
            self._logger.error(self.tr("Failed to compile inbox regex"))
            self._logger.debug(e)

        self._topicRegexOutbox = None
        try:
            self._topicRegexOutbox = re.compile(regexOutbox)
        except Exception as e:
            self._logger.error(self.tr("Failed to compile outbox regex"))
            self._logger.debug(e)

        self._topicRegexDefault = None
        try:
            self._topicRegexDefault = re.compile(regexDefault)
        except Exception as e:
            self._logger.error(
                self.tr("Failed to compile topic default regex"))
            self._logger.debug(e)

        index = self._tabWidget.currentIndex()
        current = self._tabWidget.currentWidget()

        for index in (1, self._tabWidget.count()):
            try:
                self._displays.remove(self._tabWidget.widget(index))
                self._tabWidget.widget(index).deleteLater()
                self._tabWidget.removeTab(index)
            except Exception as e:
                self._logger.error(
                    self.
                    tr("Failed to remove observation : not in display list (index="
                       ) + str(index) + self.tr(")"))
                self._logger.debug(e)

        dspmsg = ''
        for d in self._displays:
            if dspmsg:
                dspmsg += ' | '
            else:
                dspmsg = 'Displays : '
            dspmsg += d.title()
        self._logger.debug(dspmsg)

        reg.beginGroup(self._session)
        for i in reg.childGroups():
            self.addDisplay(i)
        reg.endGroup()

        QCoreApplication.processEvents()

        if self._mqttSwitchingConnection:
            self.switchConnection()
        elif self._mqttSwitchingSubscription:
            self.switchSubscription()
Beispiel #31
0
    def _buildUi(self):
        self._options = {}
        if os.path.isfile('definitions.ini'):
            definitions = QSettings('definitions.ini', QSettings.IniFormat)
            for group in definitions.childGroups():
                definitions.beginGroup(group)
                if group == "options":
                    for key in definitions.childKeys():
                        self._options[key] = definitions.value(key)
                definitions.endGroup()

        main_layout = QVBoxLayout()
        main_layout.setSpacing(12)

        self._led = LedWidget(self.tr("Arduino Echo"), QSize(40, 20))
        self._led.setRedAsBold(True)
        self._led.setRedAsRed(True)
        self._led.switchOn('gray')

        settings_button = QPushButton()
        settings_button.setIcon(QIcon("./images/settings.svg"))
        settings_button.setFlat(True)
        settings_button.setToolTip(self.tr("Configuration"))
        settings_button.setIconSize(QSize(16, 16))
        settings_button.setFixedSize(QSize(24, 24))

        header_layout = QHBoxLayout()
        header_layout.addWidget(self._led)
        header_layout.addWidget(settings_button, Qt.AlignRight)
        main_layout.addLayout(header_layout)

        self._selectionComboBox = QComboBox()
        self.loadMessages()
        main_layout.addWidget(self._selectionComboBox)

        self._props_messages_input = QPlainTextEdit()
        self._props_messages_input.setFrameShape(QFrame.NoFrame)
        self._props_messages_input.setCursorWidth(8)
        main_layout.addWidget(self._props_messages_input)

        buttons_layout = QHBoxLayout()
        main_layout.addLayout(buttons_layout)

        send_button = QPushButton(self.tr("Send"))
        buttons_layout.addWidget(send_button)

        clear_button = QPushButton(self.tr("Clear"))
        buttons_layout.addWidget(clear_button)

        self._props_messages_display = QTextEdit()
        self._props_messages_display.setReadOnly(True)
        main_layout.addWidget(self._props_messages_display)

        main_layout.addStretch(0)

        self.setLayout(main_layout)

        self._selectionComboBox.activated.connect(self.onSelectionBox)
        clear_button.pressed.connect(self.onClearButton)
        send_button.pressed.connect(self.onSendButton)
        settings_button.pressed.connect(self.settings)
        self.switchLed.connect(self._led.switchOn)