minor fixes
This commit is contained in:
parent
9a3f622941
commit
fa3cd39674
@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: 'HA Matter Bridge'
|
name: 'HA Matter Bridge'
|
||||||
version: '0.0.1-alpha'
|
version: '0.0.2-alpha'
|
||||||
slug: ha-matter-bridge
|
slug: ha-matter-bridge
|
||||||
description: This project serves as a proof of concept to connect HomeAssistant devices to Voice Assistants through the Matter Protocol.
|
description: This project serves as a proof of concept to connect HomeAssistant devices to Voice Assistants through the Matter Protocol.
|
||||||
init: false
|
init: false
|
||||||
|
@ -1,11 +0,0 @@
|
|||||||
version: '3'
|
|
||||||
services:
|
|
||||||
ha-bridge:
|
|
||||||
build: .
|
|
||||||
environment:
|
|
||||||
- HA_HOST=${HA_HOST}
|
|
||||||
- HA_PORT=${HA_PORT}
|
|
||||||
- HA_ACCESS_TOKEN=${HA_ACCESS_TOKEN}
|
|
||||||
volumes:
|
|
||||||
- ./deviceData:/app/deviceData:rw
|
|
||||||
network_mode: host
|
|
@ -1,12 +0,0 @@
|
|||||||
FROM node:18.19.0-alpine
|
|
||||||
WORKDIR /app
|
|
||||||
COPY ./package.json ./
|
|
||||||
COPY ./package-lock.json ./
|
|
||||||
COPY ./src ./src
|
|
||||||
COPY ./tsconfig.json ./
|
|
||||||
|
|
||||||
|
|
||||||
RUN npm install
|
|
||||||
RUN npm install ts-node
|
|
||||||
|
|
||||||
CMD [ "npm", "run", "start" ]
|
|
@ -2,35 +2,21 @@ import { Logger } from '@project-chip/matter-node.js/log';
|
|||||||
import { HassEntity, StateChangedEvent } from './HAssTypes';
|
import { HassEntity, StateChangedEvent } from './HAssTypes';
|
||||||
import hass, { HassApi, HassWsOptions } from 'homeassistant-ws';
|
import hass, { HassApi, HassWsOptions } from 'homeassistant-ws';
|
||||||
|
|
||||||
const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));
|
|
||||||
|
|
||||||
export class HAMiddleware {
|
export class HAMiddleware {
|
||||||
private logger = new Logger('HAMiddleware');
|
private logger = new Logger('HAMiddleware');
|
||||||
private hassClient: HassApi;
|
private hassClient: HassApi;
|
||||||
private static instance: HAMiddleware;
|
private static instance: HAMiddleware;
|
||||||
private static callerOptions: Partial<HassWsOptions> | undefined;
|
|
||||||
private requestFulfilled: boolean = true;
|
|
||||||
private entities: { [k: string]: HassEntity } = {};
|
private entities: { [k: string]: HassEntity } = {};
|
||||||
private functionsToCallOnChange: {
|
private functionsToCallOnChange: {
|
||||||
[k: string]: ((data: StateChangedEvent) => void) | undefined;
|
[k: string]: ((data: StateChangedEvent) => void) | undefined;
|
||||||
} = {};
|
} = {};
|
||||||
|
|
||||||
async waitCompletition(): Promise<void> {
|
|
||||||
let waited = 0;
|
|
||||||
const timeOut = 5000;
|
|
||||||
while (!this.requestFulfilled && waited < timeOut) {
|
|
||||||
await sleep(1000);
|
|
||||||
waited += 1000;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
stop(): void {
|
stop(): void {
|
||||||
this.hassClient.rawClient.ws.close();
|
this.hassClient.rawClient.ws.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
async callAService(domain: string, service: string, extraArgs?: unknown) {
|
async callAService(domain: string, service: string, extraArgs?: unknown) {
|
||||||
this.requestFulfilled = false;
|
await this.hassClient.callService(domain, service, extraArgs);
|
||||||
this.hassClient.callService(domain, service, extraArgs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
subscribe() {
|
subscribe() {
|
||||||
@ -43,13 +29,15 @@ export class HAMiddleware {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
subscrieToDevice(deviceId: string, fn: (event: StateChangedEvent) => void) {
|
subscribeToDevice(
|
||||||
|
deviceId: string,
|
||||||
|
fn: (event: StateChangedEvent) => void
|
||||||
|
) {
|
||||||
this.functionsToCallOnChange[deviceId] = fn;
|
this.functionsToCallOnChange[deviceId] = fn;
|
||||||
this.logger.debug(this.functionsToCallOnChange);
|
this.logger.debug(this.functionsToCallOnChange);
|
||||||
}
|
}
|
||||||
|
|
||||||
async getStates(): Promise<{ [k: string]: HassEntity }> {
|
async getStates(): Promise<{ [k: string]: HassEntity }> {
|
||||||
this.requestFulfilled = false;
|
|
||||||
const states = await this.hassClient.getStates();
|
const states = await this.hassClient.getStates();
|
||||||
const sorted = states.reduceRight<{ [k: string]: HassEntity }>(
|
const sorted = states.reduceRight<{ [k: string]: HassEntity }>(
|
||||||
(last, current) => {
|
(last, current) => {
|
||||||
@ -82,9 +70,7 @@ export class HAMiddleware {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async getServices() {
|
async getServices() {
|
||||||
this.requestFulfilled = false;
|
|
||||||
const states = await this.hassClient.getServices();
|
const states = await this.hassClient.getServices();
|
||||||
|
|
||||||
return states;
|
return states;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,7 +82,6 @@ export class HAMiddleware {
|
|||||||
callerOptions?: Partial<HassWsOptions> | undefined
|
callerOptions?: Partial<HassWsOptions> | undefined
|
||||||
): Promise<HAMiddleware> {
|
): Promise<HAMiddleware> {
|
||||||
if (!HAMiddleware.instance) {
|
if (!HAMiddleware.instance) {
|
||||||
HAMiddleware.callerOptions = callerOptions;
|
|
||||||
const client = await hass(callerOptions);
|
const client = await hass(callerOptions);
|
||||||
HAMiddleware.instance = new HAMiddleware(client);
|
HAMiddleware.instance = new HAMiddleware(client);
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ import { HAMiddleware } from '../home-assistant/HAmiddleware';
|
|||||||
|
|
||||||
const LOGGER = new Logger('Mapper');
|
const LOGGER = new Logger('Mapper');
|
||||||
|
|
||||||
async function setHasEnties(
|
async function setHasEntities(
|
||||||
haMiddleware: HAMiddleware,
|
haMiddleware: HAMiddleware,
|
||||||
bridge: Bridge
|
bridge: Bridge
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
@ -22,6 +22,6 @@ export async function addAllDevicesToBridge(
|
|||||||
haMiddleware: HAMiddleware,
|
haMiddleware: HAMiddleware,
|
||||||
bridge: Bridge
|
bridge: Bridge
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
await setHasEnties(haMiddleware, bridge);
|
await setHasEntities(haMiddleware, bridge);
|
||||||
haMiddleware.subscribe();
|
haMiddleware.subscribe();
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ import { AddHaDeviceToBridge, Bridge, HAMiddleware } from '../MapperType';
|
|||||||
import { Logger } from '@project-chip/matter-node.js/log';
|
import { Logger } from '@project-chip/matter-node.js/log';
|
||||||
|
|
||||||
const LOGGER = new Logger('DimmableLight');
|
const LOGGER = new Logger('DimmableLight');
|
||||||
export const addDimmerableLightDevice: AddHaDeviceToBridge = (
|
export const addDimmableLightDevice: AddHaDeviceToBridge = (
|
||||||
haEntity: HassEntity,
|
haEntity: HassEntity,
|
||||||
haMiddleware: HAMiddleware,
|
haMiddleware: HAMiddleware,
|
||||||
bridge: Bridge
|
bridge: Bridge
|
||||||
@ -63,7 +63,7 @@ export const addDimmerableLightDevice: AddHaDeviceToBridge = (
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
haMiddleware.subscrieToDevice(
|
haMiddleware.subscribeToDevice(
|
||||||
haEntity.entity_id,
|
haEntity.entity_id,
|
||||||
(event: StateChangedEvent) => {
|
(event: StateChangedEvent) => {
|
||||||
LOGGER.debug(`Event for device ${haEntity.entity_id}`);
|
LOGGER.debug(`Event for device ${haEntity.entity_id}`);
|
@ -8,7 +8,7 @@ import {
|
|||||||
import { AddHaDeviceToBridge, Bridge, HAMiddleware } from '../MapperType';
|
import { AddHaDeviceToBridge, Bridge, HAMiddleware } from '../MapperType';
|
||||||
import { Logger } from '@project-chip/matter-node.js/log';
|
import { Logger } from '@project-chip/matter-node.js/log';
|
||||||
|
|
||||||
const LOGGER = new Logger('OnOfflIght');
|
const LOGGER = new Logger('OnOffLight');
|
||||||
export const addOnOffLightDevice: AddHaDeviceToBridge = (
|
export const addOnOffLightDevice: AddHaDeviceToBridge = (
|
||||||
haEntity: HassEntity,
|
haEntity: HassEntity,
|
||||||
haMiddleware: HAMiddleware,
|
haMiddleware: HAMiddleware,
|
||||||
@ -42,7 +42,7 @@ export const addOnOffLightDevice: AddHaDeviceToBridge = (
|
|||||||
`Identify called for OnOffDevice ${haEntity.attributes['friendly_name']} with id: ${serialFromId} and identifyTime: ${identifyTime}`
|
`Identify called for OnOffDevice ${haEntity.attributes['friendly_name']} with id: ${serialFromId} and identifyTime: ${identifyTime}`
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
haMiddleware.subscrieToDevice(
|
haMiddleware.subscribeToDevice(
|
||||||
haEntity.entity_id,
|
haEntity.entity_id,
|
||||||
(event: StateChangedEvent) => {
|
(event: StateChangedEvent) => {
|
||||||
LOGGER.debug(`Event for device ${haEntity.entity_id}`);
|
LOGGER.debug(`Event for device ${haEntity.entity_id}`);
|
||||||
|
@ -2,11 +2,11 @@ import { Logger } from '@project-chip/matter-node.js/log';
|
|||||||
import { HAMiddleware } from '../../../home-assistant/HAmiddleware';
|
import { HAMiddleware } from '../../../home-assistant/HAmiddleware';
|
||||||
import { HassEntity } from '../../../home-assistant/HAssTypes';
|
import { HassEntity } from '../../../home-assistant/HAssTypes';
|
||||||
import { AddHaDeviceToBridge, Bridge } from '../MapperType';
|
import { AddHaDeviceToBridge, Bridge } from '../MapperType';
|
||||||
import { addDimmerableLightDevice } from './DimmerableLightDevice';
|
import { addDimmableLightDevice } from './DimmableLightDevice';
|
||||||
import { addOnOffLightDevice } from './OnOffLightDevice';
|
import { addOnOffLightDevice } from './OnOffLightDevice';
|
||||||
import { Device } from '@project-chip/matter-node.js/device';
|
import { Device } from '@project-chip/matter-node.js/device';
|
||||||
|
|
||||||
export * from './DimmerableLightDevice';
|
export * from './DimmableLightDevice';
|
||||||
export * from './OnOffLightDevice';
|
export * from './OnOffLightDevice';
|
||||||
|
|
||||||
const LOGGER = new Logger('Lights');
|
const LOGGER = new Logger('Lights');
|
||||||
@ -16,8 +16,8 @@ const LIGHTS_MAP_FUNCTIONS: Map<string, AddHaDeviceToBridge> = new Map<
|
|||||||
AddHaDeviceToBridge
|
AddHaDeviceToBridge
|
||||||
>([
|
>([
|
||||||
['onoff', addOnOffLightDevice],
|
['onoff', addOnOffLightDevice],
|
||||||
['rgb', addDimmerableLightDevice],
|
['rgb', addDimmableLightDevice],
|
||||||
['brightness', addDimmerableLightDevice],
|
['brightness', addDimmableLightDevice],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const LIGHTS_MAP: Map<string, Device> = new Map<string, Device>();
|
const LIGHTS_MAP: Map<string, Device> = new Map<string, Device>();
|
||||||
|
@ -29,7 +29,7 @@ export class Bridge {
|
|||||||
private ready = false;
|
private ready = false;
|
||||||
|
|
||||||
private matterServer: MatterServer;
|
private matterServer: MatterServer;
|
||||||
private static instace: Bridge;
|
private static instance: Bridge;
|
||||||
private logger = new Logger('bridge');
|
private logger = new Logger('bridge');
|
||||||
private storageManager: StorageManager;
|
private storageManager: StorageManager;
|
||||||
private aggregator: Aggregator;
|
private aggregator: Aggregator;
|
||||||
@ -49,10 +49,10 @@ export class Bridge {
|
|||||||
matterServer: MatterServer,
|
matterServer: MatterServer,
|
||||||
storageManager: StorageManager
|
storageManager: StorageManager
|
||||||
): Bridge {
|
): Bridge {
|
||||||
if (!Bridge.instace) {
|
if (!Bridge.instance) {
|
||||||
this.instace = new Bridge(matterServer, storageManager);
|
this.instance = new Bridge(matterServer, storageManager);
|
||||||
}
|
}
|
||||||
return Bridge.instace;
|
return Bridge.instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async setupContextAndCommissioningServer(): Promise<CommissioningServer> {
|
private async setupContextAndCommissioningServer(): Promise<CommissioningServer> {
|
||||||
|
@ -1 +1,3 @@
|
|||||||
name: ha-matter-bridge
|
name: ha-matter-bridge
|
||||||
|
maintainer: Jatus93
|
||||||
|
url: https://github.com/Jatus93/ha-matter-bridge
|
Loading…
Reference in New Issue
Block a user