Communication Module API ======================== The AirPhoton communication module is a remote access point for AirPhoton instrumentation. It connects periodically to the ``/remote`` endpoint on the production API server. .. WARNING:: As of October 2019, one communication module links up with one instrument. Currently, there is developments planned for a setup with one communication module for multiple instruments. Communication modules have two interfaces. A local USB terminal for hard configuration, and the remote interface for remote control. The following documentations will focus on remote control of the communication module as this is the interface used via the API server. Remote Interface Overview ------------------------- When working with the communication module through the API server, the following commands are exposed for remote operation: - `echo`_ - `sendcommand`_ - `sendmlcommand`_ - `setinterval`_ - `downloadfile`_ - `transmitfile`_ - `execscript`_ These commands will be explained in enough detail to get started in the sections below. For more advance examples and usage cases, see the instrument specific documentation. Those sections will cover not just the instrument commands, but also some example playbook scenarios. .. NOTE:: There are more communication module commands not available over the remote interface. In addition to the commands covered here, the local USB terminal provides the following functionality: - load - save - sethost - setapipass - setnetpass - setssid - setuid To learn more about these commands specific to site setup and the local USB terminal, in general, please see the user manual for the *AirPhoton Commmunication Module*. .. _`echo`: Remote Command: ``echo`` ------------------------ If you worked through the :ref:`Example: Sending a Basic Command` in :ref:`API Server`, you already sent an *echo* command via a communication module to an instrument. We can use ``echo`` to check connectivity with the communication module in the same way. .. NOTE:: Under normal setups, a communication module will not connect to the API server unless there are instruments attached and powered. If you can *echo* an instrument remotely, you know the communication module is also working. Therefore, sending *echo* to the communication module is likely not needed, but it can be handy diagnostic tool. We want to create a *control* action with the command ``echo online``. If you examine the JSON closely, you will notice that an instrument reference is required since the communication module will not connect to the API server alone. .. code-block:: bash :linenos: # NOTE: # This command has the [INSTRUMENT-URL] and [USER-URL] pre-populated. # Make sure you change these. curl --user [USER] \ --request POST https://sandbox.airphoton.io/v1/controls/ \ -H "Content-Type: application/json" \ -d '{"instrument":"https://sandbox.airphoton.io/v1/instruments/51e38515-3fb6-4f00-838b-7fea3cadc42f/","created_by":"https://sandbox.airphoton.io/v1/users/3/","name":"api demo","command":"echo online"}' After sending the command, monitor the *controls* UUID provided. Once the ``status`` field is *completed*, check the *controlresponse* associated with that UUID to make sure the communication module responded as expected. Your output will vary slightly, but it should look similar to the following: .. code-block:: json :linenos: [{ "url": "https://sandbox.airphoton.io/v1/controlresponses/f77aa3e5-5a47-4466-a15d-a4651ca8b827/", "control": "https://sandbox.airphoton.io/v1/controls/7875b454-d18f-4268-9930-1ec012081cc8/", "error": "", "response": { "text":"echo online\r\n" } }] Compared to the example in :ref:`controlresponses-functionality` which was sent to the instrument, the *text* output is only ``echo online`` when the communication module alone responds. .. _`setinterval`: Remote Command: ``setinterval`` ------------------------------- The communication module checks in with the API server at set time intervals whenever an instrument is attached and powered. When used remotely, the ``setinterval`` command can be used to *report* and to temporarily *change* this check-in interval. .. WARNING:: The check-in interval affects bandwidth. When operating on a metered Internet connection this can drive up costs or lock out the cellular module account. The *setinterval* time should be as slow or as large as reasonably usable. This command exists to temporary change the *setinterval* when remote user interaction is needed, and slow responses are not tolerated. If you reduced the *setinterval*, remember to return it to the original setting. AirPhoton recommends **[TBD]** interval as a default. Reporting the ``setinterval`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The *setinterval* period can be requested remotely by sending the command without a value. Notice that in the following example, the command sent is only ``setinterval``. .. code-block:: bash :linenos: # NOTE: # This command has the [INSTRUMENT-URL] and [USER-URL] pre-populated. # Make sure you change these. curl --user [USER] \ --request POST https://sandbox.airphoton.io/v1/controls/ \ -H "Content-Type: application/json" \ -d '{"instrument":"https://sandbox.airphoton.io/v1/instruments/51e38515-3fb6-4f00-838b-7fea3cadc42f/","created_by":"https://sandbox.airphoton.io/v1/users/3/","name":"api demo","command":"setinterval"}' After sending the command, monitor the *controls* UUID provided. Once the ``status`` field is *completed*, check the *controlresponse* associated with that UUID to see the current *setinterval* period. Your output will vary slightly, but it should look similar to the following: .. code-block:: json :linenos: [{ "url": "https://sandbox.airphoton.io/v1/controlresponses/42f034af-f6c4-4e28-be31-9e5ac7d7a7ff/", "control":"https://sandbox.airphoton.io/v1/controls/5bbfb7f6-0e92-4c36-8cab-4f6d26fec162/", "error":"", "response": { "text":"Interval is:300\r\n" } }] Changing the ``setinterval`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. WARNING:: When used remotely, the ``setinterval`` command will not persisted in storage. When the system is rebooted such as during a power loss event, it will reboot using the stored setting. To persist *setinterval* changes, use the command while connected to the local USB terminal. For more information, please see the user manual for the *AirPhoton Communication Module*. The *setinterval* period can be changed remotely by sending the command with the new period in seconds. Notice that in the following example, the command sent is ``setinterval 60``. .. code-block:: bash :linenos: # NOTE: # This command has the [INSTRUMENT-URL] and [USER-URL] pre-populated. # Make sure you change these. curl --user [USER] \ --request POST https://sandbox.airphoton.io/v1/controls/ \ -H "Content-Type: application/json" \ -d '{"instrument":"https://sandbox.airphoton.io/v1/instruments/51e38515-3fb6-4f00-838b-7fea3cadc42f/","created_by":"https://sandbox.airphoton.io/v1/users/3/","name":"api demo","command":"setinterval 60"}' After sending the command, the communication module should start checking in with the API server at the new rate. .. _`sendcommand`: Remote Command: ``sendcommand`` ------------------------------- This command asks the communication module to send a command to the instrument and report back the results. The example in :ref:`Example: Sending a Basic Command` from :ref:`API Server` covers the same principle of setting up a JSON object to send. We will create another *control* action with the command ``sendcommand``. The communication module will take the parameters given after ``sendcommand`` and send that to the instrument, returning the result. We will use the same example command given: ``sendcommand echo Science!`` .. code-block:: bash :linenos: # NOTE: # This command has the [INSTRUMENT-URL] and [USER-URL] pre-populated. # Make sure you change these. curl --user [USER] \ --request POST https://sandbox.airphoton.io/v1/controls/ \ -H "Content-Type: application/json" \ -d '{"instrument":"https://sandbox.airphoton.io/v1/instruments/51e38515-3fb6-4f00-838b-7fea3cadc42f/","created_by":"https://sandbox.airphoton.io/v1/users/3/","name":"api demo","command":"sendcommand echo Science!"}' In this case, the instrument should respond back similarly to the following: .. code-block:: json :linenos: [{ "url": "https://sandbox.airphoton.io/v1/controlresponses/8d0c99a1-0dbb-48d0-863c-b9e48d326183/", "control": "https://sandbox.airphoton.io/v1/controls/7df9437a-d7cb-468f-a957-79d114dfd9ba/", "error": "", "response": { "text": "Instrument:echo Science!\r\n" } }] .. _`sendmlcommand`: Remote Command: ``sendmlcommand`` --------------------------------- This command is very similar to `sendcommand`_, but is used for multiline responses from the instrument. In this example, we will ask the communication module to get the status of the instrument using ``sendmlcommand ENDSTATUS status``. .. code-block:: bash :linenos: # NOTE: # This command has the [INSTRUMENT-URL] and [USER-URL] pre-populated. # Make sure you change these. curl --user [USER] \ --request POST https://sandbox.airphoton.io/v1/controls/ \ -H "Content-Type: application/json" \ -d '{"instrument":"https://sandbox.airphoton.io/v1/instruments/51e38515-3fb6-4f00-838b-7fea3cadc42f/","created_by":"https://sandbox.airphoton.io/v1/users/3/","name":"api demo","command":"sendmlcommand ENDSTATUS status"}' You should expect the response to be similar to `sendcommand`_, but with a much larger ``text`` field in ``response``: .. code-block:: json :linenos: [{ "id": "66be44f8-23d2-4953-a0f2-77658402dccf", "control": "https://sandbox.airphoton.io/v1/controls/937e2977-e049-4383-b49f-0f29072f40d9/", "error": "", "response": { "text": "Instrument:serialnumber=SS5013\r\ndate=2020-02-06\r\ntime=13:00:18\r\nmemoryfree=76572\r\nmode=script\r\nrtcbattery=ok\r\ncartridge=275\r\ncartridgecount=255\r\nscriptcartridge=-1\r\nstorage=backup,cartridge\r\nscriptname=script.aps\r\nscriptstate=not_running\r\nscripterror=none\r\nscriptline=none\r\nactivefilter=none\r\ndataname=\r\npump_a=off\r\npump_b=off\r\nflow_a=0.01\r\nflow_b=0.03\r\nvacuum_a=0.04\r\nvacuum_b=0.51\r\ntemperature=28.96\r\n\r\n" } }] The response is lengthly and contains unescaped line-endings, so here is the response formated as an unescaped .. code-block:: html :linenos: Instrument: serialnumber=SS5013 date=2020-02-06 time=13:00:18 memoryfree=76572 mode=script rtcbattery=ok cartridge=275 cartridgecount=255 scriptcartridge=-1 storage=backup,cartridge scriptname=script.aps scriptstate=not_running scripterror=none scriptline=none activefilter=none dataname= pump_a=off pump_b=off flow_a=0.01 flow_b=0.03 vacuum_a=0.04 vacuum_b=0.51 temperature=28.96 .. _`downloadfile`: Remote Command: ``downloadfile`` -------------------------------- Remote files are not downloaded directly to an instrument. They are first buffered by the communication module using the ``downloadfile`` control. After the download is complete, see the ``transmitfile`` control in the next section below. The following command schedule a control action with the central server. The specific command to be sent to the communication module is ``downloadfile [URL] /[NAME]``. The file URL can be any HTTPS source backed by a `Lets Encrypt Certificate`_. Here are some example scripts provided by AirPhoton for testing: - :download:`simple-eight <./media/simple-eight.aps>` - :download:`simple-repeat-eight <./media/simple-repeat-eight.aps>` - :download:`cycle-a7b1 <./media/cycle-a7b1.aps>` .. code-block:: bash :linenos: curl --user [USER] \ --request POST https://sandbox.airphoton.io/v1/controls/ \ -H "Content-Type: application/json" \ -d '{"instrument":"https://sandbox.airphoton.io/v1/instruments/51e38515-3fb6-4f00-838b-7fea3cadc42f/","created_by":"https://sandbox.airphoton.io/v1/users/3/","name":"script download","command":"downloadfile https://www.airphoton.io/_downloads/d9f683385e77db0c392924ed251a01e2/simple-eight.aps /script.aps"}' In this case, the instrument should respond back similarly to the following: .. code-block:: json :linenos: [{ "url": "https://sandbox.airphoton.io/v1/controlresponses/33390f84-5dfd-4482-acd7-550e642065f1/", "control": "https://sandbox.airphoton.io/v1/controls/ed853a9d-5e7e-4563-8116-ce46d2f8f19e/", "error": "", "response": { "text":"downloading file succeeded\r\n" } }] .. .. _`file`: Remote Command: ``file`` ------------------------ .. ERROR: As of 2019 October 08, this function appears broken. .. _`transmitfile`: Remote Command: ``transmitfile`` -------------------------------- ``transmitfile`` takes two positional arguments: ``transmitfile [source] [target]`` This command will copy the contents of the source file downloaded from `downloadfile`_ into a new file located at ``[target]`` on the instrument. The target location must be rooted at either ``B`` (BACKUP) or ``C`` (CARTRIDGE). Omitting this indicator will default to B. For example, after creating the example control action above for ``downloadfile``, transmitting that file using ``transmitfile /script.aps script1.aps``: .. code-block:: bash :linenos: curl --user [USER] \ --request POST https://sandbox.airphoton.io/v1/controls/ \ -H "Content-Type: application/json" \ -d '{"instrument":"https://sandbox.airphoton.io/v1/instruments/51e38515-3fb6-4f00-838b-7fea3cadc42f/","created_by":"https://sandbox.airphoton.io/v1/users/3/","name":"script transmit","command":"transmitfile /script.aps script.aps"}' .. _`execscript`: Remote Command: ``execscript`` ------------------------------ ``execscript`` takes up to two positional arguments: ``execscript (strict) [source]`` Execute a script with optional strict mode. .. _lets encrypt certificate: https://letsencrypt.org/