import { expect, tap } from '@git.zone/tstest/tapbundle'; import { DsmrClient, DsmrMapper, DsmrTelegramParser, type IDsmrConfig } from '../../ts/integrations/dsmr/index.js'; const sampleTelegram = `/ISk5\\2MT382-1000 1-3:0.2.8(50) 0-0:1.0.0(240101120000W) 0-0:96.1.1(453030333630303337383931323334) 1-0:1.8.1(00123.456*kWh) 1-0:1.8.2(00234.567*kWh) 1-0:2.8.1(00012.345*kWh) 1-0:2.8.2(00023.456*kWh) 0-0:96.14.0(0002) 1-0:1.7.0(01.193*kW) 1-0:2.7.0(00.000*kW) 1-0:21.7.0(00.378*kW) 1-0:41.7.0(00.400*kW) 1-0:61.7.0(00.415*kW) 0-1:24.1.0(003) 0-1:96.1.0(473030333930303137) 0-1:24.2.1(240101110000W)(00024.123*m3) !ABCD`; tap.test('parses DSMR telegrams and maps energy gas and power sensors', async () => { const snapshot = DsmrTelegramParser.parseTelegram(sampleTelegram, { config: { dsmrVersion: '5', connectionType: 'serial', serialPort: '/dev/ttyUSB0' } }); const entities = DsmrMapper.toEntities(snapshot); const devices = DsmrMapper.toDevices(snapshot); expect(snapshot.connected).toBeTrue(); expect(snapshot.telegram?.objects.some((objectArg) => objectArg.obisCode === '1-0:1.7.0')).toBeTrue(); expect(snapshot.sensors.find((sensorArg) => sensorArg.key === 'current_electricity_usage')?.value).toEqual(1.193); expect(snapshot.sensors.find((sensorArg) => sensorArg.key === 'electricity_used_tariff_1')?.value).toEqual(123.456); expect(snapshot.sensors.find((sensorArg) => sensorArg.key === 'electricity_active_tariff')?.value).toEqual('normal'); expect(snapshot.sensors.find((sensorArg) => sensorArg.key === 'hourly_gas_meter_reading')?.value).toEqual(24.123); expect(entities.find((entityArg) => entityArg.attributes?.key === 'current_electricity_usage')?.attributes?.unitOfMeasurement).toEqual('kW'); expect(entities.find((entityArg) => entityArg.attributes?.key === 'hourly_gas_meter_reading')?.deviceId).toContain('dsmr.gas'); expect(devices.some((deviceArg) => deviceArg.id.startsWith('dsmr.electricity.'))).toBeTrue(); expect(devices.some((deviceArg) => deviceArg.id.startsWith('dsmr.gas.'))).toBeTrue(); }); tap.test('maps status snapshots without raw telegrams', async () => { const config: IDsmrConfig = { id: 'meter-status', dsmrVersion: '5', status: { meter: { serialId: 'E123', serialIdGas: 'G123' }, values: { current_electricity_usage: { value: 0.456, unit: 'kW' }, electricity_used_tariff_1: { value: 12.3, unit: 'kWh' }, hourly_gas_meter_reading: { value: 4.2, unit: 'm3' }, }, }, }; const snapshot = await new DsmrClient(config).getSnapshot(); const entities = DsmrMapper.toEntities(snapshot); expect(snapshot.source).toEqual('status'); expect(entities.find((entityArg) => entityArg.attributes?.key === 'current_electricity_usage')?.state).toEqual(0.456); expect(entities.find((entityArg) => entityArg.attributes?.key === 'electricity_used_tariff_1')?.attributes?.stateClass).toEqual('total_increasing'); expect(entities.find((entityArg) => entityArg.attributes?.key === 'hourly_gas_meter_reading')?.state).toEqual(4.2); }); tap.test('does not fake live serial refresh success without a telegram source', async () => { const client = new DsmrClient({ connectionType: 'serial', serialPort: '/dev/ttyUSB0', port: '/dev/ttyUSB0', dsmrVersion: '5' }); const snapshot = await client.getSnapshot(); const result = await client.refresh(); expect(snapshot.connected).toBeFalse(); expect(snapshot.sensors.length).toEqual(0); expect(result.success).toBeFalse(); expect(result.error).toContain('telegramProvider'); }); export default tap.start();