diff --git a/de/source/Software/API_Bindings.rst b/de/source/Software/API_Bindings.rst index b7132483..d56769a4 100644 --- a/de/source/Software/API_Bindings.rst +++ b/de/source/Software/API_Bindings.rst @@ -31,6 +31,7 @@ Programmiersprache: * :ref:`LabVIEW ` * :ref:`Mathematica ` * :ref:`MATLAB/Octave ` +* :ref:`MicroPython ` * :ref:`MQTT ` * :ref:`openHAB ` * :ref:`Perl ` @@ -57,6 +58,7 @@ Programmiersprache: LabVIEW Mathematica MATLAB/Octave + MicroPython MQTT openHAB Perl diff --git a/de/source/Software/API_Bindings_MicroPython.rst b/de/source/Software/API_Bindings_MicroPython.rst new file mode 100644 index 00000000..89b1e010 --- /dev/null +++ b/de/source/Software/API_Bindings_MicroPython.rst @@ -0,0 +1,205 @@ + +.. _api_bindings_micropython: + +MicroPython - API Bindings +========================== + +Die MicroPython Bindings ermöglichen es :ref:`Bricks ` und +:ref:`Bricklets ` aus selbst erstellten MicroPython-Skripten +heraus zu steuern, die auf Mikrocontroller-Boards wie ESP32, Raspberry Pi Pico +und anderen laufen. Die :ref:`ZIP Datei ` für +die Bindings beinhaltet: + +* in ``source/`` den Quelltext der Bindings als flache ``.py`` Dateien +* in ``examples/`` die Beispiele für alle Bricks und Bricklets +* in ``stubs/`` die ``.pyi`` Type-Stub-Dateien für IDE Code-Vervollständigung + +Voraussetzungen +--------------- + +* `MicroPython `__ 1.17 oder neuer +* Ein MicroPython-fähiges Board mit WiFi oder Ethernet Netzwerkanbindung + (z.B. ESP32, Raspberry Pi Pico W) + +.. _api_bindings_micropython_install: + +Installation +------------ + +Da MicroPython-Boards ein begrenztes Dateisystem haben und kein pip oder +setuptools unterstützen, gibt es keinen Paketmanager. Stattdessen werden die +Binding-Dateien direkt auf das Board kopiert. + +Die ``.py`` Dateien aus dem ``source/`` Ordner der +:ref:`ZIP Datei ` können mit einem Tool wie +`mpremote `__, +`Thonny `__ oder +`ampy `__ auf das Board kopiert werden. +Zum Beispiel mit mpremote:: + + mpremote cp source/ip_connection.py : + mpremote cp source/bricklet_temperature_v2.py : + +Es müssen nur die tatsächlich benötigten Bindings kopiert werden, um Platz auf +dem Board zu sparen. Mindestens werden immer ``ip_connection.py`` sowie die +Binding-Datei für jedes zu verwendende Gerät benötigt. + +WiFi-Einrichtung +---------------- + +Für WiFi-fähige Boards (z.B. ESP32) muss die Netzwerkverbindung hergestellt +werden, bevor eine Verbindung zum Brick Daemon aufgebaut werden kann. Dies kann +mit dem ``network`` Modul von MicroPython durchgeführt werden: + +.. code-block:: python + + import network + + wlan = network.WLAN(network.STA_IF) + wlan.active(True) + wlan.connect("YOUR_SSID", "YOUR_PASSWORD") + + while not wlan.isconnected(): + pass + + print("Connected:", wlan.ifconfig()) + +hmac-Modul (für Authentifizierung) +---------------------------------- + +Wenn Authentifizierung (``ipcon.authenticate()``) verwendet werden soll, wird +das ``hmac`` Modul benötigt. Die meisten MicroPython-Builds enthalten es nicht +standardmäßig. Es kann über MicroPythons Paketmanager installiert werden +(benötigt eine Netzwerkverbindung):: + + import mip + mip.install("hmac") + +Test eines Beispiels +-------------------- + +Um ein MicroPython Beispiel testen zu können, müssen zuerst :ref:`Brick Daemon +` und :ref:`Brick Viewer ` installiert werden. Brick Daemon +arbeitet als Proxy zwischen der USB Schnittstelle der Bricks und den API +Bindings. Brick Viewer kann sich mit Brick Daemon verbinden und gibt +Informationen über die angeschlossenen Bricks und Bricklets aus. + +Als Beispiel wird im Folgenden das Konfigurationsbeispiel des Stepper Bricks +getestet. Dafür müssen die ``example_configuration.py`` Datei aus dem +``examples/brick/stepper/`` Ordner und die benötigten Binding-Dateien auf das +Board kopiert werden:: + + board/ + -> ip_connection.py + -> brick_stepper.py + -> example_configuration.py + +Am Anfang des Beispiels ist mit ``HOST`` und ``PORT`` angegeben unter welcher +Netzwerkadresse der Stepper Brick zu erreichen ist. Ist er lokal per USB +angeschlossen dann ist ``localhost`` und 4223 richtig. Wenn das Beispiel auf +einem Mikrocontroller-Board ausgeführt wird, muss ``localhost`` durch die +IP-Adresse des Computers ersetzt werden, auf dem der Brick Daemon läuft. Als +``UID`` muss die UID des angeschlossenen Stepper Bricks angegeben werden, diese +kann über den Brick Viewer ermittelt werden: + +.. code-block:: python + + HOST = "192.168.1.100" + PORT = 4223 + UID = "XXYYZZ" # Change XXYYZZ to the UID of your Stepper Brick + +Dann ist auch schon alles bereit, um dieses Beispiel auf dem Board testen zu +können:: + + mpremote run example_configuration.py + +.. note:: + Anders als die regulären Python Bindings verwenden die MicroPython Bindings + eine flache Modulstruktur. Imports verwenden die Form + ``from ip_connection import IPConnection`` anstatt + ``from tinkerforge.ip_connection import IPConnection``. + +.. note:: + Die MicroPython Bindings verwenden eine synchrone/Polling Architektur. Es gibt + keinen Hintergrund-Thread für die Callback-Auslieferung. Die Methode + ``ipcon.dispatch_callbacks(seconds)`` muss periodisch aufgerufen werden, um + eingehende Callbacks zu verarbeiten. Ein negativer Wert steht für + unendliche Auslieferung: ``ipcon.dispatch_callbacks(-1)``. + +.. note:: + Auto-Reconnect wird in den MicroPython Bindings nicht unterstützt, da dafür + Hintergrund-Threads benötigt werden. Die Verbindungswiederherstellung muss + explizit im eigenen Code behandelt werden. + +Dateigröße reduzieren mit mpy-cross +------------------------------------ + +Die ``.py`` Binding-Dateien können mit dem ``mpy-cross`` Tool zu MicroPython +Bytecode (``.mpy`` Dateien) kompiliert werden, um die Dateigröße zu reduzieren +und die Importzeiten zu beschleunigen. + +.. important:: + Die ``mpy-cross`` Version muss zur MicroPython Firmware-Version auf dem Board + passen. Wenn auf dem Board zum Beispiel MicroPython 1.23.x läuft, wird + ``mpy-cross`` aus dem 1.23 Release benötigt. Eine nicht passende Version führt + zu Importfehlern auf dem Board. + +``mpy-cross`` passend zur Firmware-Version installieren:: + + pip install mpy-cross==1.23.0 # Version an eigene Firmware anpassen + +Eine Binding-Datei kompilieren:: + + mpy-cross bricklet_temperature_v2.py + +Dies erzeugt ``bricklet_temperature_v2.mpy`` im selben Verzeichnis. Die +``.mpy`` Datei wird anstelle der ``.py`` Datei auf das Board kopiert. Alle +Imports funktionieren auf die gleiche Weise — MicroPython findet ``.mpy`` +Dateien automatisch. + +Alle Binding-Dateien auf einmal kompilieren:: + + for f in source/*.py; do mpy-cross "$f"; done + +Die typische Größenreduzierung beträgt ca. 70-80% im Vergleich zu den +originalen ``.py`` Dateien. + +IDE-Unterstützung mit Type Stubs +-------------------------------- + +Die ZIP-Datei enthält einen ``stubs/`` Ordner mit ``.pyi`` Type-Stub-Dateien +für alle Bindings. Diese ermöglichen Code-Vervollständigung, Typprüfung und +Inline-Dokumentation in IDEs wie VS Code (mit Pylance) oder PyCharm. + +Um die Stubs zu verwenden, muss die IDE so konfiguriert werden, dass der +``stubs/`` Ordner als zusätzlicher Analysepfad eingebunden wird. Für VS Code +wird folgendes in die ``.vscode/settings.json`` eingetragen: + +.. code-block:: json + + { + "python.analysis.extraPaths": ["path/to/stubs"] + } + +Die Stubs enthalten vollständige Typ-Annotationen und Docstrings für alle +Geräteklassen, Methoden und Konstanten. Sie werden nicht auf dem Board +benötigt — sie werden nur von der IDE während der Entwicklung verwendet. + +API Referenz und Beispiele +-------------------------- + +Links zur API Referenz der IP Connection, Bricks und Bricklets sowie die +Beispiele aus der ZIP Datei der Bindings sind in der folgenden Tabelle +aufgelistet. Anleitungen für weiterführende Projekte finden sich im Abschnitt +über :ref:`Kits `. + +.. include:: API_Bindings_MicroPython_links.table + +.. toctree:: + :hidden: + + IP Connection + Bricks + Bricks (Abgekündigt) + Bricklets + Bricklets (Abgekündigt) diff --git a/de/source/Software/IPConnection_MicroPython.rst b/de/source/Software/IPConnection_MicroPython.rst new file mode 100644 index 00000000..c0562b79 --- /dev/null +++ b/de/source/Software/IPConnection_MicroPython.rst @@ -0,0 +1,309 @@ + +.. |ref_api_bindings| replace:: :ref:`MicroPython API Bindings ` +.. |ref_install_guide| replace:: :ref:`Installationanleitung ` +.. |bindings_name| replace:: MicroPython + +.. _ip_connection_micropython: + +MicroPython - IP Connection +============================ + +.. include:: IPConnection_Common.substitutions + :start-after: >>>intro + :end-before: <<`__. + +Enumerate +^^^^^^^^^ + +`Download (example_enumerate.py) `__ + +.. literalinclude:: IPConnection_MicroPython_example_enumerate.py + :language: python + :linenos: + :tab-width: 4 + + +Authenticate +^^^^^^^^^^^^ + +`Download (example_authenticate.py) `__ + +.. literalinclude:: IPConnection_MicroPython_example_authenticate.py + :language: python + :linenos: + :tab-width: 4 + + +.. _ip_connection_micropython_api: + +API +--- + +Prinzipiell kann jede Funktion der MicroPython Bindings +``ip_connection.Error`` Exception werfen, welche ein ``value`` und +eine ``description`` Property hat. ``value`` kann verschiedene Werte haben: + +* Error.TIMEOUT = -1 +* Error.NOT_ADDED = -6 (seit Version 2.0.0 nicht mehr verwendet) +* Error.ALREADY_CONNECTED = -7 +* Error.NOT_CONNECTED = -8 +* Error.INVALID_PARAMETER = -9 +* Error.NOT_SUPPORTED = -10 +* Error.UNKNOWN_ERROR_CODE = -11 +* Error.STREAM_OUT_OF_SYNC = -12 +* Error.INVALID_UID = -13 +* Error.NON_ASCII_CHAR_IN_SECRET = -14 +* Error.WRONG_DEVICE_TYPE = -15 +* Error.DEVICE_REPLACED = -16 +* Error.WRONG_RESPONSE_LENGTH = -17 + +.. note:: + Anders als die regulären Python Bindings sind die MicroPython Bindings + single-threaded. Es gibt keinen Hintergrund-Empfangsthread. Callbacks + werden explizit durch Aufruf von :py:func:`dispatch_callbacks(seconds) + `, z.B. ``dispatch_callbacks(0)`` oder + ``dispatch_callbacks(-1)``, ausgeliefert. + +Grundfunktionen +^^^^^^^^^^^^^^^ + +.. py:function:: IPConnection() + + Erzeugt ein IP Connection Objekt das verwendet werden kann um die verfügbar + Geräte zu enumerieren. Es wird auch für den Konstruktor von Bricks und + Bricklets benötigt. + + +.. py:function:: IPConnection.connect(host, port) + + :param host: str + :param port: int + :rtype: None + + Erstellt eine TCP/IP Verbindung zum gegebenen ``host`` und ``port``. Host und Port + können auf einen Brick Daemon oder einer WIFI/Ethernet Extension verweisen. + + Bricks/Bricklets können erst gesteuert werden, wenn die Verbindung erfolgreich + aufgebaut wurde. + + Blockiert bis die Verbindung aufgebaut wurde und wirft eine Exception, falls + kein Brick Daemon oder WIFI/Ethernet Extension auf dem gegebenen Host und Port + horcht. + + +.. py:function:: IPConnection.disconnect() + + :rtype: None + + Trennt die TCP/IP Verbindung zum Brick Daemon oder einer WIFI/Ethernet + Extension. + + +.. py:function:: IPConnection.authenticate(secret) + + :param secret: str + :rtype: None + + Führt einen Authentifizierungs-Handshake mit dem verbundenen Brick Daemon + oder WIFI/Ethernet Extension durch. + Ist der Handshake erfolgreich dann wechselt die Verbindung vom + nicht-authentifizierten in den authentifizierten Zustand und die Kommunikation + kann normal weitergeführt werden. Schlägt der Handshake fehl wird die + Verbindung durch die Gegenseite geschlossen. Die Authentifizierung kann + fehlschlagen wenn das Authentifizierungsgeheimnis nicht übereinstimmt oder + Authentifizierung für den Brick Daemon oder die WIFI/Ethernet Extension nicht + aktiviert ist. + + Für mehr Informationen zur Authentifizierung siehe das dazugehörige + :ref:`Tutorial `. + + .. note:: + Authentifizierung benötigt das ``hmac`` Modul, welches in den meisten + MicroPython-Builds nicht enthalten ist. Es kann über MicroPythons + Paketmanager installiert werden: + ``import mip; mip.install("hmac")`` + + .. versionadded:: 2.1.0 + + +.. py:function:: IPConnection.get_connection_state() + + :rtype: int + + Kann die folgenden Zustände zurückgeben: + + * IPConnection.\ **CONNECTION_STATE**\ _DISCONNECTED = 0: Keine Verbindung aufgebaut. + * IPConnection.\ **CONNECTION_STATE**\ _CONNECTED = 1: Eine Verbindung zum Brick + Daemon oder der WIFI/Ethernet Extension ist aufgebaut. + + +.. py:function:: IPConnection.set_timeout(timeout) + + :param timeout: float + :rtype: None + + Setzt den Timeout in Sekunden für Getter und für Setter die das + Response-Expected-Flag aktiviert haben. + + Standardwert ist 2,5. + + +.. py:function:: IPConnection.get_timeout() + + :rtype: float + + Gibt den Timeout zurück, wie er von :py:func:`set_timeout() + ` gesetzt wurde. + + +.. py:function:: IPConnection.enumerate() + + :rtype: None + + Broadcast einer Enumerierungsanfrage. Alle Bricks und Bricklets werden mit + einem Enumerate Callback antworten. + + +.. py:function:: IPConnection.dispatch_callbacks(seconds) + + :param seconds: float + :rtype: None + + Liefert eingehende Callbacks für die gegebene Dauer in Sekunden aus (negative + Werte bedeuten unendlich). Da MicroPython keine Threads unterstützt muss diese + Methode periodisch aufgerufen werden, um sicherzustellen, dass eingehende + Callbacks behandelt werden. Falls keine Callbacks benutzt werden braucht diese + Methode nicht aufgerufen zu werden. + + Die empfohlene Auslieferungsdauer ist 0. Dadurch werden nur die Callbacks + ausgeliefert die noch auf Auslieferung warten. Es wird jedoch nicht auf den + Eingang weitere Callbacks gewartet. + + +Konfigurationsfunktionen für Callbacks +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. py:function:: IPConnection.register_callback(callback_id, function) + + :param callback_id: int + :param function: callable + :rtype: None + + Registriert die ``function`` für die gegebene ``callback_id``. + + Die verfügbaren Callback IDs mit zugehörenden Funktionssignaturen + sind unten beschrieben. + + +Callbacks +^^^^^^^^^ + +Callbacks können registriert werden um über Ereignisse informiert zu werden. +Die Registrierung kann mit der Funktion :py:func:`register_callback() +` durchgeführt werden. Der erste Parameter +ist der Callback ID und der zweite die Callback Funktion: + +.. code-block:: python + + def my_callback(param): + print(param) + + ipcon.register_callback(IPConnection.CALLBACK_EXAMPLE, my_callback) + +Die verfügbaren IDs mit der dazugehörigen Parameteranzahl und -typen +werden weiter unten beschrieben. + +.. note:: + Um Callbacks zu verwenden, muss + :py:func:`dispatch_callbacks(seconds) ` + periodisch mit einem passenden Sekundenintervall aufgerufen werden, um ausstehende Callbacks auszuliefern. + + +.. py:attribute:: IPConnection.CALLBACK_ENUMERATE + + :param uid: str + :param connected_uid: str + :param position: chr + :param hardware_version: [int, int, int] + :param firmware_version: [int, int, int] + :param device_identifier: int + :param enumeration_type: int + + Der Callback empfängt sieben Parameter: + + * ``uid``: Die UID des Bricks/Bricklets. + * ``connected_uid``: Die UID des Gerätes mit dem der Brick/das Bricklet verbunden + ist. Für ein Bricklet ist dies die UID des Bricks oder Bricklets mit dem es verbunden ist. + Für einen Brick ist es die UID des untersten Bricks im Stapel. + Der unterste Master Brick hat die Connected-UID "0". Mit diesen Informationen + sollte es möglich sein die komplette Netzwerktopologie zu rekonstruieren. + * ``position``: Für Bricks: '0' - '8' (Position in Stapel). Für Bricklets: + 'a' - 'h' (Position an Brick) oder 'i' (Position des Raspberry Pi (Zero) HAT) + oder 'z' (Bricklet an :ref:`Isolator Bricklet `). + * ``hardware_version``: Major, Minor und Release Nummer der Hardwareversion. + * ``firmware_version``: Major, Minor und Release Nummer der Firmwareversion. + * ``device_identifier``: Eine Zahl, welche den Brick/Bricklet repräsentiert. + * ``enumeration_type``: Art der Enumerierung. + + Mögliche Enumerierungsarten sind: + + * IPConnection.\ **ENUMERATION_TYPE**\ _AVAILABLE = 0: Gerät ist verfügbar + (Enumerierung vom Benutzer ausgelöst: :py:func:`enumerate() + `). Diese Enumerierungsart kann mehrfach für das + selbe Gerät auftreten. + * IPConnection.\ **ENUMERATION_TYPE**\ _CONNECTED = 1: Gerät wurde neu verbunden + (Automatisch vom Brick gesendet nachdem die Kommunikation aufgebaut wurde). + Dies kann bedeuten, dass das Gerät die vorher eingestellte Konfiguration + verloren hat und neu konfiguriert werden muss. + * IPConnection.\ **ENUMERATION_TYPE**\ _DISCONNECTED = 2: Gerät wurde getrennt (Nur bei + USB-Verbindungen möglich). In diesem Fall haben nur ``uid`` und + ``enumeration_type`` einen gültigen Wert. + + Es sollte möglich sein Plug-and-Play-Funktionalität mit diesem Callback + zu implementieren (wie es im Brick Viewer geschieht) + + Die Device Identifier Werte sind :ref:`hier ` zu finden. + Es gibt auch Konstanten für diese Werte, welche nach dem folgenden Muster + benannt sind:: + + .DEVICE_IDENTIFIER + + Zum Beispiel: :py:attr:`Master.DEVICE_IDENTIFIER` + oder :py:attr:`AmbientLight.DEVICE_IDENTIFIER`. + + +.. py:attribute:: IPConnection.CALLBACK_CONNECTED + + :param connect_reason: int + + Dieser Callback wird aufgerufen wenn die IP Connection eine Verbindung + zu einem Brick Daemon oder einer WIFI/Ethernet Extension aufgebaut hat, + mögliche Gründe sind: + + * IPConnection.\ **CONNECT_REASON**\ _REQUEST = 0: Verbindung aufgebaut nach Anfrage + vom Benutzer. + + +.. py:attribute:: IPConnection.CALLBACK_DISCONNECTED + + :param disconnect_reason: int + + Dieser Callback wird aufgerufen wenn die Verbindung der IP Connection + zu einem Brick Daemon oder einer WIFI/Ethernet Extension getrennt wurde, + mögliche Gründe sind: + + * IPConnection.\ **DISCONNECT_REASON**\ _REQUEST = 0: Trennung wurde vom Benutzer + angefragt. + * IPConnection.\ **DISCONNECT_REASON**\ _ERROR = 1: Trennung aufgrund eines unlösbaren + Problems. + * IPConnection.\ **DISCONNECT_REASON**\ _SHUTDOWN = 2: Trennung wurde vom Brick Daemon + oder WIFI/Ethernet Extension eingeleitet. diff --git a/en/source/Software/API_Bindings.rst b/en/source/Software/API_Bindings.rst index d6663ddc..80dd1cd3 100644 --- a/en/source/Software/API_Bindings.rst +++ b/en/source/Software/API_Bindings.rst @@ -30,6 +30,7 @@ Installation and usage instructions for each supported programming language: * :ref:`LabVIEW ` * :ref:`Mathematica ` * :ref:`MATLAB/Octave ` +* :ref:`MicroPython ` * :ref:`MQTT ` * :ref:`openHAB ` * :ref:`Perl ` @@ -56,6 +57,7 @@ Installation and usage instructions for each supported programming language: LabVIEW Mathematica MATLAB/Octave + MicroPython MQTT openHAB Perl diff --git a/en/source/Software/API_Bindings_MicroPython.rst b/en/source/Software/API_Bindings_MicroPython.rst new file mode 100644 index 00000000..d6c60886 --- /dev/null +++ b/en/source/Software/API_Bindings_MicroPython.rst @@ -0,0 +1,196 @@ + +.. _api_bindings_micropython: + +MicroPython - API Bindings +========================== + +The MicroPython bindings allow you to control :ref:`Bricks ` and +:ref:`Bricklets ` from MicroPython scripts running on +microcontroller boards such as ESP32, Raspberry Pi Pico and others. The +:ref:`ZIP file ` for the bindings contains: + +* in ``source/`` the source code of the bindings as flat ``.py`` files +* in ``examples/`` the examples for every Brick and Bricklet +* in ``stubs/`` the ``.pyi`` type stub files for IDE code completion + +Requirements +------------ + +* `MicroPython `__ 1.17 or newer +* A MicroPython-capable board with WiFi or Ethernet networking (e.g. ESP32, + Raspberry Pi Pico W) + +.. _api_bindings_micropython_install: + +Installation +------------ + +Since MicroPython boards have limited filesystems and do not support pip or +setuptools, there is no package installer. Instead, copy the binding files +directly onto your board. + +Copy the ``.py`` files from the ``source/`` folder of the +:ref:`ZIP file ` to your board using a tool such as +`mpremote `__, +`Thonny `__ or +`ampy `__. For example, using mpremote:: + + mpremote cp source/ip_connection.py : + mpremote cp source/bricklet_temperature_v2.py : + +Copy only the bindings you actually need to save space on the board. At +minimum, you always need ``ip_connection.py`` plus the binding file for each +device you want to use. + +WiFi Setup +---------- + +For WiFi-capable boards (e.g. ESP32), the network connection must be +established before connecting to a Brick Daemon. This can be done using +MicroPython's ``network`` module: + +.. code-block:: python + + import network + + wlan = network.WLAN(network.STA_IF) + wlan.active(True) + wlan.connect("YOUR_SSID", "YOUR_PASSWORD") + + while not wlan.isconnected(): + pass + + print("Connected:", wlan.ifconfig()) + +hmac Module (for Authentication) +-------------------------------- + +If you want to use authentication (``ipcon.authenticate()``), the ``hmac`` +module is required. Most MicroPython builds do not include it by default. +Install it using MicroPython's package manager (requires a network connection):: + + import mip + mip.install("hmac") + +Testing an Example +------------------ + +To test a MicroPython example :ref:`Brick Daemon ` and :ref:`Brick +Viewer ` have to be installed first. Brick Daemon acts as a proxy +between the USB interface of the Bricks and the API bindings. Brick Viewer +connects to Brick Daemon and helps to figure out basic information about the +connected Bricks and Bricklets. + +As an example let's test the configuration example for the Stepper Brick. +For this copy the ``example_configuration.py`` file from the +``examples/brick/stepper/`` folder and the required binding files to your +board:: + + board/ + -> ip_connection.py + -> brick_stepper.py + -> example_configuration.py + +In the example ``HOST`` and ``PORT`` specify at which network address the +Stepper Brick can be found. If it is connected locally to USB then ``localhost`` +and 4223 is correct. When running on a microcontroller board, replace +``localhost`` with the IP address of the computer running Brick Daemon. The +``UID`` value has to be changed to the UID of the connected Stepper Brick, +which you can figure out using Brick Viewer: + +.. code-block:: python + + HOST = "192.168.1.100" + PORT = 4223 + UID = "XXYYZZ" # Change XXYYZZ to the UID of your Stepper Brick + +Now you're ready to run this example on your board:: + + mpremote run example_configuration.py + +.. note:: + Unlike the regular Python bindings, MicroPython bindings use a flat module + structure. Imports use the form ``from ip_connection import IPConnection`` + instead of ``from tinkerforge.ip_connection import IPConnection``. + +.. note:: + The MicroPython bindings use a synchronous/polling architecture. There is no + background thread for callback dispatch. You must call + ``ipcon.dispatch_callbacks(seconds)`` periodically to handle incoming + callbacks. Use a negative value for infinite dispatching: + ``ipcon.dispatch_callbacks(-1)``. + +.. note:: + Auto-reconnect is not supported in the MicroPython bindings because it + requires background threads. You must handle reconnection explicitly in your + code. + +Reducing File Size with mpy-cross +---------------------------------- + +The ``.py`` binding files can be compiled to MicroPython bytecode (``.mpy`` +files) to reduce file size and speed up import times. This is done using the +``mpy-cross`` tool. + +.. important:: + The ``mpy-cross`` version must match the MicroPython firmware version on your + board. For example, if your board runs MicroPython 1.23.x, you need + ``mpy-cross`` from the 1.23 release. Using a mismatched version will result + in import errors on the board. + +Install ``mpy-cross`` matching your firmware version:: + + pip install mpy-cross==1.23.0 # adjust version to match your firmware + +Compile a binding file:: + + mpy-cross bricklet_temperature_v2.py + +This creates ``bricklet_temperature_v2.mpy`` in the same directory. Copy the +``.mpy`` file to your board instead of the ``.py`` file. All imports work the +same way — MicroPython automatically finds ``.mpy`` files. + +To compile all binding files at once:: + + for f in source/*.py; do mpy-cross "$f"; done + +Typical size reduction is around 70-80% compared to the original ``.py`` files. + +IDE Support with Type Stubs +--------------------------- + +The ZIP file includes a ``stubs/`` folder with ``.pyi`` type stub files for all +bindings. These provide code completion, type checking and inline documentation +in IDEs such as VS Code (with Pylance) or PyCharm. + +To use the stubs, configure your IDE to include the ``stubs/`` folder as an +extra analysis path. For VS Code, add the following to your ``.vscode/settings.json``: + +.. code-block:: json + + { + "python.analysis.extraPaths": ["path/to/stubs"] + } + +The stubs contain full type annotations and docstrings for all device classes, +methods and constants. They are not needed on the board itself — they are only +used by the IDE during development. + +API Reference and Examples +-------------------------- + +Links to the API reference for the IP Connection, Bricks and Bricklets as +well as the examples from the ZIP file of the bindings are listed in the +following table. Further project descriptions can be found in the +:ref:`Kits ` section. + +.. include:: API_Bindings_MicroPython_links.table + +.. toctree:: + :hidden: + + IP Connection + Bricks + Bricks (Discontinued) + Bricklets + Bricklets (Discontinued) diff --git a/en/source/Software/IPConnection_MicroPython.rst b/en/source/Software/IPConnection_MicroPython.rst new file mode 100644 index 00000000..31f1b2a7 --- /dev/null +++ b/en/source/Software/IPConnection_MicroPython.rst @@ -0,0 +1,297 @@ + +.. |ref_api_bindings| replace:: :ref:`MicroPython API bindings ` +.. |ref_install_guide| replace:: :ref:`installation guide ` +.. |bindings_name| replace:: MicroPython + +.. _ip_connection_micropython: + +MicroPython - IP Connection +============================ + +.. include:: IPConnection_Common.substitutions + :start-after: >>>intro + :end-before: <<`__. + +Enumerate +^^^^^^^^^ + +`Download (example_enumerate.py) `__ + +.. literalinclude:: IPConnection_MicroPython_example_enumerate.py + :language: python + :linenos: + :tab-width: 4 + + +Authenticate +^^^^^^^^^^^^ + +`Download (example_authenticate.py) `__ + +.. literalinclude:: IPConnection_MicroPython_example_authenticate.py + :language: python + :linenos: + :tab-width: 4 + + +.. _ip_connection_micropython_api: + +API +--- + +Generally, every method of the MicroPython bindings can throw an +``ip_connection.Error`` exception that has a ``value`` and a +``description`` property. ``value`` can have different values: + +* Error.TIMEOUT = -1 +* Error.NOT_ADDED = -6 (unused since version 2.0.0) +* Error.ALREADY_CONNECTED = -7 +* Error.NOT_CONNECTED = -8 +* Error.INVALID_PARAMETER = -9 +* Error.NOT_SUPPORTED = -10 +* Error.UNKNOWN_ERROR_CODE = -11 +* Error.STREAM_OUT_OF_SYNC = -12 +* Error.INVALID_UID = -13 +* Error.NON_ASCII_CHAR_IN_SECRET = -14 +* Error.WRONG_DEVICE_TYPE = -15 +* Error.DEVICE_REPLACED = -16 +* Error.WRONG_RESPONSE_LENGTH = -17 + +.. note:: + Unlike the regular Python bindings, the MicroPython bindings are + single-threaded. There is no background receive thread. Callbacks are + dispatched explicitly by calling :py:func:`dispatch_callbacks(0) + `. + +Basic Functions +^^^^^^^^^^^^^^^ + +.. py:function:: IPConnection() + + Creates an IP Connection object that can be used to enumerate the available + devices. It is also required for the constructor of Bricks and Bricklets. + + +.. py:function:: IPConnection.connect(host, port) + + :param host: str + :param port: int + :rtype: None + + Creates a TCP/IP connection to the given ``host`` and ``port``. The host and port + can refer to a Brick Daemon or to a WIFI/Ethernet Extension. + + Devices can only be controlled when the connection was established + successfully. + + Blocks until the connection is established and throws an exception if there + is no Brick Daemon or WIFI/Ethernet Extension listening at the given + host and port. + + +.. py:function:: IPConnection.disconnect() + + :rtype: None + + Disconnects the TCP/IP connection from the Brick Daemon or the WIFI/Ethernet + Extension. + + +.. py:function:: IPConnection.authenticate(secret) + + :param secret: str + :rtype: None + + Performs an authentication handshake with the connected Brick Daemon or + WIFI/Ethernet Extension. + If the handshake succeeds the connection switches from non-authenticated to + authenticated state and communication can continue as normal. If the handshake + fails then the connection gets closed. Authentication can fail if the wrong + secret was used or if authentication is not enabled at all on the Brick Daemon + or the WIFI/Ethernet Extension. + + See the :ref:`authentication tutorial ` for more + information. + + .. note:: + Authentication requires the ``hmac`` module which is not included in most + MicroPython builds. Install it using MicroPython's package manager: + ``import mip; mip.install("hmac")`` + + .. versionadded:: 2.1.0 + + +.. py:function:: IPConnection.get_connection_state() + + :rtype: int + + Can return the following states: + + * IPConnection.\ **CONNECTION_STATE**\ _DISCONNECTED = 0: No connection is established. + * IPConnection.\ **CONNECTION_STATE**\ _CONNECTED = 1: A connection to the Brick + Daemon or the WIFI/Ethernet Extension is established. + + +.. py:function:: IPConnection.set_timeout(timeout) + + :param timeout: float + :rtype: None + + Sets the timeout in seconds for getters and for setters for which the + response expected flag is activated. + + Default timeout is 2.5. + + +.. py:function:: IPConnection.get_timeout() + + :rtype: float + + Returns the timeout as set by :py:func:`set_timeout() `. + + +.. py:function:: IPConnection.enumerate() + + :rtype: None + + Broadcasts an enumerate request. All devices will respond with an enumerate + callback. + + +.. py:function:: IPConnection.dispatch_callbacks(seconds) + + :param seconds: float + :rtype: None + + Dispatches incoming callbacks for the given amount of time in seconds (negative + value means infinity). Because MicroPython doesn't support threads you need to + call this method periodically to ensure that incoming callbacks are handled. If + you don't use callbacks you don't need to call this method. + + The recommended dispatch time is 0. This will just dispatch all pending + callbacks without waiting for further callbacks. + + +Callback Configuration Functions +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. py:function:: IPConnection.register_callback(callback_id, function) + + :param callback_id: int + :param function: callable + :rtype: None + + Registers the given ``function`` with the given ``callback_id``. + + The available callback IDs with corresponding function signatures + are described below. + + +Callbacks +^^^^^^^^^ + +Callbacks can be registered to be notified about events. The registration is +done with the :py:func:`register_callback() ` +function. The first parameter is the callback ID and the second +parameter the callback function: + +.. code-block:: python + + def my_callback(param): + print(param) + + ipcon.register_callback(IPConnection.CALLBACK_EXAMPLE, my_callback) + +The available constants with inherent number and type of parameters are +described below. + +.. note:: + Using callbacks requires calling + :py:func:`dispatch_callbacks(seconds) ` + periodically to dispatch pending callbacks. + + +.. py:attribute:: IPConnection.CALLBACK_ENUMERATE + + :param uid: str + :param connected_uid: str + :param position: chr + :param hardware_version: [int, int, int] + :param firmware_version: [int, int, int] + :param device_identifier: int + :param enumeration_type: int + + The callback has seven parameters: + + * ``uid``: The UID of the device. + * ``connected_uid``: UID where the device is connected to. For a Bricklet this + is the UID of the Brick or Bricklet it is connected to. For a Brick it is + the UID of the bottommost Brick in the stack. For the bottommost Brick + in a stack it is "0". With this information it is possible to + reconstruct the complete network topology. + * ``position``: For Bricks: '0' - '8' (position in stack). For Bricklets: + 'a' - 'h' (position on Brick) or 'i' (position of the Raspberry Pi (Zero) HAT) + or 'z' (Bricklet on :ref:`Isolator Bricklet `). + * ``hardware_version``: Major, minor and release number for hardware version. + * ``firmware_version``: Major, minor and release number for firmware version. + * ``device_identifier``: A number that represents the device. + * ``enumeration_type``: Type of enumeration. + + Possible enumeration types are: + + * IPConnection.\ **ENUMERATION_TYPE**\ _AVAILABLE = 0: Device is available + (enumeration triggered by user: :py:func:`enumerate() + `). This enumeration type can occur multiple times + for the same device. + * IPConnection.\ **ENUMERATION_TYPE**\ _CONNECTED = 1: Device is newly connected + (automatically send by Brick after establishing a communication connection). + This indicates that the device has potentially lost its previous + configuration and needs to be reconfigured. + * IPConnection.\ **ENUMERATION_TYPE**\ _DISCONNECTED = 2: Device is disconnected (only + possible for USB connection). In this case only ``uid`` and + ``enumeration_type`` are valid. + + It should be possible to implement plug-and-play functionality with this + (as is done in Brick Viewer). + + The device identifier numbers can be found :ref:`here `. + There are also constants for these numbers named following this pattern:: + + .DEVICE_IDENTIFIER + + For example: :py:attr:`Master.DEVICE_IDENTIFIER` + or :py:attr:`AmbientLight.DEVICE_IDENTIFIER`. + + +.. py:attribute:: IPConnection.CALLBACK_CONNECTED + + :param connect_reason: int + + This callback is called whenever the IP Connection got connected to a + Brick Daemon or to a WIFI/Ethernet Extension, possible reasons are: + + * IPConnection.\ **CONNECT_REASON**\ _REQUEST = 0: Connection established after + request from user. + + +.. py:attribute:: IPConnection.CALLBACK_DISCONNECTED + + :param disconnect_reason: int + + This callback is called whenever the IP Connection got disconnected from a + Brick Daemon or from a WIFI/Ethernet Extension, possible reasons are: + + * IPConnection.\ **DISCONNECT_REASON**\ _REQUEST = 0: Disconnect was requested by user. + * IPConnection.\ **DISCONNECT_REASON**\ _ERROR = 1: Disconnect because of an + unresolvable error. + * IPConnection.\ **DISCONNECT_REASON**\ _SHUTDOWN = 2: Disconnect initiated by Brick + Daemon or WIFI/Ethernet Extension. diff --git a/generate_tables.py b/generate_tables.py index 1564f246..c6c8dd41 100644 --- a/generate_tables.py +++ b/generate_tables.py @@ -188,6 +188,20 @@ def debug(*args, **kwargs): tutorial={'en': 'FIXME', 'de': 'FIXME'}, is_hardware_supported=lambda device_info: True), + BindingsInfo(display_name={'en': 'MicroPython', 'de': 'MicroPython'}, + url_part='micropython', + software_doc_suffix='MicroPython', + is_programming_language=True, + is_released=True, + has_authentication_example=True, + has_download=True, + misc_docs=[ + MiscDoc('IPConnection_{suffix}', 'ip_connection_{suffix}', {'en': 'IP Connection', 'de': 'IP Connection'}, True, True), + MiscDoc('API_Bindings_{suffix}', 'api_bindings_{suffix}', {'en': 'Usage', 'de': 'Benutzung'}, False, False) + ], + tutorial={'en': 'https://docs.micropython.org/en/latest/', + 'de': 'https://docs.micropython.org/en/latest/'}, + is_hardware_supported=lambda device_info: True), BindingsInfo(display_name={'en': 'MQTT', 'de': 'MQTT'}, url_part='mqtt', software_doc_suffix='MQTT', @@ -678,6 +692,9 @@ def make_download_bindings_table(): if not bindings_info.is_released or not bindings_info.has_download: continue + if bindings_info.url_part not in bindings_versions: + continue + rows.append(row.format(bindings_info.display_name[lang], bindings_info.url_part, archive[lang],