Doover Device Services
Doover Device Services (DDS) is the suite of containerized services that run on Doover devices to enable cloud connectivity, application management, and hardware abstraction. These services are pre-installed on Doover devices and start automatically on boot.
Service Overview
DDS consists of two categories of services: core services and bridge services.
Core Services
| Service | Port | Description |
|---|---|---|
| Device Agent (DDA) | 50051 | Cloud connectivity and channel management |
| App Controller | 50052 | Application lifecycle and deployment management |
Bridge Services
| Service | Port | Description |
|---|---|---|
| platform_iface | 50053 | Hardware I/O abstraction |
| modbus_iface | 50054 | Modbus communication |
| camera_iface | 50050 | RTSP camera support |
Management Services
| Service | Description |
|---|---|
| Host Configurator | Device configuration and system updates |
Device Agent (DDA)
The Device Agent is the primary service for cloud connectivity. It maintains a persistent connection to the Doover cloud and handles all data synchronization.
Responsibilities
- Cloud Connection - Establishes and maintains WebSocket connection to the Doover cloud
- Channel Management - Manages subscriptions and publishes data to channels
- Data Buffering - Queues data when offline and syncs when connection is restored
- Authentication - Handles device authentication and token management
- Configuration Sync - Receives deployment configurations from the cloud
Application Interaction
Your application interacts with DDA through the DeviceAgentInterface:
from pydoover.docker import Application, run_app
from pydoover.config import Schema
class MyApp(Application):
def setup(self):
# Check DDA status
if self.device_agent.get_is_dda_available():
print("DDA is running")
if self.device_agent.get_is_dda_online():
print("Connected to cloud")
# Subscribe to channels
self.device_agent.add_subscription(
"deployment_config",
self.on_config_update
)
async def on_config_update(self, channel_name, data):
print(f"Config updated: {data}")
def main_loop(self):
# Publish telemetry
self.device_agent.publish_to_channel("telemetry", {
"temperature": self.platform_iface.get_system_temperature(),
"voltage": self.platform_iface.get_system_voltage()
})
if __name__ == "__main__":
run_app(MyApp(config=Schema()))
Standard Channels
DDA manages several standard channels:
| Channel | Direction | Description |
|---|---|---|
| deployment_config | Cloud to Device | Application deployment configuration |
| tag_values | Bidirectional | Shared tag values between applications |
| ui_state | Bidirectional | User interface state |
| cmds | Cloud to Device | Commands from the cloud |
App Controller
The App Controller manages application lifecycle, including starting, stopping, and updating application containers.
Responsibilities
- Container Management - Starts and stops application containers
- Health Monitoring - Monitors application health and restarts failed containers
- Deployment Scheduling - Schedules deployments based on cloud configuration
- Resource Management - Manages container resources and limits
Deployment Scheduling
The App Controller supports scheduled deployments. Your application receives shutdown notifications and can request delays:
class SafeShutdownApp(Application):
async def on_shutdown_at(self, shutdown_time):
"""Called when a shutdown is scheduled."""
print(f"Shutdown scheduled for {shutdown_time}")
# Prepare for shutdown
await self.save_state()
async def check_can_shutdown(self) -> bool:
"""Called to verify if shutdown can proceed."""
# Return False to delay shutdown
if self.is_critical_operation_running:
return False
return True
Platform Interface Bridge
The platform_iface bridge provides hardware abstraction for the device's built-in I/O.
Capabilities
- Digital input reading with edge detection
- Digital output control with scheduling
- Analog input reading
- Analog output control with scheduling
- Pulse counting for flow meters and encoders
- System metrics (voltage, power, temperature)
- GPS location (on devices with 4G modems)
Container Configuration
The platform_iface container is configured based on the device type. Environment variables control which hardware drivers to load:
environment: - DEVICE_TYPE=doovit - PLT_IFACE_TYPE=platform_iface
Application Interaction
# Read all I/O
io_table = self.platform_iface.get_io_table()
print(f"Digital Inputs: {io_table.get('di')}")
print(f"Digital Outputs: {io_table.get('do')}")
print(f"Analog Inputs: {io_table.get('ai')}")
print(f"Analog Outputs: {io_table.get('ao')}")
# System monitoring
voltage = self.platform_iface.get_system_voltage()
temp = self.platform_iface.get_system_temperature()
power = self.platform_iface.get_system_power()
Modbus Interface Bridge
The modbus_iface bridge handles Modbus communication, supporting both RTU (serial) and TCP connections.
Capabilities
- Modbus RTU over serial ports
- Modbus TCP over Ethernet
- Multiple simultaneous bus connections
- Automatic reconnection
- Polling subscriptions with callbacks
Container Configuration
environment: - MODBUS_DEFAULT_PORT=/dev/ttyAMA0 - MODBUS_DEFAULT_BAUD=9600
Application Interaction
# Open a TCP bus to a Moxa slave
self.modbus_iface.open_bus(
bus_type="tcp",
name="remote_io",
tcp_uri="192.168.1.10:502"
)
# Read registers
values = self.modbus_iface.read_registers(
bus_id="remote_io",
modbus_id=1,
start_address=0,
num_registers=10,
register_type=3 # Input registers
)
Camera Interface Bridge
The camera_iface bridge manages RTSP camera connections for snapshot capture and streaming.
Capabilities
- RTSP camera streaming
- Snapshot capture
- Dahua camera integration
- Power management for PoE cameras
See Camera Interface for detailed documentation.
Host Configurator
The Host Configurator manages device-level configuration and system updates.
Responsibilities
- Network Configuration - Manages network interfaces and connectivity
- System Updates - Handles firmware and system package updates
- Device Registration - Manages device identity and registration
- Diagnostic Collection - Gathers system diagnostics for troubleshooting
Volume Mounts and Persistent Storage
DDS services use persistent storage for data that must survive container restarts.
Standard Paths
| Path | Description |
|---|---|
| /var/lib/dds/ | Root directory for DDS persistent data |
| /var/lib/dds/dda/ | Device Agent data and queue storage |
| /var/lib/dds/config/ | Device configuration |
| /var/lib/dds/apps/ | Application data directories |
Application Data
Applications can store persistent data in their designated directory:
import os
class MyApp(Application):
def setup(self):
# Get application data directory
data_dir = os.environ.get("APP_DATA_DIR", "/var/lib/dds/apps/myapp")
# Store persistent data
self.state_file = os.path.join(data_dir, "state.json")
Service Dependencies
Services have dependencies that determine startup order:
Host Configurator (starts first)
|
+-- Device Agent (DDA)
| |
| +-- App Controller
| |
| +-- Application Containers
|
+-- Platform Interface
+-- Modbus Interface
+-- Camera Interface
Applications should handle cases where bridge services are not yet available:
def setup(self):
# Wait for DDA to be available
if not self.device_agent.await_dda_available(timeout=30):
print("Warning: DDA not available, running in offline mode")
# Test platform interface connection
response = self.platform_iface.test_comms()
if response is None:
print("Warning: Platform interface not responding")
Monitoring and Troubleshooting
Checking Service Status
From a device shell:
# List running containers docker ps # Check DDA logs docker logs dda # Check platform interface logs docker logs platform_iface # Check application logs docker logs my-app
Common Issues
DDA Not Connecting
- Check network connectivity
- Verify device registration
- Check DDA logs for authentication errors
Platform Interface Not Responding
- Verify the device type is correctly configured
- Check for hardware driver issues
- Review platform_iface container logs
Application Not Starting
- Check App Controller logs
- Verify container image is available
- Check deployment configuration in the cloud
Next Steps
- Device Bridges Overview - Bridge architecture details
- Supported Hardware - Hardware platform details
- Camera Interface - Camera service documentation
- DeviceAgentInterface - DDA API reference