Update to 2.0.0

This commit is contained in:
2025-09-13 23:40:38 +08:00
parent 5a929f5b06
commit 63e404d610
247 changed files with 13586 additions and 11497 deletions

View File

@@ -4,11 +4,10 @@
# CMakeLists in this exact order for cmake to work correctly # CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.16) cmake_minimum_required(VERSION 3.16)
set(PROJECT_VER "1.9.1") set(PROJECT_VER "2.0.0")
# Add this line to disable the specific warning # Add this line to disable the specific warning
add_compile_options(-Wno-missing-field-initializers) add_compile_options(-Wno-missing-field-initializers)
include($ENV{IDF_PATH}/tools/cmake/project.cmake) include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(xiaozhi) project(xiaozhi)

View File

@@ -1,6 +1,6 @@
dependencies: dependencies:
78/esp-ml307: 78/esp-ml307:
component_hash: 97a1eeb5274d841bbfbe50ef6b6976f028b0f53e57aee95eda57f49048d02fb9 component_hash: 6e027bda53d9ac45ae17f33cce84c3b9fc0f5bdbe61a5b1642798d3088035a13
dependencies: dependencies:
- name: idf - name: idf
require: private require: private
@@ -8,7 +8,7 @@ dependencies:
source: source:
registry_url: https://components.espressif.com/ registry_url: https://components.espressif.com/
type: service type: service
version: 3.3.0 version: 3.3.3
78/esp-opus: 78/esp-opus:
component_hash: 8182b733f071d7bfe1e837f4c9f8649a63e4c937177f089e65772880c02f2e17 component_hash: 8182b733f071d7bfe1e837f4c9f8649a63e4c937177f089e65772880c02f2e17
dependencies: dependencies:
@@ -58,7 +58,7 @@ dependencies:
type: service type: service
version: 1.0.0 version: 1.0.0
78/xiaozhi-fonts: 78/xiaozhi-fonts:
component_hash: d9cc3aad735638e558cee514103b25d2cb60afc78ef53709ffeea443b4d1c835 component_hash: 677fa98425b8c20f3db336c81b5abdf0445ea0adf2ce40b28940daaa84c92dcb
dependencies: dependencies:
- name: idf - name: idf
require: private require: private
@@ -66,7 +66,7 @@ dependencies:
source: source:
registry_url: https://components.espressif.com/ registry_url: https://components.espressif.com/
type: service type: service
version: 1.5.1 version: 1.5.2
chmorgan/esp-libhelix-mp3: chmorgan/esp-libhelix-mp3:
component_hash: cbb76089dc2c5749f7b470e2e70aedc44c9da519e04eb9a67d4c7ec275229e53 component_hash: cbb76089dc2c5749f7b470e2e70aedc44c9da519e04eb9a67d4c7ec275229e53
dependencies: dependencies:
@@ -336,7 +336,7 @@ dependencies:
type: service type: service
version: 1.0.1 version: 1.0.1
espressif/esp_lcd_st7796: espressif/esp_lcd_st7796:
component_hash: 00ab2872c56a4037e6d1efda104ef0da00c5296865f8f938cc7cc2fc3e99f962 component_hash: 9e165065cf25b4575dd9f587440ad22aa94d011359d55a97fc39bb691a9fc0cd
dependencies: dependencies:
- name: espressif/cmake_utilities - name: espressif/cmake_utilities
registry_url: https://components.espressif.com registry_url: https://components.espressif.com
@@ -353,7 +353,7 @@ dependencies:
- esp32s2 - esp32s2
- esp32s3 - esp32s3
- esp32p4 - esp32p4
version: 1.3.2 version: 1.3.4
espressif/esp_lcd_touch: espressif/esp_lcd_touch:
component_hash: 779b4ba2464a3ae85681e4b860caa5fdc35801458c23f3039ee761bae7f442a4 component_hash: 779b4ba2464a3ae85681e4b860caa5fdc35801458c23f3039ee761bae7f442a4
dependencies: dependencies:
@@ -654,6 +654,6 @@ direct_dependencies:
- waveshare/esp_lcd_sh8601 - waveshare/esp_lcd_sh8601
- waveshare/esp_lcd_touch_cst9217 - waveshare/esp_lcd_touch_cst9217
- wvirgil123/sscma_client - wvirgil123/sscma_client
manifest_hash: 1af3184e8179db5dd2d5a0a78e420c425305f4b1d7378a0340ce6fbbffd67c14 manifest_hash: 659036190b734dad33276480a74cb2e2104cfe1b84178427bce474673a9f6e04
target: esp32s3 target: esp32s3
version: 2.0.0 version: 2.0.0

BIN
main/.DS_Store vendored

Binary file not shown.

View File

@@ -1,3 +1,39 @@
# Define default assets files (Absolute url starting with http or https is supported)
set(ASSETS_URL_PREFIX "https://files.xiaozhi.me/assets/default/")
set(ASSETS_PUHUI_COMMON_14_1 "${ASSETS_URL_PREFIX}none-font_puhui_common_14_1-none.bin")
set(ASSETS_XIAOZHI_WAKENET_ONLY "${ASSETS_URL_PREFIX}wn9_nihaoxiaozhi_tts-none-none.bin")
set(ASSETS_XIAOZHI_PUHUI_COMMON_14_1 "${ASSETS_URL_PREFIX}wn9_nihaoxiaozhi_tts-font_puhui_common_14_1-none.bin")
set(ASSETS_XIAOZHI_PUHUI_COMMON_16_4_EMOJI_32 "${ASSETS_URL_PREFIX}wn9_nihaoxiaozhi_tts-font_puhui_common_16_4-emojis_32.bin")
set(ASSETS_XIAOZHI_PUHUI_COMMON_16_4_EMOJI_64 "${ASSETS_URL_PREFIX}wn9_nihaoxiaozhi_tts-font_puhui_common_16_4-emojis_64.bin")
set(ASSETS_XIAOZHI_PUHUI_COMMON_20_4_EMOJI_64 "${ASSETS_URL_PREFIX}wn9_nihaoxiaozhi_tts-font_puhui_common_20_4-emojis_64.bin")
set(ASSETS_XIAOZHI_PUHUI_COMMON_30_4_EMOJI_64 "${ASSETS_URL_PREFIX}wn9_nihaoxiaozhi_tts-font_puhui_common_30_4-emojis_64.bin")
set(ASSETS_XIAOZHI_S_WAKENET_ONLY "${ASSETS_URL_PREFIX}wn9s_nihaoxiaozhi-none-none.bin")
set(ASSETS_XIAOZHI_S_PUHUI_COMMON_14_1 "${ASSETS_URL_PREFIX}wn9s_nihaoxiaozhi-font_puhui_common_14_1-none.bin")
set(ASSETS_XIAOZHI_S_PUHUI_COMMON_16_4_EMOJI_32 "${ASSETS_URL_PREFIX}wn9s_nihaoxiaozhi-font_puhui_common_16_4-emojis_32.bin")
set(ASSETS_XIAOZHI_S_PUHUI_COMMON_20_4_EMOJI_32 "${ASSETS_URL_PREFIX}wn9s_nihaoxiaozhi-font_puhui_common_20_4-emojis_32.bin")
set(ASSETS_XIAOZHI_S_PUHUI_COMMON_20_4_EMOJI_64 "${ASSETS_URL_PREFIX}wn9s_nihaoxiaozhi-font_puhui_common_20_4-emojis_64.bin")
set(ASSETS_XIAOZHI_S_PUHUI_COMMON_30_4_EMOJI_64 "${ASSETS_URL_PREFIX}wn9s_nihaoxiaozhi-font_puhui_common_30_4-emojis_64.bin")
# Embedded font files defined in `xiaozhi-fonts` component
# Basic fonts include ASCII and about 600 characters used in assets/locales
set(FONT_PUHUI_BASIC_14_1 font_puhui_basic_14_1)
set(FONT_PUHUI_BASIC_16_4 font_puhui_basic_16_4)
set(FONT_PUHUI_BASIC_20_4 font_puhui_basic_20_4)
set(FONT_PUHUI_BASIC_30_4 font_puhui_basic_30_4)
# Common fonts include about 7000 common characters generated with DeepSeek R1 tokenizer
set(FONT_PUHUI_COMMON_14_1 font_puhui_14_1)
set(FONT_PUHUI_COMMON_16_4 font_puhui_16_4)
set(FONT_PUHUI_COMMON_20_4 font_puhui_20_4)
set(FONT_PUHUI_COMMON_30_4 font_puhui_30_4)
set(FONT_AWESOME_14_1 font_awesome_14_1)
set(FONT_AWESOME_30_1 font_awesome_30_1)
set(FONT_AWESOME_16_4 font_awesome_16_4)
set(FONT_AWESOME_20_4 font_awesome_20_4)
set(FONT_AWESOME_30_4 font_awesome_30_4)
# Define source files
set(SOURCES "audio/audio_codec.cc" set(SOURCES "audio/audio_codec.cc"
"audio/audio_service.cc" "audio/audio_service.cc"
"audio/codecs/no_audio_codec.cc" "audio/codecs/no_audio_codec.cc"
@@ -14,6 +50,13 @@ set(SOURCES "audio/audio_codec.cc"
"display/display.cc" "display/display.cc"
"display/lcd_display.cc" "display/lcd_display.cc"
"display/oled_display.cc" "display/oled_display.cc"
"display/lvgl_display/lvgl_display.cc"
"display/lvgl_display/emoji_collection.cc"
"display/lvgl_display/lvgl_theme.cc"
"display/lvgl_display/lvgl_font.cc"
"display/lvgl_display/lvgl_image.cc"
"display/lvgl_display/gif/lvgl_gif.cc"
"display/lvgl_display/gif/gifdec.c"
"protocols/protocol.cc" "protocols/protocol.cc"
"protocols/mqtt_protocol.cc" "protocols/mqtt_protocol.cc"
"protocols/websocket_protocol.cc" "protocols/websocket_protocol.cc"
@@ -23,210 +66,465 @@ set(SOURCES "audio/audio_codec.cc"
"ota.cc" "ota.cc"
"settings.cc" "settings.cc"
"device_state_event.cc" "device_state_event.cc"
"assets.cc"
"main.cc"
) )
set(INCLUDE_DIRS "." "display" "audio" "protocols") set(INCLUDE_DIRS "." "display" "display/lvgl_display" "audio" "protocols")
# 添加板级公共文件 # Add board common files
file(GLOB BOARD_COMMON_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/boards/common/*.cc) file(GLOB BOARD_COMMON_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/boards/common/*.cc)
list(APPEND SOURCES ${BOARD_COMMON_SOURCES}) list(APPEND SOURCES ${BOARD_COMMON_SOURCES})
list(APPEND INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/boards/common) list(APPEND INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/boards/common)
# 根据 BOARD_TYPE 配置添加对应的板级文件 # Set default LVGL_TEXT_FONT and LVGL_ICON_FONT
set(LVGL_TEXT_FONT ${FONT_PUHUI_COMMON_14_1})
set(LVGL_ICON_FONT ${FONT_AWESOME_14_1})
# Add board files according to BOARD_TYPE
# Set default assets if the board uses partition table V2
if(CONFIG_BOARD_TYPE_BREAD_COMPACT_WIFI) if(CONFIG_BOARD_TYPE_BREAD_COMPACT_WIFI)
set(BOARD_TYPE "bread-compact-wifi") set(BOARD_TYPE "bread-compact-wifi")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_14_1})
set(LVGL_ICON_FONT ${FONT_AWESOME_14_1})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_14_1})
elseif(CONFIG_BOARD_TYPE_BREAD_COMPACT_ML307) elseif(CONFIG_BOARD_TYPE_BREAD_COMPACT_ML307)
set(BOARD_TYPE "bread-compact-ml307") set(BOARD_TYPE "bread-compact-ml307")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_14_1})
set(LVGL_ICON_FONT ${FONT_AWESOME_14_1})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_14_1})
elseif(CONFIG_BOARD_TYPE_BREAD_COMPACT_ESP32) elseif(CONFIG_BOARD_TYPE_BREAD_COMPACT_ESP32)
set(BOARD_TYPE "bread-compact-esp32") set(BOARD_TYPE "bread-compact-esp32")
elseif(CONFIG_BOARD_TYPE_BREAD_COMPACT_ESP32_LCD) elseif(CONFIG_BOARD_TYPE_BREAD_COMPACT_ESP32_LCD)
set(BOARD_TYPE "bread-compact-esp32-lcd") set(BOARD_TYPE "bread-compact-esp32-lcd")
set(LVGL_TEXT_FONT ${FONT_PUHUI_COMMON_14_1})
set(LVGL_ICON_FONT ${FONT_AWESOME_14_1})
elseif(CONFIG_BOARD_TYPE_DF_K10) elseif(CONFIG_BOARD_TYPE_DF_K10)
set(BOARD_TYPE "df-k10") set(BOARD_TYPE "df-k10")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_20_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_20_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_20_4_EMOJI_64})
elseif(CONFIG_BOARD_TYPE_DF_S3_AI_CAM) elseif(CONFIG_BOARD_TYPE_DF_S3_AI_CAM)
set(BOARD_TYPE "df-s3-ai-cam") set(BOARD_TYPE "df-s3-ai-cam")
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_WAKENET_ONLY})
elseif(CONFIG_BOARD_TYPE_ESP_BOX_3) elseif(CONFIG_BOARD_TYPE_ESP_BOX_3)
set(BOARD_TYPE "esp-box-3") set(BOARD_TYPE "esp-box-3")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_20_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_20_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_20_4_EMOJI_64})
elseif(CONFIG_BOARD_TYPE_ESP_BOX) elseif(CONFIG_BOARD_TYPE_ESP_BOX)
set(BOARD_TYPE "esp-box") set(BOARD_TYPE "esp-box")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_20_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_20_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_20_4_EMOJI_64})
elseif(CONFIG_BOARD_TYPE_ESP_BOX_LITE) elseif(CONFIG_BOARD_TYPE_ESP_BOX_LITE)
set(BOARD_TYPE "esp-box-lite") set(BOARD_TYPE "esp-box-lite")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_20_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_20_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_20_4_EMOJI_64})
elseif(CONFIG_BOARD_TYPE_KEVIN_BOX_1) elseif(CONFIG_BOARD_TYPE_KEVIN_BOX_1)
set(BOARD_TYPE "kevin-box-1") set(BOARD_TYPE "kevin-box-1")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_14_1})
set(LVGL_ICON_FONT ${FONT_AWESOME_14_1})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_14_1})
elseif(CONFIG_BOARD_TYPE_KEVIN_BOX_2) elseif(CONFIG_BOARD_TYPE_KEVIN_BOX_2)
set(BOARD_TYPE "kevin-box-2") set(BOARD_TYPE "kevin-box-2")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_14_1})
set(LVGL_ICON_FONT ${FONT_AWESOME_14_1})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_14_1})
elseif(CONFIG_BOARD_TYPE_KEVIN_C3) elseif(CONFIG_BOARD_TYPE_KEVIN_C3)
set(BOARD_TYPE "kevin-c3") set(BOARD_TYPE "kevin-c3")
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_S_WAKENET_ONLY})
elseif(CONFIG_BOARD_TYPE_KEVIN_SP_V3_DEV) elseif(CONFIG_BOARD_TYPE_KEVIN_SP_V3_DEV)
set(BOARD_TYPE "kevin-sp-v3-dev") set(BOARD_TYPE "kevin-sp-v3-dev")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_20_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_20_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_20_4_EMOJI_64})
elseif(CONFIG_BOARD_TYPE_KEVIN_SP_V4_DEV) elseif(CONFIG_BOARD_TYPE_KEVIN_SP_V4_DEV)
set(BOARD_TYPE "kevin-sp-v4-dev") set(BOARD_TYPE "kevin-sp-v4-dev")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_20_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_20_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_20_4_EMOJI_64})
elseif(CONFIG_BOARD_TYPE_KEVIN_YUYING_313LCD) elseif(CONFIG_BOARD_TYPE_KEVIN_YUYING_313LCD)
set(BOARD_TYPE "kevin-yuying-313lcd") set(BOARD_TYPE "kevin-yuying-313lcd")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_30_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_30_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_30_4_EMOJI_64})
elseif(CONFIG_BOARD_TYPE_LICHUANG_DEV) elseif(CONFIG_BOARD_TYPE_LICHUANG_DEV)
set(BOARD_TYPE "lichuang-dev") set(BOARD_TYPE "lichuang-dev")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_20_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_20_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_20_4_EMOJI_64})
elseif(CONFIG_BOARD_TYPE_LICHUANG_C3_DEV) elseif(CONFIG_BOARD_TYPE_LICHUANG_C3_DEV)
set(BOARD_TYPE "lichuang-c3-dev") set(BOARD_TYPE "lichuang-c3-dev")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_20_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_20_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_S_PUHUI_COMMON_20_4_EMOJI_32})
elseif(CONFIG_BOARD_TYPE_MAGICLICK_2P4) elseif(CONFIG_BOARD_TYPE_MAGICLICK_2P4)
set(BOARD_TYPE "magiclick-2p4") set(BOARD_TYPE "magiclick-2p4")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_16_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_16_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_16_4_EMOJI_32})
elseif(CONFIG_BOARD_TYPE_MAGICLICK_2P5) elseif(CONFIG_BOARD_TYPE_MAGICLICK_2P5)
set(BOARD_TYPE "magiclick-2p5") set(BOARD_TYPE "magiclick-2p5")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_16_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_16_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_16_4_EMOJI_32})
elseif(CONFIG_BOARD_TYPE_MAGICLICK_C3) elseif(CONFIG_BOARD_TYPE_MAGICLICK_C3)
set(BOARD_TYPE "magiclick-c3") set(BOARD_TYPE "magiclick-c3")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_16_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_16_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_S_PUHUI_COMMON_16_4_EMOJI_32})
elseif(CONFIG_BOARD_TYPE_MAGICLICK_C3_V2) elseif(CONFIG_BOARD_TYPE_MAGICLICK_C3_V2)
set(BOARD_TYPE "magiclick-c3-v2") set(BOARD_TYPE "magiclick-c3-v2")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_16_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_16_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_S_PUHUI_COMMON_16_4_EMOJI_32})
elseif(CONFIG_BOARD_TYPE_M5STACK_CORE_S3) elseif(CONFIG_BOARD_TYPE_M5STACK_CORE_S3)
set(BOARD_TYPE "m5stack-core-s3") set(BOARD_TYPE "m5stack-core-s3")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_20_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_20_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_20_4_EMOJI_64})
elseif(CONFIG_BOARD_TYPE_M5STACK_CORE_TAB5) elseif(CONFIG_BOARD_TYPE_M5STACK_CORE_TAB5)
set(BOARD_TYPE "m5stack-tab5") set(BOARD_TYPE "m5stack-tab5")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_30_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_30_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_30_4_EMOJI_64})
elseif(CONFIG_BOARD_TYPE_ATOMS3_ECHO_BASE) elseif(CONFIG_BOARD_TYPE_ATOMS3_ECHO_BASE)
set(BOARD_TYPE "atoms3-echo-base") set(BOARD_TYPE "atoms3-echo-base")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_16_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_16_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_16_4_EMOJI_32})
elseif(CONFIG_BOARD_TYPE_ATOMS3R_ECHO_BASE) elseif(CONFIG_BOARD_TYPE_ATOMS3R_ECHO_BASE)
set(BOARD_TYPE "atoms3r-echo-base") set(BOARD_TYPE "atoms3r-echo-base")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_16_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_16_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_16_4_EMOJI_32})
elseif(CONFIG_BOARD_TYPE_ATOMS3R_CAM_M12_ECHO_BASE) elseif(CONFIG_BOARD_TYPE_ATOMS3R_CAM_M12_ECHO_BASE)
set(BOARD_TYPE "atoms3r-cam-m12-echo-base") set(BOARD_TYPE "atoms3r-cam-m12-echo-base")
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_WAKENET_ONLY})
elseif(CONFIG_BOARD_TYPE_ATOM_ECHOS3R) elseif(CONFIG_BOARD_TYPE_ATOM_ECHOS3R)
set(BOARD_TYPE "atom-echos3r") set(BOARD_TYPE "atom-echos3r")
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_WAKENET_ONLY})
elseif(CONFIG_BOARD_TYPE_ATOMMATRIX_ECHO_BASE) elseif(CONFIG_BOARD_TYPE_ATOMMATRIX_ECHO_BASE)
set(BOARD_TYPE "atommatrix-echo-base") set(BOARD_TYPE "atommatrix-echo-base")
elseif(CONFIG_BOARD_TYPE_XMINI_C3_V3) elseif(CONFIG_BOARD_TYPE_XMINI_C3_V3)
set(BOARD_TYPE "xmini-c3-v3") set(BOARD_TYPE "xmini-c3-v3")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_14_1})
set(LVGL_ICON_FONT ${FONT_AWESOME_14_1})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_S_PUHUI_COMMON_14_1})
elseif(CONFIG_BOARD_TYPE_XMINI_C3_4G) elseif(CONFIG_BOARD_TYPE_XMINI_C3_4G)
set(BOARD_TYPE "xmini-c3-4g") set(BOARD_TYPE "xmini-c3-4g")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_14_1})
set(LVGL_ICON_FONT ${FONT_AWESOME_14_1})
set(DEFAULT_ASSETS ${ASSETS_PUHUI_COMMON_14_1})
elseif(CONFIG_BOARD_TYPE_XMINI_C3) elseif(CONFIG_BOARD_TYPE_XMINI_C3)
set(BOARD_TYPE "xmini-c3") set(BOARD_TYPE "xmini-c3")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_14_1})
set(LVGL_ICON_FONT ${FONT_AWESOME_14_1})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_S_PUHUI_COMMON_14_1})
elseif(CONFIG_BOARD_TYPE_ESP32S3_KORVO2_V3) elseif(CONFIG_BOARD_TYPE_ESP32S3_KORVO2_V3)
set(BOARD_TYPE "esp32s3-korvo2-v3") set(BOARD_TYPE "esp32s3-korvo2-v3")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_20_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_20_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_20_4_EMOJI_64})
elseif(CONFIG_BOARD_TYPE_ESP_SPARKBOT) elseif(CONFIG_BOARD_TYPE_ESP_SPARKBOT)
set(BOARD_TYPE "esp-sparkbot") set(BOARD_TYPE "esp-sparkbot")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_20_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_20_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_20_4_EMOJI_64})
elseif(CONFIG_BOARD_TYPE_ESP_SPOT_S3) elseif(CONFIG_BOARD_TYPE_ESP_SPOT_S3)
set(BOARD_TYPE "esp-spot-s3") set(BOARD_TYPE "esp-spot-s3")
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_WAKENET_ONLY})
elseif(CONFIG_BOARD_TYPE_ESP_HI) elseif(CONFIG_BOARD_TYPE_ESP_HI)
set(BOARD_TYPE "esp-hi") set(BOARD_TYPE "esp-hi")
elseif(CONFIG_BOARD_TYPE_ECHOEAR) elseif(CONFIG_BOARD_TYPE_ECHOEAR)
set(BOARD_TYPE "echoear") set(BOARD_TYPE "echoear")
set(LVGL_TEXT_FONT ${FONT_PUHUI_COMMON_20_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_20_4})
elseif(CONFIG_BOARD_TYPE_ESP32S3_AUDIO_BOARD)
set(BOARD_TYPE "waveshare-s3-audio-board")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_16_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_16_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_16_4_EMOJI_32})
elseif(CONFIG_BOARD_TYPE_ESP32S3_Touch_AMOLED_1_8) elseif(CONFIG_BOARD_TYPE_ESP32S3_Touch_AMOLED_1_8)
set(BOARD_TYPE "esp32-s3-touch-amoled-1.8") set(BOARD_TYPE "esp32-s3-touch-amoled-1.8")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_30_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_30_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_30_4_EMOJI_64})
elseif(CONFIG_BOARD_TYPE_ESP32S3_Touch_AMOLED_2_06) elseif(CONFIG_BOARD_TYPE_ESP32S3_Touch_AMOLED_2_06)
set(BOARD_TYPE "waveshare-s3-touch-amoled-2.06") set(BOARD_TYPE "waveshare-s3-touch-amoled-2.06")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_30_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_30_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_30_4_EMOJI_64})
elseif(CONFIG_BOARD_TYPE_ESP32S3_Touch_AMOLED_1_75) elseif(CONFIG_BOARD_TYPE_ESP32S3_Touch_AMOLED_1_75)
set(BOARD_TYPE "waveshare-s3-touch-amoled-1.75") set(BOARD_TYPE "waveshare-s3-touch-amoled-1.75")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_30_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_30_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_30_4_EMOJI_64})
elseif(CONFIG_BOARD_TYPE_ESP32S3_Touch_LCD_1_85C) elseif(CONFIG_BOARD_TYPE_ESP32S3_Touch_LCD_1_85C)
set(BOARD_TYPE "esp32-s3-touch-lcd-1.85c") set(BOARD_TYPE "esp32-s3-touch-lcd-1.85c")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_16_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_16_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_16_4_EMOJI_64})
elseif(CONFIG_BOARD_TYPE_ESP32S3_Touch_LCD_1_85) elseif(CONFIG_BOARD_TYPE_ESP32S3_Touch_LCD_1_85)
set(BOARD_TYPE "esp32-s3-touch-lcd-1.85") set(BOARD_TYPE "esp32-s3-touch-lcd-1.85")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_16_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_16_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_16_4_EMOJI_64})
elseif(CONFIG_BOARD_TYPE_ESP32S3_Touch_LCD_1_46) elseif(CONFIG_BOARD_TYPE_ESP32S3_Touch_LCD_1_46)
set(BOARD_TYPE "esp32-s3-touch-lcd-1.46") set(BOARD_TYPE "esp32-s3-touch-lcd-1.46")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_16_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_16_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_16_4_EMOJI_64})
elseif(CONFIG_BOARD_TYPE_ESP32S3_Touch_LCD_3_5) elseif(CONFIG_BOARD_TYPE_ESP32S3_Touch_LCD_3_5)
set(BOARD_TYPE "esp32-s3-touch-lcd-3.5") set(BOARD_TYPE "esp32-s3-touch-lcd-3.5")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_20_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_20_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_20_4_EMOJI_64})
elseif(CONFIG_BOARD_TYPE_ESP32S3_Touch_LCD_3_5B) elseif(CONFIG_BOARD_TYPE_ESP32S3_Touch_LCD_3_5B)
set(BOARD_TYPE "waveshare-s3-touch-lcd-3.5b") set(BOARD_TYPE "waveshare-s3-touch-lcd-3.5b")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_16_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_16_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_16_4_EMOJI_32})
elseif(CONFIG_BOARD_TYPE_ESP32C6_LCD_1_69) elseif(CONFIG_BOARD_TYPE_ESP32C6_LCD_1_69)
set(BOARD_TYPE "waveshare-c6-lcd-1.69") set(BOARD_TYPE "waveshare-c6-lcd-1.69")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_20_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_20_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_S_PUHUI_COMMON_20_4_EMOJI_64})
elseif(CONFIG_BOARD_TYPE_ESP32C6_Touch_AMOLED_1_43) elseif(CONFIG_BOARD_TYPE_ESP32C6_Touch_AMOLED_1_43)
set(BOARD_TYPE "waveshare-c6-touch-amoled-1.43") set(BOARD_TYPE "waveshare-c6-touch-amoled-1.43")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_30_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_30_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_S_PUHUI_COMMON_30_4_EMOJI_64})
elseif(CONFIG_BOARD_TYPE_ESP32P4_NANO) elseif(CONFIG_BOARD_TYPE_ESP32P4_NANO)
set(BOARD_TYPE "waveshare-p4-nano") set(BOARD_TYPE "waveshare-p4-nano")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_30_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_30_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_30_4_EMOJI_64})
elseif(CONFIG_BOARD_TYPE_ESP32P4_WIFI6_Touch_LCD_4B) elseif(CONFIG_BOARD_TYPE_ESP32P4_WIFI6_Touch_LCD_4B)
set(BOARD_TYPE "waveshare-p4-wifi6-touch-lcd-4b") set(BOARD_TYPE "waveshare-p4-wifi6-touch-lcd-4b")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_30_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_30_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_30_4_EMOJI_64})
elseif(CONFIG_BOARD_TYPE_ESP32P4_WIFI6_Touch_LCD_XC) elseif(CONFIG_BOARD_TYPE_ESP32P4_WIFI6_Touch_LCD_XC)
set(BOARD_TYPE "waveshare-p4-wifi6-touch-lcd-xc") set(BOARD_TYPE "waveshare-p4-wifi6-touch-lcd-xc")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_30_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_30_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_30_4_EMOJI_64})
elseif(CONFIG_BOARD_TYPE_BREAD_COMPACT_WIFI_LCD) elseif(CONFIG_BOARD_TYPE_BREAD_COMPACT_WIFI_LCD)
set(BOARD_TYPE "bread-compact-wifi-lcd") set(BOARD_TYPE "bread-compact-wifi-lcd")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_16_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_16_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_16_4_EMOJI_32})
elseif(CONFIG_BOARD_TYPE_TUDOUZI) elseif(CONFIG_BOARD_TYPE_TUDOUZI)
set(BOARD_TYPE "tudouzi") set(BOARD_TYPE "tudouzi")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_14_1})
set(LVGL_ICON_FONT ${FONT_AWESOME_14_1})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_14_1})
elseif(CONFIG_BOARD_TYPE_LILYGO_T_CIRCLE_S3) elseif(CONFIG_BOARD_TYPE_LILYGO_T_CIRCLE_S3)
set(BOARD_TYPE "lilygo-t-circle-s3") set(BOARD_TYPE "lilygo-t-circle-s3")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_16_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_16_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_16_4_EMOJI_32})
elseif(CONFIG_BOARD_TYPE_LILYGO_T_CAMERAPLUS_S3_V1_0_V1_1) elseif(CONFIG_BOARD_TYPE_LILYGO_T_CAMERAPLUS_S3_V1_0_V1_1)
set(BOARD_TYPE "lilygo-t-cameraplus-s3") set(BOARD_TYPE "lilygo-t-cameraplus-s3")
elseif(CONFIG_BOARD_TYPE_LILYGO_T_CAMERAPLUS_S3_V1_2) set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_20_4})
set(BOARD_TYPE "lilygo-t-cameraplus-s3") set(LVGL_ICON_FONT ${FONT_AWESOME_20_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_20_4_EMOJI_64})
elseif(CONFIG_BOARD_TYPE_LILYGO_T_DISPLAY_S3_PRO_MVSRLORA) elseif(CONFIG_BOARD_TYPE_LILYGO_T_DISPLAY_S3_PRO_MVSRLORA)
set(BOARD_TYPE "lilygo-t-display-s3-pro-mvsrlora") set(BOARD_TYPE "lilygo-t-display-s3-pro-mvsrlora")
elseif(CONFIG_BOARD_TYPE_LILYGO_T_DISPLAY_S3_PRO_MVSRLORA_NO_BATTERY) set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_20_4})
set(BOARD_TYPE "lilygo-t-display-s3-pro-mvsrlora") set(LVGL_ICON_FONT ${FONT_AWESOME_20_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_20_4_EMOJI_64})
elseif(CONFIG_BOARD_TYPE_MOVECALL_MOJI_ESP32S3) elseif(CONFIG_BOARD_TYPE_MOVECALL_MOJI_ESP32S3)
set(BOARD_TYPE "movecall-moji-esp32s3") set(BOARD_TYPE "movecall-moji-esp32s3")
elseif(CONFIG_BOARD_TYPE_MOVECALL_CUICAN_ESP32S3) set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_20_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_20_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_20_4_EMOJI_64})
elseif(CONFIG_BOARD_TYPE_MOVECALL_CUICAN_ESP32S3)
set(BOARD_TYPE "movecall-cuican-esp32s3") set(BOARD_TYPE "movecall-cuican-esp32s3")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_20_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_20_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_20_4_EMOJI_64})
elseif(CONFIG_BOARD_TYPE_ATK_DNESP32S3) elseif(CONFIG_BOARD_TYPE_ATK_DNESP32S3)
set(BOARD_TYPE "atk-dnesp32s3") set(BOARD_TYPE "atk-dnesp32s3")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_20_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_20_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_20_4_EMOJI_64})
elseif(CONFIG_BOARD_TYPE_ATK_DNESP32S3_BOX) elseif(CONFIG_BOARD_TYPE_ATK_DNESP32S3_BOX)
set(BOARD_TYPE "atk-dnesp32s3-box") set(BOARD_TYPE "atk-dnesp32s3-box")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_20_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_20_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_20_4_EMOJI_64})
elseif(CONFIG_BOARD_TYPE_ATK_DNESP32S3_BOX0) elseif(CONFIG_BOARD_TYPE_ATK_DNESP32S3_BOX0)
set(BOARD_TYPE "atk-dnesp32s3-box0") set(BOARD_TYPE "atk-dnesp32s3-box0")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_20_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_20_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_20_4_EMOJI_64})
elseif(CONFIG_BOARD_TYPE_ATK_DNESP32S3_BOX2_WIFI) elseif(CONFIG_BOARD_TYPE_ATK_DNESP32S3_BOX2_WIFI)
set(BOARD_TYPE "atk-dnesp32s3-box2-wifi") set(BOARD_TYPE "atk-dnesp32s3-box2-wifi")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_20_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_20_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_20_4_EMOJI_64})
elseif(CONFIG_BOARD_TYPE_ATK_DNESP32S3_BOX2_4G) elseif(CONFIG_BOARD_TYPE_ATK_DNESP32S3_BOX2_4G)
set(BOARD_TYPE "atk-dnesp32s3-box2-4g") set(BOARD_TYPE "atk-dnesp32s3-box2-4g")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_20_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_20_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_20_4_EMOJI_64})
elseif(CONFIG_BOARD_TYPE_ATK_DNESP32S3M_WIFI) elseif(CONFIG_BOARD_TYPE_ATK_DNESP32S3M_WIFI)
set(BOARD_TYPE "atk-dnesp32s3m-wifi") set(BOARD_TYPE "atk-dnesp32s3m-wifi")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_16_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_16_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_16_4_EMOJI_32})
elseif(CONFIG_BOARD_TYPE_ATK_DNESP32S3M_4G) elseif(CONFIG_BOARD_TYPE_ATK_DNESP32S3M_4G)
set(BOARD_TYPE "atk-dnesp32s3m-4g") set(BOARD_TYPE "atk-dnesp32s3m-4g")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_16_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_16_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_16_4_EMOJI_32})
elseif(CONFIG_BOARD_TYPE_DU_CHATX) elseif(CONFIG_BOARD_TYPE_DU_CHATX)
set(BOARD_TYPE "du-chatx") set(BOARD_TYPE "du-chatx")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_16_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_16_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_16_4_EMOJI_32})
elseif(CONFIG_BOARD_TYPE_ESP32S3_Taiji_Pi) elseif(CONFIG_BOARD_TYPE_ESP32S3_Taiji_Pi)
set(BOARD_TYPE "taiji-pi-s3") set(BOARD_TYPE "taiji-pi-s3")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_20_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_20_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_20_4_EMOJI_64})
elseif(CONFIG_BOARD_TYPE_XINGZHI_Cube_0_85TFT_WIFI) elseif(CONFIG_BOARD_TYPE_XINGZHI_Cube_0_85TFT_WIFI)
set(BOARD_TYPE "xingzhi-cube-0.85tft-wifi") set(BOARD_TYPE "xingzhi-cube-0.85tft-wifi")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_16_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_16_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_16_4_EMOJI_32})
elseif(CONFIG_BOARD_TYPE_XINGZHI_Cube_0_85TFT_ML307) elseif(CONFIG_BOARD_TYPE_XINGZHI_Cube_0_85TFT_ML307)
set(BOARD_TYPE "xingzhi-cube-0.85tft-ml307") set(BOARD_TYPE "xingzhi-cube-0.85tft-ml307")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_16_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_16_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_16_4_EMOJI_32})
elseif(CONFIG_BOARD_TYPE_XINGZHI_Cube_0_96OLED_WIFI) elseif(CONFIG_BOARD_TYPE_XINGZHI_Cube_0_96OLED_WIFI)
set(BOARD_TYPE "xingzhi-cube-0.96oled-wifi") set(BOARD_TYPE "xingzhi-cube-0.96oled-wifi")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_14_1})
set(LVGL_ICON_FONT ${FONT_AWESOME_14_1})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_14_1})
elseif(CONFIG_BOARD_TYPE_XINGZHI_Cube_0_96OLED_ML307) elseif(CONFIG_BOARD_TYPE_XINGZHI_Cube_0_96OLED_ML307)
set(BOARD_TYPE "xingzhi-cube-0.96oled-ml307") set(BOARD_TYPE "xingzhi-cube-0.96oled-ml307")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_14_1})
set(LVGL_ICON_FONT ${FONT_AWESOME_14_1})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_14_1})
elseif(CONFIG_BOARD_TYPE_XINGZHI_Cube_1_54TFT_WIFI) elseif(CONFIG_BOARD_TYPE_XINGZHI_Cube_1_54TFT_WIFI)
set(BOARD_TYPE "xingzhi-cube-1.54tft-wifi") set(BOARD_TYPE "xingzhi-cube-1.54tft-wifi")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_20_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_20_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_20_4_EMOJI_64})
elseif(CONFIG_BOARD_TYPE_XINGZHI_Cube_1_54TFT_ML307) elseif(CONFIG_BOARD_TYPE_XINGZHI_Cube_1_54TFT_ML307)
set(BOARD_TYPE "xingzhi-cube-1.54tft-ml307") set(BOARD_TYPE "xingzhi-cube-1.54tft-ml307")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_20_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_20_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_20_4_EMOJI_64})
elseif(CONFIG_BOARD_TYPE_SENSECAP_WATCHER) elseif(CONFIG_BOARD_TYPE_SENSECAP_WATCHER)
set(BOARD_TYPE "sensecap-watcher") set(BOARD_TYPE "sensecap-watcher")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_30_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_20_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_30_4_EMOJI_64})
elseif(CONFIG_BOARD_TYPE_DOIT_S3_AIBOX) elseif(CONFIG_BOARD_TYPE_DOIT_S3_AIBOX)
set(BOARD_TYPE "doit-s3-aibox") set(BOARD_TYPE "doit-s3-aibox")
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_WAKENET_ONLY})
elseif(CONFIG_BOARD_TYPE_MIXGO_NOVA) elseif(CONFIG_BOARD_TYPE_MIXGO_NOVA)
set(BOARD_TYPE "mixgo-nova") set(BOARD_TYPE "mixgo-nova")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_16_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_16_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_16_4_EMOJI_32})
elseif(CONFIG_BOARD_TYPE_GENJUTECH_S3_1_54TFT) elseif(CONFIG_BOARD_TYPE_GENJUTECH_S3_1_54TFT)
set(BOARD_TYPE "genjutech-s3-1.54tft") set(BOARD_TYPE "genjutech-s3-1.54tft")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_20_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_20_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_20_4_EMOJI_64})
elseif(CONFIG_BOARD_TYPE_ESP32_CGC) elseif(CONFIG_BOARD_TYPE_ESP32_CGC)
set(BOARD_TYPE "esp32-cgc") set(BOARD_TYPE "esp32-cgc")
set(LVGL_TEXT_FONT ${FONT_PUHUI_COMMON_14_1})
set(LVGL_ICON_FONT ${FONT_AWESOME_14_1})
elseif(CONFIG_BOARD_TYPE_ESP32_CGC_144) elseif(CONFIG_BOARD_TYPE_ESP32_CGC_144)
set(BOARD_TYPE "esp32-cgc-144") set(BOARD_TYPE "esp32-cgc-144")
set(LVGL_TEXT_FONT ${FONT_PUHUI_COMMON_14_1})
set(LVGL_ICON_FONT ${FONT_AWESOME_14_1})
elseif(CONFIG_BOARD_TYPE_ESP_S3_LCD_EV_Board) elseif(CONFIG_BOARD_TYPE_ESP_S3_LCD_EV_Board)
set(BOARD_TYPE "esp-s3-lcd-ev-board") set(BOARD_TYPE "esp-s3-lcd-ev-board")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_30_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_30_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_30_4_EMOJI_64})
elseif(CONFIG_BOARD_TYPE_ESP_S3_LCD_EV_Board_2) elseif(CONFIG_BOARD_TYPE_ESP_S3_LCD_EV_Board_2)
set(BOARD_TYPE "esp-s3-lcd-ev-board-2") set(BOARD_TYPE "esp-s3-lcd-ev-board-2")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_30_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_30_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_30_4_EMOJI_64})
elseif(CONFIG_BOARD_TYPE_ZHENGCHEN_1_54TFT_WIFI) elseif(CONFIG_BOARD_TYPE_ZHENGCHEN_1_54TFT_WIFI)
set(BOARD_TYPE "zhengchen-1.54tft-wifi") set(BOARD_TYPE "zhengchen-1.54tft-wifi")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_20_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_20_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_20_4_EMOJI_64})
elseif(CONFIG_BOARD_TYPE_MINSI_K08_DUAL) elseif(CONFIG_BOARD_TYPE_MINSI_K08_DUAL)
set(BOARD_TYPE "minsi-k08-dual") set(BOARD_TYPE "minsi-k08-dual")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_20_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_20_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_20_4_EMOJI_64})
elseif(CONFIG_BOARD_TYPE_ZHENGCHEN_1_54TFT_ML307) elseif(CONFIG_BOARD_TYPE_ZHENGCHEN_1_54TFT_ML307)
set(BOARD_TYPE "zhengchen-1.54tft-ml307") set(BOARD_TYPE "zhengchen-1.54tft-ml307")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_20_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_20_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_20_4_EMOJI_64})
elseif(CONFIG_BOARD_TYPE_ESP32_S3_1_54_MUMA) elseif(CONFIG_BOARD_TYPE_ESP32_S3_1_54_MUMA)
set(BOARD_TYPE "sp-esp32-s3-1.54-muma") set(BOARD_TYPE "sp-esp32-s3-1.54-muma")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_16_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_16_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_16_4_EMOJI_32})
elseif(CONFIG_BOARD_TYPE_ESP32_S3_1_28_BOX) elseif(CONFIG_BOARD_TYPE_ESP32_S3_1_28_BOX)
set(BOARD_TYPE "sp-esp32-s3-1.28-box") set(BOARD_TYPE "sp-esp32-s3-1.28-box")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_16_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_16_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_16_4_EMOJI_64})
elseif(CONFIG_BOARD_TYPE_OTTO_ROBOT) elseif(CONFIG_BOARD_TYPE_OTTO_ROBOT)
set(BOARD_TYPE "otto-robot") set(BOARD_TYPE "otto-robot")
set(LVGL_TEXT_FONT ${FONT_PUHUI_COMMON_16_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_16_4})
elseif(CONFIG_BOARD_TYPE_ELECTRON_BOT) elseif(CONFIG_BOARD_TYPE_ELECTRON_BOT)
set(BOARD_TYPE "electron-bot") set(BOARD_TYPE "electron-bot")
set(LVGL_TEXT_FONT ${FONT_PUHUI_COMMON_20_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_20_4})
elseif(CONFIG_BOARD_TYPE_BREAD_COMPACT_WIFI_CAM) elseif(CONFIG_BOARD_TYPE_BREAD_COMPACT_WIFI_CAM)
set(BOARD_TYPE "bread-compact-wifi-s3cam") set(BOARD_TYPE "bread-compact-wifi-s3cam")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_16_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_16_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_16_4_EMOJI_64})
elseif(CONFIG_BOARD_TYPE_JIUCHUAN) elseif(CONFIG_BOARD_TYPE_JIUCHUAN)
set(BOARD_TYPE "jiuchuan-s3") set(BOARD_TYPE "jiuchuan-s3")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_20_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_20_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_20_4_EMOJI_64})
elseif(CONFIG_BOARD_TYPE_LABPLUS_MPYTHON_V3) elseif(CONFIG_BOARD_TYPE_LABPLUS_MPYTHON_V3)
set(BOARD_TYPE "labplus-mpython-v3") set(BOARD_TYPE "labplus-mpython-v3")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_20_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_20_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_20_4_EMOJI_64})
elseif(CONFIG_BOARD_TYPE_LABPLUS_LEDONG_V2) elseif(CONFIG_BOARD_TYPE_LABPLUS_LEDONG_V2)
set(BOARD_TYPE "labplus-ledong-v2") set(BOARD_TYPE "labplus-ledong-v2")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_20_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_20_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_PUHUI_COMMON_20_4_EMOJI_64})
elseif(CONFIG_BOARD_TYPE_SURFER_C3_1_14TFT) elseif(CONFIG_BOARD_TYPE_SURFER_C3_1_14TFT)
set(BOARD_TYPE "surfer-c3-1.14tft") set(BOARD_TYPE "surfer-c3-1.14tft")
set(LVGL_TEXT_FONT ${FONT_PUHUI_BASIC_20_4})
set(LVGL_ICON_FONT ${FONT_AWESOME_20_4})
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_S_PUHUI_COMMON_20_4_EMOJI_32})
endif() endif()
file(GLOB BOARD_SOURCES file(GLOB BOARD_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/boards/${BOARD_TYPE}/*.cc ${CMAKE_CURRENT_SOURCE_DIR}/boards/${BOARD_TYPE}/*.cc
${CMAKE_CURRENT_SOURCE_DIR}/boards/${BOARD_TYPE}/*.c ${CMAKE_CURRENT_SOURCE_DIR}/boards/${BOARD_TYPE}/*.c
) )
list(APPEND SOURCES ${BOARD_SOURCES}) list(APPEND SOURCES ${BOARD_SOURCES})
# Select audio processor according to Kconfig
if(CONFIG_USE_AUDIO_PROCESSOR) if(CONFIG_USE_AUDIO_PROCESSOR)
list(APPEND SOURCES "audio/processors/afe_audio_processor.cc") list(APPEND SOURCES "audio/processors/afe_audio_processor.cc")
else() else()
@@ -240,7 +538,7 @@ elseif(CONFIG_USE_CUSTOM_WAKE_WORD)
list(APPEND SOURCES "audio/wake_words/custom_wake_word.cc") list(APPEND SOURCES "audio/wake_words/custom_wake_word.cc")
endif() endif()
# 根据Kconfig选择语言目录 # Select language directory according to Kconfig
if(CONFIG_LANGUAGE_ZH_CN) if(CONFIG_LANGUAGE_ZH_CN)
set(LANG_DIR "zh-CN") set(LANG_DIR "zh-CN")
elseif(CONFIG_LANGUAGE_ZH_TW) elseif(CONFIG_LANGUAGE_ZH_TW)
@@ -287,13 +585,13 @@ elseif(CONFIG_LANGUAGE_RO_RO)
set(LANG_DIR "ro-RO") set(LANG_DIR "ro-RO")
endif() endif()
# 定义生成路径 # Define generation path
set(LANG_JSON "${CMAKE_CURRENT_SOURCE_DIR}/assets/locales/${LANG_DIR}/language.json") set(LANG_JSON "${CMAKE_CURRENT_SOURCE_DIR}/assets/locales/${LANG_DIR}/language.json")
set(LANG_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/assets/lang_config.h") set(LANG_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/assets/lang_config.h")
file(GLOB LANG_SOUNDS ${CMAKE_CURRENT_SOURCE_DIR}/assets/locales/${LANG_DIR}/*.ogg) file(GLOB LANG_SOUNDS ${CMAKE_CURRENT_SOURCE_DIR}/assets/locales/${LANG_DIR}/*.ogg)
file(GLOB COMMON_SOUNDS ${CMAKE_CURRENT_SOURCE_DIR}/assets/common/*.ogg) file(GLOB COMMON_SOUNDS ${CMAKE_CURRENT_SOURCE_DIR}/assets/common/*.ogg)
# 如果目标芯片是 ESP32则排除特定文件 # If target chip is ESP32, exclude specific files to avoid build errors
if(CONFIG_IDF_TARGET_ESP32) if(CONFIG_IDF_TARGET_ESP32)
list(REMOVE_ITEM SOURCES "audio/codecs/box_audio_codec.cc" list(REMOVE_ITEM SOURCES "audio/codecs/box_audio_codec.cc"
"audio/codecs/es8388_audio_codec.cc" "audio/codecs/es8388_audio_codec.cc"
@@ -308,16 +606,17 @@ idf_component_register(SRCS ${SOURCES}
WHOLE_ARCHIVE WHOLE_ARCHIVE
) )
# 使用 target_compile_definitions 来定义 BOARD_TYPE, BOARD_NAME # Use target_compile_definitions to define BOARD_TYPE, BOARD_NAME
# 如果 BOARD_NAME 为空,则使用 BOARD_TYPE # If BOARD_NAME is empty, use BOARD_TYPE
if(NOT BOARD_NAME) if(NOT BOARD_NAME)
set(BOARD_NAME ${BOARD_TYPE}) set(BOARD_NAME ${BOARD_TYPE})
endif() endif()
target_compile_definitions(${COMPONENT_LIB} target_compile_definitions(${COMPONENT_LIB}
PRIVATE BOARD_TYPE=\"${BOARD_TYPE}\" BOARD_NAME=\"${BOARD_NAME}\" PRIVATE BOARD_TYPE=\"${BOARD_TYPE}\" BOARD_NAME=\"${BOARD_NAME}\"
PRIVATE DEFAULT_ASSETS=\"${DEFAULT_ASSETS}\" LVGL_TEXT_FONT=${LVGL_TEXT_FONT} LVGL_ICON_FONT=${LVGL_ICON_FONT}
) )
# 添加生成规则 # Add generation rules
add_custom_command( add_custom_command(
OUTPUT ${LANG_HEADER} OUTPUT ${LANG_HEADER}
COMMAND python ${PROJECT_DIR}/scripts/gen_lang.py COMMAND python ${PROJECT_DIR}/scripts/gen_lang.py
@@ -329,7 +628,7 @@ add_custom_command(
COMMENT "Generating ${LANG_DIR} language config" COMMENT "Generating ${LANG_DIR} language config"
) )
# 强制建立生成依赖 # Force build generation dependencies
add_custom_target(lang_header ALL add_custom_target(lang_header ALL
DEPENDS ${LANG_HEADER} DEPENDS ${LANG_HEADER}
) )
@@ -355,7 +654,7 @@ foreach(FILENAME IN LISTS FILES_TO_DOWNLOAD)
set(REMOTE_FILE "${URL}/${FILENAME}") set(REMOTE_FILE "${URL}/${FILENAME}")
set(LOCAL_FILE "${SPIFFS_DIR}/${FILENAME}") set(LOCAL_FILE "${SPIFFS_DIR}/${FILENAME}")
# 检查本地文件是否存在 # Check if local file exists
if(EXISTS ${LOCAL_FILE}) if(EXISTS ${LOCAL_FILE})
message(STATUS "File ${FILENAME} already exists, skipping download") message(STATUS "File ${FILENAME} already exists, skipping download")
else() else()
@@ -397,3 +696,131 @@ spiffs_create_partition_assets(
IMPORT_INC_PATH ${CMAKE_CURRENT_SOURCE_DIR}/boards/${BOARD_TYPE} IMPORT_INC_PATH ${CMAKE_CURRENT_SOURCE_DIR}/boards/${BOARD_TYPE}
) )
endif() endif()
# Font configuration validation function
function(validate_font_config board_name text_font default_assets)
if(text_font)
# Check if DEFAULT_ASSETS contains font
if(default_assets AND default_assets MATCHES "font_")
# Rule 1: If DEFAULT_ASSETS uses font, LVGL_TEXT_FONT must be BASIC
if(NOT text_font MATCHES "basic")
message(FATAL_ERROR "Font config error for ${board_name}: DEFAULT_ASSETS contains COMMON font but LVGL_TEXT_FONT is not BASIC (${text_font})")
endif()
else()
# Rule 2: If no DEFAULT_ASSETS or DEFAULT_ASSETS doesn't contain font_, LVGL_TEXT_FONT must not be BASIC
if(text_font MATCHES "basic")
message(FATAL_ERROR "Font config error for ${board_name}: No DEFAULT_ASSETS with COMMON font but LVGL_TEXT_FONT is not COMMON (${text_font})")
endif()
endif()
# Pass validation
message(STATUS "Font config validation passed for ${board_name}: LVGL_TEXT_FONT=${text_font}, DEFAULT_ASSETS=${default_assets}")
endif()
endfunction()
# DEFAULT_ASSETS prefix validation function
function(validate_default_assets_prefix board_name default_assets)
if(default_assets)
# Check for ESP32S3/P4 target - DEFAULT_ASSETS cannot start with "wn9s_"
if(CONFIG_IDF_TARGET_ESP32S3 OR CONFIG_IDF_TARGET_ESP32P4)
if(default_assets MATCHES "^wn9s_")
message(FATAL_ERROR "Assets config error for ${board_name}: DEFAULT_ASSETS cannot start with 'wn9s_' for ESP32S3 target (${default_assets})")
endif()
endif()
# Check for ESP32C3/C6 target - DEFAULT_ASSETS cannot start with "wn9_"
if(CONFIG_IDF_TARGET_ESP32C3 OR CONFIG_IDF_TARGET_ESP32C6)
if(default_assets MATCHES "^wn9_")
message(FATAL_ERROR "Assets config error for ${board_name}: DEFAULT_ASSETS cannot start with 'wn9_' for ESP32C3/C6 target (${default_assets})")
endif()
endif()
# Pass validation
message(STATUS "Assets prefix validation passed for ${board_name}: DEFAULT_ASSETS=${default_assets}")
endif()
endfunction()
# Global font configuration validation
# This will validate the current board's font configuration
if(LVGL_TEXT_FONT)
validate_font_config("${BOARD_TYPE}" "${LVGL_TEXT_FONT}" "${DEFAULT_ASSETS}")
endif()
# Global DEFAULT_ASSETS prefix validation
# This will validate the current board's DEFAULT_ASSETS prefix configuration
if(DEFAULT_ASSETS)
validate_default_assets_prefix("${BOARD_TYPE}" "${DEFAULT_ASSETS}")
endif()
# Function to get local assets file path (handles both URL and local file)
function(get_assets_local_file assets_source assets_local_file_var)
# Check if it's a URL (starts with http:// or https://)
if(assets_source MATCHES "^https?://")
# It's a URL, download it
get_filename_component(ASSETS_FILENAME "${assets_source}" NAME)
set(ASSETS_LOCAL_FILE "${CMAKE_BINARY_DIR}/${ASSETS_FILENAME}")
set(ASSETS_TEMP_FILE "${CMAKE_BINARY_DIR}/${ASSETS_FILENAME}.tmp")
# Check if local file exists
if(EXISTS ${ASSETS_LOCAL_FILE})
message(STATUS "Assets file ${ASSETS_FILENAME} already exists, skipping download")
else()
message(STATUS "Downloading ${ASSETS_FILENAME}")
# Clean up any existing temp file
if(EXISTS ${ASSETS_TEMP_FILE})
file(REMOVE ${ASSETS_TEMP_FILE})
endif()
# Download to temporary file first
file(DOWNLOAD ${assets_source} ${ASSETS_TEMP_FILE}
STATUS DOWNLOAD_STATUS)
list(GET DOWNLOAD_STATUS 0 STATUS_CODE)
if(NOT STATUS_CODE EQUAL 0)
# Clean up temp file on failure
if(EXISTS ${ASSETS_TEMP_FILE})
file(REMOVE ${ASSETS_TEMP_FILE})
endif()
message(FATAL_ERROR "Failed to download ${ASSETS_FILENAME} from ${assets_source}")
endif()
# Move temp file to final location (atomic operation)
file(RENAME ${ASSETS_TEMP_FILE} ${ASSETS_LOCAL_FILE})
message(STATUS "Successfully downloaded ${ASSETS_FILENAME}")
endif()
else()
# It's a local file path
if(IS_ABSOLUTE "${assets_source}")
set(ASSETS_LOCAL_FILE "${assets_source}")
else()
set(ASSETS_LOCAL_FILE "${CMAKE_CURRENT_SOURCE_DIR}/${assets_source}")
endif()
# Check if local file exists
if(NOT EXISTS ${ASSETS_LOCAL_FILE})
message(FATAL_ERROR "Assets file not found: ${ASSETS_LOCAL_FILE}")
endif()
message(STATUS "Using assets file: ${ASSETS_LOCAL_FILE}")
endif()
set(${assets_local_file_var} ${ASSETS_LOCAL_FILE} PARENT_SCOPE)
endfunction()
# Flash assets based on configuration
if(CONFIG_FLASH_DEFAULT_ASSETS)
# Flash default assets
if(DEFAULT_ASSETS)
get_assets_local_file("${DEFAULT_ASSETS}" ASSETS_LOCAL_FILE)
esptool_py_flash_to_partition(flash "assets" "${ASSETS_LOCAL_FILE}")
message(STATUS "Default assets download and flash configured: ${DEFAULT_ASSETS} -> assets partition")
else()
message(WARNING "FLASH_DEFAULT_ASSETS is enabled but no DEFAULT_ASSETS is defined for board ${BOARD_TYPE}")
endif()
elseif(CONFIG_FLASH_CUSTOM_ASSETS)
# Flash custom assets
get_assets_local_file("${CONFIG_CUSTOM_ASSETS_FILE}" ASSETS_LOCAL_FILE)
esptool_py_flash_to_partition(flash "assets" "${ASSETS_LOCAL_FILE}")
message(STATUS "Custom assets flash configured: ${ASSETS_LOCAL_FILE} -> assets partition")
elseif(CONFIG_FLASH_NONE_ASSETS)
message(STATUS "Assets flashing disabled (FLASH_NONE_ASSETS)")
endif()

View File

@@ -6,6 +6,27 @@ config OTA_URL
help help
The application will access this URL to check for new firmwares and server address. The application will access this URL to check for new firmwares and server address.
choice
prompt "Flash Assets"
default FLASH_NONE_ASSETS
help
Select the assets to flash.
config FLASH_NONE_ASSETS
bool "Do not flash assets"
config FLASH_DEFAULT_ASSETS
bool "Flash Default Assets"
config FLASH_CUSTOM_ASSETS
bool "Flash Custom Assets"
endchoice
config CUSTOM_ASSETS_FILE
depends on FLASH_CUSTOM_ASSETS
string "Custom Assets File"
default "assets.bin"
help
The custom assets file to flash.
It can be a local file relative to the project directory or a remote url.
choice choice
prompt "Default Language" prompt "Default Language"
@@ -556,4 +577,4 @@ choice I2S_TYPE_TAIJIPI_S3
bool "I2S Type PDM" bool "I2S Type PDM"
endchoice endchoice
endmenu endmenu

View File

@@ -7,6 +7,8 @@
#include "websocket_protocol.h" #include "websocket_protocol.h"
#include "assets/lang_config.h" #include "assets/lang_config.h"
#include "mcp_server.h" #include "mcp_server.h"
#include "assets.h"
#include "settings.h"
#include <cstring> #include <cstring>
#include <esp_log.h> #include <esp_log.h>
@@ -49,7 +51,7 @@ Application::Application() {
esp_timer_create_args_t clock_timer_args = { esp_timer_create_args_t clock_timer_args = {
.callback = [](void* arg) { .callback = [](void* arg) {
Application* app = (Application*)arg; Application* app = (Application*)arg;
app->OnClockTimer(); xEventGroupSetBits(app->event_group_, MAIN_EVENT_CLOCK_TICK);
}, },
.arg = this, .arg = this,
.dispatch_method = ESP_TIMER_TASK, .dispatch_method = ESP_TIMER_TASK,
@@ -67,6 +69,65 @@ Application::~Application() {
vEventGroupDelete(event_group_); vEventGroupDelete(event_group_);
} }
void Application::CheckAssetsVersion() {
auto& board = Board::GetInstance();
auto display = board.GetDisplay();
auto assets = board.GetAssets();
if (!assets) {
ESP_LOGE(TAG, "Assets is not set for board %s", BOARD_NAME);
return;
}
if (!assets->partition_valid()) {
ESP_LOGE(TAG, "Assets partition is not valid for board %s", BOARD_NAME);
return;
}
Settings settings("assets", true);
// Check if there is a new assets need to be downloaded
std::string download_url = settings.GetString("download_url");
if (!download_url.empty()) {
settings.EraseKey("download_url");
}
if (download_url.empty() && !assets->checksum_valid()) {
download_url = assets->default_assets_url();
}
if (!download_url.empty()) {
char message[256];
snprintf(message, sizeof(message), Lang::Strings::FOUND_NEW_ASSETS, download_url.c_str());
Alert(Lang::Strings::LOADING_ASSETS, message, "cloud_arrow_down", Lang::Sounds::OGG_UPGRADE);
// Wait for the audio service to be idle for 3 seconds
vTaskDelay(pdMS_TO_TICKS(3000));
SetDeviceState(kDeviceStateUpgrading);
board.SetPowerSaveMode(false);
display->SetChatMessage("system", Lang::Strings::PLEASE_WAIT);
bool success = assets->Download(download_url, [display](int progress, size_t speed) -> void {
std::thread([display, progress, speed]() {
char buffer[32];
snprintf(buffer, sizeof(buffer), "%d%% %uKB/s", progress, speed / 1024);
display->SetChatMessage("system", buffer);
}).detach();
});
board.SetPowerSaveMode(true);
vTaskDelay(pdMS_TO_TICKS(1000));
if (!success) {
Alert(Lang::Strings::ERROR, Lang::Strings::DOWNLOAD_ASSETS_FAILED, "circle_xmark", Lang::Sounds::OGG_EXCLAMATION);
vTaskDelay(pdMS_TO_TICKS(2000));
return;
}
}
// Apply assets
assets->Apply();
display->SetChatMessage("system", "");
display->SetEmotion("microchip_ai");
}
void Application::CheckNewVersion(Ota& ota) { void Application::CheckNewVersion(Ota& ota) {
const int MAX_RETRY = 10; const int MAX_RETRY = 10;
int retry_count = 0; int retry_count = 0;
@@ -103,43 +164,10 @@ void Application::CheckNewVersion(Ota& ota) {
retry_delay = 10; // 重置重试延迟时间 retry_delay = 10; // 重置重试延迟时间
if (ota.HasNewVersion()) { if (ota.HasNewVersion()) {
Alert(Lang::Strings::OTA_UPGRADE, Lang::Strings::UPGRADING, "download", Lang::Sounds::OGG_UPGRADE); if (UpgradeFirmware(ota)) {
vTaskDelay(pdMS_TO_TICKS(3000));
SetDeviceState(kDeviceStateUpgrading);
std::string message = std::string(Lang::Strings::NEW_VERSION) + ota.GetFirmwareVersion();
display->SetChatMessage("system", message.c_str());
board.SetPowerSaveMode(false);
audio_service_.Stop();
vTaskDelay(pdMS_TO_TICKS(1000));
bool upgrade_success = ota.StartUpgrade([display](int progress, size_t speed) {
std::thread([display, progress, speed]() {
char buffer[32];
snprintf(buffer, sizeof(buffer), "%d%% %uKB/s", progress, speed / 1024);
display->SetChatMessage("system", buffer);
}).detach();
});
if (!upgrade_success) {
// Upgrade failed, restart audio service and continue running
ESP_LOGE(TAG, "Firmware upgrade failed, restarting audio service and continuing operation...");
audio_service_.Start(); // Restart audio service
board.SetPowerSaveMode(true); // Restore power save mode
Alert(Lang::Strings::ERROR, Lang::Strings::UPGRADE_FAILED, "circle_xmark", Lang::Sounds::OGG_EXCLAMATION);
vTaskDelay(pdMS_TO_TICKS(3000));
// Continue to normal operation (don't break, just fall through)
} else {
// Upgrade success, reboot immediately
ESP_LOGI(TAG, "Firmware upgrade successful, rebooting...");
display->SetChatMessage("system", "Upgrade successful, rebooting...");
vTaskDelay(pdMS_TO_TICKS(1000)); // Brief pause to show message
Reboot();
return; // This line will never be reached after reboot return; // This line will never be reached after reboot
} }
// If upgrade failed, continue to normal operation (don't break, just fall through)
} }
// No new version, mark the current version as valid // No new version, mark the current version as valid
@@ -358,6 +386,9 @@ void Application::Start() {
// Update the status bar immediately to show the network state // Update the status bar immediately to show the network state
display->UpdateStatusBar(true); display->UpdateStatusBar(true);
// Check for new assets version
CheckAssetsVersion();
// Check for new firmware version or get the MQTT broker address // Check for new firmware version or get the MQTT broker address
Ota ota; Ota ota;
CheckNewVersion(ota); CheckNewVersion(ota);
@@ -366,7 +397,9 @@ void Application::Start() {
display->SetStatus(Lang::Strings::LOADING_PROTOCOL); display->SetStatus(Lang::Strings::LOADING_PROTOCOL);
// Add MCP common tools before initializing the protocol // Add MCP common tools before initializing the protocol
McpServer::GetInstance().AddCommonTools(); auto& mcp_server = McpServer::GetInstance();
mcp_server.AddCommonTools();
mcp_server.AddUserOnlyTools();
if (ota.HasMqttConfig()) { if (ota.HasMqttConfig()) {
protocol_ = std::make_unique<MqttProtocol>(); protocol_ = std::make_unique<MqttProtocol>();
@@ -496,6 +529,7 @@ void Application::Start() {
}); });
bool protocol_started = protocol_->Start(); bool protocol_started = protocol_->Start();
SystemInfo::PrintHeapStats();
SetDeviceState(kDeviceStateIdle); SetDeviceState(kDeviceStateIdle);
has_server_time_ = ota.HasServerTime(); has_server_time_ = ota.HasServerTime();
@@ -506,23 +540,6 @@ void Application::Start() {
// Play the success sound to indicate the device is ready // Play the success sound to indicate the device is ready
audio_service_.PlaySound(Lang::Sounds::OGG_SUCCESS); audio_service_.PlaySound(Lang::Sounds::OGG_SUCCESS);
} }
// Print heap stats
SystemInfo::PrintHeapStats();
}
void Application::OnClockTimer() {
clock_ticks_++;
auto display = Board::GetInstance().GetDisplay();
display->UpdateStatusBar();
// Print the debug info every 10 seconds
if (clock_ticks_ % 10 == 0) {
// SystemInfo::PrintTaskCpuUsage(pdMS_TO_TICKS(1000));
// SystemInfo::PrintTaskList();
SystemInfo::PrintHeapStats();
}
} }
// Add a async task to MainLoop // Add a async task to MainLoop
@@ -546,7 +563,9 @@ void Application::MainEventLoop() {
MAIN_EVENT_SEND_AUDIO | MAIN_EVENT_SEND_AUDIO |
MAIN_EVENT_WAKE_WORD_DETECTED | MAIN_EVENT_WAKE_WORD_DETECTED |
MAIN_EVENT_VAD_CHANGE | MAIN_EVENT_VAD_CHANGE |
MAIN_EVENT_CLOCK_TICK |
MAIN_EVENT_ERROR, pdTRUE, pdFALSE, portMAX_DELAY); MAIN_EVENT_ERROR, pdTRUE, pdFALSE, portMAX_DELAY);
if (bits & MAIN_EVENT_ERROR) { if (bits & MAIN_EVENT_ERROR) {
SetDeviceState(kDeviceStateIdle); SetDeviceState(kDeviceStateIdle);
Alert(Lang::Strings::ERROR, last_error_message_.c_str(), "circle_xmark", Lang::Sounds::OGG_EXCLAMATION); Alert(Lang::Strings::ERROR, last_error_message_.c_str(), "circle_xmark", Lang::Sounds::OGG_EXCLAMATION);
@@ -554,7 +573,7 @@ void Application::MainEventLoop() {
if (bits & MAIN_EVENT_SEND_AUDIO) { if (bits & MAIN_EVENT_SEND_AUDIO) {
while (auto packet = audio_service_.PopPacketFromSendQueue()) { while (auto packet = audio_service_.PopPacketFromSendQueue()) {
if (!protocol_->SendAudio(std::move(packet))) { if (protocol_ && !protocol_->SendAudio(std::move(packet))) {
break; break;
} }
} }
@@ -579,6 +598,19 @@ void Application::MainEventLoop() {
task(); task();
} }
} }
if (bits & MAIN_EVENT_CLOCK_TICK) {
clock_ticks_++;
auto display = Board::GetInstance().GetDisplay();
display->UpdateStatusBar();
// Print the debug info every 10 seconds
if (clock_ticks_ % 10 == 0) {
// SystemInfo::PrintTaskCpuUsage(pdMS_TO_TICKS(1000));
// SystemInfo::PrintTaskList();
SystemInfo::PrintHeapStats();
}
}
} }
} }
@@ -623,7 +655,9 @@ void Application::OnWakeWordDetected() {
void Application::AbortSpeaking(AbortReason reason) { void Application::AbortSpeaking(AbortReason reason) {
ESP_LOGI(TAG, "Abort speaking"); ESP_LOGI(TAG, "Abort speaking");
aborted_ = true; aborted_ = true;
protocol_->SendAbortSpeaking(reason); if (protocol_) {
protocol_->SendAbortSpeaking(reason);
}
} }
void Application::SetListeningMode(ListeningMode mode) { void Application::SetListeningMode(ListeningMode mode) {
@@ -706,9 +740,70 @@ void Application::SetDeviceState(DeviceState state) {
void Application::Reboot() { void Application::Reboot() {
ESP_LOGI(TAG, "Rebooting..."); ESP_LOGI(TAG, "Rebooting...");
// Disconnect the audio channel
if (protocol_ && protocol_->IsAudioChannelOpened()) {
protocol_->CloseAudioChannel();
}
protocol_.reset();
audio_service_.Stop();
vTaskDelay(pdMS_TO_TICKS(1000));
esp_restart(); esp_restart();
} }
bool Application::UpgradeFirmware(Ota& ota, const std::string& url) {
auto& board = Board::GetInstance();
auto display = board.GetDisplay();
// Use provided URL or get from OTA object
std::string upgrade_url = url.empty() ? ota.GetFirmwareUrl() : url;
std::string version_info = url.empty() ? ota.GetFirmwareVersion() : "(Manual upgrade)";
// Close audio channel if it's open
if (protocol_ && protocol_->IsAudioChannelOpened()) {
ESP_LOGI(TAG, "Closing audio channel before firmware upgrade");
protocol_->CloseAudioChannel();
}
ESP_LOGI(TAG, "Starting firmware upgrade from URL: %s", upgrade_url.c_str());
Alert(Lang::Strings::OTA_UPGRADE, Lang::Strings::UPGRADING, "download", Lang::Sounds::OGG_UPGRADE);
vTaskDelay(pdMS_TO_TICKS(3000));
SetDeviceState(kDeviceStateUpgrading);
std::string message = std::string(Lang::Strings::NEW_VERSION) + version_info;
display->SetChatMessage("system", message.c_str());
board.SetPowerSaveMode(false);
audio_service_.Stop();
vTaskDelay(pdMS_TO_TICKS(1000));
bool upgrade_success = ota.StartUpgradeFromUrl(upgrade_url, [display](int progress, size_t speed) {
std::thread([display, progress, speed]() {
char buffer[32];
snprintf(buffer, sizeof(buffer), "%d%% %uKB/s", progress, speed / 1024);
display->SetChatMessage("system", buffer);
}).detach();
});
if (!upgrade_success) {
// Upgrade failed, restart audio service and continue running
ESP_LOGE(TAG, "Firmware upgrade failed, restarting audio service and continuing operation...");
audio_service_.Start(); // Restart audio service
board.SetPowerSaveMode(true); // Restore power save mode
Alert(Lang::Strings::ERROR, Lang::Strings::UPGRADE_FAILED, "circle_xmark", Lang::Sounds::OGG_EXCLAMATION);
vTaskDelay(pdMS_TO_TICKS(3000));
return false;
} else {
// Upgrade success, reboot immediately
ESP_LOGI(TAG, "Firmware upgrade successful, rebooting...");
display->SetChatMessage("system", "Upgrade successful, rebooting...");
vTaskDelay(pdMS_TO_TICKS(1000)); // Brief pause to show message
Reboot();
return true;
}
}
void Application::WakeWordInvoke(const std::string& wake_word) { void Application::WakeWordInvoke(const std::string& wake_word) {
if (device_state_ == kDeviceStateIdle) { if (device_state_ == kDeviceStateIdle) {
ToggleChatState(); ToggleChatState();

View File

@@ -16,12 +16,15 @@
#include "audio_service.h" #include "audio_service.h"
#include "device_state_event.h" #include "device_state_event.h"
#define MAIN_EVENT_SCHEDULE (1 << 0) #define MAIN_EVENT_SCHEDULE (1 << 0)
#define MAIN_EVENT_SEND_AUDIO (1 << 1) #define MAIN_EVENT_SEND_AUDIO (1 << 1)
#define MAIN_EVENT_WAKE_WORD_DETECTED (1 << 2) #define MAIN_EVENT_WAKE_WORD_DETECTED (1 << 2)
#define MAIN_EVENT_VAD_CHANGE (1 << 3) #define MAIN_EVENT_VAD_CHANGE (1 << 3)
#define MAIN_EVENT_ERROR (1 << 4) #define MAIN_EVENT_ERROR (1 << 4)
#define MAIN_EVENT_CHECK_NEW_VERSION_DONE (1 << 5) #define MAIN_EVENT_CHECK_NEW_VERSION_DONE (1 << 5)
#define MAIN_EVENT_CLOCK_TICK (1 << 6)
enum AecMode { enum AecMode {
kAecOff, kAecOff,
@@ -53,6 +56,7 @@ public:
void StopListening(); void StopListening();
void Reboot(); void Reboot();
void WakeWordInvoke(const std::string& wake_word); void WakeWordInvoke(const std::string& wake_word);
bool UpgradeFirmware(Ota& ota, const std::string& url = "");
bool CanEnterSleepMode(); bool CanEnterSleepMode();
void SendMcpMessage(const std::string& payload); void SendMcpMessage(const std::string& payload);
void SetAecMode(AecMode mode); void SetAecMode(AecMode mode);
@@ -85,8 +89,8 @@ private:
void OnWakeWordDetected(); void OnWakeWordDetected();
void CheckNewVersion(Ota& ota); void CheckNewVersion(Ota& ota);
void CheckAssetsVersion();
void ShowActivationCode(const std::string& code, const std::string& message); void ShowActivationCode(const std::string& code, const std::string& message);
void OnClockTimer();
void SetListeningMode(ListeningMode mode); void SetListeningMode(ListeningMode mode);
}; };

406
main/assets.cc Normal file
View File

@@ -0,0 +1,406 @@
#include "assets.h"
#include "board.h"
#include "display.h"
#include "application.h"
#include "lvgl_theme.h"
#include <esp_log.h>
#include <spi_flash_mmap.h>
#include <esp_timer.h>
#include <cbin_font.h>
#define TAG "Assets"
struct mmap_assets_table {
char asset_name[32]; /*!< Name of the asset */
uint32_t asset_size; /*!< Size of the asset */
uint32_t asset_offset; /*!< Offset of the asset */
uint16_t asset_width; /*!< Width of the asset */
uint16_t asset_height; /*!< Height of the asset */
};
Assets::Assets(std::string default_assets_url) {
if (default_assets_url.find("http") == 0) {
default_assets_url_ = default_assets_url;
} else {
ESP_LOGE(TAG, "The default assets url is not a http url: %s", default_assets_url.c_str());
}
// Initialize the partition
InitializePartition();
}
Assets::~Assets() {
if (mmap_handle_ != 0) {
esp_partition_munmap(mmap_handle_);
}
}
uint32_t Assets::CalculateChecksum(const char* data, uint32_t length) {
uint32_t checksum = 0;
for (uint32_t i = 0; i < length; i++) {
checksum += data[i];
}
return checksum & 0xFFFF;
}
bool Assets::InitializePartition() {
partition_valid_ = false;
checksum_valid_ = false;
assets_.clear();
partition_ = esp_partition_find_first(ESP_PARTITION_TYPE_ANY, ESP_PARTITION_SUBTYPE_ANY, "assets");
if (partition_ == nullptr) {
ESP_LOGI(TAG, "No assets partition found");
return false;
}
int free_pages = spi_flash_mmap_get_free_pages(SPI_FLASH_MMAP_DATA);
uint32_t storage_size = free_pages * 64 * 1024;
ESP_LOGI(TAG, "The storage free size is %ld KB", storage_size / 1024);
ESP_LOGI(TAG, "The partition size is %ld KB", partition_->size / 1024);
if (storage_size < partition_->size) {
ESP_LOGE(TAG, "The free size %ld KB is less than assets partition required %ld KB", storage_size / 1024, partition_->size / 1024);
return false;
}
esp_err_t err = esp_partition_mmap(partition_, 0, partition_->size, ESP_PARTITION_MMAP_DATA, (const void**)&mmap_root_, &mmap_handle_);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to mmap assets partition: %s", esp_err_to_name(err));
return false;
}
partition_valid_ = true;
uint32_t stored_files = *(uint32_t*)(mmap_root_ + 0);
uint32_t stored_chksum = *(uint32_t*)(mmap_root_ + 4);
uint32_t stored_len = *(uint32_t*)(mmap_root_ + 8);
if (stored_len > partition_->size - 12) {
ESP_LOGD(TAG, "The stored_len (0x%lx) is greater than the partition size (0x%lx) - 12", stored_len, partition_->size);
return false;
}
auto start_time = esp_timer_get_time();
uint32_t calculated_checksum = CalculateChecksum(mmap_root_ + 12, stored_len);
auto end_time = esp_timer_get_time();
ESP_LOGI(TAG, "The checksum calculation time is %d ms", int((end_time - start_time) / 1000));
if (calculated_checksum != stored_chksum) {
ESP_LOGE(TAG, "The calculated checksum (0x%lx) does not match the stored checksum (0x%lx)", calculated_checksum, stored_chksum);
return false;
}
checksum_valid_ = true;
for (uint32_t i = 0; i < stored_files; i++) {
auto item = (const mmap_assets_table*)(mmap_root_ + 12 + i * sizeof(mmap_assets_table));
auto asset = Asset{
.size = static_cast<size_t>(item->asset_size),
.offset = static_cast<size_t>(12 + sizeof(mmap_assets_table) * stored_files + item->asset_offset)
};
assets_[item->asset_name] = asset;
}
return checksum_valid_;
}
bool Assets::Apply() {
void* ptr = nullptr;
size_t size = 0;
if (!GetAssetData("index.json", ptr, size)) {
ESP_LOGE(TAG, "The index.json file is not found");
return false;
}
cJSON* root = cJSON_ParseWithLength(static_cast<char*>(ptr), size);
if (root == nullptr) {
ESP_LOGE(TAG, "The index.json file is not valid");
return false;
}
cJSON* version = cJSON_GetObjectItem(root, "version");
if (cJSON_IsNumber(version)) {
if (version->valuedouble > 1) {
ESP_LOGE(TAG, "The assets version %d is not supported, please upgrade the firmware", version->valueint);
return false;
}
}
cJSON* srmodels = cJSON_GetObjectItem(root, "srmodels");
if (cJSON_IsString(srmodels)) {
std::string srmodels_file = srmodels->valuestring;
if (GetAssetData(srmodels_file, ptr, size)) {
if (models_list_ != nullptr) {
esp_srmodel_deinit(models_list_);
models_list_ = nullptr;
}
models_list_ = srmodel_load(static_cast<uint8_t*>(ptr));
if (models_list_ != nullptr) {
auto& app = Application::GetInstance();
app.GetAudioService().SetModelsList(models_list_);
} else {
ESP_LOGE(TAG, "Failed to load srmodels.bin");
}
} else {
ESP_LOGE(TAG, "The srmodels file %s is not found", srmodels_file.c_str());
}
}
#ifdef HAVE_LVGL
auto& theme_manager = LvglThemeManager::GetInstance();
auto light_theme = theme_manager.GetTheme("light");
auto dark_theme = theme_manager.GetTheme("dark");
cJSON* font = cJSON_GetObjectItem(root, "text_font");
if (cJSON_IsString(font)) {
std::string fonts_text_file = font->valuestring;
if (GetAssetData(fonts_text_file, ptr, size)) {
auto text_font = std::make_shared<LvglCBinFont>(ptr);
if (text_font->font() == nullptr) {
ESP_LOGE(TAG, "Failed to load fonts.bin");
return false;
}
if (light_theme != nullptr) {
light_theme->set_text_font(text_font);
}
if (dark_theme != nullptr) {
dark_theme->set_text_font(text_font);
}
} else {
ESP_LOGE(TAG, "The font file %s is not found", fonts_text_file.c_str());
}
}
cJSON* emoji_collection = cJSON_GetObjectItem(root, "emoji_collection");
if (cJSON_IsArray(emoji_collection)) {
auto custom_emoji_collection = std::make_shared<EmojiCollection>();
int emoji_count = cJSON_GetArraySize(emoji_collection);
for (int i = 0; i < emoji_count; i++) {
cJSON* emoji = cJSON_GetArrayItem(emoji_collection, i);
if (cJSON_IsObject(emoji)) {
cJSON* name = cJSON_GetObjectItem(emoji, "name");
cJSON* file = cJSON_GetObjectItem(emoji, "file");
if (cJSON_IsString(name) && cJSON_IsString(file)) {
if (!GetAssetData(file->valuestring, ptr, size)) {
ESP_LOGE(TAG, "Emoji %s image file %s is not found", name->valuestring, file->valuestring);
continue;
}
custom_emoji_collection->AddEmoji(name->valuestring, new LvglRawImage(ptr, size));
}
}
}
if (light_theme != nullptr) {
light_theme->set_emoji_collection(custom_emoji_collection);
}
if (dark_theme != nullptr) {
dark_theme->set_emoji_collection(custom_emoji_collection);
}
}
cJSON* skin = cJSON_GetObjectItem(root, "skin");
if (cJSON_IsObject(skin)) {
cJSON* light_skin = cJSON_GetObjectItem(skin, "light");
if (cJSON_IsObject(light_skin) && light_theme != nullptr) {
cJSON* text_color = cJSON_GetObjectItem(light_skin, "text_color");
cJSON* background_color = cJSON_GetObjectItem(light_skin, "background_color");
cJSON* background_image = cJSON_GetObjectItem(light_skin, "background_image");
if (cJSON_IsString(text_color)) {
light_theme->set_text_color(LvglTheme::ParseColor(text_color->valuestring));
}
if (cJSON_IsString(background_color)) {
light_theme->set_background_color(LvglTheme::ParseColor(background_color->valuestring));
light_theme->set_chat_background_color(LvglTheme::ParseColor(background_color->valuestring));
}
if (cJSON_IsString(background_image)) {
if (!GetAssetData(background_image->valuestring, ptr, size)) {
ESP_LOGE(TAG, "The background image file %s is not found", background_image->valuestring);
return false;
}
auto background_image = std::make_shared<LvglCBinImage>(ptr);
light_theme->set_background_image(background_image);
}
}
cJSON* dark_skin = cJSON_GetObjectItem(skin, "dark");
if (cJSON_IsObject(dark_skin) && dark_theme != nullptr) {
cJSON* text_color = cJSON_GetObjectItem(dark_skin, "text_color");
cJSON* background_color = cJSON_GetObjectItem(dark_skin, "background_color");
cJSON* background_image = cJSON_GetObjectItem(dark_skin, "background_image");
if (cJSON_IsString(text_color)) {
dark_theme->set_text_color(LvglTheme::ParseColor(text_color->valuestring));
}
if (cJSON_IsString(background_color)) {
dark_theme->set_background_color(LvglTheme::ParseColor(background_color->valuestring));
dark_theme->set_chat_background_color(LvglTheme::ParseColor(background_color->valuestring));
}
if (cJSON_IsString(background_image)) {
if (!GetAssetData(background_image->valuestring, ptr, size)) {
ESP_LOGE(TAG, "The background image file %s is not found", background_image->valuestring);
return false;
}
auto background_image = std::make_shared<LvglCBinImage>(ptr);
dark_theme->set_background_image(background_image);
}
}
}
#endif
auto display = Board::GetInstance().GetDisplay();
ESP_LOGI(TAG, "Refreshing display theme...");
auto current_theme = display->GetTheme();
if (current_theme != nullptr) {
display->SetTheme(current_theme);
}
cJSON_Delete(root);
return true;
}
bool Assets::Download(std::string url, std::function<void(int progress, size_t speed)> progress_callback) {
ESP_LOGI(TAG, "Downloading new version of assets from %s", url.c_str());
// 取消当前资源分区的内存映射
if (mmap_handle_ != 0) {
esp_partition_munmap(mmap_handle_);
mmap_handle_ = 0;
mmap_root_ = nullptr;
}
checksum_valid_ = false;
assets_.clear();
// 下载新的资源文件
auto network = Board::GetInstance().GetNetwork();
auto http = network->CreateHttp(0);
if (!http->Open("GET", url)) {
ESP_LOGE(TAG, "Failed to open HTTP connection");
return false;
}
if (http->GetStatusCode() != 200) {
ESP_LOGE(TAG, "Failed to get assets, status code: %d", http->GetStatusCode());
return false;
}
size_t content_length = http->GetBodyLength();
if (content_length == 0) {
ESP_LOGE(TAG, "Failed to get content length");
return false;
}
if (content_length > partition_->size) {
ESP_LOGE(TAG, "Assets file size (%u) is larger than partition size (%lu)", content_length, partition_->size);
return false;
}
// 定义扇区大小为4KBESP32的标准扇区大小
const size_t SECTOR_SIZE = esp_partition_get_main_flash_sector_size();
// 计算需要擦除的扇区数量
size_t sectors_to_erase = (content_length + SECTOR_SIZE - 1) / SECTOR_SIZE; // 向上取整
size_t total_erase_size = sectors_to_erase * SECTOR_SIZE;
ESP_LOGI(TAG, "Sector size: %u, content length: %u, sectors to erase: %u, total erase size: %u",
SECTOR_SIZE, content_length, sectors_to_erase, total_erase_size);
// 写入新的资源文件到分区一边erase一边写入
char buffer[512];
size_t total_written = 0;
size_t recent_written = 0;
size_t current_sector = 0;
auto last_calc_time = esp_timer_get_time();
while (true) {
int ret = http->Read(buffer, sizeof(buffer));
if (ret < 0) {
ESP_LOGE(TAG, "Failed to read HTTP data: %s", esp_err_to_name(ret));
return false;
}
if (ret == 0) {
break;
}
// 检查是否需要擦除新的扇区
size_t write_end_offset = total_written + ret;
size_t needed_sectors = (write_end_offset + SECTOR_SIZE - 1) / SECTOR_SIZE;
// 擦除需要的新扇区
while (current_sector < needed_sectors) {
size_t sector_start = current_sector * SECTOR_SIZE;
size_t sector_end = (current_sector + 1) * SECTOR_SIZE;
// 确保擦除范围不超过分区大小
if (sector_end > partition_->size) {
ESP_LOGE(TAG, "Sector end (%u) exceeds partition size (%lu)", sector_end, partition_->size);
return false;
}
ESP_LOGD(TAG, "Erasing sector %u (offset: %u, size: %u)", current_sector, sector_start, SECTOR_SIZE);
esp_err_t err = esp_partition_erase_range(partition_, sector_start, SECTOR_SIZE);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to erase sector %u at offset %u: %s", current_sector, sector_start, esp_err_to_name(err));
return false;
}
current_sector++;
}
// 写入数据到分区
esp_err_t err = esp_partition_write(partition_, total_written, buffer, ret);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to write to assets partition at offset %u: %s", total_written, esp_err_to_name(err));
return false;
}
total_written += ret;
recent_written += ret;
// 计算进度和速度
if (esp_timer_get_time() - last_calc_time >= 1000000 || total_written == content_length || ret == 0) {
size_t progress = total_written * 100 / content_length;
size_t speed = recent_written; // 每秒的字节数
ESP_LOGI(TAG, "Progress: %u%% (%u/%u), Speed: %u B/s, Sectors erased: %u",
progress, total_written, content_length, speed, current_sector);
if (progress_callback) {
progress_callback(progress, speed);
}
last_calc_time = esp_timer_get_time();
recent_written = 0; // 重置最近写入的字节数
}
}
http->Close();
if (total_written != content_length) {
ESP_LOGE(TAG, "Downloaded size (%u) does not match expected size (%u)", total_written, content_length);
return false;
}
ESP_LOGI(TAG, "Assets download completed, total written: %u bytes, total sectors erased: %u",
total_written, current_sector);
// 重新初始化资源分区
if (!InitializePartition()) {
ESP_LOGE(TAG, "Failed to re-initialize assets partition");
return false;
}
return true;
}
bool Assets::GetAssetData(const std::string& name, void*& ptr, size_t& size) {
auto asset = assets_.find(name);
if (asset == assets_.end()) {
return false;
}
auto data = (const char*)(mmap_root_ + asset->second.offset);
if (data[0] != 'Z' || data[1] != 'Z') {
ESP_LOGE(TAG, "The asset %s is not valid with magic %02x%02x", name.c_str(), data[0], data[1]);
return false;
}
ptr = static_cast<void*>(const_cast<char*>(data + 2));
size = asset->second.size;
return true;
}

65
main/assets.h Normal file
View File

@@ -0,0 +1,65 @@
#ifndef ASSETS_H
#define ASSETS_H
#include <map>
#include <string>
#include <functional>
#include <cJSON.h>
#include <esp_partition.h>
#include <model_path.h>
// All combinations of wakenet_model, text_font, emoji_collection can be found from the following url:
// https://github.com/78/xiaozhi-fonts/releases/tag/assets
#define ASSETS_PUHUI_COMMON_14_1 "none-font_puhui_common_14_1-none.bin"
#define ASSETS_XIAOZHI_WAKENET "wn9_nihaoxiaozhi_tts-none-none.bin"
#define ASSETS_XIAOZHI_WAKENET_SMALL "wn9s_nihaoxiaozhi-none-none.bin"
#define ASSETS_XIAOZHI_PUHUI_COMMON_14_1 "wn9_nihaoxiaozhi_tts-font_puhui_common_14_1-none.bin"
#define ASSETS_XIAOZHI_PUHUI_COMMON_16_4_EMOJI_32 "wn9_nihaoxiaozhi_tts-font_puhui_common_16_4-emojis_32.bin"
#define ASSETS_XIAOZHI_PUHUI_COMMON_16_4_EMOJI_64 "wn9_nihaoxiaozhi_tts-font_puhui_common_16_4-emojis_64.bin"
#define ASSETS_XIAOZHI_PUHUI_COMMON_20_4_EMOJI_64 "wn9_nihaoxiaozhi_tts-font_puhui_common_20_4-emojis_64.bin"
#define ASSETS_XIAOZHI_PUHUI_COMMON_30_4_EMOJI_64 "wn9_nihaoxiaozhi_tts-font_puhui_common_30_4-emojis_64.bin"
#define ASSETS_XIAOZHI_S_PUHUI_COMMON_14_1 "wn9s_nihaoxiaozhi-font_puhui_common_14_1-none.bin"
#define ASSETS_XIAOZHI_S_PUHUI_COMMON_16_4_EMOJI_32 "wn9s_nihaoxiaozhi-font_puhui_common_16_4-emojis_32.bin"
#define ASSETS_XIAOZHI_S_PUHUI_COMMON_20_4_EMOJI_32 "wn9s_nihaoxiaozhi-font_puhui_common_20_4-emojis_32.bin"
#define ASSETS_XIAOZHI_S_PUHUI_COMMON_20_4_EMOJI_64 "wn9s_nihaoxiaozhi-font_puhui_common_20_4-emojis_64.bin"
#define ASSETS_XIAOZHI_S_PUHUI_COMMON_30_4_EMOJI_64 "wn9s_nihaoxiaozhi-font_puhui_common_30_4-emojis_64.bin"
struct Asset {
size_t size;
size_t offset;
};
class Assets {
public:
Assets(std::string default_assets_url);
~Assets();
bool Download(std::string url, std::function<void(int progress, size_t speed)> progress_callback);
bool Apply();
inline bool partition_valid() const { return partition_valid_; }
inline bool checksum_valid() const { return checksum_valid_; }
inline std::string default_assets_url() const { return default_assets_url_; }
private:
Assets(const Assets&) = delete;
Assets& operator=(const Assets&) = delete;
bool InitializePartition();
uint32_t CalculateChecksum(const char* data, uint32_t length);
bool GetAssetData(const std::string& name, void*& ptr, size_t& size);
const esp_partition_t* partition_ = nullptr;
esp_partition_mmap_handle_t mmap_handle_ = 0;
const char* mmap_root_ = nullptr;
bool partition_valid_ = false;
bool checksum_valid_ = false;
std::string default_assets_url_;
srmodel_list_t* models_list_ = nullptr;
std::map<std::string, Asset> assets_;
};
#endif

View File

@@ -28,17 +28,22 @@ namespace Lang {
constexpr const char* CONNECT_TO = "连接 "; constexpr const char* CONNECT_TO = "连接 ";
constexpr const char* CONNECT_TO_HOTSPOT = "手机连接热点 "; constexpr const char* CONNECT_TO_HOTSPOT = "手机连接热点 ";
constexpr const char* DETECTING_MODULE = "检测模组..."; constexpr const char* DETECTING_MODULE = "检测模组...";
constexpr const char* DOWNLOAD_ASSETS_FAILED = "下载资源失败";
constexpr const char* ENTERING_WIFI_CONFIG_MODE = "进入配网模式..."; constexpr const char* ENTERING_WIFI_CONFIG_MODE = "进入配网模式...";
constexpr const char* ERROR = "错误"; constexpr const char* ERROR = "错误";
constexpr const char* FOUND_NEW_ASSETS = "发现新资源: %s";
constexpr const char* HELLO_MY_FRIEND = "你好,我的朋友!";
constexpr const char* INFO = "信息"; constexpr const char* INFO = "信息";
constexpr const char* INITIALIZING = "正在初始化..."; constexpr const char* INITIALIZING = "正在初始化...";
constexpr const char* LISTENING = "聆听中..."; constexpr const char* LISTENING = "聆听中...";
constexpr const char* LOADING_ASSETS = "加载资源...";
constexpr const char* LOADING_PROTOCOL = "登录服务器..."; constexpr const char* LOADING_PROTOCOL = "登录服务器...";
constexpr const char* MAX_VOLUME = "最大音量"; constexpr const char* MAX_VOLUME = "最大音量";
constexpr const char* MUTED = "已静音"; constexpr const char* MUTED = "已静音";
constexpr const char* NEW_VERSION = "新版本 "; constexpr const char* NEW_VERSION = "新版本 ";
constexpr const char* OTA_UPGRADE = "OTA 升级"; constexpr const char* OTA_UPGRADE = "OTA 升级";
constexpr const char* PIN_ERROR = "请插入 SIM 卡"; constexpr const char* PIN_ERROR = "请插入 SIM 卡";
constexpr const char* PLEASE_WAIT = "请稍候...";
constexpr const char* REGISTERING_NETWORK = "等待网络..."; constexpr const char* REGISTERING_NETWORK = "等待网络...";
constexpr const char* REG_ERROR = "无法接入网络,请检查流量卡状态"; constexpr const char* REG_ERROR = "无法接入网络,请检查流量卡状态";
constexpr const char* RTC_MODE_OFF = "AEC 关闭"; constexpr const char* RTC_MODE_OFF = "AEC 关闭";

View File

@@ -1,58 +1,55 @@
{ {
"language": { "language": {
"type" :"ar-SA" "type": "ar-SA"
}, },
"strings": { "strings": {
"WARNING":"تحذير", "WARNING": "تحذير",
"INFO":"معلومات", "INFO": "معلومات",
"ERROR":"خطأ", "ERROR": "خطأ",
"VERSION": "الإصدار ", "VERSION": "الإصدار ",
"LOADING_PROTOCOL":"الاتصال بالخادم...", "LOADING_PROTOCOL": "الاتصال بالخادم...",
"INITIALIZING":"التهيئة...", "INITIALIZING": "التهيئة...",
"PIN_ERROR":"يرجى إدخال بطاقة SIM", "PIN_ERROR": "يرجى إدخال بطاقة SIM",
"REG_ERROR":"لا يمكن الوصول إلى الشبكة، يرجى التحقق من حالة بطاقة البيانات", "REG_ERROR": "لا يمكن الوصول إلى الشبكة، يرجى التحقق من حالة بطاقة البيانات",
"DETECTING_MODULE":"اكتشاف الوحدة...", "DETECTING_MODULE": "اكتشاف الوحدة...",
"REGISTERING_NETWORK":"انتظار الشبكة...", "REGISTERING_NETWORK": "انتظار الشبكة...",
"CHECKING_NEW_VERSION":"فحص الإصدار الجديد...", "CHECKING_NEW_VERSION": "فحص الإصدار الجديد...",
"CHECK_NEW_VERSION_FAILED":"فشل فحص الإصدار الجديد، سيتم المحاولة خلال %d ثانية: %s", "CHECK_NEW_VERSION_FAILED": "فشل فحص الإصدار الجديد، سيتم المحاولة خلال %d ثانية: %s",
"SWITCH_TO_WIFI_NETWORK":"التبديل إلى Wi-Fi...", "SWITCH_TO_WIFI_NETWORK": "التبديل إلى Wi-Fi...",
"SWITCH_TO_4G_NETWORK":"التبديل إلى 4G...", "SWITCH_TO_4G_NETWORK": "التبديل إلى 4G...",
"STANDBY": "في الانتظار",
"STANDBY":"في الانتظار", "CONNECT_TO": "الاتصال بـ ",
"CONNECT_TO":"الاتصال بـ ", "CONNECTING": "جاري الاتصال...",
"CONNECTING":"جاري الاتصال...", "CONNECTED_TO": "متصل بـ ",
"CONNECTED_TO":"متصل بـ ", "LISTENING": "الاستماع...",
"SPEAKING": "التحدث...",
"LISTENING":"الاستماع...", "SERVER_NOT_FOUND": "البحث عن خدمة متاحة",
"SPEAKING":"التحدث...", "SERVER_NOT_CONNECTED": "لا يمكن الاتصال بالخدمة، يرجى المحاولة لاحقاً",
"SERVER_TIMEOUT": "انتهت مهلة الاستجابة",
"SERVER_NOT_FOUND":"البحث عن خدمة متاحة", "SERVER_ERROR": "فشل الإرسال، يرجى التحقق من الشبكة",
"SERVER_NOT_CONNECTED":ا يمكن الاتصال بالخدمة، يرجى المحاولة لاحقاً", "CONNECT_TO_HOTSPOT": "اتصل الهاتف بنقطة الاتصال ",
"SERVER_TIMEOUT":"انتهت مهلة الاستجابة", "ACCESS_VIA_BROWSER": "،الوصول عبر المتصفح ",
"SERVER_ERROR":"فشل الإرسال، يرجى التحقق من الشبكة", "WIFI_CONFIG_MODE": "وضع تكوين الشبكة",
"ENTERING_WIFI_CONFIG_MODE": "الدخول في وضع تكوين الشبكة...",
"CONNECT_TO_HOTSPOT":"اتصل الهاتف بنقطة الاتصال ", "SCANNING_WIFI": "فحص Wi-Fi...",
"ACCESS_VIA_BROWSER":"،الوصول عبر المتصفح ",
"WIFI_CONFIG_MODE":"وضع تكوين الشبكة",
"ENTERING_WIFI_CONFIG_MODE":"الدخول في وضع تكوين الشبكة...",
"SCANNING_WIFI":"فحص Wi-Fi...",
"NEW_VERSION": "إصدار جديد ", "NEW_VERSION": "إصدار جديد ",
"OTA_UPGRADE":"تحديث OTA", "OTA_UPGRADE": "تحديث OTA",
"UPGRADING":"تحديث النظام...", "UPGRADING": "تحديث النظام...",
"UPGRADE_FAILED":"فشل التحديث", "UPGRADE_FAILED": "فشل التحديث",
"ACTIVATION":"تفعيل الجهاز", "ACTIVATION": "تفعيل الجهاز",
"BATTERY_LOW": "البطارية منخفضة",
"BATTERY_LOW":"البطارية منخفضة", "BATTERY_CHARGING": "جاري الشحن",
"BATTERY_CHARGING":"جاري الشحن", "BATTERY_FULL": "البطارية ممتلئة",
"BATTERY_FULL":"البطارية ممتلئة", "BATTERY_NEED_CHARGE": "البطارية منخفضة، يرجى الشحن",
"BATTERY_NEED_CHARGE":"البطارية منخفضة، يرجى الشحن", "VOLUME": "الصوت ",
"MUTED": "صامت",
"VOLUME":"الصوت ", "MAX_VOLUME": "أقصى صوت",
"MUTED":"صامت", "RTC_MODE_OFF": "AEC مُوقف",
"MAX_VOLUME":"أقصى صوت", "RTC_MODE_ON": "AEC مُشغل",
"DOWNLOAD_ASSETS_FAILED": "فشل في تنزيل الموارد",
"RTC_MODE_OFF":"AEC مُوقف", "LOADING_ASSETS": "جاري تحميل الموارد...",
"RTC_MODE_ON":"AEC مُشغل" "PLEASE_WAIT": "يرجى الانتظار...",
"FOUND_NEW_ASSETS": "تم العثور على موارد جديدة: %s",
"HELLO_MY_FRIEND": "مرحباً، صديقي!"
} }
} }

View File

@@ -1,58 +1,55 @@
{ {
"language": { "language": {
"type" :"cs-CZ" "type": "cs-CZ"
}, },
"strings": { "strings": {
"WARNING":"Varování", "WARNING": "Varování",
"INFO":"Informace", "INFO": "Informace",
"ERROR":"Chyba", "ERROR": "Chyba",
"VERSION": "Verze ", "VERSION": "Verze ",
"LOADING_PROTOCOL":"Připojování k serveru...", "LOADING_PROTOCOL": "Připojování k serveru...",
"INITIALIZING":"Inicializace...", "INITIALIZING": "Inicializace...",
"PIN_ERROR":"Prosím vložte SIM kartu", "PIN_ERROR": "Prosím vložte SIM kartu",
"REG_ERROR":"Nelze se připojit k síti, zkontrolujte stav datové karty", "REG_ERROR": "Nelze se připojit k síti, zkontrolujte stav datové karty",
"DETECTING_MODULE":"Detekce modulu...", "DETECTING_MODULE": "Detekce modulu...",
"REGISTERING_NETWORK":"Čekání na síť...", "REGISTERING_NETWORK": "Čekání na síť...",
"CHECKING_NEW_VERSION":"Kontrola nové verze...", "CHECKING_NEW_VERSION": "Kontrola nové verze...",
"CHECK_NEW_VERSION_FAILED":"Kontrola nové verze selhala, opakování za %d sekund: %s", "CHECK_NEW_VERSION_FAILED": "Kontrola nové verze selhala, opakování za %d sekund: %s",
"SWITCH_TO_WIFI_NETWORK":"Přepínání na Wi-Fi...", "SWITCH_TO_WIFI_NETWORK": "Přepínání na Wi-Fi...",
"SWITCH_TO_4G_NETWORK":"Přepínání na 4G...", "SWITCH_TO_4G_NETWORK": "Přepínání na 4G...",
"STANDBY": "Pohotovost",
"STANDBY":"Pohotovost", "CONNECT_TO": "Připojit k ",
"CONNECT_TO":"Připojit k ", "CONNECTING": "Připojování...",
"CONNECTING":"Připojování...", "CONNECTED_TO": "Připojeno k ",
"CONNECTED_TO":"Připojeno k ", "LISTENING": "Naslouchání...",
"SPEAKING": "Mluvení...",
"LISTENING":"Naslouchání...", "SERVER_NOT_FOUND": "Hledání dostupné služby",
"SPEAKING":"Mluvení...", "SERVER_NOT_CONNECTED": "Nelze se připojit ke službě, zkuste to později",
"SERVER_TIMEOUT": "Čas odpovědi vypršel",
"SERVER_NOT_FOUND":"Hledání dostupné služby", "SERVER_ERROR": "Odeslání selhalo, zkontrolujte síť",
"SERVER_NOT_CONNECTED":"Nelze se připojit ke službě, zkuste to později", "CONNECT_TO_HOTSPOT": "Připojte telefon k hotspotu ",
"SERVER_TIMEOUT":"Čas odpovědi vypršel", "ACCESS_VIA_BROWSER": "přístup přes prohlížeč ",
"SERVER_ERROR":"Odeslání selhalo, zkontrolujte síť", "WIFI_CONFIG_MODE": "Režim konfigurace sí",
"ENTERING_WIFI_CONFIG_MODE": "Vstup do režimu konfigurace sítě...",
"CONNECT_TO_HOTSPOT":"Připojte telefon k hotspotu ", "SCANNING_WIFI": "Skenování Wi-Fi...",
"ACCESS_VIA_BROWSER":"přístup přes prohlížeč ",
"WIFI_CONFIG_MODE":"Režim konfigurace sítě",
"ENTERING_WIFI_CONFIG_MODE":"Vstup do režimu konfigurace sítě...",
"SCANNING_WIFI":"Skenování Wi-Fi...",
"NEW_VERSION": "Nová verze ", "NEW_VERSION": "Nová verze ",
"OTA_UPGRADE":"OTA upgrade", "OTA_UPGRADE": "OTA upgrade",
"UPGRADING":"Aktualizace systému...", "UPGRADING": "Aktualizace systému...",
"UPGRADE_FAILED":"Upgrade selhal", "UPGRADE_FAILED": "Upgrade selhal",
"ACTIVATION":"Aktivace zařízení", "ACTIVATION": "Aktivace zařízení",
"BATTERY_LOW": "Slabá baterie",
"BATTERY_LOW":"Slabá baterie", "BATTERY_CHARGING": "Nabíjení",
"BATTERY_CHARGING":"Nabíjení", "BATTERY_FULL": "Baterie plná",
"BATTERY_FULL":"Baterie plná", "BATTERY_NEED_CHARGE": "Slabá baterie, prosím nabijte",
"BATTERY_NEED_CHARGE":"Slabá baterie, prosím nabijte", "VOLUME": "Hlasitost ",
"MUTED": "Ztlumeno",
"VOLUME":"Hlasitost ", "MAX_VOLUME": "Maximální hlasitost",
"MUTED":"Ztlumeno", "RTC_MODE_OFF": "AEC vypnuto",
"MAX_VOLUME":"Maximální hlasitost", "RTC_MODE_ON": "AEC zapnuto",
"DOWNLOAD_ASSETS_FAILED": "Nepodařilo se stáhnout prostředky",
"RTC_MODE_OFF":"AEC vypnuto", "LOADING_ASSETS": "Načítání prostředků...",
"RTC_MODE_ON":"AEC zapnuto" "PLEASE_WAIT": "Prosím čekejte...",
"FOUND_NEW_ASSETS": "Nalezeny nové prostředky: %s",
"HELLO_MY_FRIEND": "Ahoj, můj příteli!"
} }
} }

View File

@@ -1,58 +1,55 @@
{ {
"language": { "language": {
"type" :"de-DE" "type": "de-DE"
}, },
"strings": { "strings": {
"WARNING":"Warnung", "WARNING": "Warnung",
"INFO":"Information", "INFO": "Information",
"ERROR":"Fehler", "ERROR": "Fehler",
"VERSION": "Version ", "VERSION": "Version ",
"LOADING_PROTOCOL":"Verbindung zum Server...", "LOADING_PROTOCOL": "Verbindung zum Server...",
"INITIALIZING":"Initialisierung...", "INITIALIZING": "Initialisierung...",
"PIN_ERROR":"Bitte SIM-Karte einlegen", "PIN_ERROR": "Bitte SIM-Karte einlegen",
"REG_ERROR":"Netzwerkverbindung fehlgeschlagen, bitte Datenkartenstatus prüfen", "REG_ERROR": "Netzwerkverbindung fehlgeschlagen, bitte Datenkartenstatus prüfen",
"DETECTING_MODULE":"Modul erkennen...", "DETECTING_MODULE": "Modul erkennen...",
"REGISTERING_NETWORK":"Auf Netzwerk warten...", "REGISTERING_NETWORK": "Auf Netzwerk warten...",
"CHECKING_NEW_VERSION":"Neue Version prüfen...", "CHECKING_NEW_VERSION": "Neue Version prüfen...",
"CHECK_NEW_VERSION_FAILED":"Neue Version prüfen fehlgeschlagen, Wiederholung in %d Sekunden: %s", "CHECK_NEW_VERSION_FAILED": "Neue Version prüfen fehlgeschlagen, Wiederholung in %d Sekunden: %s",
"SWITCH_TO_WIFI_NETWORK":"Zu Wi-Fi wechseln...", "SWITCH_TO_WIFI_NETWORK": "Zu Wi-Fi wechseln...",
"SWITCH_TO_4G_NETWORK":"Zu 4G wechseln...", "SWITCH_TO_4G_NETWORK": "Zu 4G wechseln...",
"STANDBY": "Bereitschaft",
"STANDBY":"Bereitschaft", "CONNECT_TO": "Verbinden zu ",
"CONNECT_TO":"Verbinden zu ", "CONNECTING": "Verbindung wird hergestellt...",
"CONNECTING":"Verbindung wird hergestellt...", "CONNECTED_TO": "Verbunden mit ",
"CONNECTED_TO":"Verbunden mit ", "LISTENING": "Zuhören...",
"SPEAKING": "Sprechen...",
"LISTENING":"Zuhören...", "SERVER_NOT_FOUND": "Verfügbaren Service suchen",
"SPEAKING":"Sprechen...", "SERVER_NOT_CONNECTED": "Service-Verbindung fehlgeschlagen, bitte später versuchen",
"SERVER_TIMEOUT": "Antwort-Timeout",
"SERVER_NOT_FOUND":"Verfügbaren Service suchen", "SERVER_ERROR": "Senden fehlgeschlagen, bitte Netzwerk prüfen",
"SERVER_NOT_CONNECTED":"Service-Verbindung fehlgeschlagen, bitte später versuchen", "CONNECT_TO_HOTSPOT": "Handy mit Hotspot verbinden ",
"SERVER_TIMEOUT":"Antwort-Timeout", "ACCESS_VIA_BROWSER": "Browser öffnen ",
"SERVER_ERROR":"Senden fehlgeschlagen, bitte Netzwerk prüfen", "WIFI_CONFIG_MODE": "Netzwerkkonfigurationsmodus",
"ENTERING_WIFI_CONFIG_MODE": "Netzwerkkonfigurationsmodus eingeben...",
"CONNECT_TO_HOTSPOT":"Handy mit Hotspot verbinden ", "SCANNING_WIFI": "Wi-Fi scannen...",
"ACCESS_VIA_BROWSER":"Browser öffnen ",
"WIFI_CONFIG_MODE":"Netzwerkkonfigurationsmodus",
"ENTERING_WIFI_CONFIG_MODE":"Netzwerkkonfigurationsmodus eingeben...",
"SCANNING_WIFI":"Wi-Fi scannen...",
"NEW_VERSION": "Neue Version ", "NEW_VERSION": "Neue Version ",
"OTA_UPGRADE":"OTA-Upgrade", "OTA_UPGRADE": "OTA-Upgrade",
"UPGRADING":"System wird aktualisiert...", "UPGRADING": "System wird aktualisiert...",
"UPGRADE_FAILED":"Upgrade fehlgeschlagen", "UPGRADE_FAILED": "Upgrade fehlgeschlagen",
"ACTIVATION":"Gerät aktivieren", "ACTIVATION": "Gerät aktivieren",
"BATTERY_LOW": "Niedriger Batteriestand",
"BATTERY_LOW":"Niedriger Batteriestand", "BATTERY_CHARGING": "Wird geladen",
"BATTERY_CHARGING":"Wird geladen", "BATTERY_FULL": "Batterie voll",
"BATTERY_FULL":"Batterie voll", "BATTERY_NEED_CHARGE": "Niedriger Batteriestand, bitte aufladen",
"BATTERY_NEED_CHARGE":"Niedriger Batteriestand, bitte aufladen", "VOLUME": "Lautstärke ",
"MUTED": "Stummgeschaltet",
"VOLUME":"Lautstärke ", "MAX_VOLUME": "Maximale Lautstärke",
"MUTED":"Stummgeschaltet", "RTC_MODE_OFF": "AEC aus",
"MAX_VOLUME":"Maximale Lautstärke", "RTC_MODE_ON": "AEC ein",
"DOWNLOAD_ASSETS_FAILED": "Fehler beim Herunterladen der Ressourcen",
"RTC_MODE_OFF":"AEC aus", "LOADING_ASSETS": "Ressourcen werden geladen...",
"RTC_MODE_ON":"AEC ein" "PLEASE_WAIT": "Bitte warten...",
"FOUND_NEW_ASSETS": "Neue Ressourcen gefunden: %s",
"HELLO_MY_FRIEND": "Hallo, mein Freund!"
} }
} }

View File

@@ -17,43 +17,40 @@
"CHECK_NEW_VERSION_FAILED": "Check for new version failed, will retry in %d seconds: %s", "CHECK_NEW_VERSION_FAILED": "Check for new version failed, will retry in %d seconds: %s",
"SWITCH_TO_WIFI_NETWORK": "Switching to Wi-Fi...", "SWITCH_TO_WIFI_NETWORK": "Switching to Wi-Fi...",
"SWITCH_TO_4G_NETWORK": "Switching to 4G...", "SWITCH_TO_4G_NETWORK": "Switching to 4G...",
"STANDBY": "Standby", "STANDBY": "Standby",
"CONNECT_TO": "Connect to ", "CONNECT_TO": "Connect to ",
"CONNECTING": "Connecting...", "CONNECTING": "Connecting...",
"CONNECTION_SUCCESSFUL": "Connection Successful", "CONNECTION_SUCCESSFUL": "Connection Successful",
"CONNECTED_TO": "Connected to ", "CONNECTED_TO": "Connected to ",
"LISTENING": "Listening...", "LISTENING": "Listening...",
"SPEAKING": "Speaking...", "SPEAKING": "Speaking...",
"SERVER_NOT_FOUND": "Looking for available service", "SERVER_NOT_FOUND": "Looking for available service",
"SERVER_NOT_CONNECTED": "Unable to connect to service, please try again later", "SERVER_NOT_CONNECTED": "Unable to connect to service, please try again later",
"SERVER_TIMEOUT": "Waiting for response timeout", "SERVER_TIMEOUT": "Waiting for response timeout",
"SERVER_ERROR": "Sending failed, please check the network", "SERVER_ERROR": "Sending failed, please check the network",
"CONNECT_TO_HOTSPOT": "Hotspot: ", "CONNECT_TO_HOTSPOT": "Hotspot: ",
"ACCESS_VIA_BROWSER": " Config URL: ", "ACCESS_VIA_BROWSER": " Config URL: ",
"WIFI_CONFIG_MODE": "Wi-Fi Configuration Mode", "WIFI_CONFIG_MODE": "Wi-Fi Configuration Mode",
"ENTERING_WIFI_CONFIG_MODE": "Entering Wi-Fi configuration mode...", "ENTERING_WIFI_CONFIG_MODE": "Entering Wi-Fi configuration mode...",
"SCANNING_WIFI": "Scanning Wi-Fi...", "SCANNING_WIFI": "Scanning Wi-Fi...",
"NEW_VERSION": "New version ", "NEW_VERSION": "New version ",
"OTA_UPGRADE": "OTA Upgrade", "OTA_UPGRADE": "OTA Upgrade",
"UPGRADING": "System is upgrading...", "UPGRADING": "System is upgrading...",
"UPGRADE_FAILED": "Upgrade failed", "UPGRADE_FAILED": "Upgrade failed",
"ACTIVATION": "Activation", "ACTIVATION": "Activation",
"BATTERY_LOW": "Low battery", "BATTERY_LOW": "Low battery",
"BATTERY_CHARGING": "Charging", "BATTERY_CHARGING": "Charging",
"BATTERY_FULL": "Battery full", "BATTERY_FULL": "Battery full",
"BATTERY_NEED_CHARGE": "Low battery, please charge", "BATTERY_NEED_CHARGE": "Low battery, please charge",
"VOLUME": "Volume ", "VOLUME": "Volume ",
"MUTED": "Muted", "MUTED": "Muted",
"MAX_VOLUME": "Max volume", "MAX_VOLUME": "Max volume",
"RTC_MODE_OFF": "AEC Off", "RTC_MODE_OFF": "AEC Off",
"RTC_MODE_ON": "AEC On" "RTC_MODE_ON": "AEC On",
"PLEASE_WAIT": "Please wait...",
"FOUND_NEW_ASSETS": "Found new assets: %s",
"DOWNLOAD_ASSETS_FAILED": "Failed to download assets",
"LOADING_ASSETS": "Loading assets...",
"HELLO_MY_FRIEND": "Hello, my friend!"
} }
} }

View File

@@ -1,58 +1,55 @@
{ {
"language": { "language": {
"type" :"es-ES" "type": "es-ES"
}, },
"strings": { "strings": {
"WARNING":"Advertencia", "WARNING": "Advertencia",
"INFO":"Información", "INFO": "Información",
"ERROR":"Error", "ERROR": "Error",
"VERSION": "Versión ", "VERSION": "Versión ",
"LOADING_PROTOCOL":"Conectando al servidor...", "LOADING_PROTOCOL": "Conectando al servidor...",
"INITIALIZING":"Inicializando...", "INITIALIZING": "Inicializando...",
"PIN_ERROR":"Por favor inserte la tarjeta SIM", "PIN_ERROR": "Por favor inserte la tarjeta SIM",
"REG_ERROR":"No se puede acceder a la red, verifique el estado de la tarjeta de datos", "REG_ERROR": "No se puede acceder a la red, verifique el estado de la tarjeta de datos",
"DETECTING_MODULE":"Detectando módulo...", "DETECTING_MODULE": "Detectando módulo...",
"REGISTERING_NETWORK":"Esperando red...", "REGISTERING_NETWORK": "Esperando red...",
"CHECKING_NEW_VERSION":"Verificando nueva versión...", "CHECKING_NEW_VERSION": "Verificando nueva versión...",
"CHECK_NEW_VERSION_FAILED":"Error al verificar nueva versión, reintentando en %d segundos: %s", "CHECK_NEW_VERSION_FAILED": "Error al verificar nueva versión, reintentando en %d segundos: %s",
"SWITCH_TO_WIFI_NETWORK":"Cambiando a Wi-Fi...", "SWITCH_TO_WIFI_NETWORK": "Cambiando a Wi-Fi...",
"SWITCH_TO_4G_NETWORK":"Cambiando a 4G...", "SWITCH_TO_4G_NETWORK": "Cambiando a 4G...",
"STANDBY": "En espera",
"STANDBY":"En espera", "CONNECT_TO": "Conectar a ",
"CONNECT_TO":"Conectar a ", "CONNECTING": "Conectando...",
"CONNECTING":"Conectando...", "CONNECTED_TO": "Conectado a ",
"CONNECTED_TO":"Conectado a ", "LISTENING": "Escuchando...",
"SPEAKING": "Hablando...",
"LISTENING":"Escuchando...", "SERVER_NOT_FOUND": "Buscando servicio disponible",
"SPEAKING":"Hablando...", "SERVER_NOT_CONNECTED": "No se puede conectar al servicio, inténtelo más tarde",
"SERVER_TIMEOUT": "Tiempo de espera agotado",
"SERVER_NOT_FOUND":"Buscando servicio disponible", "SERVER_ERROR": "Error de envío, verifique la red",
"SERVER_NOT_CONNECTED":"No se puede conectar al servicio, inténtelo más tarde", "CONNECT_TO_HOTSPOT": "Conectar teléfono al punto de acceso ",
"SERVER_TIMEOUT":"Tiempo de espera agotado", "ACCESS_VIA_BROWSER": "acceder mediante navegador ",
"SERVER_ERROR":"Error de envío, verifique la red", "WIFI_CONFIG_MODE": "Modo configuración de red",
"ENTERING_WIFI_CONFIG_MODE": "Entrando en modo configuración de red...",
"CONNECT_TO_HOTSPOT":"Conectar teléfono al punto de acceso ", "SCANNING_WIFI": "Escaneando Wi-Fi...",
"ACCESS_VIA_BROWSER":"acceder mediante navegador ",
"WIFI_CONFIG_MODE":"Modo configuración de red",
"ENTERING_WIFI_CONFIG_MODE":"Entrando en modo configuración de red...",
"SCANNING_WIFI":"Escaneando Wi-Fi...",
"NEW_VERSION": "Nueva versión ", "NEW_VERSION": "Nueva versión ",
"OTA_UPGRADE":"Actualización OTA", "OTA_UPGRADE": "Actualización OTA",
"UPGRADING":"Actualizando sistema...", "UPGRADING": "Actualizando sistema...",
"UPGRADE_FAILED":"Actualización fallida", "UPGRADE_FAILED": "Actualización fallida",
"ACTIVATION":"Activación del dispositivo", "ACTIVATION": "Activación del dispositivo",
"BATTERY_LOW": "Batería baja",
"BATTERY_LOW":"Batería baja", "BATTERY_CHARGING": "Cargando",
"BATTERY_CHARGING":"Cargando", "BATTERY_FULL": "Batería llena",
"BATTERY_FULL":"Batería llena", "BATTERY_NEED_CHARGE": "Batería baja, por favor cargar",
"BATTERY_NEED_CHARGE":"Batería baja, por favor cargar", "VOLUME": "Volumen ",
"MUTED": "Silenciado",
"VOLUME":"Volumen ", "MAX_VOLUME": "Volumen máximo",
"MUTED":"Silenciado", "RTC_MODE_OFF": "AEC desactivado",
"MAX_VOLUME":"Volumen máximo", "RTC_MODE_ON": "AEC activado",
"DOWNLOAD_ASSETS_FAILED": "Error al descargar recursos",
"RTC_MODE_OFF":"AEC desactivado", "LOADING_ASSETS": "Cargando recursos...",
"RTC_MODE_ON":"AEC activado" "PLEASE_WAIT": "Por favor espere...",
"FOUND_NEW_ASSETS": "Encontrados nuevos recursos: %s",
"HELLO_MY_FRIEND": "¡Hola, mi amigo!"
} }
} }

View File

@@ -1,58 +1,55 @@
{ {
"language": { "language": {
"type" :"fi-FI" "type": "fi-FI"
}, },
"strings": { "strings": {
"WARNING":"Varoitus", "WARNING": "Varoitus",
"INFO":"Tieto", "INFO": "Tieto",
"ERROR":"Virhe", "ERROR": "Virhe",
"VERSION": "Versio ", "VERSION": "Versio ",
"LOADING_PROTOCOL":"Yhdistetään palvelimeen...", "LOADING_PROTOCOL": "Yhdistetään palvelimeen...",
"INITIALIZING":"Alustetaan...", "INITIALIZING": "Alustetaan...",
"PIN_ERROR":"Ole hyvä ja aseta SIM-kortti", "PIN_ERROR": "Ole hyvä ja aseta SIM-kortti",
"REG_ERROR":"Ei voi muodostaa yhteyttä verkkoon, tarkista datakortin tila", "REG_ERROR": "Ei voi muodostaa yhteyttä verkkoon, tarkista datakortin tila",
"DETECTING_MODULE":"Tunnistetaan moduuli...", "DETECTING_MODULE": "Tunnistetaan moduuli...",
"REGISTERING_NETWORK":"Odotetaan verkkoa...", "REGISTERING_NETWORK": "Odotetaan verkkoa...",
"CHECKING_NEW_VERSION":"Tarkistetaan uutta versiota...", "CHECKING_NEW_VERSION": "Tarkistetaan uutta versiota...",
"CHECK_NEW_VERSION_FAILED":"Uuden version tarkistus epäonnistui, yritetään uudelleen %d sekunnin kuluttua: %s", "CHECK_NEW_VERSION_FAILED": "Uuden version tarkistus epäonnistui, yritetään uudelleen %d sekunnin kuluttua: %s",
"SWITCH_TO_WIFI_NETWORK":"Vaihdetaan Wi-Fi:hin...", "SWITCH_TO_WIFI_NETWORK": "Vaihdetaan Wi-Fi:hin...",
"SWITCH_TO_4G_NETWORK":"Vaihdetaan 4G:hen...", "SWITCH_TO_4G_NETWORK": "Vaihdetaan 4G:hen...",
"STANDBY": "Valmiustila",
"STANDBY":"Valmiustila", "CONNECT_TO": "Yhdistä ",
"CONNECT_TO":"Yhdistä ", "CONNECTING": "Yhdistetään...",
"CONNECTING":"Yhdistetään...", "CONNECTED_TO": "Yhdistetty ",
"CONNECTED_TO":"Yhdistetty ", "LISTENING": "Kuunnellaan...",
"SPEAKING": "Puhutaan...",
"LISTENING":"Kuunnellaan...", "SERVER_NOT_FOUND": "Etsitään käytettävissä olevaa palvelua",
"SPEAKING":"Puhutaan...", "SERVER_NOT_CONNECTED": "Ei voi yhdistää palveluun, yritä myöhemmin",
"SERVER_TIMEOUT": "Vastauksen aikakatkaisu",
"SERVER_NOT_FOUND":"Etsitään käytettävissä olevaa palvelua", "SERVER_ERROR": "Lähetys epäonnistui, tarkista verkko",
"SERVER_NOT_CONNECTED":"Ei voi yhdistää palveluun, yritä myöhemmin", "CONNECT_TO_HOTSPOT": "Yhdistä puhelin hotspottiin ",
"SERVER_TIMEOUT":"Vastauksen aikakatkaisu", "ACCESS_VIA_BROWSER": "pääsy selaimen kautta ",
"SERVER_ERROR":"Lähetys epäonnistui, tarkista verkko", "WIFI_CONFIG_MODE": "Verkon konfigurointitila",
"ENTERING_WIFI_CONFIG_MODE": "Siirrytään verkon konfigurointitilaan...",
"CONNECT_TO_HOTSPOT":"Yhdistä puhelin hotspottiin ", "SCANNING_WIFI": "Skannataan Wi-Fi...",
"ACCESS_VIA_BROWSER":"pääsy selaimen kautta ",
"WIFI_CONFIG_MODE":"Verkon konfigurointitila",
"ENTERING_WIFI_CONFIG_MODE":"Siirrytään verkon konfigurointitilaan...",
"SCANNING_WIFI":"Skannataan Wi-Fi...",
"NEW_VERSION": "Uusi versio ", "NEW_VERSION": "Uusi versio ",
"OTA_UPGRADE":"OTA-päivitys", "OTA_UPGRADE": "OTA-päivitys",
"UPGRADING":"Päivitetään järjestelmää...", "UPGRADING": "Päivitetään järjestelmää...",
"UPGRADE_FAILED":"Päivitys epäonnistui", "UPGRADE_FAILED": "Päivitys epäonnistui",
"ACTIVATION":"Laitteen aktivointi", "ACTIVATION": "Laitteen aktivointi",
"BATTERY_LOW": "Akku vähissä",
"BATTERY_LOW":"Akku vähissä", "BATTERY_CHARGING": "Ladataan",
"BATTERY_CHARGING":"Ladataan", "BATTERY_FULL": "Akku täynnä",
"BATTERY_FULL":"Akku täynnä", "BATTERY_NEED_CHARGE": "Akku vähissä, ole hyvä ja lataa",
"BATTERY_NEED_CHARGE":"Akku vähissä, ole hyvä ja lataa", "VOLUME": "Äänenvoimakkuus ",
"MUTED": "Mykistetty",
"VOLUME":"Äänenvoimakkuus ", "MAX_VOLUME": "Maksimi äänenvoimakkuus",
"MUTED":"Mykistetty", "RTC_MODE_OFF": "AEC pois päältä",
"MAX_VOLUME":"Maksimi äänenvoimakkuus", "RTC_MODE_ON": "AEC päällä",
"DOWNLOAD_ASSETS_FAILED": "Resurssien lataaminen epäonnistui",
"RTC_MODE_OFF":"AEC pois päältä", "LOADING_ASSETS": "Ladataan resursseja...",
"RTC_MODE_ON":"AEC päällä" "PLEASE_WAIT": "Odota hetki...",
"FOUND_NEW_ASSETS": "Löydetty uusia resursseja: %s",
"HELLO_MY_FRIEND": "Hei, ystäväni!"
} }
} }

View File

@@ -1,58 +1,55 @@
{ {
"language": { "language": {
"type" :"fr-FR" "type": "fr-FR"
}, },
"strings": { "strings": {
"WARNING":"Avertissement", "WARNING": "Avertissement",
"INFO":"Information", "INFO": "Information",
"ERROR":"Erreur", "ERROR": "Erreur",
"VERSION": "Version ", "VERSION": "Version ",
"LOADING_PROTOCOL":"Connexion au serveur...", "LOADING_PROTOCOL": "Connexion au serveur...",
"INITIALIZING":"Initialisation...", "INITIALIZING": "Initialisation...",
"PIN_ERROR":"Veuillez insérer la carte SIM", "PIN_ERROR": "Veuillez insérer la carte SIM",
"REG_ERROR":"Impossible d'accéder au réseau, veuillez vérifier l'état de la carte de données", "REG_ERROR": "Impossible d'accéder au réseau, veuillez vérifier l'état de la carte de données",
"DETECTING_MODULE":"Détection du module...", "DETECTING_MODULE": "Détection du module...",
"REGISTERING_NETWORK":"En attente du réseau...", "REGISTERING_NETWORK": "En attente du réseau...",
"CHECKING_NEW_VERSION":"Vérification de nouvelle version...", "CHECKING_NEW_VERSION": "Vérification de nouvelle version...",
"CHECK_NEW_VERSION_FAILED":"Échec de vérification de nouvelle version, nouvelle tentative dans %d secondes : %s", "CHECK_NEW_VERSION_FAILED": "Échec de vérification de nouvelle version, nouvelle tentative dans %d secondes : %s",
"SWITCH_TO_WIFI_NETWORK":"Basculer vers Wi-Fi...", "SWITCH_TO_WIFI_NETWORK": "Basculer vers Wi-Fi...",
"SWITCH_TO_4G_NETWORK":"Basculer vers 4G...", "SWITCH_TO_4G_NETWORK": "Basculer vers 4G...",
"STANDBY": "En attente",
"STANDBY":"En attente", "CONNECT_TO": "Se connecter à ",
"CONNECT_TO":"Se connecter à ", "CONNECTING": "Connexion en cours...",
"CONNECTING":"Connexion en cours...", "CONNECTED_TO": "Connecté à ",
"CONNECTED_TO":"Connecté à ", "LISTENING": "Écoute...",
"SPEAKING": "Parole...",
"LISTENING":"Écoute...", "SERVER_NOT_FOUND": "Recherche d'un service disponible",
"SPEAKING":"Parole...", "SERVER_NOT_CONNECTED": "Impossible de se connecter au service, veuillez réessayer plus tard",
"SERVER_TIMEOUT": "Délai d'attente de réponse",
"SERVER_NOT_FOUND":"Recherche d'un service disponible", "SERVER_ERROR": "Échec d'envoi, veuillez vérifier le réseau",
"SERVER_NOT_CONNECTED":"Impossible de se connecter au service, veuillez réessayer plus tard", "CONNECT_TO_HOTSPOT": "Connecter le téléphone au point d'accès ",
"SERVER_TIMEOUT":"Délai d'attente de réponse", "ACCESS_VIA_BROWSER": "accéder via le navigateur ",
"SERVER_ERROR":"Échec d'envoi, veuillez vérifier le réseau", "WIFI_CONFIG_MODE": "Mode configuration réseau",
"ENTERING_WIFI_CONFIG_MODE": "Entrer en mode configuration réseau...",
"CONNECT_TO_HOTSPOT":"Connecter le téléphone au point d'accès ", "SCANNING_WIFI": "Scan Wi-Fi...",
"ACCESS_VIA_BROWSER":"accéder via le navigateur ",
"WIFI_CONFIG_MODE":"Mode configuration réseau",
"ENTERING_WIFI_CONFIG_MODE":"Entrer en mode configuration réseau...",
"SCANNING_WIFI":"Scan Wi-Fi...",
"NEW_VERSION": "Nouvelle version ", "NEW_VERSION": "Nouvelle version ",
"OTA_UPGRADE":"Mise à jour OTA", "OTA_UPGRADE": "Mise à jour OTA",
"UPGRADING":"Mise à jour du système...", "UPGRADING": "Mise à jour du système...",
"UPGRADE_FAILED":"Échec de mise à jour", "UPGRADE_FAILED": "Échec de mise à jour",
"ACTIVATION":"Activation de l'appareil", "ACTIVATION": "Activation de l'appareil",
"BATTERY_LOW": "Batterie faible",
"BATTERY_LOW":"Batterie faible", "BATTERY_CHARGING": "En charge",
"BATTERY_CHARGING":"En charge", "BATTERY_FULL": "Batterie pleine",
"BATTERY_FULL":"Batterie pleine", "BATTERY_NEED_CHARGE": "Batterie faible, veuillez charger",
"BATTERY_NEED_CHARGE":"Batterie faible, veuillez charger", "VOLUME": "Volume ",
"MUTED": "Muet",
"VOLUME":"Volume ", "MAX_VOLUME": "Volume maximum",
"MUTED":"Muet", "RTC_MODE_OFF": "AEC désactivé",
"MAX_VOLUME":"Volume maximum", "RTC_MODE_ON": "AEC activé",
"DOWNLOAD_ASSETS_FAILED": "Échec du téléchargement des ressources",
"RTC_MODE_OFF":"AEC désactivé", "LOADING_ASSETS": "Chargement des ressources...",
"RTC_MODE_ON":"AEC activé" "PLEASE_WAIT": "Veuillez patienter...",
"FOUND_NEW_ASSETS": "Nouvelles ressources trouvées: %s",
"HELLO_MY_FRIEND": "Bonjour, mon ami !"
} }
} }

View File

@@ -1,58 +1,55 @@
{ {
"language": { "language": {
"type" :"hi-IN" "type": "hi-IN"
}, },
"strings": { "strings": {
"WARNING":"चेतावनी", "WARNING": "चेतावनी",
"INFO":"जानकारी", "INFO": "जानकारी",
"ERROR":"त्रुटि", "ERROR": "त्रुटि",
"VERSION": "संस्करण ", "VERSION": "संस्करण ",
"LOADING_PROTOCOL":"सर्वर से कनेक्ट हो रहे हैं...", "LOADING_PROTOCOL": "सर्वर से कनेक्ट हो रहे हैं...",
"INITIALIZING":"आरंभीकरण...", "INITIALIZING": "आरंभीकरण...",
"PIN_ERROR":"कृपया सिम कार्ड डालें", "PIN_ERROR": "कृपया सिम कार्ड डालें",
"REG_ERROR":"नेटवर्क तक पहुंच नहीं हो सकती, कृपया डेटा कार्ड स्थिति जांचें", "REG_ERROR": "नेटवर्क तक पहुंच नहीं हो सकती, कृपया डेटा कार्ड स्थिति जांचें",
"DETECTING_MODULE":"मॉड्यूल का पता लगाया जा रहा है...", "DETECTING_MODULE": "मॉड्यूल का पता लगाया जा रहा है...",
"REGISTERING_NETWORK":"नेटवर्क की प्रतीक्षा...", "REGISTERING_NETWORK": "नेटवर्क की प्रतीक्षा...",
"CHECKING_NEW_VERSION":"नया संस्करण जाँच रहे हैं...", "CHECKING_NEW_VERSION": "नया संस्करण जाँच रहे हैं...",
"CHECK_NEW_VERSION_FAILED":"नया संस्करण जाँचना असफल, %d सेकंड में पुनः प्रयास: %s", "CHECK_NEW_VERSION_FAILED": "नया संस्करण जाँचना असफल, %d सेकंड में पुनः प्रयास: %s",
"SWITCH_TO_WIFI_NETWORK":"Wi-Fi पर स्विच कर रहे हैं...", "SWITCH_TO_WIFI_NETWORK": "Wi-Fi पर स्विच कर रहे हैं...",
"SWITCH_TO_4G_NETWORK":"4G पर स्विच कर रहे हैं...", "SWITCH_TO_4G_NETWORK": "4G पर स्विच कर रहे हैं...",
"STANDBY": "स्टैंडबाय",
"STANDBY":"स्टैंडबाय", "CONNECT_TO": "कनेक्ट करें ",
"CONNECT_TO":"कनेक्ट करें ", "CONNECTING": "कनेक्ट हो रहे हैं...",
"CONNECTING":"कनेक्ट हो रहे हैं...", "CONNECTED_TO": "कनेक्ट हो गए ",
"CONNECTED_TO":"कनेक्ट हो गए ", "LISTENING": "सुन रहे हैं...",
"SPEAKING": "बोल रहे हैं...",
"LISTENING":"सुन रहे हैं...", "SERVER_NOT_FOUND": "उपलब्ध सेवा खोज रहे हैं",
"SPEAKING":"बोल रहे हैं...", "SERVER_NOT_CONNECTED": "सेवा से कनेक्ट नहीं हो सकते, कृपया बाद में कोशिश करें",
"SERVER_TIMEOUT": "प्रतिक्रिया का समय समाप्त",
"SERVER_NOT_FOUND":"उपलब्ध सेवा खोज रहे हैं", "SERVER_ERROR": "भेजना असफल, कृपया नेटवर्क जांचें",
"SERVER_NOT_CONNECTED":"सेवा से कनेक्ट नहीं हो सकते, कृपया बाद में कोशिश करें", "CONNECT_TO_HOTSPOT": "फोन को हॉटस्पॉट से कनेक्ट करें ",
"SERVER_TIMEOUT":"प्रतिक्रिया का समय समाप्त", "ACCESS_VIA_BROWSER": ",ब्राउज़र के माध्यम से पहुंचें ",
"SERVER_ERROR":"भेजना असफल, कृपया नेटवर्क जांचें", "WIFI_CONFIG_MODE": "नेटवर्क कॉन्फ़िगरेशन मोड",
"ENTERING_WIFI_CONFIG_MODE": "नेटवर्क कॉन्फ़िगरेशन मोड में प्रवेश...",
"CONNECT_TO_HOTSPOT":"फोन को हॉटस्पॉट से कनेक्ट करें ", "SCANNING_WIFI": "Wi-Fi स्कैन कर रहे हैं...",
"ACCESS_VIA_BROWSER":",ब्राउज़र के माध्यम से पहुंचें ",
"WIFI_CONFIG_MODE":"नेटवर्क कॉन्फ़िगरेशन मोड",
"ENTERING_WIFI_CONFIG_MODE":"नेटवर्क कॉन्फ़िगरेशन मोड में प्रवेश...",
"SCANNING_WIFI":"Wi-Fi स्कैन कर रहे हैं...",
"NEW_VERSION": "नया संस्करण ", "NEW_VERSION": "नया संस्करण ",
"OTA_UPGRADE":"OTA अपग्रेड", "OTA_UPGRADE": "OTA अपग्रेड",
"UPGRADING":"सिस्टम अपग्रेड हो रहा है...", "UPGRADING": "सिस्टम अपग्रेड हो रहा है...",
"UPGRADE_FAILED":"अपग्रेड असफल", "UPGRADE_FAILED": "अपग्रेड असफल",
"ACTIVATION":"डिवाइस सक्रियण", "ACTIVATION": "डिवाइस सक्रियण",
"BATTERY_LOW": "बैटरी कम",
"BATTERY_LOW":"बैटरी कम", "BATTERY_CHARGING": "चार्ज हो रही है",
"BATTERY_CHARGING":"चार्ज हो रही है", "BATTERY_FULL": "बैटरी फुल",
"BATTERY_FULL":"बैटरी फुल", "BATTERY_NEED_CHARGE": "बैटरी कम है, कृपया चार्ज करें",
"BATTERY_NEED_CHARGE":"बैटरी कम है, कृपया चार्ज करें", "VOLUME": "आवाज़ ",
"MUTED": "म्यूट",
"VOLUME":"आवाज़ ", "MAX_VOLUME": "अधिकतम आवाज़",
"MUTED":"म्यूट", "RTC_MODE_OFF": "AEC बंद",
"MAX_VOLUME":"अधिकतम आवाज़", "RTC_MODE_ON": "AEC चालू",
"DOWNLOAD_ASSETS_FAILED": "संसाधन डाउनलोड करने में विफल",
"RTC_MODE_OFF":"AEC बंद", "LOADING_ASSETS": "संसाधन लोड हो रहे हैं...",
"RTC_MODE_ON":"AEC चालू" "PLEASE_WAIT": "कृपया प्रतीक्षा करें...",
"FOUND_NEW_ASSETS": "नए संसाधन मिले: %s",
"HELLO_MY_FRIEND": "नमस्ते, मेरे दोस्त!"
} }
} }

View File

@@ -1,58 +1,55 @@
{ {
"language": { "language": {
"type" :"id-ID" "type": "id-ID"
}, },
"strings": { "strings": {
"WARNING":"Peringatan", "WARNING": "Peringatan",
"INFO":"Informasi", "INFO": "Informasi",
"ERROR":"Kesalahan", "ERROR": "Kesalahan",
"VERSION": "Versi ", "VERSION": "Versi ",
"LOADING_PROTOCOL":"Menghubungkan ke server...", "LOADING_PROTOCOL": "Menghubungkan ke server...",
"INITIALIZING":"Menginisialisasi...", "INITIALIZING": "Menginisialisasi...",
"PIN_ERROR":"Silakan masukkan kartu SIM", "PIN_ERROR": "Silakan masukkan kartu SIM",
"REG_ERROR":"Tidak dapat mengakses jaringan, periksa status kartu data", "REG_ERROR": "Tidak dapat mengakses jaringan, periksa status kartu data",
"DETECTING_MODULE":"Mendeteksi modul...", "DETECTING_MODULE": "Mendeteksi modul...",
"REGISTERING_NETWORK":"Menunggu jaringan...", "REGISTERING_NETWORK": "Menunggu jaringan...",
"CHECKING_NEW_VERSION":"Memeriksa versi baru...", "CHECKING_NEW_VERSION": "Memeriksa versi baru...",
"CHECK_NEW_VERSION_FAILED":"Pemeriksaan versi baru gagal, mencoba lagi dalam %d detik: %s", "CHECK_NEW_VERSION_FAILED": "Pemeriksaan versi baru gagal, mencoba lagi dalam %d detik: %s",
"SWITCH_TO_WIFI_NETWORK":"Beralih ke Wi-Fi...", "SWITCH_TO_WIFI_NETWORK": "Beralih ke Wi-Fi...",
"SWITCH_TO_4G_NETWORK":"Beralih ke 4G...", "SWITCH_TO_4G_NETWORK": "Beralih ke 4G...",
"STANDBY": "Siaga",
"STANDBY":"Siaga", "CONNECT_TO": "Hubungkan ke ",
"CONNECT_TO":"Hubungkan ke ", "CONNECTING": "Menghubungkan...",
"CONNECTING":"Menghubungkan...", "CONNECTED_TO": "Terhubung ke ",
"CONNECTED_TO":"Terhubung ke ", "LISTENING": "Mendengarkan...",
"SPEAKING": "Berbicara...",
"LISTENING":"Mendengarkan...", "SERVER_NOT_FOUND": "Mencari layanan yang tersedia",
"SPEAKING":"Berbicara...", "SERVER_NOT_CONNECTED": "Tidak dapat terhubung ke layanan, coba lagi nanti",
"SERVER_TIMEOUT": "Waktu respons habis",
"SERVER_NOT_FOUND":"Mencari layanan yang tersedia", "SERVER_ERROR": "Pengiriman gagal, periksa jaringan",
"SERVER_NOT_CONNECTED":"Tidak dapat terhubung ke layanan, coba lagi nanti", "CONNECT_TO_HOTSPOT": "Hubungkan ponsel ke hotspot ",
"SERVER_TIMEOUT":"Waktu respons habis", "ACCESS_VIA_BROWSER": "akses melalui browser ",
"SERVER_ERROR":"Pengiriman gagal, periksa jaringan", "WIFI_CONFIG_MODE": "Mode konfigurasi jaringan",
"ENTERING_WIFI_CONFIG_MODE": "Memasuki mode konfigurasi jaringan...",
"CONNECT_TO_HOTSPOT":"Hubungkan ponsel ke hotspot ", "SCANNING_WIFI": "Memindai Wi-Fi...",
"ACCESS_VIA_BROWSER":"akses melalui browser ",
"WIFI_CONFIG_MODE":"Mode konfigurasi jaringan",
"ENTERING_WIFI_CONFIG_MODE":"Memasuki mode konfigurasi jaringan...",
"SCANNING_WIFI":"Memindai Wi-Fi...",
"NEW_VERSION": "Versi baru ", "NEW_VERSION": "Versi baru ",
"OTA_UPGRADE":"Pembaruan OTA", "OTA_UPGRADE": "Pembaruan OTA",
"UPGRADING":"Memperbarui sistem...", "UPGRADING": "Memperbarui sistem...",
"UPGRADE_FAILED":"Pembaruan gagal", "UPGRADE_FAILED": "Pembaruan gagal",
"ACTIVATION":"Aktivasi perangkat", "ACTIVATION": "Aktivasi perangkat",
"BATTERY_LOW": "Baterai lemah",
"BATTERY_LOW":"Baterai lemah", "BATTERY_CHARGING": "Mengisi",
"BATTERY_CHARGING":"Mengisi", "BATTERY_FULL": "Baterai penuh",
"BATTERY_FULL":"Baterai penuh", "BATTERY_NEED_CHARGE": "Baterai lemah, silakan isi",
"BATTERY_NEED_CHARGE":"Baterai lemah, silakan isi", "VOLUME": "Volume ",
"MUTED": "Bisu",
"VOLUME":"Volume ", "MAX_VOLUME": "Volume maksimum",
"MUTED":"Bisu", "RTC_MODE_OFF": "AEC mati",
"MAX_VOLUME":"Volume maksimum", "RTC_MODE_ON": "AEC nyala",
"DOWNLOAD_ASSETS_FAILED": "Gagal mengunduh aset",
"RTC_MODE_OFF":"AEC mati", "LOADING_ASSETS": "Memuat aset...",
"RTC_MODE_ON":"AEC nyala" "PLEASE_WAIT": "Mohon tunggu...",
"FOUND_NEW_ASSETS": "Ditemukan aset baru: %s",
"HELLO_MY_FRIEND": "Halo, teman saya!"
} }
} }

View File

@@ -1,58 +1,55 @@
{ {
"language": { "language": {
"type" :"it-IT" "type": "it-IT"
}, },
"strings": { "strings": {
"WARNING":"Avviso", "WARNING": "Avviso",
"INFO":"Informazione", "INFO": "Informazione",
"ERROR":"Errore", "ERROR": "Errore",
"VERSION": "Versione ", "VERSION": "Versione ",
"LOADING_PROTOCOL":"Connessione al server...", "LOADING_PROTOCOL": "Connessione al server...",
"INITIALIZING":"Inizializzazione...", "INITIALIZING": "Inizializzazione...",
"PIN_ERROR":"Inserire la scheda SIM", "PIN_ERROR": "Inserire la scheda SIM",
"REG_ERROR":"Impossibile accedere alla rete, controllare lo stato della scheda dati", "REG_ERROR": "Impossibile accedere alla rete, controllare lo stato della scheda dati",
"DETECTING_MODULE":"Rilevamento modulo...", "DETECTING_MODULE": "Rilevamento modulo...",
"REGISTERING_NETWORK":"In attesa della rete...", "REGISTERING_NETWORK": "In attesa della rete...",
"CHECKING_NEW_VERSION":"Controllo nuova versione...", "CHECKING_NEW_VERSION": "Controllo nuova versione...",
"CHECK_NEW_VERSION_FAILED":"Controllo nuova versione fallito, riprovo tra %d secondi: %s", "CHECK_NEW_VERSION_FAILED": "Controllo nuova versione fallito, riprovo tra %d secondi: %s",
"SWITCH_TO_WIFI_NETWORK":"Passaggio a Wi-Fi...", "SWITCH_TO_WIFI_NETWORK": "Passaggio a Wi-Fi...",
"SWITCH_TO_4G_NETWORK":"Passaggio a 4G...", "SWITCH_TO_4G_NETWORK": "Passaggio a 4G...",
"STANDBY": "In attesa",
"STANDBY":"In attesa", "CONNECT_TO": "Connetti a ",
"CONNECT_TO":"Connetti a ", "CONNECTING": "Connessione...",
"CONNECTING":"Connessione...", "CONNECTED_TO": "Connesso a ",
"CONNECTED_TO":"Connesso a ", "LISTENING": "In ascolto...",
"SPEAKING": "Parlando...",
"LISTENING":"In ascolto...", "SERVER_NOT_FOUND": "Ricerca servizio disponibile",
"SPEAKING":"Parlando...", "SERVER_NOT_CONNECTED": "Impossibile connettersi al servizio, riprovare più tardi",
"SERVER_TIMEOUT": "Timeout risposta",
"SERVER_NOT_FOUND":"Ricerca servizio disponibile", "SERVER_ERROR": "Invio fallito, controllare la rete",
"SERVER_NOT_CONNECTED":"Impossibile connettersi al servizio, riprovare più tardi", "CONNECT_TO_HOTSPOT": "Connetti telefono al hotspot ",
"SERVER_TIMEOUT":"Timeout risposta", "ACCESS_VIA_BROWSER": "accedi tramite browser ",
"SERVER_ERROR":"Invio fallito, controllare la rete", "WIFI_CONFIG_MODE": "Modalità configurazione rete",
"ENTERING_WIFI_CONFIG_MODE": "Entrata in modalità configurazione rete...",
"CONNECT_TO_HOTSPOT":"Connetti telefono al hotspot ", "SCANNING_WIFI": "Scansione Wi-Fi...",
"ACCESS_VIA_BROWSER":"accedi tramite browser ",
"WIFI_CONFIG_MODE":"Modalità configurazione rete",
"ENTERING_WIFI_CONFIG_MODE":"Entrata in modalità configurazione rete...",
"SCANNING_WIFI":"Scansione Wi-Fi...",
"NEW_VERSION": "Nuova versione ", "NEW_VERSION": "Nuova versione ",
"OTA_UPGRADE":"Aggiornamento OTA", "OTA_UPGRADE": "Aggiornamento OTA",
"UPGRADING":"Aggiornamento sistema...", "UPGRADING": "Aggiornamento sistema...",
"UPGRADE_FAILED":"Aggiornamento fallito", "UPGRADE_FAILED": "Aggiornamento fallito",
"ACTIVATION":"Attivazione dispositivo", "ACTIVATION": "Attivazione dispositivo",
"BATTERY_LOW": "Batteria scarica",
"BATTERY_LOW":"Batteria scarica", "BATTERY_CHARGING": "In carica",
"BATTERY_CHARGING":"In carica", "BATTERY_FULL": "Batteria piena",
"BATTERY_FULL":"Batteria piena", "BATTERY_NEED_CHARGE": "Batteria scarica, ricaricare",
"BATTERY_NEED_CHARGE":"Batteria scarica, ricaricare", "VOLUME": "Volume ",
"MUTED": "Silenziato",
"VOLUME":"Volume ", "MAX_VOLUME": "Volume massimo",
"MUTED":"Silenziato", "RTC_MODE_OFF": "AEC disattivato",
"MAX_VOLUME":"Volume massimo", "RTC_MODE_ON": "AEC attivato",
"DOWNLOAD_ASSETS_FAILED": "Impossibile scaricare le risorse",
"RTC_MODE_OFF":"AEC disattivato", "LOADING_ASSETS": "Caricamento risorse...",
"RTC_MODE_ON":"AEC attivato" "PLEASE_WAIT": "Attendere prego...",
"FOUND_NEW_ASSETS": "Trovate nuove risorse: %s",
"HELLO_MY_FRIEND": "Ciao, amico mio!"
} }
} }

View File

@@ -17,42 +17,39 @@
"CHECK_NEW_VERSION_FAILED": "更新確認に失敗しました。%d 秒後に再試行します: %s", "CHECK_NEW_VERSION_FAILED": "更新確認に失敗しました。%d 秒後に再試行します: %s",
"SWITCH_TO_WIFI_NETWORK": "Wi-Fiに切り替え中...", "SWITCH_TO_WIFI_NETWORK": "Wi-Fiに切り替え中...",
"SWITCH_TO_4G_NETWORK": "4Gに切り替え中...", "SWITCH_TO_4G_NETWORK": "4Gに切り替え中...",
"STANDBY": "待機中", "STANDBY": "待機中",
"CONNECT_TO": "接続先 ", "CONNECT_TO": "接続先 ",
"CONNECTING": "接続中...", "CONNECTING": "接続中...",
"CONNECTED_TO": "接続完了 ", "CONNECTED_TO": "接続完了 ",
"LISTENING": "リスニング中...", "LISTENING": "リスニング中...",
"SPEAKING": "話しています...", "SPEAKING": "話しています...",
"SERVER_NOT_FOUND": "利用可能なサーバーを探しています", "SERVER_NOT_FOUND": "利用可能なサーバーを探しています",
"SERVER_NOT_CONNECTED": "サーバーに接続できません。後でもう一度お試しください", "SERVER_NOT_CONNECTED": "サーバーに接続できません。後でもう一度お試しください",
"SERVER_TIMEOUT": "応答待機時間が終了しました", "SERVER_TIMEOUT": "応答待機時間が終了しました",
"SERVER_ERROR": "送信に失敗しました。ネットワークを確認してください", "SERVER_ERROR": "送信に失敗しました。ネットワークを確認してください",
"CONNECT_TO_HOTSPOT": "スマートフォンをWi-Fi ", "CONNECT_TO_HOTSPOT": "スマートフォンをWi-Fi ",
"ACCESS_VIA_BROWSER": " に接続し、ブラウザでアクセスしてください ", "ACCESS_VIA_BROWSER": " に接続し、ブラウザでアクセスしてください ",
"WIFI_CONFIG_MODE": "ネットワーク設定モード", "WIFI_CONFIG_MODE": "ネットワーク設定モード",
"ENTERING_WIFI_CONFIG_MODE": "ネットワーク設定中...", "ENTERING_WIFI_CONFIG_MODE": "ネットワーク設定中...",
"SCANNING_WIFI": "Wi-Fiをスキャン中...", "SCANNING_WIFI": "Wi-Fiをスキャン中...",
"NEW_VERSION": "新しいバージョン ", "NEW_VERSION": "新しいバージョン ",
"OTA_UPGRADE": "OTAアップグレード", "OTA_UPGRADE": "OTAアップグレード",
"UPGRADING": "システムをアップグレード中...", "UPGRADING": "システムをアップグレード中...",
"UPGRADE_FAILED": "アップグレード失敗", "UPGRADE_FAILED": "アップグレード失敗",
"ACTIVATION": "デバイスをアクティベート", "ACTIVATION": "デバイスをアクティベート",
"BATTERY_LOW": "バッテリーが少なくなっています", "BATTERY_LOW": "バッテリーが少なくなっています",
"BATTERY_CHARGING": "充電中", "BATTERY_CHARGING": "充電中",
"BATTERY_FULL": "バッテリー満タン", "BATTERY_FULL": "バッテリー満タン",
"BATTERY_NEED_CHARGE": "バッテリーが低下しています。充電してください", "BATTERY_NEED_CHARGE": "バッテリーが低下しています。充電してください",
"VOLUME": "音量 ", "VOLUME": "音量 ",
"MUTED": "ミュートされています", "MUTED": "ミュートされています",
"MAX_VOLUME": "最大音量", "MAX_VOLUME": "最大音量",
"RTC_MODE_OFF": "AEC 無効", "RTC_MODE_OFF": "AEC 無効",
"RTC_MODE_ON": "AEC 有効" "RTC_MODE_ON": "AEC 有効",
"DOWNLOAD_ASSETS_FAILED": "アセットのダウンロードに失敗しました",
"LOADING_ASSETS": "アセットを読み込み中...",
"PLEASE_WAIT": "お待ちください...",
"FOUND_NEW_ASSETS": "新しいアセットが見つかりました: %s",
"HELLO_MY_FRIEND": "こんにちは、友達!"
} }
} }

View File

@@ -17,43 +17,40 @@
"CHECK_NEW_VERSION_FAILED": "새 버전 확인에 실패했습니다. %d초 후에 다시 시도합니다: %s", "CHECK_NEW_VERSION_FAILED": "새 버전 확인에 실패했습니다. %d초 후에 다시 시도합니다: %s",
"SWITCH_TO_WIFI_NETWORK": "Wi-Fi로 전환 중...", "SWITCH_TO_WIFI_NETWORK": "Wi-Fi로 전환 중...",
"SWITCH_TO_4G_NETWORK": "4G로 전환 중...", "SWITCH_TO_4G_NETWORK": "4G로 전환 중...",
"STANDBY": "대기", "STANDBY": "대기",
"CONNECT_TO": "연결 대상: ", "CONNECT_TO": "연결 대상: ",
"CONNECTING": "연결 중...", "CONNECTING": "연결 중...",
"CONNECTION_SUCCESSFUL": "연결 성공", "CONNECTION_SUCCESSFUL": "연결 성공",
"CONNECTED_TO": "연결됨: ", "CONNECTED_TO": "연결됨: ",
"LISTENING": "듣는 중...", "LISTENING": "듣는 중...",
"SPEAKING": "말하는 중...", "SPEAKING": "말하는 중...",
"SERVER_NOT_FOUND": "사용 가능한 서비스를 찾는 중", "SERVER_NOT_FOUND": "사용 가능한 서비스를 찾는 중",
"SERVER_NOT_CONNECTED": "서비스에 연결할 수 없습니다. 나중에 다시 시도하세요", "SERVER_NOT_CONNECTED": "서비스에 연결할 수 없습니다. 나중에 다시 시도하세요",
"SERVER_TIMEOUT": "응답 대기 시간 초과", "SERVER_TIMEOUT": "응답 대기 시간 초과",
"SERVER_ERROR": "전송 실패, 네트워크를 확인하세요", "SERVER_ERROR": "전송 실패, 네트워크를 확인하세요",
"CONNECT_TO_HOTSPOT": "핫스팟: ", "CONNECT_TO_HOTSPOT": "핫스팟: ",
"ACCESS_VIA_BROWSER": " 설정 URL: ", "ACCESS_VIA_BROWSER": " 설정 URL: ",
"WIFI_CONFIG_MODE": "Wi-Fi 설정 모드", "WIFI_CONFIG_MODE": "Wi-Fi 설정 모드",
"ENTERING_WIFI_CONFIG_MODE": "Wi-Fi 설정 모드 진입 중...", "ENTERING_WIFI_CONFIG_MODE": "Wi-Fi 설정 모드 진입 중...",
"SCANNING_WIFI": "Wi-Fi 스캔 중...", "SCANNING_WIFI": "Wi-Fi 스캔 중...",
"NEW_VERSION": "새 버전 ", "NEW_VERSION": "새 버전 ",
"OTA_UPGRADE": "OTA 업그레이드", "OTA_UPGRADE": "OTA 업그레이드",
"UPGRADING": "시스템 업그레이드 중...", "UPGRADING": "시스템 업그레이드 중...",
"UPGRADE_FAILED": "업그레이드 실패", "UPGRADE_FAILED": "업그레이드 실패",
"ACTIVATION": "활성화", "ACTIVATION": "활성화",
"BATTERY_LOW": "배터리 부족", "BATTERY_LOW": "배터리 부족",
"BATTERY_CHARGING": "충전 중", "BATTERY_CHARGING": "충전 중",
"BATTERY_FULL": "배터리 완충", "BATTERY_FULL": "배터리 완충",
"BATTERY_NEED_CHARGE": "배터리 부족, 충전하세요", "BATTERY_NEED_CHARGE": "배터리 부족, 충전하세요",
"VOLUME": "볼륨 ", "VOLUME": "볼륨 ",
"MUTED": "음소거", "MUTED": "음소거",
"MAX_VOLUME": "최대 볼륨", "MAX_VOLUME": "최대 볼륨",
"RTC_MODE_OFF": "AEC 끄기", "RTC_MODE_OFF": "AEC 끄기",
"RTC_MODE_ON": "AEC 켜기" "RTC_MODE_ON": "AEC 켜기",
"DOWNLOAD_ASSETS_FAILED": "에셋 다운로드 실패",
"LOADING_ASSETS": "에셋 로딩 중...",
"PLEASE_WAIT": "잠시 기다려 주세요...",
"FOUND_NEW_ASSETS": "새로운 에셋을 발견했습니다: %s",
"HELLO_MY_FRIEND": "안녕하세요, 친구!"
} }
} }

View File

@@ -1,58 +1,55 @@
{ {
"language": { "language": {
"type" :"pl-PL" "type": "pl-PL"
}, },
"strings": { "strings": {
"WARNING":"Ostrzeżenie", "WARNING": "Ostrzeżenie",
"INFO":"Informacja", "INFO": "Informacja",
"ERROR":"Błąd", "ERROR": "Błąd",
"VERSION": "Wersja ", "VERSION": "Wersja ",
"LOADING_PROTOCOL":"Łączenie z serwerem...", "LOADING_PROTOCOL": "Łączenie z serwerem...",
"INITIALIZING":"Inicjalizacja...", "INITIALIZING": "Inicjalizacja...",
"PIN_ERROR":"Proszę włożyć kartę SIM", "PIN_ERROR": "Proszę włożyć kartę SIM",
"REG_ERROR":"Nie można uzyskać dostępu do sieci, sprawdź stan karty danych", "REG_ERROR": "Nie można uzyskać dostępu do sieci, sprawdź stan karty danych",
"DETECTING_MODULE":"Wykrywanie modułu...", "DETECTING_MODULE": "Wykrywanie modułu...",
"REGISTERING_NETWORK":"Oczekiwanie na sieć...", "REGISTERING_NETWORK": "Oczekiwanie na sieć...",
"CHECKING_NEW_VERSION":"Sprawdzanie nowej wersji...", "CHECKING_NEW_VERSION": "Sprawdzanie nowej wersji...",
"CHECK_NEW_VERSION_FAILED":"Sprawdzanie nowej wersji nie powiodło się, ponowna próba za %d sekund: %s", "CHECK_NEW_VERSION_FAILED": "Sprawdzanie nowej wersji nie powiodło się, ponowna próba za %d sekund: %s",
"SWITCH_TO_WIFI_NETWORK":"Przełączanie na Wi-Fi...", "SWITCH_TO_WIFI_NETWORK": "Przełączanie na Wi-Fi...",
"SWITCH_TO_4G_NETWORK":"Przełączanie na 4G...", "SWITCH_TO_4G_NETWORK": "Przełączanie na 4G...",
"STANDBY": "Gotowość",
"STANDBY":"Gotowość", "CONNECT_TO": "Połącz z ",
"CONNECT_TO":"Połącz z ", "CONNECTING": "Łączenie...",
"CONNECTING":"Łączenie...", "CONNECTED_TO": "Połączono z ",
"CONNECTED_TO":"Połączono z ", "LISTENING": "Słuchanie...",
"SPEAKING": "Mówienie...",
"LISTENING":"Słuchanie...", "SERVER_NOT_FOUND": "Szukanie dostępnej usługi",
"SPEAKING":"Mówienie...", "SERVER_NOT_CONNECTED": "Nie można połączyć się z usługą, spróbuj ponownie później",
"SERVER_TIMEOUT": "Przekroczono czas oczekiwania na odpowiedź",
"SERVER_NOT_FOUND":"Szukanie dostępnej usługi", "SERVER_ERROR": "Wysyłanie nie powiodło się, sprawdź sieć",
"SERVER_NOT_CONNECTED":"Nie można połączyć się z usługą, spróbuj ponownie później", "CONNECT_TO_HOTSPOT": "Podłącz telefon do hotspotu ",
"SERVER_TIMEOUT":"Przekroczono czas oczekiwania na odpowiedź", "ACCESS_VIA_BROWSER": "dostęp przez przeglądarkę ",
"SERVER_ERROR":"Wysyłanie nie powiodło się, sprawdź sieć", "WIFI_CONFIG_MODE": "Tryb konfiguracji sieci",
"ENTERING_WIFI_CONFIG_MODE": "Wchodzenie w tryb konfiguracji sieci...",
"CONNECT_TO_HOTSPOT":"Podłącz telefon do hotspotu ", "SCANNING_WIFI": "Skanowanie Wi-Fi...",
"ACCESS_VIA_BROWSER":"dostęp przez przeglądarkę ",
"WIFI_CONFIG_MODE":"Tryb konfiguracji sieci",
"ENTERING_WIFI_CONFIG_MODE":"Wchodzenie w tryb konfiguracji sieci...",
"SCANNING_WIFI":"Skanowanie Wi-Fi...",
"NEW_VERSION": "Nowa wersja ", "NEW_VERSION": "Nowa wersja ",
"OTA_UPGRADE":"Aktualizacja OTA", "OTA_UPGRADE": "Aktualizacja OTA",
"UPGRADING":"Aktualizacja systemu...", "UPGRADING": "Aktualizacja systemu...",
"UPGRADE_FAILED":"Aktualizacja nie powiodła się", "UPGRADE_FAILED": "Aktualizacja nie powiodła się",
"ACTIVATION":"Aktywacja urządzenia", "ACTIVATION": "Aktywacja urządzenia",
"BATTERY_LOW": "Niski poziom baterii",
"BATTERY_LOW":"Niski poziom baterii", "BATTERY_CHARGING": "Ładowanie",
"BATTERY_CHARGING":"Ładowanie", "BATTERY_FULL": "Bateria pełna",
"BATTERY_FULL":"Bateria pełna", "BATTERY_NEED_CHARGE": "Niski poziom baterii, proszę naładować",
"BATTERY_NEED_CHARGE":"Niski poziom baterii, proszę naładować", "VOLUME": "Głośność ",
"MUTED": "Wyciszony",
"VOLUME":"Głośność ", "MAX_VOLUME": "Maksymalna głośność",
"MUTED":"Wyciszony", "RTC_MODE_OFF": "AEC wyłączony",
"MAX_VOLUME":"Maksymalna głośność", "RTC_MODE_ON": "AEC włączony",
"DOWNLOAD_ASSETS_FAILED": "Nie udało się pobrać zasobów",
"RTC_MODE_OFF":"AEC wyłączony", "LOADING_ASSETS": "Ładowanie zasobów...",
"RTC_MODE_ON":"AEC włączony" "PLEASE_WAIT": "Proszę czekać...",
"FOUND_NEW_ASSETS": "Znaleziono nowe zasoby: %s",
"HELLO_MY_FRIEND": "Cześć, mój przyjacielu!"
} }
} }

View File

@@ -1,58 +1,55 @@
{ {
"language": { "language": {
"type" :"pt-PT" "type": "pt-PT"
}, },
"strings": { "strings": {
"WARNING":"Aviso", "WARNING": "Aviso",
"INFO":"Informação", "INFO": "Informação",
"ERROR":"Erro", "ERROR": "Erro",
"VERSION": "Versão ", "VERSION": "Versão ",
"LOADING_PROTOCOL":"Ligando ao servidor...", "LOADING_PROTOCOL": "Ligando ao servidor...",
"INITIALIZING":"A inicializar...", "INITIALIZING": "A inicializar...",
"PIN_ERROR":"Por favor insira o cartão SIM", "PIN_ERROR": "Por favor insira o cartão SIM",
"REG_ERROR":"Não é possível aceder à rede, verifique o estado do cartão de dados", "REG_ERROR": "Não é possível aceder à rede, verifique o estado do cartão de dados",
"DETECTING_MODULE":"A detectar módulo...", "DETECTING_MODULE": "A detectar módulo...",
"REGISTERING_NETWORK":"À espera da rede...", "REGISTERING_NETWORK": "À espera da rede...",
"CHECKING_NEW_VERSION":"A verificar nova versão...", "CHECKING_NEW_VERSION": "A verificar nova versão...",
"CHECK_NEW_VERSION_FAILED":"Falha na verificação de nova versão, nova tentativa em %d segundos: %s", "CHECK_NEW_VERSION_FAILED": "Falha na verificação de nova versão, nova tentativa em %d segundos: %s",
"SWITCH_TO_WIFI_NETWORK":"A mudar para Wi-Fi...", "SWITCH_TO_WIFI_NETWORK": "A mudar para Wi-Fi...",
"SWITCH_TO_4G_NETWORK":"A mudar para 4G...", "SWITCH_TO_4G_NETWORK": "A mudar para 4G...",
"STANDBY": "Em espera",
"STANDBY":"Em espera", "CONNECT_TO": "Ligar a ",
"CONNECT_TO":"Ligar a ", "CONNECTING": "A ligar...",
"CONNECTING":"A ligar...", "CONNECTED_TO": "Ligado a ",
"CONNECTED_TO":"Ligado a ", "LISTENING": "A escutar...",
"SPEAKING": "A falar...",
"LISTENING":"A escutar...", "SERVER_NOT_FOUND": "A procurar serviço disponível",
"SPEAKING":"A falar...", "SERVER_NOT_CONNECTED": "Não é possível ligar ao serviço, tente mais tarde",
"SERVER_TIMEOUT": "Tempo limite de resposta",
"SERVER_NOT_FOUND":"A procurar serviço disponível", "SERVER_ERROR": "Falha no envio, verifique a rede",
"SERVER_NOT_CONNECTED":"Não é possível ligar ao serviço, tente mais tarde", "CONNECT_TO_HOTSPOT": "Ligue o telefone ao hotspot ",
"SERVER_TIMEOUT":"Tempo limite de resposta", "ACCESS_VIA_BROWSER": "aceder através do navegador ",
"SERVER_ERROR":"Falha no envio, verifique a rede", "WIFI_CONFIG_MODE": "Modo de configuração de rede",
"ENTERING_WIFI_CONFIG_MODE": "A entrar no modo de configuração de rede...",
"CONNECT_TO_HOTSPOT":"Ligue o telefone ao hotspot ", "SCANNING_WIFI": "A procurar Wi-Fi...",
"ACCESS_VIA_BROWSER":"aceder através do navegador ",
"WIFI_CONFIG_MODE":"Modo de configuração de rede",
"ENTERING_WIFI_CONFIG_MODE":"A entrar no modo de configuração de rede...",
"SCANNING_WIFI":"A procurar Wi-Fi...",
"NEW_VERSION": "Nova versão ", "NEW_VERSION": "Nova versão ",
"OTA_UPGRADE":"Atualização OTA", "OTA_UPGRADE": "Atualização OTA",
"UPGRADING":"A atualizar sistema...", "UPGRADING": "A atualizar sistema...",
"UPGRADE_FAILED":"Atualização falhada", "UPGRADE_FAILED": "Atualização falhada",
"ACTIVATION":"Ativação do dispositivo", "ACTIVATION": "Ativação do dispositivo",
"BATTERY_LOW": "Bateria fraca",
"BATTERY_LOW":"Bateria fraca", "BATTERY_CHARGING": "A carregar",
"BATTERY_CHARGING":"A carregar", "BATTERY_FULL": "Bateria cheia",
"BATTERY_FULL":"Bateria cheia", "BATTERY_NEED_CHARGE": "Bateria fraca, por favor carregue",
"BATTERY_NEED_CHARGE":"Bateria fraca, por favor carregue", "VOLUME": "Volume ",
"MUTED": "Silenciado",
"VOLUME":"Volume ", "MAX_VOLUME": "Volume máximo",
"MUTED":"Silenciado", "RTC_MODE_OFF": "AEC desligado",
"MAX_VOLUME":"Volume máximo", "RTC_MODE_ON": "AEC ligado",
"DOWNLOAD_ASSETS_FAILED": "Falha ao descarregar recursos",
"RTC_MODE_OFF":"AEC desligado", "LOADING_ASSETS": "A carregar recursos...",
"RTC_MODE_ON":"AEC ligado" "PLEASE_WAIT": "Por favor aguarde...",
"FOUND_NEW_ASSETS": "Encontrados novos recursos: %s",
"HELLO_MY_FRIEND": "Olá, meu amigo!"
} }
} }

View File

@@ -1,58 +1,55 @@
{ {
"language": { "language": {
"type" :"ro-RO" "type": "ro-RO"
}, },
"strings": { "strings": {
"WARNING":"Avertisment", "WARNING": "Avertisment",
"INFO":"Informație", "INFO": "Informație",
"ERROR":"Eroare", "ERROR": "Eroare",
"VERSION": "Versiune ", "VERSION": "Versiune ",
"LOADING_PROTOCOL":"Se conectează la server...", "LOADING_PROTOCOL": "Se conectează la server...",
"INITIALIZING":"Se inițializează...", "INITIALIZING": "Se inițializează...",
"PIN_ERROR":"Vă rugăm să introduceți cardul SIM", "PIN_ERROR": "Vă rugăm să introduceți cardul SIM",
"REG_ERROR":"Nu se poate accesa rețeaua, verificați starea cardului de date", "REG_ERROR": "Nu se poate accesa rețeaua, verificați starea cardului de date",
"DETECTING_MODULE":"Se detectează modulul...", "DETECTING_MODULE": "Se detectează modulul...",
"REGISTERING_NETWORK":"Se așteaptă rețeaua...", "REGISTERING_NETWORK": "Se așteaptă rețeaua...",
"CHECKING_NEW_VERSION":"Se verifică versiunea nouă...", "CHECKING_NEW_VERSION": "Se verifică versiunea nouă...",
"CHECK_NEW_VERSION_FAILED":"Verificarea versiunii noi a eșuat, se reîncearcă în %d secunde: %s", "CHECK_NEW_VERSION_FAILED": "Verificarea versiunii noi a eșuat, se reîncearcă în %d secunde: %s",
"SWITCH_TO_WIFI_NETWORK":"Se comută la Wi-Fi...", "SWITCH_TO_WIFI_NETWORK": "Se comută la Wi-Fi...",
"SWITCH_TO_4G_NETWORK":"Se comută la 4G...", "SWITCH_TO_4G_NETWORK": "Se comută la 4G...",
"STANDBY": "În așteptare",
"STANDBY":"În așteptare", "CONNECT_TO": "Conectare la ",
"CONNECT_TO":"Conectare la ", "CONNECTING": "Se conectează...",
"CONNECTING":"Se conectează...", "CONNECTED_TO": "Conectat la ",
"CONNECTED_TO":"Conectat la ", "LISTENING": "Se ascultă...",
"SPEAKING": "Se vorbește...",
"LISTENING":"Se ascultă...", "SERVER_NOT_FOUND": "Se caută serviciul disponibil",
"SPEAKING":"Se vorbește...", "SERVER_NOT_CONNECTED": "Nu se poate conecta la serviciu, încercați mai târziu",
"SERVER_TIMEOUT": "Timpul de răspuns a expirat",
"SERVER_NOT_FOUND":"Se caută serviciul disponibil", "SERVER_ERROR": "Trimiterea a eșuat, verificați rețeaua",
"SERVER_NOT_CONNECTED":"Nu se poate conecta la serviciu, încercați mai târziu", "CONNECT_TO_HOTSPOT": "Conectați telefonul la hotspot ",
"SERVER_TIMEOUT":"Timpul de răspuns a expirat", "ACCESS_VIA_BROWSER": "accesați prin browser ",
"SERVER_ERROR":"Trimiterea a eșuat, verificați rețeaua", "WIFI_CONFIG_MODE": "Modul de configurare rețea",
"ENTERING_WIFI_CONFIG_MODE": "Se intră în modul de configurare rețea...",
"CONNECT_TO_HOTSPOT":"Conectați telefonul la hotspot ", "SCANNING_WIFI": "Se scanează Wi-Fi...",
"ACCESS_VIA_BROWSER":"accesați prin browser ",
"WIFI_CONFIG_MODE":"Modul de configurare rețea",
"ENTERING_WIFI_CONFIG_MODE":"Se intră în modul de configurare rețea...",
"SCANNING_WIFI":"Se scanează Wi-Fi...",
"NEW_VERSION": "Versiune nouă ", "NEW_VERSION": "Versiune nouă ",
"OTA_UPGRADE":"Actualizare OTA", "OTA_UPGRADE": "Actualizare OTA",
"UPGRADING":"Se actualizează sistemul...", "UPGRADING": "Se actualizează sistemul...",
"UPGRADE_FAILED":"Actualizarea a eșuat", "UPGRADE_FAILED": "Actualizarea a eșuat",
"ACTIVATION":"Activarea dispozitivului", "ACTIVATION": "Activarea dispozitivului",
"BATTERY_LOW": "Baterie scăzută",
"BATTERY_LOW":"Baterie scăzută", "BATTERY_CHARGING": "Se încarcă",
"BATTERY_CHARGING":"Se încarcă", "BATTERY_FULL": "Baterie plină",
"BATTERY_FULL":"Baterie plină", "BATTERY_NEED_CHARGE": "Baterie scăzută, vă rugăm să încărcați",
"BATTERY_NEED_CHARGE":"Baterie scăzută, vă rugăm să încărcați", "VOLUME": "Volum ",
"MUTED": "Silențios",
"VOLUME":"Volum ", "MAX_VOLUME": "Volum maxim",
"MUTED":"Silențios", "RTC_MODE_OFF": "AEC oprit",
"MAX_VOLUME":"Volum maxim", "RTC_MODE_ON": "AEC pornit",
"DOWNLOAD_ASSETS_FAILED": "Eșec la descărcarea resurselor",
"RTC_MODE_OFF":"AEC oprit", "LOADING_ASSETS": "Se încarcă resursele...",
"RTC_MODE_ON":"AEC pornit" "PLEASE_WAIT": "Vă rugăm să așteptați...",
"FOUND_NEW_ASSETS": "S-au găsit resurse noi: %s",
"HELLO_MY_FRIEND": "Salut, prietenul meu!"
} }
} }

View File

@@ -1,58 +1,55 @@
{ {
"language": { "language": {
"type" :"ru-RU" "type": "ru-RU"
}, },
"strings": { "strings": {
"WARNING":"Предупреждение", "WARNING": "Предупреждение",
"INFO":"Информация", "INFO": "Информация",
"ERROR":"Ошибка", "ERROR": "Ошибка",
"VERSION": "Версия ", "VERSION": "Версия ",
"LOADING_PROTOCOL":"Подключение к серверу...", "LOADING_PROTOCOL": "Подключение к серверу...",
"INITIALIZING":"Инициализация...", "INITIALIZING": "Инициализация...",
"PIN_ERROR":"Пожалуйста, вставьте SIM-карту", "PIN_ERROR": "Пожалуйста, вставьте SIM-карту",
"REG_ERROR":"Невозможно подключиться к сети, проверьте состояние карты данных", "REG_ERROR": "Невозможно подключиться к сети, проверьте состояние карты данных",
"DETECTING_MODULE":"Обнаружение модуля...", "DETECTING_MODULE": "Обнаружение модуля...",
"REGISTERING_NETWORK":"Ожидание сети...", "REGISTERING_NETWORK": "Ожидание сети...",
"CHECKING_NEW_VERSION":"Проверка новой версии...", "CHECKING_NEW_VERSION": "Проверка новой версии...",
"CHECK_NEW_VERSION_FAILED":"Ошибка проверки новой версии, повтор через %d секунд: %s", "CHECK_NEW_VERSION_FAILED": "Ошибка проверки новой версии, повтор через %d секунд: %s",
"SWITCH_TO_WIFI_NETWORK":"Переключение на Wi-Fi...", "SWITCH_TO_WIFI_NETWORK": "Переключение на Wi-Fi...",
"SWITCH_TO_4G_NETWORK":"Переключение на 4G...", "SWITCH_TO_4G_NETWORK": "Переключение на 4G...",
"STANDBY": "Ожидание",
"STANDBY":"Ожидание", "CONNECT_TO": "Подключение к ",
"CONNECT_TO":"Подключение к ", "CONNECTING": "Подключение...",
"CONNECTING":"Подключение...", "CONNECTED_TO": "Подключено к ",
"CONNECTED_TO":одключено к ", "LISTENING": рослушивание...",
"SPEAKING": "Говорение...",
"LISTENING":рослушивание...", "SERVER_NOT_FOUND": оиск доступного сервиса",
"SPEAKING":"Говорение...", "SERVER_NOT_CONNECTED": "Невозможно подключиться к сервису, попробуйте позже",
"SERVER_TIMEOUT": "Тайм-аут ответа",
"SERVER_NOT_FOUND":"Поиск доступного сервиса", "SERVER_ERROR": "Ошибка отправки, проверьте сеть",
"SERVER_NOT_CONNECTED":"Невозможно подключиться к сервису, попробуйте позже", "CONNECT_TO_HOTSPOT": "Подключите телефон к точке доступа ",
"SERVER_TIMEOUT":"Тайм-аут ответа", "ACCESS_VIA_BROWSER": ",доступ через браузер ",
"SERVER_ERROR":"Ошибка отправки, проверьте сеть", "WIFI_CONFIG_MODE": "Режим настройки сети",
"ENTERING_WIFI_CONFIG_MODE": "Вход в режим настройки сети...",
"CONNECT_TO_HOTSPOT":"Подключите телефон к точке доступа ", "SCANNING_WIFI": "Сканирование Wi-Fi...",
"ACCESS_VIA_BROWSER":",доступ через браузер ",
"WIFI_CONFIG_MODE":"Режим настройки сети",
"ENTERING_WIFI_CONFIG_MODE":"Вход в режим настройки сети...",
"SCANNING_WIFI":"Сканирование Wi-Fi...",
"NEW_VERSION": "Новая версия ", "NEW_VERSION": "Новая версия ",
"OTA_UPGRADE":"Обновление OTA", "OTA_UPGRADE": "Обновление OTA",
"UPGRADING":"Обновление системы...", "UPGRADING": "Обновление системы...",
"UPGRADE_FAILED":"Обновление не удалось", "UPGRADE_FAILED": "Обновление не удалось",
"ACTIVATION":"Активация устройства", "ACTIVATION": "Активация устройства",
"BATTERY_LOW": "Низкий заряд батареи",
"BATTERY_LOW":"Низкий заряд батареи", "BATTERY_CHARGING": "Зарядка",
"BATTERY_CHARGING":"Зарядка", "BATTERY_FULL": "Батарея полная",
"BATTERY_FULL":"Батарея полная", "BATTERY_NEED_CHARGE": "Низкий заряд, пожалуйста, зарядите",
"BATTERY_NEED_CHARGE":"Низкий заряд, пожалуйста, зарядите", "VOLUME": "Громкость ",
"MUTED": "Звук отключен",
"VOLUME":"Громкость ", "MAX_VOLUME": "Максимальная громкость",
"MUTED":"Звук отключен", "RTC_MODE_OFF": "AEC выключен",
"MAX_VOLUME":"Максимальная громкость", "RTC_MODE_ON": "AEC включен",
"DOWNLOAD_ASSETS_FAILED": "Не удалось загрузить ресурсы",
"RTC_MODE_OFF":"AEC выключен", "LOADING_ASSETS": "Загрузка ресурсов...",
"RTC_MODE_ON":"AEC включен" "PLEASE_WAIT": "Пожалуйста, подождите...",
"FOUND_NEW_ASSETS": "Найдены новые ресурсы: %s",
"HELLO_MY_FRIEND": "Привет, мой друг!"
} }
} }

View File

@@ -17,43 +17,40 @@
"CHECK_NEW_VERSION_FAILED": "การตรวจสอบเวอร์ชันใหม่ล้มเหลว จะลองใหม่ใน %d วินาที: %s", "CHECK_NEW_VERSION_FAILED": "การตรวจสอบเวอร์ชันใหม่ล้มเหลว จะลองใหม่ใน %d วินาที: %s",
"SWITCH_TO_WIFI_NETWORK": "กำลังเปลี่ยนเป็น Wi-Fi...", "SWITCH_TO_WIFI_NETWORK": "กำลังเปลี่ยนเป็น Wi-Fi...",
"SWITCH_TO_4G_NETWORK": "กำลังเปลี่ยนเป็น 4G...", "SWITCH_TO_4G_NETWORK": "กำลังเปลี่ยนเป็น 4G...",
"STANDBY": "พร้อม", "STANDBY": "พร้อม",
"CONNECT_TO": "เชื่อมต่อกับ ", "CONNECT_TO": "เชื่อมต่อกับ ",
"CONNECTING": "กำลังเชื่อมต่อ...", "CONNECTING": "กำลังเชื่อมต่อ...",
"CONNECTION_SUCCESSFUL": "เชื่อมต่อสำเร็จ", "CONNECTION_SUCCESSFUL": "เชื่อมต่อสำเร็จ",
"CONNECTED_TO": "เชื่อมต่อกับ ", "CONNECTED_TO": "เชื่อมต่อกับ ",
"LISTENING": "กำลังฟัง...", "LISTENING": "กำลังฟัง...",
"SPEAKING": "กำลังพูด...", "SPEAKING": "กำลังพูด...",
"SERVER_NOT_FOUND": "กำลังค้นหาบริการที่ใช้งานได้", "SERVER_NOT_FOUND": "กำลังค้นหาบริการที่ใช้งานได้",
"SERVER_NOT_CONNECTED": "ไม่สามารถเชื่อมต่อกับบริการได้ กรุณาลองใหม่ในภายหลัง", "SERVER_NOT_CONNECTED": "ไม่สามารถเชื่อมต่อกับบริการได้ กรุณาลองใหม่ในภายหลัง",
"SERVER_TIMEOUT": "หมดเวลารอการตอบกลับ", "SERVER_TIMEOUT": "หมดเวลารอการตอบกลับ",
"SERVER_ERROR": "การส่งข้อมูลล้มเหลว กรุณาตรวจสอบเครือข่าย", "SERVER_ERROR": "การส่งข้อมูลล้มเหลว กรุณาตรวจสอบเครือข่าย",
"CONNECT_TO_HOTSPOT": "ฮอตสปอต: ", "CONNECT_TO_HOTSPOT": "ฮอตสปอต: ",
"ACCESS_VIA_BROWSER": " URL การตั้งค่า: ", "ACCESS_VIA_BROWSER": " URL การตั้งค่า: ",
"WIFI_CONFIG_MODE": "โหมดการตั้งค่า Wi-Fi", "WIFI_CONFIG_MODE": "โหมดการตั้งค่า Wi-Fi",
"ENTERING_WIFI_CONFIG_MODE": "กำลังเข้าสู่โหมดการตั้งค่า Wi-Fi...", "ENTERING_WIFI_CONFIG_MODE": "กำลังเข้าสู่โหมดการตั้งค่า Wi-Fi...",
"SCANNING_WIFI": "กำลังสแกน Wi-Fi...", "SCANNING_WIFI": "กำลังสแกน Wi-Fi...",
"NEW_VERSION": "เวอร์ชันใหม่ ", "NEW_VERSION": "เวอร์ชันใหม่ ",
"OTA_UPGRADE": "การอัปเกรด OTA", "OTA_UPGRADE": "การอัปเกรด OTA",
"UPGRADING": "ระบบกำลังอัปเกรด...", "UPGRADING": "ระบบกำลังอัปเกรด...",
"UPGRADE_FAILED": "การอัปเกรดล้มเหลว", "UPGRADE_FAILED": "การอัปเกรดล้มเหลว",
"ACTIVATION": "การเปิดใช้งาน", "ACTIVATION": "การเปิดใช้งาน",
"BATTERY_LOW": "แบตเตอรี่ต่ำ", "BATTERY_LOW": "แบตเตอรี่ต่ำ",
"BATTERY_CHARGING": "กำลังชาร์จ", "BATTERY_CHARGING": "กำลังชาร์จ",
"BATTERY_FULL": "แบตเตอรี่เต็ม", "BATTERY_FULL": "แบตเตอรี่เต็ม",
"BATTERY_NEED_CHARGE": "แบตเตอรี่ต่ำ กรุณาชาร์จ", "BATTERY_NEED_CHARGE": "แบตเตอรี่ต่ำ กรุณาชาร์จ",
"VOLUME": "เสียง ", "VOLUME": "เสียง ",
"MUTED": "ปิดเสียง", "MUTED": "ปิดเสียง",
"MAX_VOLUME": "เสียงสูงสุด", "MAX_VOLUME": "เสียงสูงสุด",
"RTC_MODE_OFF": "ปิด AEC", "RTC_MODE_OFF": "ปิด AEC",
"RTC_MODE_ON": "เปิด AEC" "RTC_MODE_ON": "เปิด AEC",
"DOWNLOAD_ASSETS_FAILED": "ดาวน์โหลดทรัพยากรล้มเหลว",
"LOADING_ASSETS": "กำลังโหลดทรัพยากร...",
"PLEASE_WAIT": "กรุณารอสักครู่...",
"FOUND_NEW_ASSETS": "พบทรัพยากรใหม่: %s",
"HELLO_MY_FRIEND": "สวัสดี เพื่อนของฉัน!"
} }
} }

View File

@@ -1,58 +1,55 @@
{ {
"language": { "language": {
"type" :"tr-TR" "type": "tr-TR"
}, },
"strings": { "strings": {
"WARNING":"Uyarı", "WARNING": "Uyarı",
"INFO":"Bilgi", "INFO": "Bilgi",
"ERROR":"Hata", "ERROR": "Hata",
"VERSION": "Sürüm ", "VERSION": "Sürüm ",
"LOADING_PROTOCOL":"Sunucuya bağlanıyor...", "LOADING_PROTOCOL": "Sunucuya bağlanıyor...",
"INITIALIZING":"Başlatılıyor...", "INITIALIZING": "Başlatılıyor...",
"PIN_ERROR":"Lütfen SIM kartı takın", "PIN_ERROR": "Lütfen SIM kartı takın",
"REG_ERROR":"Ağa erişilemiyor, veri kartı durumunu kontrol edin", "REG_ERROR": "Ağa erişilemiyor, veri kartı durumunu kontrol edin",
"DETECTING_MODULE":"Modül algılanıyor...", "DETECTING_MODULE": "Modül algılanıyor...",
"REGISTERING_NETWORK":"Ağ bekleniyor...", "REGISTERING_NETWORK": "Ağ bekleniyor...",
"CHECKING_NEW_VERSION":"Yeni sürüm kontrol ediliyor...", "CHECKING_NEW_VERSION": "Yeni sürüm kontrol ediliyor...",
"CHECK_NEW_VERSION_FAILED":"Yeni sürüm kontrolü başarısız, %d saniye sonra tekrar denenecek: %s", "CHECK_NEW_VERSION_FAILED": "Yeni sürüm kontrolü başarısız, %d saniye sonra tekrar denenecek: %s",
"SWITCH_TO_WIFI_NETWORK":"Wi-Fi'ye geçiliyor...", "SWITCH_TO_WIFI_NETWORK": "Wi-Fi'ye geçiliyor...",
"SWITCH_TO_4G_NETWORK":"4G'ye geçiliyor...", "SWITCH_TO_4G_NETWORK": "4G'ye geçiliyor...",
"STANDBY": "Bekleme",
"STANDBY":"Bekleme", "CONNECT_TO": "Bağlan ",
"CONNECT_TO":"Bağlan ", "CONNECTING": "Bağlanıyor...",
"CONNECTING":"Bağlanıyor...", "CONNECTED_TO": "Bağlandı ",
"CONNECTED_TO":"Bağlandı ", "LISTENING": "Dinleniyor...",
"SPEAKING": "Konuşuluyor...",
"LISTENING":"Dinleniyor...", "SERVER_NOT_FOUND": "Mevcut hizmet aranıyor",
"SPEAKING":"Konuşuluyor...", "SERVER_NOT_CONNECTED": "Hizmete bağlanılamıyor, lütfen daha sonra deneyin",
"SERVER_TIMEOUT": "Yanıt zaman aşımı",
"SERVER_NOT_FOUND":"Mevcut hizmet aranıyor", "SERVER_ERROR": "Gönderme başarısız, ağı kontrol edin",
"SERVER_NOT_CONNECTED":"Hizmete bağlanılamıyor, lütfen daha sonra deneyin", "CONNECT_TO_HOTSPOT": "Telefonu hotspot'a bağlayın ",
"SERVER_TIMEOUT":"Yanıt zaman aşımı", "ACCESS_VIA_BROWSER": "tarayıcı üzerinden erişin ",
"SERVER_ERROR":"nderme başarısız, ağı kontrol edin", "WIFI_CONFIG_MODE": "Ağ yapılandırma modu",
"ENTERING_WIFI_CONFIG_MODE": "Ağ yapılandırma moduna giriliyor...",
"CONNECT_TO_HOTSPOT":"Telefonu hotspot'a bağlayın ", "SCANNING_WIFI": "Wi-Fi taranıyor...",
"ACCESS_VIA_BROWSER":"tarayıcı üzerinden erişin ",
"WIFI_CONFIG_MODE":"Ağ yapılandırma modu",
"ENTERING_WIFI_CONFIG_MODE":"Ağ yapılandırma moduna giriliyor...",
"SCANNING_WIFI":"Wi-Fi taranıyor...",
"NEW_VERSION": "Yeni sürüm ", "NEW_VERSION": "Yeni sürüm ",
"OTA_UPGRADE":"OTA güncelleme", "OTA_UPGRADE": "OTA güncelleme",
"UPGRADING":"Sistem güncelleniyor...", "UPGRADING": "Sistem güncelleniyor...",
"UPGRADE_FAILED":"Güncelleme başarısız", "UPGRADE_FAILED": "Güncelleme başarısız",
"ACTIVATION":"Cihaz aktivasyonu", "ACTIVATION": "Cihaz aktivasyonu",
"BATTERY_LOW": "Pil düşük",
"BATTERY_LOW":"Pil düşük", "BATTERY_CHARGING": "Şarj oluyor",
"BATTERY_CHARGING":"Şarj oluyor", "BATTERY_FULL": "Pil dolu",
"BATTERY_FULL":"Pil dolu", "BATTERY_NEED_CHARGE": "Pil düşük, lütfen şarj edin",
"BATTERY_NEED_CHARGE":"Pil düşük, lütfen şarj edin", "VOLUME": "Ses ",
"MUTED": "Sessiz",
"VOLUME":"Ses ", "MAX_VOLUME": "Maksimum ses",
"MUTED":"Sessiz", "RTC_MODE_OFF": "AEC kapalı",
"MAX_VOLUME":"Maksimum ses", "RTC_MODE_ON": "AEC açık",
"DOWNLOAD_ASSETS_FAILED": "Varlıklar indirilemedi",
"RTC_MODE_OFF":"AEC kapalı", "LOADING_ASSETS": "Varlıklar yükleniyor...",
"RTC_MODE_ON":"AEC açık" "PLEASE_WAIT": "Lütfen bekleyin...",
"FOUND_NEW_ASSETS": "Yeni varlıklar bulundu: %s",
"HELLO_MY_FRIEND": "Merhaba, arkadaşım!"
} }
} }

View File

@@ -1,58 +1,55 @@
{ {
"language": { "language": {
"type" :"uk-UA" "type": "uk-UA"
}, },
"strings": { "strings": {
"WARNING":"Попередження", "WARNING": "Попередження",
"INFO":"Інформація", "INFO": "Інформація",
"ERROR":"Помилка", "ERROR": "Помилка",
"VERSION": "Версія ", "VERSION": "Версія ",
"LOADING_PROTOCOL":"Підключення до сервера...", "LOADING_PROTOCOL": "Підключення до сервера...",
"INITIALIZING":"Ініціалізація...", "INITIALIZING": "Ініціалізація...",
"PIN_ERROR":"Будь ласка, вставте SIM-карту", "PIN_ERROR": "Будь ласка, вставте SIM-карту",
"REG_ERROR":"Неможливо отримати доступ до мережі, перевірте стан карти даних", "REG_ERROR": "Неможливо отримати доступ до мережі, перевірте стан карти даних",
"DETECTING_MODULE":"Виявлення модуля...", "DETECTING_MODULE": "Виявлення модуля...",
"REGISTERING_NETWORK":"Очікування мережі...", "REGISTERING_NETWORK": "Очікування мережі...",
"CHECKING_NEW_VERSION":"Перевірка нової версії...", "CHECKING_NEW_VERSION": "Перевірка нової версії...",
"CHECK_NEW_VERSION_FAILED":"Перевірка нової версії не вдалася, повтор через %d секунд: %s", "CHECK_NEW_VERSION_FAILED": "Перевірка нової версії не вдалася, повтор через %d секунд: %s",
"SWITCH_TO_WIFI_NETWORK":"Перемикання на Wi-Fi...", "SWITCH_TO_WIFI_NETWORK": "Перемикання на Wi-Fi...",
"SWITCH_TO_4G_NETWORK":"Перемикання на 4G...", "SWITCH_TO_4G_NETWORK": "Перемикання на 4G...",
"STANDBY": "Очікування",
"STANDBY":"Очікування", "CONNECT_TO": "Підключитися до ",
"CONNECT_TO":"Підключитися до ", "CONNECTING": "Підключення...",
"CONNECTING":"Підключення...", "CONNECTED_TO": "Підключено до ",
"CONNECTED_TO":ідключено до ", "LISTENING": рослуховування...",
"SPEAKING": "Говоріння...",
"LISTENING":рослуховування...", "SERVER_NOT_FOUND": ошук доступного сервісу",
"SPEAKING":"Говоріння...", "SERVER_NOT_CONNECTED": "Неможливо підключитися до сервісу, спробуйте пізніше",
"SERVER_TIMEOUT": "Час очікування відповіді",
"SERVER_NOT_FOUND":"Пошук доступного сервісу", "SERVER_ERROR": "Помилка відправки, перевірте мережу",
"SERVER_NOT_CONNECTED":"Неможливо підключитися до сервісу, спробуйте пізніше", "CONNECT_TO_HOTSPOT": "Підключіть телефон до точки доступу ",
"SERVER_TIMEOUT":"Час очікування відповіді", "ACCESS_VIA_BROWSER": ",доступ через браузер ",
"SERVER_ERROR":"Помилка відправки, перевірте мережу", "WIFI_CONFIG_MODE": "Режим налаштування мережі",
"ENTERING_WIFI_CONFIG_MODE": "Вхід у режим налаштування мережі...",
"CONNECT_TO_HOTSPOT":"Підключіть телефон до точки доступу ", "SCANNING_WIFI": "Сканування Wi-Fi...",
"ACCESS_VIA_BROWSER":",доступ через браузер ",
"WIFI_CONFIG_MODE":"Режим налаштування мережі",
"ENTERING_WIFI_CONFIG_MODE":"Вхід у режим налаштування мережі...",
"SCANNING_WIFI":"Сканування Wi-Fi...",
"NEW_VERSION": "Нова версія ", "NEW_VERSION": "Нова версія ",
"OTA_UPGRADE":"Оновлення OTA", "OTA_UPGRADE": "Оновлення OTA",
"UPGRADING":"Оновлення системи...", "UPGRADING": "Оновлення системи...",
"UPGRADE_FAILED":"Оновлення не вдалося", "UPGRADE_FAILED": "Оновлення не вдалося",
"ACTIVATION":"Активація пристрою", "ACTIVATION": "Активація пристрою",
"BATTERY_LOW": "Низький заряд батареї",
"BATTERY_LOW":"Низький заряд батареї", "BATTERY_CHARGING": "Зарядка",
"BATTERY_CHARGING":"Зарядка", "BATTERY_FULL": "Батарея повна",
"BATTERY_FULL":"Батарея повна", "BATTERY_NEED_CHARGE": "Низький заряд, будь ласка, зарядіть",
"BATTERY_NEED_CHARGE":"Низький заряд, будь ласка, зарядіть", "VOLUME": "Гучність ",
"MUTED": "Звук вимкнено",
"VOLUME":"Гучність ", "MAX_VOLUME": "Максимальна гучність",
"MUTED":"Звук вимкнено", "RTC_MODE_OFF": "AEC вимкнено",
"MAX_VOLUME":"Максимальна гучність", "RTC_MODE_ON": "AEC увімкнено",
"DOWNLOAD_ASSETS_FAILED": "Не вдалося завантажити ресурси",
"RTC_MODE_OFF":"AEC вимкнено", "LOADING_ASSETS": "Завантаження ресурсів...",
"RTC_MODE_ON":"AEC увімкнено" "PLEASE_WAIT": "Будь ласка, зачекайте...",
"FOUND_NEW_ASSETS": "Знайдено нові ресурси: %s",
"HELLO_MY_FRIEND": "Привіт, мій друже!"
} }
} }

View File

@@ -17,43 +17,40 @@
"CHECK_NEW_VERSION_FAILED": "Kiểm tra phiên bản mới thất bại, sẽ thử lại sau %d giây: %s", "CHECK_NEW_VERSION_FAILED": "Kiểm tra phiên bản mới thất bại, sẽ thử lại sau %d giây: %s",
"SWITCH_TO_WIFI_NETWORK": "Đang chuyển sang Wi-Fi...", "SWITCH_TO_WIFI_NETWORK": "Đang chuyển sang Wi-Fi...",
"SWITCH_TO_4G_NETWORK": "Đang chuyển sang 4G...", "SWITCH_TO_4G_NETWORK": "Đang chuyển sang 4G...",
"STANDBY": "Chờ", "STANDBY": "Chờ",
"CONNECT_TO": "Kết nối đến ", "CONNECT_TO": "Kết nối đến ",
"CONNECTING": "Đang kết nối...", "CONNECTING": "Đang kết nối...",
"CONNECTION_SUCCESSFUL": "Kết nối thành công", "CONNECTION_SUCCESSFUL": "Kết nối thành công",
"CONNECTED_TO": "Đã kết nối đến ", "CONNECTED_TO": "Đã kết nối đến ",
"LISTENING": "Đang lắng nghe...", "LISTENING": "Đang lắng nghe...",
"SPEAKING": "Đang nói...", "SPEAKING": "Đang nói...",
"SERVER_NOT_FOUND": "Đang tìm dịch vụ khả dụng", "SERVER_NOT_FOUND": "Đang tìm dịch vụ khả dụng",
"SERVER_NOT_CONNECTED": "Không thể kết nối đến dịch vụ, vui lòng thử lại sau", "SERVER_NOT_CONNECTED": "Không thể kết nối đến dịch vụ, vui lòng thử lại sau",
"SERVER_TIMEOUT": "Hết thời gian chờ phản hồi", "SERVER_TIMEOUT": "Hết thời gian chờ phản hồi",
"SERVER_ERROR": "Gửi thất bại, vui lòng kiểm tra mạng", "SERVER_ERROR": "Gửi thất bại, vui lòng kiểm tra mạng",
"CONNECT_TO_HOTSPOT": "Điểm phát sóng: ", "CONNECT_TO_HOTSPOT": "Điểm phát sóng: ",
"ACCESS_VIA_BROWSER": " URL cấu hình: ", "ACCESS_VIA_BROWSER": " URL cấu hình: ",
"WIFI_CONFIG_MODE": "Chế độ cấu hình Wi-Fi", "WIFI_CONFIG_MODE": "Chế độ cấu hình Wi-Fi",
"ENTERING_WIFI_CONFIG_MODE": "Đang vào chế độ cấu hình Wi-Fi...", "ENTERING_WIFI_CONFIG_MODE": "Đang vào chế độ cấu hình Wi-Fi...",
"SCANNING_WIFI": "Đang quét Wi-Fi...", "SCANNING_WIFI": "Đang quét Wi-Fi...",
"NEW_VERSION": "Phiên bản mới ", "NEW_VERSION": "Phiên bản mới ",
"OTA_UPGRADE": "Nâng cấp OTA", "OTA_UPGRADE": "Nâng cấp OTA",
"UPGRADING": "Hệ thống đang nâng cấp...", "UPGRADING": "Hệ thống đang nâng cấp...",
"UPGRADE_FAILED": "Nâng cấp thất bại", "UPGRADE_FAILED": "Nâng cấp thất bại",
"ACTIVATION": "Kích hoạt", "ACTIVATION": "Kích hoạt",
"BATTERY_LOW": "Pin yếu", "BATTERY_LOW": "Pin yếu",
"BATTERY_CHARGING": "Đang sạc", "BATTERY_CHARGING": "Đang sạc",
"BATTERY_FULL": "Pin đầy", "BATTERY_FULL": "Pin đầy",
"BATTERY_NEED_CHARGE": "Pin yếu, vui lòng sạc", "BATTERY_NEED_CHARGE": "Pin yếu, vui lòng sạc",
"VOLUME": "Âm lượng ", "VOLUME": "Âm lượng ",
"MUTED": "Tắt tiếng", "MUTED": "Tắt tiếng",
"MAX_VOLUME": "Âm lượng tối đa", "MAX_VOLUME": "Âm lượng tối đa",
"RTC_MODE_OFF": "Tắt AEC", "RTC_MODE_OFF": "Tắt AEC",
"RTC_MODE_ON": "Bật AEC" "RTC_MODE_ON": "Bật AEC",
"DOWNLOAD_ASSETS_FAILED": "Tải xuống tài nguyên thất bại",
"LOADING_ASSETS": "Đang tải tài nguyên...",
"PLEASE_WAIT": "Vui lòng đợi...",
"FOUND_NEW_ASSETS": "Tìm thấy tài nguyên mới: %s",
"HELLO_MY_FRIEND": "Xin chào, bạn của tôi!"
} }
} }

View File

@@ -1,58 +1,55 @@
{ {
"language": { "language": {
"type" :"zh-CN" "type": "zh-CN"
}, },
"strings": { "strings": {
"WARNING":"警告", "WARNING": "警告",
"INFO":"信息", "INFO": "信息",
"ERROR":"错误", "ERROR": "错误",
"VERSION": "版本 ", "VERSION": "版本 ",
"LOADING_PROTOCOL":"登录服务器...", "LOADING_PROTOCOL": "登录服务器...",
"INITIALIZING":"正在初始化...", "INITIALIZING": "正在初始化...",
"PIN_ERROR":"请插入 SIM 卡", "PIN_ERROR": "请插入 SIM 卡",
"REG_ERROR":"无法接入网络,请检查流量卡状态", "REG_ERROR": "无法接入网络,请检查流量卡状态",
"DETECTING_MODULE":"检测模组...", "DETECTING_MODULE": "检测模组...",
"REGISTERING_NETWORK":"等待网络...", "REGISTERING_NETWORK": "等待网络...",
"CHECKING_NEW_VERSION":"检查新版本...", "CHECKING_NEW_VERSION": "检查新版本...",
"CHECK_NEW_VERSION_FAILED":"检查新版本失败,将在 %d 秒后重试:%s", "CHECK_NEW_VERSION_FAILED": "检查新版本失败,将在 %d 秒后重试:%s",
"SWITCH_TO_WIFI_NETWORK":"切换到 Wi-Fi...", "SWITCH_TO_WIFI_NETWORK": "切换到 Wi-Fi...",
"SWITCH_TO_4G_NETWORK":"切换到 4G...", "SWITCH_TO_4G_NETWORK": "切换到 4G...",
"STANDBY": "待命",
"STANDBY":"待命", "CONNECT_TO": "连接 ",
"CONNECT_TO":"连接 ", "CONNECTING": "连接中...",
"CONNECTING":"连接中...", "CONNECTED_TO": "连接 ",
"CONNECTED_TO":"已连接 ", "LISTENING": "聆听中...",
"SPEAKING": "说话中...",
"LISTENING":"聆听中...", "SERVER_NOT_FOUND": "正在寻找可用服务",
"SPEAKING":"说话中...", "SERVER_NOT_CONNECTED": "无法连接服务,请稍后再试",
"SERVER_TIMEOUT": "等待响应超时",
"SERVER_NOT_FOUND":"正在寻找可用服务", "SERVER_ERROR": "发送失败,请检查网络",
"SERVER_NOT_CONNECTED":"无法连接服务,请稍后再试", "CONNECT_TO_HOTSPOT": "手机连接热点 ",
"SERVER_TIMEOUT":"等待响应超时", "ACCESS_VIA_BROWSER": ",浏览器访问 ",
"SERVER_ERROR":"发送失败,请检查网络", "WIFI_CONFIG_MODE": "配网模式",
"ENTERING_WIFI_CONFIG_MODE": "进入配网模式...",
"CONNECT_TO_HOTSPOT":"手机连接热点 ", "SCANNING_WIFI": "扫描 Wi-Fi...",
"ACCESS_VIA_BROWSER":",浏览器访问 ",
"WIFI_CONFIG_MODE":"配网模式",
"ENTERING_WIFI_CONFIG_MODE":"进入配网模式...",
"SCANNING_WIFI":"扫描 Wi-Fi...",
"NEW_VERSION": "新版本 ", "NEW_VERSION": "新版本 ",
"OTA_UPGRADE":"OTA 升级", "OTA_UPGRADE": "OTA 升级",
"UPGRADING":"正在升级系统...", "UPGRADING": "正在升级系统...",
"UPGRADE_FAILED":"升级失败", "UPGRADE_FAILED": "升级失败",
"ACTIVATION":"激活设备", "ACTIVATION": "激活设备",
"BATTERY_LOW": "电量不足",
"BATTERY_LOW":"电量不足", "BATTERY_CHARGING": "正在充电",
"BATTERY_CHARGING":"正在充电", "BATTERY_FULL": "电量已满",
"BATTERY_FULL":"电量已满", "BATTERY_NEED_CHARGE": "电量低,请充电",
"BATTERY_NEED_CHARGE":"电量低,请充电", "VOLUME": "音量 ",
"MUTED": "已静音",
"VOLUME":"音量 ", "MAX_VOLUME": "最大音量",
"MUTED":"已静音", "RTC_MODE_OFF": "AEC 关闭",
"MAX_VOLUME":"最大音量", "RTC_MODE_ON": "AEC 开启",
"DOWNLOAD_ASSETS_FAILED": "下载资源失败",
"RTC_MODE_OFF":"AEC 关闭", "LOADING_ASSETS": "加载资源...",
"RTC_MODE_ON":"AEC 开启" "PLEASE_WAIT": "请稍候...",
"FOUND_NEW_ASSETS": "发现新资源: %s",
"HELLO_MY_FRIEND": "你好,我的朋友!"
} }
} }

View File

@@ -17,42 +17,39 @@
"CHECK_NEW_VERSION_FAILED": "檢查新版本失敗,將在 %d 秒後重試:%s", "CHECK_NEW_VERSION_FAILED": "檢查新版本失敗,將在 %d 秒後重試:%s",
"SWITCH_TO_WIFI_NETWORK": "切換到 Wi-Fi...", "SWITCH_TO_WIFI_NETWORK": "切換到 Wi-Fi...",
"SWITCH_TO_4G_NETWORK": "切換到 4G...", "SWITCH_TO_4G_NETWORK": "切換到 4G...",
"STANDBY": "待命", "STANDBY": "待命",
"CONNECT_TO": "連接 ", "CONNECT_TO": "連接 ",
"CONNECTING": "連接中...", "CONNECTING": "連接中...",
"CONNECTED_TO": "已連接 ", "CONNECTED_TO": "已連接 ",
"LISTENING": "聆聽中...", "LISTENING": "聆聽中...",
"SPEAKING": "說話中...", "SPEAKING": "說話中...",
"SERVER_NOT_FOUND": "正在尋找可用服務", "SERVER_NOT_FOUND": "正在尋找可用服務",
"SERVER_NOT_CONNECTED": "無法連接服務,請稍後再試", "SERVER_NOT_CONNECTED": "無法連接服務,請稍後再試",
"SERVER_TIMEOUT": "等待響應超時", "SERVER_TIMEOUT": "等待響應超時",
"SERVER_ERROR": "發送失敗,請檢查網絡", "SERVER_ERROR": "發送失敗,請檢查網絡",
"CONNECT_TO_HOTSPOT": "手機連接WiFi ", "CONNECT_TO_HOTSPOT": "手機連接WiFi ",
"ACCESS_VIA_BROWSER": ",瀏覽器訪問 ", "ACCESS_VIA_BROWSER": ",瀏覽器訪問 ",
"WIFI_CONFIG_MODE": "網路設定模式", "WIFI_CONFIG_MODE": "網路設定模式",
"ENTERING_WIFI_CONFIG_MODE": "正在設定網路...", "ENTERING_WIFI_CONFIG_MODE": "正在設定網路...",
"SCANNING_WIFI": "掃描 Wi-Fi...", "SCANNING_WIFI": "掃描 Wi-Fi...",
"NEW_VERSION": "新版本 ", "NEW_VERSION": "新版本 ",
"OTA_UPGRADE": "OTA 升級", "OTA_UPGRADE": "OTA 升級",
"UPGRADING": "正在升級系統...", "UPGRADING": "正在升級系統...",
"UPGRADE_FAILED": "升級失敗", "UPGRADE_FAILED": "升級失敗",
"ACTIVATION": "啟用設備", "ACTIVATION": "啟用設備",
"BATTERY_LOW": "電量不足", "BATTERY_LOW": "電量不足",
"BATTERY_CHARGING": "正在充電", "BATTERY_CHARGING": "正在充電",
"BATTERY_FULL": "電量已滿", "BATTERY_FULL": "電量已滿",
"BATTERY_NEED_CHARGE": "電量低,請充電", "BATTERY_NEED_CHARGE": "電量低,請充電",
"VOLUME": "音量 ", "VOLUME": "音量 ",
"MUTED": "已靜音", "MUTED": "已靜音",
"MAX_VOLUME": "最大音量", "MAX_VOLUME": "最大音量",
"RTC_MODE_OFF": "AEC 關閉", "RTC_MODE_OFF": "AEC 關閉",
"RTC_MODE_ON": "AEC 開啟" "RTC_MODE_ON": "AEC 開啟",
"DOWNLOAD_ASSETS_FAILED": "下載資源失敗",
"LOADING_ASSETS": "載入資源...",
"PLEASE_WAIT": "請稍候...",
"FOUND_NEW_ASSETS": "發現新資源: %s",
"HELLO_MY_FRIEND": "你好,我的朋友!"
} }
} }

View File

@@ -8,28 +8,28 @@
#define TAG "AudioCodec" #define TAG "AudioCodec"
AudioCodec::AudioCodec(){ AudioCodec::AudioCodec() {
} }
AudioCodec::~AudioCodec(){ AudioCodec::~AudioCodec() {
} }
void AudioCodec::OutputData(std::vector<int16_t> &data){ void AudioCodec::OutputData(std::vector<int16_t>& data) {
Write(data.data(), data.size()); Write(data.data(), data.size());
} }
bool AudioCodec::InputData(std::vector<int16_t> &data){ bool AudioCodec::InputData(std::vector<int16_t>& data) {
int samples = Read(data.data(), data.size()); int samples = Read(data.data(), data.size());
if (samples > 0){ if (samples > 0) {
return true; return true;
} }
return false; return false;
} }
void AudioCodec::Start(){ void AudioCodec::Start() {
Settings settings("audio", false); Settings settings("audio", false);
output_volume_ = settings.GetInt("output_volume", output_volume_); output_volume_ = settings.GetInt("output_volume", output_volume_);
if (output_volume_ <= 0){ if (output_volume_ <= 0) {
ESP_LOGW(TAG, "Output volume value (%d) is too small, setting to default (10)", output_volume_); ESP_LOGW(TAG, "Output volume value (%d) is too small, setting to default (10)", output_volume_);
output_volume_ = 10; output_volume_ = 10;
} }
@@ -40,11 +40,11 @@ void AudioCodec::Start(){
ESP_LOGI(TAG, "Saved original output sample rate: %d Hz", original_output_sample_rate_); ESP_LOGI(TAG, "Saved original output sample rate: %d Hz", original_output_sample_rate_);
} }
if (tx_handle_ != nullptr){ if (tx_handle_ != nullptr) {
ESP_ERROR_CHECK(i2s_channel_enable(tx_handle_)); ESP_ERROR_CHECK(i2s_channel_enable(tx_handle_));
} }
if (rx_handle_ != nullptr){ if (rx_handle_ != nullptr) {
ESP_ERROR_CHECK(i2s_channel_enable(rx_handle_)); ESP_ERROR_CHECK(i2s_channel_enable(rx_handle_));
} }
@@ -53,74 +53,73 @@ void AudioCodec::Start(){
ESP_LOGI(TAG, "Audio codec started"); ESP_LOGI(TAG, "Audio codec started");
} }
void AudioCodec::SetOutputVolume(int volume){ void AudioCodec::SetOutputVolume(int volume) {
output_volume_ = volume; output_volume_ = volume;
ESP_LOGI(TAG, "Set output volume to %d", output_volume_); ESP_LOGI(TAG, "Set output volume to %d", output_volume_);
Settings settings("audio", true); Settings settings("audio", true);
settings.SetInt("output_volume", output_volume_); settings.SetInt("output_volume", output_volume_);
} }
void AudioCodec::EnableInput(bool enable){ void AudioCodec::EnableInput(bool enable) {
if (enable == input_enabled_){ if (enable == input_enabled_) {
return; return;
} }
input_enabled_ = enable; input_enabled_ = enable;
ESP_LOGI(TAG, "Set input enable to %s", enable ? "true" : "false"); ESP_LOGI(TAG, "Set input enable to %s", enable ? "true" : "false");
} }
void AudioCodec::EnableOutput(bool enable){ void AudioCodec::EnableOutput(bool enable) {
if (enable == output_enabled_){ if (enable == output_enabled_) {
return; return;
} }
output_enabled_ = enable; output_enabled_ = enable;
ESP_LOGI(TAG, "Set output enable to %s", enable ? "true" : "false"); ESP_LOGI(TAG, "Set output enable to %s", enable ? "true" : "false");
} }
bool AudioCodec::SetOutputSampleRate(int sample_rate){ bool AudioCodec::SetOutputSampleRate(int sample_rate) {
// 特殊处理:如果传入 -1表示重置到原始采样率 // 特殊处理:如果传入 -1表示重置到原始采样率
if (sample_rate == -1){ if (sample_rate == -1) {
if (original_output_sample_rate_ > 0){ if (original_output_sample_rate_ > 0) {
sample_rate = original_output_sample_rate_; sample_rate = original_output_sample_rate_;
ESP_LOGI(TAG, "Resetting to original output sample rate: %d Hz", sample_rate); ESP_LOGI(TAG, "Resetting to original output sample rate: %d Hz", sample_rate);
}else{ } else {
ESP_LOGW(TAG, "Original sample rate not available, cannot reset"); ESP_LOGW(TAG, "Original sample rate not available, cannot reset");
return false; return false;
} }
} }
if (sample_rate <= 0 || sample_rate > 192000){ if (sample_rate <= 0 || sample_rate > 192000) {
ESP_LOGE(TAG, "Invalid sample rate: %d", sample_rate); ESP_LOGE(TAG, "Invalid sample rate: %d", sample_rate);
return false; return false;
} }
if (output_sample_rate_ == sample_rate){ if (output_sample_rate_ == sample_rate) {
ESP_LOGI(TAG, "Sample rate already set to %d Hz", sample_rate); ESP_LOGI(TAG, "Sample rate already set to %d Hz", sample_rate);
return true; return true;
} }
if (tx_handle_ == nullptr){ if (tx_handle_ == nullptr) {
ESP_LOGW(TAG, "TX handle is null, only updating sample rate variable"); ESP_LOGW(TAG, "TX handle is null, only updating sample rate variable");
output_sample_rate_ = sample_rate; output_sample_rate_ = sample_rate;
return true; return true;
} }
ESP_LOGI(TAG, "Changing output sample rate from %d to %d Hz", output_sample_rate_, sample_rate); ESP_LOGI(TAG, "Changing output sample rate from %d to %d Hz", output_sample_rate_, sample_rate);
// 先尝试禁用 I2S 通道(如果已启用的话) // 先尝试禁用 I2S 通道(如果已启用的话)
bool was_enabled = false; bool was_enabled = false;
esp_err_t disable_ret = i2s_channel_disable(tx_handle_); esp_err_t disable_ret = i2s_channel_disable(tx_handle_);
if (disable_ret == ESP_OK){ if (disable_ret == ESP_OK) {
was_enabled = true; was_enabled = true;
ESP_LOGI(TAG, "Disabled I2S TX channel for reconfiguration"); ESP_LOGI(TAG, "Disabled I2S TX channel for reconfiguration");
} } else if (disable_ret == ESP_ERR_INVALID_STATE) {
else if (disable_ret == ESP_ERR_INVALID_STATE){
// 通道可能已经是禁用状态,这是正常的 // 通道可能已经是禁用状态,这是正常的
ESP_LOGI(TAG, "I2S TX channel was already disabled"); ESP_LOGI(TAG, "I2S TX channel was already disabled");
}else{ } else {
ESP_LOGW(TAG, "Failed to disable I2S TX channel: %s", esp_err_to_name(disable_ret)); ESP_LOGW(TAG, "Failed to disable I2S TX channel: %s", esp_err_to_name(disable_ret));
} }
// 重新配置 I2S 时钟 // 重新配置 I2S 时钟
i2s_std_clk_config_t clk_cfg = { i2s_std_clk_config_t clk_cfg = {
.sample_rate_hz = (uint32_t)sample_rate, .sample_rate_hz = (uint32_t)sample_rate,
@@ -130,23 +129,23 @@ bool AudioCodec::SetOutputSampleRate(int sample_rate){
.ext_clk_freq_hz = 0, .ext_clk_freq_hz = 0,
#endif #endif
}; };
esp_err_t ret = i2s_channel_reconfig_std_clock(tx_handle_, &clk_cfg); esp_err_t ret = i2s_channel_reconfig_std_clock(tx_handle_, &clk_cfg);
// 重新启用通道(无论之前是什么状态,现在都需要启用以便播放音频) // 重新启用通道(无论之前是什么状态,现在都需要启用以便播放音频)
esp_err_t enable_ret = i2s_channel_enable(tx_handle_); esp_err_t enable_ret = i2s_channel_enable(tx_handle_);
if (enable_ret != ESP_OK){ if (enable_ret != ESP_OK) {
ESP_LOGE(TAG, "Failed to enable I2S TX channel: %s", esp_err_to_name(enable_ret)); ESP_LOGE(TAG, "Failed to enable I2S TX channel: %s", esp_err_to_name(enable_ret));
}else{ } else {
ESP_LOGI(TAG, "Enabled I2S TX channel"); ESP_LOGI(TAG, "Enabled I2S TX channel");
} }
if (ret == ESP_OK){ if (ret == ESP_OK) {
output_sample_rate_ = sample_rate; output_sample_rate_ = sample_rate;
ESP_LOGI(TAG, "Successfully changed output sample rate to %d Hz", sample_rate); ESP_LOGI(TAG, "Successfully changed output sample rate to %d Hz", sample_rate);
return true; return true;
}else{ } else {
ESP_LOGE(TAG, "Failed to change sample rate to %d Hz: %s", sample_rate, esp_err_to_name(ret)); ESP_LOGE(TAG, "Failed to change sample rate to %d Hz: %s", sample_rate, esp_err_to_name(ret));
return false; return false;
} }
} }

View File

@@ -5,13 +5,14 @@
#include <vector> #include <vector>
#include <functional> #include <functional>
#include <model_path.h>
#include "audio_codec.h" #include "audio_codec.h"
class AudioProcessor { class AudioProcessor {
public: public:
virtual ~AudioProcessor() = default; virtual ~AudioProcessor() = default;
virtual void Initialize(AudioCodec* codec, int frame_duration_ms) = 0; virtual void Initialize(AudioCodec* codec, int frame_duration_ms, srmodel_list_t* models_list) = 0;
virtual void Feed(std::vector<int16_t>&& data) = 0; virtual void Feed(std::vector<int16_t>&& data) = 0;
virtual void Start() = 0; virtual void Start() = 0;
virtual void Stop() = 0; virtual void Stop() = 0;

View File

@@ -111,7 +111,7 @@ void AudioService::Start() {
AudioService* audio_service = (AudioService*)arg; AudioService* audio_service = (AudioService*)arg;
audio_service->AudioOutputTask(); audio_service->AudioOutputTask();
vTaskDelete(NULL); vTaskDelete(NULL);
}, "audio_output", 2048 * 2, this, 3, &audio_output_task_handle_); }, "audio_output", 2048 * 2, this, 4, &audio_output_task_handle_);
#else #else
/* Start the audio input task */ /* Start the audio input task */
xTaskCreate([](void* arg) { xTaskCreate([](void* arg) {
@@ -125,7 +125,7 @@ void AudioService::Start() {
AudioService* audio_service = (AudioService*)arg; AudioService* audio_service = (AudioService*)arg;
audio_service->AudioOutputTask(); audio_service->AudioOutputTask();
vTaskDelete(NULL); vTaskDelete(NULL);
}, "audio_output", 2048, this, 3, &audio_output_task_handle_); }, "audio_output", 2048, this, 4, &audio_output_task_handle_);
#endif #endif
/* Start the opus codec task */ /* Start the opus codec task */
@@ -479,7 +479,7 @@ void AudioService::EnableWakeWordDetection(bool enable) {
ESP_LOGD(TAG, "%s wake word detection", enable ? "Enabling" : "Disabling"); ESP_LOGD(TAG, "%s wake word detection", enable ? "Enabling" : "Disabling");
if (enable) { if (enable) {
if (!wake_word_initialized_) { if (!wake_word_initialized_) {
if (!wake_word_->Initialize(codec_)) { if (!wake_word_->Initialize(codec_, models_list_)) {
ESP_LOGE(TAG, "Failed to initialize wake word"); ESP_LOGE(TAG, "Failed to initialize wake word");
return; return;
} }
@@ -497,7 +497,7 @@ void AudioService::EnableVoiceProcessing(bool enable) {
ESP_LOGD(TAG, "%s voice processing", enable ? "Enabling" : "Disabling"); ESP_LOGD(TAG, "%s voice processing", enable ? "Enabling" : "Disabling");
if (enable) { if (enable) {
if (!audio_processor_initialized_) { if (!audio_processor_initialized_) {
audio_processor_->Initialize(codec_, OPUS_FRAME_DURATION_MS); audio_processor_->Initialize(codec_, OPUS_FRAME_DURATION_MS, models_list_);
audio_processor_initialized_ = true; audio_processor_initialized_ = true;
} }
@@ -528,7 +528,7 @@ void AudioService::EnableAudioTesting(bool enable) {
void AudioService::EnableDeviceAec(bool enable) { void AudioService::EnableDeviceAec(bool enable) {
ESP_LOGI(TAG, "%s device AEC", enable ? "Enabling" : "Disabling"); ESP_LOGI(TAG, "%s device AEC", enable ? "Enabling" : "Disabling");
if (!audio_processor_initialized_) { if (!audio_processor_initialized_) {
audio_processor_->Initialize(codec_, OPUS_FRAME_DURATION_MS); audio_processor_->Initialize(codec_, OPUS_FRAME_DURATION_MS, models_list_);
audio_processor_initialized_ = true; audio_processor_initialized_ = true;
} }
@@ -668,6 +668,10 @@ void AudioService::CheckAndUpdateAudioPowerState() {
} }
} }
void AudioService::SetModelsList(srmodel_list_t* models_list) {
models_list_ = models_list;
}
void AudioService::UpdateOutputTimestamp() { void AudioService::UpdateOutputTimestamp() {
last_output_time_ = std::chrono::steady_clock::now(); last_output_time_ = std::chrono::steady_clock::now();
} }

View File

@@ -11,6 +11,7 @@
#include <freertos/task.h> #include <freertos/task.h>
#include <freertos/event_groups.h> #include <freertos/event_groups.h>
#include <esp_timer.h> #include <esp_timer.h>
#include <model_path.h>
#include <opus_encoder.h> #include <opus_encoder.h>
#include <opus_decoder.h> #include <opus_decoder.h>
@@ -106,6 +107,7 @@ public:
void PlaySound(const std::string_view& sound); void PlaySound(const std::string_view& sound);
bool ReadAudioData(std::vector<int16_t>& data, int sample_rate, int samples); bool ReadAudioData(std::vector<int16_t>& data, int sample_rate, int samples);
void ResetDecoder(); void ResetDecoder();
void SetModelsList(srmodel_list_t* models_list);
void UpdateOutputTimestamp(); void UpdateOutputTimestamp();
@@ -121,6 +123,7 @@ private:
OpusResampler reference_resampler_; OpusResampler reference_resampler_;
OpusResampler output_resampler_; OpusResampler output_resampler_;
DebugStatistics debug_statistics_; DebugStatistics debug_statistics_;
srmodel_list_t* models_list_ = nullptr;
EventGroupHandle_t event_group_; EventGroupHandle_t event_group_;

View File

@@ -10,7 +10,7 @@ AfeAudioProcessor::AfeAudioProcessor()
event_group_ = xEventGroupCreate(); event_group_ = xEventGroupCreate();
} }
void AfeAudioProcessor::Initialize(AudioCodec* codec, int frame_duration_ms) { void AfeAudioProcessor::Initialize(AudioCodec* codec, int frame_duration_ms, srmodel_list_t* models_list) {
codec_ = codec; codec_ = codec;
frame_samples_ = frame_duration_ms * 16000 / 1000; frame_samples_ = frame_duration_ms * 16000 / 1000;
@@ -27,7 +27,13 @@ void AfeAudioProcessor::Initialize(AudioCodec* codec, int frame_duration_ms) {
input_format.push_back('R'); input_format.push_back('R');
} }
srmodel_list_t *models = esp_srmodel_init("model"); srmodel_list_t *models;
if (models_list == nullptr) {
models = esp_srmodel_init("model");
} else {
models = models_list;
}
char* ns_model_name = esp_srmodel_filter(models, ESP_NSNET_PREFIX, NULL); char* ns_model_name = esp_srmodel_filter(models, ESP_NSNET_PREFIX, NULL);
char* vad_model_name = esp_srmodel_filter(models, ESP_VADN_PREFIX, NULL); char* vad_model_name = esp_srmodel_filter(models, ESP_VADN_PREFIX, NULL);

View File

@@ -18,7 +18,7 @@ public:
AfeAudioProcessor(); AfeAudioProcessor();
~AfeAudioProcessor(); ~AfeAudioProcessor();
void Initialize(AudioCodec* codec, int frame_duration_ms) override; void Initialize(AudioCodec* codec, int frame_duration_ms, srmodel_list_t* models_list) override;
void Feed(std::vector<int16_t>&& data) override; void Feed(std::vector<int16_t>&& data) override;
void Start() override; void Start() override;
void Stop() override; void Stop() override;

View File

@@ -3,7 +3,7 @@
#define TAG "NoAudioProcessor" #define TAG "NoAudioProcessor"
void NoAudioProcessor::Initialize(AudioCodec* codec, int frame_duration_ms) { void NoAudioProcessor::Initialize(AudioCodec* codec, int frame_duration_ms, srmodel_list_t* models_list) {
codec_ = codec; codec_ = codec;
frame_samples_ = frame_duration_ms * 16000 / 1000; frame_samples_ = frame_duration_ms * 16000 / 1000;
} }

View File

@@ -12,7 +12,7 @@ public:
NoAudioProcessor() = default; NoAudioProcessor() = default;
~NoAudioProcessor() = default; ~NoAudioProcessor() = default;
void Initialize(AudioCodec* codec, int frame_duration_ms) override; void Initialize(AudioCodec* codec, int frame_duration_ms, srmodel_list_t* models_list) override;
void Feed(std::vector<int16_t>&& data) override; void Feed(std::vector<int16_t>&& data) override;
void Start() override; void Start() override;
void Stop() override; void Stop() override;

View File

@@ -5,13 +5,14 @@
#include <vector> #include <vector>
#include <functional> #include <functional>
#include <model_path.h>
#include "audio_codec.h" #include "audio_codec.h"
class WakeWord { class WakeWord {
public: public:
virtual ~WakeWord() = default; virtual ~WakeWord() = default;
virtual bool Initialize(AudioCodec* codec) = 0; virtual bool Initialize(AudioCodec* codec, srmodel_list_t* models_list) = 0;
virtual void Feed(const std::vector<int16_t>& data) = 0; virtual void Feed(const std::vector<int16_t>& data) = 0;
virtual void OnWakeWordDetected(std::function<void(const std::string& wake_word)> callback) = 0; virtual void OnWakeWordDetected(std::function<void(const std::string& wake_word)> callback) = 0;
virtual void Start() = 0; virtual void Start() = 0;

View File

@@ -36,11 +36,16 @@ AfeWakeWord::~AfeWakeWord() {
vEventGroupDelete(event_group_); vEventGroupDelete(event_group_);
} }
bool AfeWakeWord::Initialize(AudioCodec* codec) { bool AfeWakeWord::Initialize(AudioCodec* codec, srmodel_list_t* models_list) {
codec_ = codec; codec_ = codec;
int ref_num = codec_->input_reference() ? 1 : 0; int ref_num = codec_->input_reference() ? 1 : 0;
models_ = esp_srmodel_init("model"); if (models_list == nullptr) {
models_ = esp_srmodel_init("model");
} else {
models_ = models_list;
}
if (models_ == nullptr || models_->num == -1) { if (models_ == nullptr || models_->num == -1) {
ESP_LOGE(TAG, "Failed to initialize wakenet model"); ESP_LOGE(TAG, "Failed to initialize wakenet model");
return false; return false;

View File

@@ -24,7 +24,7 @@ public:
AfeWakeWord(); AfeWakeWord();
~AfeWakeWord(); ~AfeWakeWord();
bool Initialize(AudioCodec* codec); bool Initialize(AudioCodec* codec, srmodel_list_t* models_list);
void Feed(const std::vector<int16_t>& data); void Feed(const std::vector<int16_t>& data);
void OnWakeWordDetected(std::function<void(const std::string& wake_word)> callback); void OnWakeWordDetected(std::function<void(const std::string& wake_word)> callback);
void Start(); void Start();

View File

@@ -34,10 +34,15 @@ CustomWakeWord::~CustomWakeWord() {
} }
} }
bool CustomWakeWord::Initialize(AudioCodec* codec) { bool CustomWakeWord::Initialize(AudioCodec* codec, srmodel_list_t* models_list) {
codec_ = codec; codec_ = codec;
models_ = esp_srmodel_init("model"); if (models_list == nullptr) {
models_ = esp_srmodel_init("model");
} else {
models_ = models_list;
}
if (models_ == nullptr || models_->num == -1) { if (models_ == nullptr || models_->num == -1) {
ESP_LOGE(TAG, "Failed to initialize wakenet model"); ESP_LOGE(TAG, "Failed to initialize wakenet model");
return false; return false;

View File

@@ -22,7 +22,7 @@ public:
CustomWakeWord(); CustomWakeWord();
~CustomWakeWord(); ~CustomWakeWord();
bool Initialize(AudioCodec* codec); bool Initialize(AudioCodec* codec, srmodel_list_t* models_list);
void Feed(const std::vector<int16_t>& data); void Feed(const std::vector<int16_t>& data);
void OnWakeWordDetected(std::function<void(const std::string& wake_word)> callback); void OnWakeWordDetected(std::function<void(const std::string& wake_word)> callback);
void Start(); void Start();

View File

@@ -14,10 +14,15 @@ EspWakeWord::~EspWakeWord() {
} }
} }
bool EspWakeWord::Initialize(AudioCodec* codec) { bool EspWakeWord::Initialize(AudioCodec* codec, srmodel_list_t* models_list) {
codec_ = codec; codec_ = codec;
wakenet_model_ = esp_srmodel_init("model"); if (models_list == nullptr) {
wakenet_model_ = esp_srmodel_init("model");
} else {
wakenet_model_ = models_list;
}
if (wakenet_model_ == nullptr || wakenet_model_->num == -1) { if (wakenet_model_ == nullptr || wakenet_model_->num == -1) {
ESP_LOGE(TAG, "Failed to initialize wakenet model"); ESP_LOGE(TAG, "Failed to initialize wakenet model");
return false; return false;

View File

@@ -18,7 +18,7 @@ public:
EspWakeWord(); EspWakeWord();
~EspWakeWord(); ~EspWakeWord();
bool Initialize(AudioCodec* codec); bool Initialize(AudioCodec* codec, srmodel_list_t* models_list);
void Feed(const std::vector<int16_t>& data); void Feed(const std::vector<int16_t>& data);
void OnWakeWordDetected(std::function<void(const std::string& wake_word)> callback); void OnWakeWordDetected(std::function<void(const std::string& wake_word)> callback);
void Start(); void Start();

BIN
main/boards/.DS_Store vendored

Binary file not shown.

View File

@@ -98,7 +98,7 @@ mkdir main/boards/my-custom-board
"sdkconfig_append": [ "sdkconfig_append": [
// 额外需要的编译配置 // 额外需要的编译配置
"CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y", "CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y",
"CONFIG_PARTITION_TABLE_CUSTOM_FILENAME=\"partitions/v1/8m.csv\"" "CONFIG_PARTITION_TABLE_CUSTOM_FILENAME=\"partitions/v2/8m.csv\""
] ]
} }
] ]
@@ -131,10 +131,6 @@ mkdir main/boards/my-custom-board
#define TAG "MyCustomBoard" #define TAG "MyCustomBoard"
// 声明字体
LV_FONT_DECLARE(font_puhui_16_4);
LV_FONT_DECLARE(font_awesome_16_4);
class MyCustomBoard : public WifiBoard { class MyCustomBoard : public WifiBoard {
private: private:
i2c_master_bus_handle_t codec_i2c_bus_; i2c_master_bus_handle_t codec_i2c_bus_;
@@ -212,12 +208,7 @@ private:
display_ = new SpiLcdDisplay(panel_io, panel, display_ = new SpiLcdDisplay(panel_io, panel,
DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_WIDTH, DISPLAY_HEIGHT,
DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y,
DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY);
{
.text_font = &font_puhui_16_4,
.icon_font = &font_awesome_16_4,
.emoji_font = font_emoji_32_init(),
});
} }
// MCP Tools 初始化 // MCP Tools 初始化

View File

@@ -20,10 +20,6 @@
#define TAG "atk_dnesp32s3_box" #define TAG "atk_dnesp32s3_box"
LV_FONT_DECLARE(font_puhui_20_4);
LV_FONT_DECLARE(font_awesome_20_4);
class ATK_NoAudioCodecDuplex : public NoAudioCodec { class ATK_NoAudioCodecDuplex : public NoAudioCodec {
public: public:
ATK_NoAudioCodecDuplex(int input_sample_rate, int output_sample_rate, gpio_num_t bclk, gpio_num_t ws, gpio_num_t dout, gpio_num_t din) { ATK_NoAudioCodecDuplex(int input_sample_rate, int output_sample_rate, gpio_num_t bclk, gpio_num_t ws, gpio_num_t dout, gpio_num_t din) {
@@ -84,7 +80,6 @@ public:
} }
}; };
class XL9555_IN : public I2cDevice { class XL9555_IN : public I2cDevice {
public: public:
XL9555_IN(i2c_master_bus_handle_t i2c_bus, uint8_t addr) : I2cDevice(i2c_bus, addr) { XL9555_IN(i2c_master_bus_handle_t i2c_bus, uint8_t addr) : I2cDevice(i2c_bus, addr) {
@@ -243,16 +238,7 @@ private:
ESP_ERROR_CHECK(esp_lcd_panel_disp_on_off(panel, true)); ESP_ERROR_CHECK(esp_lcd_panel_disp_on_off(panel, true));
display_ = new SpiLcdDisplay(panel_io, panel, display_ = new SpiLcdDisplay(panel_io, panel,
DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY, DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY);
{
.text_font = &font_puhui_20_4,
.icon_font = &font_awesome_20_4,
#if CONFIG_USE_WECHAT_MESSAGE_STYLE
.emoji_font = font_emoji_32_init(),
#else
.emoji_font = DISPLAY_HEIGHT >= 240 ? font_emoji_64_init() : font_emoji_32_init(),
#endif
});
} }
void InitializeButtons() { void InitializeButtons() {

View File

@@ -20,9 +20,6 @@
#define TAG "atk_dnesp32s3_box0" #define TAG "atk_dnesp32s3_box0"
LV_FONT_DECLARE(font_puhui_20_4);
LV_FONT_DECLARE(font_awesome_20_4);
class atk_dnesp32s3_box0 : public WifiBoard { class atk_dnesp32s3_box0 : public WifiBoard {
private: private:
i2c_master_bus_handle_t i2c_bus_; i2c_master_bus_handle_t i2c_bus_;
@@ -294,7 +291,6 @@ private:
GetDisplay()->ShowNotification(Lang::Strings::MAX_VOLUME); GetDisplay()->ShowNotification(Lang::Strings::MAX_VOLUME);
}); });
} }
void InitializeSt7789Display() { void InitializeSt7789Display() {
@@ -325,12 +321,7 @@ private:
esp_lcd_panel_mirror(panel, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y); esp_lcd_panel_mirror(panel, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y);
display_ = new SpiLcdDisplay(panel_io, panel, display_ = new SpiLcdDisplay(panel_io, panel,
DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY, DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY);
{
.text_font = &font_puhui_20_4,
.icon_font = &font_awesome_20_4,
.emoji_font = DISPLAY_HEIGHT >= 240 ? font_emoji_64_init() : font_emoji_32_init(),
});
} }
public: public:

View File

@@ -21,9 +21,6 @@
#define TAG "atk_dnesp32s3_box2_4g" #define TAG "atk_dnesp32s3_box2_4g"
LV_FONT_DECLARE(font_puhui_20_4);
LV_FONT_DECLARE(font_awesome_20_4);
class atk_dnesp32s3_box2_4g : public DualNetworkBoard { class atk_dnesp32s3_box2_4g : public DualNetworkBoard {
private: private:
i2c_master_bus_handle_t i2c_bus_; i2c_master_bus_handle_t i2c_bus_;
@@ -412,12 +409,7 @@ private:
esp_lcd_panel_mirror(panel, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y); esp_lcd_panel_mirror(panel, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y);
display_ = new SpiLcdDisplay(panel_io, panel, display_ = new SpiLcdDisplay(panel_io, panel,
DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY, DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY);
{
.text_font = &font_puhui_20_4,
.icon_font = &font_awesome_20_4,
.emoji_font = DISPLAY_HEIGHT >= 240 ? font_emoji_64_init() : font_emoji_32_init(),
});
} }
public: public:

View File

@@ -21,9 +21,6 @@
#define TAG "atk_dnesp32s3_box2_wifi" #define TAG "atk_dnesp32s3_box2_wifi"
LV_FONT_DECLARE(font_puhui_20_4);
LV_FONT_DECLARE(font_awesome_20_4);
class atk_dnesp32s3_box2_wifi : public WifiBoard { class atk_dnesp32s3_box2_wifi : public WifiBoard {
private: private:
i2c_master_bus_handle_t i2c_bus_; i2c_master_bus_handle_t i2c_bus_;
@@ -392,12 +389,7 @@ private:
esp_lcd_panel_mirror(panel, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y); esp_lcd_panel_mirror(panel, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y);
display_ = new SpiLcdDisplay(panel_io, panel, display_ = new SpiLcdDisplay(panel_io, panel,
DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY, DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY);
{
.text_font = &font_puhui_20_4,
.icon_font = &font_awesome_20_4,
.emoji_font = DISPLAY_HEIGHT >= 240 ? font_emoji_64_init() : font_emoji_32_init(),
});
} }
public: public:

View File

@@ -16,9 +16,6 @@
#define TAG "atk_dnesp32s3" #define TAG "atk_dnesp32s3"
LV_FONT_DECLARE(font_puhui_20_4);
LV_FONT_DECLARE(font_awesome_20_4);
class XL9555 : public I2cDevice { class XL9555 : public I2cDevice {
public: public:
XL9555(i2c_master_bus_handle_t i2c_bus, uint8_t addr) : I2cDevice(i2c_bus, addr) { XL9555(i2c_master_bus_handle_t i2c_bus, uint8_t addr) : I2cDevice(i2c_bus, addr) {
@@ -47,7 +44,6 @@ public:
} }
}; };
class atk_dnesp32s3 : public WifiBoard { class atk_dnesp32s3 : public WifiBoard {
private: private:
i2c_master_bus_handle_t i2c_bus_; i2c_master_bus_handle_t i2c_bus_;
@@ -131,16 +127,7 @@ private:
esp_lcd_panel_swap_xy(panel, DISPLAY_SWAP_XY); esp_lcd_panel_swap_xy(panel, DISPLAY_SWAP_XY);
esp_lcd_panel_mirror(panel, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y); esp_lcd_panel_mirror(panel, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y);
display_ = new SpiLcdDisplay(panel_io, panel, display_ = new SpiLcdDisplay(panel_io, panel,
DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY, DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY);
{
.text_font = &font_puhui_20_4,
.icon_font = &font_awesome_20_4,
#if CONFIG_USE_WECHAT_MESSAGE_STYLE
.emoji_font = font_emoji_32_init(),
#else
.emoji_font = DISPLAY_HEIGHT >= 240 ? font_emoji_64_init() : font_emoji_32_init(),
#endif
});
} }
// 初始化摄像头ov2640 // 初始化摄像头ov2640

View File

@@ -20,9 +20,6 @@
#define TAG "atk_dnesp32s3m_4g" #define TAG "atk_dnesp32s3m_4g"
LV_FONT_DECLARE(font_puhui_16_4);
LV_FONT_DECLARE(font_awesome_16_4);
class atk_dnesp32s3m_4g : public Ml307Board { class atk_dnesp32s3m_4g : public Ml307Board {
private: private:
i2c_master_bus_handle_t i2c_bus_; i2c_master_bus_handle_t i2c_bus_;
@@ -167,12 +164,7 @@ private:
esp_lcd_panel_mirror(panel, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y); esp_lcd_panel_mirror(panel, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y);
display_ = new SpiLcdDisplay(panel_io, panel, display_ = new SpiLcdDisplay(panel_io, panel,
DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY, DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY);
{
.text_font = &font_puhui_16_4,
.icon_font = &font_awesome_16_4,
.emoji_font = font_emoji_32_init(),
});
} }
public: public:

View File

@@ -19,9 +19,6 @@
#define TAG "atk_dnesp32s3m_wifi" #define TAG "atk_dnesp32s3m_wifi"
LV_FONT_DECLARE(font_puhui_16_4);
LV_FONT_DECLARE(font_awesome_16_4);
class atk_dnesp32s3m_wifi : public WifiBoard { class atk_dnesp32s3m_wifi : public WifiBoard {
private: private:
i2c_master_bus_handle_t i2c_bus_; i2c_master_bus_handle_t i2c_bus_;
@@ -177,12 +174,7 @@ private:
esp_lcd_panel_mirror(panel, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y); esp_lcd_panel_mirror(panel, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y);
display_ = new SpiLcdDisplay(panel_io, panel, display_ = new SpiLcdDisplay(panel_io, panel,
DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY, DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY);
{
.text_font = &font_puhui_16_4,
.icon_font = &font_awesome_16_4,
.emoji_font = font_emoji_32_init(),
});
} }
public: public:

View File

@@ -22,7 +22,7 @@ idf.py menuconfig
分别配置如下选项: 分别配置如下选项:
- `Xiaozhi Assistant``Board Type` → 选择 `AtomEchoS3R` - `Xiaozhi Assistant``Board Type` → 选择 `AtomEchoS3R`
- `Partition Table``Custom partition CSV file` → 删除原有内容,输入 `partitions/v1/8m.csv` - `Partition Table``Custom partition CSV file` → 删除原有内容,输入 `partitions/v2/8m.csv`
- `Serial flasher config``Flash size` → 选择 `8 MB` - `Serial flasher config``Flash size` → 选择 `8 MB`
- `Component config``ESP PSRAM``Support for external, SPI-connected RAM``SPI RAM config` → 选择 `Octal Mode PSRAM` - `Component config``ESP PSRAM``Support for external, SPI-connected RAM``SPI RAM config` → 选择 `Octal Mode PSRAM`

View File

@@ -12,7 +12,6 @@
#define TAG "AtomEchoS3R" #define TAG "AtomEchoS3R"
class AtomEchoS3rBaseBoard : public WifiBoard { class AtomEchoS3rBaseBoard : public WifiBoard {
private: private:
i2c_master_bus_handle_t i2c_bus_; i2c_master_bus_handle_t i2c_bus_;

View File

@@ -5,7 +5,7 @@
"name": "atom-echos3r", "name": "atom-echos3r",
"sdkconfig_append": [ "sdkconfig_append": [
"CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y", "CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y",
"CONFIG_PARTITION_TABLE_CUSTOM_FILENAME=\"partitions/v1/8m.csv\"" "CONFIG_PARTITION_TABLE_CUSTOM_FILENAME=\"partitions/v2/8m.csv\""
] ]
} }
] ]

View File

@@ -33,7 +33,6 @@ public:
} }
}; };
class AtomMatrixEchoBaseBoard : public WifiBoard { class AtomMatrixEchoBaseBoard : public WifiBoard {
private: private:
i2c_master_bus_handle_t i2c_bus_; i2c_master_bus_handle_t i2c_bus_;
@@ -87,7 +86,6 @@ private:
pi4ioe_->SetSpeakerMute(false); pi4ioe_->SetSpeakerMute(false);
} }
void InitializeButtons() { void InitializeButtons() {
face_button_.OnClick([this]() { face_button_.OnClick([this]() {

View File

@@ -33,7 +33,7 @@ Serial flasher config -> Flash size -> 8 MB
**修改分区表:** **修改分区表:**
``` ```
Partition Table -> Custom partition CSV file -> partitions/v1/8m.csv Partition Table -> Custom partition CSV file -> partitions/v2/8m.csv
``` ```
**关闭片外 PSRAM** **关闭片外 PSRAM**

View File

@@ -16,9 +16,6 @@
#define TAG "AtomS3+EchoBase" #define TAG "AtomS3+EchoBase"
LV_FONT_DECLARE(font_puhui_16_4);
LV_FONT_DECLARE(font_awesome_16_4);
static const gc9a01_lcd_init_cmd_t gc9107_lcd_init_cmds[] = { static const gc9a01_lcd_init_cmd_t gc9107_lcd_init_cmds[] = {
// {cmd, { data }, data_size, delay_ms} // {cmd, { data }, data_size, delay_ms}
{0xfe, (uint8_t[]){0x00}, 0, 0}, {0xfe, (uint8_t[]){0x00}, 0, 0},
@@ -176,14 +173,8 @@ private:
ESP_ERROR_CHECK(esp_lcd_panel_init(panel_handle)); ESP_ERROR_CHECK(esp_lcd_panel_init(panel_handle));
ESP_ERROR_CHECK(esp_lcd_panel_disp_on_off(panel_handle, true)); ESP_ERROR_CHECK(esp_lcd_panel_disp_on_off(panel_handle, true));
display_ = new SpiLcdDisplay(io_handle, panel_handle, display_ = new SpiLcdDisplay(io_handle, panel_handle,
DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY, DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY);
{
.text_font = &font_puhui_16_4,
.icon_font = &font_awesome_16_4,
.emoji_font = font_emoji_32_init(),
});
} }
void InitializeButtons() { void InitializeButtons() {

View File

@@ -7,7 +7,7 @@
"CONFIG_SPIRAM=n", "CONFIG_SPIRAM=n",
"CONFIG_USE_AFE=n", "CONFIG_USE_AFE=n",
"CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y", "CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y",
"CONFIG_PARTITION_TABLE_CUSTOM_FILENAME=\"partitions/v1/8m.csv\"" "CONFIG_PARTITION_TABLE_CUSTOM_FILENAME=\"partitions/v2/8m.csv\""
] ]
} }
] ]

View File

@@ -32,7 +32,7 @@ idf.py menuconfig
- `Xiaozhi Assistant``Board Type` → 选择 `AtomS3R CAM/M12 + Echo Base` - `Xiaozhi Assistant``Board Type` → 选择 `AtomS3R CAM/M12 + Echo Base`
- `Xiaozhi Assistant``IoT Protocol` → 选择 `MCP协议` 可开启摄像头识别功能 - `Xiaozhi Assistant``IoT Protocol` → 选择 `MCP协议` 可开启摄像头识别功能
- `Partition Table``Custom partition CSV file` → 删除原有内容,输入 `partitions/v1/8m.csv` - `Partition Table``Custom partition CSV file` → 删除原有内容,输入 `partitions/v2/8m.csv`
- `Serial flasher config``Flash size` → 选择 `8 MB` - `Serial flasher config``Flash size` → 选择 `8 MB`
`S` 保存,按 `Q` 退出。 `S` 保存,按 `Q` 退出。

View File

@@ -5,7 +5,7 @@
"name": "atoms3r-cam-m12-echo-base", "name": "atoms3r-cam-m12-echo-base",
"sdkconfig_append": [ "sdkconfig_append": [
"CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y", "CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y",
"CONFIG_PARTITION_TABLE_CUSTOM_FILENAME=\"partitions/v1/8m.csv\"" "CONFIG_PARTITION_TABLE_CUSTOM_FILENAME=\"partitions/v2/8m.csv\""
] ]
} }
] ]

View File

@@ -27,7 +27,7 @@ Serial flasher config -> Flash size -> 8 MB
**修改分区表:** **修改分区表:**
``` ```
Partition Table -> Custom partition CSV file -> partitions/v1/8m.csv Partition Table -> Custom partition CSV file -> partitions/v2/8m.csv
``` ```
**修改 psram 配置:** **修改 psram 配置:**

View File

@@ -23,9 +23,6 @@
#define PI4IOE_REG_IO_OUT 0x05 #define PI4IOE_REG_IO_OUT 0x05
#define PI4IOE_REG_IO_PULLUP 0x0D #define PI4IOE_REG_IO_PULLUP 0x0D
LV_FONT_DECLARE(font_puhui_16_4);
LV_FONT_DECLARE(font_awesome_16_4);
class Pi4ioe : public I2cDevice { class Pi4ioe : public I2cDevice {
public: public:
Pi4ioe(i2c_master_bus_handle_t i2c_bus, uint8_t addr) : I2cDevice(i2c_bus, addr) { Pi4ioe(i2c_master_bus_handle_t i2c_bus, uint8_t addr) : I2cDevice(i2c_bus, addr) {
@@ -114,6 +111,7 @@ private:
Display* display_ = nullptr; Display* display_ = nullptr;
Button boot_button_; Button boot_button_;
bool is_echo_base_connected_ = false; bool is_echo_base_connected_ = false;
void InitializeI2c() { void InitializeI2c() {
// Initialize I2C peripheral // Initialize I2C peripheral
i2c_master_bus_config_t i2c_bus_cfg = { i2c_master_bus_config_t i2c_bus_cfg = {
@@ -254,12 +252,7 @@ private:
ESP_ERROR_CHECK(esp_lcd_panel_disp_on_off(panel_handle, true)); ESP_ERROR_CHECK(esp_lcd_panel_disp_on_off(panel_handle, true));
display_ = new SpiLcdDisplay(io_handle, panel_handle, display_ = new SpiLcdDisplay(io_handle, panel_handle,
DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY, DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY);
{
.text_font = &font_puhui_16_4,
.icon_font = &font_awesome_16_4,
.emoji_font = font_emoji_32_init(),
});
} }
void InitializeButtons() { void InitializeButtons() {

View File

@@ -5,7 +5,7 @@
"name": "atoms3r-echo-base", "name": "atoms3r-echo-base",
"sdkconfig_append": [ "sdkconfig_append": [
"CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y", "CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y",
"CONFIG_PARTITION_TABLE_CUSTOM_FILENAME=\"partitions/v1/8m.csv\"" "CONFIG_PARTITION_TABLE_CUSTOM_FILENAME=\"partitions/v2/8m.csv\""
] ]
} }
] ]

View File

@@ -58,9 +58,6 @@ static const gc9a01_lcd_init_cmd_t gc9107_lcd_init_cmds[] = {
#define TAG "ESP32-LCD-MarsbearSupport" #define TAG "ESP32-LCD-MarsbearSupport"
LV_FONT_DECLARE(font_puhui_14_1);
LV_FONT_DECLARE(font_awesome_14_1);
class CompactWifiBoardLCD : public WifiBoard { class CompactWifiBoardLCD : public WifiBoard {
private: private:
Button boot_button_; Button boot_button_;
@@ -114,7 +111,6 @@ private:
#endif #endif
esp_lcd_panel_reset(panel); esp_lcd_panel_reset(panel);
esp_lcd_panel_init(panel); esp_lcd_panel_init(panel);
esp_lcd_panel_invert_color(panel, DISPLAY_INVERT_COLOR); esp_lcd_panel_invert_color(panel, DISPLAY_INVERT_COLOR);
@@ -124,16 +120,9 @@ private:
panel_config.vendor_config = &gc9107_vendor_config; panel_config.vendor_config = &gc9107_vendor_config;
#endif #endif
display_ = new SpiLcdDisplay(panel_io, panel, display_ = new SpiLcdDisplay(panel_io, panel,
DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY, DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY);
{
.text_font = &font_puhui_14_1,
.icon_font = &font_awesome_14_1,
.emoji_font = font_emoji_32_init(),
});
} }
void InitializeButtons() { void InitializeButtons() {
// 配置 GPIO // 配置 GPIO

View File

@@ -17,10 +17,6 @@
#define TAG "ESP32-MarsbearSupport" #define TAG "ESP32-MarsbearSupport"
LV_FONT_DECLARE(font_puhui_14_1);
LV_FONT_DECLARE(font_awesome_14_1);
class CompactWifiBoard : public WifiBoard { class CompactWifiBoard : public WifiBoard {
private: private:
Button boot_button_; Button boot_button_;
@@ -92,8 +88,7 @@ private:
ESP_LOGI(TAG, "Turning display on"); ESP_LOGI(TAG, "Turning display on");
ESP_ERROR_CHECK(esp_lcd_panel_disp_on_off(panel_, true)); ESP_ERROR_CHECK(esp_lcd_panel_disp_on_off(panel_, true));
display_ = new OledDisplay(panel_io_, panel_, DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, display_ = new OledDisplay(panel_io_, panel_, DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y);
{&font_puhui_14_1, &font_awesome_14_1});
} }
void InitializeButtons() { void InitializeButtons() {

View File

@@ -18,9 +18,6 @@
#define TAG "CompactMl307Board" #define TAG "CompactMl307Board"
LV_FONT_DECLARE(font_puhui_14_1);
LV_FONT_DECLARE(font_awesome_14_1);
class CompactMl307Board : public DualNetworkBoard { class CompactMl307Board : public DualNetworkBoard {
private: private:
i2c_master_bus_handle_t display_i2c_bus_; i2c_master_bus_handle_t display_i2c_bus_;
@@ -92,8 +89,7 @@ private:
ESP_LOGI(TAG, "Turning display on"); ESP_LOGI(TAG, "Turning display on");
ESP_ERROR_CHECK(esp_lcd_panel_disp_on_off(panel_, true)); ESP_ERROR_CHECK(esp_lcd_panel_disp_on_off(panel_, true));
display_ = new OledDisplay(panel_io_, panel_, DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, display_ = new OledDisplay(panel_io_, panel_, DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y);
{&font_puhui_14_1, &font_awesome_14_1});
} }
void InitializeButtons() { void InitializeButtons() {

View File

@@ -1,198 +1,183 @@
#include "wifi_board.h" #include "wifi_board.h"
#include "codecs/no_audio_codec.h" #include "codecs/no_audio_codec.h"
#include "display/lcd_display.h" #include "display/lcd_display.h"
#include "system_reset.h" #include "system_reset.h"
#include "application.h" #include "application.h"
#include "button.h" #include "button.h"
#include "config.h" #include "config.h"
#include "mcp_server.h" #include "mcp_server.h"
#include "lamp_controller.h" #include "lamp_controller.h"
#include "led/single_led.h" #include "led/single_led.h"
#include <wifi_station.h> #include <wifi_station.h>
#include <esp_log.h> #include <esp_log.h>
#include <driver/i2c_master.h> #include <driver/i2c_master.h>
#include <esp_lcd_panel_vendor.h> #include <esp_lcd_panel_vendor.h>
#include <esp_lcd_panel_io.h> #include <esp_lcd_panel_io.h>
#include <esp_lcd_panel_ops.h> #include <esp_lcd_panel_ops.h>
#include <driver/spi_common.h> #include <driver/spi_common.h>
#if defined(LCD_TYPE_ILI9341_SERIAL) #if defined(LCD_TYPE_ILI9341_SERIAL)
#include "esp_lcd_ili9341.h" #include "esp_lcd_ili9341.h"
#endif #endif
#if defined(LCD_TYPE_GC9A01_SERIAL) #if defined(LCD_TYPE_GC9A01_SERIAL)
#include "esp_lcd_gc9a01.h" #include "esp_lcd_gc9a01.h"
static const gc9a01_lcd_init_cmd_t gc9107_lcd_init_cmds[] = { static const gc9a01_lcd_init_cmd_t gc9107_lcd_init_cmds[] = {
// {cmd, { data }, data_size, delay_ms} // {cmd, { data }, data_size, delay_ms}
{0xfe, (uint8_t[]){0x00}, 0, 0}, {0xfe, (uint8_t[]){0x00}, 0, 0},
{0xef, (uint8_t[]){0x00}, 0, 0}, {0xef, (uint8_t[]){0x00}, 0, 0},
{0xb0, (uint8_t[]){0xc0}, 1, 0}, {0xb0, (uint8_t[]){0xc0}, 1, 0},
{0xb1, (uint8_t[]){0x80}, 1, 0}, {0xb1, (uint8_t[]){0x80}, 1, 0},
{0xb2, (uint8_t[]){0x27}, 1, 0}, {0xb2, (uint8_t[]){0x27}, 1, 0},
{0xb3, (uint8_t[]){0x13}, 1, 0}, {0xb3, (uint8_t[]){0x13}, 1, 0},
{0xb6, (uint8_t[]){0x19}, 1, 0}, {0xb6, (uint8_t[]){0x19}, 1, 0},
{0xb7, (uint8_t[]){0x05}, 1, 0}, {0xb7, (uint8_t[]){0x05}, 1, 0},
{0xac, (uint8_t[]){0xc8}, 1, 0}, {0xac, (uint8_t[]){0xc8}, 1, 0},
{0xab, (uint8_t[]){0x0f}, 1, 0}, {0xab, (uint8_t[]){0x0f}, 1, 0},
{0x3a, (uint8_t[]){0x05}, 1, 0}, {0x3a, (uint8_t[]){0x05}, 1, 0},
{0xb4, (uint8_t[]){0x04}, 1, 0}, {0xb4, (uint8_t[]){0x04}, 1, 0},
{0xa8, (uint8_t[]){0x08}, 1, 0}, {0xa8, (uint8_t[]){0x08}, 1, 0},
{0xb8, (uint8_t[]){0x08}, 1, 0}, {0xb8, (uint8_t[]){0x08}, 1, 0},
{0xea, (uint8_t[]){0x02}, 1, 0}, {0xea, (uint8_t[]){0x02}, 1, 0},
{0xe8, (uint8_t[]){0x2A}, 1, 0}, {0xe8, (uint8_t[]){0x2A}, 1, 0},
{0xe9, (uint8_t[]){0x47}, 1, 0}, {0xe9, (uint8_t[]){0x47}, 1, 0},
{0xe7, (uint8_t[]){0x5f}, 1, 0}, {0xe7, (uint8_t[]){0x5f}, 1, 0},
{0xc6, (uint8_t[]){0x21}, 1, 0}, {0xc6, (uint8_t[]){0x21}, 1, 0},
{0xc7, (uint8_t[]){0x15}, 1, 0}, {0xc7, (uint8_t[]){0x15}, 1, 0},
{0xf0, {0xf0,
(uint8_t[]){0x1D, 0x38, 0x09, 0x4D, 0x92, 0x2F, 0x35, 0x52, 0x1E, 0x0C, (uint8_t[]){0x1D, 0x38, 0x09, 0x4D, 0x92, 0x2F, 0x35, 0x52, 0x1E, 0x0C,
0x04, 0x12, 0x14, 0x1f}, 0x04, 0x12, 0x14, 0x1f},
14, 0}, 14, 0},
{0xf1, {0xf1,
(uint8_t[]){0x16, 0x40, 0x1C, 0x54, 0xA9, 0x2D, 0x2E, 0x56, 0x10, 0x0D, (uint8_t[]){0x16, 0x40, 0x1C, 0x54, 0xA9, 0x2D, 0x2E, 0x56, 0x10, 0x0D,
0x0C, 0x1A, 0x14, 0x1E}, 0x0C, 0x1A, 0x14, 0x1E},
14, 0}, 14, 0},
{0xf4, (uint8_t[]){0x00, 0x00, 0xFF}, 3, 0}, {0xf4, (uint8_t[]){0x00, 0x00, 0xFF}, 3, 0},
{0xba, (uint8_t[]){0xFF, 0xFF}, 2, 0}, {0xba, (uint8_t[]){0xFF, 0xFF}, 2, 0},
}; };
#endif #endif
#define TAG "CompactWifiBoardLCD" #define TAG "CompactWifiBoardLCD"
LV_FONT_DECLARE(font_puhui_16_4); class CompactWifiBoardLCD : public WifiBoard {
LV_FONT_DECLARE(font_awesome_16_4); private:
class CompactWifiBoardLCD : public WifiBoard { Button boot_button_;
private: LcdDisplay* display_;
Button boot_button_; void InitializeSpi() {
LcdDisplay* display_; spi_bus_config_t buscfg = {};
buscfg.mosi_io_num = DISPLAY_MOSI_PIN;
void InitializeSpi() { buscfg.miso_io_num = GPIO_NUM_NC;
spi_bus_config_t buscfg = {}; buscfg.sclk_io_num = DISPLAY_CLK_PIN;
buscfg.mosi_io_num = DISPLAY_MOSI_PIN; buscfg.quadwp_io_num = GPIO_NUM_NC;
buscfg.miso_io_num = GPIO_NUM_NC; buscfg.quadhd_io_num = GPIO_NUM_NC;
buscfg.sclk_io_num = DISPLAY_CLK_PIN; buscfg.max_transfer_sz = DISPLAY_WIDTH * DISPLAY_HEIGHT * sizeof(uint16_t);
buscfg.quadwp_io_num = GPIO_NUM_NC; ESP_ERROR_CHECK(spi_bus_initialize(SPI3_HOST, &buscfg, SPI_DMA_CH_AUTO));
buscfg.quadhd_io_num = GPIO_NUM_NC; }
buscfg.max_transfer_sz = DISPLAY_WIDTH * DISPLAY_HEIGHT * sizeof(uint16_t);
ESP_ERROR_CHECK(spi_bus_initialize(SPI3_HOST, &buscfg, SPI_DMA_CH_AUTO)); void InitializeLcdDisplay() {
} esp_lcd_panel_io_handle_t panel_io = nullptr;
esp_lcd_panel_handle_t panel = nullptr;
void InitializeLcdDisplay() { // 液晶屏控制IO初始化
esp_lcd_panel_io_handle_t panel_io = nullptr; ESP_LOGD(TAG, "Install panel IO");
esp_lcd_panel_handle_t panel = nullptr; esp_lcd_panel_io_spi_config_t io_config = {};
// 液晶屏控制IO初始化 io_config.cs_gpio_num = DISPLAY_CS_PIN;
ESP_LOGD(TAG, "Install panel IO"); io_config.dc_gpio_num = DISPLAY_DC_PIN;
esp_lcd_panel_io_spi_config_t io_config = {}; io_config.spi_mode = DISPLAY_SPI_MODE;
io_config.cs_gpio_num = DISPLAY_CS_PIN; io_config.pclk_hz = 40 * 1000 * 1000;
io_config.dc_gpio_num = DISPLAY_DC_PIN; io_config.trans_queue_depth = 10;
io_config.spi_mode = DISPLAY_SPI_MODE; io_config.lcd_cmd_bits = 8;
io_config.pclk_hz = 40 * 1000 * 1000; io_config.lcd_param_bits = 8;
io_config.trans_queue_depth = 10; ESP_ERROR_CHECK(esp_lcd_new_panel_io_spi(SPI3_HOST, &io_config, &panel_io));
io_config.lcd_cmd_bits = 8;
io_config.lcd_param_bits = 8; // 初始化液晶屏驱动芯片
ESP_ERROR_CHECK(esp_lcd_new_panel_io_spi(SPI3_HOST, &io_config, &panel_io)); ESP_LOGD(TAG, "Install LCD driver");
esp_lcd_panel_dev_config_t panel_config = {};
// 初始化液晶屏驱动芯片 panel_config.reset_gpio_num = DISPLAY_RST_PIN;
ESP_LOGD(TAG, "Install LCD driver"); panel_config.rgb_ele_order = DISPLAY_RGB_ORDER;
esp_lcd_panel_dev_config_t panel_config = {}; panel_config.bits_per_pixel = 16;
panel_config.reset_gpio_num = DISPLAY_RST_PIN; #if defined(LCD_TYPE_ILI9341_SERIAL)
panel_config.rgb_ele_order = DISPLAY_RGB_ORDER; ESP_ERROR_CHECK(esp_lcd_new_panel_ili9341(panel_io, &panel_config, &panel));
panel_config.bits_per_pixel = 16; #elif defined(LCD_TYPE_GC9A01_SERIAL)
#if defined(LCD_TYPE_ILI9341_SERIAL) ESP_ERROR_CHECK(esp_lcd_new_panel_gc9a01(panel_io, &panel_config, &panel));
ESP_ERROR_CHECK(esp_lcd_new_panel_ili9341(panel_io, &panel_config, &panel)); gc9a01_vendor_config_t gc9107_vendor_config = {
#elif defined(LCD_TYPE_GC9A01_SERIAL) .init_cmds = gc9107_lcd_init_cmds,
ESP_ERROR_CHECK(esp_lcd_new_panel_gc9a01(panel_io, &panel_config, &panel)); .init_cmds_size = sizeof(gc9107_lcd_init_cmds) / sizeof(gc9a01_lcd_init_cmd_t),
gc9a01_vendor_config_t gc9107_vendor_config = { };
.init_cmds = gc9107_lcd_init_cmds, #else
.init_cmds_size = sizeof(gc9107_lcd_init_cmds) / sizeof(gc9a01_lcd_init_cmd_t), ESP_ERROR_CHECK(esp_lcd_new_panel_st7789(panel_io, &panel_config, &panel));
}; #endif
#else
ESP_ERROR_CHECK(esp_lcd_new_panel_st7789(panel_io, &panel_config, &panel)); esp_lcd_panel_reset(panel);
#endif
esp_lcd_panel_init(panel);
esp_lcd_panel_reset(panel); esp_lcd_panel_invert_color(panel, DISPLAY_INVERT_COLOR);
esp_lcd_panel_swap_xy(panel, DISPLAY_SWAP_XY);
esp_lcd_panel_mirror(panel, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y);
esp_lcd_panel_init(panel); #ifdef LCD_TYPE_GC9A01_SERIAL
esp_lcd_panel_invert_color(panel, DISPLAY_INVERT_COLOR); panel_config.vendor_config = &gc9107_vendor_config;
esp_lcd_panel_swap_xy(panel, DISPLAY_SWAP_XY); #endif
esp_lcd_panel_mirror(panel, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y); display_ = new SpiLcdDisplay(panel_io, panel,
#ifdef LCD_TYPE_GC9A01_SERIAL DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY);
panel_config.vendor_config = &gc9107_vendor_config; }
#endif
display_ = new SpiLcdDisplay(panel_io, panel, void InitializeButtons() {
DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY, boot_button_.OnClick([this]() {
{ auto& app = Application::GetInstance();
.text_font = &font_puhui_16_4, if (app.GetDeviceState() == kDeviceStateStarting && !WifiStation::GetInstance().IsConnected()) {
.icon_font = &font_awesome_16_4, ResetWifiConfiguration();
#if CONFIG_USE_WECHAT_MESSAGE_STYLE }
.emoji_font = font_emoji_32_init(), app.ToggleChatState();
#else });
.emoji_font = DISPLAY_HEIGHT >= 240 ? font_emoji_64_init() : font_emoji_32_init(), }
#endif
}); // 物联网初始化,添加对 AI 可见设备
} void InitializeTools() {
static LampController lamp(LAMP_GPIO);
}
void InitializeButtons() { public:
boot_button_.OnClick([this]() { CompactWifiBoardLCD() :
auto& app = Application::GetInstance(); boot_button_(BOOT_BUTTON_GPIO) {
if (app.GetDeviceState() == kDeviceStateStarting && !WifiStation::GetInstance().IsConnected()) { InitializeSpi();
ResetWifiConfiguration(); InitializeLcdDisplay();
} InitializeButtons();
app.ToggleChatState(); InitializeTools();
}); if (DISPLAY_BACKLIGHT_PIN != GPIO_NUM_NC) {
} GetBacklight()->RestoreBrightness();
}
// 物联网初始化,添加对 AI 可见设备
void InitializeTools() { }
static LampController lamp(LAMP_GPIO);
} virtual Led* GetLed() override {
static SingleLed led(BUILTIN_LED_GPIO);
public: return &led;
CompactWifiBoardLCD() : }
boot_button_(BOOT_BUTTON_GPIO) {
InitializeSpi(); virtual AudioCodec* GetAudioCodec() override {
InitializeLcdDisplay(); #ifdef AUDIO_I2S_METHOD_SIMPLEX
InitializeButtons(); static NoAudioCodecSimplex audio_codec(AUDIO_INPUT_SAMPLE_RATE, AUDIO_OUTPUT_SAMPLE_RATE,
InitializeTools(); AUDIO_I2S_SPK_GPIO_BCLK, AUDIO_I2S_SPK_GPIO_LRCK, AUDIO_I2S_SPK_GPIO_DOUT, AUDIO_I2S_MIC_GPIO_SCK, AUDIO_I2S_MIC_GPIO_WS, AUDIO_I2S_MIC_GPIO_DIN);
if (DISPLAY_BACKLIGHT_PIN != GPIO_NUM_NC) { #else
GetBacklight()->RestoreBrightness(); static NoAudioCodecDuplex audio_codec(AUDIO_INPUT_SAMPLE_RATE, AUDIO_OUTPUT_SAMPLE_RATE,
} AUDIO_I2S_GPIO_BCLK, AUDIO_I2S_GPIO_WS, AUDIO_I2S_GPIO_DOUT, AUDIO_I2S_GPIO_DIN);
#endif
} return &audio_codec;
}
virtual Led* GetLed() override {
static SingleLed led(BUILTIN_LED_GPIO); virtual Display* GetDisplay() override {
return &led; return display_;
} }
virtual AudioCodec* GetAudioCodec() override { virtual Backlight* GetBacklight() override {
#ifdef AUDIO_I2S_METHOD_SIMPLEX if (DISPLAY_BACKLIGHT_PIN != GPIO_NUM_NC) {
static NoAudioCodecSimplex audio_codec(AUDIO_INPUT_SAMPLE_RATE, AUDIO_OUTPUT_SAMPLE_RATE, static PwmBacklight backlight(DISPLAY_BACKLIGHT_PIN, DISPLAY_BACKLIGHT_OUTPUT_INVERT);
AUDIO_I2S_SPK_GPIO_BCLK, AUDIO_I2S_SPK_GPIO_LRCK, AUDIO_I2S_SPK_GPIO_DOUT, AUDIO_I2S_MIC_GPIO_SCK, AUDIO_I2S_MIC_GPIO_WS, AUDIO_I2S_MIC_GPIO_DIN); return &backlight;
#else }
static NoAudioCodecDuplex audio_codec(AUDIO_INPUT_SAMPLE_RATE, AUDIO_OUTPUT_SAMPLE_RATE, return nullptr;
AUDIO_I2S_GPIO_BCLK, AUDIO_I2S_GPIO_WS, AUDIO_I2S_GPIO_DOUT, AUDIO_I2S_GPIO_DIN); }
#endif };
return &audio_codec;
} DECLARE_BOARD(CompactWifiBoardLCD);
virtual Display* GetDisplay() override {
return display_;
}
virtual Backlight* GetBacklight() override {
if (DISPLAY_BACKLIGHT_PIN != GPIO_NUM_NC) {
static PwmBacklight backlight(DISPLAY_BACKLIGHT_PIN, DISPLAY_BACKLIGHT_OUTPUT_INVERT);
return &backlight;
}
return nullptr;
}
};
DECLARE_BOARD(CompactWifiBoardLCD);

View File

@@ -1,227 +1,214 @@
#include "wifi_board.h" #include "wifi_board.h"
#include "codecs/no_audio_codec.h" #include "codecs/no_audio_codec.h"
#include "display/lcd_display.h" #include "display/lcd_display.h"
#include "system_reset.h" #include "system_reset.h"
#include "application.h" #include "application.h"
#include "button.h" #include "button.h"
#include "config.h" #include "config.h"
#include "mcp_server.h" #include "mcp_server.h"
#include "lamp_controller.h" #include "lamp_controller.h"
#include "led/single_led.h" #include "led/single_led.h"
#include "esp32_camera.h" #include "esp32_camera.h"
#include <wifi_station.h> #include <wifi_station.h>
#include <esp_log.h> #include <esp_log.h>
#include <driver/i2c_master.h> #include <driver/i2c_master.h>
#include <esp_lcd_panel_vendor.h> #include <esp_lcd_panel_vendor.h>
#include <esp_lcd_panel_io.h> #include <esp_lcd_panel_io.h>
#include <esp_lcd_panel_ops.h> #include <esp_lcd_panel_ops.h>
#include <driver/spi_common.h> #include <driver/spi_common.h>
#if defined(LCD_TYPE_ILI9341_SERIAL) #if defined(LCD_TYPE_ILI9341_SERIAL)
#include "esp_lcd_ili9341.h" #include "esp_lcd_ili9341.h"
#endif #endif
#if defined(LCD_TYPE_GC9A01_SERIAL) #if defined(LCD_TYPE_GC9A01_SERIAL)
#include "esp_lcd_gc9a01.h" #include "esp_lcd_gc9a01.h"
static const gc9a01_lcd_init_cmd_t gc9107_lcd_init_cmds[] = { static const gc9a01_lcd_init_cmd_t gc9107_lcd_init_cmds[] = {
// {cmd, { data }, data_size, delay_ms} // {cmd, { data }, data_size, delay_ms}
{0xfe, (uint8_t[]){0x00}, 0, 0}, {0xfe, (uint8_t[]){0x00}, 0, 0},
{0xef, (uint8_t[]){0x00}, 0, 0}, {0xef, (uint8_t[]){0x00}, 0, 0},
{0xb0, (uint8_t[]){0xc0}, 1, 0}, {0xb0, (uint8_t[]){0xc0}, 1, 0},
{0xb1, (uint8_t[]){0x80}, 1, 0}, {0xb1, (uint8_t[]){0x80}, 1, 0},
{0xb2, (uint8_t[]){0x27}, 1, 0}, {0xb2, (uint8_t[]){0x27}, 1, 0},
{0xb3, (uint8_t[]){0x13}, 1, 0}, {0xb3, (uint8_t[]){0x13}, 1, 0},
{0xb6, (uint8_t[]){0x19}, 1, 0}, {0xb6, (uint8_t[]){0x19}, 1, 0},
{0xb7, (uint8_t[]){0x05}, 1, 0}, {0xb7, (uint8_t[]){0x05}, 1, 0},
{0xac, (uint8_t[]){0xc8}, 1, 0}, {0xac, (uint8_t[]){0xc8}, 1, 0},
{0xab, (uint8_t[]){0x0f}, 1, 0}, {0xab, (uint8_t[]){0x0f}, 1, 0},
{0x3a, (uint8_t[]){0x05}, 1, 0}, {0x3a, (uint8_t[]){0x05}, 1, 0},
{0xb4, (uint8_t[]){0x04}, 1, 0}, {0xb4, (uint8_t[]){0x04}, 1, 0},
{0xa8, (uint8_t[]){0x08}, 1, 0}, {0xa8, (uint8_t[]){0x08}, 1, 0},
{0xb8, (uint8_t[]){0x08}, 1, 0}, {0xb8, (uint8_t[]){0x08}, 1, 0},
{0xea, (uint8_t[]){0x02}, 1, 0}, {0xea, (uint8_t[]){0x02}, 1, 0},
{0xe8, (uint8_t[]){0x2A}, 1, 0}, {0xe8, (uint8_t[]){0x2A}, 1, 0},
{0xe9, (uint8_t[]){0x47}, 1, 0}, {0xe9, (uint8_t[]){0x47}, 1, 0},
{0xe7, (uint8_t[]){0x5f}, 1, 0}, {0xe7, (uint8_t[]){0x5f}, 1, 0},
{0xc6, (uint8_t[]){0x21}, 1, 0}, {0xc6, (uint8_t[]){0x21}, 1, 0},
{0xc7, (uint8_t[]){0x15}, 1, 0}, {0xc7, (uint8_t[]){0x15}, 1, 0},
{0xf0, {0xf0,
(uint8_t[]){0x1D, 0x38, 0x09, 0x4D, 0x92, 0x2F, 0x35, 0x52, 0x1E, 0x0C, (uint8_t[]){0x1D, 0x38, 0x09, 0x4D, 0x92, 0x2F, 0x35, 0x52, 0x1E, 0x0C,
0x04, 0x12, 0x14, 0x1f}, 0x04, 0x12, 0x14, 0x1f},
14, 0}, 14, 0},
{0xf1, {0xf1,
(uint8_t[]){0x16, 0x40, 0x1C, 0x54, 0xA9, 0x2D, 0x2E, 0x56, 0x10, 0x0D, (uint8_t[]){0x16, 0x40, 0x1C, 0x54, 0xA9, 0x2D, 0x2E, 0x56, 0x10, 0x0D,
0x0C, 0x1A, 0x14, 0x1E}, 0x0C, 0x1A, 0x14, 0x1E},
14, 0}, 14, 0},
{0xf4, (uint8_t[]){0x00, 0x00, 0xFF}, 3, 0}, {0xf4, (uint8_t[]){0x00, 0x00, 0xFF}, 3, 0},
{0xba, (uint8_t[]){0xFF, 0xFF}, 2, 0}, {0xba, (uint8_t[]){0xFF, 0xFF}, 2, 0},
}; };
#endif #endif
#define TAG "CompactWifiBoardS3Cam" #define TAG "CompactWifiBoardS3Cam"
LV_FONT_DECLARE(font_puhui_16_4); class CompactWifiBoardS3Cam : public WifiBoard {
LV_FONT_DECLARE(font_awesome_16_4); private:
class CompactWifiBoardS3Cam : public WifiBoard { Button boot_button_;
private: LcdDisplay* display_;
Esp32Camera* camera_;
Button boot_button_;
LcdDisplay* display_; void InitializeSpi() {
Esp32Camera* camera_; spi_bus_config_t buscfg = {};
buscfg.mosi_io_num = DISPLAY_MOSI_PIN;
void InitializeSpi() { buscfg.miso_io_num = GPIO_NUM_NC;
spi_bus_config_t buscfg = {}; buscfg.sclk_io_num = DISPLAY_CLK_PIN;
buscfg.mosi_io_num = DISPLAY_MOSI_PIN; buscfg.quadwp_io_num = GPIO_NUM_NC;
buscfg.miso_io_num = GPIO_NUM_NC; buscfg.quadhd_io_num = GPIO_NUM_NC;
buscfg.sclk_io_num = DISPLAY_CLK_PIN; buscfg.max_transfer_sz = DISPLAY_WIDTH * DISPLAY_HEIGHT * sizeof(uint16_t);
buscfg.quadwp_io_num = GPIO_NUM_NC; ESP_ERROR_CHECK(spi_bus_initialize(SPI3_HOST, &buscfg, SPI_DMA_CH_AUTO));
buscfg.quadhd_io_num = GPIO_NUM_NC; }
buscfg.max_transfer_sz = DISPLAY_WIDTH * DISPLAY_HEIGHT * sizeof(uint16_t);
ESP_ERROR_CHECK(spi_bus_initialize(SPI3_HOST, &buscfg, SPI_DMA_CH_AUTO)); void InitializeLcdDisplay() {
} esp_lcd_panel_io_handle_t panel_io = nullptr;
esp_lcd_panel_handle_t panel = nullptr;
void InitializeLcdDisplay() { // 液晶屏控制IO初始化
esp_lcd_panel_io_handle_t panel_io = nullptr; ESP_LOGD(TAG, "Install panel IO");
esp_lcd_panel_handle_t panel = nullptr; esp_lcd_panel_io_spi_config_t io_config = {};
// 液晶屏控制IO初始化 io_config.cs_gpio_num = DISPLAY_CS_PIN;
ESP_LOGD(TAG, "Install panel IO"); io_config.dc_gpio_num = DISPLAY_DC_PIN;
esp_lcd_panel_io_spi_config_t io_config = {}; io_config.spi_mode = DISPLAY_SPI_MODE;
io_config.cs_gpio_num = DISPLAY_CS_PIN; io_config.pclk_hz = 40 * 1000 * 1000;
io_config.dc_gpio_num = DISPLAY_DC_PIN; io_config.trans_queue_depth = 10;
io_config.spi_mode = DISPLAY_SPI_MODE; io_config.lcd_cmd_bits = 8;
io_config.pclk_hz = 40 * 1000 * 1000; io_config.lcd_param_bits = 8;
io_config.trans_queue_depth = 10; ESP_ERROR_CHECK(esp_lcd_new_panel_io_spi(SPI3_HOST, &io_config, &panel_io));
io_config.lcd_cmd_bits = 8;
io_config.lcd_param_bits = 8; // 初始化液晶屏驱动芯片
ESP_ERROR_CHECK(esp_lcd_new_panel_io_spi(SPI3_HOST, &io_config, &panel_io)); ESP_LOGD(TAG, "Install LCD driver");
esp_lcd_panel_dev_config_t panel_config = {};
// 初始化液晶屏驱动芯片 panel_config.reset_gpio_num = DISPLAY_RST_PIN;
ESP_LOGD(TAG, "Install LCD driver"); panel_config.rgb_ele_order = DISPLAY_RGB_ORDER;
esp_lcd_panel_dev_config_t panel_config = {}; panel_config.bits_per_pixel = 16;
panel_config.reset_gpio_num = DISPLAY_RST_PIN; #if defined(LCD_TYPE_ILI9341_SERIAL)
panel_config.rgb_ele_order = DISPLAY_RGB_ORDER; ESP_ERROR_CHECK(esp_lcd_new_panel_ili9341(panel_io, &panel_config, &panel));
panel_config.bits_per_pixel = 16; #elif defined(LCD_TYPE_GC9A01_SERIAL)
#if defined(LCD_TYPE_ILI9341_SERIAL) ESP_ERROR_CHECK(esp_lcd_new_panel_gc9a01(panel_io, &panel_config, &panel));
ESP_ERROR_CHECK(esp_lcd_new_panel_ili9341(panel_io, &panel_config, &panel)); gc9a01_vendor_config_t gc9107_vendor_config = {
#elif defined(LCD_TYPE_GC9A01_SERIAL) .init_cmds = gc9107_lcd_init_cmds,
ESP_ERROR_CHECK(esp_lcd_new_panel_gc9a01(panel_io, &panel_config, &panel)); .init_cmds_size = sizeof(gc9107_lcd_init_cmds) / sizeof(gc9a01_lcd_init_cmd_t),
gc9a01_vendor_config_t gc9107_vendor_config = { };
.init_cmds = gc9107_lcd_init_cmds, #else
.init_cmds_size = sizeof(gc9107_lcd_init_cmds) / sizeof(gc9a01_lcd_init_cmd_t), ESP_ERROR_CHECK(esp_lcd_new_panel_st7789(panel_io, &panel_config, &panel));
}; #endif
#else
ESP_ERROR_CHECK(esp_lcd_new_panel_st7789(panel_io, &panel_config, &panel)); esp_lcd_panel_reset(panel);
#endif
esp_lcd_panel_init(panel);
esp_lcd_panel_reset(panel); esp_lcd_panel_invert_color(panel, DISPLAY_INVERT_COLOR);
esp_lcd_panel_swap_xy(panel, DISPLAY_SWAP_XY);
esp_lcd_panel_mirror(panel, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y);
esp_lcd_panel_init(panel); #ifdef LCD_TYPE_GC9A01_SERIAL
esp_lcd_panel_invert_color(panel, DISPLAY_INVERT_COLOR); panel_config.vendor_config = &gc9107_vendor_config;
esp_lcd_panel_swap_xy(panel, DISPLAY_SWAP_XY); #endif
esp_lcd_panel_mirror(panel, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y); display_ = new SpiLcdDisplay(panel_io, panel,
#ifdef LCD_TYPE_GC9A01_SERIAL DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY);
panel_config.vendor_config = &gc9107_vendor_config; }
#endif
display_ = new SpiLcdDisplay(panel_io, panel, void InitializeCamera() {
DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY, camera_config_t config = {};
{ config.pin_d0 = CAMERA_PIN_D0;
.text_font = &font_puhui_16_4, config.pin_d1 = CAMERA_PIN_D1;
.icon_font = &font_awesome_16_4, config.pin_d2 = CAMERA_PIN_D2;
#if CONFIG_USE_WECHAT_MESSAGE_STYLE config.pin_d3 = CAMERA_PIN_D3;
.emoji_font = font_emoji_32_init(), config.pin_d4 = CAMERA_PIN_D4;
#else config.pin_d5 = CAMERA_PIN_D5;
.emoji_font = DISPLAY_HEIGHT >= 240 ? font_emoji_64_init() : font_emoji_32_init(), config.pin_d6 = CAMERA_PIN_D6;
#endif config.pin_d7 = CAMERA_PIN_D7;
}); config.pin_xclk = CAMERA_PIN_XCLK;
} config.pin_pclk = CAMERA_PIN_PCLK;
config.pin_vsync = CAMERA_PIN_VSYNC;
void InitializeCamera() { config.pin_href = CAMERA_PIN_HREF;
camera_config_t config = {}; config.pin_sccb_sda = CAMERA_PIN_SIOD;
config.pin_d0 = CAMERA_PIN_D0; config.pin_sccb_scl = CAMERA_PIN_SIOC;
config.pin_d1 = CAMERA_PIN_D1; config.sccb_i2c_port = 0;
config.pin_d2 = CAMERA_PIN_D2; config.pin_pwdn = CAMERA_PIN_PWDN;
config.pin_d3 = CAMERA_PIN_D3; config.pin_reset = CAMERA_PIN_RESET;
config.pin_d4 = CAMERA_PIN_D4; config.xclk_freq_hz = XCLK_FREQ_HZ;
config.pin_d5 = CAMERA_PIN_D5; config.pixel_format = PIXFORMAT_RGB565;
config.pin_d6 = CAMERA_PIN_D6; config.frame_size = FRAMESIZE_QVGA;
config.pin_d7 = CAMERA_PIN_D7; config.jpeg_quality = 12;
config.pin_xclk = CAMERA_PIN_XCLK; config.fb_count = 1;
config.pin_pclk = CAMERA_PIN_PCLK; config.fb_location = CAMERA_FB_IN_PSRAM;
config.pin_vsync = CAMERA_PIN_VSYNC; config.grab_mode = CAMERA_GRAB_WHEN_EMPTY;
config.pin_href = CAMERA_PIN_HREF; camera_ = new Esp32Camera(config);
config.pin_sccb_sda = CAMERA_PIN_SIOD; camera_->SetHMirror(false);
config.pin_sccb_scl = CAMERA_PIN_SIOC; }
config.sccb_i2c_port = 0;
config.pin_pwdn = CAMERA_PIN_PWDN; void InitializeButtons() {
config.pin_reset = CAMERA_PIN_RESET; boot_button_.OnClick([this]() {
config.xclk_freq_hz = XCLK_FREQ_HZ; auto& app = Application::GetInstance();
config.pixel_format = PIXFORMAT_RGB565; if (app.GetDeviceState() == kDeviceStateStarting && !WifiStation::GetInstance().IsConnected()) {
config.frame_size = FRAMESIZE_QVGA; ResetWifiConfiguration();
config.jpeg_quality = 12; }
config.fb_count = 1; app.ToggleChatState();
config.fb_location = CAMERA_FB_IN_PSRAM; });
config.grab_mode = CAMERA_GRAB_WHEN_EMPTY; }
camera_ = new Esp32Camera(config);
camera_->SetHMirror(false); public:
} CompactWifiBoardS3Cam() :
boot_button_(BOOT_BUTTON_GPIO) {
void InitializeButtons() { InitializeSpi();
boot_button_.OnClick([this]() { InitializeLcdDisplay();
auto& app = Application::GetInstance(); InitializeButtons();
if (app.GetDeviceState() == kDeviceStateStarting && !WifiStation::GetInstance().IsConnected()) { InitializeCamera();
ResetWifiConfiguration(); if (DISPLAY_BACKLIGHT_PIN != GPIO_NUM_NC) {
} GetBacklight()->RestoreBrightness();
app.ToggleChatState(); }
});
} }
public: virtual Led* GetLed() override {
CompactWifiBoardS3Cam() : static SingleLed led(BUILTIN_LED_GPIO);
boot_button_(BOOT_BUTTON_GPIO) { return &led;
InitializeSpi(); }
InitializeLcdDisplay();
InitializeButtons(); virtual AudioCodec* GetAudioCodec() override {
InitializeCamera(); #ifdef AUDIO_I2S_METHOD_SIMPLEX
if (DISPLAY_BACKLIGHT_PIN != GPIO_NUM_NC) { static NoAudioCodecSimplex audio_codec(AUDIO_INPUT_SAMPLE_RATE, AUDIO_OUTPUT_SAMPLE_RATE,
GetBacklight()->RestoreBrightness(); AUDIO_I2S_SPK_GPIO_BCLK, AUDIO_I2S_SPK_GPIO_LRCK, AUDIO_I2S_SPK_GPIO_DOUT, AUDIO_I2S_MIC_GPIO_SCK, AUDIO_I2S_MIC_GPIO_WS, AUDIO_I2S_MIC_GPIO_DIN);
} #else
static NoAudioCodecDuplex audio_codec(AUDIO_INPUT_SAMPLE_RATE, AUDIO_OUTPUT_SAMPLE_RATE,
} AUDIO_I2S_GPIO_BCLK, AUDIO_I2S_GPIO_WS, AUDIO_I2S_GPIO_DOUT, AUDIO_I2S_GPIO_DIN);
#endif
virtual Led* GetLed() override { return &audio_codec;
static SingleLed led(BUILTIN_LED_GPIO); }
return &led;
} virtual Display* GetDisplay() override {
return display_;
virtual AudioCodec* GetAudioCodec() override { }
#ifdef AUDIO_I2S_METHOD_SIMPLEX
static NoAudioCodecSimplex audio_codec(AUDIO_INPUT_SAMPLE_RATE, AUDIO_OUTPUT_SAMPLE_RATE, virtual Backlight* GetBacklight() override {
AUDIO_I2S_SPK_GPIO_BCLK, AUDIO_I2S_SPK_GPIO_LRCK, AUDIO_I2S_SPK_GPIO_DOUT, AUDIO_I2S_MIC_GPIO_SCK, AUDIO_I2S_MIC_GPIO_WS, AUDIO_I2S_MIC_GPIO_DIN); if (DISPLAY_BACKLIGHT_PIN != GPIO_NUM_NC) {
#else static PwmBacklight backlight(DISPLAY_BACKLIGHT_PIN, DISPLAY_BACKLIGHT_OUTPUT_INVERT);
static NoAudioCodecDuplex audio_codec(AUDIO_INPUT_SAMPLE_RATE, AUDIO_OUTPUT_SAMPLE_RATE, return &backlight;
AUDIO_I2S_GPIO_BCLK, AUDIO_I2S_GPIO_WS, AUDIO_I2S_GPIO_DOUT, AUDIO_I2S_GPIO_DIN); }
#endif return nullptr;
return &audio_codec; }
}
virtual Camera* GetCamera() override {
virtual Display* GetDisplay() override { return camera_;
return display_; }
} };
virtual Backlight* GetBacklight() override { DECLARE_BOARD(CompactWifiBoardS3Cam);
if (DISPLAY_BACKLIGHT_PIN != GPIO_NUM_NC) {
static PwmBacklight backlight(DISPLAY_BACKLIGHT_PIN, DISPLAY_BACKLIGHT_OUTPUT_INVERT);
return &backlight;
}
return nullptr;
}
virtual Camera* GetCamera() override {
return camera_;
}
};
DECLARE_BOARD(CompactWifiBoardS3Cam);

View File

@@ -22,9 +22,6 @@
#define TAG "CompactWifiBoard" #define TAG "CompactWifiBoard"
LV_FONT_DECLARE(font_puhui_14_1);
LV_FONT_DECLARE(font_awesome_14_1);
class CompactWifiBoard : public WifiBoard { class CompactWifiBoard : public WifiBoard {
private: private:
i2c_master_bus_handle_t display_i2c_bus_; i2c_master_bus_handle_t display_i2c_bus_;
@@ -101,8 +98,7 @@ private:
ESP_LOGI(TAG, "Turning display on"); ESP_LOGI(TAG, "Turning display on");
ESP_ERROR_CHECK(esp_lcd_panel_disp_on_off(panel_, true)); ESP_ERROR_CHECK(esp_lcd_panel_disp_on_off(panel_, true));
display_ = new OledDisplay(panel_io_, panel_, DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, display_ = new OledDisplay(panel_io_, panel_, DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y);
{&font_puhui_14_1, &font_awesome_14_1});
} }
void InitializeButtons() { void InitializeButtons() {

View File

@@ -85,7 +85,7 @@ Led* Board::GetLed() {
return &led; return &led;
} }
std::string Board::GetJson() { std::string Board::GetSystemInfoJson() {
/* /*
{ {
"version": 2, "version": 2,
@@ -178,4 +178,13 @@ std::string Board::GetJson() {
// Close the JSON object // Close the JSON object
json += R"(})"; json += R"(})";
return json; return json;
}
Assets* Board::GetAssets() {
#ifdef DEFAULT_ASSETS
static Assets assets(DEFAULT_ASSETS);
return &assets;
#else
return nullptr;
#endif
} }

View File

@@ -12,6 +12,8 @@
#include "backlight.h" #include "backlight.h"
#include "camera.h" #include "camera.h"
#include "music.h" #include "music.h"
#include "assets.h"
void* create_board(); void* create_board();
class AudioCodec; class AudioCodec;
@@ -30,14 +32,13 @@ protected:
// 音乐播放器实例 // 音乐播放器实例
Music* music_; Music* music_;
public: public:
static Board& GetInstance() { static Board& GetInstance() {
static Board* instance = static_cast<Board*>(create_board()); static Board* instance = static_cast<Board*>(create_board());
return *instance; return *instance;
} }
virtual ~Board(); virtual ~Board(); // 改为非默认析构函数,用于清理 music_
virtual std::string GetBoardType() = 0; virtual std::string GetBoardType() = 0;
virtual std::string GetUuid() { return uuid_; } virtual std::string GetUuid() { return uuid_; }
virtual Backlight* GetBacklight() { return nullptr; } virtual Backlight* GetBacklight() { return nullptr; }
@@ -51,10 +52,11 @@ public:
virtual void StartNetwork() = 0; virtual void StartNetwork() = 0;
virtual const char* GetNetworkStateIcon() = 0; virtual const char* GetNetworkStateIcon() = 0;
virtual bool GetBatteryLevel(int &level, bool& charging, bool& discharging); virtual bool GetBatteryLevel(int &level, bool& charging, bool& discharging);
virtual std::string GetJson(); virtual std::string GetSystemInfoJson();
virtual void SetPowerSaveMode(bool enabled) = 0; virtual void SetPowerSaveMode(bool enabled) = 0;
virtual std::string GetBoardJson() = 0; virtual std::string GetBoardJson() = 0;
virtual std::string GetDeviceStatusJson() = 0; virtual std::string GetDeviceStatusJson() = 0;
virtual Assets* GetAssets();
}; };
#define DECLARE_BOARD(BOARD_CLASS_NAME) \ #define DECLARE_BOARD(BOARD_CLASS_NAME) \
@@ -62,4 +64,4 @@ void* create_board() { \
return new BOARD_CLASS_NAME(); \ return new BOARD_CLASS_NAME(); \
} }
#endif // BOARD_H #endif // BOARD_H

View File

@@ -3,6 +3,7 @@
#include "display.h" #include "display.h"
#include "board.h" #include "board.h"
#include "system_info.h" #include "system_info.h"
#include "lvgl_display.h"
#include <esp_log.h> #include <esp_log.h>
#include <esp_heap_caps.h> #include <esp_heap_caps.h>
@@ -23,48 +24,6 @@ Esp32Camera::Esp32Camera(const camera_config_t& config) {
if (s->id.PID == GC0308_PID) { if (s->id.PID == GC0308_PID) {
s->set_hmirror(s, 0); // 这里控制摄像头镜像 写1镜像 写0不镜像 s->set_hmirror(s, 0); // 这里控制摄像头镜像 写1镜像 写0不镜像
} }
// 初始化预览图片的内存
memset(&preview_image_, 0, sizeof(preview_image_));
preview_image_.header.magic = LV_IMAGE_HEADER_MAGIC;
preview_image_.header.cf = LV_COLOR_FORMAT_RGB565;
preview_image_.header.flags = 0;
switch (config.frame_size) {
case FRAMESIZE_SVGA:
preview_image_.header.w = 800;
preview_image_.header.h = 600;
break;
case FRAMESIZE_VGA:
preview_image_.header.w = 640;
preview_image_.header.h = 480;
break;
case FRAMESIZE_QVGA:
preview_image_.header.w = 320;
preview_image_.header.h = 240;
break;
case FRAMESIZE_128X128:
preview_image_.header.w = 128;
preview_image_.header.h = 128;
break;
case FRAMESIZE_240X240:
preview_image_.header.w = 240;
preview_image_.header.h = 240;
break;
default:
ESP_LOGE(TAG, "Unsupported frame size: %d, image preview will not be shown", config.frame_size);
preview_image_.data_size = 0;
preview_image_.data = nullptr;
return;
}
preview_image_.header.stride = preview_image_.header.w * 2;
preview_image_.data_size = preview_image_.header.w * preview_image_.header.h * 2;
preview_image_.data = (uint8_t*)heap_caps_malloc(preview_image_.data_size, MALLOC_CAP_SPIRAM);
if (preview_image_.data == nullptr) {
ESP_LOGE(TAG, "Failed to allocate memory for preview image");
return;
}
} }
Esp32Camera::~Esp32Camera() { Esp32Camera::~Esp32Camera() {
@@ -72,10 +31,6 @@ Esp32Camera::~Esp32Camera() {
esp_camera_fb_return(fb_); esp_camera_fb_return(fb_);
fb_ = nullptr; fb_ = nullptr;
} }
if (preview_image_.data) {
heap_caps_free((void*)preview_image_.data);
preview_image_.data = nullptr;
}
esp_camera_deinit(); esp_camera_deinit();
} }
@@ -89,6 +44,7 @@ bool Esp32Camera::Capture() {
encoder_thread_.join(); encoder_thread_.join();
} }
auto start_time = esp_timer_get_time();
int frames_to_get = 2; int frames_to_get = 2;
// Try to get a stable frame // Try to get a stable frame
for (int i = 0; i < frames_to_get; i++) { for (int i = 0; i < frames_to_get; i++) {
@@ -101,28 +57,36 @@ bool Esp32Camera::Capture() {
return false; return false;
} }
} }
auto end_time = esp_timer_get_time();
ESP_LOGI(TAG, "Camera captured %d frames in %d ms", frames_to_get, int((end_time - start_time) / 1000));
// 如果预览图片 buffer 为空,则跳过预览
// 但仍返回 true因为此时图像可以上传至服务器
if (preview_image_.data_size == 0) {
ESP_LOGW(TAG, "Skip preview because of unsupported frame size");
return true;
}
if (preview_image_.data == nullptr) {
ESP_LOGE(TAG, "Preview image data is not initialized");
return true;
}
// 显示预览图片 // 显示预览图片
auto display = Board::GetInstance().GetDisplay(); auto display = dynamic_cast<LvglDisplay*>(Board::GetInstance().GetDisplay());
if (display != nullptr) { if (display != nullptr) {
// Create a new preview image
auto img_dsc = (lv_img_dsc_t*)heap_caps_calloc(1, sizeof(lv_img_dsc_t), MALLOC_CAP_8BIT);
img_dsc->header.magic = LV_IMAGE_HEADER_MAGIC;
img_dsc->header.cf = LV_COLOR_FORMAT_RGB565;
img_dsc->header.flags = 0;
img_dsc->header.w = fb_->width;
img_dsc->header.h = fb_->height;
img_dsc->header.stride = fb_->width * 2;
img_dsc->data_size = fb_->width * fb_->height * 2;
img_dsc->data = (uint8_t*)heap_caps_malloc(img_dsc->data_size, MALLOC_CAP_SPIRAM);
if (img_dsc->data == nullptr) {
ESP_LOGE(TAG, "Failed to allocate memory for preview image");
heap_caps_free(img_dsc);
return false;
}
auto src = (uint16_t*)fb_->buf; auto src = (uint16_t*)fb_->buf;
auto dst = (uint16_t*)preview_image_.data; auto dst = (uint16_t*)img_dsc->data;
size_t pixel_count = fb_->len / 2; size_t pixel_count = fb_->len / 2;
for (size_t i = 0; i < pixel_count; i++) { for (size_t i = 0; i < pixel_count; i++) {
// 交换每个16位字内的字节 // 交换每个16位字内的字节
dst[i] = __builtin_bswap16(src[i]); dst[i] = __builtin_bswap16(src[i]);
} }
display->SetPreviewImage(&preview_image_); display->SetPreviewImage(img_dsc);
} }
return true; return true;
} }
@@ -185,14 +149,14 @@ bool Esp32Camera::SetVFlip(bool enabled) {
*/ */
std::string Esp32Camera::Explain(const std::string& question) { std::string Esp32Camera::Explain(const std::string& question) {
if (explain_url_.empty()) { if (explain_url_.empty()) {
return "{\"success\": false, \"message\": \"Image explain URL or token is not set\"}"; throw std::runtime_error("Image explain URL or token is not set");
} }
// 创建局部的 JPEG 队列, 40 entries is about to store 512 * 40 = 20480 bytes of JPEG data // 创建局部的 JPEG 队列, 40 entries is about to store 512 * 40 = 20480 bytes of JPEG data
QueueHandle_t jpeg_queue = xQueueCreate(40, sizeof(JpegChunk)); QueueHandle_t jpeg_queue = xQueueCreate(40, sizeof(JpegChunk));
if (jpeg_queue == nullptr) { if (jpeg_queue == nullptr) {
ESP_LOGE(TAG, "Failed to create JPEG queue"); ESP_LOGE(TAG, "Failed to create JPEG queue");
return "{\"success\": false, \"message\": \"Failed to create JPEG queue\"}"; throw std::runtime_error("Failed to create JPEG queue");
} }
// We spawn a thread to encode the image to JPEG // We spawn a thread to encode the image to JPEG
@@ -235,7 +199,7 @@ std::string Esp32Camera::Explain(const std::string& question) {
} }
} }
vQueueDelete(jpeg_queue); vQueueDelete(jpeg_queue);
return "{\"success\": false, \"message\": \"Failed to connect to explain URL\"}"; throw std::runtime_error("Failed to connect to explain URL");
} }
{ {
@@ -288,7 +252,7 @@ std::string Esp32Camera::Explain(const std::string& question) {
if (http->GetStatusCode() != 200) { if (http->GetStatusCode() != 200) {
ESP_LOGE(TAG, "Failed to upload photo, status code: %d", http->GetStatusCode()); ESP_LOGE(TAG, "Failed to upload photo, status code: %d", http->GetStatusCode());
return "{\"success\": false, \"message\": \"Failed to upload photo\"}"; throw std::runtime_error("Failed to upload photo");
} }
std::string result = http->ReadAll(); std::string result = http->ReadAll();

View File

@@ -19,7 +19,6 @@ struct JpegChunk {
class Esp32Camera : public Camera { class Esp32Camera : public Camera {
private: private:
camera_fb_t* fb_ = nullptr; camera_fb_t* fb_ = nullptr;
lv_img_dsc_t preview_image_;
std::string explain_url_; std::string explain_url_;
std::string explain_token_; std::string explain_token_;
std::thread encoder_thread_; std::thread encoder_thread_;

File diff suppressed because it is too large Load Diff

View File

@@ -38,6 +38,7 @@ private:
std::string current_music_url_; std::string current_music_url_;
std::string current_song_name_; std::string current_song_name_;
bool song_name_displayed_; bool song_name_displayed_;
std::atomic<bool> stop_flag_{false}; // 停止播放标志位
// 歌词相关 // 歌词相关
std::string current_lyric_url_; std::string current_lyric_url_;

View File

@@ -153,7 +153,10 @@ std::string Ml307Board::GetDeviceStatusJson() {
} }
auto display = board.GetDisplay(); auto display = board.GetDisplay();
if (display && display->height() > 64) { // For LCD display only if (display && display->height() > 64) { // For LCD display only
cJSON_AddStringToObject(screen, "theme", display->GetTheme().c_str()); auto theme = display->GetTheme();
if (theme != nullptr) {
cJSON_AddStringToObject(screen, "theme", theme->name().c_str());
}
} }
cJSON_AddItemToObject(root, "screen", screen); cJSON_AddItemToObject(root, "screen", screen);

View File

@@ -216,7 +216,10 @@ std::string WifiBoard::GetDeviceStatusJson() {
} }
auto display = board.GetDisplay(); auto display = board.GetDisplay();
if (display && display->height() > 64) { // For LCD display only if (display && display->height() > 64) { // For LCD display only
cJSON_AddStringToObject(screen, "theme", display->GetTheme().c_str()); auto theme = display->GetTheme();
if (theme != nullptr) {
cJSON_AddStringToObject(screen, "theme", theme->name().c_str());
}
} }
cJSON_AddItemToObject(root, "screen", screen); cJSON_AddItemToObject(root, "screen", screen);

View File

@@ -21,9 +21,6 @@
#define TAG "DF-K10" #define TAG "DF-K10"
LV_FONT_DECLARE(font_puhui_20_4);
LV_FONT_DECLARE(font_awesome_20_4);
class Df_K10Board : public WifiBoard { class Df_K10Board : public WifiBoard {
private: private:
i2c_master_bus_handle_t i2c_bus_; i2c_master_bus_handle_t i2c_bus_;
@@ -104,6 +101,7 @@ private:
ESP_LOGE(TAG, "Set direction failed: %s", esp_err_to_name(ret)); ESP_LOGE(TAG, "Set direction failed: %s", esp_err_to_name(ret));
} }
} }
void InitializeButtons() { void InitializeButtons() {
instance_ = this; instance_ = this;
@@ -233,12 +231,7 @@ private:
ESP_ERROR_CHECK(esp_lcd_panel_disp_on_off(panel, true)); ESP_ERROR_CHECK(esp_lcd_panel_disp_on_off(panel, true));
display_ = new SpiLcdDisplay(panel_io, panel, display_ = new SpiLcdDisplay(panel_io, panel,
DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY, DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY);
{
.text_font = &font_puhui_20_4,
.icon_font = &font_awesome_20_4,
.emoji_font = font_emoji_64_init(),
});
} }
// 物联网初始化,添加对 AI 可见设备 // 物联网初始化,添加对 AI 可见设备
@@ -258,7 +251,7 @@ public:
InitializeCamera(); InitializeCamera();
} }
virtual Led* GetLed() override { virtual Led* GetLed() override {
return led_strip_; return led_strip_;
} }

View File

@@ -41,7 +41,6 @@ K10AudioCodec::K10AudioCodec(void* i2c_master_handle, int input_sample_rate, int
const audio_codec_if_t *in_codec_if_ = es7243e_codec_new(&es7243e_cfg); const audio_codec_if_t *in_codec_if_ = es7243e_codec_new(&es7243e_cfg);
assert(in_codec_if_ != NULL); assert(in_codec_if_ != NULL);
esp_codec_dev_cfg_t codec_es7243e_dev_cfg = { esp_codec_dev_cfg_t codec_es7243e_dev_cfg = {
.dev_type = ESP_CODEC_DEV_TYPE_IN, .dev_type = ESP_CODEC_DEV_TYPE_IN,
.codec_if = in_codec_if_, .codec_if = in_codec_if_,

View File

@@ -69,6 +69,8 @@ class DfrobotEsp32S3AiCam : public WifiBoard {
InitializeCamera(); InitializeCamera();
} }
// Wakenet model only
virtual Led* GetLed() override { virtual Led* GetLed() override {
static GpioLed led(BUILTIN_LED_GPIO, 0); static GpioLed led(BUILTIN_LED_GPIO, 0);
return &led; return &led;

View File

@@ -99,7 +99,6 @@ private:
}); });
} }
void InitializeGpio(gpio_num_t gpio_num_) { void InitializeGpio(gpio_num_t gpio_num_) {
gpio_config_t config = { gpio_config_t config = {
.pin_bit_mask = (1ULL << gpio_num_), .pin_bit_mask = (1ULL << gpio_num_),

View File

@@ -19,9 +19,6 @@
#define TAG "DuChatX" #define TAG "DuChatX"
LV_FONT_DECLARE(font_puhui_16_4);
LV_FONT_DECLARE(font_awesome_16_4);
class DuChatX : public WifiBoard { class DuChatX : public WifiBoard {
private: private:
Button boot_button_; Button boot_button_;
@@ -101,12 +98,7 @@ private:
esp_lcd_panel_invert_color(panel_, DISPLAY_INVERT_COLOR); esp_lcd_panel_invert_color(panel_, DISPLAY_INVERT_COLOR);
esp_lcd_panel_swap_xy(panel_, DISPLAY_SWAP_XY); esp_lcd_panel_swap_xy(panel_, DISPLAY_SWAP_XY);
esp_lcd_panel_mirror(panel_, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y); esp_lcd_panel_mirror(panel_, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y);
display_ = new SpiLcdDisplay(panel_io, panel_,DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y,DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY, display_ = new SpiLcdDisplay(panel_io, panel_,DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y,DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY);
{
.text_font = &font_puhui_16_4,
.icon_font = &font_awesome_16_4,
.emoji_font = DISPLAY_HEIGHT >= 240 ? font_emoji_64_init() : font_emoji_32_init(),
});
} }
void InitializeButtons() { void InitializeButtons() {

View File

@@ -28,8 +28,6 @@
#define USE_LVGL_DEFAULT 0 #define USE_LVGL_DEFAULT 0
LV_FONT_DECLARE(font_puhui_20_4);
LV_FONT_DECLARE(font_awesome_20_4);
temperature_sensor_handle_t temp_sensor = NULL; temperature_sensor_handle_t temp_sensor = NULL;
static const st77916_lcd_init_cmd_t vendor_specific_init_yysj[] = { static const st77916_lcd_init_cmd_t vendor_specific_init_yysj[] = {
{0xF0, (uint8_t []){0x28}, 1, 0}, {0xF0, (uint8_t []){0x28}, 1, 0},
@@ -562,11 +560,7 @@ private:
#if USE_LVGL_DEFAULT #if USE_LVGL_DEFAULT
display_ = new SpiLcdDisplay(panel_io, panel, display_ = new SpiLcdDisplay(panel_io, panel,
DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY, { DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY);
.text_font = &font_puhui_20_4,
.icon_font = &font_awesome_20_4,
.emoji_font = font_emoji_64_init(),
});
#else #else
display_ = new anim::EmoteDisplay(panel, panel_io); display_ = new anim::EmoteDisplay(panel, panel_io);
#endif #endif

View File

@@ -4,6 +4,7 @@
{ {
"name": "electron-bot", "name": "electron-bot",
"sdkconfig_append": [ "sdkconfig_append": [
"CONFIG_PARTITION_TABLE_CUSTOM_FILENAME=\"partitions/v1/16m.csv\""
] ]
} }
] ]

View File

@@ -24,9 +24,6 @@
// 控制器初始化函数声明 // 控制器初始化函数声明
void InitializeElectronBotController(); void InitializeElectronBotController();
LV_FONT_DECLARE(font_puhui_20_4);
LV_FONT_DECLARE(font_awesome_20_4);
class ElectronBot : public WifiBoard { class ElectronBot : public WifiBoard {
private: private:
Display* display_; Display* display_;
@@ -73,12 +70,7 @@ private:
display_ = new ElectronEmojiDisplay(io_handle, panel_handle, DISPLAY_WIDTH, DISPLAY_HEIGHT, display_ = new ElectronEmojiDisplay(io_handle, panel_handle, DISPLAY_WIDTH, DISPLAY_HEIGHT,
DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X,
DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY);
{
.text_font = &font_puhui_20_4,
.icon_font = &font_awesome_20_4,
.emoji_font = font_emoji_64_init(),
});
} }
void InitializeButtons() { void InitializeButtons() {

View File

@@ -1,4 +1,5 @@
#include "electron_emoji_display.h" #include "electron_emoji_display.h"
#include "lvgl_theme.h"
#include <esp_log.h> #include <esp_log.h>
#include <font_awesome.h> #include <font_awesome.h>
@@ -7,7 +8,6 @@
#include <cstring> #include <cstring>
#include <string> #include <string>
#define TAG "ElectronEmojiDisplay" #define TAG "ElectronEmojiDisplay"
// 表情映射表 - 将多种表情映射到现有6个GIF // 表情映射表 - 将多种表情映射到现有6个GIF
@@ -51,9 +51,8 @@ const ElectronEmojiDisplay::EmotionMap ElectronEmojiDisplay::emotion_maps_[] = {
ElectronEmojiDisplay::ElectronEmojiDisplay(esp_lcd_panel_io_handle_t panel_io, ElectronEmojiDisplay::ElectronEmojiDisplay(esp_lcd_panel_io_handle_t panel_io,
esp_lcd_panel_handle_t panel, int width, int height, esp_lcd_panel_handle_t panel, int width, int height,
int offset_x, int offset_y, bool mirror_x, bool mirror_y, int offset_x, int offset_y, bool mirror_x, bool mirror_y,
bool swap_xy, DisplayFonts fonts) bool swap_xy)
: SpiLcdDisplay(panel_io, panel, width, height, offset_x, offset_y, mirror_x, mirror_y, swap_xy, : SpiLcdDisplay(panel_io, panel, width, height, offset_x, offset_y, mirror_x, mirror_y, swap_xy),
fonts),
emotion_gif_(nullptr) { emotion_gif_(nullptr) {
SetupGifContainer(); SetupGifContainer();
} }
@@ -61,8 +60,8 @@ ElectronEmojiDisplay::ElectronEmojiDisplay(esp_lcd_panel_io_handle_t panel_io,
void ElectronEmojiDisplay::SetupGifContainer() { void ElectronEmojiDisplay::SetupGifContainer() {
DisplayLockGuard lock(this); DisplayLockGuard lock(this);
if (emotion_label_) { if (emoji_label_) {
lv_obj_del(emotion_label_); lv_obj_del(emoji_label_);
} }
if (chat_message_label_) { if (chat_message_label_) {
lv_obj_del(chat_message_label_); lv_obj_del(chat_message_label_);
@@ -79,11 +78,11 @@ void ElectronEmojiDisplay::SetupGifContainer() {
lv_obj_set_flex_grow(content_, 1); lv_obj_set_flex_grow(content_, 1);
lv_obj_center(content_); lv_obj_center(content_);
emotion_label_ = lv_label_create(content_); emoji_label_ = lv_label_create(content_);
lv_label_set_text(emotion_label_, ""); lv_label_set_text(emoji_label_, "");
lv_obj_set_width(emotion_label_, 0); lv_obj_set_width(emoji_label_, 0);
lv_obj_set_style_border_width(emotion_label_, 0, 0); lv_obj_set_style_border_width(emoji_label_, 0, 0);
lv_obj_add_flag(emotion_label_, LV_OBJ_FLAG_HIDDEN); lv_obj_add_flag(emoji_label_, LV_OBJ_FLAG_HIDDEN);
emotion_gif_ = lv_gif_create(content_); emotion_gif_ = lv_gif_create(content_);
int gif_size = LV_HOR_RES; int gif_size = LV_HOR_RES;
@@ -107,7 +106,11 @@ void ElectronEmojiDisplay::SetupGifContainer() {
lv_obj_align(chat_message_label_, LV_ALIGN_BOTTOM_MID, 0, 0); lv_obj_align(chat_message_label_, LV_ALIGN_BOTTOM_MID, 0, 0);
LcdDisplay::SetTheme("dark"); auto& theme_manager = LvglThemeManager::GetInstance();
auto theme = theme_manager.GetTheme("dark");
if (theme != nullptr) {
LcdDisplay::SetTheme(theme);
}
} }
void ElectronEmojiDisplay::SetEmotion(const char* emotion) { void ElectronEmojiDisplay::SetEmotion(const char* emotion) {
@@ -144,27 +147,4 @@ void ElectronEmojiDisplay::SetChatMessage(const char* role, const char* content)
lv_obj_remove_flag(chat_message_label_, LV_OBJ_FLAG_HIDDEN); lv_obj_remove_flag(chat_message_label_, LV_OBJ_FLAG_HIDDEN);
ESP_LOGI(TAG, "设置聊天消息 [%s]: %s", role, content); ESP_LOGI(TAG, "设置聊天消息 [%s]: %s", role, content);
}
void ElectronEmojiDisplay::SetIcon(const char* icon) {
if (!icon) {
return;
}
DisplayLockGuard lock(this);
if (chat_message_label_ != nullptr) {
std::string icon_message = std::string(icon) + " ";
if (strcmp(icon, FONT_AWESOME_DOWNLOAD) == 0) {
icon_message += "正在升级...";
} else {
icon_message += "系统状态";
}
lv_label_set_text(chat_message_label_, icon_message.c_str());
lv_obj_remove_flag(chat_message_label_, LV_OBJ_FLAG_HIDDEN);
ESP_LOGI(TAG, "设置图标: %s", icon);
}
} }

View File

@@ -23,7 +23,7 @@ public:
*/ */
ElectronEmojiDisplay(esp_lcd_panel_io_handle_t panel_io, esp_lcd_panel_handle_t panel, ElectronEmojiDisplay(esp_lcd_panel_io_handle_t panel_io, esp_lcd_panel_handle_t panel,
int width, int height, int offset_x, int offset_y, bool mirror_x, int width, int height, int offset_x, int offset_y, bool mirror_x,
bool mirror_y, bool swap_xy, DisplayFonts fonts); bool mirror_y, bool swap_xy);
virtual ~ElectronEmojiDisplay() = default; virtual ~ElectronEmojiDisplay() = default;
@@ -33,9 +33,6 @@ public:
// 重写聊天消息设置方法 // 重写聊天消息设置方法
virtual void SetChatMessage(const char* role, const char* content) override; virtual void SetChatMessage(const char* role, const char* content) override;
// 重写图标设置方法
virtual void SetIcon(const char* icon) override;
private: private:
void SetupGifContainer(); void SetupGifContainer();

View File

@@ -5,8 +5,6 @@
#include "oscillator.h" #include "oscillator.h"
static const char* TAG = "Movements";
Otto::Otto() { Otto::Otto() {
is_otto_resting_ = false; is_otto_resting_ = false;
for (int i = 0; i < SERVO_COUNT; i++) { for (int i = 0; i < SERVO_COUNT; i++) {

View File

@@ -6,12 +6,8 @@
#include <algorithm> #include <algorithm>
#include <cmath> #include <cmath>
static const char* TAG = "Oscillator";
extern unsigned long IRAM_ATTR millis(); extern unsigned long IRAM_ATTR millis();
static ledc_channel_t next_free_channel = LEDC_CHANNEL_0;
Oscillator::Oscillator(int trim) { Oscillator::Oscillator(int trim) {
trim_ = trim; trim_ = trim;
diff_limit_ = 0; diff_limit_ = 0;

View File

@@ -14,9 +14,6 @@
#define TAG "EspBox3Board" #define TAG "EspBox3Board"
LV_FONT_DECLARE(font_puhui_20_4);
LV_FONT_DECLARE(font_awesome_20_4);
// Init ili9341 by custom cmd // Init ili9341 by custom cmd
static const ili9341_lcd_init_cmd_t vendor_specific_init[] = { static const ili9341_lcd_init_cmd_t vendor_specific_init[] = {
{0xC8, (uint8_t []){0xFF, 0x93, 0x42}, 3, 0}, {0xC8, (uint8_t []){0xFF, 0x93, 0x42}, 3, 0},
@@ -129,16 +126,7 @@ private:
esp_lcd_panel_mirror(panel, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y); esp_lcd_panel_mirror(panel, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y);
esp_lcd_panel_disp_on_off(panel, true); esp_lcd_panel_disp_on_off(panel, true);
display_ = new SpiLcdDisplay(panel_io, panel, display_ = new SpiLcdDisplay(panel_io, panel,
DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY, DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY);
{
.text_font = &font_puhui_20_4,
.icon_font = &font_awesome_20_4,
#if CONFIG_USE_WECHAT_MESSAGE_STYLE
.emoji_font = font_emoji_32_init(),
#else
.emoji_font = font_emoji_64_init(),
#endif
});
} }
public: public:

View File

@@ -3,7 +3,9 @@
"builds": [ "builds": [
{ {
"name": "esp-box-lite", "name": "esp-box-lite",
"sdkconfig_append": ["CONFIG_SOC_ADC_SUPPORTED=y"] "sdkconfig_append": [
"CONFIG_SOC_ADC_SUPPORTED=y"
]
} }
] ]
} }

View File

@@ -16,9 +16,6 @@
#define TAG "EspBoxBoardLite" #define TAG "EspBoxBoardLite"
LV_FONT_DECLARE(font_puhui_20_4);
LV_FONT_DECLARE(font_awesome_20_4);
/* ADC Buttons */ /* ADC Buttons */
typedef enum { typedef enum {
BSP_ADC_BUTTON_PREV, BSP_ADC_BUTTON_PREV,
@@ -191,16 +188,7 @@ private:
esp_lcd_panel_mirror(panel, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y); esp_lcd_panel_mirror(panel, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y);
esp_lcd_panel_disp_on_off(panel, true); esp_lcd_panel_disp_on_off(panel, true);
display_ = new SpiLcdDisplay(panel_io, panel, display_ = new SpiLcdDisplay(panel_io, panel,
DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY, DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY);
{
.text_font = &font_puhui_20_4,
.icon_font = &font_awesome_20_4,
#if CONFIG_USE_WECHAT_MESSAGE_STYLE
.emoji_font = font_emoji_32_init(),
#else
.emoji_font = font_emoji_64_init(),
#endif
});
} }
public: public:

View File

@@ -14,9 +14,6 @@
#define TAG "EspBoxBoard" #define TAG "EspBoxBoard"
LV_FONT_DECLARE(font_puhui_20_4);
LV_FONT_DECLARE(font_awesome_20_4);
// Init ili9341 by custom cmd // Init ili9341 by custom cmd
static const ili9341_lcd_init_cmd_t vendor_specific_init[] = { static const ili9341_lcd_init_cmd_t vendor_specific_init[] = {
{0xC8, (uint8_t []){0xFF, 0x93, 0x42}, 3, 0}, {0xC8, (uint8_t []){0xFF, 0x93, 0x42}, 3, 0},
@@ -129,16 +126,7 @@ private:
esp_lcd_panel_mirror(panel, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y); esp_lcd_panel_mirror(panel, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y);
esp_lcd_panel_disp_on_off(panel, true); esp_lcd_panel_disp_on_off(panel, true);
display_ = new SpiLcdDisplay(panel_io, panel, display_ = new SpiLcdDisplay(panel_io, panel,
DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY, DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY);
{
.text_font = &font_puhui_20_4,
.icon_font = &font_awesome_20_4,
#if CONFIG_USE_WECHAT_MESSAGE_STYLE
.emoji_font = font_emoji_32_init(),
#else
.emoji_font = font_emoji_64_init(),
#endif
});
} }
public: public:

View File

@@ -22,9 +22,6 @@
#define TAG "ESP_S3_LCD_EV_Board_2" #define TAG "ESP_S3_LCD_EV_Board_2"
LV_FONT_DECLARE(font_puhui_30_4);
LV_FONT_DECLARE(font_awesome_30_4);
class ESP_S3_LCD_EV_Board_2 : public WifiBoard { class ESP_S3_LCD_EV_Board_2 : public WifiBoard {
private: private:
i2c_master_bus_handle_t i2c_bus_; i2c_master_bus_handle_t i2c_bus_;
@@ -63,7 +60,6 @@ private:
int espok = esp_lcd_new_panel_io_3wire_spi(&io_config, &panel_io); int espok = esp_lcd_new_panel_io_3wire_spi(&io_config, &panel_io);
ESP_LOGI(TAG, "Install 3-wire SPI panel IO:%d",espok); ESP_LOGI(TAG, "Install 3-wire SPI panel IO:%d",espok);
ESP_LOGI(TAG, "Install RGB LCD panel driver"); ESP_LOGI(TAG, "Install RGB LCD panel driver");
esp_lcd_panel_handle_t panel_handle = NULL; esp_lcd_panel_handle_t panel_handle = NULL;
esp_lcd_rgb_panel_config_t rgb_config = { esp_lcd_rgb_panel_config_t rgb_config = {
@@ -126,13 +122,9 @@ private:
display_ = new RgbLcdDisplay(panel_io, panel_handle, display_ = new RgbLcdDisplay(panel_io, panel_handle,
DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X,
DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY);
{
.text_font = &font_puhui_30_4,
.icon_font = &font_awesome_30_4,
.emoji_font = font_emoji_64_init(),
});
} }
void InitializeCodecI2c() { void InitializeCodecI2c() {
// Initialize I2C peripheral // Initialize I2C peripheral
i2c_master_bus_config_t i2c_bus_cfg = { i2c_master_bus_config_t i2c_bus_cfg = {
@@ -211,8 +203,6 @@ public:
InitializeTouch(); InitializeTouch();
} }
//es7210用作音频采集
virtual AudioCodec* GetAudioCodec() override { virtual AudioCodec* GetAudioCodec() override {
static BoxAudioCodec audio_codec( static BoxAudioCodec audio_codec(
i2c_bus_, i2c_bus_,
@@ -230,8 +220,6 @@ public:
return &audio_codec; return &audio_codec;
} }
virtual Display* GetDisplay() override { virtual Display* GetDisplay() override {
return display_; return display_;
} }
@@ -242,7 +230,6 @@ public:
return &led; return &led;
} }
}; };
DECLARE_BOARD(ESP_S3_LCD_EV_Board_2); DECLARE_BOARD(ESP_S3_LCD_EV_Board_2);

View File

@@ -20,9 +20,6 @@
#define TAG "ESP_S3_LCD_EV_Board" #define TAG "ESP_S3_LCD_EV_Board"
LV_FONT_DECLARE(font_puhui_30_4);
LV_FONT_DECLARE(font_awesome_30_4);
class ESP_S3_LCD_EV_Board : public WifiBoard { class ESP_S3_LCD_EV_Board : public WifiBoard {
private: private:
i2c_master_bus_handle_t codec_i2c_bus_; i2c_master_bus_handle_t codec_i2c_bus_;
@@ -62,7 +59,6 @@ private:
int espok = esp_lcd_new_panel_io_3wire_spi(&io_config, &panel_io); int espok = esp_lcd_new_panel_io_3wire_spi(&io_config, &panel_io);
ESP_LOGI(TAG, "Install 3-wire SPI panel IO:%d",espok); ESP_LOGI(TAG, "Install 3-wire SPI panel IO:%d",espok);
ESP_LOGI(TAG, "Install RGB LCD panel driver"); ESP_LOGI(TAG, "Install RGB LCD panel driver");
esp_lcd_panel_handle_t panel_handle = NULL; esp_lcd_panel_handle_t panel_handle = NULL;
esp_lcd_rgb_panel_config_t rgb_config = { esp_lcd_rgb_panel_config_t rgb_config = {
@@ -126,13 +122,9 @@ private:
display_ = new RgbLcdDisplay(panel_io, panel_handle, display_ = new RgbLcdDisplay(panel_io, panel_handle,
DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X,
DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY);
{
.text_font = &font_puhui_30_4,
.icon_font = &font_awesome_30_4,
.emoji_font = font_emoji_64_init(),
});
} }
void InitializeCodecI2c() { void InitializeCodecI2c() {
// Initialize I2C peripheral // Initialize I2C peripheral
i2c_master_bus_config_t i2c_bus_cfg = { i2c_master_bus_config_t i2c_bus_cfg = {
@@ -180,8 +172,6 @@ public:
InitializeRGB_GC9503V_Display(); InitializeRGB_GC9503V_Display();
} }
//es7210用作音频采集
virtual AudioCodec* GetAudioCodec() override { virtual AudioCodec* GetAudioCodec() override {
static BoxAudioCodec audio_codec( static BoxAudioCodec audio_codec(
codec_i2c_bus_, codec_i2c_bus_,
@@ -199,8 +189,6 @@ public:
return &audio_codec; return &audio_codec;
} }
virtual Display* GetDisplay() override { virtual Display* GetDisplay() override {
return display_; return display_;
} }
@@ -211,7 +199,6 @@ public:
return &led; return &led;
} }
}; };
DECLARE_BOARD(ESP_S3_LCD_EV_Board); DECLARE_BOARD(ESP_S3_LCD_EV_Board);

Some files were not shown because too many files have changed in this diff Show More