Overview
The Device Catalog provides centralized management for:
Device Categories : SENSOR or ACTUATOR classifications
Device Types : Specific sensor/actuator types (temperature, humidity, pumps, valves, etc.)
Actuator States : Operational states for actuators (ON, OFF, AUTO, MANUAL, ERROR)
This catalog enables dynamic device configuration and type-safe device management across greenhouses.
Device Categories
Get All Device Categories
GET /api/v1/catalog/device-categories
curl -X GET "https://api.invernaderos.com/api/v1/catalog/device-categories" \
-H "Authorization: Bearer YOUR_TOKEN"
Retrieves available device categories (SENSOR and ACTUATOR).
Response
[
{
"id" : 1 ,
"name" : "SENSOR"
},
{
"id" : 2 ,
"name" : "ACTUATOR"
}
]
System Constants Device categories are system-defined:
ID 1 = SENSOR (devices that measure values)
ID 2 = ACTUATOR (devices that perform actions)
Device Types
Get All Device Types
GET /api/v1/catalog/device-types
curl -X GET "https://api.invernaderos.com/api/v1/catalog/device-types?categoryId=1&activeOnly=true" \
-H "Authorization: Bearer YOUR_TOKEN"
Retrieves device types with optional filtering.
Query Parameters
Filter by category: 1 = SENSOR, 2 = ACTUATOR
Return only active device types
Response
Array of device type objects Device type name (e.g., “TEMPERATURE”, “HUMIDITY”, “PUMP”)
Description of the device type
Category ID (1=SENSOR, 2=ACTUATOR)
Category name (“SENSOR” or “ACTUATOR”)
Default measurement unit ID
Default unit symbol (e.g., “°C”, ”%”, “hPa”)
Data type: DECIMAL, INTEGER, BOOLEAN, TEXT, JSON
Minimum expected physical value
Maximum expected physical value
For actuators: BINARY (on/off), CONTINUOUS (0-100%), MULTI_STATE (predefined states)
Whether the device type is active
200 OK - Sensor Types
200 OK - Actuator Types
[
{
"id" : 1 ,
"name" : "TEMPERATURE" ,
"description" : "Temperature sensor" ,
"categoryId" : 1 ,
"categoryName" : "SENSOR" ,
"defaultUnitId" : 1 ,
"defaultUnitSymbol" : "°C" ,
"dataType" : "DECIMAL" ,
"minExpectedValue" : -50.0 ,
"maxExpectedValue" : 100.0 ,
"controlType" : null ,
"isActive" : true
},
{
"id" : 2 ,
"name" : "HUMIDITY" ,
"description" : "Relative humidity sensor" ,
"categoryId" : 1 ,
"categoryName" : "SENSOR" ,
"defaultUnitId" : 2 ,
"defaultUnitSymbol" : "%" ,
"dataType" : "DECIMAL" ,
"minExpectedValue" : 0.0 ,
"maxExpectedValue" : 100.0 ,
"controlType" : null ,
"isActive" : true
}
]
Get Sensor Types (Shortcut)
GET /api/v1/catalog/device-types/sensors
curl -X GET "https://api.invernaderos.com/api/v1/catalog/device-types/sensors" \
-H "Authorization: Bearer YOUR_TOKEN"
Shortcut endpoint to retrieve only sensor types (equivalent to ?categoryId=1).
Get Actuator Types (Shortcut)
GET /api/v1/catalog/device-types/actuators
curl -X GET "https://api.invernaderos.com/api/v1/catalog/device-types/actuators" \
-H "Authorization: Bearer YOUR_TOKEN"
Shortcut endpoint to retrieve only actuator types (equivalent to ?categoryId=2).
Get Device Type by ID
GET /api/v1/catalog/device-types/{id}
curl -X GET "https://api.invernaderos.com/api/v1/catalog/device-types/1" \
-H "Authorization: Bearer YOUR_TOKEN"
Path Parameters
Response
{
"id" : 1 ,
"name" : "TEMPERATURE" ,
"description" : "Temperature sensor" ,
"categoryId" : 1 ,
"categoryName" : "SENSOR" ,
"defaultUnitId" : 1 ,
"defaultUnitSymbol" : "°C" ,
"dataType" : "DECIMAL" ,
"minExpectedValue" : -50.0 ,
"maxExpectedValue" : 100.0 ,
"controlType" : null ,
"isActive" : true
}
Create Device Type
POST /api/v1/catalog/device-types
curl -X POST "https://api.invernaderos.com/api/v1/catalog/device-types" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "SOIL_MOISTURE",
"description": "Soil moisture sensor",
"categoryId": 1,
"defaultUnitId": 2,
"dataType": "DECIMAL",
"minExpectedValue": 0.0,
"maxExpectedValue": 100.0,
"isActive": true
}'
Request Body
Device type name (max 30 characters, must be unique)
Description of the device type
Category ID: 1 = SENSOR, 2 = ACTUATOR
Default measurement unit ID (from Units catalog)
Data type: DECIMAL, INTEGER, BOOLEAN, TEXT, JSON
Minimum expected physical value (for validation)
Maximum expected physical value (for validation)
For actuators: BINARY (on/off), CONTINUOUS (0-100%), MULTI_STATE (predefined states)
Whether the device type is active
Response
201 Created
400 Bad Request - Duplicate Name
400 Bad Request - Invalid Category
{
"id" : 15 ,
"name" : "SOIL_MOISTURE" ,
"description" : "Soil moisture sensor" ,
"categoryId" : 1 ,
"categoryName" : "SENSOR" ,
"defaultUnitId" : 2 ,
"defaultUnitSymbol" : "%" ,
"dataType" : "DECIMAL" ,
"minExpectedValue" : 0.0 ,
"maxExpectedValue" : 100.0 ,
"controlType" : null ,
"isActive" : true
}
Update Device Type
PUT /api/v1/catalog/device-types/{id}
curl -X PUT "https://api.invernaderos.com/api/v1/catalog/device-types/15" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"description": "Soil moisture sensor with improved accuracy",
"maxExpectedValue": 90.0
}'
Path Parameters
Request Body
All fields are optional. Only provided fields will be updated.
New device type name (max 30 characters, must be unique)
New minimum expected value
New maximum expected value
New control type (for actuators)
Response
Same structure as “Create Device Type” with updated values.
Activate/Deactivate Device Type
PATCH /api/v1/catalog/device-types/{id}/activate
curl -X PATCH "https://api.invernaderos.com/api/v1/catalog/device-types/15/activate" \
-H "Authorization: Bearer YOUR_TOKEN"
Soft delete/restore device types without removing from database.
Path Parameters
Response
{
"id" : 15 ,
"name" : "SOIL_MOISTURE" ,
"description" : "Soil moisture sensor" ,
"categoryId" : 1 ,
"categoryName" : "SENSOR" ,
"defaultUnitId" : 2 ,
"defaultUnitSymbol" : "%" ,
"dataType" : "DECIMAL" ,
"minExpectedValue" : 0.0 ,
"maxExpectedValue" : 100.0 ,
"controlType" : null ,
"isActive" : false // Changed to false after deactivation
}
Delete Device Type
DELETE /api/v1/catalog/device-types/{id}
curl -X DELETE "https://api.invernaderos.com/api/v1/catalog/device-types/15" \
-H "Authorization: Bearer YOUR_TOKEN"
Path Parameters
Response
204 No Content
404 Not Found
409 Conflict - Associated Devices Exist
Device type deleted successfully (no body)
Deletion Constraints Cannot delete device types that have associated devices (sensors or actuators). You must:
Remove or reassign all devices using this type, OR
Use deactivation (PATCH /deactivate) instead for soft delete
Actuator States Catalog
Get All Actuator States
GET /api/v1/catalog/actuator-states
curl -X GET "https://api.invernaderos.com/api/v1/catalog/actuator-states" \
-H "Authorization: Bearer YOUR_TOKEN"
Retrieves all possible actuator states (ON, OFF, AUTO, MANUAL, ERROR, etc.).
Response
Array of actuator state objects Show ActuatorStateResponse
State name (e.g., “ON”, “OFF”, “AUTO”, “MANUAL”, “ERROR”)
Whether the actuator is functioning in this state
Sort order for UI display
Hex color code for UI visualization (e.g., “#00FF00”)
[
{
"id" : 1 ,
"name" : "ON" ,
"description" : "Actuator is running" ,
"isOperational" : true ,
"displayOrder" : 1 ,
"color" : "#00FF00"
},
{
"id" : 2 ,
"name" : "OFF" ,
"description" : "Actuator is stopped" ,
"isOperational" : false ,
"displayOrder" : 2 ,
"color" : "#808080"
},
{
"id" : 3 ,
"name" : "AUTO" ,
"description" : "Automatic mode based on sensors" ,
"isOperational" : true ,
"displayOrder" : 3 ,
"color" : "#0066FF"
},
{
"id" : 4 ,
"name" : "MANUAL" ,
"description" : "Manual control mode" ,
"isOperational" : true ,
"displayOrder" : 4 ,
"color" : "#FFAA00"
},
{
"id" : 5 ,
"name" : "ERROR" ,
"description" : "Actuator malfunction" ,
"isOperational" : false ,
"displayOrder" : 10 ,
"color" : "#FF0000"
}
]
Get Operational States Only
GET /api/v1/catalog/actuator-states/operational
curl -X GET "https://api.invernaderos.com/api/v1/catalog/actuator-states/operational" \
-H "Authorization: Bearer YOUR_TOKEN"
Retrieves only states where the actuator is functioning (isOperational = true).
Response
Same structure as “Get All Actuator States”, but filtered to operational states only (ON, AUTO, MANUAL, etc.).
Get Actuator State by ID
GET /api/v1/catalog/actuator-states/{id}
curl -X GET "https://api.invernaderos.com/api/v1/catalog/actuator-states/1" \
-H "Authorization: Bearer YOUR_TOKEN"
Path Parameters
Response
{
"id" : 1 ,
"name" : "ON" ,
"description" : "Actuator is running" ,
"isOperational" : true ,
"displayOrder" : 1 ,
"color" : "#00FF00"
}
Create Actuator State
POST /api/v1/catalog/actuator-states
curl -X POST "https://api.invernaderos.com/api/v1/catalog/actuator-states" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "WARMING_UP",
"description": "Actuator is warming up before full operation",
"isOperational": true,
"displayOrder": 5,
"color": "#FFA500"
}'
Request Body
State name (max 20 characters, must be unique)
Whether the actuator is functioning in this state
Sort order for UI display (minimum 0)
Hex color code (format: #RRGGBB, e.g., “#FFA500”)
Response
201 Created
400 Bad Request - Duplicate Name
400 Bad Request - Invalid Color
{
"id" : 6 ,
"name" : "WARMING_UP" ,
"description" : "Actuator is warming up before full operation" ,
"isOperational" : true ,
"displayOrder" : 5 ,
"color" : "#FFA500"
}
Update Actuator State
PUT /api/v1/catalog/actuator-states/{id}
curl -X PUT "https://api.invernaderos.com/api/v1/catalog/actuator-states/6" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"description": "Actuator warming up - full operation in 30 seconds",
"displayOrder": 3
}'
Path Parameters
Actuator state ID to update
Request Body
All fields are optional. Only provided fields will be updated.
New state name (max 20 characters, must be unique)
New display order (minimum 0)
Response
Same structure as “Create Actuator State” with updated values.
Delete Actuator State
DELETE /api/v1/catalog/actuator-states/{id}
curl -X DELETE "https://api.invernaderos.com/api/v1/catalog/actuator-states/6" \
-H "Authorization: Bearer YOUR_TOKEN"
Path Parameters
Actuator state ID to delete
Response
204 No Content
404 Not Found
Actuator state deleted successfully (no body)
Control Types Explained
Use Case : Simple on/off actuatorsExamples :
Irrigation pumps (ON/OFF)
Grow lights (ON/OFF)
Heaters (ON/OFF)
Data Type : BOOLEANStates : ON, OFFImplementation :{
"name" : "IRRIGATION_PUMP" ,
"categoryId" : 2 ,
"controlType" : "BINARY" ,
"dataType" : "BOOLEAN"
}
Use Case : Variable speed/position actuatorsExamples :
Vent windows (0-100% open)
Variable speed fans (0-100% speed)
Dimmers (0-100% brightness)
Data Type : INTEGER or DECIMALRange : 0-100 (percentage)Implementation :{
"name" : "VENT_WINDOW" ,
"categoryId" : 2 ,
"controlType" : "CONTINUOUS" ,
"dataType" : "INTEGER" ,
"minExpectedValue" : 0 ,
"maxExpectedValue" : 100 ,
"defaultUnitId" : 2 // % symbol
}
Use Case : Actuators with predefined statesExamples :
Irrigation valves (CLOSED, ZONE_1, ZONE_2, ZONE_3)
Multi-speed fans (OFF, LOW, MEDIUM, HIGH)
Heating systems (OFF, ECO, COMFORT, BOOST)
Data Type : TEXT or INTEGER (state index)States : Defined in actuator_states catalogImplementation :{
"name" : "IRRIGATION_VALVE" ,
"categoryId" : 2 ,
"controlType" : "MULTI_STATE" ,
"dataType" : "TEXT"
}
Integration Examples
Dynamic Device Configuration UI
Sensor Value Validation
Actuator State Management (Android)
// Generate device configuration form based on device type
const loadDeviceTypeConfig = async ( deviceTypeId ) => {
const deviceType = await fetch (
`https://api.invernaderos.com/api/v1/catalog/device-types/ ${ deviceTypeId } ` ,
{ headers: { 'Authorization' : `Bearer ${ token } ` } }
). then ( res => res . json ());
// Generate UI based on control type
switch ( deviceType . controlType ) {
case 'BINARY' :
return {
component: 'Toggle' ,
props: {
label: deviceType . name ,
states: [ 'ON' , 'OFF' ]
}
};
case 'CONTINUOUS' :
return {
component: 'Slider' ,
props: {
label: deviceType . name ,
min: deviceType . minExpectedValue ,
max: deviceType . maxExpectedValue ,
unit: deviceType . defaultUnitSymbol ,
step: 1
}
};
case 'MULTI_STATE' :
const states = await fetch (
'https://api.invernaderos.com/api/v1/catalog/actuator-states' ,
{ headers: { 'Authorization' : `Bearer ${ token } ` } }
). then ( res => res . json ());
return {
component: 'Dropdown' ,
props: {
label: deviceType . name ,
options: states . map ( s => ({ value: s . id , label: s . name }))
}
};
default :
return { component: 'Input' , props: { label: deviceType . name } };
}
};
Error Codes
Status Code Description Resolution 200 OK Request successful - 201 Created Resource created successfully - 204 No Content Resource deleted successfully - 400 Bad Request Invalid input (duplicate name, invalid category, invalid color format) Check error message for details 404 Not Found Resource not found with specified ID Verify the ID exists 409 Conflict Cannot delete resource due to dependencies (devices using type) Remove dependencies or use deactivation
Best Practices
When creating sensor types:
Set realistic value ranges (minExpectedValue, maxExpectedValue) for validation
Choose appropriate units from the Units catalog
Use DECIMAL data type for most measurements (temperature, humidity, pressure)
Document physical constraints in the description field
Example: {
"name" : "SOIL_TEMPERATURE" ,
"description" : "Soil temperature at 10cm depth" ,
"categoryId" : 1 ,
"defaultUnitId" : 1 , // °C
"dataType" : "DECIMAL" ,
"minExpectedValue" : -10.0 ,
"maxExpectedValue" : 50.0
}
When creating actuator types:
Choose correct control type (BINARY, CONTINUOUS, MULTI_STATE)
For CONTINUOUS , always set min/max values (typically 0-100)
For MULTI_STATE , define states in actuator_states catalog first
Document control behavior in the description
Example: {
"name" : "NUTRIENT_PUMP" ,
"description" : "Variable speed nutrient injection pump (0-100% flow rate)" ,
"categoryId" : 2 ,
"defaultUnitId" : 2 , // %
"controlType" : "CONTINUOUS" ,
"dataType" : "INTEGER" ,
"minExpectedValue" : 0 ,
"maxExpectedValue" : 100
}
When defining actuator states:
Use consistent naming (uppercase: ON, OFF, AUTO, MANUAL)
Set isOperational correctly (true = actuator functioning, false = error/stopped)
Choose intuitive colors : Green (operational), Red (error), Gray (off), Orange (transitional)
Order by priority : Critical states (ERROR) should have high displayOrder
Example: {
"name" : "STARTING" ,
"description" : "Actuator is starting up" ,
"isOperational" : true ,
"displayOrder" : 4 ,
"color" : "#FFA500" // Orange for transitional state
}
Prefer deactivation over deletion to preserve historical device configurations
Only delete truly unused custom types with zero associated devices
Document deprecation in description before deactivating
Use activeOnly=true in queries to filter out deprecated types
Units Catalog
Units define measurement units for sensors (°C, %, lux, ppm, etc.).
Get All Units
GET /api/v1/catalog/units
Retrieves all available measurement units.
Response
Unit name (e.g., “Celsius”, “Percent”, “Lux”)
Unit symbol (e.g., “°C”, ”%”, “lux”)
Whether the unit is currently active
Example
curl -X GET "https://api.example.com/api/v1/catalog/units" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
Get Unit by ID
GET /api/v1/catalog/units/{id}
Create Unit
POST /api/v1/catalog/units
Update Unit
PUT /api/v1/catalog/units/{id}
Activate Unit
PUT /api/v1/catalog/units/{id}/activate
Activates a previously deactivated unit.
Deactivate Unit
PUT /api/v1/catalog/units/{id}/deactivate
Deactivated units cannot be deleted if they are referenced by devices or settings.
Periods Catalog
Periods define time intervals for alerts and automation rules.
Get All Periods
GET /api/v1/catalog/periods
Retrieves all available time periods.
Response
Period name (e.g., “Morning”, “Afternoon”, “Night”)
Example
curl -X GET "https://api.example.com/api/v1/catalog/periods" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
Get Period by ID
GET /api/v1/catalog/periods/{id}
Create Period
POST /api/v1/catalog/periods
Update Period
PUT /api/v1/catalog/periods/{id}
Delete Period
DELETE /api/v1/catalog/periods/{id}
Cannot delete periods that are referenced by active automation rules or alerts.