Skip to content

API Reference: Generated Models

django_devicehub.models

BaseDevice

Bases: Model

Abstract base for all device models generated by DeviceType.create_models().

Provides identity, status tracking, MQTT authentication, and lifecycle fields. DeviceType-specific StateFields are added as extra columns on the concrete model.

check_mqtt_password(raw_password)

Verify a plaintext password against the stored hash.

generate_credentials()

Generate MQTT credentials and API key.

Returns a dict with plaintext values (shown once, then hashed).

is_heartbeat_overdue(heartbeat_interval=300, multiplier=2.5)

Check if the device has missed its heartbeat window.

send_command(command_name, payload=None, broker_name='default')

Send a command to this device via the configured broker.

BaseMessage

Bases: Model

Abstract base for raw message storage (audit trail / debugging).

BaseReading

Bases: Model

Abstract base for reading models.

Subclasses get one nullable column per Reading field declared on the DeviceType, forming a wide time-series table.

When you call DeviceType.create_models(), three concrete Django models are generated. They inherit from the abstract base models documented here.

BaseDevice

from django_devicehub.models import BaseDevice

Abstract base for all generated device models. Provides device identity, status tracking, MQTT authentication, and lifecycle fields.

Fields

Field Type Description
device_id CharField(128) Unique device identifier. Indexed.
name CharField(255) Human-readable name. Blank allowed.
status CharField(20) Device status. Choices from DeviceStatus. Default: "offline". Indexed.
battery_level FloatField Battery percentage. Nullable.
last_seen DateTimeField Last communication timestamp. Nullable.
firmware_version CharField(50) Firmware version string. Blank allowed.
is_active BooleanField Whether the device is active. Default: True. Indexed.
mqtt_username CharField(128) MQTT login username. Unique. Nullable.
mqtt_password_hash CharField(256) Hashed MQTT password.
api_key CharField(128) API key for REST authentication. Unique. Nullable.
metadata JSONField Free-form metadata dict. Default: {}.
created_at DateTimeField Auto-set on creation.
updated_at DateTimeField Auto-set on save.

Plus any StateField columns declared on the DeviceType.

Meta

  • abstract = True
  • ordering = ["-created_at"]

Methods

__str__()

Returns "{name or device_id} ({status})".


generate_credentials()

Generate MQTT credentials and API key.

Returns: dict with plaintext values:

{
    "mqtt_username": "myapp-weatherstationdevice-STATION-001",
    "mqtt_password": "dG9rZW4t...",    # plaintext, shown once
    "api_key": "a1b2c3d4...",          # 64-char hex
}

Sets mqtt_username, mqtt_password_hash, and api_key on the instance. Call .save() after to persist.


check_mqtt_password(raw_password)

Verify a plaintext password against the stored hash.

Parameters:

  • raw_password (str): The plaintext password to check.

Returns: bool -- True if the password matches.


mark_online()

Set status to "online", update last_seen to now, and save.


mark_offline()

Set status to "offline" and save.


is_heartbeat_overdue(heartbeat_interval=300, multiplier=2.5)

Check if the device has missed its heartbeat window.

Parameters:

  • heartbeat_interval (int): Expected interval in seconds. Default: 300.
  • multiplier (float): How many intervals before considered overdue. Default: 2.5.

Returns: bool -- True if last_seen is older than heartbeat_interval * multiplier seconds ago, or if last_seen is None.


send_command(command_name, payload=None, broker_name="default")

Send a command to this device via MQTT.

Parameters:

  • command_name (str): Name of a command declared on the DeviceType.
  • payload (dict | None): Command payload. Validated against the Command's schema.
  • broker_name (str): Which broker to publish through. Default: "default".

Raises:

  • ValueError if the device has no associated DeviceType, or the command name is unknown, or payload validation fails.
  • TypeError if a payload value has the wrong type.

Side effects:

  • Publishes a JSON message to {prefix}/{type}/{device_id}/cmd
  • Fires the device_command_sent signal
device.send_command("reboot")
device.send_command("set_interval", {"interval": 60})

Generated device models have these reverse relations:

  • device.readings -- QuerySet of Reading instances (ForeignKey related_name)
  • device.messages -- QuerySet of Message instances (ForeignKey related_name)

DeviceStatus

from django_devicehub.models import DeviceStatus

TextChoices enum for device status values.

Value Label
"online" Online
"offline" Offline
"error" Error
"maintenance" Maintenance
"low_battery" Low Battery
"provisioning" Provisioning

BaseReading

from django_devicehub.models import BaseReading

Abstract base for all generated reading models. Each Reading field declared on the DeviceType becomes a nullable column.

Fields

Field Type Description
device ForeignKey Reference to the device. Related name: "readings".
timestamp DateTimeField Data point timestamp. Indexed.
received_at DateTimeField Server receive time. Auto-set.

Plus one nullable column per Reading declared on the DeviceType.

Meta

  • abstract = True
  • ordering = ["-timestamp"]
  • Composite index on (device, timestamp) on generated models

Methods

__str__()

Returns "Reading at {timestamp}".


ProcessingStatus

from django_devicehub.models import ProcessingStatus

TextChoices enum for message processing status.

Value Label
"pending" Pending
"processing" Processing
"completed" Completed
"failed" Failed

BaseMessage

from django_devicehub.models import BaseMessage

Abstract base for raw message storage. Every MQTT message received by the MessageRouter is stored as a Message record for audit and debugging.

Fields

Field Type Description
device ForeignKey Reference to the device. Related name: "messages".
topic CharField(512) MQTT topic the message was received on.
payload_json JSONField Parsed JSON payload. Nullable.
payload_raw BinaryField Raw binary payload. Nullable.
content_type CharField(100) MQTT 5 content type property.
correlation_id CharField(256) MQTT 5 correlation data.
user_properties JSONField MQTT 5 user properties dict. Default: {}.
processing_status CharField(20) Processing state. Choices from ProcessingStatus. Default: "pending". Indexed.
processing_error TextField Error message if processing failed.
received_at DateTimeField Server receive time. Auto-set.
processed_at DateTimeField When processing completed. Nullable.

Meta

  • abstract = True
  • ordering = ["-received_at"]

Methods

__str__()

Returns "Message on {topic} ({processing_status})".


mark_completed()

Set processing_status to "completed" and processed_at to now.


mark_failed(error="")

Set processing_status to "failed", store the error message, and set processed_at to now.

Parameters:

  • error (str): Error description.

Generated Model Naming

For a DeviceType named WeatherStation, the generated models are:

Model Class name Default table name
Device WeatherStationDevice {app_label}_weatherstationdevice
Reading WeatherStationReading {app_label}_weatherstationreading
Message WeatherStationMessage {app_label}_weatherstationmessage

The verbose_name is derived from the CamelCase class name: "Weather Station", "Weather Station Reading", "Weather Station Message".

Each generated model has __module__ set to the module that called create_models(), so Django's migration system places it in the correct app.