Skip to content

Code Structure

Rin Nguyen edited this page Jun 18, 2026 · 1 revision

Matterbridge Roborock Vacuum Plugin - Code Structure

Version: 1.1.7-rc01 Last Updated: June 12, 2026 Test Coverage: 1911+ tests passed (177 test files)


Table of Contents

  1. Overview
  2. Architecture Patterns
  3. Dependency Tree
  4. Directory Structure
  5. Core Components
  6. Platform Layer
  7. Core Domain Layer
  8. Service Layer
  9. Communication Layer
  10. Behavior System
  11. Error Handling & Plugin Models
  12. CLI Tool
  13. Shared Utilities
  14. Data Flow
  15. Key Design Patterns
  16. Testing Strategy

Overview

This plugin integrates Roborock vacuum cleaners into the Matter ecosystem via Matterbridge. It enables control through Apple Home and other Matter-compatible applications.

Key Technologies:

  • TypeScript 5.x targeting ESNext
  • Matterbridge 3.7.3
  • Vitest for unit testing
  • MQTT for real-time device communication
  • REST API for Roborock cloud services

Main Entry Point: src/module.ts


Architecture Patterns

1. Layered Architecture

┌─────────────────────────────────────────┐
│   Matter Protocol Layer (Matterbridge)  │
├─────────────────────────────────────────┤
│   Platform Layer (module.ts + platform/)│
├─────────────────────────────────────────┤
│   Service Layer (services/)             │
├─────────────────────────────────────────┤
│   Core Domain Layer (core/)             │
├─────────────────────────────────────────┤
│   Behavior Layer (behaviors/)           │
├─────────────────────────────────────────┤
│   Communication Layer (roborockComm/)   │
├─────────────────────────────────────────┤
│   Roborock IoT Platform                 │
└─────────────────────────────────────────┘

2. Hexagonal Architecture (Ports & Adapters)

  • Ports: Interfaces in core/ports/ (IDeviceGateway, IAuthGateway)
  • Adapters: Implementations in roborockCommunication/adapters/
  • Clear separation between domain logic and infrastructure

3. Dependency Injection

  • services/ServiceContainer manages service lifecycle
  • core/ServiceContainer manages port adapters
  • Services are lazy-loaded singletons
  • Facilitates testing and modularity

4. Facade Pattern

  • RoborockService acts as facade over specialized services
  • Maintains backward compatibility
  • Reduced from 923 lines to ~300 lines

Dependency Tree

This tree visualizes the dependency flow starting from src/module.ts and reflects the latest code structure:

src/module.ts (RoborockMatterbridgePlatform)
│
├── Platform Layer (platform/)
│   ├── platformConfig.ts         # Validates and manages plugin configuration
│   ├── deviceRegistry.ts         # Stores registered devices and robots
│   ├── platformState.ts          # Tracks platform and startup state
│   ├── deviceDiscovery.ts        # Authentication, API calls, device filtering
│   └── deviceConfigurator.ts     # Device setup, room mapping, Matterbridge registration
│
├── platformRunner.ts             # Orchestrates device updates and message routing (~80 LOC, dispatcher only)
│   └── uses: runtimes/
│       ├── handleLocalMessage.ts
│       ├── handleCloudMessage.ts
│       ├── handleHomeDataMessage.ts
│       └── handlers/              # Pure exported handler functions (extracted from PlatformRunner)
│           ├── serviceAreaHandler.ts   # handleServiceAreaUpdate + area resolution helpers
│           ├── errorStateHandler.ts    # handleErrorOccurred
│           ├── deviceStateHandler.ts   # handleDeviceStatusUpdate (returns bool), handleDeviceStatusSimpleUpdate
│           ├── batteryStateHandler.ts  # handleBatteryUpdate
│           └── cleanModeHandler.ts     # handleCleanModeUpdate
│
├── services/ (Service Layer)
│   ├── serviceContainer.ts       # Main DI container for services
│   ├── roborockService.ts        # Service facade
│   ├── authenticationService.ts
│   ├── authentication/           # Auth strategies (Coordinator, Password, 2FA, etc.)
│   ├── deviceManagementService.ts
│   ├── areaManagementService.ts
│   ├── messageRoutingService.ts
│   ├── pollingService.ts
│   ├── connectionService.ts
│   ├── emailNotificationService.ts
│   └── clientManager.ts          # Manages MQTT client instances
│
├── core/ (Core Domain Layer)
│   ├── ServiceContainer.ts       # Port adapter DI container
│   ├── application/              # Application layer
│   │   └── models/               # Application models (MapInfo, MapRoom, RoomMap, etc.)
│   ├── domain/                   # Domain layer
│   │   ├── entities/             # Domain entities (Device, Home, Room)
│   │   └── value-objects/        # Value objects (DeviceId, CleanMode)
│   └── ports/                    # Port interfaces
│       ├── IDeviceGateway.ts
│       └── IAuthGateway.ts
│
├── services/roborockService.ts (Facade)
│   └── Uses: services/serviceContainer.ts
│        └── Uses: core/ServiceContainer.ts
│            ├── IAuthGateway → roborockCommunication/adapters/RoborockAuthGateway
│            │      └── roborockCommunication/api/authClient.ts (RoborockAuthenticateApi)
│            └── IDeviceGateway → roborockCommunication/adapters/RoborockDeviceGateway
│                   └── roborockCommunication/routing/clientRouter.ts (ClientRouter)
│                        ├── roborockCommunication/mqtt/mqttClient.ts (MQTTClient)
│                        └── roborockCommunication/local/localClient.ts (LocalNetworkClient)
│
├── behaviors/ (Behavior Layer)
│   ├── BehaviorDeviceGeneric.ts
│   └── roborock.vacuum/
│       ├── core/                 # Core behavior logic
│       ├── handlers/             # Mode handlers
│       ├── enums/                # Behavior enums
│       └── b01/                  # Protocol-specific behaviors
│
└── roborockCommunication/ (Communication Layer)
    ├── adapters/                # Port adapter implementations
    ├── api/                     # REST API clients
    ├── enums/                   # Enumerations
    ├── helper/                  # Helper utilities
    ├── local/                   # Local network clients
    ├── models/                  # Data models and DTOs
    │   └── home/                # Home/room DTOs and mappers
    ├── mqtt/                    # MQTT communication
    ├── protocol/                # Protocol handling
    │   ├── builders/            # Message builders
    │   ├── serializers/         # Message serializers
    │   ├── deserializers/       # Message deserializers
    │   └── dispatcher/          # Message dispatchers
    └── routing/                 # Message routing
        ├── handlers/            # Message handlers
        └── listeners/           # Message listeners

Key Relationships:

  • src/module.ts is the entry point and wires up the platform, service, and core layers.
  • The platform/ directory encapsulates platform-specific logic and state.
  • The services/ directory provides business logic and orchestrates communication between platform, core, and communication layers.
  • The core/ directory defines domain models and port interfaces, with adapters implemented in roborockCommunication/adapters/.
  • The roborockService.ts acts as a facade, exposing a unified API to the rest of the platform.
  • The roborockCommunication/ directory contains all communication logic, including MQTT, local, and protocol-specific code.

Detailed Service Dependencies

┌─────────────────────────────────────────────────────────────────────────┐
│                     MODULE.TS (Entry Point)                             │
│                   RoborockMatterbridgePlatform                          │
└─────────────────────────────┬───────────────────────────────────────────┘
                              │
        ┌─────────────────────┼─────────────────────┐
        │                     │                     │
        ▼                     ▼                     ▼
┌──────────────────┐  ┌──────────────────┐  ┌──────────────────────────┐
│ Platform Layer   │  │ PlatformRunner   │  │  RoborockService         │
│  (platform/)     │  │                  │  │     (Facade)             │
├──────────────────┤  ├──────────────────┤  ├──────────────────────────┤
│• platformConfig  │  │• updateRobot()   │  │• authenticate()          │
│• deviceRegistry  │  │• requestHomeData │  │• listDevices()           │
│• platformState   │  │                  │  │• initMessageClient()     │
│• deviceDiscovery │  │  Uses runtimes/: │  │• startClean/pause/dock   │
│• deviceConfig    │
└──────────────────┘  │  ├ handleLocal   │  │• getMapInformation()     │
                      │  ├ handleCloud   │  └────────┬─────────────────┘
                      │  └ handleHomeData│           │
                      └──────────────────┘           │
                                                     │
                                                     ▼
┌─────────────────────────────────────────────────────────────────────────┐
│                    SERVICE CONTAINER (DI)                               │
│                    services/serviceContainer.ts                         │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│  ┌──────────────────────┐    ┌──────────────────────┐                  │
│  │ Authentication       │    │ DeviceManagement     │                  │
│  │ Service              │    │ Service              │                  │
│  ├──────────────────────┤    ├──────────────────────┤                  │
│  │• authenticate2FA()   │    │• listDevices()       │                  │
│  │• authenticatePass()  │    │• getHomeData()       │                  │
│  │• requestCode()       │    │• stopService()       │                  │
│  └──────┬───────────────┘    └───────┬──────────────┘                  │
│         │                            │                                 │
│         │                            ▼                                 │
│         │                    ┌─────────────────────────────┐           │
│         │                    │  core/ServiceContainer      │           │
│         │                    │  (Port Adapter DI)          │           │
│         │                    ├─────────────────────────────┤           │
│         │                    │ IDeviceGateway →            │           │
│         │                    │   RoborockDeviceGateway     │           │
│         │                    │     └→ ClientRouter         │           │
│         │                    └─────────────────────────────┘           │
│         │                                                              │
│         ▼                                                              │
│  ┌────────────────────────────────┐                                    │
│  │ core/ports/IAuthGateway        │                                    │
│  │        ↓                       │                                    │
│  │ adapters/RoborockAuthGateway   │                                    │
│  │        ↓                       │                                    │
│  │ api/authClient.ts              │                                    │
│  └────────────────────────────────┘                                    │
│                                                                         │
│  ┌──────────────────────┐    ┌──────────────────────┐                  │
│  │ AreaManagement       │    │ MessageRouting       │                  │
│  │ Service              │    │ Service              │                  │
│  ├──────────────────────┤    ├──────────────────────┤                  │
│  │• setAreas()          │    │• getClient()         │                  │
│  │• getMapInfo()        │    │• sendRequest()       │                  │
│  │• getRoomMap()        │    │• subscribe()         │                  │
│  └──────────────────────┘    └──────────────────────┘                  │
│                                                                         │
│  ┌──────────────────────┐    ┌──────────────────────┐                  │
│  │ Connection           │    │ Polling              │                  │
│  │ Service              │    │ Service              │                  │
│  ├──────────────────────┤    ├──────────────────────┤                  │
│  │• initMessageClient() │◄───│• activateNotify()    │                  │
│  │• initLocal()         │    │• stopPolling()       │                  │
│  │• setNotify()         │    └──────────────────────┘                  │
│  └──────┬───────────────┘                                              │
│         │                                                              │
│         ▼                                                              │
│  ┌────────────────────────────────┐                                    │
│  │ services/clientManager.ts      │                                    │
│  │ • getClient(duid)              │                                    │
│  │ • createClient(device)         │                                    │
│  │ • disposeClient(duid)          │                                    │
│  └────────────┬───────────────────┘                                    │
└───────────────┼────────────────────────────────────────────────────────┘
                │
                ▼
┌─────────────────────────────────────────────────────────────────────────┐
│                      COMMUNICATION LAYER                                │
│                   roborockCommunication/                                │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│  ┌──────────────────────────────────────────────────────────────────┐  │
│  │              routing/clientRouter.ts (ClientRouter)              │  │
│  │  • route(device) → MQTTClient | LocalNetworkClient               │  │
│  │  • sendRequest(device, command, params)                          │  │
│  └──────────────┬─────────────────────────────────────┬─────────────┘  │
│                 │                                     │                │
│                 ▼                                     ▼                │
│  ┌──────────────────────────┐        ┌──────────────────────────────┐ │
│  │ mqtt/mqttClient.ts       │        │ local/localClient.ts         │ │
│  │ (MQTTClient)             │        │ (LocalNetworkClient)         │ │
│  ├──────────────────────────┤        ├──────────────────────────────┤ │
│  │• Cloud MQTT connection   │        │• TCP local connection        │ │
│  │• TLS encrypted           │        │• Low latency                 │ │
│  │• Auto-reconnect          │        │• Uses local/udpClient.ts     │ │
│  │• Subscribe to topics     │        │  for discovery               │ │
│  └──────────┬───────────────┘        └──────────┬───────────────────┘ │
│             │                                   │                     │
│             └───────────────┬───────────────────┘                     │
│                             ▼                                         │
│  ┌──────────────────────────────────────────────────────────────────┐ │
│  │           mqtt/messageProcessor.ts (MessageProcessor)            │ │
│  │  Deserialize → Validate → Route to Message Listeners             │ │
│  └──────────────────────────────────────────────────────────────────┘ │
│                             │                                         │
│                             ▼                                         │
│  ┌──────────────────────────────────────────────────────────────────┐ │
│  │                     routing/listeners/                           │ │
│  │  • simpleMessageListener.ts                                      │ │
│  │  • syncMessageListener.ts                                        │ │
│  │  • connectionStateListener.ts                                    │ │
│  │  • mapResponseListener.ts                                        │ │
│  │  • statusMessageListener.ts                                      │ │
│  └──────────────────────────────────────────────────────────────────┘ │
│                                                                         │
│  ┌──────────────────────────────────────────────────────────────────┐  │
│  │                     protocol/ (Protocol Layer)                   │  │
│  │                                                                  │  │
│  │  builders/              serializers/           dispatcher/      │  │
│  │  ├ L01MessageBuilder     ├ L01Serializer       ├ Q7Dispatcher   │  │
│  │  ├ A01MessageBuilder     ├ A01Serializer       ├ Q10Dispatcher  │  │
│  │  ├ B01MessageBuilder     ├ B01Serializer       ├ V01Dispatcher  │  │
│  │  └ V01MessageBuilder     └ V01Serializer       └ ...            │  │
│  │                                                                  │  │
│  │  deserializers/                                                 │  │
│  │  └ messageDeserializer.ts                                       │  │
│  └──────────────────────────────────────────────────────────────────┘  │
│                                                                         │
│  ┌──────────────────────────────────────────────────────────────────┐  │
│  │                     api/ (REST API Layer)                        │  │
│  │  • authClient.ts (RoborockAuthenticateApi)                       │  │
│  │    - sendEmailCode(), loginWithCode(), loginWithPassword()       │  │
│  │  • iotClient.ts (RoborockIoTApi)                                 │  │
│  │    - getHomeData(), getDeviceList(), getScenes()                 │  │
│  └──────────────────────────────────────────────────────────────────┘  │
│                                                                         │
│  ┌──────────────────────────────────────────────────────────────────┐  │
│  │                  models/home/ (DTOs & Mappers)                   │  │
│  │  • MapDataDto, MapRoomDto, MultipleMapDto, RoomDto               │  │
│  │  • mappers.ts (HomeModelMapper)                                  │  │
│  │    - API DTO → Application Model transformation                  │  │
│  └──────────────────────────────────────────────────────────────────┘  │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

Legend:
  ──────►  Direct dependency / calls
  │       Component boundary
  ┌─────┐ Module/Component

Directory Structure

Root Structure

src/
├── module.ts                    # Main platform entry point
├── platformRunner.ts            # Orchestrates device updates
├── settings.ts                  # Plugin configuration
│
├── platform/                    # Platform layer
│   ├── platformConfig.ts        # Config validation
│   ├── platformState.ts         # State management
│   ├── deviceRegistry.ts        # Device/robot registry
│   ├── deviceDiscovery.ts       # Authentication, API calls, device filtering
│   └── deviceConfigurator.ts    # Device setup, room mapping, registration
│
├── core/                        # Core domain layer
│   ├── ServiceContainer.ts      # Port adapter DI container
│   ├── application/             # Application layer
│   │   └── models/
│   │       ├── MapInfo.ts
│   │       ├── MapRoom.ts
│   │       ├── RoomIndexMap.ts
│   │       ├── RoomMap.ts
│   │       ├── RoomMapping.ts
│   │       └── index.ts
│   ├── domain/                  # Domain layer
│   │   ├── entities/
│   │   │   ├── Device.ts
│   │   │   ├── Home.ts
│   │   │   └── Room.ts
│   │   └── value-objects/
│   │       ├── DeviceId.ts
│   │       └── CleanMode.ts
│   └── ports/                   # Port interfaces
│       ├── IDeviceGateway.ts
│       └── IAuthGateway.ts
│
├── services/                    # Service layer
│   ├── serviceContainer.ts      # Main DI container
│   ├── roborockService.ts       # Service facade
│   ├── authenticationService.ts
│   ├── authentication/          # Authentication strategies
│   │   ├── AuthContext.ts
│   │   ├── AuthenticationCoordinator.ts
│   │   ├── AuthenticationStateRepository.ts
│   │   ├── BaseAuthStrategy.ts
│   │   ├── IAuthStrategy.ts
│   │   ├── PasswordAuthStrategy.ts
│   │   ├── TwoFactorAuthStrategy.ts
│   │   ├── UserDataRepository.ts
│   │   └── VerificationCodeService.ts
│   ├── deviceManagementService.ts
│   ├── areaManagementService.ts
│   ├── messageRoutingService.ts
│   ├── pollingService.ts
│   ├── connectionService.ts
│   ├── emailNotificationService.ts
│   ├── clientManager.ts
│   └── index.ts
│
├── behaviors/                   # Device behavior implementations
│   ├── BehaviorDeviceGeneric.ts # Base behavior class
│   └── roborock.vacuum/
│       ├── b01/                 # B01 protocol-specific behaviors
│       │   └── q7.ts
│       ├── core/                # Core behavior logic
│       │   ├── CleanModeSetting.ts
│       │   ├── behaviorConfig.ts
│       │   ├── cleanModeConfig/         # Directory module (split from cleanModeConfig.ts)
│       │   │   ├── types.ts             # CleanModeConfig, CleanModeDisplayLabel, CleanModeLabel, CleanModeLabelInfo
│       │   │   ├── vacuumAndMop.ts      # 6 V+M mode entries
│       │   │   ├── mopOnly.ts           # 5 mop-only entries
│       │   │   ├── vacuumOnly.ts        # 4 vacuum-only entries
│       │   │   ├── special.ts           # smartPlanModeConfig, vacFollowedByMopModeConfig, vacAndMopDeepModeConfig
│       │   │   ├── helpers.ts           # getModeDisplayMap, getModeSettingsMap, getModeOptions
│       │   │   └── index.ts             # Re-exports + assembles baseCleanModeConfigs, smartCleanModeConfigs
│       │   ├── cleanModeUtils.ts
│       │   ├── commonCommands.ts
│       │   ├── deviceCapabilityRegistry.ts
│       │   ├── modeHandler.ts
│       │   ├── modeHandlerRegistry.ts
│       │   ├── modeResolver.ts
│       │   └── runModeConfig.ts
│       ├── enums/               # Behavior enumerations
│       │   ├── CleanSequenceType.ts
│       │   ├── MopRoute.ts
│       │   ├── MopWaterFlow.ts
│       │   ├── VacuumSuctionPower.ts
│       │   └── index.ts
│       └── handlers/            # Mode-specific handlers
│           ├── cleaningModeHandler.ts
│           ├── customCleanModeHandler.ts
│           ├── defaultCleanModeHandler.ts
│           ├── goVacationHandler.ts
│           ├── presetCleanModeHandler.ts
│           └── smartPlanHandler.ts
│
├── roborockCommunication/       # Communication layer
│   ├── adapters/                # Port adapters
│   │   ├── RoborockAuthGateway.ts
│   │   └── RoborockDeviceGateway.ts
│   │
│   ├── api/                     # REST API clients
│   │   ├── authClient.ts        # Authentication API
│   │   └── iotClient.ts         # IoT API
│   │
│   ├── mqtt/                    # MQTT communication
│   │   ├── mqttClient.ts
│   │   └── messageProcessor.ts
│   │
│   ├── local/                   # Local network
│   │   ├── localClient.ts
│   │   └── udpClient.ts
│   │
│   ├── protocol/                # Protocol handling
│   │   ├── builders/
│   │   │   ├── A01MessageBodyBuilder.ts
│   │   │   ├── B01MessageBodyBuilder.ts
│   │   │   ├── L01MessageBodyBuilder.ts
│   │   │   ├── V01MessageBodyBuilder.ts
│   │   │   ├── UnknownMessageBodyBuilder.ts
│   │   │   ├── abstractMessageBodyBuilder.ts
│   │   │   └── messageBodyBuilderFactory.ts
│   │   ├── serializers/
│   │   │   ├── A01Serializer.ts
│   │   │   ├── B01Serializer.ts
│   │   │   ├── L01Serializer.ts
│   │   │   ├── V01Serializer.ts
│   │   │   ├── abstractSerializer.ts
│   │   │   ├── messageSerializer.ts
│   │   │   └── messageSerializerFactory.ts
│   │   ├── deserializers/
│   │   │   └── messageDeserializer.ts
│   │   └── dispatcher/          # Message dispatchers
│   │       ├── Q10MessageDispatcher.ts
│   │       ├── Q7MessageDispatcher.ts
│   │       ├── V10MessageDispatcher.ts
│   │       ├── abstractMessageDispatcher.ts
│   │       ├── dispatcherFactory.ts
│   │       └── protocolCalculator.ts
│   │
│   ├── routing/                 # Message routing
│   │   ├── clientRouter.ts
│   │   ├── client.ts
│   │   ├── abstractClient.ts
│   │   ├── handlers/
│   │   │   ├── abstractMessageHandler.ts
│   │   │   └── implementation/
│   │   │       └── simpleMessageHandler.ts
│   │   └── listeners/
│   │       ├── abstractConnectionListener.ts
│   │       ├── abstractMessageListener.ts
│   │       ├── abstractUDPMessageListener.ts
│   │       ├── b01ResponseBroadcaster.ts
│   │       ├── connectionBroadcaster.ts
│   │       ├── oneShotResponseListener.ts  # OneShotResponseListener<T>, replaces PendingResponseTracker
│   │       ├── responseBroadcaster.ts
│   │       ├── responseBroadcasterFactory.ts
│   │       ├── v1ResponseBroadcaster.ts
│   │       └── implementation/
│   │           ├── connectionStateListener.ts
│   │           ├── deviceStatusListener.ts
│   │           ├── disconnectNotificationListener.ts
│   │           ├── helloResponseListener.ts
│   │           ├── mapResponseListener.ts
│   │           └── simpleMessageListener.ts
│   │
│   ├── models/                  # Data models
│   │   ├── home/                # Home/room DTOs
│   │   │   ├── MapDataDto.ts
│   │   │   ├── MapRoomDto.ts
│   │   │   ├── MultipleMapDto.ts
│   │   │   ├── RoomDto.ts
│   │   │   ├── mappers.ts       # DTO to application model mappers
│   │   │   └── index.ts
│   │   ├── apiResponse.ts
│   │   ├── authenticateFlowState.ts
│   │   ├── authenticateResponse.ts
│   │   ├── baseURL.ts
│   │   ├── batteryMessage.ts
│   │   ├── contentMessage.ts
│   │   ├── device.ts
│   │   ├── deviceCategory.ts
│   │   ├── deviceModel.ts
│   │   ├── deviceSchema.ts
│   │   ├── deviceStatus.ts
│   │   ├── dockInfo.ts
│   │   ├── dps.ts
│   │   ├── headerMessage.ts
│   │   ├── home.ts
│   │   ├── homeInfo.ts
│   │   ├── messageContext.ts
│   │   ├── messageResult.ts
│   │   ├── networkInfo.ts
│   │   ├── product.ts
│   │   ├── protocol.ts
│   │   ├── requestMessage.ts
│   │   ├── responseBody.ts
│   │   ├── responseMessage.ts
│   │   ├── scene.ts
│   │   ├── userData.ts
│   │   ├── vacuumError.ts
│   │   └── index.ts
│   │
│   ├── enums/                   # Enumerations
│   │   ├── Q10RequestCode.ts
│   │   ├── Q7RequestCode.ts
│   │   ├── additionalPropCode.ts
│   │   ├── authenticateResponseCode.ts
│   │   ├── dockType.ts
│   │   ├── operationStatusCode.ts
│   │   ├── protocolVersion.ts
│   │   ├── vacuumAndDockErrorCode.ts
│   │   └── index.ts
│   │
│   ├── helper/                  # Communication helpers
│   │   ├── B01VacuumModeResolver.ts
│   │   ├── chunkBuffer.ts
│   │   ├── cryptoHelper.ts
│   │   ├── nameDecoder.ts
│   │   └── sequence.ts
│   │
│
├── runtimes/                    # Message runtime handlers
│   ├── handleCloudMessage.ts
│   ├── handleHomeDataMessage.ts
│   ├── handleLocalMessage.ts
│   └── handlers/                # Pure exported handler functions (extracted from platformRunner.ts)
│       ├── serviceAreaHandler.ts    # handleServiceAreaUpdate + area resolution helpers
│       ├── errorStateHandler.ts     # handleErrorOccurred
│       ├── deviceStateHandler.ts    # handleDeviceStatusUpdate (returns bool), handleDeviceStatusSimpleUpdate
│       ├── batteryStateHandler.ts   # handleBatteryUpdate
│       └── cleanModeHandler.ts      # handleCleanModeUpdate
│
├── initialData/                 # Initial data fetchers
│   ├── getBatteryStatus.ts      # getBatteryStatus, getBatteryState
│   ├── getOperationalStates.ts  # getOperationalStates, getOperationalErrorState, getErrorFromDSS
│   ├── getSupportedAreas.ts     # getSupportedAreas (rooms → ServiceArea.Area + RoomIndexMap)
│   ├── getSupportedCleanModes.ts
│   ├── getSupportedRoutines.ts  # Roborock scenes → ServiceArea.Area (routines as rooms)
│   ├── getSupportedRunModes.ts  # getRunningMode
│   ├── regionUrls.ts            # REGION_URLS map + getBaseUrl()
│   └── index.ts
│
├── constants/                   # Constant definitions
│   ├── battery.ts
│   ├── device.ts                # UNREGISTER_DEVICES_DELAY_MS
│   ├── distance.ts
│   ├── ids.ts
│   ├── timeouts.ts
│   ├── sensitiveDataRegexReplacements.ts  # NOT re-exported via index.ts; import directly (used by FilterLogger)
│   └── index.ts                 # re-exports battery, device, distance, ids, timeouts only
│
├── errors/                      # Custom error classes (BaseError hierarchy)
│   ├── AuthenticationError.ts   # + VerificationCodeExpiredError, InvalidCredentialsError, InvalidVerificationCodeError, TokenExpiredError, RateLimitExceededError
│   ├── BaseError.ts             # abstract base: code, statusCode, metadata, toJSON()
│   ├── CommunicationError.ts    # + TimeoutError, NetworkError, ProtocolError, MQTTConnectionError, LocalNetworkError, APIError, Serialization/DeserializationError
│   ├── ConfigurationError.ts    # + MissingConfigurationError, InvalidConfigurationError, MissingCredentialsError, InvalidRegionError
│   ├── DeviceError.ts           # + DeviceNotFoundError, DeviceConnectionError, DeviceOfflineError, DeviceCommandError, UnsupportedDeviceError, DeviceInitializationError
│   ├── ValidationError.ts       # + InvalidParameterError, OutOfRangeError, MissingParameterError, InvalidFormatError
│   └── index.ts
│
├── model/                       # Plugin data/config models
│   ├── AuthenticationResponse.ts    # AuthenticationResponse { userData, shouldContinue, isSuccess }
│   ├── CleanCommand.ts              # CleanCommand / CleanSelection discriminated unions
│   ├── CloudMessageModel.ts         # CloudMessageModel { duid, dps }
│   ├── DockStationStatus.ts         # DockStationStatus (bit-field parsing) + DockStationStatusCode
│   ├── ExperimentalFeatureSetting.ts # empty placeholder (no exports)
│   ├── RoborockPluginPlatformConfig.ts # RoborockPluginPlatformConfig + Authentication/Plugin/AdvancedFeature config interfaces, createDefault* helpers
│   └── VacuumStatus.ts              # VacuumStatus.getErrorState() -> RvcOperationalState.ErrorState
│
├── types/                       # TypeScript type definitions
│   ├── callbacks.ts
│   ├── communication.ts
│   ├── config.ts
│   ├── device.ts
│   ├── factories.ts
│   ├── MessagePayloads.ts
│   ├── notifyMessageTypes.ts
│   ├── roborockVacuumCleaner.ts
│   ├── state.ts
│   ├── WssSendSnackbarMessage.ts
│   └── index.ts
│
├── share/                       # Shared utilities
│   ├── behaviorFactory.ts       # Behavior creation
│   ├── dependency-check.ts      # Dependency version checks
│   ├── filterLogger.ts          # Logger with sensitive data filtering
│   ├── function.ts              # Utility functions
│   ├── helper.ts                # Helper functions
│   ├── matterStateNames.ts      # Matter state name mappings
│   ├── runtimeHelper.ts         # Runtime helper utilities
│   └── stateResolver.ts         # Device state resolution
│
├── cli/                         # CLI tool for standalone device interaction
│   ├── cli.ts                   # CLI entry point
│   ├── main.ts                  # Main CLI runner
│   ├── connection.ts            # Connection setup
│   ├── deviceBuilder.ts         # Device builder for CLI
│   ├── help.ts                  # Help text
│   ├── loggingMessageListener.ts
│   ├── session.ts               # CLI session management
│   ├── types.ts                 # CLI-specific types
│   ├── utils.ts                 # CLI utilities
│   └── commands/                # CLI command implementations
│       ├── cleanMode.ts
│       ├── custom.ts
│       ├── devices.ts
│       ├── login.ts
│       ├── mapInfo.ts
│       ├── networkInfo.ts
│       ├── pause.ts
│       ├── ping.ts
│       ├── resume.ts
│       ├── rooms.ts
│       ├── scenes.ts
│       ├── start.ts
│       ├── status.ts
│       └── stop.ts
│
└── tests/                       # Unit tests (177+ files)
    ├── behaviors/
    ├── core/
    ├── errors/
    ├── helpers/
    ├── initialData/
    ├── model/
    ├── roborockCommunication/
    ├── runtimes/
    ├── services/
    ├── share/
    ├── testData/
    └── ...

Core Components

1. RoborockMatterbridgePlatform (module.ts)

Responsibility: Main platform class extending MatterbridgeDynamicPlatform

Key Properties:

// Platform layer
registry: DeviceRegistry; // Device/robot storage
configManager: PlatformConfigManager; // Configuration management
discovery: DeviceDiscovery; // Device discovery and authentication
configurator: DeviceConfigurator; // Device setup and registration
state: PlatformState; // Startup state tracking

// Services
roborockService: RoborockService; // Service facade (via discovery getter)
platformRunner: PlatformRunner; // Update orchestrator
persist: LocalStorage; // Data persistence

Key Methods:

  • onStart() - Initialize storage, validate config, discover devices, configure devices
  • onConfigure() - Set up periodic polling interval, handle clearStorageOnStartup
  • onShutdown() - Clean up intervals, stop services, optionally unregister devices

2. PlatformRunner (platformRunner.ts)

Responsibility: Orchestrates device state updates from various message sources

Key Methods:

  • updateRobotWithPayload() - Type-safe message routing
  • requestHomeData() - Polls for device state updates
  • updateFromMQTTMessage() - Processes MQTT messages

Message Flow:

MQTT/Cloud → PlatformRunner → Runtime Handlers → Robot Update

3. RoborockVacuumCleaner Types (types/roborockVacuumCleaner.ts)

Responsibility: Type definitions for Roborock vacuum cleaner

Key Types:

  • Device configuration types
  • State types
  • Map and room types
  • Behavior types

Platform Layer

Located in: src/platform/

DeviceDiscovery (deviceDiscovery.ts)

Responsibility: Handles authentication, API calls, and device filtering

Key Properties:

  • roborockService — Created during discovery, used by configurator and platform

Key Methods:

  • discoverDevices() — Authenticate, fetch home data, filter supported devices

DeviceConfigurator (deviceConfigurator.ts)

Responsibility: Handles device setup, local network connection, room mapping, and Matterbridge registration

Key Properties:

  • rrHomeId — Set during device configuration

Key Methods:

  • onConfigureDevice(roborockService) — Configure all discovered devices
  • configureDevice(vacuum, roborockService) — Configure a single device

PlatformConfigManager (platformConfig.ts)

Responsibility: Configuration validation and access

Key Properties:

  • username, password, verificationCode
  • authenticationMethod
  • refreshInterval, whiteList, blackList
  • experimentalSettings, cleanModeSettings
  • isServerModeEnabled, isMultipleMapEnabled

DeviceRegistry (deviceRegistry.ts)

Responsibility: Storage for discovered devices and robots

Key Methods:

  • registerDevice() / registerRobot()
  • getDevice() / getRobot()
  • getAllDevices() / getAllRobots()
  • hasDevices() / size

PlatformState (platformState.ts)

Responsibility: Track platform state

Key Properties:

  • isStartupCompleted - Whether startup finished successfully

Core Domain Layer

Located in: src/core/

ServiceContainer (ServiceContainer.ts)

Responsibility: Dependency injection for port adapters

Key Methods:

  • initialize(userData) - Create device gateway after auth
  • getAuthGateway() - Get IAuthGateway instance
  • getDeviceGateway() - Get IDeviceGateway instance
  • dispose() - Clean up resources

Application Models (application/models/)

Application-layer models for room and map management:

MapInfo.ts:

class MapInfo {
  readonly maps: Map<number, string>; // Map ID → Map name
  readonly allRooms: RoomMapping[]; // All rooms across all maps

  getById(mapId: number): string | undefined;
  getByName(name: string): number | undefined;
  static fromDto(dto: MultipleMapDto): MapInfo;
}

RoomMapping.ts:

class RoomMapping {
  readonly id: number; // Local room ID
  readonly globalId: number; // Global room ID
  readonly iot_name_id: number; // IoT name identifier
  readonly tag: number; // Room tag
  readonly mapId: number; // Associated map ID
  readonly displayName: string; // Decoded room name
}

MapRoom.ts:

class MapRoom {
  readonly id: number;
  readonly globalId: number;
  readonly iot_name_id: number;
  readonly tag: number;
  readonly displayName: string;
  readonly mapId: number;

  static fromDto(dto: MapRoomDto): MapRoom;
}

RoomMap.ts:

class RoomMap {
  private readonly roomMappings: RoomMapping[];

  getRooms(): RoomMapping[];
  getRoomName(roomId: number): string | undefined;
  getRoomIdByName(roomName: string): number | undefined;

  static fromDevice(
    duid: string,
    platform: RoborockMatterbridgePlatform,
  ): Promise<RoomMap>;
  static fromDeviceDirect(
    device: Device,
    platform: RoborockMatterbridgePlatform,
  ): Promise<RoomMap>;
}

RoomIndexMap.ts:

class RoomIndexMap {
  readonly mapInfo: MapInfo;
  readonly indexToRoomId: Map<number, number>;
  readonly roomIdToIndex: Map<number, number>;

  getRoomIdByIndex(index: number): number | undefined;
  getIndexByRoomId(roomId: number): number | undefined;
}

Domain Entities (domain/entities/)

Device.ts:

interface DeviceEntity {
  readonly duid: string;
  readonly name: string;
  readonly model: string;
  readonly localKey: string;
  readonly status: DeviceStatus;
}

Home.ts:

interface HomeEntity {
  readonly id: number;
  readonly name: string;
  readonly devices: DeviceEntity[];
  readonly rooms: RoomEntity[];
}

Value Objects (domain/value-objects/)

DeviceId.ts:

class DeviceId {
  static create(duid: string): DeviceId;
  toString(): string;
  equals(other: DeviceId): boolean;
}

CleanMode.ts:

class CleanMode {
  static readonly Vacuum: CleanMode;
  static readonly Mop: CleanMode;
  static readonly VacuumAndMop: CleanMode;
}

Port Interfaces (ports/)

IAuthGateway.ts:

interface IAuthGateway {
  requestVerificationCode(email: string): Promise<void>;
  authenticate(email: string, code: string): Promise<UserData>;
  refreshToken(userData: UserData): Promise<UserData>;
}

IDeviceGateway.ts:

interface IDeviceGateway {
  sendCommand(deviceId: string, command: DeviceCommand): Promise<void>;
  getStatus(deviceId: string): Promise<DeviceStatus>;
  subscribe(deviceId: string, callback: StatusCallback): () => void;
}

Service Layer

Located in: src/services/

ServiceContainer (serviceContainer.ts)

Responsibility: Main dependency injection container

Services Managed:

  1. AuthenticationService
  2. DeviceManagementService
  3. AreaManagementService
  4. MessageRoutingService
  5. PollingService
  6. ConnectionService

Key Methods:

getAuthenticationService(): AuthenticationService;
getDeviceManagementService(): DeviceManagementService;
getAreaManagementService(): AreaManagementService;
getMessageRoutingService(): MessageRoutingService;
getPollingService(): PollingService;
getConnectionService(): ConnectionService;
setUserData(userData: UserData): void;
destroy(): Promise<void>;

AuthenticationService (authenticationService.ts)

Responsibilities:

  • User authentication flow (2FA, password)
  • Token management
  • Session handling

Key Methods:

  • authenticate2FAFlow() - Two-factor authentication
  • authenticateWithPasswordFlow() - Password-based auth
  • requestVerificationCode() - Send code to email

DeviceManagementService (deviceManagementService.ts)

Responsibilities:

  • Device discovery and listing
  • Device lifecycle coordination

Key Methods:

  • listDevices() - Fetch all devices
  • getHomeDataForUpdating() - Get home data for updates
  • stopService() - Clean up resources

ConnectionService (connectionService.ts)

Responsibilities:

  • MQTT client initialization
  • Local network client setup
  • Connection timeout handling

Key Methods:

  • initializeMessageClient() - Setup MQTT connection
  • initializeMessageClientForLocal() - Setup local connection
  • setDeviceNotify() - Set notification callback

PollingService (pollingService.ts)

Responsibilities:

  • Device status polling
  • Refresh interval management

Key Methods:

  • activateDeviceNotifyOverLocal() - Start local polling
  • activateDeviceNotifyOverMQTT() - Start MQTT polling
  • stopPolling() - Stop all polling

AreaManagementService (areaManagementService.ts)

Responsibilities:

  • Room/area management
  • Map data processing
  • Scene management

MessageRoutingService (messageRoutingService.ts)

Responsibilities:

  • Message subscription management
  • Device command execution
  • Clean mode management

Communication Layer

Located in: src/roborockCommunication/

Structure

roborockCommunication/
├── adapters/                    # Port adapter implementations
│   ├── RoborockAuthGateway.ts   # Implements IAuthGateway
│   └── RoborockDeviceGateway.ts # Implements IDeviceGateway
├── api/                         # REST API clients
│   ├── authClient.ts            # Authentication API
│   └── iotClient.ts             # IoT API
├── mqtt/                        # MQTT communication
│   ├── mqttClient.ts
│   └── messageProcessor.ts
├── local/                       # Local network communication
│   ├── localClient.ts
│   └── udpClient.ts
├── protocol/                    # Protocol handling
│   ├── builders/                # Message body builders
│   ├── serializers/             # Protocol serializers
│   ├── deserializers/           # Protocol deserializers
│   └── dispatcher/              # Message dispatchers (Q7, Q10, V01)
├── routing/                     # Message routing
│   ├── clientRouter.ts
│   ├── abstractClient.ts
│   ├── handlers/                # Message handlers
│   └── listeners/               # Message listeners
├── models/                      # Data models
│   └── home/                    # Home/room DTOs and mappers
├── enums/                       # Enumerations
└── helper/                      # Utilities

Adapters (adapters/)

RoborockAuthGateway.ts:

  • Implements IAuthGateway interface
  • Wraps RoborockAuthenticateApi
  • Adapts REST API to domain port

RoborockDeviceGateway.ts:

  • Implements IDeviceGateway interface
  • Wraps ClientRouter
  • Adapts message routing to domain port

API Layer (api/)

authClient.ts (RoborockAuthenticateApi):

  • sendEmailCode() - Request verification code
  • loginWithCode() - Login with verification code
  • loginWithPassword() - Password-based login

iotClient.ts (RoborockIoTApi):

  • getHomeData() - Fetch home and device data
  • getDeviceList() - List all devices
  • getScenes() - Get cleaning scenes

Client Architecture

ClientRouter (facade)
    ├── MQTTClient (cloud connection)
    │   └── TLS encrypted, auto-reconnect
    └── LocalNetworkClient (LAN connection)
        └── UDP, low latency

Protocol Support

Protocol Builder Serializer Dispatcher Description
L01 L01MessageBodyBuilder L01Serializer - Legacy protocol
A01 A01MessageBodyBuilder A01Serializer - Standard protocol
B01 B01MessageBodyBuilder B01Serializer Q7MessageDispatcher Extended protocol
V01 V01MessageBodyBuilder V01Serializer V10MessageDispatcher Latest protocol

Message Dispatchers:

  • V10MessageDispatcher - Handles V01 protocol messages, including room mapping and map data
  • Q7MessageDispatcher - Handles Q7-specific B01 protocol messages
  • Q10MessageDispatcher - Handles Q10-specific messages

DTO to Application Model Mapping:

The communication layer uses DTOs (Data Transfer Objects) with mappers to transform API responses into application models:

API Response → DTO (RoomDto, MapRoomDto) → Mapper (HomeModelMapper) → Application Model (RoomMapping, MapInfo)

This separation ensures the domain layer is decoupled from external API changes.


Behavior System

Located in: src/behaviors/

Architecture

The behavior system has been refactored from device-based behaviors (default/smart) to a modular, handler-based architecture:

BehaviorDeviceGeneric (base class)
    │
    └── roborock.vacuum/
        ├── core/           # Core behavior logic and configuration
        ├── handlers/       # Mode-specific handlers
        ├── enums/          # Behavior-specific enumerations
        └── b01/            # Protocol-specific behaviors

Core Behavior Components (core/)

Key Files:

  • CleanModeSetting.ts - Clean mode configuration
  • behaviorConfig.ts - Behavior configuration
  • cleanMode.ts - Clean mode definitions
  • cleanModeConfig.ts - Clean mode settings
  • cleanModeUtils.ts - Clean mode utilities
  • cleanSetting.ts - Clean setting management
  • commonCommands.ts - Common device commands
  • modeHandler.ts - Mode handler interface
  • modeHandlerRegistry.ts - Mode handler registry
  • modeResolver.ts - Mode resolution logic
  • runModeConfig.ts - Run mode configuration

Mode Handlers (handlers/)

Handler Types:

  • cleaningModeHandler.ts - Standard cleaning mode
  • customCleanModeHandler.ts - Custom cleaning mode
  • defaultCleanModeHandler.ts - Default cleaning mode
  • goVacationHandler.ts - Vacation mode
  • presetCleanModeHandler.ts - Preset cleaning modes
  • smartPlanHandler.ts - Smart cleaning plan

Supported Clusters:

  • RvcRunMode
  • RvcOperationalState
  • RvcCleanMode
  • PowerSource
  • ServiceArea (for room-based cleaning)

Protocol-Specific Behaviors (b01/)

Device-specific behavior implementations:

  • q7.ts - Roborock Q7 (B01 protocol). Defines legacy Q7VacuumSuctionPower, Q7MopWaterFlow, Q7MopRoute enums (subset of the standard enums, no Smart variant).

Error Handling & Plugin Models

Errors (errors/)

Typed error hierarchy, all extending BaseError (code, statusCode, metadata, toJSON()):

  • AuthenticationErrorVerificationCodeExpiredError, InvalidCredentialsError, InvalidVerificationCodeError, TokenExpiredError, RateLimitExceededError
  • CommunicationErrorTimeoutError, NetworkError, ProtocolError, MQTTConnectionError, LocalNetworkError, APIError, SerializationError, DeserializationError
  • ConfigurationErrorMissingConfigurationError, InvalidConfigurationError, MissingCredentialsError, InvalidRegionError
  • DeviceErrorDeviceNotFoundError, DeviceConnectionError, DeviceOfflineError, DeviceCommandError, UnsupportedDeviceError, DeviceInitializationError
  • ValidationErrorInvalidParameterError, OutOfRangeError, MissingParameterError, InvalidFormatError

All exported from errors/index.ts.

Plugin Models (model/)

  • AuthenticationResponse - { userData, shouldContinue, isSuccess }, returned by authentication strategies
  • CleanCommand / CleanSelection - discriminated unions for routine/room/global clean requests
  • CloudMessageModel - { duid, dps } shape for cloud MQTT messages
  • DockStationStatus - parses the dock status bit-field (clean fluid, water box filter, dust bag, dirty/clear water box, updown water ready) into DockStationStatusCode; hasError(), getMatterOperationalError(), static parseDockStationStatus()/parseDockErrorCode()
  • VacuumStatus - wraps VacuumErrorCode and maps it to RvcOperationalState.ErrorState via getErrorState()
  • RoborockPluginPlatformConfig - PlatformConfig extension with authentication, pluginConfiguration, advancedFeature sections; includes CleanModeSettings, MatterOverrideSettings, EmailNotificationSettings, and createDefaultAdvancedFeature()/createDefaultCleanModeSettings() factories
  • ExperimentalFeatureSetting - empty placeholder file, no exports

CLI Tool

Located in: src/cli/ (entry point: src/cli.ts)

A standalone command-line tool for interacting with Roborock devices directly, independent of Matterbridge - useful for debugging and exploring device capabilities.

  • main.ts - command dispatcher for: login, devices, status, start, stop, pause, resume, ping, room-info, map-info, clean-mode, network-info, scenes, custom
  • connection.ts - builds a ClientRouter + message dispatcher and connects to a device
  • session.ts - loads/saves the CLI session (cached UserData, DEFAULT_BASE_URL) to disk
  • deviceBuilder.ts - builds Device instances for CLI use
  • loggingMessageListener.ts - logs incoming device messages to the console
  • utils.ts - parseArgs/prompt helpers
  • help.ts / types.ts - help text and CliSession/shared CLI types
  • commands/ - one file per command (thin wrappers calling into connection.ts + RoborockService/dispatcher methods): login, devices, status, start, stop, pause, resume, ping, rooms, mapInfo, cleanMode, networkInfo, scenes, custom

Shared Utilities

Located in: src/share/

Shared utilities and helper functions used across the codebase:

BehaviorFactory (behaviorFactory.ts)

Responsibility: Factory for creating device behaviors

Key Functions:

  • Creates appropriate behavior instances based on device type
  • Handles behavior initialization and configuration

FilterLogger (filterLogger.ts)

Responsibility: Logger with sensitive data filtering

Key Features:

  • Filters sensitive information (passwords, tokens, keys) from logs
  • Wraps Matterbridge logger with security enhancements
  • Uses regex patterns from constants/sensitiveDataRegexReplacements.ts

Helper Functions (helper.ts)

Responsibility: General utility functions

Key Functions:

  • String manipulation utilities
  • Data transformation helpers
  • Common operations used across modules

Function Utilities (function.ts)

Responsibility: Functional programming utilities

Key Functions:

  • Functional composition helpers
  • Data processing utilities

Runtime Helpers (runtimeHelper.ts)

Responsibility: Runtime message processing helpers

Key Functions:

  • Message validation and transformation
  • Runtime data processing utilities
  • Common message handling operations

Data Flow

1. Startup Flow

module.ts constructor
    ↓
Create PlatformConfigManager, DeviceRegistry, PlatformState
    ↓
Create DeviceDiscovery, DeviceConfigurator
    ↓
onStart() called
    ↓
discovery.discoverDevices()
    ↓
Create RoborockService (facade)
    ↓
ServiceContainer created with all services
    ↓
authenticate() → AuthenticationService
    ↓
listDevices() → DeviceManagementService
    ↓
initializeMessageClient() → ConnectionService
    ↓
configureDevice() for each device
    ↓
Create RoborockVacuumCleaner
    ↓
Register with Matterbridge

2. Authentication Flow

User Input (Email)
    ↓
RoborockService.authenticate()
    ↓
AuthenticationService.authenticate2FAFlow()
    ↓
IAuthGateway.requestVerificationCode()
    ↓
RoborockAuthGateway → RoborockAuthenticateApi
    ↓
User receives code via email
    ↓
IAuthGateway.authenticate()
    ↓
UserData stored → ServiceContainer.setUserData()

3. Message Update Flow

MQTT Message Received
    ↓
MessageProcessor.processMessage()
    ↓
Route to registered listeners
    ↓
PlatformRunner.updateRobotWithPayload()
    ↓
Runtime Handler (handleLocalMessage/handleCloudMessage)
    ↓
Update robot state
    ↓
Update Matter clusters
    ↓
Notify Matter controllers

4. Command Execution Flow

Matter Controller (Apple Home)
    ↓
Matterbridge Endpoint
    ↓
RoborockVacuumCleaner behavior handler
    ↓
RoborockService.startClean/pauseClean/etc.
    ↓
MessageRoutingService
    ↓
ClientRouter.sendRequest()
    ↓
MQTTClient/LocalNetworkClient
    ↓
Roborock Device

5. Room/Map Data Flow (DTO → Mapper → Application Model)

API Response (number[][])
    ↓
V10MessageDispatcher.getRoomMappings()
    ↓
HomeModelMapper.rawArrayToMapRoomDto() → MapRoomDto[]
    ↓
HomeModelMapper.toRoomMapping() → RoomMapping[]
    ↓
new RoomMap(roomMappings)
    ↓
Application uses RoomMap

Key Transformation Steps:

  1. API Layer: Raw data from Roborock API (e.g., number[][] for room mappings)
  2. DTO Layer: Transform to typed DTOs (MapRoomDto, RoomDto, MultipleMapDto)
  3. Mapper Layer: HomeModelMapper transforms DTOs to application models
  4. Application Layer: Clean models (RoomMapping, MapInfo, RoomMap) used in business logic

Benefits:

  • API changes only affect DTOs and mappers
  • Business logic works with clean, domain-focused models
  • Clear separation of concerns
  • Type safety throughout the transformation

Key Design Patterns

1. Hexagonal Architecture (Ports & Adapters)

  • core/ports/ defines interfaces (ports)
  • roborockCommunication/adapters/ implements them
  • Domain logic is decoupled from infrastructure

2. Service Locator / Dependency Injection

  • services/ServiceContainer provides centralized service access
  • core/ServiceContainer manages port adapters
  • Lazy initialization for performance

3. Facade Pattern

  • RoborockService simplifies complex service interactions
  • ClientRouter simplifies client selection
  • Clean public APIs hide complexity

4. Factory Pattern

  • behaviorFactory.ts creates device behaviors
  • messageBodyBuilderFactory.ts creates protocol builders
  • messageProcessorFactory.ts creates processors

5. Strategy Pattern

  • Different behaviors (Default vs Smart)
  • Protocol-specific serializers
  • Message builders by protocol version

6. Observer Pattern

  • Message listeners observe MQTT messages
  • Platform observes device state changes
  • Event-driven updates

Testing Strategy

Test Coverage Summary

Overall: 95.74% statement coverage (959+ tests)

Coverage by Layer:

  • Services: 90-100%
    • ConnectionService: 98.11%
    • PollingService: 100%
    • AuthenticationService: 91.83%
  • Communication: 94-100%
  • Behaviors: 98-100%
  • Runtimes: 92.38%

Test Organization

src/tests/
├── behaviors/              # Behavior tests
├── core/                   # Core domain tests
│   └── ports/              # Port interface tests
├── errors/                 # Error class tests
├── roborockCommunication/  # Communication layer tests
│   ├── adapters/           # Adapter tests
│   ├── api/                # API client tests
│   ├── broadcast/          # Message routing tests
│   └── ...
├── services/               # Service layer tests
└── testData/               # Mock data and fixtures

Test Commands

npm run test               # Run all tests
npm run test -- --coverage # Run with coverage
npm run test:verbose       # Verbose output

References

Documentation

Links


Document Version: 4.0 Last Updated: January 30, 2026

Clone this wiki locally