update
This commit is contained in:
@@ -1,11 +1,15 @@
|
|||||||
{
|
{
|
||||||
"name": "@kevisual/ha-api",
|
"name": "@kevisual/ha-api",
|
||||||
"version": "0.0.5",
|
"version": "0.0.6",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "src/index.ts",
|
"main": "src/index.ts",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "echo \"Error: no test specified\" && exit 1"
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
},
|
},
|
||||||
|
"app": {
|
||||||
|
"type": "pm2-system-app",
|
||||||
|
"entry": "src/index.ts"
|
||||||
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"src"
|
"src"
|
||||||
],
|
],
|
||||||
|
|||||||
21
readme.md
21
readme.md
@@ -1,4 +1,4 @@
|
|||||||
# 灯光管理
|
## 灯光管理
|
||||||
|
|
||||||
该模块提供对Home Assistant中灯光设备的管理功能,包括获取灯光列表、搜索特定灯光设备以及控制灯光的开关状态。
|
该模块提供对Home Assistant中灯光设备的管理功能,包括获取灯光列表、搜索特定灯光设备以及控制灯光的开关状态。
|
||||||
|
|
||||||
@@ -25,3 +25,22 @@ if(searchResult.hasMore) {
|
|||||||
console.log('没有找到匹配的灯光设备。');
|
console.log('没有找到匹配的灯光设备。');
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## 音箱管理
|
||||||
|
|
||||||
|
该模块提供对Home Assistant中音箱设备的管理功能,执行文本指令等。
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { TextHA } from '@kevisual/ha-api';
|
||||||
|
|
||||||
|
const tts = new TextHA({
|
||||||
|
host: 'http://your-home-assistant:8123',
|
||||||
|
token: 'your-long-lived-access-token',
|
||||||
|
});
|
||||||
|
// 获取所有音箱设备
|
||||||
|
const entities = await text.getSpeakerEntities();
|
||||||
|
// 执行文本指令
|
||||||
|
const res2 = await text.executeTextDirective('text.xiaomi_lx06_9e08_execute_text_directive', '关闭阳台灯');
|
||||||
|
console.log(res2);
|
||||||
|
```
|
||||||
|
|
||||||
|
|||||||
12
src/core.ts
12
src/core.ts
@@ -4,6 +4,7 @@ export type HACoreOptions = {
|
|||||||
token: string;
|
token: string;
|
||||||
homeassistantURL?: string;
|
homeassistantURL?: string;
|
||||||
ttl?: number;
|
ttl?: number;
|
||||||
|
ha?: HACore;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* https://developers.home-assistant.io/docs/api/rest/
|
* https://developers.home-assistant.io/docs/api/rest/
|
||||||
@@ -14,7 +15,10 @@ export class HACore {
|
|||||||
static serviceName = '';
|
static serviceName = '';
|
||||||
cache: LRUStorage;
|
cache: LRUStorage;
|
||||||
constructor(options: HACoreOptions) {
|
constructor(options: HACoreOptions) {
|
||||||
this.token = options?.token;
|
this.token = options?.token!;
|
||||||
|
if (!this.token && options.ha) {
|
||||||
|
this.token = options.ha?.token;
|
||||||
|
}
|
||||||
this.homeassistantURL = options?.homeassistantURL || 'http://localhost:8123';
|
this.homeassistantURL = options?.homeassistantURL || 'http://localhost:8123';
|
||||||
this.cache = new LRUStorage({ max: 200, ttl: options?.ttl || 1000 * 60 * 30 }); // 30分钟缓存
|
this.cache = new LRUStorage({ max: 200, ttl: options?.ttl || 1000 * 60 * 30 }); // 30分钟缓存
|
||||||
}
|
}
|
||||||
@@ -91,9 +95,9 @@ export class HACore {
|
|||||||
});
|
});
|
||||||
return infoList;
|
return infoList;
|
||||||
}
|
}
|
||||||
async runService(opts: { entity_id?: string, name?: string, service?: string, data?: Record<string, any> }) {
|
async runService(opts: { entity_id?: string, name?: string, serverName?: string, service?: string, data?: Record<string, any> }) {
|
||||||
// e.g., service: 'turn_on', 'turn_off', 'toggle'
|
// e.g., service: 'turn_on', 'turn_off', 'toggle'
|
||||||
const serviceName = (this.constructor as typeof HACore).serviceName;
|
const serviceName = opts?.serverName || (this.constructor as typeof HACore).serviceName;
|
||||||
let { entity_id, service = '', data } = opts;
|
let { entity_id, service = '', data } = opts;
|
||||||
if (!entity_id && opts.name) {
|
if (!entity_id && opts.name) {
|
||||||
const entities = await this.getServiceEntities();
|
const entities = await this.getServiceEntities();
|
||||||
@@ -156,7 +160,7 @@ export const entitiesTypes = [
|
|||||||
{ "type": "number", "desc": "可调整的数值控件,有上下限,如温度设定、定时器" }
|
{ "type": "number", "desc": "可调整的数值控件,有上下限,如温度设定、定时器" }
|
||||||
]
|
]
|
||||||
|
|
||||||
type EntityItem = {
|
export type EntityItem = {
|
||||||
entity_id: string;
|
entity_id: string;
|
||||||
attributes: {
|
attributes: {
|
||||||
friendly_name?: string;
|
friendly_name?: string;
|
||||||
|
|||||||
46
src/light.ts
46
src/light.ts
@@ -1,5 +1,5 @@
|
|||||||
import Fuse from "fuse.js";
|
import Fuse from "fuse.js";
|
||||||
import { HACore, HACoreOptions, InfoItem } from "./core.ts";
|
import { HACore, HACoreOptions, InfoItem, EntityItem } from "./core.ts";
|
||||||
export class LightHA extends HACore {
|
export class LightHA extends HACore {
|
||||||
static serviceName = 'light';
|
static serviceName = 'light';
|
||||||
constructor(options: HACoreOptions) {
|
constructor(options: HACoreOptions) {
|
||||||
@@ -59,4 +59,48 @@ export class ButtonHA extends HACore {
|
|||||||
constructor(options: HACoreOptions) {
|
constructor(options: HACoreOptions) {
|
||||||
super(options);
|
super(options);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export class SpeakerHA extends HACore {
|
||||||
|
static serviceName = 'notify';
|
||||||
|
constructor(options: HACoreOptions) {
|
||||||
|
super(options);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 获取音箱实体列表
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
getSpeakerEntities(): Promise<EntityItem[]> {
|
||||||
|
return this.getEntities((entity: EntityItem) => entity.entity_id.startsWith(`notify.`) && entity.attributes?.friendly_name?.includes?.('音箱'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class TextHA extends HACore {
|
||||||
|
static serviceName = 'text';
|
||||||
|
constructor(options: HACoreOptions) {
|
||||||
|
super(options);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 获取音箱实体列表
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
getSpeakerEntities(): Promise<EntityItem[]> {
|
||||||
|
return this.getEntities((entity: EntityItem) => entity.entity_id.startsWith(`text.`) && entity.attributes?.friendly_name?.includes?.('音箱'));
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 执行文本指令
|
||||||
|
* @param entity_id
|
||||||
|
* @param value
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
executeTextDirective(entity_id: string, value: string): Promise<any> {
|
||||||
|
return this.runService({
|
||||||
|
entity_id,
|
||||||
|
service: 'set_value',
|
||||||
|
data: {
|
||||||
|
value
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { LightHA, AutoHA, EventHA, ScriptHA, ButtonHA } from "../src/index.ts";
|
import { LightHA, AutoHA, EventHA, ScriptHA, ButtonHA, HACore, SpeakerHA, TextHA } from "../src/index.ts";
|
||||||
|
|
||||||
import util from 'node:util';
|
import util from 'node:util';
|
||||||
import dotenv from 'dotenv';
|
import dotenv from 'dotenv';
|
||||||
@@ -7,13 +7,15 @@ export const showMore = (obj: any) => {
|
|||||||
return util.inspect(obj, { depth: null, colors: true });
|
return util.inspect(obj, { depth: null, colors: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
export const hacore = new LightHA({ token: process.env.HAAS_TOKEN || '', homeassistantURL: process.env.HAAS_URL });
|
export const hacore = new HACore({ token: process.env.HAAS_TOKEN || '', homeassistantURL: process.env.HAAS_URL });
|
||||||
|
export const light = new LightHA({ token: process.env.HAAS_TOKEN || '', homeassistantURL: process.env.HAAS_URL });
|
||||||
|
|
||||||
export const auto = new AutoHA({ token: process.env.HAAS_TOKEN || '', homeassistantURL: process.env.HAAS_URL });
|
export const auto = new AutoHA({ token: process.env.HAAS_TOKEN || '', homeassistantURL: process.env.HAAS_URL });
|
||||||
export const event = new EventHA({ token: process.env.HAAS_TOKEN || '', homeassistantURL: process.env.HAAS_URL });
|
export const event = new EventHA({ token: process.env.HAAS_TOKEN || '', homeassistantURL: process.env.HAAS_URL });
|
||||||
export const script = new ScriptHA({ token: process.env.HAAS_TOKEN || '', homeassistantURL: process.env.HAAS_URL });
|
export const script = new ScriptHA({ token: process.env.HAAS_TOKEN || '', homeassistantURL: process.env.HAAS_URL });
|
||||||
export const button = new ButtonHA({ token: process.env.HAAS_TOKEN || '', homeassistantURL: process.env.HAAS_URL });
|
export const button = new ButtonHA({ token: process.env.HAAS_TOKEN || '', homeassistantURL: process.env.HAAS_URL });
|
||||||
|
export const speaker = new SpeakerHA({ token: process.env.HAAS_TOKEN || '', homeassistantURL: process.env.HAAS_URL });
|
||||||
|
export const text = new TextHA({ token: process.env.HAAS_TOKEN || '', homeassistantURL: process.env.HAAS_URL });
|
||||||
// const enti = await hacore.getEntities((item) => item.attributes?.friendly_name?.includes?.('电视'));
|
// const enti = await hacore.getEntities((item) => item.attributes?.friendly_name?.includes?.('电视'));
|
||||||
// console.log(showMore(enti), enti.length);
|
// console.log(showMore(enti), enti.length);
|
||||||
|
|
||||||
|
|||||||
27
test/speaker.ts
Normal file
27
test/speaker.ts
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import { speaker, showMore, text } from './common.ts';
|
||||||
|
|
||||||
|
// const entities = await speaker.getSpeakerEntities();
|
||||||
|
const entities = await text.getSpeakerEntities();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
console.log(showMore(entities));
|
||||||
|
|
||||||
|
console.log(`实体数量: ${entities.length}`);
|
||||||
|
|
||||||
|
// const res = await speaker.runService({
|
||||||
|
// entity_id: 'text.xiaomi_lx06_9e08_execute_text_directive',
|
||||||
|
// service: 'set_value',
|
||||||
|
// serverName: 'text',
|
||||||
|
// data: {
|
||||||
|
// value: '关闭阳台灯'
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
|
||||||
|
// console.log(showMore(res));
|
||||||
|
|
||||||
|
const res2 = await text.executeTextDirective('text.xiaomi_lx06_9e08_execute_text_directive', '关闭阳台灯');
|
||||||
|
|
||||||
|
console.log(showMore(res2));
|
||||||
|
|
||||||
|
const call = { "type": "call_service", "domain": "text", "service": "set_value", "target": { "entity_id": "text.xiaomi_lx06_9e08_execute_text_directive" }, "return_response": false, "service_data": { "value": "关闭阳台灯" }, "id": 101 }
|
||||||
Reference in New Issue
Block a user