/** * GigLez Pattern Decoder - Main Entry Point * JavaScript RF Signal Decoder for Sub-GHz Devices * * Export all decoder modules for browser and Node.js usage * * @module giglez-decoder * @version 1.0.0 */ // ============================================================================ // Protocol Database // ============================================================================ export { ProtocolSignature, ProtocolDatabase, WEATHER_SENSORS, GARAGE_DOOR_OPENERS, DOORBELLS, TIRE_PRESSURE, SECURITY_SENSORS, REMOTE_CONTROLS, ALL_PROTOCOLS, protocolDb } from './protocol-database.js'; // ============================================================================ // Pulse Analysis // ============================================================================ export { kMeans, identifyPulseWidths, decodeToBits, analyzePulseTrain, validatePulseData, estimateSNR } from './pulse-analyzer.js'; // ============================================================================ // Statistical Fingerprinting // ============================================================================ export { PulseFingerprint, extractFingerprint, calculateSimilarity, compareToProtocol, classifySignal, generateReport } from './fingerprint.js'; // ============================================================================ // Pattern Decoder (Main) // ============================================================================ export { DeviceMatch, PatternDecoder, decode } from './pattern-decoder.js'; // ============================================================================ // Convenience API // ============================================================================ /** * Quick decode function - analyze .sub file and return device matches * * @param {Object} metadata - Parsed .sub file metadata * @param {number} metadata.frequency - Frequency in Hz * @param {string} metadata.preset - Modulation preset * @param {string} metadata.protocol - Protocol name * @param {number[]} metadata.raw_data - Pulse timing array * @param {Object} options - Decoder options * @param {number} options.minConfidence - Minimum confidence threshold (default: 0.4) * @param {number} options.maxResults - Maximum results to return (default: 10) * @param {boolean} options.debug - Enable debug logging (default: false) * @returns {Promise} Array of DeviceMatch objects * * @example * import { quickDecode } from './decoder/index.js'; * * const metadata = { * frequency: 433920000, * preset: 'FuriHalSubGhzPresetOok270Async', * protocol: 'RAW', * raw_data: [2980, -240, 520, -980, 520, -980, ...] * }; * * const matches = await quickDecode(metadata, { debug: true }); * console.log(matches[0].toString()); */ export async function quickDecode(metadata, options = {}) { const { PatternDecoder } = await import('./pattern-decoder.js'); const decoder = new PatternDecoder(options); return decoder.decode(metadata); } /** * Parse Flipper Zero .sub file format * * @param {string} content - Raw .sub file content * @returns {Object} Parsed metadata * * @example * const content = await fetch('capture.sub').then(r => r.text()); * const metadata = parseSubFile(content); * const matches = await quickDecode(metadata); */ export function parseSubFile(content) { const lines = content.split('\n'); const metadata = { filetype: null, version: null, frequency: null, preset: null, protocol: null, bit: null, key: null, te: null, raw_data: [] }; for (const line of lines) { const trimmed = line.trim(); if (!trimmed || trimmed.startsWith('#')) continue; if (trimmed.includes(':')) { const [key, value] = trimmed.split(':', 2).map(s => s.trim()); switch (key) { case 'Filetype': metadata.filetype = value; break; case 'Version': metadata.version = parseInt(value); break; case 'Frequency': metadata.frequency = parseInt(value); break; case 'Preset': metadata.preset = value; break; case 'Protocol': metadata.protocol = value; break; case 'Bit': metadata.bit = parseInt(value); break; case 'Key': metadata.key = value; break; case 'TE': metadata.te = parseInt(value); break; case 'RAW_Data': // Parse pulse timing array const pulses = value.split(/\s+/) .map(s => parseInt(s)) .filter(n => !isNaN(n)); metadata.raw_data.push(...pulses); break; } } } return metadata; } /** * Decode .sub file from URL * * @param {string} url - URL to .sub file * @param {Object} options - Decoder options * @returns {Promise} Device matches * * @example * const matches = await decodeFromURL('https://example.com/capture.sub'); * console.log(`Found ${matches.length} potential devices`); */ export async function decodeFromURL(url, options = {}) { const response = await fetch(url); const content = await response.text(); const metadata = parseSubFile(content); return quickDecode(metadata, options); } /** * Decode .sub file from File object (browser) * * @param {File} file - File object from file input * @param {Object} options - Decoder options * @returns {Promise} Device matches * * @example * document.getElementById('fileInput').addEventListener('change', async (e) => { * const file = e.target.files[0]; * const matches = await decodeFromFile(file, { debug: true }); * console.log(matches); * }); */ export async function decodeFromFile(file, options = {}) { const content = await file.text(); const metadata = parseSubFile(content); return quickDecode(metadata, options); } /** * Get decoder version information * @returns {Object} Version info */ export async function getVersion() { const { ALL_PROTOCOLS } = await import('./protocol-database.js'); return { version: '1.0.0', name: 'GigLez Pattern Decoder', description: 'JavaScript RF Signal Decoder for Sub-GHz Devices', protocols: ALL_PROTOCOLS.length, features: [ 'K-means pulse width clustering', 'Statistical fingerprinting', 'Protocol library matching', '18 built-in protocols', 'Single-transmission decoding', 'Browser and Node.js compatible' ] }; }