Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions Apps/home-assistant-matter-hub/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Exclude everything
test/
*.docker-entrypoint.sh
*.Dockerfile
build.js
tsconfig.json
package.tgz

# EXPLICITLY INCLUDE
!dist/
!package.json
!README.md
!LICENSE
34 changes: 34 additions & 0 deletions Apps/home-assistant-matter-hub/addon.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
ARG NODE_VERSION="22"

FROM node:${NODE_VERSION}-alpine AS nodebuild

FROM ghcr.io/hassio-addons/base:18.2.1

# Install Node.js
RUN apk add --no-cache libstdc++ bash
COPY --from=nodebuild /usr/local/bin/node /usr/local/bin/
COPY --from=nodebuild /usr/local/lib/node_modules /usr/local/lib/node_modules
RUN \
ln -s ../lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm && \
ln -s ../lib/node_modules/npm/bin/npx-cli.js /usr/local/bin/npx && \
ln -s ../lib/node_modules/corepack/dist/corepack.js /usr/local/bin/corepack
RUN corepack enable

ENV SUPERVISOR_TOKEN=""
VOLUME /config

COPY addon.docker-entrypoint.sh /docker-entrypoint.sh
RUN chmod +x /docker-entrypoint.sh

ARG PACKAGE_VERSION="unknown"
LABEL \
io.hass.version="$PACKAGE_VERSION" \
io.hass.type="addon" \
io.hass.arch="armhf|aarch64|i386|amd64"

RUN mkdir /install
COPY package.tgz /install/package.tgz
RUN npm install -g /install/package.tgz
RUN rm -rf /install

CMD /docker-entrypoint.sh
11 changes: 11 additions & 0 deletions Apps/home-assistant-matter-hub/addon.docker-entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/usr/bin/with-contenv bashio

exec home-assistant-matter-hub start \
--log-level=$(bashio::config 'app_log_level') \
--disable-log-colors=$(bashio::config 'disable_log_colors') \
--mdns-network-interface="$(bashio::config 'mdns_network_interface')" \
--storage-location=/config/data \
--web-port=$(bashio::addon.ingress_port) \
--home-assistant-url='http://supervisor/core' \
--home-assistant-access-token="$SUPERVISOR_TOKEN" \
--http-ip-whitelist="172.30.32.2"
42 changes: 42 additions & 0 deletions Apps/home-assistant-matter-hub/build.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import * as fs from "node:fs";
import * as path from "node:path";
import { fileURLToPath } from "node:url";
import { rimraf } from "rimraf";

const projectRoot = path.join(import.meta.dirname, "../..");

const frontend = packageDir("@home-assistant-matter-hub/frontend", "dist");
const backend = packageDir("@home-assistant-matter-hub/backend", "dist");

const dist = path.resolve(import.meta.dirname, "dist");
await rimraf(dist);

fs.cpSync(frontend, path.join(dist, "frontend"), {
recursive: true,
});
fs.cpSync(backend, path.join(dist, "backend"), {
recursive: true,
});

fs.cpSync(
path.join(projectRoot, "README.md"),
path.join(import.meta.dirname, "README.md"),
);
fs.cpSync(
path.join(projectRoot, "LICENSE"),
path.join(import.meta.dirname, "LICENSE"),
);

/**
* Resolve a directory in a package
* @param {string} packageName The path of the package json
* @param {string} directory The dist dir in the package
* @returns {string}
*/
function packageDir(packageName, directory) {
const packageJsonPath = fileURLToPath(
import.meta.resolve(path.join(packageName, "package.json")),
);
const packagePath = path.dirname(packageJsonPath);
return path.join(packagePath, directory);
}
67 changes: 67 additions & 0 deletions Apps/home-assistant-matter-hub/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
name: home-assistant-matter-hub
services:
home-assistant-matter-hub:
image: panwang/home-assistant-matter-hub:latest
container_name: home-assistant-matter-hub
restart: unless-stopped
network_mode: host
volumes:
- /DATA/AppData/$AppID/data:/data
environment:
- HAMH_HOME_ASSISTANT_URL=${HAMH_HOME_ASSISTANT_URL}
- HAMH_HOME_ASSISTANT_ACCESS_TOKEN=${HAMH_HOME_ASSISTANT_ACCESS_TOKEN}
- HAMH_STORAGE_LOCATION=/data
- TZ=${TZ}
- PUID=${PUID}
- PGID=${PGID}
x-casaos:
envs:
- container: HAMH_HOME_ASSISTANT_URL
default: "http://localhost:8123"
description:
en_US: "Home Assistant URL (Must start with http:// or https://)"
zh_CN: "Home Assistant 访问地址 (必须以 http:// 或 https:// 开头)"
- container: HAMH_HOME_ASSISTANT_ACCESS_TOKEN
description:
en_US: "Long-lived Access Token (Required! Generate in HA Profile)"
zh_CN: "HA 长期访问令牌 (必填!在 HA 个人资料页底部生成)"
ports:
- container: "8482"
host: "8482"
description:
en_US: Web UI Port
zh_CN: 网页管理界面端口
- container: "5540"
description:
en_US: Matter Communication Port
zh_CN: Matter 通信端口
volumes:
- container: /data
description:
en_US: Data directory
zh_CN: 数据持久化目录

x-casaos:
architectures:
- amd64
- arm
- arm64
main: home-assistant-matter-hub
scheme: http
port_map: "8482"
index: /
author: symi-daguo
category: Home Automation
developer: t0bst4r
description:
en_US: "Simulate Matter bridges to publish your entities from Home Assistant to any Matter-compatible controller like Alexa, Apple Home, or Google Home. Completely local communication, no port forwarding required."
zh_CN: "模拟 Matter 桥接器,将 Home Assistant 中的实体发布到任何兼容 Matter 的控制器(如 Alexa、Apple Home 或 Google Home)。完全本地化通信,无需配置端口转发。"
tagline:
en_US: "Bridge Home Assistant entities to Matter (HomeKit/Alexa/Google)"
zh_CN: "将 Home Assistant 实体桥接到 Matter (HomeKit/Alexa/Google)"
title:
en_US: "HA Matter Hub"
zh_CN: "HA Matter 枢纽"
icon: https://raw.githubusercontent.com/symi-daguo/home-assistant-matter-hub/main/Apps/home-assistant-matter-hub/icon.png
screenshot_link:
- https://raw.githubusercontent.com/symi-daguo/home-assistant-matter-hub/main/Apps/home-assistant-matter-hub/screenshot-1.png
Binary file added Apps/home-assistant-matter-hub/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
103 changes: 103 additions & 0 deletions Apps/home-assistant-matter-hub/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
{
"name": "home-assistant-matter-hub",
"description": "",
"version": "0.0.0",
"private": false,
"type": "module",
"bin": {
"home-assistant-matter-hub": "./dist/backend/cli.js"
},
"author": {
"email": "[email protected]",
"name": "t0bst4r",
"url": "https://github.com/t0bst4r"
},
"keywords": [
"home-assistant",
"homeassistant",
"home",
"assistant",
"apple home",
"google home",
"apple",
"google",
"alexa",
"matter",
"matter.js",
"matterjs",
"project-chip",
"smart",
"smarthome",
"smart-home"
],
"bugs": {
"url": "https://github.com/t0bst4r/home-assistant-matter-hub/issues"
},
"license": "Apache-2.0",
"repository": "github:t0bst4r/home-assistant-matter-hub",
"scripts": {
"cleanup": "npx rimraf node_modules dist pack LICENSE README.md",
"build": "node build.js",
"bundle": "pnpm pack --out package.tgz",
"postbuild": "pnpm run bundle",
"test": "vitest run",
"prestart": "pnpm run build",
"start": "dotenvx run -f ../../.env -- ./dist/backend/cli.js start"
},
"dependencies": {
"@matter/main": "0.15.6",
"@matter/nodejs": "0.15.6",
"@matter/general": "0.15.6",
"ajv": "8.17.1",
"color": "5.0.3",
"debounce": "3.0.0",
"express": "5.2.1",
"express-basic-auth": "1.2.1",
"express-ip-access-control": "1.1.3",
"home-assistant-js-websocket": "9.6.0",
"lodash-es": "4.17.21",
"nocache": "4.0.0",
"rxjs": "7.8.2",
"strip-color": "0.1.0",
"yargs": "18.0.0",
"ws": "8.18.3"
},
"devDependencies": {
"@home-assistant-matter-hub/backend": "workspace:*",
"@home-assistant-matter-hub/frontend": "workspace:*",
"@home-assistant-matter-hub/common": "workspace:*",
"@types/lodash-es": "^4.17.12"
},
"nx": {
"targets": {
"start": {
"cache": false,
"dependsOn": [
"build"
]
},
"pack": {
"cache": true,
"dependsOn": [
"build"
],
"outputs": [
"{projectRoot}/pack"
]
},
"build": {
"inputs": [
"^default",
"default",
"{workspaceRoot}/README.md",
"{workspaceRoot}/LICENSE"
],
"outputs": [
"{projectRoot}/dist",
"{projectRoot}/README.md",
"{projectRoot}/LICENSE"
]
}
}
}
}
Binary file added Apps/home-assistant-matter-hub/screenshot-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 18 additions & 0 deletions Apps/home-assistant-matter-hub/standalone.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
ARG NODE_VERSION="22"
ARG PACKAGE_VERSION="unknown"

FROM node:${NODE_VERSION}-alpine
ARG PACKAGE_VERSION
RUN apk add --no-cache netcat-openbsd

ENV HAMH_STORAGE_LOCATION="/data"
VOLUME /data

LABEL package.version="${PACKAGE_VERSION}"

RUN mkdir /install
COPY package.tgz /install/package.tgz
RUN npm install -g /install/package.tgz
RUN rm -rf /install

CMD ["home-assistant-matter-hub", "start"]
26 changes: 26 additions & 0 deletions Apps/home-assistant-matter-hub/test/package.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import backend from "@home-assistant-matter-hub/backend/package.json" with {
type: "json",
};
import common from "@home-assistant-matter-hub/common/package.json" with {
type: "json",
};
import { mapValues, pickBy } from "lodash-es";
import { describe, expect, it } from "vitest";
import own from "../package.json" with { type: "json" };

describe("home-assistant-matter-hub", () => {
it("should include all necessary dependencies", () => {
const expected = pickBy(
{ ...backend.dependencies, ...common.dependencies },
(_, key) => !key.startsWith("@home-assistant-matter-hub/"),
);
expect(own.dependencies).toEqual(expected);
});

it("should pin all dependencies", () => {
const expected = mapValues(own.dependencies, (value) =>
value.replace(/^\D+/, ""),
);
expect(own.dependencies).toEqual(expected);
});
});
17 changes: 17 additions & 0 deletions Apps/home-assistant-matter-hub/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"compilerOptions": {
// Compiler
"target": "ES2020",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"noEmit": true,

// Lint
"resolveJsonModule": true,
"strict": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"skipLibCheck": true
},
"include": ["./test/"]
}