API Reference: DeviceType¶
django_devicehub.device_type
¶
DeviceType
¶
Base class for declaring IoT device types.
Usage::
# devices.py
from django_devicehub import DeviceType, Reading, Command, reading_types
class WeatherStation(DeviceType):
class Meta:
protocol = "mqtt"
broker = "default"
heartbeat_interval = 300
temperature = Reading(type=reading_types.FLOAT, unit="C")
humidity = Reading(type=reading_types.FLOAT, unit="%")
reboot = Command()
set_interval = Command(payload={"interval": int})
# models.py
from .devices import WeatherStation
WeatherStationDevice, WeatherStationReading, WeatherStationMessage = (
WeatherStation.create_models()
)
create_models(module=None)
classmethod
¶
Generate concrete Django models for this DeviceType.
Call this in your app's models.py. Returns (DeviceModel, ReadingModel, MessageModel).
get_meta()
classmethod
¶
Get Meta configuration with defaults.
get_subscribe_topics()
classmethod
¶
Get MQTT topic patterns to subscribe to (with + wildcards).
get_topic(device_id, message_type='data')
classmethod
¶
Generate the MQTT topic for a specific device and message type.
on_command_response(device, command, response)
¶
Called when a device responds to a command.
on_connect(device)
¶
Called when a device connects.
on_data(device, readings)
¶
Called when a device sends data readings.
on_disconnect(device)
¶
Called when a device disconnects or heartbeat times out.
on_status_change(device, old_status, new_status)
¶
Called when a device status changes.
DeviceTypeMeta
¶
Bases: type
Metaclass that collects Reading, Command, and StateField descriptors from the class namespace and stores them as _readings, _commands, _state_fields.
DeviceType¶
Base class for declaring IoT device types. Uses DeviceTypeMeta metaclass to collect descriptors and auto-register in the global registry.
Class Attributes¶
| Attribute | Type | Description |
|---|---|---|
_readings |
dict[str, Reading] |
Collected Reading descriptors (set by metaclass) |
_commands |
dict[str, Command] |
Collected Command descriptors (set by metaclass) |
_state_fields |
dict[str, StateField] |
Collected StateField descriptors (set by metaclass) |
_device_model |
type | None |
Generated Device model class (set by create_models()) |
_reading_model |
type | None |
Generated Reading model class (set by create_models()) |
_message_model |
type | None |
Generated Message model class (set by create_models()) |
Inner Class: Meta¶
Optional configuration class. All attributes have defaults.
class WeatherStation(DeviceType):
class Meta:
protocol = "mqtt"
broker = "default"
auth = "token"
heartbeat_interval = 300
topic_template = "{prefix}/{type_name}/{device_id}/{message_type}"
| Attribute | Type | Default | Description |
|---|---|---|---|
protocol |
str |
"mqtt" |
Communication protocol identifier |
broker |
str |
"default" |
Named broker from DJANGO_DEVICEHUB["BROKERS"] |
auth |
str |
"token" |
Authentication mechanism |
heartbeat_interval |
int |
300 |
Expected heartbeat interval in seconds |
topic_template |
str |
"{prefix}/{type_name}/{device_id}/{message_type}" |
MQTT topic format string |
Class Methods¶
create_models(module=None)¶
Generate concrete Django models for this DeviceType.
Parameters:
module(str | None): The module name to assign to generated models. IfNone, auto-detected from the caller's stack frame (inspect.currentframe().f_back).
Returns: tuple[type, type, type] -- (DeviceModel, ReadingModel, MessageModel)
# myapp/models.py
from .devices import WeatherStation
WeatherStationDevice, WeatherStationReading, WeatherStationMessage = (
WeatherStation.create_models()
)
The generated models have __module__ set to the calling module, so Django's migration system discovers them in the correct app.
get_meta()¶
Get Meta configuration merged with defaults.
Returns: dict with keys: protocol, broker, auth, heartbeat_interval, topic_template.
meta = WeatherStation.get_meta()
# {'protocol': 'mqtt', 'broker': 'default', 'auth': 'token',
# 'heartbeat_interval': 300, 'topic_template': '...'}
get_topic(device_id, message_type="data")¶
Generate the MQTT topic for a specific device and message type.
Parameters:
device_id(str): The device identifier.message_type(str): Channel name. Default:"data".
Returns: str -- the full MQTT topic.
WeatherStation.get_topic("STATION-001", "data")
# "myproject/weatherstation/STATION-001/data"
WeatherStation.get_topic("STATION-001", "cmd")
# "myproject/weatherstation/STATION-001/cmd"
get_subscribe_topics()¶
Get MQTT topic patterns to subscribe to, using + wildcards for device_id.
Returns: list[str] -- two topic patterns (data and status).
WeatherStation.get_subscribe_topics()
# ["myproject/weatherstation/+/data", "myproject/weatherstation/+/status"]
Instance Methods (Hooks)¶
Override these in subclasses to add custom behavior. They are called by the MessageRouter after signals are fired.
on_data(self, device, readings)¶
Called when a device sends data readings.
Parameters:
device: Device model instance.readings(dict): Field name to value mapping.
on_status_change(self, device, old_status, new_status)¶
Called when a device status changes.
Parameters:
device: Device model instance.old_status(str): Previous status value.new_status(str): Current status value.
on_connect(self, device)¶
Called when a device connects.
Parameters:
device: Device model instance.
on_disconnect(self, device)¶
Called when a device disconnects or heartbeat times out.
Parameters:
device: Device model instance.
on_command_response(self, device, command, response)¶
Called when a device responds to a command.
Parameters:
device: Device model instance.command(str): Command name.response: Response data from the device.
DeviceTypeMeta¶
Metaclass for DeviceType. You do not use this directly -- it operates automatically when a class inherits from DeviceType.
Behavior¶
- Inherits
_readings,_commands,_state_fieldsfrom base classes - Scans the class namespace for
Reading,Command,StateFieldinstances - Removes descriptors from the namespace and stores them in class dicts
- Sets each descriptor's
.nameattribute - Calls
registry.register(cls)for non-base, non-abstract classes
Abstract device types¶
Set _abstract = True to prevent registration:
class BaseSensor(DeviceType):
_abstract = True
battery = Reading(type=reading_types.FLOAT, unit="%")
DeviceTypeRegistry¶
Global singleton registry of device types and their models.
Methods¶
| Method | Returns | Description |
|---|---|---|
register(cls) |
None |
Register a DeviceType class. Raises RegistryError on name conflict. |
register_models(cls, device, reading, message) |
None |
Register generated models for a DeviceType. |
get(name) |
DeviceType | None |
Look up by name (case-insensitive). |
get_models(name) |
tuple | None |
Get (DeviceModel, ReadingModel, MessageModel) by name. |
get_by_device_model(model) |
DeviceType | None |
Find the DeviceType that owns a device model class. |
all() |
list[DeviceType] |
All registered DeviceType classes. |
all_with_models() |
list[tuple] |
All (DeviceType, DeviceModel, ReadingModel, MessageModel) tuples. |
clear() |
None |
Clear the registry (for testing). |
Dunder methods¶
| Method | Description |
|---|---|
len(registry) |
Number of registered types |
"name" in registry |
Check if a name is registered (case-insensitive) |