import { expect, tap } from '@git.zone/tstest/tapbundle'; import { EsphomeMapper } from '../../ts/integrations/esphome/index.js'; const snapshot = EsphomeMapper.toSnapshot({ host: 'living-room-node.local', deviceInfo: { name: 'living_room_node', friendlyName: 'Living Room Node', macAddress: 'AA:BB:CC:DD:EE:FF', manufacturer: 'Espressif', model: 'ESP32', esphomeVersion: '2026.4.4', }, entities: [ { platform: 'light', key: 1, name: 'Lamp', objectId: 'lamp' }, { platform: 'switch', key: 2, name: 'Relay', objectId: 'relay' }, { platform: 'sensor', key: 3, name: 'Temperature', objectId: 'temperature', unitOfMeasurement: 'C', deviceClass: 'temperature' }, { platform: 'binary_sensor', key: 4, name: 'Motion', objectId: 'motion', deviceClass: 'motion' }, { platform: 'fan', key: 5, name: 'Fan', objectId: 'fan' }, { platform: 'cover', key: 6, name: 'Blind', objectId: 'blind', supportsPosition: true }, { platform: 'climate', key: 7, name: 'Thermostat', objectId: 'thermostat' }, { platform: 'button', key: 8, name: 'Restart', objectId: 'restart' }, { platform: 'number', key: 9, name: 'Target humidity', objectId: 'target_humidity', minValue: 0, maxValue: 100, step: 1 }, { platform: 'select', key: 10, name: 'Mode', objectId: 'mode', options: ['Auto', 'Manual'] }, ], states: [ { platform: 'light', key: 1, state: true, brightness: 0.5 }, { platform: 'switch', key: 2, state: false }, { platform: 'sensor', key: 3, state: 21.25 }, { platform: 'binary_sensor', key: 4, state: true }, { platform: 'fan', key: 5, state: true, percentage: 66 }, { platform: 'cover', key: 6, position: 0.42 }, { platform: 'climate', key: 7, mode: 'heat', current_temperature: 20.5, target_temperature: 22 }, { platform: 'number', key: 9, state: 45 }, { platform: 'select', key: 10, state: 'Auto' }, ], }); tap.test('maps ESPHome snapshot devices and entities', async () => { const devices = EsphomeMapper.toDevices(snapshot); const entities = EsphomeMapper.toEntities(snapshot); expect(devices.some((deviceArg) => deviceArg.id === 'esphome.device.aabbccddeeff')).toBeTrue(); expect(entities.some((entityArg) => entityArg.platform === 'light' && entityArg.state === 'on')).toBeTrue(); expect(entities.some((entityArg) => entityArg.platform === 'switch' && entityArg.state === 'off')).toBeTrue(); expect(entities.some((entityArg) => entityArg.platform === 'sensor' && entityArg.state === 21.25)).toBeTrue(); expect(entities.some((entityArg) => entityArg.platform === 'cover' && entityArg.state === 42)).toBeTrue(); expect(entities.some((entityArg) => entityArg.platform === 'select' && entityArg.state === 'Auto')).toBeTrue(); }); tap.test('maps entity services to safe ESPHome command shapes', async () => { const deviceId = EsphomeMapper.toEntities(snapshot).find((entityArg) => entityArg.platform === 'number')?.deviceId; const numberCommand = EsphomeMapper.commandForService(snapshot, { domain: 'number', service: 'set_value', target: { entityId: 'number.living_room_node_target_humidity' }, data: { value: 55 }, }); const coverCommand = EsphomeMapper.commandForService(snapshot, { domain: 'cover', service: 'set_position', target: { entityId: 'cover.living_room_node_blind' }, data: { position: 70 }, }); const selectCommand = EsphomeMapper.commandForService(snapshot, { domain: 'select', service: 'select_option', target: { entityId: 'select.living_room_node_mode' }, data: { option: 'Manual' }, }); expect(numberCommand?.payload.value).toEqual(55); expect(coverCommand?.payload.position).toEqual(0.7); expect(selectCommand?.payload.option).toEqual('Manual'); if (!deviceId) { throw new Error('Expected mapped number entity device id'); } const deviceTargetNumberCommand = EsphomeMapper.commandForService(snapshot, { domain: 'number', service: 'set_value', target: { deviceId }, data: { value: 60 }, }); expect(deviceTargetNumberCommand?.platform).toEqual('number'); expect(deviceTargetNumberCommand?.payload.value).toEqual(60); }); tap.test('uses manual entry data for snapshots', async () => { const manualSnapshot = EsphomeMapper.toSnapshot({ manualEntries: [{ host: 'manual-node.local', port: 6053, name: 'Manual Node', deviceName: 'manual_node', manufacturer: 'ESPHome', model: 'ESP32-S3', encryptionKey: 'base64-key', }], }); expect(manualSnapshot.host).toEqual('manual-node.local'); expect(manualSnapshot.deviceInfo.name).toEqual('manual_node'); expect(manualSnapshot.deviceInfo.friendlyName).toEqual('Manual Node'); expect(manualSnapshot.deviceInfo.apiEncryptionSupported).toBeTrue(); }); export default tap.start();