Skip to content

Rest API

Oshgnacknak edited this page Feb 4, 2026 · 1 revision

The Qitech Control Panel exposes a small HTTP interface for discovering machines and reading their current values. All examples below assume you are connected to the panel’s Ethernet subnet and talk directly to the panel at:

  • Base URL: http://10.10.10.1:3001

Schema note: This documentation intentionally stays light on field details beyond what is shown in the examples. For the exact datatypes and complete payload shapes, refer to the corresponding Rust types (linked below).


Authentication

The panel does not perform HTTP authentication. The expected security model is network-level isolation: anything that can send packets to the panel’s Ethernet interface is treated as trusted. This matches common security assumptions in EtherCAT-style control networks. It is therefore suggested to run the entire production line in isolated operation.

The panel is configured to administer its own subnet 10.10.10.0/24 via DHCP, while Wi-Fi can be used for upstream internet connectivity. To let the outside world communicate with the production line, a router should be placed at the network bondary bridging the production line's subnet and the rest of the network. The router can run in client/bridge mode on the line's subnet and expose the panel's API via port forwading or through a reverse proxy where one can add authentication, logging, rate limiting, etc.

The following graphic depicts the suggested network topology for a single production line. Many lines could potentially share the same router.

Suggested network topology

If DNS is available on the subnet, you may be able to resolve qitech.control; otherwise use the static address 10.10.10.1.


List machines GET /api/v2/machine

Returns the set of machines currently known/connected to the panel.

Machines are identified by:

  • slug: the machine type / model identifier (string)
  • serial: the specific machine instance identifier (int)

Each machine also includes a legacy_id to support older v1 workflows. If a machine reports an issue, the error field may be present and non-null (containing an error message).

Example request

curl -X GET "http://10.10.10.1:3001/api/v2/machine"

Example response

{
  "machines": [
    {
      "legacy_id": {
        "machine_identification": {
          "vendor": 1,
          "machine": 7
        },
        "serial": 57922
      },
      "serial": 57922,
      "vendor": "QiTech",
      "slug": "mock",
      "error": null
    },
    {
      "legacy_id": {
        "machine_identification": {
          "vendor": 1,
          "machine": 4
        },
        "serial": 57922
      },
      "serial": 57922,
      "vendor": "QiTech",
      "slug": "extruder_v1",
      "error": null
    },
    {
      "legacy_id": {
        "machine_identification": {
          "vendor": 1,
          "machine": 2
        },
        "serial": 57922
      },
      "serial": 57922,
      "vendor": "QiTech",
      "slug": "winder_v1",
      "error": null
    },
    {
      "legacy_id": {
        "machine_identification": {
          "vendor": 1,
          "machine": 10
        },
        "serial": 48879
      },
      "serial": 48879,
      "vendor": "QiTech",
      "slug": "wago_power_v1",
      "error": null
    }
  ]
}

Get current values GET /api/v2/machine/<slug>/<serial>

Returns all currently known values for a single machine.

Values are categorized into two groups:

  • State: requested/commanded values (these typically change only after a state-change request, or if another controller updates them)
  • Live Values: measured/observed values coming from the machine and potentially changing quickly

This REST endpoint returns only the current snapshot, not a stream of live values. To receive continuous updates (via WebSockets), subscribe to the machine namespace (see WebSockets below).

Example request (mock machine)

curl -X GET "http://10.10.10.1:3001/api/v2/machine/mock/57922"

Example response

{
  "machine": {
    "legacy_id": {
      "machine_identification": {
        "vendor": 1,
        "machine": 7
      },
      "serial": 57922
    },
    "serial": 57922,
    "vendor": "QiTech",
    "slug": "mock",
    "error": null
  },
  "state": {
    "frequency1": 100.0,
    "frequency2": 200.0,
    "frequency3": 500.0,
    "is_default_state": false,
    "mode_state": {
      "mode": "Running"
    }
  },
  "live_values": {
    "amplitude1": -0.03438523433309566,
    "amplitude2": -0.06872980145477608,
    "amplitude3": -0.1711138370170743,
    "amplitude_sum": -0.27422887280494607
  }
}

Change machine state POST /api/v1/machine/<slug>/<serial>

State changes are submitted as mutations. The mutation payload is defined per machine type in Rust. Conceptually, each item in the mutation list represents a setter-style operation that is applied by the real-time control loop.

The API does not return the newly-applied state in the POST response. The panel runs a real-time loop and generally won’t block waiting for the physical system to converge. Instead:

  • Submit the mutation via POST
  • Poll GET /api/v2/machine/<slug>/<serial> to observe the updated state and/or any reported errors

Example request (mock machine)

curl -X POST \
  -d  \
  -H "Content-Type: application/json" \
  "http://10.10.10.1:3001/api/v1/machine/mock/57922"

Example response

null

WebSockets

For continuous updates, subscribe to a machine-specific namespace derived from its legacy_id:

  • Namespace: /machine/<vendor>/<id>/<serial>

The stream emits events for:

  • state changes (StateEvent)
  • live value updates (LiveValuesEvent)

Both event payloads use the same machine-specific schema as the /api/v2 REST responses.


List of all machines

Below is a template you can fill with links to the relevant Rust types (mutations + state/live structs). For each machine, link to:

  • Mutations: the request payload type used by POST /api/v1/machine/<slug>/<serial>
  • State / Live Values: the response payload types returned by GET /api/v2/machine/<slug>/<serial>

Machines

Clone this wiki locally