@coffeerunhobby/mcp-ha-connect 2.2.1 → 2.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +1 -1
- package/README.md +11 -2
- package/dist/omadaClient/client.d.ts +6 -1
- package/dist/omadaClient/client.js +12 -1
- package/dist/omadaClient/client.js.map +1 -1
- package/dist/omadaClient/diagnose.d.ts +68 -0
- package/dist/omadaClient/diagnose.js +164 -0
- package/dist/omadaClient/diagnose.js.map +1 -0
- package/dist/omadaClient/index.d.ts +6 -0
- package/dist/omadaClient/index.js +15 -0
- package/dist/omadaClient/index.js.map +1 -1
- package/dist/omadaClient/macGroups.d.ts +58 -0
- package/dist/omadaClient/macGroups.js +124 -0
- package/dist/omadaClient/macGroups.js.map +1 -0
- package/dist/tools/infra/actions.d.ts +1 -1
- package/dist/tools/infra/actions.js +1 -1
- package/dist/tools/omada/index.js +6 -0
- package/dist/tools/omada/index.js.map +1 -1
- package/dist/tools/omada/macGroups.d.ts +19 -0
- package/dist/tools/omada/macGroups.js +77 -0
- package/dist/tools/omada/macGroups.js.map +1 -0
- package/dist/tools/omada/namespace.js +8 -0
- package/dist/tools/omada/namespace.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +5 -1
- package/.codex/review-rules.md +0 -16
- package/.dockerignore +0 -8
- package/.gitattributes +0 -30
- package/.github/workflows/ci.yml +0 -193
- package/AGENTS.md +0 -389
- package/Dockerfile +0 -50
- package/docker-compose.yml +0 -23
- package/docs/CHANGELOG.md +0 -341
- package/docs/COVERAGE.md +0 -219
- package/docs/QUICK_START.md +0 -240
- package/eslint.config.js +0 -33
- package/n8n/ai-agent-safety-monitor.json +0 -355
- package/openapi.json +0 -1259
- package/scripts/check-version-sync.mjs +0 -69
- package/scripts/generate-jwt.ts +0 -121
- package/src/config.ts +0 -440
- package/src/haClient/automations.ts +0 -261
- package/src/haClient/calendars.ts +0 -94
- package/src/haClient/config.ts +0 -52
- package/src/haClient/devices.ts +0 -653
- package/src/haClient/entities.ts +0 -128
- package/src/haClient/events.ts +0 -689
- package/src/haClient/history.ts +0 -73
- package/src/haClient/index.ts +0 -336
- package/src/haClient/request.ts +0 -142
- package/src/haClient/services.ts +0 -45
- package/src/haClient/states.ts +0 -60
- package/src/haClient/updates.ts +0 -58
- package/src/haClient/wsCommand.ts +0 -44
- package/src/index.ts +0 -164
- package/src/localAI/index.ts +0 -88
- package/src/localAI/prompts.ts +0 -50
- package/src/localAI/providers/base.ts +0 -120
- package/src/localAI/providers/ollama.ts +0 -78
- package/src/localAI/providers/openai.ts +0 -86
- package/src/localAI/types.ts +0 -67
- package/src/omadaClient/auth.ts +0 -178
- package/src/omadaClient/client.ts +0 -337
- package/src/omadaClient/device.ts +0 -118
- package/src/omadaClient/index.ts +0 -310
- package/src/omadaClient/network.ts +0 -284
- package/src/omadaClient/request.ts +0 -365
- package/src/omadaClient/security.ts +0 -51
- package/src/omadaClient/site.ts +0 -344
- package/src/ownerQuestions/service.ts +0 -536
- package/src/permissions/index.ts +0 -143
- package/src/resources/index.ts +0 -213
- package/src/server/auth.ts +0 -175
- package/src/server/chatFace.ts +0 -789
- package/src/server/chatSlice.ts +0 -57
- package/src/server/common.ts +0 -170
- package/src/server/eventSubscription.ts +0 -343
- package/src/server/http.ts +0 -626
- package/src/server/instructions.ts +0 -97
- package/src/server/rateLimiter.ts +0 -227
- package/src/server/stdio.ts +0 -41
- package/src/server/stream.ts +0 -205
- package/src/tools/ai/analyzeSensors.ts +0 -33
- package/src/tools/ai/index.ts +0 -20
- package/src/tools/common.ts +0 -442
- package/src/tools/homeassistant/askOwner.ts +0 -133
- package/src/tools/homeassistant/automationControls.ts +0 -66
- package/src/tools/homeassistant/calendar.ts +0 -97
- package/src/tools/homeassistant/callService.ts +0 -25
- package/src/tools/homeassistant/controlClimate.ts +0 -68
- package/src/tools/homeassistant/controlCover.ts +0 -48
- package/src/tools/homeassistant/controlFan.ts +0 -44
- package/src/tools/homeassistant/controlLight.ts +0 -38
- package/src/tools/homeassistant/controlMediaPlayer.ts +0 -50
- package/src/tools/homeassistant/createAutomation.ts +0 -35
- package/src/tools/homeassistant/deleteAutomation.ts +0 -24
- package/src/tools/homeassistant/entityAction.ts +0 -35
- package/src/tools/homeassistant/entityGuard.ts +0 -28
- package/src/tools/homeassistant/getAllSensors.ts +0 -46
- package/src/tools/homeassistant/getAutomationTrace.ts +0 -30
- package/src/tools/homeassistant/getDomainSummary.ts +0 -29
- package/src/tools/homeassistant/getEntitiesByDomain.ts +0 -56
- package/src/tools/homeassistant/getHistory.ts +0 -24
- package/src/tools/homeassistant/getState.ts +0 -24
- package/src/tools/homeassistant/getStates.ts +0 -46
- package/src/tools/homeassistant/getVersion.ts +0 -21
- package/src/tools/homeassistant/index.ts +0 -121
- package/src/tools/homeassistant/listAutomations.ts +0 -35
- package/src/tools/homeassistant/listEntities.ts +0 -44
- package/src/tools/homeassistant/listPersons.ts +0 -46
- package/src/tools/homeassistant/sceneAndScript.ts +0 -53
- package/src/tools/homeassistant/searchEntities.ts +0 -58
- package/src/tools/homeassistant/sendNotification.ts +0 -179
- package/src/tools/homeassistant/systemTools.ts +0 -52
- package/src/tools/homeassistant/triggerAutomation.ts +0 -24
- package/src/tools/index.ts +0 -78
- package/src/tools/infra/actions.ts +0 -95
- package/src/tools/infra/index.ts +0 -138
- package/src/tools/omada/blockClient.ts +0 -28
- package/src/tools/omada/cyclePoePort.ts +0 -32
- package/src/tools/omada/deleteClient.ts +0 -27
- package/src/tools/omada/disableClientRateLimit.ts +0 -23
- package/src/tools/omada/getClient.ts +0 -14
- package/src/tools/omada/getDevice.ts +0 -14
- package/src/tools/omada/getFirewallSetting.ts +0 -14
- package/src/tools/omada/getInternetInfo.ts +0 -14
- package/src/tools/omada/getLanNetworkList.ts +0 -14
- package/src/tools/omada/getLanProfileList.ts +0 -14
- package/src/tools/omada/getPortForwardingStatus.ts +0 -26
- package/src/tools/omada/getRateLimitProfiles.ts +0 -14
- package/src/tools/omada/getSiteNtpStatus.ts +0 -14
- package/src/tools/omada/getSsidDetail.ts +0 -22
- package/src/tools/omada/getSsidList.ts +0 -21
- package/src/tools/omada/getSwitchStackDetail.ts +0 -14
- package/src/tools/omada/getThreatList.ts +0 -42
- package/src/tools/omada/getWlanGroupList.ts +0 -14
- package/src/tools/omada/graph.ts +0 -187
- package/src/tools/omada/index.ts +0 -153
- package/src/tools/omada/listBlockedClients.ts +0 -17
- package/src/tools/omada/listClients.ts +0 -14
- package/src/tools/omada/listClientsActivity.ts +0 -25
- package/src/tools/omada/listClientsPastConnections.ts +0 -44
- package/src/tools/omada/listDevices.ts +0 -14
- package/src/tools/omada/listDevicesStats.ts +0 -41
- package/src/tools/omada/listMostActiveClients.ts +0 -14
- package/src/tools/omada/listSites.ts +0 -18
- package/src/tools/omada/namespace.ts +0 -1164
- package/src/tools/omada/searchDevices.ts +0 -20
- package/src/tools/omada/setClientRateLimit.ts +0 -26
- package/src/tools/omada/setClientRateLimitProfile.ts +0 -25
- package/src/tools/omada/setSiteNtpServers.ts +0 -36
- package/src/tools/omada/setSsidEnabled.ts +0 -38
- package/src/tools/omada/unblockClient.ts +0 -26
- package/src/tools/types.ts +0 -11
- package/src/tools/utils/pagination-schema.ts +0 -27
- package/src/types/ai/index.ts +0 -11
- package/src/types/ai/types.ts +0 -67
- package/src/types/homeassistant/automations.ts +0 -43
- package/src/types/homeassistant/calendars.ts +0 -26
- package/src/types/homeassistant/config.ts +0 -14
- package/src/types/homeassistant/entities.ts +0 -14
- package/src/types/homeassistant/errors.ts +0 -33
- package/src/types/homeassistant/haConfig.ts +0 -7
- package/src/types/homeassistant/history.ts +0 -13
- package/src/types/homeassistant/index.ts +0 -46
- package/src/types/homeassistant/request.ts +0 -6
- package/src/types/homeassistant/serviceCall.ts +0 -18
- package/src/types/homeassistant/states.ts +0 -58
- package/src/types/homeassistant/updates.ts +0 -28
- package/src/types/index.ts +0 -12
- package/src/types/omada/activeClientInfo.ts +0 -17
- package/src/types/omada/clientActivity.ts +0 -32
- package/src/types/omada/clientBlockStatus.ts +0 -11
- package/src/types/omada/clientPastConnection.ts +0 -82
- package/src/types/omada/index.ts +0 -14
- package/src/types/omada/omadaApiResponse.ts +0 -5
- package/src/types/omada/omadaClientInfo.ts +0 -11
- package/src/types/omada/omadaDeviceInfo.ts +0 -11
- package/src/types/omada/omadaDeviceStats.ts +0 -31
- package/src/types/omada/omadaSiteSummary.ts +0 -5
- package/src/types/omada/oswStackDetail.ts +0 -11
- package/src/types/omada/paginatedResult.ts +0 -6
- package/src/types/omada/rateLimitProfile.ts +0 -58
- package/src/types/omada/threatInfo.ts +0 -38
- package/src/types/omada/tokenResult.ts +0 -6
- package/src/types.ts +0 -2
- package/src/utils/config-validations.ts +0 -68
- package/src/utils/jwt.ts +0 -112
- package/src/utils/logger.ts +0 -121
- package/src/utils/plainText.ts +0 -48
- package/src/utils/redact.ts +0 -59
- package/src/utils/sanitizeError.ts +0 -18
- package/src/utils/tlsDispatcher.ts +0 -69
- package/src/version.ts +0 -5
- package/tests/bdd/automation-creation.spec.ts +0 -214
- package/tests/bdd/automation-management.spec.ts +0 -267
- package/tests/bdd/calendar.spec.ts +0 -190
- package/tests/bdd/configuration.spec.ts +0 -283
- package/tests/bdd/device-control.spec.ts +0 -344
- package/tests/bdd/entity-listing.spec.ts +0 -208
- package/tests/bdd/entity-search.spec.ts +0 -183
- package/tests/bdd/history-retrieval.spec.ts +0 -195
- package/tests/bdd/notifications.spec.ts +0 -238
- package/tests/bdd/service-calls.spec.ts +0 -144
- package/tests/bdd/state-retrieval.spec.ts +0 -204
- package/tests/bench/hotpaths.bench.ts +0 -68
- package/tests/config.test.ts +0 -355
- package/tests/features/automation-creation.feature +0 -36
- package/tests/features/automation-management.feature +0 -54
- package/tests/features/calendar.feature +0 -37
- package/tests/features/configuration.feature +0 -70
- package/tests/features/device-control.feature +0 -100
- package/tests/features/entity-listing.feature +0 -51
- package/tests/features/entity-search.feature +0 -44
- package/tests/features/history-retrieval.feature +0 -38
- package/tests/features/notifications.feature +0 -37
- package/tests/features/service-calls.feature +0 -35
- package/tests/features/state-retrieval.feature +0 -37
- package/tests/fixtures/openapi-default-slice.json +0 -290
- package/tests/haClient/automationTrace.test.ts +0 -59
- package/tests/haClient/automations.test.ts +0 -149
- package/tests/haClient/config.test.ts +0 -117
- package/tests/haClient/entities.test.ts +0 -188
- package/tests/haClient/events.test.ts +0 -455
- package/tests/haClient/eventsTls.test.ts +0 -52
- package/tests/haClient/history.test.ts +0 -228
- package/tests/haClient/index.test.ts +0 -243
- package/tests/haClient/request.test.ts +0 -217
- package/tests/haClient/services.test.ts +0 -120
- package/tests/haClient/states.test.ts +0 -119
- package/tests/haClient/updates.test.ts +0 -193
- package/tests/index.test.ts +0 -160
- package/tests/integration/homeassistant.test.ts +0 -144
- package/tests/integration/omada.test.ts +0 -167
- package/tests/integration/server.test.ts +0 -151
- package/tests/localAI/index.test.ts +0 -177
- package/tests/localAI/ollama.test.ts +0 -187
- package/tests/localAI/openai.test.ts +0 -257
- package/tests/omadaClient/actions.test.ts +0 -161
- package/tests/omadaClient/clientBlocks.test.ts +0 -170
- package/tests/omadaClient/ntp.test.ts +0 -381
- package/tests/omadaClient/site.test.ts +0 -37
- package/tests/ownerQuestions/service.test.ts +0 -499
- package/tests/ownerQuestions/tools.test.ts +0 -186
- package/tests/permissions/index.test.ts +0 -217
- package/tests/resources/index.test.ts +0 -288
- package/tests/scripts/generateJwt.test.ts +0 -44
- package/tests/security/accessControl.test.ts +0 -223
- package/tests/security/authentication.test.ts +0 -117
- package/tests/security/configuration.test.ts +0 -170
- package/tests/security/cryptoTransport.test.ts +0 -172
- package/tests/security/dependencies.test.ts +0 -152
- package/tests/security/injection.test.ts +0 -117
- package/tests/security/insecureDesign.test.ts +0 -121
- package/tests/security/logging.test.ts +0 -131
- package/tests/security/resourceConsumption.test.ts +0 -142
- package/tests/server/auth.test.ts +0 -249
- package/tests/server/chatFace.test.ts +0 -320
- package/tests/server/common.test.ts +0 -84
- package/tests/server/http.test.ts +0 -561
- package/tests/server/instructions.test.ts +0 -152
- package/tests/server/memoizeJsonSchema.test.ts +0 -71
- package/tests/server/stdio.test.ts +0 -99
- package/tests/server/stream.test.ts +0 -285
- package/tests/server/toolVisibility.http.test.ts +0 -111
- package/tests/server/toolVisibility.test.ts +0 -129
- package/tests/tools/ai/analyzeSensors.test.ts +0 -227
- package/tests/tools/common.test.ts +0 -123
- package/tests/tools/homeassistant/handlers.test.ts +0 -872
- package/tests/tools/infra/invokeAction.test.ts +0 -280
- package/tests/tools/omada/graph.test.ts +0 -385
- package/tests/tools/omada/handlers.test.ts +0 -897
- package/tests/tools/omada/namespace.test.ts +0 -483
- package/tests/tools/registry.test.ts +0 -168
- package/tests/utils/config-validations.test.ts +0 -352
- package/tests/utils/jwt.test.ts +0 -115
- package/tests/utils/logger.test.ts +0 -327
- package/tests/utils/redact.test.ts +0 -105
- package/tsconfig.json +0 -24
- package/vitest.config.ts +0 -38
|
@@ -1,261 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Automation Operations for Home Assistant API
|
|
3
|
-
* Handles automation listing and management
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import type { Automation, AutomationConfig, ServiceCallResponse } from '../types/index.js';
|
|
7
|
-
import { logger } from '../utils/logger.js';
|
|
8
|
-
import type { StateOperations } from './states.js';
|
|
9
|
-
import type { ServiceOperations } from './services.js';
|
|
10
|
-
import type { RequestHandler } from './request.js';
|
|
11
|
-
import type { HaWebSocketCommand } from './wsCommand.js';
|
|
12
|
-
|
|
13
|
-
/** One run of an automation, as `trace/list` summarizes it. */
|
|
14
|
-
export interface AutomationTraceSummary {
|
|
15
|
-
run_id: string;
|
|
16
|
-
state?: string;
|
|
17
|
-
script_execution?: string | null;
|
|
18
|
-
last_step?: string | null;
|
|
19
|
-
error?: string;
|
|
20
|
-
trigger?: string;
|
|
21
|
-
timestamp?: { start: string; finish: string | null };
|
|
22
|
-
[key: string]: unknown;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Automation-related operations for the Home Assistant API.
|
|
27
|
-
*/
|
|
28
|
-
export class AutomationOperations {
|
|
29
|
-
constructor(
|
|
30
|
-
private readonly stateOps: StateOperations,
|
|
31
|
-
private readonly serviceOps?: ServiceOperations,
|
|
32
|
-
private readonly request?: RequestHandler,
|
|
33
|
-
private readonly wsCommand?: HaWebSocketCommand
|
|
34
|
-
) {}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Get all automations
|
|
38
|
-
*/
|
|
39
|
-
async getAutomations(): Promise<Automation[]> {
|
|
40
|
-
logger.debug('Fetching automations');
|
|
41
|
-
|
|
42
|
-
const allStates = await this.stateOps.getStates();
|
|
43
|
-
const automations = allStates
|
|
44
|
-
.filter(entity => entity.entity_id.startsWith('automation.'))
|
|
45
|
-
.map(entity => ({
|
|
46
|
-
id: entity.entity_id,
|
|
47
|
-
alias: String(entity.attributes.friendly_name || entity.entity_id.replace('automation.', '')),
|
|
48
|
-
state: entity.state as 'on' | 'off',
|
|
49
|
-
last_triggered: entity.attributes.last_triggered as string | null,
|
|
50
|
-
description: entity.attributes.description as string | undefined,
|
|
51
|
-
mode: entity.attributes.mode as Automation['mode'],
|
|
52
|
-
}));
|
|
53
|
-
|
|
54
|
-
logger.info('Fetched automations', { count: automations.length });
|
|
55
|
-
return automations;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Get a single automation by entity_id
|
|
60
|
-
*/
|
|
61
|
-
async getAutomation(entityId: string): Promise<Automation | null> {
|
|
62
|
-
logger.debug('Fetching automation', { entityId });
|
|
63
|
-
|
|
64
|
-
const state = await this.stateOps.getState(entityId);
|
|
65
|
-
if (!state || !entityId.startsWith('automation.')) {
|
|
66
|
-
return null;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
return {
|
|
70
|
-
id: state.entity_id,
|
|
71
|
-
alias: String(state.attributes.friendly_name || state.entity_id.replace('automation.', '')),
|
|
72
|
-
state: state.state as 'on' | 'off',
|
|
73
|
-
last_triggered: state.attributes.last_triggered as string | null,
|
|
74
|
-
description: state.attributes.description as string | undefined,
|
|
75
|
-
mode: state.attributes.mode as Automation['mode'],
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Trigger an automation manually
|
|
81
|
-
*/
|
|
82
|
-
async triggerAutomation(entityId: string, variables?: Record<string, unknown>): Promise<ServiceCallResponse> {
|
|
83
|
-
if (!this.serviceOps) {
|
|
84
|
-
throw new Error('ServiceOperations not available');
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
logger.info('Triggering automation', { entityId, variables });
|
|
88
|
-
|
|
89
|
-
return this.serviceOps.callService({
|
|
90
|
-
domain: 'automation',
|
|
91
|
-
service: 'trigger',
|
|
92
|
-
target: { entity_id: entityId },
|
|
93
|
-
service_data: variables ? { variables } : undefined,
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Enable an automation
|
|
99
|
-
*/
|
|
100
|
-
async enableAutomation(entityId: string): Promise<ServiceCallResponse> {
|
|
101
|
-
if (!this.serviceOps) {
|
|
102
|
-
throw new Error('ServiceOperations not available');
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
logger.info('Enabling automation', { entityId });
|
|
106
|
-
|
|
107
|
-
return this.serviceOps.callService({
|
|
108
|
-
domain: 'automation',
|
|
109
|
-
service: 'turn_on',
|
|
110
|
-
target: { entity_id: entityId },
|
|
111
|
-
});
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* Disable an automation
|
|
116
|
-
*/
|
|
117
|
-
async disableAutomation(entityId: string): Promise<ServiceCallResponse> {
|
|
118
|
-
if (!this.serviceOps) {
|
|
119
|
-
throw new Error('ServiceOperations not available');
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
logger.info('Disabling automation', { entityId });
|
|
123
|
-
|
|
124
|
-
return this.serviceOps.callService({
|
|
125
|
-
domain: 'automation',
|
|
126
|
-
service: 'turn_off',
|
|
127
|
-
target: { entity_id: entityId },
|
|
128
|
-
});
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* Toggle an automation (enable if disabled, disable if enabled)
|
|
133
|
-
*/
|
|
134
|
-
async toggleAutomation(entityId: string): Promise<ServiceCallResponse> {
|
|
135
|
-
if (!this.serviceOps) {
|
|
136
|
-
throw new Error('ServiceOperations not available');
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
logger.info('Toggling automation', { entityId });
|
|
140
|
-
|
|
141
|
-
return this.serviceOps.callService({
|
|
142
|
-
domain: 'automation',
|
|
143
|
-
service: 'toggle',
|
|
144
|
-
target: { entity_id: entityId },
|
|
145
|
-
});
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* Reload all automations from configuration
|
|
150
|
-
*/
|
|
151
|
-
async reloadAutomations(): Promise<void> {
|
|
152
|
-
if (!this.serviceOps) {
|
|
153
|
-
throw new Error('ServiceOperations not available');
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
logger.info('Reloading automations');
|
|
157
|
-
|
|
158
|
-
await this.serviceOps.callService({
|
|
159
|
-
domain: 'automation',
|
|
160
|
-
service: 'reload',
|
|
161
|
-
});
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
/**
|
|
165
|
-
* Create a new automation via the config API
|
|
166
|
-
* Note: Requires automation: !include automations.yaml in configuration.yaml
|
|
167
|
-
*/
|
|
168
|
-
async createAutomation(config: AutomationConfig): Promise<{ id: string }> {
|
|
169
|
-
if (!this.request) {
|
|
170
|
-
throw new Error('RequestHandler not available');
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
// Generate a unique ID for the automation (timestamp-based like HA UI does)
|
|
174
|
-
const automationId = config.id || String(Date.now());
|
|
175
|
-
|
|
176
|
-
logger.info('Creating automation', { alias: config.alias, id: automationId });
|
|
177
|
-
|
|
178
|
-
// POST to /config/automation/config/{id} - the ID must be in the URL path
|
|
179
|
-
await this.request.post<{ result: string }>(`/config/automation/config/${encodeURIComponent(automationId)}`, {
|
|
180
|
-
id: automationId,
|
|
181
|
-
alias: config.alias,
|
|
182
|
-
description: config.description || '',
|
|
183
|
-
mode: config.mode ?? 'single',
|
|
184
|
-
trigger: config.trigger,
|
|
185
|
-
condition: config.condition || [],
|
|
186
|
-
action: config.action,
|
|
187
|
-
});
|
|
188
|
-
|
|
189
|
-
// Reload automations to pick up the new one
|
|
190
|
-
if (this.serviceOps) {
|
|
191
|
-
await this.serviceOps.callService({
|
|
192
|
-
domain: 'automation',
|
|
193
|
-
service: 'reload',
|
|
194
|
-
});
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
return { id: automationId };
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
/**
|
|
201
|
-
* Update an existing automation
|
|
202
|
-
* Note: Requires the automation's unique_id from the automation registry
|
|
203
|
-
*/
|
|
204
|
-
async updateAutomation(automationId: string, config: Partial<AutomationConfig>): Promise<void> {
|
|
205
|
-
if (!this.request) {
|
|
206
|
-
throw new Error('RequestHandler not available');
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
logger.info('Updating automation', { automationId, alias: config.alias });
|
|
210
|
-
|
|
211
|
-
await this.request.post(`/config/automation/config/${automationId}`, config);
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
/**
|
|
215
|
-
* Delete an automation
|
|
216
|
-
* Note: Only works for automations created via the UI/API
|
|
217
|
-
*/
|
|
218
|
-
async deleteAutomation(automationId: string): Promise<void> {
|
|
219
|
-
if (!this.request) {
|
|
220
|
-
throw new Error('RequestHandler not available');
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
logger.info('Deleting automation', { automationId });
|
|
224
|
-
|
|
225
|
-
await this.request.request(`/config/automation/config/${automationId}`, {
|
|
226
|
-
method: 'DELETE',
|
|
227
|
-
});
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
/**
|
|
231
|
-
* Get automation trace (execution history)
|
|
232
|
-
*/
|
|
233
|
-
async getAutomationTrace(entityId: string, limit = 5): Promise<AutomationTraceSummary[]> {
|
|
234
|
-
if (!this.wsCommand) {
|
|
235
|
-
throw new Error('Automation traces need the Home Assistant WebSocket API, which is not available');
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
// Traces are WebSocket-only (there is no REST endpoint) and are keyed by the
|
|
239
|
-
// automation's config id (its `id` attribute), not by the entity id.
|
|
240
|
-
const state = await this.stateOps.getState(entityId);
|
|
241
|
-
if (!state) {
|
|
242
|
-
throw new Error(`Automation ${entityId} not found`);
|
|
243
|
-
}
|
|
244
|
-
const itemId = state.attributes.id;
|
|
245
|
-
if (itemId === undefined || itemId === null || itemId === '') {
|
|
246
|
-
throw new Error(
|
|
247
|
-
`Automation ${entityId} has no 'id' (an automation defined in YAML without an id), so Home Assistant keeps no traces for it`
|
|
248
|
-
);
|
|
249
|
-
}
|
|
250
|
-
logger.debug('Fetching automation traces', { entityId, itemId });
|
|
251
|
-
|
|
252
|
-
const traces = await this.wsCommand<AutomationTraceSummary[]>({
|
|
253
|
-
type: 'trace/list',
|
|
254
|
-
domain: 'automation',
|
|
255
|
-
item_id: String(itemId),
|
|
256
|
-
});
|
|
257
|
-
return [...(traces ?? [])]
|
|
258
|
-
.sort((a, b) => (b.timestamp?.start ?? '').localeCompare(a.timestamp?.start ?? ''))
|
|
259
|
-
.slice(0, limit);
|
|
260
|
-
}
|
|
261
|
-
}
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Calendar Operations for Home Assistant API
|
|
3
|
-
* Handles calendar listing and event retrieval
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import type { CalendarEvent, Calendar } from '../types/index.js';
|
|
7
|
-
import { logger } from '../utils/logger.js';
|
|
8
|
-
import type { RequestHandler } from './request.js';
|
|
9
|
-
|
|
10
|
-
interface CalendarApiResponse {
|
|
11
|
-
entity_id: string;
|
|
12
|
-
name?: string;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Calendar-related operations for the Home Assistant API.
|
|
17
|
-
*/
|
|
18
|
-
export class CalendarOperations {
|
|
19
|
-
constructor(private readonly request: RequestHandler) {}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Get all calendar entities
|
|
23
|
-
*/
|
|
24
|
-
async getCalendars(): Promise<Calendar[]> {
|
|
25
|
-
logger.debug('Fetching calendars');
|
|
26
|
-
|
|
27
|
-
// Use dedicated /api/calendars endpoint instead of filtering all states
|
|
28
|
-
const response = await this.request.get<CalendarApiResponse[]>('/calendars');
|
|
29
|
-
const calendars = response.map(cal => ({
|
|
30
|
-
entity_id: cal.entity_id,
|
|
31
|
-
name: cal.name || cal.entity_id.replace('calendar.', ''),
|
|
32
|
-
state: 'on', // Calendar API doesn't return state, default to 'on'
|
|
33
|
-
}));
|
|
34
|
-
|
|
35
|
-
logger.info('Fetched calendars', { count: calendars.length });
|
|
36
|
-
return calendars;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Get events from a calendar
|
|
41
|
-
* @param entityId - Calendar entity ID (e.g., 'calendar.my_calendar')
|
|
42
|
-
* @param startDate - Start date for event range (defaults to now)
|
|
43
|
-
* @param endDate - End date for event range (defaults to 30 days from start)
|
|
44
|
-
*/
|
|
45
|
-
async getCalendarEvents(
|
|
46
|
-
entityId: string,
|
|
47
|
-
startDate?: Date,
|
|
48
|
-
endDate?: Date
|
|
49
|
-
): Promise<CalendarEvent[]> {
|
|
50
|
-
const start = startDate || new Date();
|
|
51
|
-
const end = endDate || new Date(start.getTime() + 30 * 24 * 60 * 60 * 1000);
|
|
52
|
-
|
|
53
|
-
logger.debug('Fetching calendar events', { entityId, start: start.toISOString(), end: end.toISOString() });
|
|
54
|
-
|
|
55
|
-
// Calendar events use a special API endpoint, not the standard services API
|
|
56
|
-
const events = await this.request.get<CalendarEvent[]>(
|
|
57
|
-
`/calendars/${encodeURIComponent(entityId)}`,
|
|
58
|
-
{
|
|
59
|
-
start: start.toISOString(),
|
|
60
|
-
end: end.toISOString(),
|
|
61
|
-
}
|
|
62
|
-
);
|
|
63
|
-
|
|
64
|
-
logger.info('Fetched calendar events', { entityId, count: events.length });
|
|
65
|
-
return events;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Get events from all calendars
|
|
70
|
-
* @param startDate - Start date for event range (defaults to now)
|
|
71
|
-
* @param endDate - End date for event range (defaults to 30 days from start)
|
|
72
|
-
*/
|
|
73
|
-
async getAllCalendarEvents(
|
|
74
|
-
startDate?: Date,
|
|
75
|
-
endDate?: Date
|
|
76
|
-
): Promise<Array<{ calendar: string; events: CalendarEvent[] }>> {
|
|
77
|
-
const calendars = await this.getCalendars();
|
|
78
|
-
|
|
79
|
-
// Fetch all calendar events in parallel
|
|
80
|
-
const results = await Promise.all(
|
|
81
|
-
calendars.map(async calendar => {
|
|
82
|
-
try {
|
|
83
|
-
const events = await this.getCalendarEvents(calendar.entity_id, startDate, endDate);
|
|
84
|
-
return { calendar: calendar.entity_id, events };
|
|
85
|
-
} catch (error) {
|
|
86
|
-
logger.warn('Failed to fetch events for calendar', { calendar: calendar.entity_id, error });
|
|
87
|
-
return { calendar: calendar.entity_id, events: [] };
|
|
88
|
-
}
|
|
89
|
-
})
|
|
90
|
-
);
|
|
91
|
-
|
|
92
|
-
return results;
|
|
93
|
-
}
|
|
94
|
-
}
|
package/src/haClient/config.ts
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Config Operations for Home Assistant API
|
|
3
|
-
* Handles configuration and version information
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import type { HaVersion } from '../types/index.js';
|
|
7
|
-
import { logger } from '../utils/logger.js';
|
|
8
|
-
import type { RequestHandler } from './request.js';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Config-related operations for the Home Assistant API.
|
|
12
|
-
*/
|
|
13
|
-
export class ConfigOperations {
|
|
14
|
-
constructor(private readonly request: RequestHandler) {}
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Get config
|
|
18
|
-
*/
|
|
19
|
-
async getConfig(): Promise<Record<string, unknown>> {
|
|
20
|
-
logger.debug('Fetching config');
|
|
21
|
-
return await this.request.get<Record<string, unknown>>('/config');
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Check API (health check)
|
|
26
|
-
*/
|
|
27
|
-
async checkApi(): Promise<{ message: string }> {
|
|
28
|
-
logger.debug('Checking API health');
|
|
29
|
-
return await this.request.get<{ message: string }>('/');
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Get Home Assistant version and configuration info
|
|
34
|
-
* Returns only safe, public information (filters out internal config details)
|
|
35
|
-
*/
|
|
36
|
-
async getVersion(): Promise<HaVersion> {
|
|
37
|
-
logger.debug('Fetching Home Assistant version');
|
|
38
|
-
const config = await this.request.get<Record<string, unknown>>('/config');
|
|
39
|
-
logger.info('Fetched version', { version: config.version });
|
|
40
|
-
|
|
41
|
-
// Return only safe, public information
|
|
42
|
-
// Excludes: components, allowlist_external_dirs, allowlist_external_urls,
|
|
43
|
-
// config_dir, whitelist_external_dirs, safe_mode, state, external_url, internal_url,
|
|
44
|
-
// currency, country, language, latitude, longitude, elevation
|
|
45
|
-
return {
|
|
46
|
-
version: config.version as string,
|
|
47
|
-
location_name: config.location_name as string | undefined,
|
|
48
|
-
time_zone: config.time_zone as string | undefined,
|
|
49
|
-
unit_system: config.unit_system as Record<string, string> | undefined,
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
}
|