-
Notifications
You must be signed in to change notification settings - Fork 30
Rest API
The panel behaves like any other NetworkManager-managed linux and is able to either receive an IP-Address over DHCP or a statically defined one. Where the static IP is most likely the easiest to work with.
-
Base URL:
https://IP_ADDRESS
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).
The panel performs Basic-Auth authentication. For EVERY request made over HTTPS, Basic Auth is required.
To set the password on the Panel for Basic Auth, do the following:
- Open a Terminal
- cd /home/qitech/control
- ./credentials.sh
The credentials.sh script sets and prints the username and password for the api ONCE in the console. Afterwards its accessible in machine_password in /tmp/ until the machine shuts down. If you ever forget your password you can simply run ./credentials.sh again, resetting the password used, however the username will always be machine
Example request with curl:
# username=machine
# password=VoMZKZK4K4ZIvON+OU2ZcCXy
# With -k you can ignore curl's self signed certificate error
curl https://192.168.130.195/api/v2/machine -k -u machine:VoMZKZK4K4ZIvON+OU2ZcCXy
For HTTPS we use self-signed certificates. These are untrusted by default in browsers,tools like curl and https libraries.
For most programs you can either ignore this warning or you can manually trust the certificate on your system. How these are installed depends on your system.
On the panel pc, the root Certificate is located at: /var/lib/caddy/.local/share/caddy/pki/authorities/local/root.crt
You need to copy this file to an usb drive or copy it some other way and add it as a trusted root certificate in your OS.
Please refer to your OS' documentation or search the Internet about how to install a trusted SSL certificate.
If you have an isolated network and don't wish to perform Authentication, then you can achieve this by:
cd control
sudo nano nixos/os/configuration.nixFind:
networking.firewall.allowedTCPPorts = [ 443 ];Change to:
networking.firewall.allowedTCPPorts = [ 3001 ];Save and exit.
sudo nixos-rebuild switch --flake .#nixos --impure
sudo rebootsystemctl status qitech-control-server --no-pager
ss -ltnp | grep 3001The service should be listening on 0.0.0.0:3001.
hostname -IExample:
192.168.130.195
Replace <PANEL_IP> with IP from previous step.
Test-NetConnection -ComputerName <PANEL_IP> -Port 3001REST API test:
curl.exe "http://<PANEL_IP>:3001/api/v2/machine"Again, you should only ever do this if you have your own reverse proxy with authentication or you have an isolated network.
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).
curl -X GET "https://IP_ADDRESS/api/v2/machine" -u machine:YOUR_PASSWORD{
"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
}
]
}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).
curl -X GET "https://IP_ADDRESS/api/v2/machine/mock/57922" -u machine:YOUR_PASSWORD{
"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
}
}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
curl -X POST \
-d \
-H "Content-Type: application/json" \
"https://IP_ADDRESS/api/v1/machine/mock/57922" -u machine:YOUR_PASSWORDnullFor 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.
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>
-
winder_v1
- Mutations: https://github.com/qitechgmbh/control/blob/1ec20074e9030a0ed1739ca9d9a77e298a2652a3/machines/src/winder2/api.rs#L87
- State: https://github.com/qitechgmbh/control/blob/1ec20074e9030a0ed1739ca9d9a77e298a2652a3/machines/src/winder2/api.rs#L163
- Live Values: https://github.com/qitechgmbh/control/blob/1ec20074e9030a0ed1739ca9d9a77e298a2652a3/machines/src/winder2/api.rs#L143
-
extruder_v1
- Mutations: https://github.com/qitechgmbh/control/blob/1ec20074e9030a0ed1739ca9d9a77e298a2652a3/machines/src/extruder1/api.rs#L214
- State: https://github.com/qitechgmbh/control/blob/1ec20074e9030a0ed1739ca9d9a77e298a2652a3/machines/src/extruder1/api.rs#L89
- Live Values: https://github.com/qitechgmbh/control/blob/1ec20074e9030a0ed1739ca9d9a77e298a2652a3/machines/src/extruder1/api.rs#L55
-
laser_v1
- Mutations: https://github.com/qitechgmbh/control/blob/1ec20074e9030a0ed1739ca9d9a77e298a2652a3/machines/src/laser/api.rs#L88
- State: https://github.com/qitechgmbh/control/blob/1ec20074e9030a0ed1739ca9d9a77e298a2652a3/machines/src/laser/api.rs#L32
- Live Values: https://github.com/qitechgmbh/control/blob/1ec20074e9030a0ed1739ca9d9a77e298a2652a3/machines/src/laser/api.rs#L17
-
mock
- Mutations: https://github.com/qitechgmbh/control/blob/1ec20074e9030a0ed1739ca9d9a77e298a2652a3/machines/src/mock/api.rs#L84
- State: https://github.com/qitechgmbh/control/blob/1ec20074e9030a0ed1739ca9d9a77e298a2652a3/machines/src/mock/api.rs#L38
- Live Values: https://github.com/qitechgmbh/control/blob/1ec20074e9030a0ed1739ca9d9a77e298a2652a3/machines/src/mock/api.rs#L24
-
extruder_v2
- Mutations: https://github.com/qitechgmbh/control/blob/1ec20074e9030a0ed1739ca9d9a77e298a2652a3/machines/src/extruder2/api.rs#L126
- State: https://github.com/qitechgmbh/control/blob/1ec20074e9030a0ed1739ca9d9a77e298a2652a3/machines/src/extruder2/api.rs#L93
- Live Values: https://github.com/qitechgmbh/control/blob/1ec20074e9030a0ed1739ca9d9a77e298a2652a3/machines/src/extruder2/api.rs#L59
QiTech Control | GitHub | Video Demo | Open Source Framework for Industrial Control
- Getting Started
- Adding a Machine
- Adding a minimal machine e.G. 4CH DO
- Code Style
- Performance
- Testing
- Adding Presets to Machines
- NixOS
Beckhoff:
WAGO:
- 4 Digital In (750-402)
- 8 Digital In (750-430)
- 8 Digital In + 8 Digital Out (750-1506)
- 4 Analog In (750-455)
- 2 Digital Out (750-501)
- 8 Digital Out (750-530)
- Stepper (750-671 & 750-672)
- Power Supply (2789‐9052)
- Serial Interface (750-652)
- 4-channel Analog input module Pt100 RTD (750-460)
- 8 Digital In + 8 Digital Out (750-430 + 750-530)
Elrest:
WAGO: