/** * Connaissances métier pour la recherche intelligente en français. * * Sans dépendances ni alias d'importation : s'exécute côté serveur (construction de l'index), * dans le navigateur (interprétation de la requête) et dans les scripts de test Node. * * Tous les termes de `termos` sont déjà normalisés (minuscules, sans accents). */ export const normalizar = (s = "") => String(s) .toLowerCase() .replace(/œ/g, "oe") .replace(/æ/g, "ae") .replace(/['’]/g, "'") .normalize("NFD") .replace(/[\u0300-\u036f]/g, ""); /** * Reconnaît les broches occupées par la flash/PSRAM selon la description du schéma. * "forte": la broche est consommée par la mémoire (ou constitue son alimentation). * "fraco": seulement affectée dans certains modes (ex. : SPI octal 8 lignes). */ const nivelMemoria = (palavra) => (p) => { const citam = p._avs.filter((a) => new RegExp(`\\b${palavra}(?![a-z])`).test(a) && !/^pour les puces (avec|sans)/i.test(a)); if (citam.some((a) => /(utilise|dedie|connecte)/i.test(a) && !/sauf si/i.test(a))) return "forte"; if (p._fn.some((f) => /alimentation/i.test(f) && f.includes(palavra))) return "forte"; if (citam.length) return "fraco"; return null; }; /** * Sujets qu'un utilisateur peut consulter en français. */ export const TOPICOS = [ { id: "flash", nome: "Flash", termos: ["flash", "memoire flash", "spi flash", "stockage", "firmware", "rom externe"], pinoNivel: nivelMemoria("flash"), pinoRotulo: "reliées à la mémoire flash" }, { id: "psram", nome: "PSRAM", termos: ["psram", "ram externe", "spiram"], pinoNivel: nivelMemoria("psram"), pinoRotulo: "reliées à la PSRAM" }, { id: "memoria", nome: "Mémoire", termos: ["memoire", "sram", "heap", "rtc ram", "ko de ram", "memoire interne", "ram", "memory"], pinoRotulo: "" }, { id: "wifi", nome: "Wi-Fi", termos: ["wifi", "wi-fi", "sans fil", "wireless", "802.11", "wifi6", "wifi 6", "wi-fi 6"], pinoCats: ["Antenne"], pinoRotulo: "d'antenne et radio" }, { id: "bluetooth", nome: "Bluetooth", termos: ["bluetooth", "ble", "bt", "bluetooth le", "mesh"], pinoCats: ["Antenne"], pinoRotulo: "d'antenne et radio" }, { id: "zigbee", nome: "Zigbee/Thread", termos: ["zigbee", "thread", "802.15.4", "ieee 802.15.4"], pinoRotulo: "" }, { id: "matter", nome: "Matter", termos: ["matter", "maison intelligente", "smart home", "domotique"], pinoRotulo: "" }, { id: "ethernet", nome: "Ethernet", termos: ["ethernet", "rmii", "cable reseau", "lan"], pinoCats: ["Ethernet"], pinoRotulo: "d'Ethernet" }, { id: "can", nome: "CAN / TWAI", termos: ["can", "twai", "can bus", "canbus", "can fd"], pinoRe: /twai|\bcan\b/, pinoRotulo: "de CAN/TWAI" }, { id: "usb", nome: "USB", termos: ["usb", "otg", "usb serie", "usb serial", "usb otg", "hid", "cdc"], pinoCats: ["USB"], pinoRotulo: "d'USB" }, { id: "jtag", nome: "JTAG / Débogage", termos: ["jtag", "debug", "debogage", "deboguer", "openocd", "gdb"], pinoCats: ["JTAG"], pinoRotulo: "de JTAG" }, { id: "adc", nome: "ADC", termos: ["adc", "analogique", "entree analogique", "convertisseur analogique", "analogread", "saradc"], pinoCats: ["ADC"], pinoRotulo: "avec ADC" }, { id: "dac", nome: "DAC", termos: ["dac", "sortie analogique", "convertisseur numerique"], pinoCats: ["DAC"], pinoRotulo: "avec DAC" }, { id: "touch", nome: "Tactile capacitif", termos: ["touch", "capacitif", "tactile", "touchpad", "capteur tactile"], pinoCats: ["Touch"], pinoRotulo: "tactiles capacitives" }, { id: "uart", nome: "UART", termos: ["uart", "serie", "serial", "tx", "rx", "txd", "rxd", "port serie"], pinoCats: ["UART"], pinoRotulo: "d'UART" }, { id: "spi", nome: "SPI", termos: ["spi", "mosi", "miso", "sclk", "bus spi"], pinoCats: ["SPI"], pinoRotulo: "de SPI" }, { id: "i2c", nome: "I2C", termos: ["i2c", "sda", "scl", "twi", "iic"], pinoCats: ["I2C"], pinoRotulo: "d'I2C" }, { id: "i2s", nome: "I2S", termos: ["i2s", "audio", "son", "microphone", "pdm", "codec"], pinoRe: /i2s|\bpdm\b/, pinoRotulo: "d'I2S / audio" }, { id: "pwm", nome: "PWM", termos: ["pwm", "ledc", "mcpwm", "servo", "variateur"], pinoRe: /ledc|pwm/, pinoRotulo: "de PWM" }, { id: "sd", nome: "Carte SD / SDIO", termos: ["sd", "sdio", "carte sd", "sd card", "microsd", "sdmmc", "mmc"], pinoCats: ["SD"], pinoRe: /sdio|sdmmc|\bsd\b/, pinoRotulo: "de carte SD/SDIO" }, { id: "camera", nome: "Caméra", termos: ["camera", "cam", "dvp", "csi", "mipi csi", "ov2640", "video"], pinoCats: ["CSI"], pinoRe: /\bcam\b|dvp|cam_/, pinoRotulo: "de caméra" }, { id: "lcd", nome: "Écran / LCD", termos: ["lcd", "display", "ecran", "dsi", "mipi dsi", "oled", "tft", "lvgl", "rgb"], pinoCats: ["DSI"], pinoRe: /lcd/, pinoRotulo: "d'écran/LCD" }, { id: "strapping", nome: "Démarrage / Strapping", termos: ["strapping", "boot", "bootstrap", "mode boot", "mode demarrage", "download mode", "demarrage"], pinoCats: ["Strapping"], pinoRotulo: "de strapping (mode de démarrage)" }, { id: "energia_pinos", nome: "Alimentation", termos: ["alimentation", "vdd", "3v3", "3.3v", "tension", "regulateur", "ldo", "source"], pinoCats: ["Power"], pinoRotulo: "d'alimentation" }, { id: "clock", nome: "Horloge / Quartz", termos: ["clock", "horloge", "xtal", "quartz", "oscillateur", "32khz", "40mhz"], pinoCats: ["Clock"], pinoRotulo: "d'horloge/quartz" }, { id: "gpio", nome: "GPIO", termos: ["gpio", "entrees sorties", "broches"], pinoCats: ["GPIO"], pinoRotulo: "de GPIO" }, { id: "baixo_consumo", nome: "Basse consommation / ULP", termos: ["ulp", "lp core", "lp cpu", "coprocesseur", "lp gpio", "low power", "rtc gpio", "basse consommation"], pinoCats: ["Low Power"], pinoRotulo: "basse consommation (LP/RTC)" }, { id: "antena", nome: "Antenne / RF", termos: ["antenne", "rf", "radiofrequence", "ipex"], pinoCats: ["Antenne"], pinoRotulo: "d'antenne/RF" }, { id: "seguranca", nome: "Sécurité", termos: ["securite", "secure boot", "cryptographie", "chiffrement", "aes", "sha", "rsa", "hmac", "ecdsa", "efuse", "tee", "trng", "rng", "hsm", "protection"], pinoRotulo: "" }, { id: "consumo", nome: "Consommation d'énergie", termos: ["consommation", "batterie", "deep sleep", "light sleep", "sleep", "modem sleep", "courant", "milliampere", "autonomie", "economie d energie", "mode veille"], pinoRotulo: "" }, { id: "temperatura", nome: "Température", termos: ["temperature", "chaleur", "degres", "plage de temperature", "industriel"], pinoRotulo: "" }, { id: "ia", nome: "IA / Accélération", termos: ["ia", "ai", "machine learning", "ml", "tinyml", "vectoriel", "intelligence artificielle", "reseau neuronal", "esp-nn", "esp-dl"], pinoRotulo: "" }, { id: "processador", nome: "Processeur", termos: ["processeur", "cpu", "coeur", "coeurs", "core", "dual core", "single core", "architecture", "xtensa", "risc-v", "riscv"], pinoRotulo: "" }, { id: "frequencia", nome: "Fréquence", termos: ["frequence", "mhz", "vitesse", "performance", "rendement"], pinoRotulo: "" }, { id: "ferramentas", nome: "Outils / SDK", termos: ["esp-idf", "idf", "arduino", "sdk", "toolchain", "chaine d outils", "version d idf"], pinoRotulo: "" }, { id: "encapsulamento", nome: "Modules et boîtier", termos: ["module", "modules", "boitier", "encapsulation", "package", "qfn", "wroom", "wrover", "mini-1"], pinoRotulo: "" }, ]; /** * Champs de données techniques en français. */ export const SPEC_CAMPOS = [ { campo: "arquitetura", label: "Architecture", secao: "processador", topicos: ["processador"] }, { campo: "nucleos", label: "Cœurs", secao: "processador", topicos: ["processador"] }, { campo: "frequencia", label: "Fréquence", secao: "processador", topicos: ["frequencia", "processador"] }, { campo: "coprocessador_ulp", label: "Coprocesseur ULP", secao: "processador", topicos: ["baixo_consumo"] }, { campo: "aceleradores_ia", label: "Accélérateurs IA", secao: "processador", topicos: ["ia"] }, { campo: "wifi", label: "Wi-Fi", secao: "conectividade", topicos: ["wifi"] }, { campo: "bluetooth", label: "Bluetooth", secao: "conectividade", topicos: ["bluetooth"] }, { campo: "zigbee_thread", label: "Zigbee/Thread", secao: "conectividade", topicos: ["zigbee"] }, { campo: "matter", label: "Matter", secao: "conectividade", topicos: ["matter"] }, { campo: "ethernet", label: "Ethernet", secao: "conectividade", topicos: ["ethernet"] }, { campo: "ethernet_mac", label: "Ethernet MAC", secao: "conectividade", topicos: ["ethernet"] }, { campo: "can", label: "CAN", secao: "conectividade", topicos: ["can"] }, { campo: "memoria_sram", label: "SRAM", secao: "memoria", topicos: ["memoria"] }, { campo: "memoria_sram_rtc", label: "SRAM RTC", secao: "memoria", topicos: ["memoria", "baixo_consumo"] }, { campo: "memoria_rom", label: "ROM", secao: "memoria", topicos: ["memoria"] }, { campo: "flash_externa", label: "Flash externe", secao: "memoria", topicos: ["flash", "memoria"] }, { campo: "psram_externa", label: "PSRAM externe", secao: "memoria", topicos: ["psram", "memoria"] }, { campo: "gpio", label: "GPIO", secao: "perifericos", topicos: ["gpio"] }, { campo: "adc", label: "ADC", secao: "perifericos", topicos: ["adc"] }, { campo: "dac", label: "DAC", secao: "perifericos", topicos: ["dac"] }, { campo: "touch", label: "Tactile capacitif", secao: "perifericos", topicos: ["touch"] }, { campo: "uart", label: "UART", secao: "perifericos", topicos: ["uart"] }, { campo: "spi", label: "SPI", secao: "perifericos", topicos: ["spi", "flash"] }, { campo: "i2c", label: "I2C", secao: "perifericos", topicos: ["i2c"] }, { campo: "i2s", label: "I2S", secao: "perifericos", topicos: ["i2s"] }, { campo: "pwm", label: "PWM", secao: "perifericos", topicos: ["pwm"] }, { campo: "usb", label: "USB", secao: "perifericos", topicos: ["usb"] }, { campo: "lcd", label: "LCD", secao: "interfaces", topicos: ["lcd"] }, { campo: "camera", label: "Caméra", secao: "interfaces", topicos: ["camera"] }, { campo: "mipi_csi", label: "MIPI CSI", secao: "interfaces", topicos: ["camera"] }, { campo: "mipi_dsi", label: "MIPI DSI", secao: "interfaces", topicos: ["lcd"] }, { campo: "sdio", label: "SDIO", secao: "interfaces", topicos: ["sd"] }, { campo: "sensor_temperatura", label: "Capteur de température", secao: "interfaces", topicos: ["temperatura"] }, { campo: "seguranca.aes", label: "AES", secao: "seguranca", topicos: ["seguranca"] }, { campo: "seguranca.sha", label: "SHA", secao: "seguranca", topicos: ["seguranca"] }, { campo: "seguranca.rsa", label: "RSA", secao: "seguranca", topicos: ["seguranca"] }, { campo: "seguranca.ecc", label: "ECC", secao: "seguranca", topicos: ["seguranca"] }, { campo: "seguranca.ecdsa", label: "ECDSA", secao: "seguranca", topicos: ["seguranca"] }, { campo: "seguranca.hmac", label: "HMAC", secao: "seguranca", topicos: ["seguranca"] }, { campo: "seguranca.assinatura_digital", label: "Signature numérique", secao: "seguranca", topicos: ["seguranca"] }, { campo: "seguranca.rng", label: "Générateur de nombres aléatoires", secao: "seguranca", topicos: ["seguranca"] }, { campo: "seguranca.criptografia_flash", label: "Chiffrement Flash", secao: "seguranca", topicos: ["seguranca", "flash"] }, { campo: "seguranca.secure_boot", label: "Secure Boot", secao: "seguranca", topicos: ["seguranca", "strapping"] }, { campo: "temperatura_operacao", label: "Température de fonctionnement", secao: "temperatura", topicos: ["temperatura"] }, { campo: "temperatura_armazenamento", label: "Température de stockage", secao: "temperatura", topicos: ["temperatura"] }, { campo: "esp_idf_minimo", label: "ESP-IDF minimum", secao: "ferramentas", topicos: ["ferramentas"] }, { campo: "arduino_core", label: "Arduino Core", secao: "ferramentas", topicos: ["ferramentas"] }, { campo: "depuracao", label: "Débogage", secao: "ferramentas", topicos: ["jtag", "ferramentas"] }, { campo: "encapsulamento", label: "Boîtier", secao: "ferramentas", topicos: ["encapsulamento"] }, { campo: "modulos", label: "Modules", secao: "ferramentas", topicos: ["encapsulamento"] }, ]; const ROTULOS_ENERGIA = { active: "Actif", modem_sleep: "Modem Sleep", light_sleep: "Light Sleep", deep_sleep: "Deep Sleep", hibernation: "Hibernation", }; const pegar = (obj, caminho) => caminho.split(".").reduce((o, k) => (o == null ? o : o[k]), obj); /** * Monte la liste à plat des spécifications pour chaque série en français. */ export function montarConhecimento(series, conexoes) { const saida = {}; for (const [chave, s] of Object.entries(series)) { const specs = []; for (const c of SPEC_CAMPOS) { const valor = pegar(s, c.campo); if (valor == null || valor === "") continue; specs.push({ label: c.label, valor: String(valor), secao: c.secao, topicos: c.topicos }); } for (const [modo, valor] of Object.entries(s.consumo_energia ?? {})) { const base = modo.replace(/_cpu.*|_wifi.*/, ""); const label = ROTULOS_ENERGIA[modo] ?? ROTULOS_ENERGIA[base] ?? modo.replace(/_/g, " "); specs.push({ label: `Consommation : ${label}`, valor: String(valor), secao: "energia", topicos: ["consumo"] }); } saida[chave] = { nome: s.nome_completo ?? chave, specs, pinos: (conexoes[chave] ?? []).map((p) => ({ n: String(p.numero), nome: p.nome, f: p.funcoes ?? [], c: p.categorias ?? [], a: p.avisos ?? [], })), }; } return saida; }