Files

91 lines
3.3 KiB
TypeScript
Raw Permalink Normal View History

2026-05-05 14:57:06 +00:00
import { expect, tap } from '@git.zone/tstest/tapbundle';
import { MatterMapper } from '../../ts/integrations/matter/index.js';
import type { IMatterSnapshot } from '../../ts/integrations/matter/index.js';
const snapshot: IMatterSnapshot = {
connected: true,
events: [],
serverInfo: {
fabric_id: 1,
compressed_fabric_id: 2,
schema_version: 11,
min_supported_schema_version: 6,
sdk_version: '1.4.2',
wifi_credentials_set: true,
thread_credentials_set: false,
bluetooth_enabled: false,
},
nodes: [{
node_id: 1234,
available: true,
attributes: {
'0/29/0': [{ deviceType: 0x0016, revision: 1 }],
'0/29/1': [29, 40],
'0/40/1': 'Acme',
'0/40/2': 123,
'0/40/3': 'Matter Test Device',
'0/40/4': 456,
'0/40/5': 'Test Node',
'0/40/15': 'serial-1',
'1/29/0': [{ deviceType: 0x0101, revision: 2 }],
'1/29/1': [29, 6, 8],
'1/6/0': true,
'1/8/0': 128,
'1/8/2': 1,
'1/8/3': 254,
'2/29/0': [{ deviceType: 0x0015, revision: 1 }],
'2/29/1': [29, 69],
'2/69/0': false,
'3/29/0': [{ deviceType: 0x0202, revision: 1 }],
'3/29/1': [29, 258],
'3/258/10': 0,
'3/258/14': 2500,
'4/29/0': [{ deviceType: 0x000a, revision: 1 }],
'4/29/1': [29, 257],
'4/257/0': 1,
'5/29/0': [{ deviceType: 0x0301, revision: 1 }],
'5/29/1': [29, 513],
'5/513/0': 2150,
'5/513/18': 2000,
'5/513/28': 4,
},
}],
};
tap.test('maps Matter nodes to canonical devices and entities', async () => {
const devices = MatterMapper.toDevices(snapshot);
const entities = MatterMapper.toEntities(snapshot);
expect(devices.some((deviceArg) => deviceArg.id === 'matter.node.1234.endpoint.1')).toBeTrue();
expect(entities.some((entityArg) => entityArg.platform === 'light' && entityArg.state === 'on')).toBeTrue();
expect(entities.some((entityArg) => entityArg.platform === 'binary_sensor' && entityArg.attributes?.deviceClass === 'door')).toBeTrue();
expect(entities.some((entityArg) => entityArg.platform === 'cover' && entityArg.attributes?.position === 75)).toBeTrue();
expect(entities.some((entityArg) => String(entityArg.platform) === 'lock' && entityArg.state === 'locked')).toBeTrue();
expect(entities.some((entityArg) => entityArg.platform === 'climate' && entityArg.state === 'heat')).toBeTrue();
});
tap.test('maps entity services to Matter server commands', async () => {
const light = MatterMapper.toEntities(snapshot).find((entityArg) => entityArg.platform === 'light');
const cover = MatterMapper.toEntities(snapshot).find((entityArg) => entityArg.platform === 'cover');
const turnOff = MatterMapper.commandForService(snapshot, {
domain: 'light',
service: 'turn_off',
target: { entityId: light?.id },
});
const setPosition = MatterMapper.commandForService(snapshot, {
domain: 'cover',
service: 'set_position',
target: { entityId: cover?.id },
data: { position: 42 },
});
expect(turnOff?.command).toEqual('device_command');
expect(turnOff?.args?.cluster_id).toEqual(6);
expect(turnOff?.args?.command_name).toEqual('Off');
expect(setPosition?.args?.cluster_id).toEqual(258);
expect(setPosition?.args?.payload).toEqual({ liftPercent100thsValue: 5800 });
});
export default tap.start();