8 Commits

Author SHA1 Message Date
f08ea8ebc6 build(app): Collect complete zeroconf module with PyInstaller
From `zeroconf` version 0.128.5 `zeroconf._utils` has been changed. The
PyInstaller does not collect all submodules automatically, this is now
forced via `--collect-submodules`.
2024-12-02 10:52:28 +01:00
1a087f213d build: Use right backslashes in make.bat file for Windows
Calling programs is written with a single backslash. When passing
parameters to a program, double backslashes should be used, otherwise a
single one could be interpreted as an escape character.
2024-12-02 10:52:28 +01:00
44d9ea4561 build: Let target venv run combined with other targets
The venv target always had to be created as a separate command. Now it
is possible to use it with other targets in a command.
2024-12-02 10:52:28 +01:00
6a1e989e19 chore: Release 0.11.0 2023-11-24 11:59:28 +01:00
6619a172c7 build: Wrong values in make.bat file for windows
During the upgrade of the build system this error was merged. Missing
app-data files and wrong PyInstaller format.
2023-11-24 11:59:28 +01:00
eb48557c77 fix: Update proginit to a compatible windows version 2023-11-15 13:42:27 +01:00
356f1d29ff chore: Release 0.11.0rc2 2023-11-15 13:26:38 +01:00
af68db167c feat: New context menu entries for DI counters and RO switching cycles
Adds functions to the context menu entries to reset the counters of a DI
module and read the switching cycles of a RO module. In addition, the
labels were also equipped with the context menu, which was otherwise
only on the value fields.
2023-11-15 13:03:52 +01:00
8 changed files with 190 additions and 71 deletions

View File

@@ -8,6 +8,9 @@ APP_NAME = RevPi\ Commander
APP_IDENT = org.revpimodio.revpicommander
APPLE_SIG = "Developer ID Application: Sven Sager (U3N5843D9K)"
# Python interpreter to use for venv creation
SYSTEM_PYTHON = python3
# Set path to create the virtual environment with package name
ifdef PYTHON3_VENV
VENV_PATH = $(PYTHON3_VENV)/$(PACKAGE)
@@ -15,39 +18,37 @@ else
VENV_PATH = venv
endif
# If virtualenv exists, use it. If not, use PATH to find commands
SYSTEM_PYTHON = python3
PYTHON = $(or $(wildcard $(VENV_PATH)/bin/python), $(SYSTEM_PYTHON))
APP_VERSION = $(shell "$(PYTHON)" src/$(PACKAGE) --version | cut -d ' ' -f 2)
all: build_ui build_rc test build
# Set targets for "all"-target
all: build-ui build-rc build
.PHONY: all
## Environment
venv-info:
@echo Environment for $(APP_NAME) $(APP_VERSION)
@echo Using path: "$(VENV_PATH)"
exit 0
## Virtual environment creation with SYSTEM_PYTHON
venv:
# Start with empty environment
"$(SYSTEM_PYTHON)" -m venv "$(VENV_PATH)"
source "$(VENV_PATH)/bin/activate" && \
python3 -m pip install --upgrade pip && \
python3 -m pip install -r requirements.txt
exit 0
"$(VENV_PATH)/bin/pip" install --upgrade pip
"$(VENV_PATH)/bin/pip" install --upgrade -r requirements.txt
venv-ssp:
# Include system installed site-packages and add just missing modules
"$(SYSTEM_PYTHON)" -m venv --system-site-packages "$(VENV_PATH)"
source "$(VENV_PATH)/bin/activate" && \
python3 -m pip install --upgrade pip && \
python3 -m pip install -r requirements.txt
exit 0
"$(VENV_PATH)/bin/pip" install --upgrade pip
"$(VENV_PATH)/bin/pip" install --upgrade -r requirements.txt
.PHONY: venv-info venv venv-ssp
.PHONY: venv venv-ssp
# Choose python interpreter from venv or system
PYTHON = $(or $(wildcard $(VENV_PATH)/bin/python), $(SYSTEM_PYTHON))
# Read app version from program
APP_VERSION = $(shell "$(PYTHON)" src/$(PACKAGE) --version | cut -d ' ' -f 2)
# Environment info
venv-info:
@echo Environment for $(APP_NAME) $(APP_VERSION)
@echo Using path: "$(VENV_PATH)"
.PHONY: venv-info
## Compile Qt UI files to python code
build-ui:
@@ -109,6 +110,7 @@ app-licenses:
app: build-ui build-rc app-licenses
"$(PYTHON)" -m PyInstaller -n $(APP_NAME) \
--collect-submodules=zeroconf \
--add-data="src/$(PACKAGE)/locale:./$(PACKAGE)/locale" \
--add-data="dist/bundled-libraries.md:$(PACKAGE)/open-source-licenses" \
--add-data="dist/open-source-licenses.*:$(PACKAGE)/open-source-licenses" \
@@ -123,6 +125,7 @@ app: build-ui build-rc app-licenses
app-mac: build-ui build-rc app-licenses
"$(PYTHON)" -m PyInstaller -n $(APP_NAME) \
--collect-submodules=zeroconf \
--add-data="src/$(PACKAGE)/locale:./$(PACKAGE)/locale" \
--add-data="dist/bundled-libraries.md:$(PACKAGE)/open-source-licenses" \
--add-data="dist/open-source-licenses.*:$(PACKAGE)/open-source-licenses" \
@@ -164,6 +167,8 @@ clean:
rm -rf build dist src/*.egg-info
# PyInstaller created files
rm -rf *.spec
# Pycaches
find . -type d -name '__pycache__' -exec rm -r {} \+
distclean: clean
# Virtual environment

View File

@@ -2,7 +2,7 @@
set PACKAGE=revpicommander
set APP_NAME=RevPi Commander
set PYTHON=venv\\Scripts\\python.exe
set PYTHON=venv\Scripts\python.exe
if "%1" == "venv" goto venv
if "%1" == "test" goto test
@@ -24,7 +24,7 @@ goto end
:venv
python -m venv venv
venv\\Scripts\\pip.exe install -r requirements.txt
venv\Scripts\pip.exe install -r requirements.txt
goto end
:test
@@ -41,7 +41,7 @@ goto end
mkdir dist
%PYTHON% -m piplicenses ^
--format=markdown ^
--output-file dist/bundled-libraries.md
--output-file dist\\bundled-libraries.md
%PYTHON% -m piplicenses ^
--with-authors ^
--with-urls ^
@@ -49,7 +49,7 @@ goto end
--with-license-file ^
--no-license-path ^
--format=json ^
--output-file dist/open-source-licenses.json
--output-file dist\\open-source-licenses.json
%PYTHON% -m piplicenses ^
--with-authors ^
--with-urls ^
@@ -57,14 +57,19 @@ goto end
--with-license-file ^
--no-license-path ^
--format=plain-vertical ^
--output-file dist/open-source-licenses.txt
--output-file dist\\open-source-licenses.txt
%PYTHON% -m PyInstaller -n "%APP_NAME%" ^
--add-data="dist/bundled-libraries.md;%PACKAGE%\open-source-licenses" ^
--add-data="dist/open-source-licenses.*;%PACKAGE%\open-source-licenses" ^
--collect-submodules=zeroconf ^
--add-data="dist\\bundled-libraries.md;%PACKAGE%\\open-source-licenses" ^
--add-data="dist\\open-source-licenses.*;%PACKAGE%\\open-source-licenses" ^
--add-data="src\\%PACKAGE%\\locale;.\\%PACKAGE%\\locale" ^
--add-data="data\\%PACKAGE%.ico;." ^
--icon=data\\%PACKAGE%.ico ^
--noconfirm ^
--clean ^
--onefile ^
src\\%PACKAGE%\\__main__.py
--onedir ^
--windowed ^
src\%PACKAGE%\__main__.py
goto end
:distclean
@@ -72,7 +77,7 @@ goto end
:clean
rmdir /S /Q .pytest_cache
rmdir /S /Q build dist src\%PACKAGE%.egg-info
rmdir /S /Q build dist src\\%PACKAGE%.egg-info
del /Q *.spec
:end

View File

@@ -2,7 +2,7 @@
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
#define MyAppName "RevPi Commander"
#define MyAppVersion "0.10.0"
#define MyAppVersion "0.11.0"
#define MyAppPublisher "Sven Sager"
#define MyAppURL "https://revpimodio.org/"
#define MyAppICO "data\revpicommander.ico"

View File

@@ -4,4 +4,4 @@ __author__ = "Sven Sager"
__copyright__ = "Copyright (C) 2023 Sven Sager"
__license__ = "GPLv2"
__package__ = "revpicommander"
__version__ = "0.11.0rc1"
__version__ = "0.11.0"

View File

@@ -10,7 +10,6 @@ from logging import getLogger
from PyQt5 import QtCore, QtGui, QtWidgets
from . import helper
from . import proginit as pi
from .ui.debugios_ui import Ui_win_debugios
log = getLogger(__name__)
@@ -102,6 +101,12 @@ class DebugIos(QtWidgets.QMainWindow, Ui_win_debugios):
signed = io[6]
word_order = io[7] if len(io) > 7 else "ignored"
# Since RevPiPyLoad 0.11.0rc2 we have a list with async functions
if len(io) > 8:
async_call = io[8]
else:
async_call = []
val = container.findChild(self.search_class, name)
if val is not None:
# Destroy IO if the properties was changed
@@ -115,24 +120,41 @@ class DebugIos(QtWidgets.QMainWindow, Ui_win_debugios):
else:
continue
lbl = QtWidgets.QLabel(name, container)
lbl.setObjectName("lbl_".format(name))
lbl.setStyleSheet(self.style_sheet)
val = self._create_widget(name, byte_length, bit_address, byteorder, signed, read_only, word_order)
lbl, val = self._create_widgets(
name,
byte_length,
bit_address,
byteorder,
signed,
read_only,
word_order,
async_call,
)
lbl.setParent(container)
val.setParent(container)
layout.insertRow(counter, val, lbl)
self.splitter.setSizes([1, 1])
def _create_widget(
def _create_widgets(
self, name: str, byte_length: int, bit_address: int, byteorder: str, signed: bool, read_only: bool,
word_order: str):
word_order: str, async_call: list):
"""Create widget in functions address space to use lambda functions."""
# Create lable to set same properties of value widget for context menues
lbl = QtWidgets.QLabel(name)
lbl.setObjectName("lbl_".format(name))
lbl.setStyleSheet(self.style_sheet)
if bit_address >= 0:
val = QtWidgets.QCheckBox()
val.setEnabled(not read_only)
if async_call:
lbl.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
val.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
lbl.customContextMenuRequested.connect(self.on_context_menu)
val.customContextMenuRequested.connect(self.on_context_menu)
# Set alias to use the same function name on all widget types
val.setValue = val.setChecked
if not read_only:
@@ -143,9 +165,12 @@ class DebugIos(QtWidgets.QMainWindow, Ui_win_debugios):
# Bytes or string
val = QtWidgets.QLineEdit()
val.setReadOnly(read_only)
lbl.setProperty("struct_type", "text")
val.setProperty("struct_type", "text")
lbl.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
val.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
lbl.customContextMenuRequested.connect(self.on_context_menu)
val.customContextMenuRequested.connect(self.on_context_menu)
# Set alias to use the same function name on all widget types
@@ -159,13 +184,20 @@ class DebugIos(QtWidgets.QMainWindow, Ui_win_debugios):
val = QtWidgets.QDoubleSpinBox()
val.setReadOnly(read_only)
lbl.setProperty("struct_type", struct_type)
val.setProperty("struct_type", struct_type)
lbl.setProperty("frm", "{0}{1}".format(
">" if byteorder == "big" else "<",
struct_type.lower() if signed else struct_type
))
val.setProperty("frm", "{0}{1}".format(
">" if byteorder == "big" else "<",
struct_type.lower() if signed else struct_type
))
lbl.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
val.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
lbl.customContextMenuRequested.connect(self.on_context_menu)
val.customContextMenuRequested.connect(self.on_context_menu)
val.setDecimals(0)
@@ -175,15 +207,23 @@ class DebugIos(QtWidgets.QMainWindow, Ui_win_debugios):
if not read_only:
val.valueChanged.connect(self._change_sbx_dvalue)
lbl.setObjectName(name)
val.setObjectName(name)
lbl.setProperty("big_endian", byteorder == "big")
val.setProperty("big_endian", byteorder == "big")
lbl.setProperty("bit_address", bit_address)
val.setProperty("bit_address", bit_address)
lbl.setProperty("byte_length", byte_length)
val.setProperty("byte_length", byte_length)
lbl.setProperty("signed", signed)
val.setProperty("signed", signed)
lbl.setProperty("word_order", word_order)
val.setProperty("word_order", word_order)
lbl.setProperty("async_call", async_call)
val.setProperty("async_call", async_call)
self.__qwa[name] = val
return val
return lbl, val
@QtCore.pyqtSlot(int)
def _change_cbx_value(self, value: int):
@@ -217,6 +257,31 @@ class DebugIos(QtWidgets.QMainWindow, Ui_win_debugios):
sender = self.sender()
men = QtWidgets.QMenu(sender)
act_reset = QtWidgets.QAction(self.tr("Reset counter"))
if "di_reset" in sender.property("async_call"):
men.addAction(act_reset)
men.addSeparator()
if "ro_get_switching_cycles" in sender.property("async_call"):
switching_cycles = helper.cm.call_remote_function(
"ps_switching_cycles",
sender.objectName(),
default_value=self.tr("Can not display"),
)
if type(switching_cycles) is not list:
switching_cycles = [switching_cycles]
for i in range(len(switching_cycles)):
relais_counter = self.tr(" Relais {0}").format(i + 1)
if len(switching_cycles) == 1:
relais_counter = ""
men.addAction(
self.tr("Switching cycles{0}: {1}").format(
relais_counter,
switching_cycles[i],
)
)
men.addSeparator()
if sender.property("byte_length") > 4:
# Textbox needs format buttons
act_as_text = QtWidgets.QAction(self.tr("as text"))
@@ -231,11 +296,13 @@ class DebugIos(QtWidgets.QMainWindow, Ui_win_debugios):
act_signed = QtWidgets.QAction(self.tr("signed"), men)
act_signed.setCheckable(True)
act_signed.setChecked(sender.property("signed") or False)
if sender.property("bit_address") == -1:
men.addAction(act_signed)
act_byteorder = QtWidgets.QAction(self.tr("big_endian"), men)
act_byteorder.setCheckable(True)
act_byteorder.setChecked(sender.property("big_endian") or False)
if sender.property("bit_address") == -1:
men.addAction(act_byteorder)
if sender.property("byte_length") > 2:
@@ -266,6 +333,12 @@ class DebugIos(QtWidgets.QMainWindow, Ui_win_debugios):
sender.setProperty("big_endian", act_byteorder.isChecked())
elif rc == act_wordorder:
sender.setProperty("word_order", "big" if act_wordorder.isChecked() else "little")
elif rc == act_reset:
try:
helper.cm.call_remote_function("ps_reset_counter", sender.objectName(), raise_exception=True)
except Exception as e:
log.error(e)
QtWidgets.QMessageBox.critical(self, self.tr("Error"), self.tr("Could not reset the counter value"))
if sender.property("frm"):
sender.setProperty("frm", "{0}{1}".format(

View File

@@ -172,7 +172,7 @@ Das kann eine der folgenden Ursachen haben:
- Der RevPiPyLoad XML-RPC Dienst ist nur an localhost gebunden
- Die Berechtigungen sind nicht für diese IP gesetzt!!!
Benutze &quot;Über SSH verbinden&quot; um eine verschlüsselte Verbindung aufzubauen oder führe 'sudo revpipyload_secure_installation' auf dem Revolution Pi aus, um eine direkte Verbindung zu konfigurieren!</translation>
Benutze &quot;Über SSH verbinden&quot; um eine verschlüsselte Verbindung aufzubauen oder führe &apos;sudo revpipyload_secure_installation&apos; auf dem Revolution Pi aus, um eine direkte Verbindung zu konfigurieren!</translation>
</message>
<message>
<location filename="../helper.py" line="399"/>
@@ -216,7 +216,7 @@ Das kann eine der folgenden Ursachen haben:
<location filename="../debugcontrol.py" line="271"/>
<source>Error set value of device &apos;{0}&apos; Output &apos;{1}&apos;: {2}
</source>
<translation>Fehler beim Setzen des Ausgangs '{1}' auf Modul '{0}': {2}
<translation>Fehler beim Setzen des Ausgangs &apos;{1}&apos; auf Modul &apos;{0}&apos;: {2}
</translation>
</message>
<message>
@@ -228,40 +228,75 @@ Das kann eine der folgenden Ursachen haben:
<context>
<name>DebugIos</name>
<message>
<location filename="../debugios.py" line="231"/>
<location filename="../debugios.py" line="287"/>
<source>signed</source>
<translation></translation>
</message>
<message>
<location filename="../debugios.py" line="236"/>
<location filename="../debugios.py" line="293"/>
<source>big_endian</source>
<translation></translation>
</message>
<message>
<location filename="../debugios.py" line="222"/>
<location filename="../debugios.py" line="278"/>
<source>as text</source>
<translation></translation>
</message>
<message>
<location filename="../debugios.py" line="224"/>
<location filename="../debugios.py" line="280"/>
<source>as number</source>
<translation></translation>
</message>
<message>
<location filename="../debugios.py" line="380"/>
<location filename="../debugios.py" line="444"/>
<source>Can not use format text</source>
<translation>Formatierung nicht möglich</translation>
</message>
<message>
<location filename="../debugios.py" line="380"/>
<location filename="../debugios.py" line="444"/>
<source>Can not convert bytes {0} to a text for IO &apos;{1}&apos;. Switch to number format instead!</source>
<translation>Kann bytes {0} für '{1}' nicht in Text konvertieren. Wechseln Sie auf Nummernformat!</translation>
<translation>Kann bytes {0} für &apos;{1}&apos; nicht in Text konvertieren. Wechseln Sie auf Nummernformat!</translation>
</message>
<message>
<location filename="../debugios.py" line="242"/>
<location filename="../debugios.py" line="300"/>
<source>switch wordorder</source>
<translation>Wordorder tauschen</translation>
</message>
<message>
<location filename="../debugios.py" line="252"/>
<source>Reset counter</source>
<translation>Zähler zurücksetzen</translation>
</message>
<message>
<location filename="../debugios.py" line="258"/>
<source>can not display</source>
<translation type="obsolete">kann nicht angezeigt werden</translation>
</message>
<message>
<location filename="../debugios.py" line="265"/>
<source> Relais {0}</source>
<translation></translation>
</message>
<message>
<location filename="../debugios.py" line="268"/>
<source>Switching cycles{0}: {1}</source>
<translation>Schaltzyklen{0}: {1}</translation>
</message>
<message>
<location filename="../debugios.py" line="332"/>
<source>Error</source>
<translation>Fehler</translation>
</message>
<message>
<location filename="../debugios.py" line="332"/>
<source>Could not reset the counter value</source>
<translation>Kann Zähler nicht zurücksetzen</translation>
</message>
<message>
<location filename="../debugios.py" line="258"/>
<source>Can not display</source>
<translation>Kann nicht angezeigt werden</translation>
</message>
</context>
<context>
<name>MqttManager</name>
@@ -396,7 +431,7 @@ Dies kann aus der Textbox oben kopiert werden.</translation>
<message>
<location filename="../revpicommander.py" line="339"/>
<source>Can not start the simulator! Maybe the piCtory file is corrupt or you have no write permissions for &apos;{0}&apos;.</source>
<translation>Kann Simulator nicht starten! Vielleicht ist die piCtory Datei defekt oder es gibt keine Schreibberechtigung für '{0}'.</translation>
<translation>Kann Simulator nicht starten! Vielleicht ist die piCtory Datei defekt oder es gibt keine Schreibberechtigung für &apos;{0}&apos;.</translation>
</message>
<message>
<location filename="../revpicommander.py" line="506"/>
@@ -442,7 +477,7 @@ Es sollten alle RevPiModIO Programme vorher beendet werden, da diese ihre IO Wer
We are trying to activate this service now and reconnect. The settings can be changed at any time via &apos;webstatus&apos;.</source>
<translation>Vielleicht läuft der RevPiPyLoad Dienst nicht.
Wir versuchen diesen Dienst jetzt zu aktivieren und verbinden uns neu. Die Einstellungen können über 'Webstatus' jederzeit geändert werden.</translation>
Wir versuchen diesen Dienst jetzt zu aktivieren und verbinden uns neu. Die Einstellungen können über &apos;Webstatus&apos; jederzeit geändert werden.</translation>
</message>
</context>
<context>
@@ -485,7 +520,7 @@ Wir versuchen diesen Dienst jetzt zu aktivieren und verbinden uns neu. Die Einst
<message>
<location filename="../revpifiles.py" line="276"/>
<source>Can not open last directory &apos;{0}&apos;.</source>
<translation>Kann letztes Verzeichnis '{0}' nicht öffnen.</translation>
<translation>Kann letztes Verzeichnis &apos;{0}&apos; nicht öffnen.</translation>
</message>
<message>
<location filename="../revpifiles.py" line="333"/>
@@ -510,7 +545,7 @@ Wir versuchen diesen Dienst jetzt zu aktivieren und verbinden uns neu. Die Einst
<message>
<location filename="../revpifiles.py" line="483"/>
<source>Can not access the folder &apos;{0}&apos; to read files.</source>
<translation>Keine Berechtigung für Zugriff auf Ordner '{0}'.</translation>
<translation>Keine Berechtigung für Zugriff auf Ordner &apos;{0}&apos;.</translation>
</message>
<message>
<location filename="../revpifiles.py" line="584"/>
@@ -520,7 +555,7 @@ Wir versuchen diesen Dienst jetzt zu aktivieren und verbinden uns neu. Die Einst
<message>
<location filename="../revpifiles.py" line="533"/>
<source>Error while download file &apos;{0}&apos;.</source>
<translation>Fehler beim Herunterladen der Datei '{0}'.</translation>
<translation>Fehler beim Herunterladen der Datei &apos;{0}&apos;.</translation>
</message>
<message>
<location filename="../revpifiles.py" line="541"/>
@@ -534,7 +569,7 @@ Wir versuchen diesen Dienst jetzt zu aktivieren und verbinden uns neu. Die Einst
Select &apos;Yes&apos; to override, &apos;No&apos; to download only missing files.</source>
<translation>Eine oder mehrere Dateien existieren auf diesem Computer! Sollen bestehende Dateien überschrieben werden?
Wählen Sie 'Ja' zum Überschreiben, 'Nein' um nur fehlende Dateien zu laden.</translation>
Wählen Sie &apos;Ja&apos; zum Überschreiben, &apos;Nein&apos; um nur fehlende Dateien zu laden.</translation>
</message>
<message>
<location filename="../revpifiles.py" line="573"/>
@@ -549,7 +584,7 @@ Wählen Sie 'Ja' zum Überschreiben, 'Nein' um nur fehlende Dateien zu laden.</t
<message>
<location filename="../revpifiles.py" line="584"/>
<source>Error while delete file &apos;{0}&apos;.</source>
<translation>Fehler beim Löschen der Datei '{0}'.</translation>
<translation>Fehler beim Löschen der Datei &apos;{0}&apos;.</translation>
</message>
<message>
<location filename="../revpifiles.py" line="135"/>
@@ -574,12 +609,12 @@ Wählen Sie 'Ja' zum Überschreiben, 'Nein' um nur fehlende Dateien zu laden.</t
<message>
<location filename="../revpifiles.py" line="179"/>
<source>Upgrade your Revolution Pi! This function needs at least &apos;revpipyload&apos; 0.11.0</source>
<translation>Aktualisiere deinen Revolution Pi! Diese Funktion benötigt mindestens 'revpipyload' 0.11.0</translation>
<translation>Aktualisiere deinen Revolution Pi! Diese Funktion benötigt mindestens &apos;revpipyload&apos; 0.11.0</translation>
</message>
<message>
<location filename="../revpifiles.py" line="198"/>
<source>Upgrade your Revolution Pi! This function needs at least &apos;revpipyload&apos; 0.9.5</source>
<translation>Aktualisiere deinen Revolution Pi! Diese Funktion benötigt mindestens 'revpipyload' 0.9.5</translation>
<translation>Aktualisiere deinen Revolution Pi! Diese Funktion benötigt mindestens &apos;revpipyload&apos; 0.9.5</translation>
</message>
<message>
<location filename="../revpifiles.py" line="193"/>
@@ -1254,7 +1289,7 @@ Dies ist kein Fehler von RevPi Commander.</translation>
<source>The base topic is the first part of any mqtt topic, the Revolution Pi will publish. You can use any character includig &apos;/&apos; to structure the messages on your broker.
For example: revpi0000/data</source>
<translation>Der Basistopic wird allen MQTT Topics vorangestellt, welche der Revolution Pi veröffentlicht. Es können alle Zeichen inklusive '/' verwendet werden, um die Nachrichten auf dem Broker zu strukturieren.
<translation>Der Basistopic wird allen MQTT Topics vorangestellt, welche der Revolution Pi veröffentlicht. Es können alle Zeichen inklusive &apos;/&apos; verwendet werden, um die Nachrichten auf dem Broker zu strukturieren.
Zum Beispiel: revpi0000/data</translation>
</message>

View File

@@ -5,7 +5,7 @@
__author__ = "Sven Sager"
__copyright__ = "Copyright (C) 2018-2023 Sven Sager"
__license__ = "LGPL-2.0-or-later"
__version__ = "1.3.0"
__version__ = "1.3.1"
import logging
import sys
@@ -14,7 +14,6 @@ from configparser import ConfigParser
from os import R_OK, W_OK, access, environ, getpid, remove
from os.path import abspath, dirname, exists, join
from shutil import copy, move
from socket import AF_UNIX, SOCK_DGRAM, socket
from threading import Event
try:
@@ -39,6 +38,8 @@ _daemon_started_up = Event()
_daemon_main_pid = getpid()
_systemd_notify = environ.get("NOTIFY_SOCKET", None)
if _systemd_notify:
from socket import AF_UNIX, SOCK_DGRAM, socket
# Set up the notification socket for systemd communication
_systemd_socket = socket(family=AF_UNIX, type=SOCK_DGRAM)
if _extend_daemon_startup_timeout: