homebridge-homeconnect
Version:
A Homebridge plugin that connects Home Connect appliances to Apple HomeKit
186 lines • 8.73 kB
JavaScript
// Homebridge plugin for Home Connect home appliances
// Copyright © 2019-2026 Alexander Thoukydides
import { on } from 'events';
import { APIAuthoriseUserAgent } from './api-ua-auth.js';
import { APIEventStream } from './api-events.js';
import { APICheckValues } from './api-value.js';
import { checkers } from './ti/api-types.js';
import { assertIsDefined } from './utils.js';
import { PrefixLogger } from './logger.js';
// Low-level access to the Home Connect API
export class CloudAPI {
// Create a new API object
constructor(log, config, persist) {
this.log = log;
this.config = config;
this.persist = persist;
this.ua = new APIAuthoriseUserAgent(log, config, persist, config.language.api);
this.events = new APIEventStream(log, this.ua);
this.checkValues = new APICheckValues(log, config, persist);
}
// Check whether a particular scope has been authorised
hasScope(scope) {
// Check for the specific scope requested
if (this.ua.scopes.includes(scope))
return true;
// Check for row or column scopes that include the requested scope
const parsedScope = /^([^-]+)-([^-]+)$/.exec(scope);
if (parsedScope) {
const [, row, column] = parsedScope;
assertIsDefined(row);
assertIsDefined(column);
if (this.ua.scopes.includes(row))
return true;
if (this.ua.scopes.includes(column))
return true;
}
// Scope has not been authorised
return false;
}
// Get a list of paired home appliances
async getAppliances() {
const response = await this.ua.get(checkers.HomeAppliancesWrapper, '/api/homeappliances');
for (const { haId, vib, name } of response.data.homeappliances) {
PrefixLogger.addApplianceId(haId, `${vib} "${name}"`);
}
return this.checkValues.appliances(response.data.homeappliances);
}
// Get details of a specific paired home appliances
async getAppliance(haid) {
const response = await this.ua.get(checkers.HomeApplianceWrapper, `/api/homeappliances/${haid}`);
return this.checkValues.appliance(haid, response.data);
}
// Get all programs
async getPrograms(haid) {
const response = await this.ua.get(checkers.ProgramsWrapper, `/api/homeappliances/${haid}/programs`);
return this.checkValues.programs(haid, response.data);
}
// Get a list of the available programs
async getAvailablePrograms(haid) {
const response = await this.ua.get(checkers.ProgramsWrapper, `/api/homeappliances/${haid}/programs/available`);
return this.checkValues.programs(haid, response.data);
}
// Get the details of a specific available programs
async getAvailableProgram(haid, key) {
const response = await this.ua.get(checkers.ProgramDefinitionWrapper, `/api/homeappliances/${haid}/programs/available/${key}`);
return this.checkValues.programDefinition(haid, response.data);
}
// Get the program which is currently being executed
async getActiveProgram(haid) {
const response = await this.ua.get(checkers.ProgramWrapper, `/api/homeappliances/${haid}/programs/active`);
return this.checkValues.program(haid, response.data);
}
// Start a specified program
setActiveProgram(haid, key, options = []) {
const putBody = { data: { key, options } };
return this.ua.put(`/api/homeappliances/${haid}/programs/active`, putBody);
}
// Stop the active program
stopActiveProgram(haid) {
return this.ua.delete(`/api/homeappliances/${haid}/programs/active`);
}
// Get all options of the active program
async getActiveProgramOptions(haid) {
const response = await this.ua.get(checkers.OptionsWrapper, `/api/homeappliances/${haid}/programs/active/options`);
return this.checkValues.options(haid, response.data.options);
}
// Set all options of the active program
setActiveProgramOptions(haid, options) {
const putBody = { data: { options } };
return this.ua.put(`/api/homeappliances/${haid}/programs/active/options`, putBody);
}
// Get a specific option of the active program
async getActiveProgramOption(haid, key) {
const response = await this.ua.get(checkers.OptionWrapper, `/api/homeappliances/${haid}/programs/active/options/${key}`);
return this.checkValues.option(haid, response.data);
}
// Set a specific option of the active program
setActiveProgramOption(haid, key, value) {
const putBody = { data: { key, value } };
return this.ua.put(`/api/homeappliances/${haid}/programs/active/options/${key}`, putBody);
}
// Get the program which is currently selected
async getSelectedProgram(haid) {
const response = await this.ua.get(checkers.ProgramWrapper, `/api/homeappliances/${haid}/programs/selected`);
return this.checkValues.program(haid, response.data);
}
// Select a program
setSelectedProgram(haid, key, options) {
const putBody = { data: { key, options } };
return this.ua.put(`/api/homeappliances/${haid}/programs/selected`, putBody);
}
// Get all options of the selected program
async getSelectedProgramOptions(haid) {
const response = await this.ua.get(checkers.OptionsWrapper, `/api/homeappliances/${haid}/programs/selected/options`);
return this.checkValues.options(haid, response.data.options);
}
// Set all options of the selected program
setSelectedProgramOptions(haid, options) {
const putBody = { data: { options } };
return this.ua.put(`/api/homeappliances/${haid}/programs/selected/options`, putBody);
}
// Get a specific option of the selected program
async getSelectedProgramOption(haid, key) {
const response = await this.ua.get(checkers.OptionWrapper, `/api/homeappliances/${haid}/programs/selected/options/${key}`);
return this.checkValues.option(haid, response.data);
}
// Set a specific option of the selected program
setSelectedProgramOption(haid, key, value) {
const putBody = { data: { key, value } };
return this.ua.put(`/api/homeappliances/${haid}/programs/selected/options/${key}`, putBody);
}
// Get the current status
async getStatus(haid) {
const response = await this.ua.get(checkers.StatusesWrapper, `/api/homeappliances/${haid}/status`);
return this.checkValues.statuses(haid, response.data.status);
}
// Get a specific status
async getStatusSpecific(haid, key) {
const response = await this.ua.get(checkers.StatusWrapper, `/api/homeappliances/${haid}/status/${key}`);
return this.checkValues.status(haid, response.data);
}
// Get all settings
async getSettings(haid) {
const response = await this.ua.get(checkers.SettingsWrapper, `/api/homeappliances/${haid}/settings`);
return this.checkValues.settings(haid, response.data.settings);
}
// Get a specific setting
async getSetting(haid, key) {
const response = await this.ua.get(checkers.SettingWrapper, `/api/homeappliances/${haid}/settings/${key}`);
return this.checkValues.setting(haid, response.data);
}
// Set a specific setting
setSetting(haid, key, value) {
const putBody = { data: { key, value } };
return this.ua.put(`/api/homeappliances/${haid}/settings/${key}`, putBody);
}
// Get a list of supported commands
async getCommands(haid) {
const response = await this.ua.get(checkers.CommandsWrapper, `/api/homeappliances/${haid}/commands`);
return this.checkValues.commands(haid, response.data.commands);
}
// Issue a command
setCommand(haid, key) {
const putBody = { data: { key, value: true } };
return this.ua.put(`/api/homeappliances/${haid}/commands/${key}`, putBody);
}
// Get events for a single appliance or all appliances
async *getEvents(haid) {
const events = on(this.events, 'event');
for await (const [event] of events) {
if (event.event !== 'KEEP-ALIVE'
&& (haid === undefined || !('id' in event) || event.id === haid)) {
yield this.checkValues.event('id' in event ? event.id : '', event);
}
}
}
// Get authorisation status updates
getAuthorisationStatus(immediate = false) {
return this.ua.getAuthorisationStatus(immediate);
}
// Trigger a retry of Device Flow authorisation
retryAuthorisation() {
this.ua.retryDeviceFlow();
}
}
//# sourceMappingURL=api.js.map