Mobivisor Integration Roadmap & Architecture¶
Status: Draft
Target Audience: Consortium Members (Dealdio, Brunel OpenSim), Developers
Goal: Achieve seamless, vendor-agnostic integration between HOMEPOT and Mobivisor.
1. Executive Summary¶
HOMEPOT Client is built on a Modular Framework designed to support multiple device management APIs. While it provides a robust "Generic API" out of the box, its architecture allows for plug-and-play integration with external providers like Mobivisor.
The goal of this roadmap is to evolve the current Mobivisor integration from a simple "Proxy" model to a full "Platform Integration." This will allow HOMEPOT users to leverage core features (Analytics, Jobs, AI Agents) on Mobivisor-managed devices while ensuring the HOMEPOT Generic API remains independent and robust.
Key Principles: 1. Modular Architecture: The system uses an Adapter pattern to support any external provider (Mobivisor, Azure IoT, etc.) without changing core code. 2. Vendor Isolation: The core system must not depend on Mobivisor availability. 3. Seamless Experience: Users should see a unified list of devices, regardless of source. 4. Graceful Degradation: If the external service is removed, local data remains accessible.
2. Architecture Strategy¶
2.1 The "Shadow Device" Concept¶
To enable HOMEPOT features on external devices, we will "sync" them into the local database as Shadow Records.
- Local Devices: Managed fully by HOMEPOT.
- Shadow Devices: Managed by Mobivisor, but mirrored in HOMEPOT for analytics and reporting.
2.2 Database Schema (Vendor-Agnostic)¶
We will avoid adding vendor-specific columns (e.g., mobivisor_id) to the core devices table. Instead, we use a generic approach.
Proposed Schema Changes:
class Device(Base):
# ... existing fields ...
# Source of the device record
source = Column(String(20), default="LOCAL") # Enum: 'LOCAL', 'EXTERNAL'
# Generic container for external provider details
# Example: {"provider": "mobivisor", "external_id": "12345", "sync_status": "active"}
integration_metadata = Column(JSON, nullable=True)
2.3 The Adapter Pattern¶
The backend will use an Interface/Adapter pattern to communicate with external providers. This ensures the core logic (Orchestrator) never imports Mobivisor-specific code directly.
Interface Definition:
class ExternalDeviceProvider(ABC):
@abstractmethod
async def sync_devices(self) -> List[DeviceData]:
"""Fetch all devices from external source."""
pass
@abstractmethod
async def execute_command(self, device_id: str, command: str, params: Dict) -> bool:
"""Execute a command (e.g., reboot, lock) on the external device."""
pass
3. Implementation Roadmap¶
Phase 1: Foundation (Database & Models)¶
- Task 1.1: Create migration to add
sourceandintegration_metadatacolumns todevicestable. - Task 1.2: Update Pydantic models to include these new fields.
- Task 1.3: Implement
ExternalDeviceProviderabstract base class.
Phase 2: The Mobivisor Adapter¶
- Task 2.1: Implement
MobivisorAdapterclass that wraps the existingMobivisorDeviceEndpointslogic. - Task 2.2: Implement
sync_devices()method to fetch from Mobivisor API and map toDeviceData. - Task 2.3: Implement
execute_command()to translate HOMEPOT jobs into Mobivisor actions.
Phase 3: Synchronization Engine¶
- Task 3.1: Create a background task (Celery or asyncio) that runs periodically (e.g., every 15 mins).
- Task 3.2: Implement "Upsert" logic:
- If device exists (match by
external_idin metadata), update status/details. - If new, create with
source='EXTERNAL'. - If deleted in Mobivisor, mark as
status='ARCHIVED'locally.
- If device exists (match by
Phase 4: Frontend Unification¶
- Task 4.1: Update
SitesList.jsxto display a "Source" badge (Local vs. Mobivisor). - Task 4.2: Update
DeviceDetail.jsxto conditionally render tabs:- Local: Show standard config, direct shell access.
- Mobivisor: Show "Policies", "System Apps", "Kiosk Mode" (fetched via Proxy API).
4. Configuration & Safety¶
Feature Flags¶
The integration must be toggleable via environment variables to ensure the Generic API can run standalone.
# .env
ENABLE_EXTERNAL_INTEGRATION=true
EXTERNAL_PROVIDER=mobivisor
MOBIVISOR_API_URL=https://api.mobivisor.com
MOBIVISOR_API_TOKEN=xyz...
Error Handling¶
- If the Sync Task fails (e.g., API down), log the error but do not crash the application.
- UI should show a "Sync Warning" if data is stale (> 1 hour).
5. Developer Guidelines¶
- Do not import Mobivisor modules in
orchestrator.pyoragents.py. Use the Adapter interface. - Keep the
devicestable clean. Put all vendor-specific data inintegration_metadata. - Test with the Flag OFF. Ensure the system passes all tests when
ENABLE_EXTERNAL_INTEGRATION=false.