minor fixes

This commit is contained in:
Jatus 2024-01-30 15:18:30 +01:00
parent 9a3f622941
commit fa3cd39674
10 changed files with 22 additions and 58 deletions

View File

@ -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

View File

@ -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

View File

@ -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" ]

View File

@ -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);
} }

View File

@ -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();
} }

View File

@ -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}`);

View File

@ -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}`);

View File

@ -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>();

View File

@ -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> {

View File

@ -1 +1,3 @@
name: ha-matter-bridge name: ha-matter-bridge
maintainer: Jatus93
url: https://github.com/Jatus93/ha-matter-bridge