Standalone Python with UDP -------------------------- In addition to plugins, X-Plane supports external communications via UDP. This allows any number of separate processes (potentially on separate computers) to get and set data remotely and execute some commands. This is *completely* unrelated to XPPython3, but as you're programming in python I figured I might as well introduce you to this method of interaction as well. Intro to UDP ============ UDP simply sends one packet of data -- like throwing a rock -- it might make it to the receiver, it might not (as opposed to TCP, which is more like a pipe.) Packets are not guaranteed to arrive in order, nor are they even guaranteed to arrive. But they're quick, with low overhead. The size of the packet is limited by the protocol -- about 65k bytes. The content of the packet can be anything, but the sender and receiver have to agree. UDP and Python ============== UDP is pretty simple: you'll create a UDP (i.e., DATAGRAM) socket, and then use that socket to send information to a remote port:: sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) msg = makeMsg() sock.send_to(msg, (X_PLANE_IP, UDP_PORT)) Receiving information is similarly simple:: data, addr = sock.recvfrom(2048) handleData(data) The more difficult part is working this ``sent_to()`` and ``recvfrom()`` into a working program so you don't get confused while interleaving sends and receives. (You can put the receiver in a python thread. See example in :doc:`rref`.) UDP and X-Plane =============== X-Plane understands a particular format, described in **/Instructions/X-Plane SPECS from Austin/Exchanging Data with X-Plane.rtfd**. However, *that document is not accurate*. I suppose because it's just not been updated in a while, but it no longer matches with X-Plane 11.55+ does. X-Plane's interface is (usually) described using C language structures and expects a particular size and encoding of data. You'll have to format ('pack') the python data into the proper structure before sending it to X-Plane, and unpack any received data in a similar manner. The easiest way to pack and unpack is to use the python ``struct`` module. For example:: cmd = b'RREF' freq = 1 index = 0 msg = struct.pack("<4sxii400s", cmd, freq, index, b'sim/aircraft/engines/acf_num_engines') The initial string ``<4sxii400s`` describes how to pack the remaining arguments: +----------+-------------------------------------------------------------+ | ``>`` | little endian (i.e., least significant byte in the lowest | | | memory position) | +----------+-------------------------------------------------------------+ | ``4s`` | a 4-byte object, commonly string, e.g., 'RREF', expressed | | | as a bytes: b'RREF'. | +----------+-------------------------------------------------------------+ | ``x`` | a null byte, or 0x00. X-Plane is looking for a | | | null-terminated 4-character string & this encodes the | | | null value. (does not consume an argument). Yes, you could | | | use ``5s``, without the ``x`` for the same effect, but this | | | method emphasizes the usable command is a 4-character value | +----------+-------------------------------------------------------------+ | ``i`` | a 4-byte integer | +----------+-------------------------------------------------------------+ | ``i`` | another 4-byte integer (you could also combine these as | | | ``2i``, which consumes two integer arguments) | +----------+-------------------------------------------------------------+ | ``400s`` | a 400-byte object. Note that Python pads and zero-fills to | | | fit 400 bytes. | +----------+-------------------------------------------------------------+ Basically what you'll do is "find" X-Plane -- the host IP address and port (See *Connecting with X-Plane*, next), and then you'll send one or more command packets to it & wait for data packets. Connecting with X-Plane +++++++++++++++++++++++ X-Plane automatically broadcasts a "beacon" on the network, allowing other programs to find it. Ideally, you should listen for this beacon to tell your standalone program a) X-Plane is running; and, b) where it is located. Multicast beacons are pretty standard, the only "custom" aspects are which port the multicast is on (49707 for X-Plane) and the data contents of the beacon itself. See example code in `find_xp() `_ which will wait for X-Plane to startup and will then return information about the version of X-Plane found. You can use it like:: beacon = find_xp() port = beacon['port'] ip = beacon['ip'] By default, X-Plane is set for UDP networking. You do not have to enable anything under X-Plane Settings->Network. This includes External Visuals, External Apps, or UDP Ports. Note your socket related to the beacon is different from the socket you use to send and receive information from X-Plane. One you've *found* X-Plane, you can close the beacon socket. X-Plane UDP Summary =================== *SEND* +-----------------------------+--------------------------------------------+ | Cmd - Description | Structure | +=============================+============================================+ | :doc:`acfn` | ACFN | +-----------------------------+--------------------------------------------+ | :doc:`acpr` | ACPR | +-----------------------------+--------------------------------------------+ | :doc:`alrt` | ALRT | +-----------------------------+--------------------------------------------+ | :doc:`cmnd` | CMND | +-----------------------------+--------------------------------------------+ | :doc:`dref` | DREF | +-----------------------------+--------------------------------------------+ | :doc:`dsel` | DSEL ... | | | | | | USEL ... | +-----------------------------+--------------------------------------------+ | :doc:`fail` | FAIL | | | | | | RECO | +-----------------------------+--------------------------------------------+ | :doc:`flir` | FLIR | | | | | | *(Deprecated since 11.41)* | +-----------------------------+--------------------------------------------+ | :doc:`ise4` | ISE4 | | | | | | ISE6 | +-----------------------------+--------------------------------------------+ | :doc:`lsnd` | LSND | | | | | | SSND | +-----------------------------+--------------------------------------------+ | :doc:`nfal` | NFAL | | | | | | NREC | +-----------------------------+--------------------------------------------+ | :doc:`objn` | OBJN | | | | | | OBJL | | | | +-----------------------------+--------------------------------------------+ | :doc:`prel` | PREL | | | | | | | +-----------------------------+--------------------------------------------+ | :doc:`radr` | RADR | +-----------------------------+--------------------------------------------+ | :doc:`rese` | RESE | +-----------------------------+--------------------------------------------+ | :doc:`rpos` | RPOS | +-----------------------------+--------------------------------------------+ | :doc:`rref` | RREF | +-----------------------------+--------------------------------------------+ | :doc:`simo` | SIMO | +-----------------------------+--------------------------------------------+ | :doc:`shut` | SHUT | | | | | | QUIT | +-----------------------------+--------------------------------------------+ | :doc:`soun` | SOUN | +-----------------------------+--------------------------------------------+ | :doc:`vehx` | VEHX | | | | +-----------------------------+--------------------------------------------+ *RECEIVE* +-------+----------------------------+-----------------------------------------+ | Cmd | In response to | Structure | +=======+============================+=========================================+ | DATA* | :doc:`dsel` | DATA*... | +-------+----------------------------+-----------------------------------------+ | FLIR | :doc:`flir` | *(Deprecated since 11.41)* | +-------+----------------------------+-----------------------------------------+ | RADR5 | :doc:`radr` | RADR5 | +-------+----------------------------+-----------------------------------------+ | RPOS4 | :doc:`rpos` | RPOS4 | | | |

| +-------+----------------------------+-----------------------------------------+ | RREF | :doc:`rref` | RREF ... | +-------+----------------------------+-----------------------------------------+ .. toctree:: :maxdepth: 1 :caption: Details acfn acpr alrt cmnd dref dsel fail flir ise4 lsnd nfal objn prel radr rese rpos rref simo shut soun vehx