IO Module

IO Module RESTful API documentation

These examples are meant to be run on the device!
If you want to run them from a remote computer, you need to change “localhost” to the IP/hostname.
You will also need to generate an access token and use the “auth basic” method.
You may also want to use the secure protocol https://.

Introduction

The IO Module provides six IOs configureable via RESTful API.
From the implementation perspective the following order should be used:

  1. Implement version check and device selection
  2. Implement GET /input/values for testing
  3. Implement notification error handling and polling
  4. Implement power management
  5. Implement outputs
  6. Test if power management, outputs and notifications (e.g: shortcut a pin) is working
  7. Implement all remaining endpoints

Base URL:

<HOSTNAME>/api/io/<version>/

Version check and device selection

See Version check and device selection

Error response

See Error Response

Caching

By default, all values in the /input directory are cached for 1 second to improve performance during parallel access. To override this cache mechanism, simply add the header cache-control: no-cache to your request.

Notification

GET /notification

Returns pending notifications.
Notifications are messages initiated and send by the module on configured events or (external) errors.
They are handled fast and are usually available >20ms after the event occurred (from the RESTful API point of view).

Request:

Method: GET
URL: <HOSTNAME>/api/io/<version>/<slot>/notification/<pin>

Parameters:

No body parameters

Response:

{
  "under_voltage_alert": <bool>,
  "high_voltage_alert": <bool>,
  "high_current_alert": <bool>,
  "custom_voltage_alert": <bool>
}

Example

Request:

curl http://localhost/api/io/1.0/3/notification/1

Response:

{
  "under_voltage_alert": false,
  "high_voltage_alert": false,
  "high_current_alert": false,
  "custom_voltage_alert": true
}

Power Management

POST /power-management

Too handle different power supply capacities the NOREYA NEXUS platform uses a passive power management concept.
This means that each module must specify its maximum power consumption and the total sum of the maximum power must not exceed the power supply capacity.
The power management daemon can be configured to handle this limit “strict” (do not allow overprovisioning) or “weak” (allow overprovisioning and warn).

The IO Module supports dynamic power configuration which means the application (and therefore the user) must specify how much maximum power per pin is used.
Before the /output/ commands can be used a valid power management configuration must be set.

The position in the array is analog to the pin number.

Please check the current limit for the 5V/12V rail from the datasheet/webpage!

Request:

Method: POST
URL: <HOSTNAME>/api/io/<version>/<slot>/power-management

Parameters:

{
    "config": [
        {
            "rail": "5_volt|12_volt",
            "current_milliampere": <int>
        },
        {
            "rail": "5_volt|12_volt",
            "current_milliampere": <int>
        },
        {
            "rail": "5_volt|12_volt",
            "current_milliampere": <int>
        },
        {
            "rail": "5_volt|12_volt",
            "current_milliampere": <int>
        },
        {
            "rail": "5_volt|12_volt",
            "current_milliampere": <int>
        },
        {
            "rail": "5_volt|12_volt",
            "current_milliampere": <int>
        }
    ]
}

Response:

{
  "status": "success|denied",
  "too_much_power": {
    "rail_3v3_milliwatt": <int>,
    "rail_5v0_milliwatt": <int>,
    "rail_12v_milliwatt": <int>
  }
}

Example

Request:

curl http://localhost/api/io/1.0/3/power-management --header "Content-Type: application/json" --request POST --data '{"config": [{"rail": "5_volt", "current_milliampere": 1}, {"rail": "5_volt", "current_milliampere": 1}, {"rail": "5_volt", "current_milliampere": 1}, {"rail": "5_volt", "current_milliampere": 1}, {"rail": "5_volt", "current_milliampere": 1}, {"rail": "5_volt", "current_milliampere": 1}]}'

Response:

{
  "status": "success",
  "too_much_power": {
    "rail_3v3_milliwatt": 0,
    "rail_5v0_milliwatt": 0,
    "rail_12v_milliwatt": 0
  }
}

Input

GET /input/values

Returns the value and type for each pin.

If the pin is configured as analog input, output or pwm the type is “voltage_millivolt” and the value is returned in millivolt.
In output mode the value represents the current voltage level at the pin. The value is load and frequency dependent.

As digital input the type is “digital_input” and the value represents the current logical state 0 (LOW) or 1 (HIGH).

As frequency counter the type is “frequency_hertz” and the value represents the current frequency in Hertz.
Please consider the minimum and maximum frequency value from the datasheet/webpage!

Request:

Method: GET
URL: <HOSTNAME>/api/io/<version>/<slot>/input/values

Parameters:

No body parameters

Response:

{
  "pins": [
    {
      "pin": 1,
      "pin_type": "voltage_millivolt | digital_input | frequency_hertz",
      "value": <int>
    },
    {
      "pin": 2,
      "pin_type": "voltage_millivolt | digital_input | frequency_hertz",
      "value": <int>
    },
    {
      "pin": 3,
      "pin_type": "voltage_millivolt | digital_input | frequency_hertz",
      "value": <int>
    },
    {
      "pin": 4,
      "pin_type": "voltage_millivolt | digital_input | frequency_hertz",
      "value": <int>
    },
    {
      "pin": 5,
      "pin_type": "voltage_millivolt | digital_input | frequency_hertz",
      "value": <int>
    },
    {
      "pin": 6,
      "pin_type": "voltage_millivolt | digital_input | frequency_hertz",
      "value": <int>
    }
  ]
}

Example

Request:

curl http://localhost/api/io/1.0/3/input/values

Response:

{
  "pins": [
    {
      "pin": 1,
      "pin_type": "voltage_millivolt",
      "value": 3300
    },
    {
      "pin": 2,
      "pin_type": "digital_input",
      "value": 1
    },
    {
      "pin": 3,
      "pin_type": "voltage_millivolt",
      "value": 0
    },
    {
      "pin": 4,
      "pin_type": "frequency_hertz",
      "value": 2000
    },
    {
      "pin": 5,
      "pin_type": "voltage_millivolt",
      "value": 0
    },
    {
      "pin": 6,
      "pin_type": "voltage_millivolt",
      "value": 0
    }
  ]
}

GET /input/values/current

Returns the current value for each pin.

The electrical current value is in milliampere.
It is returned independent from the configured mode but is usually zero in input modes.

Please note that this value includes the switching transistor loss.
This means the value will be not accurate especially in pwm mode!
The precision can be compensated by a calibration.

Request:

Method: GET
URL: <HOSTNAME>/api/io/<version>/<slot>/input/values/current

Parameters:

No body parameters

Response:

{
  "pins": [
    {
      "pin": 1,
      "pin_type": "current_milliampere",
      "value": 0
    },
    {
      "pin": 2,
      "pin_type": "current_milliampere",
      "value": 0
    },
    {
      "pin": 3,
      "pin_type": "current_milliampere",
      "value": 0
    },
    {
      "pin": 4,
      "pin_type": "current_milliampere",
      "value": 0
    },
    {
      "pin": 5,
      "pin_type": "current_milliampere",
      "value": 0
    },
    {
      "pin": 6,
      "pin_type": "current_milliampere",
      "value": 0
    }
  ]
}

Example

Request:

curl http://localhost/api/io/1.0/3/input/values/current

Response:

{
  "pins": [
    {
      "pin": 1,
      "pin_type": "current_milliampere",
      "value": 212
    },
    {
      "pin": 2,
      "pin_type": "current_milliampere",
      "value": 42
    },
    {
      "pin": 3,
      "pin_type": "current_milliampere",
      "value": 0
    },
    {
      "pin": 4,
      "pin_type": "current_milliampere",
      "value": 0
    },
    {
      "pin": 5,
      "pin_type": "current_milliampere",
      "value": 345
    },
    {
      "pin": 6,
      "pin_type": "current_milliampere",
      "value": 0
    }
  ]
}

POST /input/mode

Changes the input mode of a pin to analog or digital.
After RESET/SUSPEND the pin is always in analog mode.
Setting a pin to analog mode resets the config, including the analog threshold.

Please check /input/values for the values.

The analog mode is implicitly enabled when the pin is in output/pwm mode, /input/values and /input/analog/thresholds are available.

The digital mode can not be combined with analog/output/pwm modes.

Request:

Method: POST
URL: <HOSTNAME>/api/io/<version>/<slot>/input/mode

Parameters:

{
  "pin": <int>,
  "mode": "analog|digital"
}

Response:

{
  "status": "success"
}

Example

Request:

curl http://localhost/api/io/1.0/3/input/mode --header "Content-Type: application/json" --request POST --data '{"pin": 1, "mode": "analog"}'

Response:

{
  "status": "success"
}

POST /input/analog/threshold

Enables or disables the analog threshold mode.
The pin must be set into analog mode before the threshold can be enabled.

In analog threshold mode each threshold event triggers a notification on the SDBP.
The result must be checked via /notification endpoint.

The threshold_millivolt can be any value between the 50mV and 25000mV.

Please note that in the current implementation only the state “interrupt triggered” is stored, but not how often.

The api does currently not offer a “debounce_time_milliseconds” parameter. We recommend polling /input/values if this necessary.

Request:

Method: POST
URL: <HOSTNAME>/api/io/<version>/<slot>/input/analog/threshold

Parameters:

{
  "pin": <int>,
  "threshold_millivolt": <int>,
  "trigger": "disabled|rising|falling"
}

Response:

{
  "status": "success"
}

Example

Request:

curl http://localhost/api/io/1.0/3/input/analog/threshold --header "Content-Type: application/json" --request POST --data '{"pin": 1, "threshold_millivolt": 2000, "trigger": "rising"}'

Response:

{
  "status": "success"
}

POST /input/digital/interrupt

Enables or disables the digital interrupt mode.
The pin must be set into digital mode before the interrupt can be enabled.

In digital interrupt mode each interrupt triggers a notification on the SDBP.
The result must be checked via /notification endpoint.

Please note that in the current implementation only the state “interrupt triggered” is stored, but not how often.

The debounce_time_milliseconds is a value between 0 and 1000 milliseconds.
After the first trigger event the firmware waits debounce_time_milliseconds before sending a notification for a new event. All events in this period are ignored.
This setting is used to prevent interrupt notifications spamming the bus.
It is recommended to set the debounce_time_milliseconds to 20ms or higher.

Some things like switches or buttons typically require a ~250ms debounce_time_milliseconds to send one event per switch/press.

Please check the datasheet/webpage of the module for the HIGH/LOW thresholds.
In case you have different requirements we recommend to use the /input/analog/threshold endpoint.

Request:

Method: POST
URL: <HOSTNAME>/api/io/<version>/<slot>/input/digital/interrupt

Parameters:

{
  "pin": <int>,
  "debounce_time_milliseconds": <int>,
  "trigger": "disabled|rising|falling|pulse"
}

Response:

{
  "status": "success"
}

Example

Request:

curl http://localhost/api/io/1.0/3/input/digital/interrupt --header "Content-Type: application/json" --request POST --data '{"pin": 1, "debounce_time_milliseconds": 100, "trigger": "rising"}'

Response:

{
  "status": "success"
}

POST /input/digital/counter

Enables or disables the digital counter mode.
The pin must be set into digital mode before the counter can be enabled.

Check /input/values for the counter values.

Request:

Method: POST
URL: <HOSTNAME>/api/io/<version>/<slot>/input/digital/counter

Parameters:

{
  "pin": <int>,
  "state": "enabled|disabled"
}

Response:

{
  "status": "success"
}

Example

Request:

curl http://localhost/api/io/1.0/3/input/digital/counter --header "Content-Type: application/json" --request POST --data '{"pin": 1, "state": "enabled"}'

Response:

{
  "status": "success"
}

Output

POST /output/state

Configures the output state.
The pin is automatically reset and configured as output if the previous mode was different.

A valid power configuration must exist before this command can be used.

Check /input/values for the values.

Request:

Method: POST
URL: <HOSTNAME>/api/io/<version>/<slot>/output/state

Parameters:

{
  "pin": <int>,
  "state": "high|low"
}

Response:

{
  "status": "success"
}

Example

Request:

curl http://localhost/api/io/1.0/3/output/state --header "Content-Type: application/json" --request POST --data '{"pin": 1, "state": "high"}'

Response:

{
  "status": "success"
}

POST /output/pwm

Configures the output as pwm output.
The pin is automatically reset and configured as output if the previous mode was different.

A valid power configuration must exist before this command can be used.

Check /input/values for the values.

The pwm function is based on a 16-bit timer with a base frequency of 48MHz.

To configure the PWM the following parameters are important:
prescaler: Divisor for the 48MHz clock.
period: Amount of ticks to reach the target frequency.
time_on: Amount of ticks the signal stays high. Must be < period. e.g: if period = 100 and time_on = 60 the duty cycle is 60%

To simplify the complicated step of PWM calculation we provide a pre-calculated list.

Request:

Method: POST
URL: <HOSTNAME>/api/io/<version>/<slot>/output/pwm

Parameters:

{
  "pin": <int>,
  "prescaler": <int>,
  "time_on": <int>,
  "period": <int>
}

Response:

{
  "status": "success"
}

Example

Request:

# 25.6kHz
curl http://localhost/api/io/1.0/3/output/pwm --header "Content-Type: application/json" --request POST --data '{"pin": 1, "prescaler": 2, "time_on": 312, "period": 625}'

Response:

{
  "status": "success"
}


IO Module examples

Basic usage examples

PWM calculation

Configurations and calculation tools