Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/GaelCeballos/Smart_Enviro_Backend/llms.txt

Use this file to discover all available pages before exploring further.

Device properties are a flexible key-value store (the device_properties table) that lets mobile clients configure per-device behavior without changing firmware. Each property has a property_key and property_value string, and the full set is returned to the ESP32 on every sync and sensor-data response. This means a user can change a threshold in the app and the device will act on it within one measurement cycle — no OTA update required.

Property Storage

Properties live in the device_properties table with the following structure:
ColumnTypeNotes
idbigintAuto-incrementing primary key
device_idbigintForeign key to devices; cascades on delete
property_keystring(100)Identifies the configuration knob, e.g. humidity_threshold
property_valuestringThe value, always stored as a string
Key constraints and behavior:
  • A unique constraint on (device_id, property_key) ensures exactly one value per key per device.
  • Use PUT /api/my-devices/{id}/properties to create or update a property. The backend performs an upsert (updateOrCreate) — if the key already exists it is updated in-place; if not, a new row is inserted.
  • Every successful property update automatically creates a COMMAND log entry in device_logs recording which key was changed and the new value.
  • All values are stored as plain strings. The API casts values to boolean or int as needed before returning them in device_control and capability responses.

Standard Property Keys

The following property keys are recognized and consumed by the backend and firmware. Any other key is passed through to the ESP32 as-is in the config block.
Property KeyValue TypeExample ValueDescription
auto_waterboolean string"true" / "false"Enable automatic watering based on the humidity threshold. When true and current_state is STANDBY, the ESP32 activates the pump autonomously.
humidity_thresholdinteger string"60"Humidity percentage below which auto_water triggers the pump. Defaults to 60 if not set.
has_pumpboolean string"true" / "false"Declares whether the device has a pump actuator. Used by mobile clients to show or hide pump controls.
has_humidityboolean string"true" / "false"Declares whether the device has a humidity sensor. Used by mobile clients to show or hide humidity readings.
has_lightboolean string"true" / "false"Declares whether the device has a light sensor. Exposed as has_light_sensor in the capabilities object.
dimmer_levelinteger string"75"Dimmer percentage for compatible actuators. Passed through to the ESP32 in the sync config block.
pump_durationinteger string"10"Duration in seconds for a single pump activation cycle.

Update a Property

PUT /api/my-devices/{id}/properties requires a valid Sanctum token and ownership of the device. It accepts a single property update per request. Request body:
FieldTypeRequiredDescription
property_keystring✅ YesThe property key to create or update
property_valuestring✅ YesThe new value (always a string, even for booleans and integers)
curl -X PUT http://localhost/api/my-devices/3/properties \
  -H "Authorization: Bearer YOUR_SANCTUM_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"property_key": "humidity_threshold", "property_value": "45"}'
Successful response (200):
{
  "status": "success",
  "message": "Configuración guardada correctamente"
}
Error — device not found or not owned by the authenticated user (404):
{
  "status": "error",
  "message": "Dispositivo no encontrado"
}
All property values are stored as strings. The API handles casting to boolean or int when building structured responses. When setting boolean properties from a mobile client, always send the string "true" or "false" — not the JSON literals true or false.

Properties in Device Responses

Properties surface in three different shapes depending on the caller:
The UserDeviceController reads properties and builds two typed objects:capabilities — hardware feature flags cast to boolean:
{
  "capabilities": {
    "has_pump": true,
    "has_humidity": true,
    "has_light_sensor": false
  }
}
settings — automation configuration with proper types (only present on the single-device endpoint):
{
  "settings": {
    "auto_water": true,
    "humidity_threshold": 45
  }
}
The DeviceSyncController returns the raw properties as a flat key→value map under the config key. All values remain strings, matching what was stored:
{
  "status": "success",
  "command": "STANDBY",
  "config": {
    "auto_water": "true",
    "humidity_threshold": "45",
    "has_pump": "true",
    "dimmer_level": "75",
    "pump_duration": "10"
  }
}
The firmware is responsible for parsing the string values to the appropriate native types.
The SensorDataController injects a device_control block with pre-cast values so the ESP32 can act immediately without string parsing:
{
  "device_control": {
    "current_state": "STANDBY",
    "auto_water": true,
    "humidity_threshold": 45
  }
}

ESP32 Integration

See how the ESP32 consumes the sync config and device_control blocks in practice.

Device Overview

Review the full device lifecycle and the device_logs entries created by property updates.

Build docs developers (and LLMs) love