-
-
Notifications
You must be signed in to change notification settings - Fork 10
Code Structure
Version: 1.1.7-rc01 Last Updated: June 12, 2026 Test Coverage: 1911+ tests passed (177 test files)
- Overview
- Architecture Patterns
- Dependency Tree
- Directory Structure
- Core Components
- Platform Layer
- Core Domain Layer
- Service Layer
- Communication Layer
- Behavior System
- Error Handling & Plugin Models
- CLI Tool
- Shared Utilities
- Data Flow
- Key Design Patterns
- Testing Strategy
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
┌─────────────────────────────────────────┐
│ 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 │
└─────────────────────────────────────────┘
-
Ports: Interfaces in
core/ports/(IDeviceGateway, IAuthGateway) -
Adapters: Implementations in
roborockCommunication/adapters/ - Clear separation between domain logic and infrastructure
-
services/ServiceContainermanages service lifecycle -
core/ServiceContainermanages port adapters - Services are lazy-loaded singletons
- Facilitates testing and modularity
-
RoborockServiceacts as facade over specialized services - Maintains backward compatibility
- Reduced from 923 lines to ~300 lines
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.tsis 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 inroborockCommunication/adapters/. - The
roborockService.tsacts 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.
┌─────────────────────────────────────────────────────────────────────────┐
│ 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
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/
└── ...
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 persistenceKey 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
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
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;
}Located in: src/services/
ServiceContainer (serviceContainer.ts)
Responsibility: Main dependency injection container
Services Managed:
- AuthenticationService
- DeviceManagementService
- AreaManagementService
- MessageRoutingService
- PollingService
- 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
Located in: src/roborockCommunication/
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
IAuthGatewayinterface - Wraps
RoborockAuthenticateApi - Adapts REST API to domain port
RoborockDeviceGateway.ts:
- Implements
IDeviceGatewayinterface - 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
ClientRouter (facade)
├── MQTTClient (cloud connection)
│ └── TLS encrypted, auto-reconnect
└── LocalNetworkClient (LAN connection)
└── UDP, low latency
| 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.
Located in: src/behaviors/
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 legacyQ7VacuumSuctionPower,Q7MopWaterFlow,Q7MopRouteenums (subset of the standard enums, noSmartvariant).
Errors (errors/)
Typed error hierarchy, all extending BaseError (code, statusCode, metadata, toJSON()):
-
AuthenticationError→VerificationCodeExpiredError,InvalidCredentialsError,InvalidVerificationCodeError,TokenExpiredError,RateLimitExceededError -
CommunicationError→TimeoutError,NetworkError,ProtocolError,MQTTConnectionError,LocalNetworkError,APIError,SerializationError,DeserializationError -
ConfigurationError→MissingConfigurationError,InvalidConfigurationError,MissingCredentialsError,InvalidRegionError -
DeviceError→DeviceNotFoundError,DeviceConnectionError,DeviceOfflineError,DeviceCommandError,UnsupportedDeviceError,DeviceInitializationError -
ValidationError→InvalidParameterError,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) intoDockStationStatusCode;hasError(),getMatterOperationalError(), staticparseDockStationStatus()/parseDockErrorCode() -
VacuumStatus- wrapsVacuumErrorCodeand maps it toRvcOperationalState.ErrorStateviagetErrorState() -
RoborockPluginPlatformConfig-PlatformConfigextension withauthentication,pluginConfiguration,advancedFeaturesections; includesCleanModeSettings,MatterOverrideSettings,EmailNotificationSettings, andcreateDefaultAdvancedFeature()/createDefaultCleanModeSettings()factories -
ExperimentalFeatureSetting- empty placeholder file, no exports
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 aClientRouter+ message dispatcher and connects to a device -
session.ts- loads/saves the CLI session (cachedUserData,DEFAULT_BASE_URL) to disk -
deviceBuilder.ts- buildsDeviceinstances for CLI use -
loggingMessageListener.ts- logs incoming device messages to the console -
utils.ts-parseArgs/prompthelpers -
help.ts/types.ts- help text andCliSession/shared CLI types -
commands/- one file per command (thin wrappers calling intoconnection.ts+RoborockService/dispatcher methods):login,devices,status,start,stop,pause,resume,ping,rooms,mapInfo,cleanMode,networkInfo,scenes,custom
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
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
User Input (Email)
↓
RoborockService.authenticate()
↓
AuthenticationService.authenticate2FAFlow()
↓
IAuthGateway.requestVerificationCode()
↓
RoborockAuthGateway → RoborockAuthenticateApi
↓
User receives code via email
↓
IAuthGateway.authenticate()
↓
UserData stored → ServiceContainer.setUserData()
MQTT Message Received
↓
MessageProcessor.processMessage()
↓
Route to registered listeners
↓
PlatformRunner.updateRobotWithPayload()
↓
Runtime Handler (handleLocalMessage/handleCloudMessage)
↓
Update robot state
↓
Update Matter clusters
↓
Notify Matter controllers
Matter Controller (Apple Home)
↓
Matterbridge Endpoint
↓
RoborockVacuumCleaner behavior handler
↓
RoborockService.startClean/pauseClean/etc.
↓
MessageRoutingService
↓
ClientRouter.sendRequest()
↓
MQTTClient/LocalNetworkClient
↓
Roborock Device
API Response (number[][])
↓
V10MessageDispatcher.getRoomMappings()
↓
HomeModelMapper.rawArrayToMapRoomDto() → MapRoomDto[]
↓
HomeModelMapper.toRoomMapping() → RoomMapping[]
↓
new RoomMap(roomMappings)
↓
Application uses RoomMap
Key Transformation Steps:
-
API Layer: Raw data from Roborock API (e.g.,
number[][]for room mappings) -
DTO Layer: Transform to typed DTOs (
MapRoomDto,RoomDto,MultipleMapDto) -
Mapper Layer:
HomeModelMappertransforms DTOs to application models -
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
-
core/ports/defines interfaces (ports) -
roborockCommunication/adapters/implements them - Domain logic is decoupled from infrastructure
-
services/ServiceContainerprovides centralized service access -
core/ServiceContainermanages port adapters - Lazy initialization for performance
-
RoborockServicesimplifies complex service interactions -
ClientRoutersimplifies client selection - Clean public APIs hide complexity
-
behaviorFactory.tscreates device behaviors -
messageBodyBuilderFactory.tscreates protocol builders -
messageProcessorFactory.tscreates processors
- Different behaviors (Default vs Smart)
- Protocol-specific serializers
- Message builders by protocol version
- Message listeners observe MQTT messages
- Platform observes device state changes
- Event-driven updates
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%
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
npm run test # Run all tests
npm run test -- --coverage # Run with coverage
npm run test:verbose # Verbose output- README.md - Main documentation
- README_DEV.md - Developer guide
- migration.md - Migration plan
- to_do.md - Task tracking
- authentication-flow.md - Authentication strategy flow diagram
- GitHub: https://github.com/RinDevJunior/matterbridge-roborock-vacuum-plugin
- NPM: https://www.npmjs.com/package/matterbridge-roborock-vacuum-plugin
- Matterbridge: https://www.npmjs.com/package/matterbridge
Document Version: 4.0 Last Updated: January 30, 2026