Add TypeScript integrations package

This commit is contained in:
2026-05-05 12:01:30 +00:00
commit e91176fb9b
5889 changed files with 53433 additions and 0 deletions
+30
View File
@@ -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);
}
}
+8
View File
@@ -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);
};
+24
View File
@@ -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');
};
+8
View File
@@ -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');
};
+32
View File
@@ -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,
},
};
};
+41
View File
@@ -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);
});
}
+16
View File
@@ -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>;
}
+42
View File
@@ -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> {}
}
+47
View File
@@ -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];
}
}
+74
View File
@@ -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;
}
}
+25
View File
@@ -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);
}
}
+8
View File
@@ -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}`);
}
}
+31
View File
@@ -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();
}
}
+27
View File
@@ -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);
}
}
+10
View File
@@ -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';
+208
View File
@@ -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
View File
@@ -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;
}
+2
View File
@@ -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"
]
},
});
}
}
+4
View File
@@ -0,0 +1,4 @@
export interface IHomeAssistantAbodeConfig {
// TODO: replace with the TypeScript-native config for abode.
[key: string]: unknown;
}
+2
View File
@@ -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"
]
},
});
}
}
+4
View File
@@ -0,0 +1,4 @@
export interface IHomeAssistantAcaiaConfig {
// TODO: replace with the TypeScript-native config for acaia.
[key: string]: unknown;
}
+2
View File
@@ -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;
}
+2
View File
@@ -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;
}
+2
View File
@@ -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"
]
},
});
}
}
+4
View File
@@ -0,0 +1,4 @@
export interface IHomeAssistantAcmedaConfig {
// TODO: replace with the TypeScript-native config for acmeda.
[key: string]: unknown;
}
+2
View File
@@ -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": []
},
});
}
}
+4
View File
@@ -0,0 +1,4 @@
export interface IHomeAssistantAcomaxConfig {
// TODO: replace with the TypeScript-native config for acomax.
[key: string]: unknown;
}
+2
View File
@@ -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;
}
+2
View File
@@ -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;
}
+2
View File
@@ -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"
]
},
});
}
}
+4
View File
@@ -0,0 +1,4 @@
export interface IHomeAssistantAdaxConfig {
// TODO: replace with the TypeScript-native config for adax.
[key: string]: unknown;
}
+2
View File
@@ -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"
]
},
});
}
}
+4
View File
@@ -0,0 +1,4 @@
export interface IHomeAssistantAdguardConfig {
// TODO: replace with the TypeScript-native config for adguard.
[key: string]: unknown;
}
+2
View File
@@ -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"
]
},
});
}
}
+4
View File
@@ -0,0 +1,4 @@
export interface IHomeAssistantAdsConfig {
// TODO: replace with the TypeScript-native config for ads.
[key: string]: unknown;
}
+2
View File
@@ -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;
}
+2
View File
@@ -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"
]
},
});
}
}
+4
View File
@@ -0,0 +1,4 @@
export interface IHomeAssistantAemetConfig {
// TODO: replace with the TypeScript-native config for aemet.
[key: string]: unknown;
}
+2
View File
@@ -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;
}
+2
View File
@@ -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;
}
+2
View File
@@ -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;
}
+2
View File
@@ -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;
}
+2
View File
@@ -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"
]
},
});
}
}
+4
View File
@@ -0,0 +1,4 @@
export interface IHomeAssistantAiTaskConfig {
// TODO: replace with the TypeScript-native config for ai_task.
[key: string]: unknown;
}
+2
View File
@@ -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;
}
+2
View File
@@ -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