[UPDATE] RealTime OpenControl - Release 2.0 (En/De)

mit matplotlib, NumPy, pandas, SciPy, SymPy und weiteren mathematischen Programmbibliotheken.
Antworten
haschtl
User
Beiträge: 8
Registriert: Mittwoch 7. November 2018, 08:08

Nach einem Jahr Softwareentwicklung kann ich jetzt Version 2 von meiner Logging-Software vorstellen. Dabei habe ich den Funktionsumfang nochmals deutlich aufgebohrt.

Changelog (v2.0):
- PostgreSQL-Datenbank Integration für Langzeitaufnahmen
- GUI ist jetzt sauberer und aufgeräumter
- GUI beinhaltet jetzt die Möglichkeit, sich über TCP mit anderen RTOC-PCs zu verbinden.
- TelegramBot hat jetzt vollen Funktionsumfang (Komplexeres Plotten, Daten löschen, event/action system, Plugins steuern,...)
- Event/Action-System für Automatisierung
- Automatische Backups in SQL-datenbank
- Neuer Webserver
- Terminalzugang
- Plugins bekommen noch mehr Funktionen bereitgestellt, was die Einrichtung weiter vereinfacht
- Neue und ausführlichere Dokumentation auf readthedocs.io.

Wer Interesse hat, kann gerne mein github projekt anschauen, oder gleich mit pip3 RTOC installieren.
Beispielanwendungen finden sich in meiner plugin-repository


Wenn du meine Arbeit unterstützen willst, würde ich mich sehr über eine Tasse Kaffee freuen


Hier die Kurzbeschreibung aus der ReadMe

RealTime OpenControl offers a simple way for real-time data recording, visualization and editing.
RTOC is made for communication with different devices (IoT) in a network or local sensors or devices providing data. It collects Data from any source and provides easy and intuitive user interaction. The simplest way is, to run RTOC with the user-frontend. But it can also run a HTML-Server providing plots and events. This is the best way to view the data, if RTOC is running on screen-less devices, like a Raspberry Pi. And in any other case, you can get full access and control of RTOC with a simple Telegram-Bot all over the world, without many configurations. This bot is also capable of sending messages or warnings, if events are triggered. Read more about Events later on.
There are different ways to access data on an RTOC-Server:
- From GUI (PyQT5) (full access)
- From another RTOC-Server with TCP (partial access)
- From any device with a Telegram-Bot (full access)
- From any device with an HTML-website (only viewable)
- From any device with PostgreSQL-Database (only access to data, no controlling of RTOC)
Possible applications
- General long time data recording and automation due to postgreSQL integration
- Central measurement data recording of laboratory instruments with PC connection (e.g. power supply unit, multimeter, sensors, microcontroller)
- Central recording of measurement data from Internet devices (e.g. mobile weather stations, drones, smartphones)
- Remote monitoring and control of processes and devices with PC and Smartphone (Telegram) (e.g. 3D printing, heating, Custom-SmartHome)
- Controlling between several devices (e.g.: power regulation of a power supply unit on the temperature sensor of a multimeter)
- Decentralized data recording (e.g. on Raspberry) and access via network connection (smart projects)
- Fun projects like controlling a LED with Telegram
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

Ich hab nur mal kurz auf die Socketprogrammierung geschaut, weil dort fast immer Fehler gemacht werden. Diesmal ist die Implementierung aber fast korrekt.

In jsonsocket fällt dann auch schon gleich auf, dass Klassenattribute zur Initalisierung von Instanzattributen mißbraucht werden.
In `_send` wird stillschweigend nicht verschlüsselt, falls keine Crypto-Bibliothek installiert ist, oder der `key` vom falschen Typ. Das sollte beides in einem Error enden.
Unverständlicherweise werden die Längen nicht per sendall gesendet.
Wenn schon Binärdaten gesendet werden, warum nicht auch die Längen?

In `_recv` wird Byteweise gelesen und gleich decodiert, was im Zweifel zu einem Error führt, weil utf8 auch Mehrbyte-Zeichencodierung kennt. Eine for-Schleife über einen Index, in der für jeden einzelnen Index ein anderer Code ausgeführt wird, ist keine for-Schleife!
Dann wird dreimal der selbe Code zum Lesen eines Binär-Blocks kopiert, das wäre ein Fall für eine Funktion. Die Deserialisierung von JSON steht auch zwei mal im Code.
Eine Funktion, die im Fehlerfall mal False, mal None, mal {} zurückliefert, und im Erfolgsfall das Ergebnis einer JSON-Deserialisierung, was als gültige Werte False, None oder {} erlaubt, ist kaputt.
Fehler werfen Exceptions, und geben nichts zurück!

Namenskonvention ist, dass Module, Variablen, Funktionen und Methoden klein_mit_unterstrich geschrieben werden. Vor allem Module sollte man immer klein schreiben, um nicht in Probleme zu kommen bei Dateisystemen, die Klein-Groß-Schreibung ignorieren. Explizite Typ-Prüfung ist gegen das Ducktyping von Python und ich habe keine Stelle gefunden, wo dessen Einsatz sinnvoll gewesen wäre.
In `LoggerPlugin` sah ich, wie Du Keyword-Argumente mit *args und **kw nachprogrammiert hast, anstatt einfach die Argumente in der Funktionsdefinition so anzugeben, wie es gedacht ist. Der Einsatz von Attributen mit doppelten Unterstrichen ist falsch, das sollten alles einfache sein.
haschtl
User
Beiträge: 8
Registriert: Mittwoch 7. November 2018, 08:08

Vielen Dank für deine Vorschläge, ich werde mich darum kümmern!

Eine Frage habe ich noch zu
In jsonsocket fällt dann auch schon gleich auf, dass Klassenattribute zur Initalisierung von Instanzattributen mißbraucht werden.
.

Bei den offiziellen socket beispielen wird das auch so gemacht: https://docs.python.org/3/library/socket.html#example
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

@haschtl: ich sehe in den Beispielen keine Klassenattribute, geschweige denn überhaupt irgendeine Klassendefinition.
haschtl
User
Beiträge: 8
Registriert: Mittwoch 7. November 2018, 08:08

@ Sirius3: Habe jetzt die meisten deiner Vorschläge umgesetzt.

Hatte die Frage nicht verstanden (wusste nicht was Klassen- und Instanzattribute sind).
Was ist verkehrt daran, das so zu machen? Und wie wäre es richtig?
Benutzeravatar
__blackjack__
User
Beiträge: 13116
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@haschtl: Das ist halt einfach falsch Klassenattribute zu verwenden wenn das eigentlich ein Instanzattribut sein sollte. Nach der `__init__()` sollten alle Attribute existieren und nicht später noch eines hinzugefügt werden. Richtig wäre es also `client` in der `__init__()` zu definieren und `backlog` als Konstante `BACKLOG` zu nennen, damit man auch erkennt, das es sich um eine Konstante handelt, ohne das man den Code der Klasse lesen muss.

`__del__()` lässt sich hier einfacher als ``__del__ = close`` definieren (nachdem man `close()` definiert hat) aber eigentlich sollte man `__del__()` gar nicht definieren! Es ist nicht garantiert, dass die Methode überhaupt aufgerufen wird und alleine das vorhandensein der Methode kann unter Umständen zu einem Speicherleck führen. Man sollte aus solchen Klassen besser Kontextmanager machen und sie dann mit ``with`` verwenden. Oder wenn sie eine `close()`-Methode haben mit ``with`` und `contextlib.closing()`.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
haschtl
User
Beiträge: 8
Registriert: Mittwoch 7. November 2018, 08:08

@__blackjack__: Ah das hatte ich ganz übersehen. Jetzt passt es. Die __del__ habe ich rausgenommen, da ich sie nicht brauche

Vielen Dank für die Hinweise!
Antworten