Appendix External Access
===========================

The WebSQ driver can be accessed and controlled over its Ethernet connection.
There are two open ports, by default 12345 and 12000. The first one only emits the measured counts.
The second one allows to control the WebSQ driver basically in the same way as over the web interface.
In the following, the two access ways are explained in detail.

Receiving Counts
-------------------------
The counts per measurement time are emitted by default on port 12345 with the TCP/IP protocol. Note, that this port only sends data any data which is written to it is discarded.
The port number can be changed under the configuration tab in the web interface. The format of the emitted data is comma separated starting with a UNIX time-stamp in seconds followed by the counts of the detectors and ended with the newline character '\\n':

.. code-block:: bash

  unix time-stamp,counts detector 1,counts detector 2,...\n

For example, on a system with four detectors the data looks like:

.. code-block:: bash

  1462820844.64,200.0,238.0,234.0,212.0\n

The driver emits the counts to all connected clients starting automatically once the connection is established.
On a Unix system the connection to the driver can be tested by the following command:

.. code-block:: bash

	netcat ip_address 12345

Here, ip_address should be replaced with the IP address of the driver.

External Control
-------------------------

The default way of controlling the driver is through its built in web browser interface. To access, simply open a
web browser of your choice and enter the IP address 192.168.1.1 (standard address) of the driver in the address field.
However, your application might demand finer or automated control over the detectors. In that case, you can directly access it through precisely the same JSON protocol over which also the web browser is communicating with the driver.

In the following, this protocol is outlined in detail but it might be beneficial to also check example projects downloadable on the help page of the WebSQ driver.

The WebSQ sever listens by default for incoming connections on port 12000. If this number is inconvenient it can be changed in the web interface under config in the network section.

On a Unix system the communication can be tested by the following command:

.. code-block:: bash

	netcat ip_address 12000

Each full reply is terminated with one or several '\\x17' end of transmission block characters. This simplifies merging TCP IP messages which have been split during network passage.

Command Structure
^^^^^^^^^^^^^^^^^^^^^

Each value which is accessible in the WebSQ interface can be transparently accessed externally.

There are three types of commands:

	* Requests
	* Commands
	* And access to labels, for example the integration time

In the following each of these three types is outlined.

.. rubric:: Please be aware that the JSON protocol requires always double quotes " single quotes ' will result in errors.

Requests
^^^^^^^^^^^^^^^^^^^^^

Possible requests are:

	* *GetSystemTime*
	* *Style info*
	* *labelProps*
	* *BroadcastCounters*
	* *BroadcastBiasCurrents*
	* *BroadcastBiasVoltages*
	* *TemperatureHistory*
	* *IVHistory*
	* *SoftwareVersion*
	* *pong*
	* or a label name like "NumberOfDetectors"

A request looks like:

.. code-block:: json

  {"request":"request_name"}

where the *request_name* is one of the above possible keywords. For example:

.. code-block:: json

  {"request":"GetSystemTime"}

will return the system time.

A request will always results in a *value*-*label* JSON structure:

.. code-block:: json

  {"value": "requested_value", "label": "requested_identifier"}


Please note that the commands:

	* *BroadcastCounters*
	* *BroadcastBiasCurrents*
	* *BroadcastBiasVoltages*


only broadcast to connected websockets (Browsers), e.g. they have no effect for the external access through port 12000.

*GetSystemTime*
""""""""""""""""""""""""""""""
Returns the time in the following JSON form:

.. code-block:: json

  {"value": "2016-08-07 16:53:12", "label": "SystemTime"}

*Style info*
"""""""""""""""""""""""""""
Returns each label-value pair of *labelProps* separately.
The *labelProps*

.. code-block:: json

  {"value": [12.0, 8.0, 3.0, 8.0], "label": "BiasCurrent"}
  {"value": 4, "label": "NumberOfDetectors"}


*labelProps*
"""""""""""""""""""""""""""""""""""""
Returns the same elements like in *Style info* but with additional information like type, unit, and bounds if available:

.. code-block:: json

  {"value": {"value": [12.0, 8.0, 3.0, 8.0], "type": ["float", "int"],
    "bounds": [-50.0, 50.0], "unit": "muA"}, "label": "BiasCurrent"}
  {"value": {"type": ["int"], "bounds": [0, 8], "value": 4}, "label": "NumberOfDetectors"}


*TemperatureHistory*
"""""""""""""""""""""""""""""""""""""""
Returns the time stamped temperature history in Kelvin:

.. code-block:: json

  {"value": [{"x": "07-Aug-16 16:48:27.15", "T": 2.5},
  {"x": "07-Aug-16 16:48:37.24", "T": 2.55}],
  "label": "temperature_long_memory"}

*IVHistory*
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
Returns the last detector characterization measurement.
Two JSON objects will be returned. The first for the bias current versus detector voltage measurement:

.. code-block:: json

  {"value": {"start": true, "value": [{
  "v1": 2.292586295970549,
  "v2": 6.6360137175996243,
  "v3": 1.230466767850853,
  "v4": 5.3691603767536229,
  "biasCurrent": 0.0,
  "x": "07-Aug-16 17:13:23.279",
  "label": "biasVoltage"}],
  "label": "IVGraph"},
  "label": "iv_scan_history"}

and the second one the bias current versus counts characterization:

.. code-block:: json

  {"value": {"start": true, "value": [{
  "biasCurrent": 0.0,
  "y1": 1996638.0,
  "x": "07-Aug-16 17:13:23.289",
  "y3": 3590000.0,
  "y2": 2690000.0,
  "y4": 39290000.0}],
  "label": "ICGraph"},
  "label": "ic_scan_history"}

*SoftwareVersion*
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

Returns the software version:

.. code-block:: json

  {"value": "4.2.4", "label": "SoftwareVersion"}

*pong*
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

This is used to ping the driver and check if the connection to the driver is still active. Each pong request is answered by a ping.

.. code-block:: json

  {"value": "pong", "label": "ping"}

*A label property*
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

All the data presented on the web interface like integration time, bias currents, etc. are called label properties.
Each label can be acquired individually. For example, the numbers of detectors available in the system can be acquired by:

.. code-block:: json

    {"request":"NumberOfDetectors"}


The answer will be:

.. code-block:: json

    {"value":"4", "label": "NumberOfDetectors"}

To query all the available label properties the request "labelProps" can be used, see above.

Commands
^^^^^^^^^^^^^^^^^^^^^

Possible commands are:

  * *SetMeasurementPeriod*
  * *SetBiasCurrent*
  * *SetAllBiasCurrents*
  * *SetTriggerLevel*
  * *SetAllTriggerLevels*
  * *SetDiodeCurrent*
  * *SetTime*
  * *DetectorEnable*
  * *RecordCounts*
  * *RecordCountsReset*
  * *IVScanEnable*
  * *SetNetworking*
  * *AutoCaliBiasCurrents*
  * *SetLEDIntensity*
  * *Shutdown*

All commands are illustrated in the following for a system with 4 detectors.
In case of a different detector number change the length of the arrays accordingly.

.. rubric:: Please note that commands do not alter the labels on the web interface. The labels need to be updated with a separate command. Therefore, you'll find that the commands underneath will contain the label keyword. In this way, only one JSON expression is sent out where the value keyword is used for both the commands and the labels.

Set Measurement Period
"""""""""""""""""""""""""""""""""

JSON command:

.. code-block:: json

  {"command": "SetMeasurementPeriod", "value": 123, "label": "InptMeasurementPeriod"}

Sets the measurement period to 123 ms.

Set Bias Current
"""""""""""""""""""""""""""""""""
Sets only one bias current at a time. Which one is indicated by an index which runs from 0...n-1, where n is the number of detectors.

JSON command:

.. code-block:: json

  {"command": "SetBiasCurrent", "label": "BiasCurrent", "value": [12, 11, 13, 14], "index": 0}

Sets the bias current of detector 1 (index 0) to 12 µA.

Note: Even though all values seem updated in the web browser only the *one* specified by the index will be physically set. The update is performed upon the next counts measurement.

Set All Bias Currents
"""""""""""""""""""""""""""""""""
Sets all bias currents at once.

JSON command:

.. code-block:: json

  {"command": "SetAllBiasCurrents", "label": "BiasCurrent", "value": [12, 11, 13, 14]}

Sets the bias current of detector 1 to 12 µA, detector 2 to 11 µA and so forth.
If the array does not have the same length as the number of detectors in the system nothing will be updated.

Note: The bias currents are not updated immediately. They are automatically updated after the next counts measurement.

Set Trigger Level
"""""""""""""""""""""""""""""""""
Sets only one trigger level at a time. Which one is indicated by an index which runs from 0...n-1, where n is the number of detectors.

JSON command:

.. code-block:: json

  {"command":"SetTriggerLevel","label":"TriggerLevel","value":[100, 110, 120, 130],"index":0}

Sets the trigger level of detector 1 (index 0) to 100 mV.

Note: Even though all values seem updated in the web browser they will be only updated when the *one* specified by the index is physically set. The update takes place on the following counts measurement.

Set All Trigger Levels
"""""""""""""""""""""""""""""""""
Sets all trigger levels at once.

JSON command:

.. code-block:: json

  {"command":"SetAllTriggerLevels","label":"TriggerLevel","value":[100, 110, 120, 130]}

Sets the trigger level of detector 1 to 100 mV, of detector 2 to 110 mV and so forth.
If the array does not have the same length as the number of detectors in the system nothing will be updated.

Note: The trigger levels are not updated immediately. They are automatically updated after the next counts measurement.

Set Diode Current
"""""""""""""""""""""""""""""""""
Sets the bias current of the temperature diode, the value can be positive or negative.

JSON command:

.. code-block:: json

  {"command": "SetDiodeCurrent", "value": 10, "label": "TempDiodeBiasCurrent"}

Sets the temperature measurement diode's bias current to 10 µA.

Note: The diode's bias current is not updated immediately. It is automatically updated after the next counts measurement.


Set Time
"""""""""""""""""""""""""""""""""
First the time zone label needs to be set:

.. code-block:: json

  {"label": "TimeZone", "value": "strTZ"}

where *strTZ* is a string representing your current timezone.
This ensures that in the web interface the right timezone is displayed.
For all possible timezones see :ref:`appendix-timezones`.

You can set the time accordingly:

.. code-block:: json

  {"command": "SetTime", "value": {"time": "time", "timezone": "strTZ"}}

where the variable *time* needs to be in the following format "YYYY-MM-DDTHH:m:ss" and *strTZ* your timezone (see :ref:`appendix-timezones`).

Example:

.. code-block:: json

    {"command": "SetTime", "value": {"time": "2016-08-14T09:47:55", "timezone": "Europe/Amsterdam"}}

Detector Enable
"""""""""""""""""""""""""""""""""
To enable/disable the bias current through the detectors send:

.. code-block:: json

    {"command": "DetectorEnable", "label": "DetectorEnable", "value": true}

or:

.. code-block:: json

    {"command": "DetectorEnable", "label": "DetectorEnable", "value": false}

Record Counts
"""""""""""""""""""""""""""""""""
To re-start a count record:

.. code-block:: json

    {"command": "RecordCounts", "label": "DetectorRecording", "value": true}

and to pause:

.. code-block:: json

    {"command": "RecordCounts", "label": "DetectorRecording", "value": false}


Record Counts Reset
"""""""""""""""""""""""""""""""""
Resets the acquired counts:

.. code-block:: json

    {"command": "RecordCountsReset"}


IV Scan Enable
"""""""""""""""""""""""""""""""""
To enable/disable the IV scan do:

.. code-block:: json

    {"command": "IVScanEnable", "label": "IVScanEnable", "value": true}

or:

.. code-block:: json

    {"command": "IVScanEnable", "label": "IVScanEnable", "value": false}

To set the start, stop, and increment current use:

.. code-block:: json

    {"label": "IVScanStart", "value": 0}

Starts IV scan at 0 μA.

.. code-block:: json

    {"label": "IVScanEnd", "value": 30}

Stops IV scan at 30 μA.

.. code-block:: json

    {"label": "IVScanIncrement", "value": 0.1}

Increment IV scan with 0.1 μA.

Automatic Bias Current Calibration
"""""""""""""""""""""""""""""""""""""""""""
The automatic bias current calibration routine finds the bias current for a given amount of dark counts.
Therefore, it is important that the detectors are shielded completely from any light prior to the search and that the dark-counts are set.
To set the dark-counts send the following command:

.. code-block:: json

    {"command": "DarkCountsAutoIV", "label": "DarkCountsAutoIV", "value": [100, 100, 100, 100]}

In this example, all the dark-counts are set to 100 Hz.

Then start the automatic bias current search:

.. code-block:: json

     {"command": "AutoCaliBiasCurrents", "value": true}

To check if the system has completed the search the "StartAutoIV" label can be inquired.
The reply will be true if the search is active and false otherwise:

.. code-block:: json

    {"request": "StartAutoIV"}

Set Led Intensity
"""""""""""""""""""""""""""""""""
Set the LED intensity at the front of the driver to maximum brightness send:

.. code-block:: json

    {"command": "SetLEDIntensity", "label": "SetLEDIntensity", "value": 32000}

To switch it off send:

.. code-block:: json

    {"command": "SetLEDIntensity", "label": "SetLEDIntensity", "value": 0}

The intensity value scales between 0 and 32000.
Note, this feature is only available on newer devices.

Shutdown
"""""""""""""""""""""""""""""""""
The driver can be shutdown by sending:

.. code-block:: json

    {"command": "Shutdown"}

Note, this feature is only available on newer devices.


Labels
^^^^^^^^^^^^^^^^^^^^^
To query all available properties, their bounds, units, and types send:

.. code-block:: json

  {"request": "labelProps"}

You can also access a specific value within *labelProps*, for example the bias voltage measured over the detectors:

.. code-block:: json

  {"request":"BiasVoltage"}

Each label can also individually be set by *label* *value* pairs, for example:

.. code-block:: json

  {"label": "InptMeasurementPeriod", "value": 123}

Setting a value will transmit the changed value to all connected clients (all browsers and all TCP/IP clients). In this way, a change is always transparent to all clients.
However, setting a value never initiates an actual hardware change. This always needs to be done with a command.

Please note that *commands* can be sent together with a label value pair:

.. code-block:: json

  {"command": "SetMeasurementPeriod", "value": 123, "label": "InptMeasurementPeriod"}
