Add TypeScript integrations package
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
import { createDefaultIntegrationRegistry } from '../index.js';
|
||||
import { ConsoleLogger, DiscoveryEngine } from '../core/index.js';
|
||||
import { commandDiscover } from './commands.discover.js';
|
||||
import { commandInspect } from './commands.inspect.js';
|
||||
import { commandList } from './commands.list.js';
|
||||
import { commandSetup } from './commands.setup.js';
|
||||
|
||||
export class CliRuntime {
|
||||
public integrationRegistry = createDefaultIntegrationRegistry();
|
||||
public discoveryEngine = new DiscoveryEngine(this.integrationRegistry);
|
||||
public logger = new ConsoleLogger();
|
||||
|
||||
public async list(): Promise<string> {
|
||||
return commandList(this.integrationRegistry);
|
||||
}
|
||||
|
||||
public async inspect(domainArg: string): Promise<string> {
|
||||
return commandInspect(this.integrationRegistry, domainArg);
|
||||
}
|
||||
|
||||
public async discover() {
|
||||
return commandDiscover(this.discoveryEngine, {
|
||||
logger: this.logger,
|
||||
});
|
||||
}
|
||||
|
||||
public async setup(domainArg: string) {
|
||||
return commandSetup(this.integrationRegistry, domainArg);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import type { DiscoveryEngine, IDiscoveryCandidate, IDiscoveryContext } from '../core/index.js';
|
||||
|
||||
export const commandDiscover = async (
|
||||
discoveryEngineArg: DiscoveryEngine,
|
||||
contextArg: IDiscoveryContext = {}
|
||||
): Promise<IDiscoveryCandidate[]> => {
|
||||
return discoveryEngineArg.runActiveDiscovery(contextArg);
|
||||
};
|
||||
@@ -0,0 +1,24 @@
|
||||
import type { IntegrationRegistry } from '../core/index.js';
|
||||
|
||||
export const commandInspect = (registryArg: IntegrationRegistry, domainArg: string): string => {
|
||||
const integration = registryArg.get(domainArg);
|
||||
if (!integration) {
|
||||
throw new Error(`Integration not found: ${domainArg}`);
|
||||
}
|
||||
|
||||
const descriptor = integration.discoveryDescriptor;
|
||||
const probes = descriptor.getProbes();
|
||||
const matchers = descriptor.getMatchers();
|
||||
const validators = descriptor.getValidators();
|
||||
|
||||
return [
|
||||
`Domain: ${integration.domain}`,
|
||||
`Name: ${integration.displayName}`,
|
||||
`Status: ${integration.status}`,
|
||||
'',
|
||||
'Discovery:',
|
||||
` probes: ${probes.length ? probes.map((probeArg) => probeArg.id).join(', ') : 'none'}`,
|
||||
` matchers: ${matchers.length ? matchers.map((matcherArg) => matcherArg.id).join(', ') : 'none'}`,
|
||||
` validators: ${validators.length ? validators.map((validatorArg) => validatorArg.id).join(', ') : 'none'}`,
|
||||
].join('\n');
|
||||
};
|
||||
@@ -0,0 +1,8 @@
|
||||
import type { IntegrationRegistry } from '../core/index.js';
|
||||
|
||||
export const commandList = (registryArg: IntegrationRegistry): string => {
|
||||
return registryArg
|
||||
.list()
|
||||
.map((integrationArg) => `${integrationArg.domain}\t${integrationArg.displayName}\t${integrationArg.status}`)
|
||||
.join('\n');
|
||||
};
|
||||
@@ -0,0 +1,32 @@
|
||||
import type { IntegrationRegistry } from '../core/index.js';
|
||||
|
||||
export const commandSetup = async (registryArg: IntegrationRegistry, domainArg: string) => {
|
||||
const integration = registryArg.get(domainArg) as any;
|
||||
if (!integration) {
|
||||
throw new Error(`Integration not found: ${domainArg}`);
|
||||
}
|
||||
if (!integration.configFlow) {
|
||||
return {
|
||||
domain: domainArg,
|
||||
status: 'no-config-flow',
|
||||
};
|
||||
}
|
||||
const step = await integration.configFlow.start(
|
||||
{
|
||||
source: 'manual',
|
||||
integrationDomain: domainArg,
|
||||
id: `${domainArg}:manual`,
|
||||
},
|
||||
{}
|
||||
);
|
||||
return {
|
||||
domain: domainArg,
|
||||
step: {
|
||||
kind: step.kind,
|
||||
title: step.title,
|
||||
description: step.description,
|
||||
fields: step.fields,
|
||||
error: step.error,
|
||||
},
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,41 @@
|
||||
import { CliRuntime } from './classes.cliruntime.js';
|
||||
|
||||
export * from './classes.cliruntime.js';
|
||||
export * from './commands.discover.js';
|
||||
export * from './commands.inspect.js';
|
||||
export * from './commands.list.js';
|
||||
export * from './commands.setup.js';
|
||||
|
||||
export const runCli = async (argvArg = process.argv.slice(2)) => {
|
||||
const runtime = new CliRuntime();
|
||||
const [commandArg = 'list', integrationArg] = argvArg;
|
||||
|
||||
if (commandArg === 'list') {
|
||||
console.log(await runtime.list());
|
||||
return;
|
||||
}
|
||||
|
||||
if (commandArg === 'inspect') {
|
||||
console.log(await runtime.inspect(integrationArg || 'hue'));
|
||||
return;
|
||||
}
|
||||
|
||||
if (commandArg === 'discover') {
|
||||
console.log(JSON.stringify(await runtime.discover(), null, 2));
|
||||
return;
|
||||
}
|
||||
|
||||
if (commandArg === 'setup') {
|
||||
console.log(JSON.stringify(await runtime.setup(integrationArg || 'hue'), null, 2));
|
||||
return;
|
||||
}
|
||||
|
||||
throw new Error(`Unknown integrations CLI command: ${commandArg}`);
|
||||
};
|
||||
|
||||
if (process.argv[1]?.endsWith('/cli.js') || process.argv[1]?.endsWith('/cli.ts.js')) {
|
||||
runCli().catch((errorArg) => {
|
||||
console.error(errorArg.message);
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import type { DiscoveryDescriptor } from './classes.discoverydescriptor.js';
|
||||
import type { IIntegrationRuntime, IIntegrationSetupContext, TIntegrationStatus } from './types.js';
|
||||
|
||||
export abstract class BaseIntegration<TConfig = unknown> {
|
||||
public abstract readonly domain: string;
|
||||
public abstract readonly displayName: string;
|
||||
public abstract readonly status: TIntegrationStatus;
|
||||
public abstract readonly discoveryDescriptor: DiscoveryDescriptor;
|
||||
|
||||
public abstract setup(
|
||||
configArg: TConfig,
|
||||
contextArg: IIntegrationSetupContext
|
||||
): Promise<IIntegrationRuntime>;
|
||||
|
||||
public abstract destroy(): Promise<void>;
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
import * as plugins from '../plugins.js';
|
||||
import type { IConfigStore } from './types.js';
|
||||
|
||||
export class JsonFileConfigStore implements IConfigStore {
|
||||
constructor(private readonly filePath: string) {}
|
||||
|
||||
public async get<TValue>(keyArg: string): Promise<TValue | undefined> {
|
||||
const data = await this.readFile();
|
||||
return data[keyArg] as TValue | undefined;
|
||||
}
|
||||
|
||||
public async set<TValue>(keyArg: string, valueArg: TValue): Promise<void> {
|
||||
const data = await this.readFile();
|
||||
data[keyArg] = valueArg;
|
||||
await this.writeFile(data);
|
||||
}
|
||||
|
||||
public async delete(keyArg: string): Promise<void> {
|
||||
const data = await this.readFile();
|
||||
delete data[keyArg];
|
||||
await this.writeFile(data);
|
||||
}
|
||||
|
||||
public async list(prefixArg = ''): Promise<string[]> {
|
||||
const data = await this.readFile();
|
||||
return Object.keys(data).filter((keyArg) => keyArg.startsWith(prefixArg));
|
||||
}
|
||||
|
||||
private async readFile(): Promise<Record<string, unknown>> {
|
||||
try {
|
||||
const fileString = await plugins.fs.readFile(this.filePath, 'utf8');
|
||||
return JSON.parse(fileString) as Record<string, unknown>;
|
||||
} catch (error) {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
private async writeFile(dataArg: Record<string, unknown>): Promise<void> {
|
||||
await plugins.fs.mkdir(plugins.path.dirname(this.filePath), { recursive: true });
|
||||
await plugins.fs.writeFile(this.filePath, `${JSON.stringify(dataArg, null, 2)}\n`);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
import { BaseIntegration } from './classes.baseintegration.js';
|
||||
import { DiscoveryDescriptor } from './classes.discoverydescriptor.js';
|
||||
import { IntegrationError } from './errors.js';
|
||||
import type { IIntegrationRuntime, IIntegrationSetupContext, TIntegrationStatus } from './types.js';
|
||||
|
||||
export interface IDescriptorOnlyIntegrationOptions {
|
||||
domain: string;
|
||||
displayName: string;
|
||||
status?: TIntegrationStatus;
|
||||
metadata?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
export class DescriptorOnlyIntegration extends BaseIntegration<unknown> {
|
||||
public readonly domain: string;
|
||||
public readonly displayName: string;
|
||||
public readonly status: TIntegrationStatus;
|
||||
public readonly discoveryDescriptor: DiscoveryDescriptor;
|
||||
public readonly metadata: Record<string, unknown>;
|
||||
|
||||
constructor(optionsArg: IDescriptorOnlyIntegrationOptions) {
|
||||
super();
|
||||
this.domain = optionsArg.domain;
|
||||
this.displayName = optionsArg.displayName;
|
||||
this.status = optionsArg.status || 'descriptor-only';
|
||||
this.metadata = optionsArg.metadata || {};
|
||||
this.discoveryDescriptor = new DiscoveryDescriptor({
|
||||
integrationDomain: this.domain,
|
||||
displayName: this.displayName,
|
||||
});
|
||||
}
|
||||
|
||||
public async setup(configArg: unknown, contextArg: IIntegrationSetupContext): Promise<IIntegrationRuntime> {
|
||||
void configArg;
|
||||
void contextArg;
|
||||
throw new IntegrationError(
|
||||
`Integration ${this.domain} is descriptor-only and has no TypeScript runtime yet.`,
|
||||
'DESCRIPTOR_ONLY_INTEGRATION'
|
||||
);
|
||||
}
|
||||
|
||||
public async destroy(): Promise<void> {}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
import type {
|
||||
IDiscoveryDescriptorOptions,
|
||||
IDiscoveryMatcher,
|
||||
IDiscoveryProbe,
|
||||
IDiscoveryValidator,
|
||||
} from './types.js';
|
||||
|
||||
export class DiscoveryDescriptor {
|
||||
public readonly integrationDomain: string;
|
||||
public readonly displayName: string;
|
||||
|
||||
private readonly probes: IDiscoveryProbe[] = [];
|
||||
private readonly matchers: IDiscoveryMatcher[] = [];
|
||||
private readonly validators: IDiscoveryValidator[] = [];
|
||||
|
||||
constructor(optionsArg: IDiscoveryDescriptorOptions) {
|
||||
this.integrationDomain = optionsArg.integrationDomain;
|
||||
this.displayName = optionsArg.displayName;
|
||||
}
|
||||
|
||||
public addProbe(probeArg: IDiscoveryProbe): this {
|
||||
this.probes.push(probeArg);
|
||||
return this;
|
||||
}
|
||||
|
||||
public addMatcher<TInput>(matcherArg: IDiscoveryMatcher<TInput>): this {
|
||||
this.matchers.push(matcherArg as IDiscoveryMatcher);
|
||||
return this;
|
||||
}
|
||||
|
||||
public addValidator(validatorArg: IDiscoveryValidator): this {
|
||||
this.validators.push(validatorArg);
|
||||
return this;
|
||||
}
|
||||
|
||||
public getProbes(): IDiscoveryProbe[] {
|
||||
return [...this.probes];
|
||||
}
|
||||
|
||||
public getMatchers(): IDiscoveryMatcher[] {
|
||||
return [...this.matchers];
|
||||
}
|
||||
|
||||
public getValidators(): IDiscoveryValidator[] {
|
||||
return [...this.validators];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
import type { IntegrationRegistry } from './classes.integrationregistry.js';
|
||||
import type {
|
||||
IDiscoveryCandidate,
|
||||
IDiscoveryContext,
|
||||
IDiscoveryMatch,
|
||||
TDiscoverySource,
|
||||
} from './types.js';
|
||||
|
||||
export class DiscoveryEngine {
|
||||
constructor(private readonly integrationRegistry: IntegrationRegistry) {}
|
||||
|
||||
public async runActiveDiscovery(contextArg: IDiscoveryContext = {}): Promise<IDiscoveryCandidate[]> {
|
||||
const candidates: IDiscoveryCandidate[] = [];
|
||||
|
||||
for (const integration of this.integrationRegistry.list()) {
|
||||
const descriptor = integration.discoveryDescriptor;
|
||||
for (const probe of descriptor.getProbes()) {
|
||||
const result = await probe.probe(contextArg);
|
||||
for (const candidate of result.candidates) {
|
||||
candidates.push({
|
||||
...candidate,
|
||||
integrationDomain: candidate.integrationDomain ?? integration.domain,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return candidates;
|
||||
}
|
||||
|
||||
public async matchExistingData<TInput>(
|
||||
sourceArg: TDiscoverySource,
|
||||
inputArg: TInput,
|
||||
contextArg: IDiscoveryContext = {}
|
||||
): Promise<IDiscoveryMatch[]> {
|
||||
const matches: IDiscoveryMatch[] = [];
|
||||
|
||||
for (const integration of this.integrationRegistry.list()) {
|
||||
const descriptor = integration.discoveryDescriptor;
|
||||
for (const matcher of descriptor.getMatchers()) {
|
||||
if (matcher.source !== sourceArg) {
|
||||
continue;
|
||||
}
|
||||
const result = await matcher.matches(inputArg, contextArg);
|
||||
if (result.matched) {
|
||||
matches.push(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return matches;
|
||||
}
|
||||
|
||||
public async validateCandidate(
|
||||
candidateArg: IDiscoveryCandidate,
|
||||
contextArg: IDiscoveryContext = {}
|
||||
): Promise<IDiscoveryMatch[]> {
|
||||
const matches: IDiscoveryMatch[] = [];
|
||||
const integrations = candidateArg.integrationDomain
|
||||
? this.integrationRegistry.list().filter((integrationArg) => integrationArg.domain === candidateArg.integrationDomain)
|
||||
: this.integrationRegistry.list();
|
||||
|
||||
for (const integration of integrations) {
|
||||
for (const validator of integration.discoveryDescriptor.getValidators()) {
|
||||
const result = await validator.validate(candidateArg, contextArg);
|
||||
if (result.matched) {
|
||||
matches.push(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return matches;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import type { BaseIntegration } from './classes.baseintegration.js';
|
||||
import type { DiscoveryDescriptor } from './classes.discoverydescriptor.js';
|
||||
|
||||
export class IntegrationRegistry {
|
||||
private readonly integrations = new Map<string, BaseIntegration>();
|
||||
|
||||
public register(integrationArg: BaseIntegration): void {
|
||||
if (this.integrations.has(integrationArg.domain)) {
|
||||
throw new Error(`Integration already registered: ${integrationArg.domain}`);
|
||||
}
|
||||
this.integrations.set(integrationArg.domain, integrationArg);
|
||||
}
|
||||
|
||||
public get(domainArg: string): BaseIntegration | undefined {
|
||||
return this.integrations.get(domainArg);
|
||||
}
|
||||
|
||||
public list(): BaseIntegration[] {
|
||||
return [...this.integrations.values()];
|
||||
}
|
||||
|
||||
public getDiscoveryDescriptors(): DiscoveryDescriptor[] {
|
||||
return this.list().map((integrationArg) => integrationArg.discoveryDescriptor);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import type { ILogger } from './types.js';
|
||||
|
||||
export class ConsoleLogger implements ILogger {
|
||||
public log(levelArg: 'debug' | 'info' | 'warn' | 'error', messageArg: string, metadataArg?: Record<string, unknown>): void {
|
||||
const payload = metadataArg ? ` ${JSON.stringify(metadataArg)}` : '';
|
||||
console[levelArg === 'debug' ? 'log' : levelArg](`[${levelArg}] ${messageArg}${payload}`);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import type { BaseIntegration } from './classes.baseintegration.js';
|
||||
import type { IIntegrationRuntime, IIntegrationSetupContext } from './types.js';
|
||||
|
||||
export class IntegrationRuntimeManager {
|
||||
private readonly runtimes = new Map<string, IIntegrationRuntime>();
|
||||
|
||||
public async setupIntegration<TConfig>(
|
||||
integrationArg: BaseIntegration<TConfig>,
|
||||
configArg: TConfig,
|
||||
contextArg: IIntegrationSetupContext = {}
|
||||
): Promise<IIntegrationRuntime> {
|
||||
const runtime = await integrationArg.setup(configArg, contextArg);
|
||||
this.runtimes.set(integrationArg.domain, runtime);
|
||||
return runtime;
|
||||
}
|
||||
|
||||
public getRuntime(domainArg: string): IIntegrationRuntime | undefined {
|
||||
return this.runtimes.get(domainArg);
|
||||
}
|
||||
|
||||
public listRuntimes(): IIntegrationRuntime[] {
|
||||
return [...this.runtimes.values()];
|
||||
}
|
||||
|
||||
public async destroyAll(): Promise<void> {
|
||||
for (const runtime of this.runtimes.values()) {
|
||||
await runtime.destroy();
|
||||
}
|
||||
this.runtimes.clear();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
export class IntegrationError extends Error {
|
||||
constructor(
|
||||
messageArg: string,
|
||||
public readonly code: string,
|
||||
public readonly cause?: unknown
|
||||
) {
|
||||
super(messageArg);
|
||||
}
|
||||
}
|
||||
|
||||
export class DiscoveryError extends IntegrationError {
|
||||
constructor(messageArg: string, causeArg?: unknown) {
|
||||
super(messageArg, 'DISCOVERY_ERROR', causeArg);
|
||||
}
|
||||
}
|
||||
|
||||
export class AuthenticationError extends IntegrationError {
|
||||
constructor(messageArg: string, causeArg?: unknown) {
|
||||
super(messageArg, 'AUTHENTICATION_ERROR', causeArg);
|
||||
}
|
||||
}
|
||||
|
||||
export class DeviceCommunicationError extends IntegrationError {
|
||||
constructor(messageArg: string, causeArg?: unknown) {
|
||||
super(messageArg, 'DEVICE_COMMUNICATION_ERROR', causeArg);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
export * from './classes.baseintegration.js';
|
||||
export * from './classes.configstore.js';
|
||||
export * from './classes.descriptoronlyintegration.js';
|
||||
export * from './classes.discoverydescriptor.js';
|
||||
export * from './classes.discoveryengine.js';
|
||||
export * from './classes.integrationregistry.js';
|
||||
export * from './classes.logger.js';
|
||||
export * from './classes.runtimemanager.js';
|
||||
export * from './errors.js';
|
||||
export * from './types.js';
|
||||
@@ -0,0 +1,208 @@
|
||||
import * as plugins from '../plugins.js';
|
||||
|
||||
export type TDiscoverySource =
|
||||
| 'mdns'
|
||||
| 'ssdp'
|
||||
| 'dhcp'
|
||||
| 'bluetooth'
|
||||
| 'usb'
|
||||
| 'mqtt'
|
||||
| 'http'
|
||||
| 'manual'
|
||||
| 'broker'
|
||||
| 'cloud'
|
||||
| 'custom';
|
||||
|
||||
export type TDiscoveryConfidence = 'low' | 'medium' | 'high' | 'certain';
|
||||
|
||||
export type TIntegrationStatus =
|
||||
| 'descriptor-only'
|
||||
| 'discovery-supported'
|
||||
| 'config-flow-supported'
|
||||
| 'read-only-runtime'
|
||||
| 'control-runtime'
|
||||
| 'production-ready';
|
||||
|
||||
export interface ILogger {
|
||||
log(levelArg: 'debug' | 'info' | 'warn' | 'error', messageArg: string, metadataArg?: Record<string, unknown>): void;
|
||||
}
|
||||
|
||||
export interface INetworkInterface {
|
||||
name: string;
|
||||
address: string;
|
||||
family: 'IPv4' | 'IPv6';
|
||||
internal: boolean;
|
||||
}
|
||||
|
||||
export interface IConfigStore {
|
||||
get<TValue>(keyArg: string): Promise<TValue | undefined>;
|
||||
set<TValue>(keyArg: string, valueArg: TValue): Promise<void>;
|
||||
delete(keyArg: string): Promise<void>;
|
||||
list(prefixArg?: string): Promise<string[]>;
|
||||
}
|
||||
|
||||
export interface IDiscoveryContext {
|
||||
abortSignal?: AbortSignal;
|
||||
logger?: ILogger;
|
||||
networkInterfaces?: INetworkInterface[];
|
||||
configStore?: IConfigStore;
|
||||
}
|
||||
|
||||
export interface IDiscoveryCandidate {
|
||||
source: TDiscoverySource;
|
||||
integrationDomain?: string;
|
||||
id?: string;
|
||||
host?: string;
|
||||
port?: number;
|
||||
name?: string;
|
||||
manufacturer?: string;
|
||||
model?: string;
|
||||
serialNumber?: string;
|
||||
macAddress?: string;
|
||||
metadata?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
export interface IDiscoveryProbeResult {
|
||||
candidates: IDiscoveryCandidate[];
|
||||
}
|
||||
|
||||
export interface IDiscoveryMatch {
|
||||
matched: boolean;
|
||||
confidence: TDiscoveryConfidence;
|
||||
reason: string;
|
||||
candidate?: IDiscoveryCandidate;
|
||||
normalizedDeviceId?: string;
|
||||
metadata?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
export interface IDiscoveryProbe {
|
||||
id: string;
|
||||
source: TDiscoverySource;
|
||||
description?: string;
|
||||
probe(contextArg: IDiscoveryContext): Promise<IDiscoveryProbeResult>;
|
||||
}
|
||||
|
||||
export interface IDiscoveryMatcher<TInput = unknown> {
|
||||
id: string;
|
||||
source: TDiscoverySource;
|
||||
description?: string;
|
||||
matches(inputArg: TInput, contextArg: IDiscoveryContext): Promise<IDiscoveryMatch>;
|
||||
}
|
||||
|
||||
export interface IDiscoveryValidator {
|
||||
id: string;
|
||||
description?: string;
|
||||
validate(candidateArg: IDiscoveryCandidate, contextArg: IDiscoveryContext): Promise<IDiscoveryMatch>;
|
||||
}
|
||||
|
||||
export interface IDiscoveryDescriptorOptions {
|
||||
integrationDomain: string;
|
||||
displayName: string;
|
||||
}
|
||||
|
||||
export interface IIntegrationSetupContext {
|
||||
logger?: ILogger;
|
||||
configStore?: IConfigStore;
|
||||
abortSignal?: AbortSignal;
|
||||
}
|
||||
|
||||
export type TEntityPlatform =
|
||||
| 'light'
|
||||
| 'switch'
|
||||
| 'sensor'
|
||||
| 'binary_sensor'
|
||||
| 'button'
|
||||
| 'climate'
|
||||
| 'cover'
|
||||
| 'fan'
|
||||
| 'number'
|
||||
| 'select'
|
||||
| 'text'
|
||||
| 'update';
|
||||
|
||||
export interface IIntegrationEntity<TState = unknown> {
|
||||
id: string;
|
||||
uniqueId: string;
|
||||
integrationDomain: string;
|
||||
deviceId: string;
|
||||
platform: TEntityPlatform;
|
||||
name: string;
|
||||
state: TState;
|
||||
attributes?: Record<string, unknown>;
|
||||
available: boolean;
|
||||
}
|
||||
|
||||
export interface IServiceCallRequest {
|
||||
domain: string;
|
||||
service: string;
|
||||
target: {
|
||||
entityId?: string;
|
||||
deviceId?: string;
|
||||
};
|
||||
data?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
export interface IServiceCallResult {
|
||||
success: boolean;
|
||||
error?: string;
|
||||
data?: unknown;
|
||||
}
|
||||
|
||||
export type TIntegrationEventType =
|
||||
| 'device_added'
|
||||
| 'device_removed'
|
||||
| 'entity_added'
|
||||
| 'entity_removed'
|
||||
| 'state_changed'
|
||||
| 'availability_changed'
|
||||
| 'error';
|
||||
|
||||
export interface IIntegrationEvent {
|
||||
type: TIntegrationEventType;
|
||||
integrationDomain: string;
|
||||
deviceId?: string;
|
||||
entityId?: string;
|
||||
data?: unknown;
|
||||
timestamp: number;
|
||||
}
|
||||
|
||||
export interface IIntegrationRuntime {
|
||||
domain: string;
|
||||
devices(): Promise<plugins.shxInterfaces.data.IDeviceDefinition[]>;
|
||||
entities(): Promise<IIntegrationEntity[]>;
|
||||
subscribe?(handlerArg: (eventArg: IIntegrationEvent) => void): Promise<() => Promise<void>>;
|
||||
callService?(requestArg: IServiceCallRequest): Promise<IServiceCallResult>;
|
||||
destroy(): Promise<void>;
|
||||
}
|
||||
|
||||
export type TConfigFlowStepKind = 'form' | 'wait' | 'done' | 'error';
|
||||
|
||||
export interface IConfigFlowField {
|
||||
name: string;
|
||||
label: string;
|
||||
type: 'text' | 'password' | 'number' | 'boolean' | 'select';
|
||||
required?: boolean;
|
||||
options?: Array<{
|
||||
label: string;
|
||||
value: string;
|
||||
}>;
|
||||
}
|
||||
|
||||
export interface IConfigFlowContext {
|
||||
logger?: ILogger;
|
||||
configStore?: IConfigStore;
|
||||
}
|
||||
|
||||
export interface IConfigFlowStep<TConfig = unknown> {
|
||||
kind: TConfigFlowStepKind;
|
||||
title?: string;
|
||||
description?: string;
|
||||
fields?: IConfigFlowField[];
|
||||
submit?(valuesArg: Record<string, unknown>): Promise<IConfigFlowStep<TConfig>>;
|
||||
config?: TConfig;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
export interface IConfigFlow<TConfig = unknown> {
|
||||
start(candidateArg: IDiscoveryCandidate, contextArg: IConfigFlowContext): Promise<IConfigFlowStep<TConfig>>;
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
export * from './core/index.js';
|
||||
export * from './protocols/index.js';
|
||||
export * from './integrations/index.js';
|
||||
|
||||
import { HueIntegration } from './integrations/hue/index.js';
|
||||
import { ShellyIntegration } from './integrations/shelly/index.js';
|
||||
import { WolfSmartsetIntegration } from './integrations/wolf_smartset/index.js';
|
||||
import { generatedHomeAssistantPortIntegrations } from './integrations/generated/index.js';
|
||||
import { IntegrationRegistry } from './core/index.js';
|
||||
|
||||
export const integrations = [
|
||||
new HueIntegration(),
|
||||
new ShellyIntegration(),
|
||||
new WolfSmartsetIntegration(),
|
||||
];
|
||||
|
||||
export const createDefaultIntegrationRegistry = (): IntegrationRegistry => {
|
||||
const registry = new IntegrationRegistry();
|
||||
for (const integration of integrations) {
|
||||
registry.register(integration);
|
||||
}
|
||||
for (const integration of generatedHomeAssistantPortIntegrations) {
|
||||
if (!registry.get(integration.domain)) {
|
||||
registry.register(integration);
|
||||
}
|
||||
}
|
||||
return registry;
|
||||
};
|
||||
@@ -0,0 +1 @@
|
||||
This folder is generated from Home Assistant component metadata. Replace it with a handwritten TypeScript port when implementing runtime support.
|
||||
@@ -0,0 +1,21 @@
|
||||
import { DescriptorOnlyIntegration } from '../../core/classes.descriptoronlyintegration.js';
|
||||
|
||||
export class HomeAssistant3DayBlindsIntegration extends DescriptorOnlyIntegration {
|
||||
constructor() {
|
||||
super({
|
||||
domain: "3_day_blinds",
|
||||
displayName: "3 Day Blinds",
|
||||
status: 'descriptor-only',
|
||||
metadata: {
|
||||
"source": "home-assistant/core",
|
||||
"upstreamPath": "homeassistant/components/3_day_blinds",
|
||||
"upstreamDomain": "3_day_blinds",
|
||||
"integrationType": "virtual",
|
||||
"requirements": [],
|
||||
"dependencies": [],
|
||||
"afterDependencies": [],
|
||||
"codeowners": []
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export interface IHomeAssistant3DayBlindsConfig {
|
||||
// TODO: replace with the TypeScript-native config for 3_day_blinds.
|
||||
[key: string]: unknown;
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './3_day_blinds.classes.integration.js';
|
||||
export * from './3_day_blinds.types.js';
|
||||
@@ -0,0 +1 @@
|
||||
This folder is generated from Home Assistant component metadata. Replace it with a handwritten TypeScript port when implementing runtime support.
|
||||
@@ -0,0 +1,25 @@
|
||||
import { DescriptorOnlyIntegration } from '../../core/classes.descriptoronlyintegration.js';
|
||||
|
||||
export class HomeAssistantAbodeIntegration extends DescriptorOnlyIntegration {
|
||||
constructor() {
|
||||
super({
|
||||
domain: "abode",
|
||||
displayName: "Abode",
|
||||
status: 'descriptor-only',
|
||||
metadata: {
|
||||
"source": "home-assistant/core",
|
||||
"upstreamPath": "homeassistant/components/abode",
|
||||
"upstreamDomain": "abode",
|
||||
"iotClass": "cloud_push",
|
||||
"requirements": [
|
||||
"jaraco.abode==6.4.0"
|
||||
],
|
||||
"dependencies": [],
|
||||
"afterDependencies": [],
|
||||
"codeowners": [
|
||||
"@shred86"
|
||||
]
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export interface IHomeAssistantAbodeConfig {
|
||||
// TODO: replace with the TypeScript-native config for abode.
|
||||
[key: string]: unknown;
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './abode.classes.integration.js';
|
||||
export * from './abode.types.js';
|
||||
@@ -0,0 +1 @@
|
||||
This folder is generated from Home Assistant component metadata. Replace it with a handwritten TypeScript port when implementing runtime support.
|
||||
@@ -0,0 +1,29 @@
|
||||
import { DescriptorOnlyIntegration } from '../../core/classes.descriptoronlyintegration.js';
|
||||
|
||||
export class HomeAssistantAcaiaIntegration extends DescriptorOnlyIntegration {
|
||||
constructor() {
|
||||
super({
|
||||
domain: "acaia",
|
||||
displayName: "Acaia",
|
||||
status: 'descriptor-only',
|
||||
metadata: {
|
||||
"source": "home-assistant/core",
|
||||
"upstreamPath": "homeassistant/components/acaia",
|
||||
"upstreamDomain": "acaia",
|
||||
"integrationType": "device",
|
||||
"iotClass": "local_push",
|
||||
"qualityScale": "platinum",
|
||||
"requirements": [
|
||||
"aioacaia==0.1.17"
|
||||
],
|
||||
"dependencies": [
|
||||
"bluetooth_adapters"
|
||||
],
|
||||
"afterDependencies": [],
|
||||
"codeowners": [
|
||||
"@zweckj"
|
||||
]
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export interface IHomeAssistantAcaiaConfig {
|
||||
// TODO: replace with the TypeScript-native config for acaia.
|
||||
[key: string]: unknown;
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './acaia.classes.integration.js';
|
||||
export * from './acaia.types.js';
|
||||
@@ -0,0 +1 @@
|
||||
This folder is generated from Home Assistant component metadata. Replace it with a handwritten TypeScript port when implementing runtime support.
|
||||
@@ -0,0 +1,26 @@
|
||||
import { DescriptorOnlyIntegration } from '../../core/classes.descriptoronlyintegration.js';
|
||||
|
||||
export class HomeAssistantAccuweatherIntegration extends DescriptorOnlyIntegration {
|
||||
constructor() {
|
||||
super({
|
||||
domain: "accuweather",
|
||||
displayName: "AccuWeather",
|
||||
status: 'descriptor-only',
|
||||
metadata: {
|
||||
"source": "home-assistant/core",
|
||||
"upstreamPath": "homeassistant/components/accuweather",
|
||||
"upstreamDomain": "accuweather",
|
||||
"integrationType": "service",
|
||||
"iotClass": "cloud_polling",
|
||||
"requirements": [
|
||||
"accuweather==5.1.0"
|
||||
],
|
||||
"dependencies": [],
|
||||
"afterDependencies": [],
|
||||
"codeowners": [
|
||||
"@bieniu"
|
||||
]
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export interface IHomeAssistantAccuweatherConfig {
|
||||
// TODO: replace with the TypeScript-native config for accuweather.
|
||||
[key: string]: unknown;
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './accuweather.classes.integration.js';
|
||||
export * from './accuweather.types.js';
|
||||
@@ -0,0 +1 @@
|
||||
This folder is generated from Home Assistant component metadata. Replace it with a handwritten TypeScript port when implementing runtime support.
|
||||
@@ -0,0 +1,24 @@
|
||||
import { DescriptorOnlyIntegration } from '../../core/classes.descriptoronlyintegration.js';
|
||||
|
||||
export class HomeAssistantAcerProjectorIntegration extends DescriptorOnlyIntegration {
|
||||
constructor() {
|
||||
super({
|
||||
domain: "acer_projector",
|
||||
displayName: "Acer Projector",
|
||||
status: 'descriptor-only',
|
||||
metadata: {
|
||||
"source": "home-assistant/core",
|
||||
"upstreamPath": "homeassistant/components/acer_projector",
|
||||
"upstreamDomain": "acer_projector",
|
||||
"iotClass": "local_polling",
|
||||
"qualityScale": "legacy",
|
||||
"requirements": [
|
||||
"serialx==1.4.1"
|
||||
],
|
||||
"dependencies": [],
|
||||
"afterDependencies": [],
|
||||
"codeowners": []
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export interface IHomeAssistantAcerProjectorConfig {
|
||||
// TODO: replace with the TypeScript-native config for acer_projector.
|
||||
[key: string]: unknown;
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './acer_projector.classes.integration.js';
|
||||
export * from './acer_projector.types.js';
|
||||
@@ -0,0 +1 @@
|
||||
This folder is generated from Home Assistant component metadata. Replace it with a handwritten TypeScript port when implementing runtime support.
|
||||
@@ -0,0 +1,25 @@
|
||||
import { DescriptorOnlyIntegration } from '../../core/classes.descriptoronlyintegration.js';
|
||||
|
||||
export class HomeAssistantAcmedaIntegration extends DescriptorOnlyIntegration {
|
||||
constructor() {
|
||||
super({
|
||||
domain: "acmeda",
|
||||
displayName: "Rollease Acmeda Automate",
|
||||
status: 'descriptor-only',
|
||||
metadata: {
|
||||
"source": "home-assistant/core",
|
||||
"upstreamPath": "homeassistant/components/acmeda",
|
||||
"upstreamDomain": "acmeda",
|
||||
"iotClass": "local_push",
|
||||
"requirements": [
|
||||
"aiopulse==0.4.6"
|
||||
],
|
||||
"dependencies": [],
|
||||
"afterDependencies": [],
|
||||
"codeowners": [
|
||||
"@atmurray"
|
||||
]
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export interface IHomeAssistantAcmedaConfig {
|
||||
// TODO: replace with the TypeScript-native config for acmeda.
|
||||
[key: string]: unknown;
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './acmeda.classes.integration.js';
|
||||
export * from './acmeda.types.js';
|
||||
@@ -0,0 +1 @@
|
||||
This folder is generated from Home Assistant component metadata. Replace it with a handwritten TypeScript port when implementing runtime support.
|
||||
@@ -0,0 +1,21 @@
|
||||
import { DescriptorOnlyIntegration } from '../../core/classes.descriptoronlyintegration.js';
|
||||
|
||||
export class HomeAssistantAcomaxIntegration extends DescriptorOnlyIntegration {
|
||||
constructor() {
|
||||
super({
|
||||
domain: "acomax",
|
||||
displayName: "Acomax",
|
||||
status: 'descriptor-only',
|
||||
metadata: {
|
||||
"source": "home-assistant/core",
|
||||
"upstreamPath": "homeassistant/components/acomax",
|
||||
"upstreamDomain": "acomax",
|
||||
"integrationType": "virtual",
|
||||
"requirements": [],
|
||||
"dependencies": [],
|
||||
"afterDependencies": [],
|
||||
"codeowners": []
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export interface IHomeAssistantAcomaxConfig {
|
||||
// TODO: replace with the TypeScript-native config for acomax.
|
||||
[key: string]: unknown;
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './acomax.classes.integration.js';
|
||||
export * from './acomax.types.js';
|
||||
@@ -0,0 +1 @@
|
||||
This folder is generated from Home Assistant component metadata. Replace it with a handwritten TypeScript port when implementing runtime support.
|
||||
@@ -0,0 +1,22 @@
|
||||
import { DescriptorOnlyIntegration } from '../../core/classes.descriptoronlyintegration.js';
|
||||
|
||||
export class HomeAssistantActiontecIntegration extends DescriptorOnlyIntegration {
|
||||
constructor() {
|
||||
super({
|
||||
domain: "actiontec",
|
||||
displayName: "Actiontec",
|
||||
status: 'descriptor-only',
|
||||
metadata: {
|
||||
"source": "home-assistant/core",
|
||||
"upstreamPath": "homeassistant/components/actiontec",
|
||||
"upstreamDomain": "actiontec",
|
||||
"iotClass": "local_polling",
|
||||
"qualityScale": "legacy",
|
||||
"requirements": [],
|
||||
"dependencies": [],
|
||||
"afterDependencies": [],
|
||||
"codeowners": []
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export interface IHomeAssistantActiontecConfig {
|
||||
// TODO: replace with the TypeScript-native config for actiontec.
|
||||
[key: string]: unknown;
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './actiontec.classes.integration.js';
|
||||
export * from './actiontec.types.js';
|
||||
@@ -0,0 +1 @@
|
||||
This folder is generated from Home Assistant component metadata. Replace it with a handwritten TypeScript port when implementing runtime support.
|
||||
@@ -0,0 +1,28 @@
|
||||
import { DescriptorOnlyIntegration } from '../../core/classes.descriptoronlyintegration.js';
|
||||
|
||||
export class HomeAssistantActronAirIntegration extends DescriptorOnlyIntegration {
|
||||
constructor() {
|
||||
super({
|
||||
domain: "actron_air",
|
||||
displayName: "Actron Air",
|
||||
status: 'descriptor-only',
|
||||
metadata: {
|
||||
"source": "home-assistant/core",
|
||||
"upstreamPath": "homeassistant/components/actron_air",
|
||||
"upstreamDomain": "actron_air",
|
||||
"integrationType": "hub",
|
||||
"iotClass": "cloud_polling",
|
||||
"qualityScale": "silver",
|
||||
"requirements": [
|
||||
"actron-neo-api==0.5.6"
|
||||
],
|
||||
"dependencies": [],
|
||||
"afterDependencies": [],
|
||||
"codeowners": [
|
||||
"@kclif9",
|
||||
"@JagadishDhanamjayam"
|
||||
]
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export interface IHomeAssistantActronAirConfig {
|
||||
// TODO: replace with the TypeScript-native config for actron_air.
|
||||
[key: string]: unknown;
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './actron_air.classes.integration.js';
|
||||
export * from './actron_air.types.js';
|
||||
@@ -0,0 +1 @@
|
||||
This folder is generated from Home Assistant component metadata. Replace it with a handwritten TypeScript port when implementing runtime support.
|
||||
@@ -0,0 +1,27 @@
|
||||
import { DescriptorOnlyIntegration } from '../../core/classes.descriptoronlyintegration.js';
|
||||
|
||||
export class HomeAssistantAdaxIntegration extends DescriptorOnlyIntegration {
|
||||
constructor() {
|
||||
super({
|
||||
domain: "adax",
|
||||
displayName: "Adax",
|
||||
status: 'descriptor-only',
|
||||
metadata: {
|
||||
"source": "home-assistant/core",
|
||||
"upstreamPath": "homeassistant/components/adax",
|
||||
"upstreamDomain": "adax",
|
||||
"iotClass": "local_polling",
|
||||
"requirements": [
|
||||
"adax==0.4.0",
|
||||
"Adax-local==0.3.0"
|
||||
],
|
||||
"dependencies": [],
|
||||
"afterDependencies": [],
|
||||
"codeowners": [
|
||||
"@danielhiversen",
|
||||
"@lazytarget"
|
||||
]
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export interface IHomeAssistantAdaxConfig {
|
||||
// TODO: replace with the TypeScript-native config for adax.
|
||||
[key: string]: unknown;
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './adax.classes.integration.js';
|
||||
export * from './adax.types.js';
|
||||
@@ -0,0 +1 @@
|
||||
This folder is generated from Home Assistant component metadata. Replace it with a handwritten TypeScript port when implementing runtime support.
|
||||
@@ -0,0 +1,26 @@
|
||||
import { DescriptorOnlyIntegration } from '../../core/classes.descriptoronlyintegration.js';
|
||||
|
||||
export class HomeAssistantAdguardIntegration extends DescriptorOnlyIntegration {
|
||||
constructor() {
|
||||
super({
|
||||
domain: "adguard",
|
||||
displayName: "AdGuard Home",
|
||||
status: 'descriptor-only',
|
||||
metadata: {
|
||||
"source": "home-assistant/core",
|
||||
"upstreamPath": "homeassistant/components/adguard",
|
||||
"upstreamDomain": "adguard",
|
||||
"integrationType": "service",
|
||||
"iotClass": "local_polling",
|
||||
"requirements": [
|
||||
"adguardhome==0.8.1"
|
||||
],
|
||||
"dependencies": [],
|
||||
"afterDependencies": [],
|
||||
"codeowners": [
|
||||
"@frenck"
|
||||
]
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export interface IHomeAssistantAdguardConfig {
|
||||
// TODO: replace with the TypeScript-native config for adguard.
|
||||
[key: string]: unknown;
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './adguard.classes.integration.js';
|
||||
export * from './adguard.types.js';
|
||||
@@ -0,0 +1 @@
|
||||
This folder is generated from Home Assistant component metadata. Replace it with a handwritten TypeScript port when implementing runtime support.
|
||||
@@ -0,0 +1,26 @@
|
||||
import { DescriptorOnlyIntegration } from '../../core/classes.descriptoronlyintegration.js';
|
||||
|
||||
export class HomeAssistantAdsIntegration extends DescriptorOnlyIntegration {
|
||||
constructor() {
|
||||
super({
|
||||
domain: "ads",
|
||||
displayName: "ADS",
|
||||
status: 'descriptor-only',
|
||||
metadata: {
|
||||
"source": "home-assistant/core",
|
||||
"upstreamPath": "homeassistant/components/ads",
|
||||
"upstreamDomain": "ads",
|
||||
"iotClass": "local_push",
|
||||
"qualityScale": "legacy",
|
||||
"requirements": [
|
||||
"pyads==3.4.0"
|
||||
],
|
||||
"dependencies": [],
|
||||
"afterDependencies": [],
|
||||
"codeowners": [
|
||||
"@mrpasztoradam"
|
||||
]
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export interface IHomeAssistantAdsConfig {
|
||||
// TODO: replace with the TypeScript-native config for ads.
|
||||
[key: string]: unknown;
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './ads.classes.integration.js';
|
||||
export * from './ads.types.js';
|
||||
@@ -0,0 +1 @@
|
||||
This folder is generated from Home Assistant component metadata. Replace it with a handwritten TypeScript port when implementing runtime support.
|
||||
@@ -0,0 +1,26 @@
|
||||
import { DescriptorOnlyIntegration } from '../../core/classes.descriptoronlyintegration.js';
|
||||
|
||||
export class HomeAssistantAdvantageAirIntegration extends DescriptorOnlyIntegration {
|
||||
constructor() {
|
||||
super({
|
||||
domain: "advantage_air",
|
||||
displayName: "Advantage Air",
|
||||
status: 'descriptor-only',
|
||||
metadata: {
|
||||
"source": "home-assistant/core",
|
||||
"upstreamPath": "homeassistant/components/advantage_air",
|
||||
"upstreamDomain": "advantage_air",
|
||||
"integrationType": "hub",
|
||||
"iotClass": "local_polling",
|
||||
"requirements": [
|
||||
"advantage-air==0.4.4"
|
||||
],
|
||||
"dependencies": [],
|
||||
"afterDependencies": [],
|
||||
"codeowners": [
|
||||
"@Bre77"
|
||||
]
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export interface IHomeAssistantAdvantageAirConfig {
|
||||
// TODO: replace with the TypeScript-native config for advantage_air.
|
||||
[key: string]: unknown;
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './advantage_air.classes.integration.js';
|
||||
export * from './advantage_air.types.js';
|
||||
@@ -0,0 +1 @@
|
||||
This folder is generated from Home Assistant component metadata. Replace it with a handwritten TypeScript port when implementing runtime support.
|
||||
@@ -0,0 +1,26 @@
|
||||
import { DescriptorOnlyIntegration } from '../../core/classes.descriptoronlyintegration.js';
|
||||
|
||||
export class HomeAssistantAemetIntegration extends DescriptorOnlyIntegration {
|
||||
constructor() {
|
||||
super({
|
||||
domain: "aemet",
|
||||
displayName: "AEMET OpenData",
|
||||
status: 'descriptor-only',
|
||||
metadata: {
|
||||
"source": "home-assistant/core",
|
||||
"upstreamPath": "homeassistant/components/aemet",
|
||||
"upstreamDomain": "aemet",
|
||||
"integrationType": "service",
|
||||
"iotClass": "cloud_polling",
|
||||
"requirements": [
|
||||
"AEMET-OpenData==0.6.4"
|
||||
],
|
||||
"dependencies": [],
|
||||
"afterDependencies": [],
|
||||
"codeowners": [
|
||||
"@Noltari"
|
||||
]
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export interface IHomeAssistantAemetConfig {
|
||||
// TODO: replace with the TypeScript-native config for aemet.
|
||||
[key: string]: unknown;
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './aemet.classes.integration.js';
|
||||
export * from './aemet.types.js';
|
||||
@@ -0,0 +1 @@
|
||||
This folder is generated from Home Assistant component metadata. Replace it with a handwritten TypeScript port when implementing runtime support.
|
||||
@@ -0,0 +1,21 @@
|
||||
import { DescriptorOnlyIntegration } from '../../core/classes.descriptoronlyintegration.js';
|
||||
|
||||
export class HomeAssistantAepOhioIntegration extends DescriptorOnlyIntegration {
|
||||
constructor() {
|
||||
super({
|
||||
domain: "aep_ohio",
|
||||
displayName: "AEP Ohio",
|
||||
status: 'descriptor-only',
|
||||
metadata: {
|
||||
"source": "home-assistant/core",
|
||||
"upstreamPath": "homeassistant/components/aep_ohio",
|
||||
"upstreamDomain": "aep_ohio",
|
||||
"integrationType": "virtual",
|
||||
"requirements": [],
|
||||
"dependencies": [],
|
||||
"afterDependencies": [],
|
||||
"codeowners": []
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export interface IHomeAssistantAepOhioConfig {
|
||||
// TODO: replace with the TypeScript-native config for aep_ohio.
|
||||
[key: string]: unknown;
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './aep_ohio.classes.integration.js';
|
||||
export * from './aep_ohio.types.js';
|
||||
@@ -0,0 +1 @@
|
||||
This folder is generated from Home Assistant component metadata. Replace it with a handwritten TypeScript port when implementing runtime support.
|
||||
@@ -0,0 +1,21 @@
|
||||
import { DescriptorOnlyIntegration } from '../../core/classes.descriptoronlyintegration.js';
|
||||
|
||||
export class HomeAssistantAepTexasIntegration extends DescriptorOnlyIntegration {
|
||||
constructor() {
|
||||
super({
|
||||
domain: "aep_texas",
|
||||
displayName: "AEP Texas",
|
||||
status: 'descriptor-only',
|
||||
metadata: {
|
||||
"source": "home-assistant/core",
|
||||
"upstreamPath": "homeassistant/components/aep_texas",
|
||||
"upstreamDomain": "aep_texas",
|
||||
"integrationType": "virtual",
|
||||
"requirements": [],
|
||||
"dependencies": [],
|
||||
"afterDependencies": [],
|
||||
"codeowners": []
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export interface IHomeAssistantAepTexasConfig {
|
||||
// TODO: replace with the TypeScript-native config for aep_texas.
|
||||
[key: string]: unknown;
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './aep_texas.classes.integration.js';
|
||||
export * from './aep_texas.types.js';
|
||||
@@ -0,0 +1 @@
|
||||
This folder is generated from Home Assistant component metadata. Replace it with a handwritten TypeScript port when implementing runtime support.
|
||||
@@ -0,0 +1,24 @@
|
||||
import { DescriptorOnlyIntegration } from '../../core/classes.descriptoronlyintegration.js';
|
||||
|
||||
export class HomeAssistantAftershipIntegration extends DescriptorOnlyIntegration {
|
||||
constructor() {
|
||||
super({
|
||||
domain: "aftership",
|
||||
displayName: "AfterShip",
|
||||
status: 'descriptor-only',
|
||||
metadata: {
|
||||
"source": "home-assistant/core",
|
||||
"upstreamPath": "homeassistant/components/aftership",
|
||||
"upstreamDomain": "aftership",
|
||||
"integrationType": "service",
|
||||
"iotClass": "cloud_polling",
|
||||
"requirements": [
|
||||
"pyaftership==21.11.0"
|
||||
],
|
||||
"dependencies": [],
|
||||
"afterDependencies": [],
|
||||
"codeowners": []
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export interface IHomeAssistantAftershipConfig {
|
||||
// TODO: replace with the TypeScript-native config for aftership.
|
||||
[key: string]: unknown;
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './aftership.classes.integration.js';
|
||||
export * from './aftership.types.js';
|
||||
@@ -0,0 +1 @@
|
||||
This folder is generated from Home Assistant component metadata. Replace it with a handwritten TypeScript port when implementing runtime support.
|
||||
@@ -0,0 +1,26 @@
|
||||
import { DescriptorOnlyIntegration } from '../../core/classes.descriptoronlyintegration.js';
|
||||
|
||||
export class HomeAssistantAgentDvrIntegration extends DescriptorOnlyIntegration {
|
||||
constructor() {
|
||||
super({
|
||||
domain: "agent_dvr",
|
||||
displayName: "Agent DVR",
|
||||
status: 'descriptor-only',
|
||||
metadata: {
|
||||
"source": "home-assistant/core",
|
||||
"upstreamPath": "homeassistant/components/agent_dvr",
|
||||
"upstreamDomain": "agent_dvr",
|
||||
"integrationType": "hub",
|
||||
"iotClass": "local_polling",
|
||||
"requirements": [
|
||||
"agent-py==0.0.24"
|
||||
],
|
||||
"dependencies": [],
|
||||
"afterDependencies": [],
|
||||
"codeowners": [
|
||||
"@ispysoftware"
|
||||
]
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export interface IHomeAssistantAgentDvrConfig {
|
||||
// TODO: replace with the TypeScript-native config for agent_dvr.
|
||||
[key: string]: unknown;
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './agent_dvr.classes.integration.js';
|
||||
export * from './agent_dvr.types.js';
|
||||
@@ -0,0 +1 @@
|
||||
This folder is generated from Home Assistant component metadata. Replace it with a handwritten TypeScript port when implementing runtime support.
|
||||
@@ -0,0 +1,29 @@
|
||||
import { DescriptorOnlyIntegration } from '../../core/classes.descriptoronlyintegration.js';
|
||||
|
||||
export class HomeAssistantAiTaskIntegration extends DescriptorOnlyIntegration {
|
||||
constructor() {
|
||||
super({
|
||||
domain: "ai_task",
|
||||
displayName: "AI Task",
|
||||
status: 'descriptor-only',
|
||||
metadata: {
|
||||
"source": "home-assistant/core",
|
||||
"upstreamPath": "homeassistant/components/ai_task",
|
||||
"upstreamDomain": "ai_task",
|
||||
"integrationType": "entity",
|
||||
"qualityScale": "internal",
|
||||
"requirements": [],
|
||||
"dependencies": [
|
||||
"conversation",
|
||||
"media_source"
|
||||
],
|
||||
"afterDependencies": [
|
||||
"camera"
|
||||
],
|
||||
"codeowners": [
|
||||
"@home-assistant/core"
|
||||
]
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export interface IHomeAssistantAiTaskConfig {
|
||||
// TODO: replace with the TypeScript-native config for ai_task.
|
||||
[key: string]: unknown;
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './ai_task.classes.integration.js';
|
||||
export * from './ai_task.types.js';
|
||||
@@ -0,0 +1 @@
|
||||
This folder is generated from Home Assistant component metadata. Replace it with a handwritten TypeScript port when implementing runtime support.
|
||||
@@ -0,0 +1,24 @@
|
||||
import { DescriptorOnlyIntegration } from '../../core/classes.descriptoronlyintegration.js';
|
||||
|
||||
export class HomeAssistantAirQualityIntegration extends DescriptorOnlyIntegration {
|
||||
constructor() {
|
||||
super({
|
||||
domain: "air_quality",
|
||||
displayName: "Air Quality",
|
||||
status: 'descriptor-only',
|
||||
metadata: {
|
||||
"source": "home-assistant/core",
|
||||
"upstreamPath": "homeassistant/components/air_quality",
|
||||
"upstreamDomain": "air_quality",
|
||||
"integrationType": "entity",
|
||||
"qualityScale": "internal",
|
||||
"requirements": [],
|
||||
"dependencies": [],
|
||||
"afterDependencies": [],
|
||||
"codeowners": [
|
||||
"@home-assistant/core"
|
||||
]
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export interface IHomeAssistantAirQualityConfig {
|
||||
// TODO: replace with the TypeScript-native config for air_quality.
|
||||
[key: string]: unknown;
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './air_quality.classes.integration.js';
|
||||
export * from './air_quality.types.js';
|
||||
@@ -0,0 +1 @@
|
||||
This folder is generated from Home Assistant component metadata. Replace it with a handwritten TypeScript port when implementing runtime support.
|
||||
@@ -0,0 +1,28 @@
|
||||
import { DescriptorOnlyIntegration } from '../../core/classes.descriptoronlyintegration.js';
|
||||
|
||||
export class HomeAssistantAirgradientIntegration extends DescriptorOnlyIntegration {
|
||||
constructor() {
|
||||
super({
|
||||
domain: "airgradient",
|
||||
displayName: "AirGradient",
|
||||
status: 'descriptor-only',
|
||||
metadata: {
|
||||
"source": "home-assistant/core",
|
||||
"upstreamPath": "homeassistant/components/airgradient",
|
||||
"upstreamDomain": "airgradient",
|
||||
"integrationType": "device",
|
||||
"iotClass": "local_polling",
|
||||
"qualityScale": "platinum",
|
||||
"requirements": [
|
||||
"airgradient==0.9.2"
|
||||
],
|
||||
"dependencies": [],
|
||||
"afterDependencies": [],
|
||||
"codeowners": [
|
||||
"@airgradienthq",
|
||||
"@joostlek"
|
||||
]
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user