Files
homarr/packages/integrations/src/homeassistant/homeassistant-integration.ts
T
Meier Lukas 8c36c3e36b feat(certificates): handle self signed certificates (#1951)
* wip: add page and loading of certificates in folder

* wip: add certificate addition and removal

* feat: add removal ui for certificates

* feat: migrate integrations to fetch or agent with trusted certificates

* fix: lock file issues

* fix: typecheck issue

* fix: inconsistent package versions

* chore: address pull request feedback

* fix: add missing navigation item and restrict access to page

* chore: address pull request feedback

* fix: inconsistent undici dependency version

* fix: inconsistent undici dependency version
2025-01-17 00:08:40 +01:00

105 lines
3.0 KiB
TypeScript

import { fetchWithTrustedCertificatesAsync } from "@homarr/certificates/server";
import { logger } from "@homarr/log";
import { Integration } from "../base/integration";
import { entityStateSchema } from "./homeassistant-types";
export class HomeAssistantIntegration extends Integration {
public async getEntityStateAsync(entityId: string) {
try {
const response = await this.getAsync(`/api/states/${entityId}`);
const body = await response.json();
if (!response.ok) {
logger.warn(`Response did not indicate success`);
return {
error: "Response did not indicate success",
};
}
return entityStateSchema.safeParseAsync(body);
} catch (err) {
logger.error(`Failed to fetch from ${this.url("/")}: ${err as string}`);
return {
success: false as const,
error: err,
};
}
}
public async triggerAutomationAsync(entityId: string) {
try {
const response = await this.postAsync("/api/services/automation/trigger", {
entity_id: entityId,
});
return response.ok;
} catch (err) {
logger.error(`Failed to fetch from '${this.url("/")}': ${err as string}`);
return false;
}
}
/**
* Triggers a toggle action for a specific entity.
*
* @param entityId - The ID of the entity to toggle.
* @returns A boolean indicating whether the toggle action was successful.
*/
public async triggerToggleAsync(entityId: string) {
try {
const response = await this.postAsync("/api/services/homeassistant/toggle", {
entity_id: entityId,
});
return response.ok;
} catch (err) {
logger.error(`Failed to fetch from '${this.url("/")}': ${err as string}`);
return false;
}
}
public async testConnectionAsync(): Promise<void> {
await super.handleTestConnectionResponseAsync({
queryFunctionAsync: async () => {
return await this.getAsync("/api/config");
},
});
}
/**
* Makes a GET request to the Home Assistant API.
* It includes the authorization header with the API key.
* @param path full path to the API endpoint
* @returns the response from the API
*/
private async getAsync(path: `/api/${string}`) {
return await fetchWithTrustedCertificatesAsync(this.url(path), {
headers: this.getAuthHeaders(),
});
}
/**
* Makes a POST request to the Home Assistant API.
* It includes the authorization header with the API key.
* @param path full path to the API endpoint
* @param body the body of the request
* @returns the response from the API
*/
private async postAsync(path: `/api/${string}`, body: Record<string, string>) {
return await fetchWithTrustedCertificatesAsync(this.url(path), {
headers: this.getAuthHeaders(),
body: JSON.stringify(body),
method: "POST",
});
}
/**
* Returns the headers required for authorization.
* @returns the authorization headers
*/
private getAuthHeaders() {
return {
Authorization: `Bearer ${this.getSecretValue("apiKey")}`,
};
}
}