UNPKG

matterbridge-dyson-robot

Version:

A Matterbridge plugin that connects Dyson robot vacuums and air treatment devices to the Matter smart home ecosystem via their local or cloud MQTT APIs.

123 lines 6.05 kB
// Matterbridge plugin for Dyson robot vacuum and air treatment devices // Copyright © 2025-2026 Alexander Thoukydides import { DysonCloudAPIUserAgent } from './dyson-cloud-api-ua.js'; import { checkers } from './ti/dyson-cloud-types.js'; import { checkers as checkers360 } from './ti/dyson-360-cloud-types.js'; import { checkers as checkersAir } from './ti/dyson-air-cloud-types.js'; import { assertIsDefined } from './utils.js'; // Default locale const DEFAULT_COUNTRY = 'GB'; const DEFAULT_LANGUAGE = 'en-GB'; // Dyson cloud API client for a single device export class DysonCloudAPIDevice { log; config; china; token; manifest; // User agent used for all requests ua; // Construct a new Dyson cloud API client constructor(log, config, china, token, manifest) { this.log = log; this.config = config; this.china = china; this.token = token; this.manifest = manifest; // Create an authenticated user agent this.ua = new DysonCloudAPIUserAgent(log, config, china); this.ua.setBearerToken(token); } // Interesting information about this device get serialNumber() { return this.manifest.serialNumber; } get modelNumber() { return this.manifest.model; } get modelName() { return this.manifest.productName; } get mqttRootTopic() { return this.connectedConfiguration.mqtt.mqttRootTopicLevel; } get firmwareVersion() { return this.connectedConfiguration.firmware.version; } // Shortcut to nested (and optional but always present) object get connectedConfiguration() { assertIsDefined(this.manifest.connectedConfiguration); return this.manifest.connectedConfiguration; } // Retrieve the AWS IoT credentials for a specific device getIoTCredentials() { const body = { Serial: this.serialNumber }; const path = '/v2/authorize/iot-credentials'; return this.ua.postJSON(checkers.DysonIoTCredentialsResponse, path, body); } // Identify the timezone of the device getTimezone() { const path = `/v1/machine/${this.serialNumber}/timezone`; return this.ua.getJSON(checkers.DysonTimezoneResponse, path); } // Check the registration status of the device async getOwnership(countryCode = DEFAULT_COUNTRY) { const path = `/v1/userregistration/ownership?country=${countryCode}&serial=${this.serialNumber}`; const response = await this.ua.getJSON(checkers.DysonOwnershipResponse, path); return response.deviceStatus; } // Retrieve list of scheduled events for the device getScheduledEvents(checker) { const path = `/v1/unifiedscheduler/${this.serialNumber}/events?productType=${this.mqttRootTopic}`; return this.ua.getJSON(checker, path); } // ========================================================================= // Dyson robot vacuum device API methods... // Retrieve list of scheduled events for the device getScheduledEvents360() { return this.getScheduledEvents(checkers360.Dyson360UnifiedschedulerEventsResponse); } // Retrieve the cleaning history for the device (360 Eye only) getCleaningHistory360(languageCode = DEFAULT_LANGUAGE) { const path = `/v1/assets/devices/${this.serialNumber}/cleanhistory?culture=${languageCode}`; return this.ua.getJSON(checkers360.Dyson360CleanHistoryResponse, path); } // Retrieve the map image for a specific cleaning session (360 Eye only) getMapImage360(clean) { const path = `/v1/mapvisualizer/devices/${this.serialNumber}/map/${clean}`; return this.ua.getBinary(path, 'image/png'); } // Retrieve the zone definitions for all persistent maps (360 Vis Nav only) getPersistentMapMetadata360() { const path = `/v1/app/${this.serialNumber}/persistent-map-metadata`; return this.ua.getJSON(checkers360.Dyson360PersistentMapMetadataResponse, path); } // Retrieve the full details of a specific persistent map (360 Vis Nav only) getPersistentMap360(mapId) { const path = `/v1/app/${this.serialNumber}/persistent-maps/${mapId}`; return this.ua.getJSON(checkers360.Dyson360PersistentMapResponse, path); } // Retrieve details of recent cleaning sessions (360 Vis Nav only) getCleanMaps360() { const path = `/v1/${this.serialNumber}/clean-maps?dustMap=total`; return this.ua.getJSON(checkers360.Dyson360CleanMapsResponse, path); } // Request details of the recommended clean (360 Vis Nav only) getRecommendedCleans360() { const path = `/v1/app/${this.serialNumber}/recommended-cleans`; return this.ua.getJSON(checkers360.Dyson360RecommendedCleansResponse, path); } // Set the cleaning strategy for a single zone (360 Vis Nav only) setZoneBehaviour360(mapId, zoneId, cleaningStrategy) { const body = { cleaningStrategy }; const path = `/v1/app/${this.serialNumber}/persistent-maps/${mapId}/zones/${zoneId}/behaviour`; return this.ua.put(path, body); } // ========================================================================= // Dyson air treatment device API methods... // Retrieve list of scheduled events for the device getScheduledEventsAir() { return this.getScheduledEvents(checkersAir.DysonAirUnifiedschedulerEventsResponse); } // Retrieve current environmental data for the device getEnvironmentalDataAir(languageCode = DEFAULT_LANGUAGE) { const path = `/v1/environment/devices/${this.serialNumber}/data?language=${languageCode}`; return this.ua.getJSON(checkersAir.DysonAirEnvironmentResponse, path); } // Retrieve daily history of environmental data for the device getEnvironmentalDataDailyAir() { const path = `/v1/messageprocessor/devices/${this.serialNumber}/environmentdata/daily`; return this.ua.getJSON(checkersAir.DysonAirEnvironmentDataDailyResponse, path); } } //# sourceMappingURL=dyson-cloud-api-device.js.map