51 lines
2.4 KiB
TypeScript
51 lines
2.4 KiB
TypeScript
import { createServer } from 'node:net';
|
|
import { expect, tap } from '@git.zone/tstest/tapbundle';
|
|
import { KwbClient, KwbIntegration, type IKwbSnapshot } from '../../ts/integrations/kwb/index.js';
|
|
|
|
tap.test('reads KWB Easyfire TCP byte-stream packets into sensor snapshots', async () => {
|
|
const payload = Buffer.concat([sensePacket([21.5, 20.1, 64.4, 250.2, 48, 47.5, -3.2, 120.5, 12.3, 0, 0, 0, 55.5]), controlPacket()]);
|
|
const server = createServer((socketArg) => socketArg.end(payload));
|
|
await new Promise<void>((resolve) => server.listen(0, '127.0.0.1', resolve));
|
|
|
|
try {
|
|
const address = server.address();
|
|
const port = typeof address === 'object' && address ? address.port : 0;
|
|
const client = new KwbClient({ host: '127.0.0.1', port, timeoutMs: 1000 });
|
|
const snapshot = await client.getSnapshot(true);
|
|
|
|
expect(snapshot.online).toBeTrue();
|
|
expect(snapshot.source).toEqual('tcp');
|
|
expect(snapshot.entities.find((entityArg) => entityArg.id === 'supply')?.state).toEqual(21.5);
|
|
expect(snapshot.entities.find((entityArg) => entityArg.id === 'return_mixer')?.state).toEqual(1);
|
|
|
|
const runtime = await new KwbIntegration().setup({ host: '127.0.0.1', port, timeoutMs: 1000 }, {});
|
|
const status = await runtime.callService!({ domain: 'kwb', service: 'status', target: {} });
|
|
expect(status.success).toBeTrue();
|
|
expect((status.data as IKwbSnapshot).entities.find((entityArg) => entityArg.id === 'furnace')?.state).toEqual(250.2);
|
|
await runtime.destroy();
|
|
} finally {
|
|
await new Promise<void>((resolve, reject) => server.close((errorArg) => errorArg ? reject(errorArg) : resolve()));
|
|
}
|
|
});
|
|
|
|
const sensePacket = (temperaturesArg: number[]): Buffer => {
|
|
const tempBytes = Buffer.concat(temperaturesArg.map((valueArg) => {
|
|
const encoded = Math.round(valueArg * 10);
|
|
const buffer = Buffer.alloc(2);
|
|
buffer.writeInt16BE(encoded, 0);
|
|
return buffer;
|
|
}));
|
|
const unescapedData = Buffer.concat([Buffer.alloc(4), tempBytes, Buffer.alloc(6)]);
|
|
const packet = Buffer.concat([Buffer.from([0]), unescapedData]);
|
|
return Buffer.concat([Buffer.from([2, 2, packet.length, 1, 1]), packet, Buffer.from([0])]);
|
|
};
|
|
|
|
const controlPacket = (): Buffer => {
|
|
const packet = Buffer.alloc(16);
|
|
packet[2] = 0b00000010;
|
|
packet[3] = 0b00000010;
|
|
return Buffer.concat([Buffer.from([2, 1, 1, 1]), packet, Buffer.from([0])]);
|
|
};
|
|
|
|
export default tap.start();
|