/** * Edilkamin BLE Protocol Implementation * * Transport-agnostic protocol layer for communicating with Edilkamin stoves via BLE. * Handles AES-128-CBC encryption, CRC16-Modbus checksums, and Modbus packet building/parsing. * * The consuming application is responsible for: * - BLE device scanning and connection * - Writing to BLE characteristics * - Subscribing to BLE notifications * * Protocol details derived from: https://github.com/netmb/Edilkamin_BT */ /** Edilkamin GATT service UUID */ export declare const SERVICE_UUID = "0000abf0-0000-1000-8000-00805f9b34fb"; /** Write characteristic UUID (WRITE NO RESPONSE) */ export declare const WRITE_CHARACTERISTIC_UUID = "0000abf1-0000-1000-8000-00805f9b34fb"; /** Notify characteristic UUID (NOTIFY) */ export declare const NOTIFY_CHARACTERISTIC_UUID = "0000abf2-0000-1000-8000-00805f9b34fb"; /** * Parsed Modbus response from the device. */ export interface ModbusResponse { /** Slave address (always 0x01 for Edilkamin) */ slaveAddress: number; /** Function code (0x03 for read, 0x06 for write) */ functionCode: number; /** Byte count (for read responses) */ byteCount?: number; /** Response data */ data: Uint8Array; /** Whether the response indicates an error */ isError: boolean; } /** * Operation-tagged BLE response payload emitted by consuming apps. */ export interface OperationTaggedPayload { /** Operation name associated with this response payload */ operation: string; /** Encrypted BLE response payload bytes */ payload: Uint8Array; } /** * Parsed response bound to its originating operation. */ export interface OperationTaggedResponse { /** Operation name associated with this response payload */ operation: string; /** Parsed response data */ response: TResponse; } /** * readWifiStatus operation parse result. */ export interface ReadWifiStatusResponse { /** Operation name for this specialization */ operation: "readWifiStatus"; /** Whether Wi-Fi status is connected */ isConnected: boolean; } /** * Calculate CRC16-Modbus checksum. * * @param data - Data to calculate CRC for * @returns 2-byte CRC in little-endian order [crcLo, crcHi] */ export declare const crc16Modbus: (data: Uint8Array) => Uint8Array; /** * Encrypt data using AES-128-CBC (raw, without PKCS7 padding). * * This manually applies PKCS7 padding to make input a multiple of 16 bytes, * encrypts with Web Crypto, then strips the extra padding block from output. * * @param plaintext - Data to encrypt (must be 32 bytes) * @returns Encrypted data (32 bytes) */ export declare const aesEncrypt: (plaintext: Uint8Array) => Promise; /** * Decrypt data using AES-128-CBC (raw, handling PKCS7 padding). * * @param ciphertext - Data to decrypt (must be 32 bytes) * @returns Decrypted data (32 bytes) */ export declare const aesDecrypt: (ciphertext: Uint8Array) => Promise; /** * Build and encrypt a command packet to send to the device. * * Packet structure (32 bytes before encryption): * - Bytes 0-3: Unix timestamp (big-endian) * - Bytes 4-19: Fixed key * - Bytes 20-25: Modbus command (6 bytes) * - Bytes 26-27: CRC16-Modbus of command * - Bytes 28-31: Padding [0x04, 0x04, 0x04, 0x04] * * @param modbusCommand - 6-byte Modbus RTU command * @returns 32-byte encrypted packet ready to send via BLE */ export declare const createPacket: (modbusCommand: Uint8Array) => Promise; /** * Decrypt and parse a response packet from the device. * * Response structure (32 bytes before decryption): * - Bytes 0-3: Unix timestamp * - Bytes 4-19: Fixed key * - Bytes 20-26: Modbus response (7 bytes) * - Bytes 27-28: CRC16-Modbus * - Bytes 29-31: Padding [0x03, 0x03, 0x03] * * @param encrypted - 32-byte encrypted response from BLE notification * @returns Parsed Modbus response */ export declare const parseResponse: (encrypted: Uint8Array) => Promise; /** * Normalize and validate an operation-tagged BLE payload. * * @param taggedPayload - Operation name and encrypted payload bytes * @returns Normalized operation-tagged payload */ export declare const normalizeOperationTaggedPayload: (taggedPayload: OperationTaggedPayload) => OperationTaggedPayload; /** * Parse an operation-tagged BLE payload with a caller-provided parser. * * @param taggedPayload - Operation name and encrypted payload bytes * @param parser - Parser to apply on payload bytes * @returns Operation-tagged parsed response */ export declare const parseOperationTaggedResponse: (taggedPayload: OperationTaggedPayload, parser: (payload: Uint8Array) => TResponse | Promise) => Promise>; /** * Parse an operation-tagged BLE payload as a Modbus response. * * @param taggedPayload - Operation name and encrypted payload bytes * @returns Operation-tagged parsed Modbus response */ export declare const parseModbusOperationResponse: (taggedPayload: OperationTaggedPayload) => Promise>; /** * Parse decrypted payload bytes for readWifiStatus connectivity. * * Decrypted packets keep protocol metadata in bytes 0-19, so this parser checks * string payload from byte 20 onward. * * @param decryptedPayload - Decrypted response payload bytes * @returns true when payload contains STATUS=CONNECTED */ export declare const parseReadWifiStatusPayload: (decryptedPayload: Uint8Array) => boolean; /** * Parse operation-tagged readWifiStatus payloads. * * For protocol packets, 32-byte payloads are decrypted first, then parsed with * readWifiStatus payload conventions. * * @param taggedPayload - Operation name and payload bytes * @returns readWifiStatus operation parse result */ export declare const parseReadWifiStatusResponse: (taggedPayload: OperationTaggedPayload) => Promise; /** * Pre-built Modbus read commands for querying device state. * Each command is 6 bytes: [SlaveAddr, FuncCode, RegHi, RegLo, CountHi, CountLo] */ export declare const readCommands: { /** Power state (0=off, 1=on) */ power: Uint8Array; /** Current ambient temperature (value / 10 = °C) */ temperature: Uint8Array; /** Target temperature (value / 10 = °C) */ targetTemperature: Uint8Array; /** Power level (1-5) - register 0x0529 contains [fan1_speed, power_level] */ powerLevel: Uint8Array; /** Fan 1 speed (0=auto, 1-5=speed) */ fan1Speed: Uint8Array; /** Fan 2 speed (0=auto, 1-5=speed) */ fan2Speed: Uint8Array; /** Device state code */ state: Uint8Array; /** Alarm status code */ alarm: Uint8Array; /** Pellet warning status */ pelletAlarm: Uint8Array; /** Auto mode (0=manual, 1=auto) */ autoMode: Uint8Array; /** Standby mode status */ standby: Uint8Array; }; /** * Builder functions for Modbus write commands. * Each function returns a 6-byte command: [SlaveAddr, FuncCode, RegHi, RegLo, ValHi, ValLo] */ export declare const writeCommands: { /** * Turn power on or off. * @param on - true to turn on, false to turn off */ setPower: (on: boolean) => Uint8Array; /** * Set target temperature. * @param tempCelsius - Temperature in Celsius (e.g., 21.5) */ setTemperature: (tempCelsius: number) => Uint8Array; /** * Set power level. * @param level - Power level (1-5) */ setPowerLevel: (level: number) => Uint8Array; /** * Set fan 1 speed. * @param speed - Fan speed (0=auto, 1-5=manual speed) */ setFan1Speed: (speed: number) => Uint8Array; /** * Set fan 2 speed. * @param speed - Fan speed (0=auto, 1-5=manual speed) */ setFan2Speed: (speed: number) => Uint8Array; /** * Enable or disable auto mode. * @param enabled - true to enable auto mode */ setAutoMode: (enabled: boolean) => Uint8Array; /** * Enable or disable standby mode. * @param enabled - true to enable standby mode */ setStandby: (enabled: boolean) => Uint8Array; }; /** * Parser functions to extract meaningful values from Modbus responses. */ export declare const parsers: { /** * Parse boolean response (power state, auto mode, etc.). * @param response - Parsed Modbus response * @returns true if value is 0x01, false if 0x00 */ boolean: (response: ModbusResponse) => boolean; /** * Parse temperature response. * @param response - Parsed Modbus response * @returns Temperature in Celsius */ temperature: (response: ModbusResponse) => number; /** * Parse numeric value (power level, fan speed, state code, etc.). * @param response - Parsed Modbus response * @returns Numeric value */ number: (response: ModbusResponse) => number; /** * Parse power level from combined fan+power register. * Register 0x0529 contains: [fan1_speed, power_level] * Extracts only the low byte and validates range 1-5. * @param response - Parsed Modbus response * @returns Power level (1-5) */ powerLevel: (response: ModbusResponse) => number; };