Add native hub protocol integrations
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
import { expect, tap } from '@git.zone/tstest/tapbundle';
|
||||
import { createWizDiscoveryDescriptor } from '../../ts/integrations/wiz/index.js';
|
||||
|
||||
tap.test('matches WiZ mDNS, UDP, and manual discovery records', async () => {
|
||||
const descriptor = createWizDiscoveryDescriptor();
|
||||
const mdnsMatcher = descriptor.getMatchers()[0];
|
||||
const udpMatcher = descriptor.getMatchers()[1];
|
||||
const manualMatcher = descriptor.getMatchers()[2];
|
||||
|
||||
const mdnsResult = await mdnsMatcher.matches({
|
||||
type: '_http._tcp.local.',
|
||||
name: 'wiz_a8bb50a4f94d._http._tcp.local.',
|
||||
host: 'wiz-a4f94d.local',
|
||||
txt: {
|
||||
mac: 'a8bb50a4f94d',
|
||||
name: 'Desk Lamp',
|
||||
},
|
||||
}, {});
|
||||
const udpResult = await udpMatcher.matches({
|
||||
host: '192.168.1.51',
|
||||
response: {
|
||||
method: 'registration',
|
||||
result: {
|
||||
mac: 'a8bb50a4f94d',
|
||||
},
|
||||
},
|
||||
}, {});
|
||||
const manualResult = await manualMatcher.matches({
|
||||
host: '192.168.1.52',
|
||||
name: 'Counter Plug',
|
||||
deviceInfo: {
|
||||
model: 'WiZ Smart Plug',
|
||||
},
|
||||
}, {});
|
||||
|
||||
expect(mdnsResult.matched).toBeTrue();
|
||||
expect(mdnsResult.normalizedDeviceId).toEqual('a8:bb:50:a4:f9:4d');
|
||||
expect(udpResult.matched).toBeTrue();
|
||||
expect(udpResult.candidate?.metadata?.discoveryProtocol).toEqual('udp');
|
||||
expect(manualResult.matched).toBeTrue();
|
||||
expect(manualResult.candidate?.port).toEqual(38899);
|
||||
});
|
||||
|
||||
tap.test('validates WiZ candidates from DHCP-style metadata', async () => {
|
||||
const validator = createWizDiscoveryDescriptor().getValidators()[0];
|
||||
const result = await validator.validate({
|
||||
source: 'dhcp',
|
||||
host: 'wiz_a4f94d',
|
||||
macAddress: 'A8:BB:50:A4:F9:4D',
|
||||
port: 38899,
|
||||
}, {});
|
||||
expect(result.matched).toBeTrue();
|
||||
expect(result.confidence).toEqual('certain');
|
||||
});
|
||||
|
||||
export default tap.start();
|
||||
@@ -0,0 +1,83 @@
|
||||
import { expect, tap } from '@git.zone/tstest/tapbundle';
|
||||
import { WizMapper, type IWizSnapshot } from '../../ts/integrations/wiz/index.js';
|
||||
|
||||
const snapshot: IWizSnapshot = {
|
||||
connected: true,
|
||||
devices: [
|
||||
{
|
||||
host: '192.168.1.51',
|
||||
port: 38899,
|
||||
mac: 'a8bb50a4f94d',
|
||||
name: 'Desk Lamp',
|
||||
available: true,
|
||||
deviceInfo: {
|
||||
manufacturer: 'WiZ',
|
||||
model: 'RGBW Tunable',
|
||||
moduleName: 'ESP03_SHRGB1C_31',
|
||||
fwVersion: '1.33.0',
|
||||
features: {
|
||||
effect: true,
|
||||
power: true,
|
||||
occupancy: true,
|
||||
},
|
||||
},
|
||||
pilot: {
|
||||
mac: 'a8bb50a4f94d',
|
||||
rssi: -57,
|
||||
state: true,
|
||||
sceneId: 4,
|
||||
temp: 3000,
|
||||
dimming: 80,
|
||||
r: 255,
|
||||
g: 100,
|
||||
b: 0,
|
||||
pc: 12345,
|
||||
speed: 100,
|
||||
src: 'wfa1',
|
||||
},
|
||||
},
|
||||
],
|
||||
events: [],
|
||||
};
|
||||
|
||||
tap.test('maps WiZ lights, sensors, buttons, numbers, and selects', async () => {
|
||||
const devices = WizMapper.toDevices(snapshot);
|
||||
const entities = WizMapper.toEntities(snapshot);
|
||||
|
||||
expect(devices[0].id).toEqual('wiz.device.a8_bb_50_a4_f9_4d');
|
||||
expect(devices[0].features.some((featureArg) => featureArg.capability === 'light')).toBeTrue();
|
||||
expect(devices[0].features.some((featureArg) => featureArg.id === 'power')).toBeTrue();
|
||||
expect(entities.find((entityArg) => entityArg.id === 'light.desk_lamp')?.state).toEqual('on');
|
||||
expect(entities.find((entityArg) => entityArg.id === 'sensor.desk_lamp_power')?.state).toEqual(12.345);
|
||||
expect(entities.find((entityArg) => entityArg.id === 'button.desk_lamp_button_on')?.state).toEqual('wfa1');
|
||||
expect(entities.find((entityArg) => entityArg.id === 'select.desk_lamp_effect')?.state).toEqual('Party');
|
||||
expect(entities.find((entityArg) => entityArg.id === 'number.desk_lamp_effect_speed')?.state).toEqual(100);
|
||||
});
|
||||
|
||||
tap.test('maps canonical services to WiZ setPilot payloads', async () => {
|
||||
const turnOnCommand = WizMapper.commandForService(snapshot, {
|
||||
domain: 'light',
|
||||
service: 'turn_on',
|
||||
target: { entityId: 'light.desk_lamp' },
|
||||
data: { brightness_pct: 50, effect: 'Ocean' },
|
||||
});
|
||||
const selectCommand = WizMapper.commandForService(snapshot, {
|
||||
domain: 'select',
|
||||
service: 'select_option',
|
||||
target: { entityId: 'select.desk_lamp_effect' },
|
||||
data: { option: 'Party' },
|
||||
});
|
||||
const numberCommand = WizMapper.commandForService(snapshot, {
|
||||
domain: 'number',
|
||||
service: 'set_value',
|
||||
target: { entityId: 'number.desk_lamp_effect_speed' },
|
||||
data: { value: 120 },
|
||||
});
|
||||
|
||||
expect(turnOnCommand?.payload.dimming).toEqual(50);
|
||||
expect(turnOnCommand?.payload.sceneId).toEqual(1);
|
||||
expect(selectCommand?.payload.sceneId).toEqual(4);
|
||||
expect(numberCommand?.payload.speed).toEqual(120);
|
||||
});
|
||||
|
||||
export default tap.start();
|
||||
Reference in New Issue
Block a user