Appearance
Device Points
Overview
Device points define how a device reads or writes physical signals. Each point maps to a Modbus register, stores optional engineering conversion parameters, and can be controlled (ON/OFF/Forward/Reverse) when the underlying hardware supports it.
- Base Path:
/api/v2/projects/{project_id}/devices/{device_id}/points/ - Caching: Point list/detail endpoints cache responses for 5 minutes and automatically refresh whenever a point is added, updated, or removed.
Endpoint Summary
| Method | Path | Purpose | Notes |
|---|---|---|---|
| GET | /projects/{project_id}/devices/{device_id}/points/ | List points for a device | Cached; ordered by slave_id, address, data_index |
| GET | /projects/{project_id}/devices/{device_id}/points/{id}/ | Retrieve a single point | Includes derived metadata (the_type_detail, etc.) |
| POST | /projects/{project_id}/devices/{device_id}/points/ | Create a point | Validates uniqueness of (slave_id, address, data_index) |
| PATCH | /projects/{project_id}/devices/{device_id}/points/{id}/ | Update a point | Partial updates allowed |
| DELETE | /projects/{project_id}/devices/{device_id}/points/{id}/ | Delete a point | Cache is refreshed automatically |
| POST | /projects/{project_id}/devices/{device_id}/points/{id}/on/ | Turn on | Sends ON command to device, returns command token |
| POST | /projects/{project_id}/devices/{device_id}/points/{id}/off/ | Turn off | Sends OFF command to device, returns command token |
| POST | /projects/{project_id}/devices/{device_id}/points/{id}/forward/ | Forward rotation | Sends FORWARD command, returns command token |
| POST | /projects/{project_id}/devices/{device_id}/points/{id}/antiport/ | Reverse rotation | Sends ANTIPORT command, returns command token |
| POST | /projects/{project_id}/devices/{device_id}/points/{id}/stop/ | Stop | Sends STOP command, returns command token |
| POST | /projects/{project_id}/devices/{device_id}/points/{id}/set-content/ | Set display content | For LED/digit display devices, returns command token |
| POST | /projects/{project_id}/devices/{device_id}/points/{id}/set-alarm-level/ | Set alarm level | Level range 0–5, returns command token |
| GET | /projects/{project_id}/devices/{device_id}/points/{id}/current-data/ | Real-time snapshot | Reads latest value from low-latency cache |
| POST | /projects/{project_id}/devices/{device_id}/points/{id}/set-threshold/ | Configure threshold | Sets min_value/max_value; triggers alert when exceeded |
| GET | /projects/{project_id}/devices/{device_id}/points/threshold-points/ | List threshold points | Returns only points with at least one threshold configured |
| GET | /projects/{project_id}/devices/{device_id}/points/options/ | Get configuration options | Returns Modbus types, data types, and point types |
| POST | /projects/{project_id}/devices/{device_id}/points/{id}/duplicate/ | Duplicate a point | Creates a sibling point with auto-incremented data_index |
| GET | /api/v2/data/{point_agri_id}/ | Historical data | Query historical data by point agri_id |
Point Model
Each point exposes the following fields:
| Field | Type | Description |
|---|---|---|
id | integer | Point primary key |
agri_id | string | Full identifier: {device_agri_id}-{slave_id}-{address}{data_index} |
device_id | integer | Parent device ID |
name | string | Point name |
slave_id | integer | Modbus slave ID |
address | integer | Register address |
data_index | integer | Offset for multi-register reads (0–9) |
the_type | integer | Point type ID |
the_type_detail | object | Point type metadata (name, unit, icon) |
modbus_type | string | One of holding, input, coil, discrete |
data_type | string | int16, uint16, int32, float, etc. |
data_endian | string | Byte order: ABCD, DCBA, BADC, CDAB |
data_scale | float | Scale factor. Final value = raw × data_scale + data_delta |
data_delta | float | Additive offset. Final value = raw × data_scale + data_delta |
min_value | float | Alert lower threshold (optional) |
max_value | float | Alert upper threshold (optional) |
enabled | boolean | Whether the point is active |
info | string | Free-form note (optional) |
List Points
http
GET /api/v2/projects/{project_id}/devices/{device_id}/points/
Authorization: Bearer <token>
X-Organization-Slug: <org-slug>Response example:
json
[
{
"id": 12,
"agri_id": "d-1000-abcd-1-00",
"device_id": 5,
"name": "Inlet Temperature",
"slave_id": 1,
"address": 0,
"data_index": 0,
"the_type": 1,
"the_type_detail": {
"the_type": 1,
"name": "Temperature",
"unit": "℃",
"icon_url": "https://cloud.yengear.com/media/icon/temp.png",
"is_shared": true
},
"modbus_type": "holding",
"data_type": "int16",
"data_endian": "ABCD",
"data_scale": 0.1,
"data_delta": 0.0,
"min_value": null,
"max_value": null,
"enabled": true,
"info": null
}
]Retrieve Point
http
GET /api/v2/projects/{project_id}/devices/{device_id}/points/{id}/
Authorization: Bearer <token>
X-Organization-Slug: <org-slug>Returns the same schema as the list entry, including min_value/max_value if configured.
Create Point
http
POST /api/v2/projects/{project_id}/devices/{device_id}/points/
Authorization: Bearer <token>
X-Organization-Slug: <org-slug>
Content-Type: application/json
{
"name": "Inlet Temperature",
"slave_id": 1,
"address": 0,
"data_index": 0,
"the_type": 1,
"modbus_type": "holding",
"data_type": "int16",
"data_endian": "ABCD",
"data_scale": 0.1,
"info": "Inlet temperature sensor"
}Request Fields
| Field | Type | Required | Notes |
|---|---|---|---|
slave_id | integer | Yes | Modbus slave ID |
address | integer | Yes | Register address |
data_index | integer | Yes | Offset for multi-register reads |
the_type | integer | Yes | Point type ID |
modbus_type | string | Yes | holding, input, coil, discrete |
data_type | string | Yes | int16, uint16, int32, float, etc. |
data_endian | string | Yes | Byte order (ABCD, DCBA, BADC, CDAB) |
name | string | No | Point name |
data_scale | float | No | Scale factor, default 1 |
data_delta | float | No | Additive offset, default 0 |
enabled | boolean | No | Defaults to true |
info | string | No | Free-form note |
Returns the created point record. Duplicate (slave_id, address, data_index) combinations are rejected with 400.
Note: The device's
BaseDevice.property & 0x20must be set, otherwiseDEVICE_NOT_EDITABLEis returned.
Update Point
http
PATCH /api/v2/projects/{project_id}/devices/{device_id}/points/{id}/
Authorization: Bearer <token>
X-Organization-Slug: <org-slug>
Content-Type: application/json
{
"data_scale": 0.01,
"info": "Scaled to volts"
}Partial updates are supported — only include the fields you want to change.
Delete Point
http
DELETE /api/v2/projects/{project_id}/devices/{device_id}/points/{id}/
Authorization: Bearer <token>
X-Organization-Slug: <org-slug>Returns 204 No Content on success.
Duplicate Point
http
POST /api/v2/projects/{project_id}/devices/{device_id}/points/{id}/duplicate/
Authorization: Bearer <token>
X-Organization-Slug: <org-slug>Creates a sibling point with the same configuration. The name gets _N appended, and data_index is auto-incremented for the same (slave_id, address) pair. Returns 201 with the new point data.
Control Actions
Switch and actuator points accept control commands. Requires operator role or higher.
http
POST /api/v2/projects/{project_id}/devices/{device_id}/points/{id}/on/
Authorization: Bearer <token>
X-Organization-Slug: <org-slug>| Action | Endpoint | Description |
|---|---|---|
| Turn on | POST /on/ | Send ON command to device |
| Turn off | POST /off/ | Send OFF command to device |
| Forward | POST /forward/ | Motor forward rotation |
| Reverse | POST /antiport/ | Motor reverse rotation |
| Stop | POST /stop/ | Stop current operation |
All control actions return the same response structure:
json
{
"success": true,
"message": "Operation succeeded",
"token": "cmd_xxxxxxxxxxxxxxxx"
}The token can be used to correlate command execution status.
Set Display Content
For LED and digit display devices:
http
POST /api/v2/projects/{project_id}/devices/{device_id}/points/{id}/set-content/
Authorization: Bearer <token>
X-Organization-Slug: <org-slug>
Content-Type: application/json
{
"content": "Hello"
}| Field | Type | Required | Notes |
|---|---|---|---|
content | string | Yes | Text to display on the device |
Set Alarm Level
http
POST /api/v2/projects/{project_id}/devices/{device_id}/points/{id}/set-alarm-level/
Authorization: Bearer <token>
X-Organization-Slug: <org-slug>
Content-Type: application/json
{
"level": 2
}| Field | Type | Required | Notes |
|---|---|---|---|
level | integer | Yes | Alarm level, range 0–5 |
Real-time Snapshot
http
GET /api/v2/projects/{project_id}/devices/{device_id}/points/{id}/current-data/
Authorization: Bearer <token>
X-Organization-Slug: <org-slug>Reads the point's latest value from the low-latency cache (Cloudflare D1). Returns an empty object if no data is available yet — never returns 404.
Response example:
json
{
"agri_id": "d-1000-abcd-1-00",
"value": 24.5,
"the_type": 1,
"unit": "℃",
"updated_at": 1704758400
}Get Configuration Options
http
GET /api/v2/projects/{project_id}/devices/{device_id}/points/options/
Authorization: Bearer <token>
X-Organization-Slug: <org-slug>Returns available configuration options for creating points:
json
{
"modbus_type_choices": [
{"value": "holding", "label": "Holding Register"},
{"value": "input", "label": "Input Register"},
{"value": "coil", "label": "Coil"},
{"value": "discrete", "label": "Discrete Input"}
],
"data_type_choices": [
{"value": "int16", "label": "16-bit Integer"},
{"value": "uint16", "label": "16-bit Unsigned Integer"},
{"value": "int32", "label": "32-bit Integer"},
{"value": "float", "label": "Float"}
],
"data_endian_choices": [
{"value": "ABCD", "label": "Big Endian"},
{"value": "DCBA", "label": "Little Endian"},
{"value": "BADC", "label": "Mid-Little Endian"},
{"value": "CDAB", "label": "Mid-Big Endian"}
],
"point_types": [
{"the_type": 1, "name": "Temperature", "unit": "℃", "is_shared": true},
{"the_type": 2, "name": "Humidity", "unit": "%RH", "is_shared": true},
{"the_type": 200, "name": "Switch", "unit": "", "is_shared": true}
]
}Threshold Management
Set Threshold
http
POST /api/v2/projects/{project_id}/devices/{device_id}/points/{id}/set-threshold/
Authorization: Bearer <token>
X-Organization-Slug: <org-slug>
Content-Type: application/json
{
"min_value": 5.0,
"max_value": 35.0
}| Field | Type | Required | Notes |
|---|---|---|---|
min_value | float | No | Lower alert threshold |
max_value | float | No | Upper alert threshold |
Both fields are optional, but if both are provided, min_value must be less than max_value.
List Threshold Points
http
GET /api/v2/projects/{project_id}/devices/{device_id}/points/threshold-points/
Authorization: Bearer <token>
X-Organization-Slug: <org-slug>Returns only points where at least one threshold is configured.
Historical Data by agri_id
http
GET /api/v2/data/{point_agri_id}/?page=1&page_size=50&min_timestamp=1704758400
Authorization: Bearer <token>
X-Organization-Slug: <org-slug>Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
page | integer | 1 | Page number |
page_size | integer | 50 | Records per page |
min_timestamp | integer | — | Filter by minimum Unix timestamp (seconds) |
The API validates that the point's parent device belongs to the requester's organization before reading from the historical store.
Response example:
json
{
"count": 100,
"next": "?page=2&page_size=50",
"previous": null,
"results": [
{ "agri_id": "d-1000-abcd-1-00", "v": 24.2, "t": 1704758400 }
]
}Error Codes
| Status | Code | Description |
|---|---|---|
| 400 | DUPLICATE_POINT | (slave_id, address, data_index) combination already exists |
| 400 | DEVICE_NOT_EDITABLE | Device does not support custom point configuration |
| 400 | INVALID_THRESHOLD | Invalid min_value/max_value payload |
| 401 | UNAUTHORIZED | Missing or invalid token |
| 403 | FORBIDDEN | Caller lacks required role |
| 404 | POINT_NOT_FOUND | Point not found or not in the current organization |
| 500 | COMMAND_FAILED | Failed to dispatch control command |
Operational Notes
- Hardware Support: Only devices with
BaseDevice.property & 0x20set support custom point configuration. Create/update/delete on unsupported devices returnDEVICE_NOT_EDITABLE. - Command Tokens: Store the
tokenreturned by control endpoints to correlate with device acknowledgements. - Real-time vs. Historical:
current-datareads from low-latency cache; the historical endpoint reads from persistent storage with pagination. Expect slight divergence between the two sources. - agri_id Format:
agri_id = {device_agri_id}-{slave_id}-{address}{data_index}. No leading zeros onaddressordata_index. - Cache Refresh: Create, update, and delete operations automatically refresh the cached list/detail responses. Control actions do not alter configuration and do not flush caches.
