rtrbt Geschrieben January 24, 2019 at 15:21 Share Geschrieben January 24, 2019 at 15:21 Moin, Seit heute ist eine Beta-Version der MQTT-Bindings 2.0 verfügbar. Experimentiert damit, wir freuen uns auf Feedback, Bugs und mehr. Die MQTT-Bindings werden jetzt, genau wie die Bindings anderer Programmiersprachen, automatisch generiert. Alle Bricks und Bricklets werden unterstützt. Die Bindings bilden die API der Python-Bindings ab, weshalb sie nicht rückwärtskompatibel zur alten MQTT-Proxy sind. Die MQTT-Proxy ist damit abgekündigt. Die aktuellen Bindings, sowie Beispiele im examples-Ordner, sind angehangen. Die Bindings hängen von Python >= 2.7.9 oder >= 3.4 und der Paho-Bibliothek (>= 1.3.1), die hier verfügbar ist, ab. Die Dokumentation ist hier zu finden Viel Spaß! Erik Edit: Version 2.0.1: - Fehlerbehandlung für JSON-Fehler in Python 2 überarbeitet.tinkerforge_mqtt_bindings_2_0_1.zip Zitieren Link zu diesem Kommentar Share on other sites More sharing options...
Nic Geschrieben January 28, 2019 at 12:37 Share Geschrieben January 28, 2019 at 12:37 Hi Erik, prima, dass ihr weiterhin das Mqtt Protokoll unterstützt. Am alten Proxy habe ich immer geschätzt, dass man ohne eine Codezeile schreiben zu müssen, in einem Mqtt Client die Brick Daten adhoc sofort sehen konnte. Verhält sich die neue Variante genauso, sprich auf Kommandozeile starten und anschließend mit Clients verbinden und subscriben? Ev. habe ich das in den Doku übersehen: wie oder wo lässt sich der Mqtt-Broker Host/IP und Port angeben? Gruß, Nic Zitieren Link zu diesem Kommentar Share on other sites More sharing options...
rtrbt Geschrieben January 28, 2019 at 12:53 Autor Share Geschrieben January 28, 2019 at 12:53 Hi, Die Bindings brauchen etwas mehr manuelle Arbeit als die alte Proxy. Damit ein MQTT-Client die Daten erhält, muss ein Callback registriert, oder (periodisch) ein Getter aufgerufen werden. Die MQTT-Bindings verhalten sich hier genauso wie die Bindings der Programmiersprachen. MQTT-Broker-Verbindungsdaten lassen sich mit --broker-host [HOSTNAME/IP] und --broker-port [PORT] konfigurieren. Es gibt noch weitere Parameter für Authentisierung, Zertifikate usw., die mit --help angezeigt werden können. Ich werde das ganze aber mal noch in die Dokumentation einbauen. Gruß, Erik Zitieren Link zu diesem Kommentar Share on other sites More sharing options...
Gast piwo Geschrieben February 7, 2019 at 01:22 Share Geschrieben February 7, 2019 at 01:22 grossartig. alles gelesen. nix vestanden. entweder bin ich ein trottel, oder ... dacapo. danke Zitieren Link zu diesem Kommentar Share on other sites More sharing options...
Gast piwo Geschrieben February 10, 2019 at 15:35 Share Geschrieben February 10, 2019 at 15:35 meine kommentare: 1) (ich habe den code des "alten mqtt-proxys" wenigsten dazu nutzen könnnen, damit ich irgendwo mal ALLE möglichen imports finden kann : die braucht man ja als erstes, wenn man include-code-generatoren für beliebige stacks schreiben will. ein "import tinkerforge" ist ja eine noop ! 2) ich habe nirgends (aber vllt. bin ich auch zu deppert) code gefunden, wo zumindest ALLE deviceids in einer datenstruktur versammelt wären, die mir helfen bei meinen include-code-generatoren ... geschweige denn fand ich subpackage-names und class-names mit key deviceid ... 3) der naming-wahnsinn geht aber hier weiter ... bisherige "essentielle" bezeichner z.b. f.d. temperatur bricklet in der 2. version : - bricklet_temperature_v2 : import subpackage API - BrickletTemperatureV2 : classname API - 2113 : deviceid API nun kommt dazu : - temperature_v2_bricklet : mqtt-name - TemperatureV2Bricklet : classname mqtt-proxy - Temperature Bricklet 2.0 : displayname mqtt-proxy 4) ich habe ja den verdacht, dass ihr gar keine transparenz wollt. geschweige denn, dass man - API-funktionen von stacks dynamisch nutzen kann - auch nur IN ANSATZ IRGENDETWAS wie introspektion (selbst mit dem vorhandenen source-code) zusammenbringt 5) der neue mqtt-proxy ist wiederum eine "neuimplementierung" eines brickd prozedural und wenig transparent. keineswegs universell einsetzbar : denn es erfolgt keine klare architekturtrennung zwischen PSEUDO-BRICKD / ANWENDUNGSSCHICHT ein weiteres indiz für meine hypothese, dass es kein interesse gibt, mehr transparenz und benutzerfreundlichkeit umzusetzen. das gegenteil scheint mir der fall zu sein. lg wp Zitieren Link zu diesem Kommentar Share on other sites More sharing options...
borg Geschrieben February 10, 2019 at 23:16 Share Geschrieben February 10, 2019 at 23:16 Ich glaube da hast du etwas missverstanden. Die MQTT-Bindings sind dazu da damit man Bricks/Bricklets per MQTT ansprechen kann. Die sind nicht dazu da um irgendetwas per Python zu machen. Das ist sozusagen ein Binary welches du ausführen kannst. Das wir den Code auch veröffentlichen ist nur Zugabe. Zum Beispiel kann man damit über die MQTT-Anbindung von Node-RED Bricks/Brickelts nutzen. Was du dir da anschaust ist generierter Code (genauso wie die Python-Bindings übrigens). Das ist so als würdest du dir generierten X86-Assembler anschauen und dich darüber wundern das es schlecht lesbar ist. Wenn du wissen möchtest wie die MQTT-Bindings zustande kommen musst du hier schauen: https://github.com/Tinkerforge/generators/tree/master/mqtt Zitieren Link zu diesem Kommentar Share on other sites More sharing options...
borg Geschrieben February 11, 2019 at 00:16 Share Geschrieben February 11, 2019 at 00:16 Bezüglich deiner dynamischen ID + Name + Klasse-Problematik: Du kannst da dynamisch wie folgt dran kommen: #!/usr/bin/env python3 # -*- coding: utf-8 -*- from tinkerforge import device_factory for device_id in device_factory.DEVICE_CLASSES: name = device_factory.get_device_display_name(device_id) cls = device_factory.get_device_class(device_id) print("Device ID: {0}, Name: {1}, Class: {2}".format(device_id, name, cls)) Zitieren Link zu diesem Kommentar Share on other sites More sharing options...
rtrbt Geschrieben February 11, 2019 at 08:22 Autor Share Geschrieben February 11, 2019 at 08:22 Die MQTT-Bindings übersetzen die device_id übrigens automatisch auf den Devicenamen wie er in Topics verwendet wird und hängen in enumerate-Callback- und get_identity-Antworten den Display-Namen als _display_name-Feld an. Zitieren Link zu diesem Kommentar Share on other sites More sharing options...
Gast piwo Geschrieben February 11, 2019 at 09:32 Share Geschrieben February 11, 2019 at 09:32 ad device_factory : ... da hätte ich mir viel lebenszeit erspart, wenn man da mal in den docs mit der nase draufgestossen worden ware ... Zitieren Link zu diesem Kommentar Share on other sites More sharing options...
Gast piwo Geschrieben February 11, 2019 at 10:39 Share Geschrieben February 11, 2019 at 10:39 bezüglich code-generatoren : nicht nur ihr erzeugt code dynamisch. das erzeugen von python-code, der anschliessend ausgeführt wird, ist ja essentiell bei dieser API-struktur ;-) was aber ganz entscheidend fehlt, ist eine subclassierung aller funktionen in (daten)-getter/setter/callbacks,reine servicefunktionen und sonstige funktionen ... eine introspektion oder sonstiger generatorcode, der das für jedes bricklet macht : nämlich die oben genannten (daten)-getter/setter/callbacks einer konkreten Bricklet-API als *** halbwegs klar lesbare datenstrukturen *** als python-code visuaisieren, damit man das auch sinnvoll debuggen bzw. den generator anpassen kann .... am besten wärs ja, wenn man den generierten code gar nicht mehr bearbeiten oder modifizieren muss, weil alles notwendige zur laufzeit handle-bar ist .... sowas macht z.b. der mqtt-proxy. ... einmal die bindings rein .... speziellen hooks dran um das dann von app-klassen nutzbar zu machen .... sowas ist nicht die einzige anwendung, die sowas "braucht". das macht mehr oder minder JEDE intelligente anwendung, die nicht so wie in euren beispielen statisch definiert wird : mal den/die zielstacks runterenumierieren, die ipconn in entdlosschleife am leben erhalten und mit den gefundenen bricklets halt dann was sinnvolles machen ... ich bevorzuge ja : for stackdef in stackdefs: stack_start(stackdef) """ host,port,.... uids{} # key uid # meta-informationen der app bzw. wiring von/zur app """ def stack_starts(stackdef): """ ipconn starten, bei den dynamisch enumerierten mastern die "root master" zu finden, die dann resetten, warten, bricklet-uids der stackdef mit der ipconn initialisieren und dann einfach ein "stackstarted" callback an die app absetzen. irgendwelche exceptions, die sich durch einen impliziten disconnect oder sonstige troubles am stack ergeben wandern in ein "stackexception" callback, das die app dann auswertet und entweder den stack ewig neu startet, oder die app beendet nach einem retry_failure_count > N RETURNS: stack_callback_wrappers[] # status-callbacks f. exceptions bzw. die pseudo-exception "stack_started" bricklet_function_wrappers{} # key : uid # generische wrapper zur bricklet-ansteuerung. entweder "direct-calls" oder mit funktionen aus den app-metainformationen angereichert """ damit hat man dann mal schon einen "running stack". ok. was aber NICHT getan ist, ist ein GENERISCHES WIRING zwischen app und stack ... für jedes bricklet muss ich mehr oder weniger auch metainformationen aus der doku einbringen, d.h. konkrete implementierungsschritte. ich schreibe eine app für alle STACKS ja mit bestimmten klassen von bricklets : z.b. 2x irgendein temperatur-sensor, 1x *** irgendein aktor der die heizung schaltet *** dieser aktor kann ALLES MÖGLICHE SEIN : ein digital-out der ein externes ssr schaltet oder auch ein ssr-bricklet direkt aber auch die temperatur kann von einem ptc kommen oder auch was anderem. gott weiss. KONSEQUENZ : a) ich brauche klassen oder einen funktionsarray für ein generisches "turn on/turn off" bzw. "temperature" auf einer ganzen reihe von Bricklets, welche das denn zur laufzeit sind - gott weiss - aber dafür gibts dann ja die stackdef ;-) b) selbst bei verschiedenen Bricklets ist nicht nur ein getter notwendig. so ist z.b. beim RemoteSwitch-Bricklet eine ganze funktionskette notwendig (da KANN ich gar nicht "blocking" arbeiten, sondern es muss eben exceptions wie "try_later" geben !!!) c) desweiteren kann man nicht bei jedem Bricklet einfach EINE art von callback-struktur voraussetzen, die "einfach daten liefert". auch da ist oft eine ganze funktionslogik notwendig um die sonder- und sonstigen fälle abzudecken. für gewisse "alarm"-funktionen sind aber threshholds unabdingbar, weil getter ev. "zu spät" kommen und ein polling viel zu langsam ist (z.b.. distance-ir) ... d) C O N C L U S I O "GENERISCHES WIRING" ist daher nur möglich 1) zur LAUFZEIT für ALLE KLASSEN VON BRICKLETS 2) beim "mapping" auf konkrete stacks mit code-generatoren introspektion bzw. LESBARE strukturen welche alle bricklets abstrakt definieren sind somit unabdingbar --- ich löse DERZEIT das so, dass ich in der stackdef (siehe oben) generierten code verwende der möglichst eine generische weiterverwendung durch die app ermöglicht bzw. abstrakte klassen wie ACTOR/SENSOR die auf ganzen subsets von Bricklets arbeiten : denn was wird man schon von einem Bricklet wollen : seine daten, egal wie es das liefert - bzw. es soll was machen, egal was das ist ;-) ... ... und damit bin ich wieder bein mqtt-proxy. dort läuft ziemlich genau DAS. ... wenn man DAS in einer beliebigen app kriegt, dann trifft das 100% ... und ich seh nicht ein, dass JEDER der tf-komponenten kauft GENAU DIESES RAD JEDESMAL NEU ERFINDEN BZW. NEI IMPLEMENTIEREN MUSS ... Zitieren Link zu diesem Kommentar Share on other sites More sharing options...
rtrbt Geschrieben February 26, 2019 at 13:36 Autor Share Geschrieben February 26, 2019 at 13:36 Die MQTT-Bindings haben die Betaphase verlassen und sind jetzt auf der Tinkerforge-Seite verfügbar: https://www.tinkerforge.com/de/doc/Downloads.html Die Bindings unterstützen jetzt den --init-file Parameter, mit dem initiale Konfigurationsnachrichten aus einer Datei geladen werden können. Zitieren Link zu diesem Kommentar Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.