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
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_compile_options(-Wno-missing-field-initializers)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(xiaozhi)

View File

@@ -1,6 +1,6 @@
dependencies:
78/esp-ml307:
component_hash: 97a1eeb5274d841bbfbe50ef6b6976f028b0f53e57aee95eda57f49048d02fb9
component_hash: 6e027bda53d9ac45ae17f33cce84c3b9fc0f5bdbe61a5b1642798d3088035a13
dependencies:
- name: idf
require: private
@@ -8,7 +8,7 @@ dependencies:
source:
registry_url: https://components.espressif.com/
type: service
version: 3.3.0
version: 3.3.3
78/esp-opus:
component_hash: 8182b733f071d7bfe1e837f4c9f8649a63e4c937177f089e65772880c02f2e17
dependencies:
@@ -58,7 +58,7 @@ dependencies:
type: service
version: 1.0.0
78/xiaozhi-fonts:
component_hash: d9cc3aad735638e558cee514103b25d2cb60afc78ef53709ffeea443b4d1c835
component_hash: 677fa98425b8c20f3db336c81b5abdf0445ea0adf2ce40b28940daaa84c92dcb
dependencies:
- name: idf
require: private
@@ -66,7 +66,7 @@ dependencies:
source:
registry_url: https://components.espressif.com/
type: service
version: 1.5.1
version: 1.5.2
chmorgan/esp-libhelix-mp3:
component_hash: cbb76089dc2c5749f7b470e2e70aedc44c9da519e04eb9a67d4c7ec275229e53
dependencies:
@@ -336,7 +336,7 @@ dependencies:
type: service
version: 1.0.1
espressif/esp_lcd_st7796:
component_hash: 00ab2872c56a4037e6d1efda104ef0da00c5296865f8f938cc7cc2fc3e99f962
component_hash: 9e165065cf25b4575dd9f587440ad22aa94d011359d55a97fc39bb691a9fc0cd
dependencies:
- name: espressif/cmake_utilities
registry_url: https://components.espressif.com
@@ -353,7 +353,7 @@ dependencies:
- esp32s2
- esp32s3
- esp32p4
version: 1.3.2
version: 1.3.4
espressif/esp_lcd_touch:
component_hash: 779b4ba2464a3ae85681e4b860caa5fdc35801458c23f3039ee761bae7f442a4
dependencies:
@@ -654,6 +654,6 @@ direct_dependencies:
- waveshare/esp_lcd_sh8601
- waveshare/esp_lcd_touch_cst9217
- wvirgil123/sscma_client
manifest_hash: 1af3184e8179db5dd2d5a0a78e420c425305f4b1d7378a0340ce6fbbffd67c14
manifest_hash: 659036190b734dad33276480a74cb2e2104cfe1b84178427bce474673a9f6e04
target: esp32s3
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"
"audio/audio_service.cc"
"audio/codecs/no_audio_codec.cc"
@@ -14,6 +50,13 @@ set(SOURCES "audio/audio_codec.cc"
"display/display.cc"
"display/lcd_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/mqtt_protocol.cc"
"protocols/websocket_protocol.cc"
@@ -23,210 +66,465 @@ set(SOURCES "audio/audio_codec.cc"
"ota.cc"
"settings.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)
list(APPEND SOURCES ${BOARD_COMMON_SOURCES})
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)
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)
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)
set(BOARD_TYPE "bread-compact-esp32")
elseif(CONFIG_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)
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)
set(BOARD_TYPE "df-s3-ai-cam")
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_WAKENET_ONLY})
elseif(CONFIG_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)
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)
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)
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)
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)
set(BOARD_TYPE "kevin-c3")
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_S_WAKENET_ONLY})
elseif(CONFIG_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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
set(BOARD_TYPE "atoms3r-cam-m12-echo-base")
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_WAKENET_ONLY})
elseif(CONFIG_BOARD_TYPE_ATOM_ECHOS3R)
set(BOARD_TYPE "atom-echos3r")
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_WAKENET_ONLY})
elseif(CONFIG_BOARD_TYPE_ATOMMATRIX_ECHO_BASE)
set(BOARD_TYPE "atommatrix-echo-base")
elseif(CONFIG_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)
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)
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)
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)
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)
set(BOARD_TYPE "esp-spot-s3")
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_WAKENET_ONLY})
elseif(CONFIG_BOARD_TYPE_ESP_HI)
set(BOARD_TYPE "esp-hi")
elseif(CONFIG_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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
set(BOARD_TYPE "lilygo-t-cameraplus-s3")
elseif(CONFIG_BOARD_TYPE_LILYGO_T_CAMERAPLUS_S3_V1_2)
set(BOARD_TYPE "lilygo-t-cameraplus-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_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(BOARD_TYPE "lilygo-t-display-s3-pro-mvsrlora")
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_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(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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
set(BOARD_TYPE "doit-s3-aibox")
set(DEFAULT_ASSETS ${ASSETS_XIAOZHI_WAKENET_ONLY})
elseif(CONFIG_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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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()
file(GLOB BOARD_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/boards/${BOARD_TYPE}/*.cc
${CMAKE_CURRENT_SOURCE_DIR}/boards/${BOARD_TYPE}/*.c
)
list(APPEND SOURCES ${BOARD_SOURCES})
# Select audio processor according to Kconfig
if(CONFIG_USE_AUDIO_PROCESSOR)
list(APPEND SOURCES "audio/processors/afe_audio_processor.cc")
else()
@@ -240,7 +538,7 @@ elseif(CONFIG_USE_CUSTOM_WAKE_WORD)
list(APPEND SOURCES "audio/wake_words/custom_wake_word.cc")
endif()
# 根据Kconfig选择语言目录
# Select language directory according to Kconfig
if(CONFIG_LANGUAGE_ZH_CN)
set(LANG_DIR "zh-CN")
elseif(CONFIG_LANGUAGE_ZH_TW)
@@ -287,13 +585,13 @@ elseif(CONFIG_LANGUAGE_RO_RO)
set(LANG_DIR "ro-RO")
endif()
# 定义生成路径
# Define generation path
set(LANG_JSON "${CMAKE_CURRENT_SOURCE_DIR}/assets/locales/${LANG_DIR}/language.json")
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 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)
list(REMOVE_ITEM SOURCES "audio/codecs/box_audio_codec.cc"
"audio/codecs/es8388_audio_codec.cc"
@@ -308,16 +606,17 @@ idf_component_register(SRCS ${SOURCES}
WHOLE_ARCHIVE
)
# 使用 target_compile_definitions 来定义 BOARD_TYPE, BOARD_NAME
# 如果 BOARD_NAME 为空,则使用 BOARD_TYPE
# Use target_compile_definitions to define BOARD_TYPE, BOARD_NAME
# If BOARD_NAME is empty, use BOARD_TYPE
if(NOT BOARD_NAME)
set(BOARD_NAME ${BOARD_TYPE})
endif()
target_compile_definitions(${COMPONENT_LIB}
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(
OUTPUT ${LANG_HEADER}
COMMAND python ${PROJECT_DIR}/scripts/gen_lang.py
@@ -329,7 +628,7 @@ add_custom_command(
COMMENT "Generating ${LANG_DIR} language config"
)
# 强制建立生成依赖
# Force build generation dependencies
add_custom_target(lang_header ALL
DEPENDS ${LANG_HEADER}
)
@@ -355,7 +654,7 @@ foreach(FILENAME IN LISTS FILES_TO_DOWNLOAD)
set(REMOTE_FILE "${URL}/${FILENAME}")
set(LOCAL_FILE "${SPIFFS_DIR}/${FILENAME}")
# 检查本地文件是否存在
# Check if local file exists
if(EXISTS ${LOCAL_FILE})
message(STATUS "File ${FILENAME} already exists, skipping download")
else()
@@ -397,3 +696,131 @@ spiffs_create_partition_assets(
IMPORT_INC_PATH ${CMAKE_CURRENT_SOURCE_DIR}/boards/${BOARD_TYPE}
)
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
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
prompt "Default Language"

View File

@@ -7,6 +7,8 @@
#include "websocket_protocol.h"
#include "assets/lang_config.h"
#include "mcp_server.h"
#include "assets.h"
#include "settings.h"
#include <cstring>
#include <esp_log.h>
@@ -49,7 +51,7 @@ Application::Application() {
esp_timer_create_args_t clock_timer_args = {
.callback = [](void* arg) {
Application* app = (Application*)arg;
app->OnClockTimer();
xEventGroupSetBits(app->event_group_, MAIN_EVENT_CLOCK_TICK);
},
.arg = this,
.dispatch_method = ESP_TIMER_TASK,
@@ -67,6 +69,65 @@ Application::~Application() {
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) {
const int MAX_RETRY = 10;
int retry_count = 0;
@@ -103,43 +164,10 @@ void Application::CheckNewVersion(Ota& ota) {
retry_delay = 10; // 重置重试延迟时间
if (ota.HasNewVersion()) {
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) + 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();
if (UpgradeFirmware(ota)) {
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
@@ -358,6 +386,9 @@ void Application::Start() {
// Update the status bar immediately to show the network state
display->UpdateStatusBar(true);
// Check for new assets version
CheckAssetsVersion();
// Check for new firmware version or get the MQTT broker address
Ota ota;
CheckNewVersion(ota);
@@ -366,7 +397,9 @@ void Application::Start() {
display->SetStatus(Lang::Strings::LOADING_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()) {
protocol_ = std::make_unique<MqttProtocol>();
@@ -496,6 +529,7 @@ void Application::Start() {
});
bool protocol_started = protocol_->Start();
SystemInfo::PrintHeapStats();
SetDeviceState(kDeviceStateIdle);
has_server_time_ = ota.HasServerTime();
@@ -506,23 +540,6 @@ void Application::Start() {
// Play the success sound to indicate the device is ready
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
@@ -546,7 +563,9 @@ void Application::MainEventLoop() {
MAIN_EVENT_SEND_AUDIO |
MAIN_EVENT_WAKE_WORD_DETECTED |
MAIN_EVENT_VAD_CHANGE |
MAIN_EVENT_CLOCK_TICK |
MAIN_EVENT_ERROR, pdTRUE, pdFALSE, portMAX_DELAY);
if (bits & MAIN_EVENT_ERROR) {
SetDeviceState(kDeviceStateIdle);
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) {
while (auto packet = audio_service_.PopPacketFromSendQueue()) {
if (!protocol_->SendAudio(std::move(packet))) {
if (protocol_ && !protocol_->SendAudio(std::move(packet))) {
break;
}
}
@@ -579,6 +598,19 @@ void Application::MainEventLoop() {
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) {
ESP_LOGI(TAG, "Abort speaking");
aborted_ = true;
protocol_->SendAbortSpeaking(reason);
if (protocol_) {
protocol_->SendAbortSpeaking(reason);
}
}
void Application::SetListeningMode(ListeningMode mode) {
@@ -706,9 +740,70 @@ void Application::SetDeviceState(DeviceState state) {
void Application::Reboot() {
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();
}
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) {
if (device_state_ == kDeviceStateIdle) {
ToggleChatState();

View File

@@ -16,12 +16,15 @@
#include "audio_service.h"
#include "device_state_event.h"
#define MAIN_EVENT_SCHEDULE (1 << 0)
#define MAIN_EVENT_SEND_AUDIO (1 << 1)
#define MAIN_EVENT_WAKE_WORD_DETECTED (1 << 2)
#define MAIN_EVENT_VAD_CHANGE (1 << 3)
#define MAIN_EVENT_ERROR (1 << 4)
#define MAIN_EVENT_CHECK_NEW_VERSION_DONE (1 << 5)
#define MAIN_EVENT_CLOCK_TICK (1 << 6)
enum AecMode {
kAecOff,
@@ -53,6 +56,7 @@ public:
void StopListening();
void Reboot();
void WakeWordInvoke(const std::string& wake_word);
bool UpgradeFirmware(Ota& ota, const std::string& url = "");
bool CanEnterSleepMode();
void SendMcpMessage(const std::string& payload);
void SetAecMode(AecMode mode);
@@ -85,8 +89,8 @@ private:
void OnWakeWordDetected();
void CheckNewVersion(Ota& ota);
void CheckAssetsVersion();
void ShowActivationCode(const std::string& code, const std::string& message);
void OnClockTimer();
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_HOTSPOT = "手机连接热点 ";
constexpr const char* DETECTING_MODULE = "检测模组...";
constexpr const char* DOWNLOAD_ASSETS_FAILED = "下载资源失败";
constexpr const char* ENTERING_WIFI_CONFIG_MODE = "进入配网模式...";
constexpr const char* ERROR = "错误";
constexpr const char* FOUND_NEW_ASSETS = "发现新资源: %s";
constexpr const char* HELLO_MY_FRIEND = "你好,我的朋友!";
constexpr const char* INFO = "信息";
constexpr const char* INITIALIZING = "正在初始化...";
constexpr const char* LISTENING = "聆听中...";
constexpr const char* LOADING_ASSETS = "加载资源...";
constexpr const char* LOADING_PROTOCOL = "登录服务器...";
constexpr const char* MAX_VOLUME = "最大音量";
constexpr const char* MUTED = "已静音";
constexpr const char* NEW_VERSION = "新版本 ";
constexpr const char* OTA_UPGRADE = "OTA 升级";
constexpr const char* PIN_ERROR = "请插入 SIM 卡";
constexpr const char* PLEASE_WAIT = "请稍候...";
constexpr const char* REGISTERING_NETWORK = "等待网络...";
constexpr const char* REG_ERROR = "无法接入网络,请检查流量卡状态";
constexpr const char* RTC_MODE_OFF = "AEC 关闭";

View File

@@ -1,58 +1,55 @@
{
"language": {
"type" :"ar-SA"
"type": "ar-SA"
},
"strings": {
"WARNING":"تحذير",
"INFO":"معلومات",
"ERROR":"خطأ",
"WARNING": "تحذير",
"INFO": "معلومات",
"ERROR": "خطأ",
"VERSION": "الإصدار ",
"LOADING_PROTOCOL":"الاتصال بالخادم...",
"INITIALIZING":"التهيئة...",
"PIN_ERROR":"يرجى إدخال بطاقة SIM",
"REG_ERROR":"لا يمكن الوصول إلى الشبكة، يرجى التحقق من حالة بطاقة البيانات",
"DETECTING_MODULE":"اكتشاف الوحدة...",
"REGISTERING_NETWORK":"انتظار الشبكة...",
"CHECKING_NEW_VERSION":"فحص الإصدار الجديد...",
"CHECK_NEW_VERSION_FAILED":"فشل فحص الإصدار الجديد، سيتم المحاولة خلال %d ثانية: %s",
"SWITCH_TO_WIFI_NETWORK":"التبديل إلى Wi-Fi...",
"SWITCH_TO_4G_NETWORK":"التبديل إلى 4G...",
"STANDBY":"في الانتظار",
"CONNECT_TO":"الاتصال بـ ",
"CONNECTING":"جاري الاتصال...",
"CONNECTED_TO":"متصل بـ ",
"LISTENING":"الاستماع...",
"SPEAKING":"التحدث...",
"SERVER_NOT_FOUND":"البحث عن خدمة متاحة",
"SERVER_NOT_CONNECTED":ا يمكن الاتصال بالخدمة، يرجى المحاولة لاحقاً",
"SERVER_TIMEOUT":"انتهت مهلة الاستجابة",
"SERVER_ERROR":"فشل الإرسال، يرجى التحقق من الشبكة",
"CONNECT_TO_HOTSPOT":"اتصل الهاتف بنقطة الاتصال ",
"ACCESS_VIA_BROWSER":"،الوصول عبر المتصفح ",
"WIFI_CONFIG_MODE":"وضع تكوين الشبكة",
"ENTERING_WIFI_CONFIG_MODE":"الدخول في وضع تكوين الشبكة...",
"SCANNING_WIFI":"فحص Wi-Fi...",
"LOADING_PROTOCOL": "الاتصال بالخادم...",
"INITIALIZING": "التهيئة...",
"PIN_ERROR": "يرجى إدخال بطاقة SIM",
"REG_ERROR": "لا يمكن الوصول إلى الشبكة، يرجى التحقق من حالة بطاقة البيانات",
"DETECTING_MODULE": "اكتشاف الوحدة...",
"REGISTERING_NETWORK": "انتظار الشبكة...",
"CHECKING_NEW_VERSION": "فحص الإصدار الجديد...",
"CHECK_NEW_VERSION_FAILED": "فشل فحص الإصدار الجديد، سيتم المحاولة خلال %d ثانية: %s",
"SWITCH_TO_WIFI_NETWORK": "التبديل إلى Wi-Fi...",
"SWITCH_TO_4G_NETWORK": "التبديل إلى 4G...",
"STANDBY": "في الانتظار",
"CONNECT_TO": "الاتصال بـ ",
"CONNECTING": "جاري الاتصال...",
"CONNECTED_TO": "متصل بـ ",
"LISTENING": "الاستماع...",
"SPEAKING": "التحدث...",
"SERVER_NOT_FOUND": "البحث عن خدمة متاحة",
"SERVER_NOT_CONNECTED": "لا يمكن الاتصال بالخدمة، يرجى المحاولة لاحقاً",
"SERVER_TIMEOUT": "انتهت مهلة الاستجابة",
"SERVER_ERROR": "فشل الإرسال، يرجى التحقق من الشبكة",
"CONNECT_TO_HOTSPOT": "اتصل الهاتف بنقطة الاتصال ",
"ACCESS_VIA_BROWSER": "،الوصول عبر المتصفح ",
"WIFI_CONFIG_MODE": "وضع تكوين الشبكة",
"ENTERING_WIFI_CONFIG_MODE": "الدخول في وضع تكوين الشبكة...",
"SCANNING_WIFI": "فحص Wi-Fi...",
"NEW_VERSION": "إصدار جديد ",
"OTA_UPGRADE":"تحديث OTA",
"UPGRADING":"تحديث النظام...",
"UPGRADE_FAILED":"فشل التحديث",
"ACTIVATION":"تفعيل الجهاز",
"BATTERY_LOW":"البطارية منخفضة",
"BATTERY_CHARGING":"جاري الشحن",
"BATTERY_FULL":"البطارية ممتلئة",
"BATTERY_NEED_CHARGE":"البطارية منخفضة، يرجى الشحن",
"VOLUME":"الصوت ",
"MUTED":"صامت",
"MAX_VOLUME":"أقصى صوت",
"RTC_MODE_OFF":"AEC مُوقف",
"RTC_MODE_ON":"AEC مُشغل"
"OTA_UPGRADE": "تحديث OTA",
"UPGRADING": "تحديث النظام...",
"UPGRADE_FAILED": "فشل التحديث",
"ACTIVATION": "تفعيل الجهاز",
"BATTERY_LOW": "البطارية منخفضة",
"BATTERY_CHARGING": "جاري الشحن",
"BATTERY_FULL": "البطارية ممتلئة",
"BATTERY_NEED_CHARGE": "البطارية منخفضة، يرجى الشحن",
"VOLUME": "الصوت ",
"MUTED": "صامت",
"MAX_VOLUME": "أقصى صوت",
"RTC_MODE_OFF": "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": {
"type" :"cs-CZ"
"type": "cs-CZ"
},
"strings": {
"WARNING":"Varování",
"INFO":"Informace",
"ERROR":"Chyba",
"WARNING": "Varování",
"INFO": "Informace",
"ERROR": "Chyba",
"VERSION": "Verze ",
"LOADING_PROTOCOL":"Připojování k serveru...",
"INITIALIZING":"Inicializace...",
"PIN_ERROR":"Prosím vložte SIM kartu",
"REG_ERROR":"Nelze se připojit k síti, zkontrolujte stav datové karty",
"DETECTING_MODULE":"Detekce modulu...",
"REGISTERING_NETWORK":"Čekání na síť...",
"CHECKING_NEW_VERSION":"Kontrola nové verze...",
"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_4G_NETWORK":"Přepínání na 4G...",
"STANDBY":"Pohotovost",
"CONNECT_TO":"Připojit k ",
"CONNECTING":"Připojování...",
"CONNECTED_TO":"Připojeno k ",
"LISTENING":"Naslouchání...",
"SPEAKING":"Mluvení...",
"SERVER_NOT_FOUND":"Hledání dostupné služby",
"SERVER_NOT_CONNECTED":"Nelze se připojit ke službě, zkuste to později",
"SERVER_TIMEOUT":"Čas odpovědi vypršel",
"SERVER_ERROR":"Odeslání selhalo, zkontrolujte síť",
"CONNECT_TO_HOTSPOT":"Připojte telefon k hotspotu ",
"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...",
"LOADING_PROTOCOL": "Připojování k serveru...",
"INITIALIZING": "Inicializace...",
"PIN_ERROR": "Prosím vložte SIM kartu",
"REG_ERROR": "Nelze se připojit k síti, zkontrolujte stav datové karty",
"DETECTING_MODULE": "Detekce modulu...",
"REGISTERING_NETWORK": "Čekání na síť...",
"CHECKING_NEW_VERSION": "Kontrola nové verze...",
"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_4G_NETWORK": "Přepínání na 4G...",
"STANDBY": "Pohotovost",
"CONNECT_TO": "Připojit k ",
"CONNECTING": "Připojování...",
"CONNECTED_TO": "Připojeno k ",
"LISTENING": "Naslouchání...",
"SPEAKING": "Mluvení...",
"SERVER_NOT_FOUND": "Hledání dostupné služby",
"SERVER_NOT_CONNECTED": "Nelze se připojit ke službě, zkuste to později",
"SERVER_TIMEOUT": "Čas odpovědi vypršel",
"SERVER_ERROR": "Odeslání selhalo, zkontrolujte síť",
"CONNECT_TO_HOTSPOT": "Připojte telefon k hotspotu ",
"ACCESS_VIA_BROWSER": "přístup přes prohlížeč ",
"WIFI_CONFIG_MODE": "Režim konfigurace sí",
"ENTERING_WIFI_CONFIG_MODE": "Vstup do režimu konfigurace sítě...",
"SCANNING_WIFI": "Skenování Wi-Fi...",
"NEW_VERSION": "Nová verze ",
"OTA_UPGRADE":"OTA upgrade",
"UPGRADING":"Aktualizace systému...",
"UPGRADE_FAILED":"Upgrade selhal",
"ACTIVATION":"Aktivace zařízení",
"BATTERY_LOW":"Slabá baterie",
"BATTERY_CHARGING":"Nabíjení",
"BATTERY_FULL":"Baterie plná",
"BATTERY_NEED_CHARGE":"Slabá baterie, prosím nabijte",
"VOLUME":"Hlasitost ",
"MUTED":"Ztlumeno",
"MAX_VOLUME":"Maximální hlasitost",
"RTC_MODE_OFF":"AEC vypnuto",
"RTC_MODE_ON":"AEC zapnuto"
"OTA_UPGRADE": "OTA upgrade",
"UPGRADING": "Aktualizace systému...",
"UPGRADE_FAILED": "Upgrade selhal",
"ACTIVATION": "Aktivace zařízení",
"BATTERY_LOW": "Slabá baterie",
"BATTERY_CHARGING": "Nabíjení",
"BATTERY_FULL": "Baterie plná",
"BATTERY_NEED_CHARGE": "Slabá baterie, prosím nabijte",
"VOLUME": "Hlasitost ",
"MUTED": "Ztlumeno",
"MAX_VOLUME": "Maximální hlasitost",
"RTC_MODE_OFF": "AEC vypnuto",
"RTC_MODE_ON": "AEC zapnuto",
"DOWNLOAD_ASSETS_FAILED": "Nepodařilo se stáhnout prostředky",
"LOADING_ASSETS": "Načítání prostředků...",
"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": {
"type" :"de-DE"
"type": "de-DE"
},
"strings": {
"WARNING":"Warnung",
"INFO":"Information",
"ERROR":"Fehler",
"WARNING": "Warnung",
"INFO": "Information",
"ERROR": "Fehler",
"VERSION": "Version ",
"LOADING_PROTOCOL":"Verbindung zum Server...",
"INITIALIZING":"Initialisierung...",
"PIN_ERROR":"Bitte SIM-Karte einlegen",
"REG_ERROR":"Netzwerkverbindung fehlgeschlagen, bitte Datenkartenstatus prüfen",
"DETECTING_MODULE":"Modul erkennen...",
"REGISTERING_NETWORK":"Auf Netzwerk warten...",
"CHECKING_NEW_VERSION":"Neue Version prüfen...",
"CHECK_NEW_VERSION_FAILED":"Neue Version prüfen fehlgeschlagen, Wiederholung in %d Sekunden: %s",
"SWITCH_TO_WIFI_NETWORK":"Zu Wi-Fi wechseln...",
"SWITCH_TO_4G_NETWORK":"Zu 4G wechseln...",
"STANDBY":"Bereitschaft",
"CONNECT_TO":"Verbinden zu ",
"CONNECTING":"Verbindung wird hergestellt...",
"CONNECTED_TO":"Verbunden mit ",
"LISTENING":"Zuhören...",
"SPEAKING":"Sprechen...",
"SERVER_NOT_FOUND":"Verfügbaren Service suchen",
"SERVER_NOT_CONNECTED":"Service-Verbindung fehlgeschlagen, bitte später versuchen",
"SERVER_TIMEOUT":"Antwort-Timeout",
"SERVER_ERROR":"Senden fehlgeschlagen, bitte Netzwerk prüfen",
"CONNECT_TO_HOTSPOT":"Handy mit Hotspot verbinden ",
"ACCESS_VIA_BROWSER":"Browser öffnen ",
"WIFI_CONFIG_MODE":"Netzwerkkonfigurationsmodus",
"ENTERING_WIFI_CONFIG_MODE":"Netzwerkkonfigurationsmodus eingeben...",
"SCANNING_WIFI":"Wi-Fi scannen...",
"LOADING_PROTOCOL": "Verbindung zum Server...",
"INITIALIZING": "Initialisierung...",
"PIN_ERROR": "Bitte SIM-Karte einlegen",
"REG_ERROR": "Netzwerkverbindung fehlgeschlagen, bitte Datenkartenstatus prüfen",
"DETECTING_MODULE": "Modul erkennen...",
"REGISTERING_NETWORK": "Auf Netzwerk warten...",
"CHECKING_NEW_VERSION": "Neue Version prüfen...",
"CHECK_NEW_VERSION_FAILED": "Neue Version prüfen fehlgeschlagen, Wiederholung in %d Sekunden: %s",
"SWITCH_TO_WIFI_NETWORK": "Zu Wi-Fi wechseln...",
"SWITCH_TO_4G_NETWORK": "Zu 4G wechseln...",
"STANDBY": "Bereitschaft",
"CONNECT_TO": "Verbinden zu ",
"CONNECTING": "Verbindung wird hergestellt...",
"CONNECTED_TO": "Verbunden mit ",
"LISTENING": "Zuhören...",
"SPEAKING": "Sprechen...",
"SERVER_NOT_FOUND": "Verfügbaren Service suchen",
"SERVER_NOT_CONNECTED": "Service-Verbindung fehlgeschlagen, bitte später versuchen",
"SERVER_TIMEOUT": "Antwort-Timeout",
"SERVER_ERROR": "Senden fehlgeschlagen, bitte Netzwerk prüfen",
"CONNECT_TO_HOTSPOT": "Handy mit Hotspot verbinden ",
"ACCESS_VIA_BROWSER": "Browser öffnen ",
"WIFI_CONFIG_MODE": "Netzwerkkonfigurationsmodus",
"ENTERING_WIFI_CONFIG_MODE": "Netzwerkkonfigurationsmodus eingeben...",
"SCANNING_WIFI": "Wi-Fi scannen...",
"NEW_VERSION": "Neue Version ",
"OTA_UPGRADE":"OTA-Upgrade",
"UPGRADING":"System wird aktualisiert...",
"UPGRADE_FAILED":"Upgrade fehlgeschlagen",
"ACTIVATION":"Gerät aktivieren",
"BATTERY_LOW":"Niedriger Batteriestand",
"BATTERY_CHARGING":"Wird geladen",
"BATTERY_FULL":"Batterie voll",
"BATTERY_NEED_CHARGE":"Niedriger Batteriestand, bitte aufladen",
"VOLUME":"Lautstärke ",
"MUTED":"Stummgeschaltet",
"MAX_VOLUME":"Maximale Lautstärke",
"RTC_MODE_OFF":"AEC aus",
"RTC_MODE_ON":"AEC ein"
"OTA_UPGRADE": "OTA-Upgrade",
"UPGRADING": "System wird aktualisiert...",
"UPGRADE_FAILED": "Upgrade fehlgeschlagen",
"ACTIVATION": "Gerät aktivieren",
"BATTERY_LOW": "Niedriger Batteriestand",
"BATTERY_CHARGING": "Wird geladen",
"BATTERY_FULL": "Batterie voll",
"BATTERY_NEED_CHARGE": "Niedriger Batteriestand, bitte aufladen",
"VOLUME": "Lautstärke ",
"MUTED": "Stummgeschaltet",
"MAX_VOLUME": "Maximale Lautstärke",
"RTC_MODE_OFF": "AEC aus",
"RTC_MODE_ON": "AEC ein",
"DOWNLOAD_ASSETS_FAILED": "Fehler beim Herunterladen der Ressourcen",
"LOADING_ASSETS": "Ressourcen werden geladen...",
"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",
"SWITCH_TO_WIFI_NETWORK": "Switching to Wi-Fi...",
"SWITCH_TO_4G_NETWORK": "Switching to 4G...",
"STANDBY": "Standby",
"CONNECT_TO": "Connect to ",
"CONNECTING": "Connecting...",
"CONNECTION_SUCCESSFUL": "Connection Successful",
"CONNECTED_TO": "Connected to ",
"LISTENING": "Listening...",
"SPEAKING": "Speaking...",
"SERVER_NOT_FOUND": "Looking for available service",
"SERVER_NOT_CONNECTED": "Unable to connect to service, please try again later",
"SERVER_TIMEOUT": "Waiting for response timeout",
"SERVER_ERROR": "Sending failed, please check the network",
"CONNECT_TO_HOTSPOT": "Hotspot: ",
"ACCESS_VIA_BROWSER": " Config URL: ",
"WIFI_CONFIG_MODE": "Wi-Fi Configuration Mode",
"ENTERING_WIFI_CONFIG_MODE": "Entering Wi-Fi configuration mode...",
"SCANNING_WIFI": "Scanning Wi-Fi...",
"NEW_VERSION": "New version ",
"OTA_UPGRADE": "OTA Upgrade",
"UPGRADING": "System is upgrading...",
"UPGRADE_FAILED": "Upgrade failed",
"ACTIVATION": "Activation",
"BATTERY_LOW": "Low battery",
"BATTERY_CHARGING": "Charging",
"BATTERY_FULL": "Battery full",
"BATTERY_NEED_CHARGE": "Low battery, please charge",
"VOLUME": "Volume ",
"MUTED": "Muted",
"MAX_VOLUME": "Max volume",
"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": {
"type" :"es-ES"
"type": "es-ES"
},
"strings": {
"WARNING":"Advertencia",
"INFO":"Información",
"ERROR":"Error",
"WARNING": "Advertencia",
"INFO": "Información",
"ERROR": "Error",
"VERSION": "Versión ",
"LOADING_PROTOCOL":"Conectando al servidor...",
"INITIALIZING":"Inicializando...",
"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",
"DETECTING_MODULE":"Detectando módulo...",
"REGISTERING_NETWORK":"Esperando red...",
"CHECKING_NEW_VERSION":"Verificando nueva versión...",
"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_4G_NETWORK":"Cambiando a 4G...",
"STANDBY":"En espera",
"CONNECT_TO":"Conectar a ",
"CONNECTING":"Conectando...",
"CONNECTED_TO":"Conectado a ",
"LISTENING":"Escuchando...",
"SPEAKING":"Hablando...",
"SERVER_NOT_FOUND":"Buscando servicio disponible",
"SERVER_NOT_CONNECTED":"No se puede conectar al servicio, inténtelo más tarde",
"SERVER_TIMEOUT":"Tiempo de espera agotado",
"SERVER_ERROR":"Error de envío, verifique la red",
"CONNECT_TO_HOTSPOT":"Conectar teléfono al punto de acceso ",
"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...",
"LOADING_PROTOCOL": "Conectando al servidor...",
"INITIALIZING": "Inicializando...",
"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",
"DETECTING_MODULE": "Detectando módulo...",
"REGISTERING_NETWORK": "Esperando red...",
"CHECKING_NEW_VERSION": "Verificando nueva versión...",
"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_4G_NETWORK": "Cambiando a 4G...",
"STANDBY": "En espera",
"CONNECT_TO": "Conectar a ",
"CONNECTING": "Conectando...",
"CONNECTED_TO": "Conectado a ",
"LISTENING": "Escuchando...",
"SPEAKING": "Hablando...",
"SERVER_NOT_FOUND": "Buscando servicio disponible",
"SERVER_NOT_CONNECTED": "No se puede conectar al servicio, inténtelo más tarde",
"SERVER_TIMEOUT": "Tiempo de espera agotado",
"SERVER_ERROR": "Error de envío, verifique la red",
"CONNECT_TO_HOTSPOT": "Conectar teléfono al punto de acceso ",
"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 ",
"OTA_UPGRADE":"Actualización OTA",
"UPGRADING":"Actualizando sistema...",
"UPGRADE_FAILED":"Actualización fallida",
"ACTIVATION":"Activación del dispositivo",
"BATTERY_LOW":"Batería baja",
"BATTERY_CHARGING":"Cargando",
"BATTERY_FULL":"Batería llena",
"BATTERY_NEED_CHARGE":"Batería baja, por favor cargar",
"VOLUME":"Volumen ",
"MUTED":"Silenciado",
"MAX_VOLUME":"Volumen máximo",
"RTC_MODE_OFF":"AEC desactivado",
"RTC_MODE_ON":"AEC activado"
"OTA_UPGRADE": "Actualización OTA",
"UPGRADING": "Actualizando sistema...",
"UPGRADE_FAILED": "Actualización fallida",
"ACTIVATION": "Activación del dispositivo",
"BATTERY_LOW": "Batería baja",
"BATTERY_CHARGING": "Cargando",
"BATTERY_FULL": "Batería llena",
"BATTERY_NEED_CHARGE": "Batería baja, por favor cargar",
"VOLUME": "Volumen ",
"MUTED": "Silenciado",
"MAX_VOLUME": "Volumen máximo",
"RTC_MODE_OFF": "AEC desactivado",
"RTC_MODE_ON": "AEC activado",
"DOWNLOAD_ASSETS_FAILED": "Error al descargar recursos",
"LOADING_ASSETS": "Cargando recursos...",
"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": {
"type" :"fi-FI"
"type": "fi-FI"
},
"strings": {
"WARNING":"Varoitus",
"INFO":"Tieto",
"ERROR":"Virhe",
"WARNING": "Varoitus",
"INFO": "Tieto",
"ERROR": "Virhe",
"VERSION": "Versio ",
"LOADING_PROTOCOL":"Yhdistetään palvelimeen...",
"INITIALIZING":"Alustetaan...",
"PIN_ERROR":"Ole hyvä ja aseta SIM-kortti",
"REG_ERROR":"Ei voi muodostaa yhteyttä verkkoon, tarkista datakortin tila",
"DETECTING_MODULE":"Tunnistetaan moduuli...",
"REGISTERING_NETWORK":"Odotetaan verkkoa...",
"CHECKING_NEW_VERSION":"Tarkistetaan uutta versiota...",
"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_4G_NETWORK":"Vaihdetaan 4G:hen...",
"STANDBY":"Valmiustila",
"CONNECT_TO":"Yhdistä ",
"CONNECTING":"Yhdistetään...",
"CONNECTED_TO":"Yhdistetty ",
"LISTENING":"Kuunnellaan...",
"SPEAKING":"Puhutaan...",
"SERVER_NOT_FOUND":"Etsitään käytettävissä olevaa palvelua",
"SERVER_NOT_CONNECTED":"Ei voi yhdistää palveluun, yritä myöhemmin",
"SERVER_TIMEOUT":"Vastauksen aikakatkaisu",
"SERVER_ERROR":"Lähetys epäonnistui, tarkista verkko",
"CONNECT_TO_HOTSPOT":"Yhdistä puhelin hotspottiin ",
"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...",
"LOADING_PROTOCOL": "Yhdistetään palvelimeen...",
"INITIALIZING": "Alustetaan...",
"PIN_ERROR": "Ole hyvä ja aseta SIM-kortti",
"REG_ERROR": "Ei voi muodostaa yhteyttä verkkoon, tarkista datakortin tila",
"DETECTING_MODULE": "Tunnistetaan moduuli...",
"REGISTERING_NETWORK": "Odotetaan verkkoa...",
"CHECKING_NEW_VERSION": "Tarkistetaan uutta versiota...",
"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_4G_NETWORK": "Vaihdetaan 4G:hen...",
"STANDBY": "Valmiustila",
"CONNECT_TO": "Yhdistä ",
"CONNECTING": "Yhdistetään...",
"CONNECTED_TO": "Yhdistetty ",
"LISTENING": "Kuunnellaan...",
"SPEAKING": "Puhutaan...",
"SERVER_NOT_FOUND": "Etsitään käytettävissä olevaa palvelua",
"SERVER_NOT_CONNECTED": "Ei voi yhdistää palveluun, yritä myöhemmin",
"SERVER_TIMEOUT": "Vastauksen aikakatkaisu",
"SERVER_ERROR": "Lähetys epäonnistui, tarkista verkko",
"CONNECT_TO_HOTSPOT": "Yhdistä puhelin hotspottiin ",
"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 ",
"OTA_UPGRADE":"OTA-päivitys",
"UPGRADING":"Päivitetään järjestelmää...",
"UPGRADE_FAILED":"Päivitys epäonnistui",
"ACTIVATION":"Laitteen aktivointi",
"BATTERY_LOW":"Akku vähissä",
"BATTERY_CHARGING":"Ladataan",
"BATTERY_FULL":"Akku täynnä",
"BATTERY_NEED_CHARGE":"Akku vähissä, ole hyvä ja lataa",
"VOLUME":"Äänenvoimakkuus ",
"MUTED":"Mykistetty",
"MAX_VOLUME":"Maksimi äänenvoimakkuus",
"RTC_MODE_OFF":"AEC pois päältä",
"RTC_MODE_ON":"AEC päällä"
"OTA_UPGRADE": "OTA-päivitys",
"UPGRADING": "Päivitetään järjestelmää...",
"UPGRADE_FAILED": "Päivitys epäonnistui",
"ACTIVATION": "Laitteen aktivointi",
"BATTERY_LOW": "Akku vähissä",
"BATTERY_CHARGING": "Ladataan",
"BATTERY_FULL": "Akku täynnä",
"BATTERY_NEED_CHARGE": "Akku vähissä, ole hyvä ja lataa",
"VOLUME": "Äänenvoimakkuus ",
"MUTED": "Mykistetty",
"MAX_VOLUME": "Maksimi äänenvoimakkuus",
"RTC_MODE_OFF": "AEC pois päältä",
"RTC_MODE_ON": "AEC päällä",
"DOWNLOAD_ASSETS_FAILED": "Resurssien lataaminen epäonnistui",
"LOADING_ASSETS": "Ladataan resursseja...",
"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": {
"type" :"fr-FR"
"type": "fr-FR"
},
"strings": {
"WARNING":"Avertissement",
"INFO":"Information",
"ERROR":"Erreur",
"WARNING": "Avertissement",
"INFO": "Information",
"ERROR": "Erreur",
"VERSION": "Version ",
"LOADING_PROTOCOL":"Connexion au serveur...",
"INITIALIZING":"Initialisation...",
"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",
"DETECTING_MODULE":"Détection du module...",
"REGISTERING_NETWORK":"En attente du réseau...",
"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",
"SWITCH_TO_WIFI_NETWORK":"Basculer vers Wi-Fi...",
"SWITCH_TO_4G_NETWORK":"Basculer vers 4G...",
"STANDBY":"En attente",
"CONNECT_TO":"Se connecter à ",
"CONNECTING":"Connexion en cours...",
"CONNECTED_TO":"Connecté à ",
"LISTENING":"Écoute...",
"SPEAKING":"Parole...",
"SERVER_NOT_FOUND":"Recherche d'un service disponible",
"SERVER_NOT_CONNECTED":"Impossible de se connecter au service, veuillez réessayer plus tard",
"SERVER_TIMEOUT":"Délai d'attente de réponse",
"SERVER_ERROR":"Échec d'envoi, veuillez vérifier le réseau",
"CONNECT_TO_HOTSPOT":"Connecter le téléphone au point d'accès ",
"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...",
"LOADING_PROTOCOL": "Connexion au serveur...",
"INITIALIZING": "Initialisation...",
"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",
"DETECTING_MODULE": "Détection du module...",
"REGISTERING_NETWORK": "En attente du réseau...",
"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",
"SWITCH_TO_WIFI_NETWORK": "Basculer vers Wi-Fi...",
"SWITCH_TO_4G_NETWORK": "Basculer vers 4G...",
"STANDBY": "En attente",
"CONNECT_TO": "Se connecter à ",
"CONNECTING": "Connexion en cours...",
"CONNECTED_TO": "Connecté à ",
"LISTENING": "Écoute...",
"SPEAKING": "Parole...",
"SERVER_NOT_FOUND": "Recherche d'un service disponible",
"SERVER_NOT_CONNECTED": "Impossible de se connecter au service, veuillez réessayer plus tard",
"SERVER_TIMEOUT": "Délai d'attente de réponse",
"SERVER_ERROR": "Échec d'envoi, veuillez vérifier le réseau",
"CONNECT_TO_HOTSPOT": "Connecter le téléphone au point d'accès ",
"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 ",
"OTA_UPGRADE":"Mise à jour OTA",
"UPGRADING":"Mise à jour du système...",
"UPGRADE_FAILED":"Échec de mise à jour",
"ACTIVATION":"Activation de l'appareil",
"BATTERY_LOW":"Batterie faible",
"BATTERY_CHARGING":"En charge",
"BATTERY_FULL":"Batterie pleine",
"BATTERY_NEED_CHARGE":"Batterie faible, veuillez charger",
"VOLUME":"Volume ",
"MUTED":"Muet",
"MAX_VOLUME":"Volume maximum",
"RTC_MODE_OFF":"AEC désactivé",
"RTC_MODE_ON":"AEC activé"
"OTA_UPGRADE": "Mise à jour OTA",
"UPGRADING": "Mise à jour du système...",
"UPGRADE_FAILED": "Échec de mise à jour",
"ACTIVATION": "Activation de l'appareil",
"BATTERY_LOW": "Batterie faible",
"BATTERY_CHARGING": "En charge",
"BATTERY_FULL": "Batterie pleine",
"BATTERY_NEED_CHARGE": "Batterie faible, veuillez charger",
"VOLUME": "Volume ",
"MUTED": "Muet",
"MAX_VOLUME": "Volume maximum",
"RTC_MODE_OFF": "AEC désactivé",
"RTC_MODE_ON": "AEC activé",
"DOWNLOAD_ASSETS_FAILED": "Échec du téléchargement des ressources",
"LOADING_ASSETS": "Chargement des ressources...",
"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": {
"type" :"hi-IN"
"type": "hi-IN"
},
"strings": {
"WARNING":"चेतावनी",
"INFO":"जानकारी",
"ERROR":"त्रुटि",
"WARNING": "चेतावनी",
"INFO": "जानकारी",
"ERROR": "त्रुटि",
"VERSION": "संस्करण ",
"LOADING_PROTOCOL":"सर्वर से कनेक्ट हो रहे हैं...",
"INITIALIZING":"आरंभीकरण...",
"PIN_ERROR":"कृपया सिम कार्ड डालें",
"REG_ERROR":"नेटवर्क तक पहुंच नहीं हो सकती, कृपया डेटा कार्ड स्थिति जांचें",
"DETECTING_MODULE":"मॉड्यूल का पता लगाया जा रहा है...",
"REGISTERING_NETWORK":"नेटवर्क की प्रतीक्षा...",
"CHECKING_NEW_VERSION":"नया संस्करण जाँच रहे हैं...",
"CHECK_NEW_VERSION_FAILED":"नया संस्करण जाँचना असफल, %d सेकंड में पुनः प्रयास: %s",
"SWITCH_TO_WIFI_NETWORK":"Wi-Fi पर स्विच कर रहे हैं...",
"SWITCH_TO_4G_NETWORK":"4G पर स्विच कर रहे हैं...",
"STANDBY":"स्टैंडबाय",
"CONNECT_TO":"कनेक्ट करें ",
"CONNECTING":"कनेक्ट हो रहे हैं...",
"CONNECTED_TO":"कनेक्ट हो गए ",
"LISTENING":"सुन रहे हैं...",
"SPEAKING":"बोल रहे हैं...",
"SERVER_NOT_FOUND":"उपलब्ध सेवा खोज रहे हैं",
"SERVER_NOT_CONNECTED":"सेवा से कनेक्ट नहीं हो सकते, कृपया बाद में कोशिश करें",
"SERVER_TIMEOUT":"प्रतिक्रिया का समय समाप्त",
"SERVER_ERROR":"भेजना असफल, कृपया नेटवर्क जांचें",
"CONNECT_TO_HOTSPOT":"फोन को हॉटस्पॉट से कनेक्ट करें ",
"ACCESS_VIA_BROWSER":",ब्राउज़र के माध्यम से पहुंचें ",
"WIFI_CONFIG_MODE":"नेटवर्क कॉन्फ़िगरेशन मोड",
"ENTERING_WIFI_CONFIG_MODE":"नेटवर्क कॉन्फ़िगरेशन मोड में प्रवेश...",
"SCANNING_WIFI":"Wi-Fi स्कैन कर रहे हैं...",
"LOADING_PROTOCOL": "सर्वर से कनेक्ट हो रहे हैं...",
"INITIALIZING": "आरंभीकरण...",
"PIN_ERROR": "कृपया सिम कार्ड डालें",
"REG_ERROR": "नेटवर्क तक पहुंच नहीं हो सकती, कृपया डेटा कार्ड स्थिति जांचें",
"DETECTING_MODULE": "मॉड्यूल का पता लगाया जा रहा है...",
"REGISTERING_NETWORK": "नेटवर्क की प्रतीक्षा...",
"CHECKING_NEW_VERSION": "नया संस्करण जाँच रहे हैं...",
"CHECK_NEW_VERSION_FAILED": "नया संस्करण जाँचना असफल, %d सेकंड में पुनः प्रयास: %s",
"SWITCH_TO_WIFI_NETWORK": "Wi-Fi पर स्विच कर रहे हैं...",
"SWITCH_TO_4G_NETWORK": "4G पर स्विच कर रहे हैं...",
"STANDBY": "स्टैंडबाय",
"CONNECT_TO": "कनेक्ट करें ",
"CONNECTING": "कनेक्ट हो रहे हैं...",
"CONNECTED_TO": "कनेक्ट हो गए ",
"LISTENING": "सुन रहे हैं...",
"SPEAKING": "बोल रहे हैं...",
"SERVER_NOT_FOUND": "उपलब्ध सेवा खोज रहे हैं",
"SERVER_NOT_CONNECTED": "सेवा से कनेक्ट नहीं हो सकते, कृपया बाद में कोशिश करें",
"SERVER_TIMEOUT": "प्रतिक्रिया का समय समाप्त",
"SERVER_ERROR": "भेजना असफल, कृपया नेटवर्क जांचें",
"CONNECT_TO_HOTSPOT": "फोन को हॉटस्पॉट से कनेक्ट करें ",
"ACCESS_VIA_BROWSER": ",ब्राउज़र के माध्यम से पहुंचें ",
"WIFI_CONFIG_MODE": "नेटवर्क कॉन्फ़िगरेशन मोड",
"ENTERING_WIFI_CONFIG_MODE": "नेटवर्क कॉन्फ़िगरेशन मोड में प्रवेश...",
"SCANNING_WIFI": "Wi-Fi स्कैन कर रहे हैं...",
"NEW_VERSION": "नया संस्करण ",
"OTA_UPGRADE":"OTA अपग्रेड",
"UPGRADING":"सिस्टम अपग्रेड हो रहा है...",
"UPGRADE_FAILED":"अपग्रेड असफल",
"ACTIVATION":"डिवाइस सक्रियण",
"BATTERY_LOW":"बैटरी कम",
"BATTERY_CHARGING":"चार्ज हो रही है",
"BATTERY_FULL":"बैटरी फुल",
"BATTERY_NEED_CHARGE":"बैटरी कम है, कृपया चार्ज करें",
"VOLUME":"आवाज़ ",
"MUTED":"म्यूट",
"MAX_VOLUME":"अधिकतम आवाज़",
"RTC_MODE_OFF":"AEC बंद",
"RTC_MODE_ON":"AEC चालू"
"OTA_UPGRADE": "OTA अपग्रेड",
"UPGRADING": "सिस्टम अपग्रेड हो रहा है...",
"UPGRADE_FAILED": "अपग्रेड असफल",
"ACTIVATION": "डिवाइस सक्रियण",
"BATTERY_LOW": "बैटरी कम",
"BATTERY_CHARGING": "चार्ज हो रही है",
"BATTERY_FULL": "बैटरी फुल",
"BATTERY_NEED_CHARGE": "बैटरी कम है, कृपया चार्ज करें",
"VOLUME": "आवाज़ ",
"MUTED": "म्यूट",
"MAX_VOLUME": "अधिकतम आवाज़",
"RTC_MODE_OFF": "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": {
"type" :"id-ID"
"type": "id-ID"
},
"strings": {
"WARNING":"Peringatan",
"INFO":"Informasi",
"ERROR":"Kesalahan",
"WARNING": "Peringatan",
"INFO": "Informasi",
"ERROR": "Kesalahan",
"VERSION": "Versi ",
"LOADING_PROTOCOL":"Menghubungkan ke server...",
"INITIALIZING":"Menginisialisasi...",
"PIN_ERROR":"Silakan masukkan kartu SIM",
"REG_ERROR":"Tidak dapat mengakses jaringan, periksa status kartu data",
"DETECTING_MODULE":"Mendeteksi modul...",
"REGISTERING_NETWORK":"Menunggu jaringan...",
"CHECKING_NEW_VERSION":"Memeriksa versi baru...",
"CHECK_NEW_VERSION_FAILED":"Pemeriksaan versi baru gagal, mencoba lagi dalam %d detik: %s",
"SWITCH_TO_WIFI_NETWORK":"Beralih ke Wi-Fi...",
"SWITCH_TO_4G_NETWORK":"Beralih ke 4G...",
"STANDBY":"Siaga",
"CONNECT_TO":"Hubungkan ke ",
"CONNECTING":"Menghubungkan...",
"CONNECTED_TO":"Terhubung ke ",
"LISTENING":"Mendengarkan...",
"SPEAKING":"Berbicara...",
"SERVER_NOT_FOUND":"Mencari layanan yang tersedia",
"SERVER_NOT_CONNECTED":"Tidak dapat terhubung ke layanan, coba lagi nanti",
"SERVER_TIMEOUT":"Waktu respons habis",
"SERVER_ERROR":"Pengiriman gagal, periksa jaringan",
"CONNECT_TO_HOTSPOT":"Hubungkan ponsel ke hotspot ",
"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...",
"LOADING_PROTOCOL": "Menghubungkan ke server...",
"INITIALIZING": "Menginisialisasi...",
"PIN_ERROR": "Silakan masukkan kartu SIM",
"REG_ERROR": "Tidak dapat mengakses jaringan, periksa status kartu data",
"DETECTING_MODULE": "Mendeteksi modul...",
"REGISTERING_NETWORK": "Menunggu jaringan...",
"CHECKING_NEW_VERSION": "Memeriksa versi baru...",
"CHECK_NEW_VERSION_FAILED": "Pemeriksaan versi baru gagal, mencoba lagi dalam %d detik: %s",
"SWITCH_TO_WIFI_NETWORK": "Beralih ke Wi-Fi...",
"SWITCH_TO_4G_NETWORK": "Beralih ke 4G...",
"STANDBY": "Siaga",
"CONNECT_TO": "Hubungkan ke ",
"CONNECTING": "Menghubungkan...",
"CONNECTED_TO": "Terhubung ke ",
"LISTENING": "Mendengarkan...",
"SPEAKING": "Berbicara...",
"SERVER_NOT_FOUND": "Mencari layanan yang tersedia",
"SERVER_NOT_CONNECTED": "Tidak dapat terhubung ke layanan, coba lagi nanti",
"SERVER_TIMEOUT": "Waktu respons habis",
"SERVER_ERROR": "Pengiriman gagal, periksa jaringan",
"CONNECT_TO_HOTSPOT": "Hubungkan ponsel ke hotspot ",
"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 ",
"OTA_UPGRADE":"Pembaruan OTA",
"UPGRADING":"Memperbarui sistem...",
"UPGRADE_FAILED":"Pembaruan gagal",
"ACTIVATION":"Aktivasi perangkat",
"BATTERY_LOW":"Baterai lemah",
"BATTERY_CHARGING":"Mengisi",
"BATTERY_FULL":"Baterai penuh",
"BATTERY_NEED_CHARGE":"Baterai lemah, silakan isi",
"VOLUME":"Volume ",
"MUTED":"Bisu",
"MAX_VOLUME":"Volume maksimum",
"RTC_MODE_OFF":"AEC mati",
"RTC_MODE_ON":"AEC nyala"
"OTA_UPGRADE": "Pembaruan OTA",
"UPGRADING": "Memperbarui sistem...",
"UPGRADE_FAILED": "Pembaruan gagal",
"ACTIVATION": "Aktivasi perangkat",
"BATTERY_LOW": "Baterai lemah",
"BATTERY_CHARGING": "Mengisi",
"BATTERY_FULL": "Baterai penuh",
"BATTERY_NEED_CHARGE": "Baterai lemah, silakan isi",
"VOLUME": "Volume ",
"MUTED": "Bisu",
"MAX_VOLUME": "Volume maksimum",
"RTC_MODE_OFF": "AEC mati",
"RTC_MODE_ON": "AEC nyala",
"DOWNLOAD_ASSETS_FAILED": "Gagal mengunduh aset",
"LOADING_ASSETS": "Memuat aset...",
"PLEASE_WAIT": "Mohon tunggu...",
"FOUND_NEW_ASSETS": "Ditemukan aset baru: %s",
"HELLO_MY_FRIEND": "Halo, teman saya!"
}
}

View File

@@ -1,58 +1,55 @@
{
"language": {
"type" :"it-IT"
"type": "it-IT"
},
"strings": {
"WARNING":"Avviso",
"INFO":"Informazione",
"ERROR":"Errore",
"WARNING": "Avviso",
"INFO": "Informazione",
"ERROR": "Errore",
"VERSION": "Versione ",
"LOADING_PROTOCOL":"Connessione al server...",
"INITIALIZING":"Inizializzazione...",
"PIN_ERROR":"Inserire la scheda SIM",
"REG_ERROR":"Impossibile accedere alla rete, controllare lo stato della scheda dati",
"DETECTING_MODULE":"Rilevamento modulo...",
"REGISTERING_NETWORK":"In attesa della rete...",
"CHECKING_NEW_VERSION":"Controllo nuova versione...",
"CHECK_NEW_VERSION_FAILED":"Controllo nuova versione fallito, riprovo tra %d secondi: %s",
"SWITCH_TO_WIFI_NETWORK":"Passaggio a Wi-Fi...",
"SWITCH_TO_4G_NETWORK":"Passaggio a 4G...",
"STANDBY":"In attesa",
"CONNECT_TO":"Connetti a ",
"CONNECTING":"Connessione...",
"CONNECTED_TO":"Connesso a ",
"LISTENING":"In ascolto...",
"SPEAKING":"Parlando...",
"SERVER_NOT_FOUND":"Ricerca servizio disponibile",
"SERVER_NOT_CONNECTED":"Impossibile connettersi al servizio, riprovare più tardi",
"SERVER_TIMEOUT":"Timeout risposta",
"SERVER_ERROR":"Invio fallito, controllare la rete",
"CONNECT_TO_HOTSPOT":"Connetti telefono al hotspot ",
"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...",
"LOADING_PROTOCOL": "Connessione al server...",
"INITIALIZING": "Inizializzazione...",
"PIN_ERROR": "Inserire la scheda SIM",
"REG_ERROR": "Impossibile accedere alla rete, controllare lo stato della scheda dati",
"DETECTING_MODULE": "Rilevamento modulo...",
"REGISTERING_NETWORK": "In attesa della rete...",
"CHECKING_NEW_VERSION": "Controllo nuova versione...",
"CHECK_NEW_VERSION_FAILED": "Controllo nuova versione fallito, riprovo tra %d secondi: %s",
"SWITCH_TO_WIFI_NETWORK": "Passaggio a Wi-Fi...",
"SWITCH_TO_4G_NETWORK": "Passaggio a 4G...",
"STANDBY": "In attesa",
"CONNECT_TO": "Connetti a ",
"CONNECTING": "Connessione...",
"CONNECTED_TO": "Connesso a ",
"LISTENING": "In ascolto...",
"SPEAKING": "Parlando...",
"SERVER_NOT_FOUND": "Ricerca servizio disponibile",
"SERVER_NOT_CONNECTED": "Impossibile connettersi al servizio, riprovare più tardi",
"SERVER_TIMEOUT": "Timeout risposta",
"SERVER_ERROR": "Invio fallito, controllare la rete",
"CONNECT_TO_HOTSPOT": "Connetti telefono al hotspot ",
"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 ",
"OTA_UPGRADE":"Aggiornamento OTA",
"UPGRADING":"Aggiornamento sistema...",
"UPGRADE_FAILED":"Aggiornamento fallito",
"ACTIVATION":"Attivazione dispositivo",
"BATTERY_LOW":"Batteria scarica",
"BATTERY_CHARGING":"In carica",
"BATTERY_FULL":"Batteria piena",
"BATTERY_NEED_CHARGE":"Batteria scarica, ricaricare",
"VOLUME":"Volume ",
"MUTED":"Silenziato",
"MAX_VOLUME":"Volume massimo",
"RTC_MODE_OFF":"AEC disattivato",
"RTC_MODE_ON":"AEC attivato"
"OTA_UPGRADE": "Aggiornamento OTA",
"UPGRADING": "Aggiornamento sistema...",
"UPGRADE_FAILED": "Aggiornamento fallito",
"ACTIVATION": "Attivazione dispositivo",
"BATTERY_LOW": "Batteria scarica",
"BATTERY_CHARGING": "In carica",
"BATTERY_FULL": "Batteria piena",
"BATTERY_NEED_CHARGE": "Batteria scarica, ricaricare",
"VOLUME": "Volume ",
"MUTED": "Silenziato",
"MAX_VOLUME": "Volume massimo",
"RTC_MODE_OFF": "AEC disattivato",
"RTC_MODE_ON": "AEC attivato",
"DOWNLOAD_ASSETS_FAILED": "Impossibile scaricare le risorse",
"LOADING_ASSETS": "Caricamento risorse...",
"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",
"SWITCH_TO_WIFI_NETWORK": "Wi-Fiに切り替え中...",
"SWITCH_TO_4G_NETWORK": "4Gに切り替え中...",
"STANDBY": "待機中",
"CONNECT_TO": "接続先 ",
"CONNECTING": "接続中...",
"CONNECTED_TO": "接続完了 ",
"LISTENING": "リスニング中...",
"SPEAKING": "話しています...",
"SERVER_NOT_FOUND": "利用可能なサーバーを探しています",
"SERVER_NOT_CONNECTED": "サーバーに接続できません。後でもう一度お試しください",
"SERVER_TIMEOUT": "応答待機時間が終了しました",
"SERVER_ERROR": "送信に失敗しました。ネットワークを確認してください",
"CONNECT_TO_HOTSPOT": "スマートフォンをWi-Fi ",
"ACCESS_VIA_BROWSER": " に接続し、ブラウザでアクセスしてください ",
"WIFI_CONFIG_MODE": "ネットワーク設定モード",
"ENTERING_WIFI_CONFIG_MODE": "ネットワーク設定中...",
"SCANNING_WIFI": "Wi-Fiをスキャン中...",
"NEW_VERSION": "新しいバージョン ",
"OTA_UPGRADE": "OTAアップグレード",
"UPGRADING": "システムをアップグレード中...",
"UPGRADE_FAILED": "アップグレード失敗",
"ACTIVATION": "デバイスをアクティベート",
"BATTERY_LOW": "バッテリーが少なくなっています",
"BATTERY_CHARGING": "充電中",
"BATTERY_FULL": "バッテリー満タン",
"BATTERY_NEED_CHARGE": "バッテリーが低下しています。充電してください",
"VOLUME": "音量 ",
"MUTED": "ミュートされています",
"MAX_VOLUME": "最大音量",
"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",
"SWITCH_TO_WIFI_NETWORK": "Wi-Fi로 전환 중...",
"SWITCH_TO_4G_NETWORK": "4G로 전환 중...",
"STANDBY": "대기",
"CONNECT_TO": "연결 대상: ",
"CONNECTING": "연결 중...",
"CONNECTION_SUCCESSFUL": "연결 성공",
"CONNECTED_TO": "연결됨: ",
"LISTENING": "듣는 중...",
"SPEAKING": "말하는 중...",
"SERVER_NOT_FOUND": "사용 가능한 서비스를 찾는 중",
"SERVER_NOT_CONNECTED": "서비스에 연결할 수 없습니다. 나중에 다시 시도하세요",
"SERVER_TIMEOUT": "응답 대기 시간 초과",
"SERVER_ERROR": "전송 실패, 네트워크를 확인하세요",
"CONNECT_TO_HOTSPOT": "핫스팟: ",
"ACCESS_VIA_BROWSER": " 설정 URL: ",
"WIFI_CONFIG_MODE": "Wi-Fi 설정 모드",
"ENTERING_WIFI_CONFIG_MODE": "Wi-Fi 설정 모드 진입 중...",
"SCANNING_WIFI": "Wi-Fi 스캔 중...",
"NEW_VERSION": "새 버전 ",
"OTA_UPGRADE": "OTA 업그레이드",
"UPGRADING": "시스템 업그레이드 중...",
"UPGRADE_FAILED": "업그레이드 실패",
"ACTIVATION": "활성화",
"BATTERY_LOW": "배터리 부족",
"BATTERY_CHARGING": "충전 중",
"BATTERY_FULL": "배터리 완충",
"BATTERY_NEED_CHARGE": "배터리 부족, 충전하세요",
"VOLUME": "볼륨 ",
"MUTED": "음소거",
"MAX_VOLUME": "최대 볼륨",
"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": {
"type" :"pl-PL"
"type": "pl-PL"
},
"strings": {
"WARNING":"Ostrzeżenie",
"INFO":"Informacja",
"ERROR":"Błąd",
"WARNING": "Ostrzeżenie",
"INFO": "Informacja",
"ERROR": "Błąd",
"VERSION": "Wersja ",
"LOADING_PROTOCOL":"Łączenie z serwerem...",
"INITIALIZING":"Inicjalizacja...",
"PIN_ERROR":"Proszę włożyć kartę SIM",
"REG_ERROR":"Nie można uzyskać dostępu do sieci, sprawdź stan karty danych",
"DETECTING_MODULE":"Wykrywanie modułu...",
"REGISTERING_NETWORK":"Oczekiwanie na sieć...",
"CHECKING_NEW_VERSION":"Sprawdzanie nowej wersji...",
"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_4G_NETWORK":"Przełączanie na 4G...",
"STANDBY":"Gotowość",
"CONNECT_TO":"Połącz z ",
"CONNECTING":"Łączenie...",
"CONNECTED_TO":"Połączono z ",
"LISTENING":"Słuchanie...",
"SPEAKING":"Mówienie...",
"SERVER_NOT_FOUND":"Szukanie dostępnej usługi",
"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_ERROR":"Wysyłanie nie powiodło się, sprawdź sieć",
"CONNECT_TO_HOTSPOT":"Podłącz telefon do hotspotu ",
"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...",
"LOADING_PROTOCOL": "Łączenie z serwerem...",
"INITIALIZING": "Inicjalizacja...",
"PIN_ERROR": "Proszę włożyć kartę SIM",
"REG_ERROR": "Nie można uzyskać dostępu do sieci, sprawdź stan karty danych",
"DETECTING_MODULE": "Wykrywanie modułu...",
"REGISTERING_NETWORK": "Oczekiwanie na sieć...",
"CHECKING_NEW_VERSION": "Sprawdzanie nowej wersji...",
"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_4G_NETWORK": "Przełączanie na 4G...",
"STANDBY": "Gotowość",
"CONNECT_TO": "Połącz z ",
"CONNECTING": "Łączenie...",
"CONNECTED_TO": "Połączono z ",
"LISTENING": "Słuchanie...",
"SPEAKING": "Mówienie...",
"SERVER_NOT_FOUND": "Szukanie dostępnej usługi",
"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_ERROR": "Wysyłanie nie powiodło się, sprawdź sieć",
"CONNECT_TO_HOTSPOT": "Podłącz telefon do hotspotu ",
"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 ",
"OTA_UPGRADE":"Aktualizacja OTA",
"UPGRADING":"Aktualizacja systemu...",
"UPGRADE_FAILED":"Aktualizacja nie powiodła się",
"ACTIVATION":"Aktywacja urządzenia",
"BATTERY_LOW":"Niski poziom baterii",
"BATTERY_CHARGING":"Ładowanie",
"BATTERY_FULL":"Bateria pełna",
"BATTERY_NEED_CHARGE":"Niski poziom baterii, proszę naładować",
"VOLUME":"Głośność ",
"MUTED":"Wyciszony",
"MAX_VOLUME":"Maksymalna głośność",
"RTC_MODE_OFF":"AEC wyłączony",
"RTC_MODE_ON":"AEC włączony"
"OTA_UPGRADE": "Aktualizacja OTA",
"UPGRADING": "Aktualizacja systemu...",
"UPGRADE_FAILED": "Aktualizacja nie powiodła się",
"ACTIVATION": "Aktywacja urządzenia",
"BATTERY_LOW": "Niski poziom baterii",
"BATTERY_CHARGING": "Ładowanie",
"BATTERY_FULL": "Bateria pełna",
"BATTERY_NEED_CHARGE": "Niski poziom baterii, proszę naładować",
"VOLUME": "Głośność ",
"MUTED": "Wyciszony",
"MAX_VOLUME": "Maksymalna głośność",
"RTC_MODE_OFF": "AEC wyłączony",
"RTC_MODE_ON": "AEC włączony",
"DOWNLOAD_ASSETS_FAILED": "Nie udało się pobrać zasobów",
"LOADING_ASSETS": "Ładowanie zasobów...",
"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": {
"type" :"pt-PT"
"type": "pt-PT"
},
"strings": {
"WARNING":"Aviso",
"INFO":"Informação",
"ERROR":"Erro",
"WARNING": "Aviso",
"INFO": "Informação",
"ERROR": "Erro",
"VERSION": "Versão ",
"LOADING_PROTOCOL":"Ligando ao servidor...",
"INITIALIZING":"A inicializar...",
"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",
"DETECTING_MODULE":"A detectar módulo...",
"REGISTERING_NETWORK":"À espera da rede...",
"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",
"SWITCH_TO_WIFI_NETWORK":"A mudar para Wi-Fi...",
"SWITCH_TO_4G_NETWORK":"A mudar para 4G...",
"STANDBY":"Em espera",
"CONNECT_TO":"Ligar a ",
"CONNECTING":"A ligar...",
"CONNECTED_TO":"Ligado a ",
"LISTENING":"A escutar...",
"SPEAKING":"A falar...",
"SERVER_NOT_FOUND":"A procurar serviço disponível",
"SERVER_NOT_CONNECTED":"Não é possível ligar ao serviço, tente mais tarde",
"SERVER_TIMEOUT":"Tempo limite de resposta",
"SERVER_ERROR":"Falha no envio, verifique a rede",
"CONNECT_TO_HOTSPOT":"Ligue o telefone ao hotspot ",
"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...",
"LOADING_PROTOCOL": "Ligando ao servidor...",
"INITIALIZING": "A inicializar...",
"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",
"DETECTING_MODULE": "A detectar módulo...",
"REGISTERING_NETWORK": "À espera da rede...",
"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",
"SWITCH_TO_WIFI_NETWORK": "A mudar para Wi-Fi...",
"SWITCH_TO_4G_NETWORK": "A mudar para 4G...",
"STANDBY": "Em espera",
"CONNECT_TO": "Ligar a ",
"CONNECTING": "A ligar...",
"CONNECTED_TO": "Ligado a ",
"LISTENING": "A escutar...",
"SPEAKING": "A falar...",
"SERVER_NOT_FOUND": "A procurar serviço disponível",
"SERVER_NOT_CONNECTED": "Não é possível ligar ao serviço, tente mais tarde",
"SERVER_TIMEOUT": "Tempo limite de resposta",
"SERVER_ERROR": "Falha no envio, verifique a rede",
"CONNECT_TO_HOTSPOT": "Ligue o telefone ao hotspot ",
"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 ",
"OTA_UPGRADE":"Atualização OTA",
"UPGRADING":"A atualizar sistema...",
"UPGRADE_FAILED":"Atualização falhada",
"ACTIVATION":"Ativação do dispositivo",
"BATTERY_LOW":"Bateria fraca",
"BATTERY_CHARGING":"A carregar",
"BATTERY_FULL":"Bateria cheia",
"BATTERY_NEED_CHARGE":"Bateria fraca, por favor carregue",
"VOLUME":"Volume ",
"MUTED":"Silenciado",
"MAX_VOLUME":"Volume máximo",
"RTC_MODE_OFF":"AEC desligado",
"RTC_MODE_ON":"AEC ligado"
"OTA_UPGRADE": "Atualização OTA",
"UPGRADING": "A atualizar sistema...",
"UPGRADE_FAILED": "Atualização falhada",
"ACTIVATION": "Ativação do dispositivo",
"BATTERY_LOW": "Bateria fraca",
"BATTERY_CHARGING": "A carregar",
"BATTERY_FULL": "Bateria cheia",
"BATTERY_NEED_CHARGE": "Bateria fraca, por favor carregue",
"VOLUME": "Volume ",
"MUTED": "Silenciado",
"MAX_VOLUME": "Volume máximo",
"RTC_MODE_OFF": "AEC desligado",
"RTC_MODE_ON": "AEC ligado",
"DOWNLOAD_ASSETS_FAILED": "Falha ao descarregar recursos",
"LOADING_ASSETS": "A carregar recursos...",
"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": {
"type" :"ro-RO"
"type": "ro-RO"
},
"strings": {
"WARNING":"Avertisment",
"INFO":"Informație",
"ERROR":"Eroare",
"WARNING": "Avertisment",
"INFO": "Informație",
"ERROR": "Eroare",
"VERSION": "Versiune ",
"LOADING_PROTOCOL":"Se conectează la server...",
"INITIALIZING":"Se inițializează...",
"PIN_ERROR":"Vă rugăm să introduceți cardul SIM",
"REG_ERROR":"Nu se poate accesa rețeaua, verificați starea cardului de date",
"DETECTING_MODULE":"Se detectează modulul...",
"REGISTERING_NETWORK":"Se așteaptă rețeaua...",
"CHECKING_NEW_VERSION":"Se verifică versiunea nouă...",
"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_4G_NETWORK":"Se comută la 4G...",
"STANDBY":"În așteptare",
"CONNECT_TO":"Conectare la ",
"CONNECTING":"Se conectează...",
"CONNECTED_TO":"Conectat la ",
"LISTENING":"Se ascultă...",
"SPEAKING":"Se vorbește...",
"SERVER_NOT_FOUND":"Se caută serviciul disponibil",
"SERVER_NOT_CONNECTED":"Nu se poate conecta la serviciu, încercați mai târziu",
"SERVER_TIMEOUT":"Timpul de răspuns a expirat",
"SERVER_ERROR":"Trimiterea a eșuat, verificați rețeaua",
"CONNECT_TO_HOTSPOT":"Conectați telefonul la hotspot ",
"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...",
"LOADING_PROTOCOL": "Se conectează la server...",
"INITIALIZING": "Se inițializează...",
"PIN_ERROR": "Vă rugăm să introduceți cardul SIM",
"REG_ERROR": "Nu se poate accesa rețeaua, verificați starea cardului de date",
"DETECTING_MODULE": "Se detectează modulul...",
"REGISTERING_NETWORK": "Se așteaptă rețeaua...",
"CHECKING_NEW_VERSION": "Se verifică versiunea nouă...",
"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_4G_NETWORK": "Se comută la 4G...",
"STANDBY": "În așteptare",
"CONNECT_TO": "Conectare la ",
"CONNECTING": "Se conectează...",
"CONNECTED_TO": "Conectat la ",
"LISTENING": "Se ascultă...",
"SPEAKING": "Se vorbește...",
"SERVER_NOT_FOUND": "Se caută serviciul disponibil",
"SERVER_NOT_CONNECTED": "Nu se poate conecta la serviciu, încercați mai târziu",
"SERVER_TIMEOUT": "Timpul de răspuns a expirat",
"SERVER_ERROR": "Trimiterea a eșuat, verificați rețeaua",
"CONNECT_TO_HOTSPOT": "Conectați telefonul la hotspot ",
"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ă ",
"OTA_UPGRADE":"Actualizare OTA",
"UPGRADING":"Se actualizează sistemul...",
"UPGRADE_FAILED":"Actualizarea a eșuat",
"ACTIVATION":"Activarea dispozitivului",
"BATTERY_LOW":"Baterie scăzută",
"BATTERY_CHARGING":"Se încarcă",
"BATTERY_FULL":"Baterie plină",
"BATTERY_NEED_CHARGE":"Baterie scăzută, vă rugăm să încărcați",
"VOLUME":"Volum ",
"MUTED":"Silențios",
"MAX_VOLUME":"Volum maxim",
"RTC_MODE_OFF":"AEC oprit",
"RTC_MODE_ON":"AEC pornit"
"OTA_UPGRADE": "Actualizare OTA",
"UPGRADING": "Se actualizează sistemul...",
"UPGRADE_FAILED": "Actualizarea a eșuat",
"ACTIVATION": "Activarea dispozitivului",
"BATTERY_LOW": "Baterie scăzută",
"BATTERY_CHARGING": "Se încarcă",
"BATTERY_FULL": "Baterie plină",
"BATTERY_NEED_CHARGE": "Baterie scăzută, vă rugăm să încărcați",
"VOLUME": "Volum ",
"MUTED": "Silențios",
"MAX_VOLUME": "Volum maxim",
"RTC_MODE_OFF": "AEC oprit",
"RTC_MODE_ON": "AEC pornit",
"DOWNLOAD_ASSETS_FAILED": "Eșec la descărcarea resurselor",
"LOADING_ASSETS": "Se încarcă resursele...",
"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": {
"type" :"ru-RU"
"type": "ru-RU"
},
"strings": {
"WARNING":"Предупреждение",
"INFO":"Информация",
"ERROR":"Ошибка",
"WARNING": "Предупреждение",
"INFO": "Информация",
"ERROR": "Ошибка",
"VERSION": "Версия ",
"LOADING_PROTOCOL":"Подключение к серверу...",
"INITIALIZING":"Инициализация...",
"PIN_ERROR":"Пожалуйста, вставьте SIM-карту",
"REG_ERROR":"Невозможно подключиться к сети, проверьте состояние карты данных",
"DETECTING_MODULE":"Обнаружение модуля...",
"REGISTERING_NETWORK":"Ожидание сети...",
"CHECKING_NEW_VERSION":"Проверка новой версии...",
"CHECK_NEW_VERSION_FAILED":"Ошибка проверки новой версии, повтор через %d секунд: %s",
"SWITCH_TO_WIFI_NETWORK":"Переключение на Wi-Fi...",
"SWITCH_TO_4G_NETWORK":"Переключение на 4G...",
"STANDBY":"Ожидание",
"CONNECT_TO":"Подключение к ",
"CONNECTING":"Подключение...",
"CONNECTED_TO":одключено к ",
"LISTENING":рослушивание...",
"SPEAKING":"Говорение...",
"SERVER_NOT_FOUND":"Поиск доступного сервиса",
"SERVER_NOT_CONNECTED":"Невозможно подключиться к сервису, попробуйте позже",
"SERVER_TIMEOUT":"Тайм-аут ответа",
"SERVER_ERROR":"Ошибка отправки, проверьте сеть",
"CONNECT_TO_HOTSPOT":"Подключите телефон к точке доступа ",
"ACCESS_VIA_BROWSER":",доступ через браузер ",
"WIFI_CONFIG_MODE":"Режим настройки сети",
"ENTERING_WIFI_CONFIG_MODE":"Вход в режим настройки сети...",
"SCANNING_WIFI":"Сканирование Wi-Fi...",
"LOADING_PROTOCOL": "Подключение к серверу...",
"INITIALIZING": "Инициализация...",
"PIN_ERROR": "Пожалуйста, вставьте SIM-карту",
"REG_ERROR": "Невозможно подключиться к сети, проверьте состояние карты данных",
"DETECTING_MODULE": "Обнаружение модуля...",
"REGISTERING_NETWORK": "Ожидание сети...",
"CHECKING_NEW_VERSION": "Проверка новой версии...",
"CHECK_NEW_VERSION_FAILED": "Ошибка проверки новой версии, повтор через %d секунд: %s",
"SWITCH_TO_WIFI_NETWORK": "Переключение на Wi-Fi...",
"SWITCH_TO_4G_NETWORK": "Переключение на 4G...",
"STANDBY": "Ожидание",
"CONNECT_TO": "Подключение к ",
"CONNECTING": "Подключение...",
"CONNECTED_TO": "Подключено к ",
"LISTENING": рослушивание...",
"SPEAKING": "Говорение...",
"SERVER_NOT_FOUND": оиск доступного сервиса",
"SERVER_NOT_CONNECTED": "Невозможно подключиться к сервису, попробуйте позже",
"SERVER_TIMEOUT": "Тайм-аут ответа",
"SERVER_ERROR": "Ошибка отправки, проверьте сеть",
"CONNECT_TO_HOTSPOT": "Подключите телефон к точке доступа ",
"ACCESS_VIA_BROWSER": ",доступ через браузер ",
"WIFI_CONFIG_MODE": "Режим настройки сети",
"ENTERING_WIFI_CONFIG_MODE": "Вход в режим настройки сети...",
"SCANNING_WIFI": "Сканирование Wi-Fi...",
"NEW_VERSION": "Новая версия ",
"OTA_UPGRADE":"Обновление OTA",
"UPGRADING":"Обновление системы...",
"UPGRADE_FAILED":"Обновление не удалось",
"ACTIVATION":"Активация устройства",
"BATTERY_LOW":"Низкий заряд батареи",
"BATTERY_CHARGING":"Зарядка",
"BATTERY_FULL":"Батарея полная",
"BATTERY_NEED_CHARGE":"Низкий заряд, пожалуйста, зарядите",
"VOLUME":"Громкость ",
"MUTED":"Звук отключен",
"MAX_VOLUME":"Максимальная громкость",
"RTC_MODE_OFF":"AEC выключен",
"RTC_MODE_ON":"AEC включен"
"OTA_UPGRADE": "Обновление OTA",
"UPGRADING": "Обновление системы...",
"UPGRADE_FAILED": "Обновление не удалось",
"ACTIVATION": "Активация устройства",
"BATTERY_LOW": "Низкий заряд батареи",
"BATTERY_CHARGING": "Зарядка",
"BATTERY_FULL": "Батарея полная",
"BATTERY_NEED_CHARGE": "Низкий заряд, пожалуйста, зарядите",
"VOLUME": "Громкость ",
"MUTED": "Звук отключен",
"MAX_VOLUME": "Максимальная громкость",
"RTC_MODE_OFF": "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",
"SWITCH_TO_WIFI_NETWORK": "กำลังเปลี่ยนเป็น Wi-Fi...",
"SWITCH_TO_4G_NETWORK": "กำลังเปลี่ยนเป็น 4G...",
"STANDBY": "พร้อม",
"CONNECT_TO": "เชื่อมต่อกับ ",
"CONNECTING": "กำลังเชื่อมต่อ...",
"CONNECTION_SUCCESSFUL": "เชื่อมต่อสำเร็จ",
"CONNECTED_TO": "เชื่อมต่อกับ ",
"LISTENING": "กำลังฟัง...",
"SPEAKING": "กำลังพูด...",
"SERVER_NOT_FOUND": "กำลังค้นหาบริการที่ใช้งานได้",
"SERVER_NOT_CONNECTED": "ไม่สามารถเชื่อมต่อกับบริการได้ กรุณาลองใหม่ในภายหลัง",
"SERVER_TIMEOUT": "หมดเวลารอการตอบกลับ",
"SERVER_ERROR": "การส่งข้อมูลล้มเหลว กรุณาตรวจสอบเครือข่าย",
"CONNECT_TO_HOTSPOT": "ฮอตสปอต: ",
"ACCESS_VIA_BROWSER": " URL การตั้งค่า: ",
"WIFI_CONFIG_MODE": "โหมดการตั้งค่า Wi-Fi",
"ENTERING_WIFI_CONFIG_MODE": "กำลังเข้าสู่โหมดการตั้งค่า Wi-Fi...",
"SCANNING_WIFI": "กำลังสแกน Wi-Fi...",
"NEW_VERSION": "เวอร์ชันใหม่ ",
"OTA_UPGRADE": "การอัปเกรด OTA",
"UPGRADING": "ระบบกำลังอัปเกรด...",
"UPGRADE_FAILED": "การอัปเกรดล้มเหลว",
"ACTIVATION": "การเปิดใช้งาน",
"BATTERY_LOW": "แบตเตอรี่ต่ำ",
"BATTERY_CHARGING": "กำลังชาร์จ",
"BATTERY_FULL": "แบตเตอรี่เต็ม",
"BATTERY_NEED_CHARGE": "แบตเตอรี่ต่ำ กรุณาชาร์จ",
"VOLUME": "เสียง ",
"MUTED": "ปิดเสียง",
"MAX_VOLUME": "เสียงสูงสุด",
"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": {
"type" :"tr-TR"
"type": "tr-TR"
},
"strings": {
"WARNING":"Uyarı",
"INFO":"Bilgi",
"ERROR":"Hata",
"WARNING": "Uyarı",
"INFO": "Bilgi",
"ERROR": "Hata",
"VERSION": "Sürüm ",
"LOADING_PROTOCOL":"Sunucuya bağlanıyor...",
"INITIALIZING":"Başlatılıyor...",
"PIN_ERROR":"Lütfen SIM kartı takın",
"REG_ERROR":"Ağa erişilemiyor, veri kartı durumunu kontrol edin",
"DETECTING_MODULE":"Modül algılanıyor...",
"REGISTERING_NETWORK":"Ağ bekleniyor...",
"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",
"SWITCH_TO_WIFI_NETWORK":"Wi-Fi'ye geçiliyor...",
"SWITCH_TO_4G_NETWORK":"4G'ye geçiliyor...",
"STANDBY":"Bekleme",
"CONNECT_TO":"Bağlan ",
"CONNECTING":"Bağlanıyor...",
"CONNECTED_TO":"Bağlandı ",
"LISTENING":"Dinleniyor...",
"SPEAKING":"Konuşuluyor...",
"SERVER_NOT_FOUND":"Mevcut hizmet aranıyor",
"SERVER_NOT_CONNECTED":"Hizmete bağlanılamıyor, lütfen daha sonra deneyin",
"SERVER_TIMEOUT":"Yanıt zaman aşımı",
"SERVER_ERROR":"nderme başarısız, ağı kontrol edin",
"CONNECT_TO_HOTSPOT":"Telefonu hotspot'a bağlayın ",
"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...",
"LOADING_PROTOCOL": "Sunucuya bağlanıyor...",
"INITIALIZING": "Başlatılıyor...",
"PIN_ERROR": "Lütfen SIM kartı takın",
"REG_ERROR": "Ağa erişilemiyor, veri kartı durumunu kontrol edin",
"DETECTING_MODULE": "Modül algılanıyor...",
"REGISTERING_NETWORK": "Ağ bekleniyor...",
"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",
"SWITCH_TO_WIFI_NETWORK": "Wi-Fi'ye geçiliyor...",
"SWITCH_TO_4G_NETWORK": "4G'ye geçiliyor...",
"STANDBY": "Bekleme",
"CONNECT_TO": "Bağlan ",
"CONNECTING": "Bağlanıyor...",
"CONNECTED_TO": "Bağlandı ",
"LISTENING": "Dinleniyor...",
"SPEAKING": "Konuşuluyor...",
"SERVER_NOT_FOUND": "Mevcut hizmet aranıyor",
"SERVER_NOT_CONNECTED": "Hizmete bağlanılamıyor, lütfen daha sonra deneyin",
"SERVER_TIMEOUT": "Yanıt zaman aşımı",
"SERVER_ERROR": "Gönderme başarısız, ağı kontrol edin",
"CONNECT_TO_HOTSPOT": "Telefonu hotspot'a bağlayın ",
"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 ",
"OTA_UPGRADE":"OTA güncelleme",
"UPGRADING":"Sistem güncelleniyor...",
"UPGRADE_FAILED":"Güncelleme başarısız",
"ACTIVATION":"Cihaz aktivasyonu",
"BATTERY_LOW":"Pil düşük",
"BATTERY_CHARGING":"Şarj oluyor",
"BATTERY_FULL":"Pil dolu",
"BATTERY_NEED_CHARGE":"Pil düşük, lütfen şarj edin",
"VOLUME":"Ses ",
"MUTED":"Sessiz",
"MAX_VOLUME":"Maksimum ses",
"RTC_MODE_OFF":"AEC kapalı",
"RTC_MODE_ON":"AEC açık"
"OTA_UPGRADE": "OTA güncelleme",
"UPGRADING": "Sistem güncelleniyor...",
"UPGRADE_FAILED": "Güncelleme başarısız",
"ACTIVATION": "Cihaz aktivasyonu",
"BATTERY_LOW": "Pil düşük",
"BATTERY_CHARGING": "Şarj oluyor",
"BATTERY_FULL": "Pil dolu",
"BATTERY_NEED_CHARGE": "Pil düşük, lütfen şarj edin",
"VOLUME": "Ses ",
"MUTED": "Sessiz",
"MAX_VOLUME": "Maksimum ses",
"RTC_MODE_OFF": "AEC kapalı",
"RTC_MODE_ON": "AEC açık",
"DOWNLOAD_ASSETS_FAILED": "Varlıklar indirilemedi",
"LOADING_ASSETS": "Varlıklar yükleniyor...",
"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": {
"type" :"uk-UA"
"type": "uk-UA"
},
"strings": {
"WARNING":"Попередження",
"INFO":"Інформація",
"ERROR":"Помилка",
"WARNING": "Попередження",
"INFO": "Інформація",
"ERROR": "Помилка",
"VERSION": "Версія ",
"LOADING_PROTOCOL":"Підключення до сервера...",
"INITIALIZING":"Ініціалізація...",
"PIN_ERROR":"Будь ласка, вставте SIM-карту",
"REG_ERROR":"Неможливо отримати доступ до мережі, перевірте стан карти даних",
"DETECTING_MODULE":"Виявлення модуля...",
"REGISTERING_NETWORK":"Очікування мережі...",
"CHECKING_NEW_VERSION":"Перевірка нової версії...",
"CHECK_NEW_VERSION_FAILED":"Перевірка нової версії не вдалася, повтор через %d секунд: %s",
"SWITCH_TO_WIFI_NETWORK":"Перемикання на Wi-Fi...",
"SWITCH_TO_4G_NETWORK":"Перемикання на 4G...",
"STANDBY":"Очікування",
"CONNECT_TO":"Підключитися до ",
"CONNECTING":"Підключення...",
"CONNECTED_TO":ідключено до ",
"LISTENING":рослуховування...",
"SPEAKING":"Говоріння...",
"SERVER_NOT_FOUND":"Пошук доступного сервісу",
"SERVER_NOT_CONNECTED":"Неможливо підключитися до сервісу, спробуйте пізніше",
"SERVER_TIMEOUT":"Час очікування відповіді",
"SERVER_ERROR":"Помилка відправки, перевірте мережу",
"CONNECT_TO_HOTSPOT":"Підключіть телефон до точки доступу ",
"ACCESS_VIA_BROWSER":",доступ через браузер ",
"WIFI_CONFIG_MODE":"Режим налаштування мережі",
"ENTERING_WIFI_CONFIG_MODE":"Вхід у режим налаштування мережі...",
"SCANNING_WIFI":"Сканування Wi-Fi...",
"LOADING_PROTOCOL": "Підключення до сервера...",
"INITIALIZING": "Ініціалізація...",
"PIN_ERROR": "Будь ласка, вставте SIM-карту",
"REG_ERROR": "Неможливо отримати доступ до мережі, перевірте стан карти даних",
"DETECTING_MODULE": "Виявлення модуля...",
"REGISTERING_NETWORK": "Очікування мережі...",
"CHECKING_NEW_VERSION": "Перевірка нової версії...",
"CHECK_NEW_VERSION_FAILED": "Перевірка нової версії не вдалася, повтор через %d секунд: %s",
"SWITCH_TO_WIFI_NETWORK": "Перемикання на Wi-Fi...",
"SWITCH_TO_4G_NETWORK": "Перемикання на 4G...",
"STANDBY": "Очікування",
"CONNECT_TO": "Підключитися до ",
"CONNECTING": "Підключення...",
"CONNECTED_TO": "Підключено до ",
"LISTENING": рослуховування...",
"SPEAKING": "Говоріння...",
"SERVER_NOT_FOUND": ошук доступного сервісу",
"SERVER_NOT_CONNECTED": "Неможливо підключитися до сервісу, спробуйте пізніше",
"SERVER_TIMEOUT": "Час очікування відповіді",
"SERVER_ERROR": "Помилка відправки, перевірте мережу",
"CONNECT_TO_HOTSPOT": "Підключіть телефон до точки доступу ",
"ACCESS_VIA_BROWSER": ",доступ через браузер ",
"WIFI_CONFIG_MODE": "Режим налаштування мережі",
"ENTERING_WIFI_CONFIG_MODE": "Вхід у режим налаштування мережі...",
"SCANNING_WIFI": "Сканування Wi-Fi...",
"NEW_VERSION": "Нова версія ",
"OTA_UPGRADE":"Оновлення OTA",
"UPGRADING":"Оновлення системи...",
"UPGRADE_FAILED":"Оновлення не вдалося",
"ACTIVATION":"Активація пристрою",
"BATTERY_LOW":"Низький заряд батареї",
"BATTERY_CHARGING":"Зарядка",
"BATTERY_FULL":"Батарея повна",
"BATTERY_NEED_CHARGE":"Низький заряд, будь ласка, зарядіть",
"VOLUME":"Гучність ",
"MUTED":"Звук вимкнено",
"MAX_VOLUME":"Максимальна гучність",
"RTC_MODE_OFF":"AEC вимкнено",
"RTC_MODE_ON":"AEC увімкнено"
"OTA_UPGRADE": "Оновлення OTA",
"UPGRADING": "Оновлення системи...",
"UPGRADE_FAILED": "Оновлення не вдалося",
"ACTIVATION": "Активація пристрою",
"BATTERY_LOW": "Низький заряд батареї",
"BATTERY_CHARGING": "Зарядка",
"BATTERY_FULL": "Батарея повна",
"BATTERY_NEED_CHARGE": "Низький заряд, будь ласка, зарядіть",
"VOLUME": "Гучність ",
"MUTED": "Звук вимкнено",
"MAX_VOLUME": "Максимальна гучність",
"RTC_MODE_OFF": "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": "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_4G_NETWORK": "Đang chuyển sang 4G...",
"STANDBY": "Chờ",
"CONNECT_TO": "Kết nối đến ",
"CONNECTING": "Đang kết nối...",
"CONNECTION_SUCCESSFUL": "Kết nối thành công",
"CONNECTED_TO": "Đã kết nối đến ",
"LISTENING": "Đang lắng nghe...",
"SPEAKING": "Đang nói...",
"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_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",
"CONNECT_TO_HOTSPOT": "Điểm phát sóng: ",
"ACCESS_VIA_BROWSER": " URL cấu hình: ",
"WIFI_CONFIG_MODE": "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...",
"NEW_VERSION": "Phiên bản mới ",
"OTA_UPGRADE": "Nâng cấp OTA",
"UPGRADING": "Hệ thống đang nâng cấp...",
"UPGRADE_FAILED": "Nâng cấp thất bại",
"ACTIVATION": "Kích hoạt",
"BATTERY_LOW": "Pin yếu",
"BATTERY_CHARGING": "Đang sạc",
"BATTERY_FULL": "Pin đầy",
"BATTERY_NEED_CHARGE": "Pin yếu, vui lòng sạc",
"VOLUME": "Âm lượng ",
"MUTED": "Tắt tiếng",
"MAX_VOLUME": "Âm lượng tối đa",
"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": {
"type" :"zh-CN"
"type": "zh-CN"
},
"strings": {
"WARNING":"警告",
"INFO":"信息",
"ERROR":"错误",
"WARNING": "警告",
"INFO": "信息",
"ERROR": "错误",
"VERSION": "版本 ",
"LOADING_PROTOCOL":"登录服务器...",
"INITIALIZING":"正在初始化...",
"PIN_ERROR":"请插入 SIM 卡",
"REG_ERROR":"无法接入网络,请检查流量卡状态",
"DETECTING_MODULE":"检测模组...",
"REGISTERING_NETWORK":"等待网络...",
"CHECKING_NEW_VERSION":"检查新版本...",
"CHECK_NEW_VERSION_FAILED":"检查新版本失败,将在 %d 秒后重试:%s",
"SWITCH_TO_WIFI_NETWORK":"切换到 Wi-Fi...",
"SWITCH_TO_4G_NETWORK":"切换到 4G...",
"STANDBY":"待命",
"CONNECT_TO":"连接 ",
"CONNECTING":"连接中...",
"CONNECTED_TO":"已连接 ",
"LISTENING":"聆听中...",
"SPEAKING":"说话中...",
"SERVER_NOT_FOUND":"正在寻找可用服务",
"SERVER_NOT_CONNECTED":"无法连接服务,请稍后再试",
"SERVER_TIMEOUT":"等待响应超时",
"SERVER_ERROR":"发送失败,请检查网络",
"CONNECT_TO_HOTSPOT":"手机连接热点 ",
"ACCESS_VIA_BROWSER":",浏览器访问 ",
"WIFI_CONFIG_MODE":"配网模式",
"ENTERING_WIFI_CONFIG_MODE":"进入配网模式...",
"SCANNING_WIFI":"扫描 Wi-Fi...",
"LOADING_PROTOCOL": "登录服务器...",
"INITIALIZING": "正在初始化...",
"PIN_ERROR": "请插入 SIM 卡",
"REG_ERROR": "无法接入网络,请检查流量卡状态",
"DETECTING_MODULE": "检测模组...",
"REGISTERING_NETWORK": "等待网络...",
"CHECKING_NEW_VERSION": "检查新版本...",
"CHECK_NEW_VERSION_FAILED": "检查新版本失败,将在 %d 秒后重试:%s",
"SWITCH_TO_WIFI_NETWORK": "切换到 Wi-Fi...",
"SWITCH_TO_4G_NETWORK": "切换到 4G...",
"STANDBY": "待命",
"CONNECT_TO": "连接 ",
"CONNECTING": "连接中...",
"CONNECTED_TO": "连接 ",
"LISTENING": "聆听中...",
"SPEAKING": "说话中...",
"SERVER_NOT_FOUND": "正在寻找可用服务",
"SERVER_NOT_CONNECTED": "无法连接服务,请稍后再试",
"SERVER_TIMEOUT": "等待响应超时",
"SERVER_ERROR": "发送失败,请检查网络",
"CONNECT_TO_HOTSPOT": "手机连接热点 ",
"ACCESS_VIA_BROWSER": ",浏览器访问 ",
"WIFI_CONFIG_MODE": "配网模式",
"ENTERING_WIFI_CONFIG_MODE": "进入配网模式...",
"SCANNING_WIFI": "扫描 Wi-Fi...",
"NEW_VERSION": "新版本 ",
"OTA_UPGRADE":"OTA 升级",
"UPGRADING":"正在升级系统...",
"UPGRADE_FAILED":"升级失败",
"ACTIVATION":"激活设备",
"BATTERY_LOW":"电量不足",
"BATTERY_CHARGING":"正在充电",
"BATTERY_FULL":"电量已满",
"BATTERY_NEED_CHARGE":"电量低,请充电",
"VOLUME":"音量 ",
"MUTED":"已静音",
"MAX_VOLUME":"最大音量",
"RTC_MODE_OFF":"AEC 关闭",
"RTC_MODE_ON":"AEC 开启"
"OTA_UPGRADE": "OTA 升级",
"UPGRADING": "正在升级系统...",
"UPGRADE_FAILED": "升级失败",
"ACTIVATION": "激活设备",
"BATTERY_LOW": "电量不足",
"BATTERY_CHARGING": "正在充电",
"BATTERY_FULL": "电量已满",
"BATTERY_NEED_CHARGE": "电量低,请充电",
"VOLUME": "音量 ",
"MUTED": "已静音",
"MAX_VOLUME": "最大音量",
"RTC_MODE_OFF": "AEC 关闭",
"RTC_MODE_ON": "AEC 开启",
"DOWNLOAD_ASSETS_FAILED": "下载资源失败",
"LOADING_ASSETS": "加载资源...",
"PLEASE_WAIT": "请稍候...",
"FOUND_NEW_ASSETS": "发现新资源: %s",
"HELLO_MY_FRIEND": "你好,我的朋友!"
}
}

View File

@@ -17,42 +17,39 @@
"CHECK_NEW_VERSION_FAILED": "檢查新版本失敗,將在 %d 秒後重試:%s",
"SWITCH_TO_WIFI_NETWORK": "切換到 Wi-Fi...",
"SWITCH_TO_4G_NETWORK": "切換到 4G...",
"STANDBY": "待命",
"CONNECT_TO": "連接 ",
"CONNECTING": "連接中...",
"CONNECTED_TO": "已連接 ",
"LISTENING": "聆聽中...",
"SPEAKING": "說話中...",
"SERVER_NOT_FOUND": "正在尋找可用服務",
"SERVER_NOT_CONNECTED": "無法連接服務,請稍後再試",
"SERVER_TIMEOUT": "等待響應超時",
"SERVER_ERROR": "發送失敗,請檢查網絡",
"CONNECT_TO_HOTSPOT": "手機連接WiFi ",
"ACCESS_VIA_BROWSER": ",瀏覽器訪問 ",
"WIFI_CONFIG_MODE": "網路設定模式",
"ENTERING_WIFI_CONFIG_MODE": "正在設定網路...",
"SCANNING_WIFI": "掃描 Wi-Fi...",
"NEW_VERSION": "新版本 ",
"OTA_UPGRADE": "OTA 升級",
"UPGRADING": "正在升級系統...",
"UPGRADE_FAILED": "升級失敗",
"ACTIVATION": "啟用設備",
"BATTERY_LOW": "電量不足",
"BATTERY_CHARGING": "正在充電",
"BATTERY_FULL": "電量已滿",
"BATTERY_NEED_CHARGE": "電量低,請充電",
"VOLUME": "音量 ",
"MUTED": "已靜音",
"MAX_VOLUME": "最大音量",
"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"
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());
}
bool AudioCodec::InputData(std::vector<int16_t> &data){
bool AudioCodec::InputData(std::vector<int16_t>& data) {
int samples = Read(data.data(), data.size());
if (samples > 0){
if (samples > 0) {
return true;
}
return false;
}
void AudioCodec::Start(){
void AudioCodec::Start() {
Settings settings("audio", false);
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_);
output_volume_ = 10;
}
@@ -40,11 +40,11 @@ void AudioCodec::Start(){
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_));
}
if (rx_handle_ != nullptr){
if (rx_handle_ != nullptr) {
ESP_ERROR_CHECK(i2s_channel_enable(rx_handle_));
}
@@ -53,7 +53,7 @@ void AudioCodec::Start(){
ESP_LOGI(TAG, "Audio codec started");
}
void AudioCodec::SetOutputVolume(int volume){
void AudioCodec::SetOutputVolume(int volume) {
output_volume_ = volume;
ESP_LOGI(TAG, "Set output volume to %d", output_volume_);
@@ -61,45 +61,45 @@ void AudioCodec::SetOutputVolume(int volume){
settings.SetInt("output_volume", output_volume_);
}
void AudioCodec::EnableInput(bool enable){
if (enable == input_enabled_){
void AudioCodec::EnableInput(bool enable) {
if (enable == input_enabled_) {
return;
}
input_enabled_ = enable;
ESP_LOGI(TAG, "Set input enable to %s", enable ? "true" : "false");
}
void AudioCodec::EnableOutput(bool enable){
if (enable == output_enabled_){
void AudioCodec::EnableOutput(bool enable) {
if (enable == output_enabled_) {
return;
}
output_enabled_ = enable;
ESP_LOGI(TAG, "Set output enable to %s", enable ? "true" : "false");
}
bool AudioCodec::SetOutputSampleRate(int sample_rate){
bool AudioCodec::SetOutputSampleRate(int sample_rate) {
// 特殊处理:如果传入 -1表示重置到原始采样率
if (sample_rate == -1){
if (original_output_sample_rate_ > 0){
if (sample_rate == -1) {
if (original_output_sample_rate_ > 0) {
sample_rate = original_output_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");
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);
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);
return true;
}
if (tx_handle_ == nullptr){
if (tx_handle_ == nullptr) {
ESP_LOGW(TAG, "TX handle is null, only updating sample rate variable");
output_sample_rate_ = sample_rate;
return true;
@@ -110,14 +110,13 @@ bool AudioCodec::SetOutputSampleRate(int sample_rate){
// 先尝试禁用 I2S 通道(如果已启用的话)
bool was_enabled = false;
esp_err_t disable_ret = i2s_channel_disable(tx_handle_);
if (disable_ret == ESP_OK){
if (disable_ret == ESP_OK) {
was_enabled = true;
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");
}else{
} else {
ESP_LOGW(TAG, "Failed to disable I2S TX channel: %s", esp_err_to_name(disable_ret));
}
@@ -135,17 +134,17 @@ bool AudioCodec::SetOutputSampleRate(int sample_rate){
// 重新启用通道(无论之前是什么状态,现在都需要启用以便播放音频)
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));
}else{
} else {
ESP_LOGI(TAG, "Enabled I2S TX channel");
}
if (ret == ESP_OK){
if (ret == ESP_OK) {
output_sample_rate_ = sample_rate;
ESP_LOGI(TAG, "Successfully changed output sample rate to %d Hz", sample_rate);
return true;
}else{
} else {
ESP_LOGE(TAG, "Failed to change sample rate to %d Hz: %s", sample_rate, esp_err_to_name(ret));
return false;
}

View File

@@ -5,13 +5,14 @@
#include <vector>
#include <functional>
#include <model_path.h>
#include "audio_codec.h"
class AudioProcessor {
public:
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 Start() = 0;
virtual void Stop() = 0;

View File

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

View File

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

View File

@@ -10,7 +10,7 @@ AfeAudioProcessor::AfeAudioProcessor()
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;
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');
}
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* vad_model_name = esp_srmodel_filter(models, ESP_VADN_PREFIX, NULL);

View File

@@ -18,7 +18,7 @@ public:
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 Start() override;
void Stop() override;

View File

@@ -3,7 +3,7 @@
#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;
frame_samples_ = frame_duration_ms * 16000 / 1000;
}

View File

@@ -12,7 +12,7 @@ public:
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 Start() override;
void Stop() override;

View File

@@ -5,13 +5,14 @@
#include <vector>
#include <functional>
#include <model_path.h>
#include "audio_codec.h"
class WakeWord {
public:
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 OnWakeWordDetected(std::function<void(const std::string& wake_word)> callback) = 0;
virtual void Start() = 0;

View File

@@ -36,11 +36,16 @@ AfeWakeWord::~AfeWakeWord() {
vEventGroupDelete(event_group_);
}
bool AfeWakeWord::Initialize(AudioCodec* codec) {
bool AfeWakeWord::Initialize(AudioCodec* codec, srmodel_list_t* models_list) {
codec_ = codec;
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) {
ESP_LOGE(TAG, "Failed to initialize wakenet model");
return false;

View File

@@ -24,7 +24,7 @@ public:
AfeWakeWord();
~AfeWakeWord();
bool Initialize(AudioCodec* codec);
bool Initialize(AudioCodec* codec, srmodel_list_t* models_list);
void Feed(const std::vector<int16_t>& data);
void OnWakeWordDetected(std::function<void(const std::string& wake_word)> callback);
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;
models_ = esp_srmodel_init("model");
if (models_list == nullptr) {
models_ = esp_srmodel_init("model");
} else {
models_ = models_list;
}
if (models_ == nullptr || models_->num == -1) {
ESP_LOGE(TAG, "Failed to initialize wakenet model");
return false;

View File

@@ -22,7 +22,7 @@ public:
CustomWakeWord();
~CustomWakeWord();
bool Initialize(AudioCodec* codec);
bool Initialize(AudioCodec* codec, srmodel_list_t* models_list);
void Feed(const std::vector<int16_t>& data);
void OnWakeWordDetected(std::function<void(const std::string& wake_word)> callback);
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;
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) {
ESP_LOGE(TAG, "Failed to initialize wakenet model");
return false;

View File

@@ -18,7 +18,7 @@ public:
EspWakeWord();
~EspWakeWord();
bool Initialize(AudioCodec* codec);
bool Initialize(AudioCodec* codec, srmodel_list_t* models_list);
void Feed(const std::vector<int16_t>& data);
void OnWakeWordDetected(std::function<void(const std::string& wake_word)> callback);
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": [
// 额外需要的编译配置
"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"
// 声明字体
LV_FONT_DECLARE(font_puhui_16_4);
LV_FONT_DECLARE(font_awesome_16_4);
class MyCustomBoard : public WifiBoard {
private:
i2c_master_bus_handle_t codec_i2c_bus_;
@@ -212,12 +208,7 @@ private:
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 = font_emoji_32_init(),
});
DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY);
}
// MCP Tools 初始化

View File

@@ -20,10 +20,6 @@
#define TAG "atk_dnesp32s3_box"
LV_FONT_DECLARE(font_puhui_20_4);
LV_FONT_DECLARE(font_awesome_20_4);
class ATK_NoAudioCodecDuplex : public NoAudioCodec {
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) {
@@ -84,7 +80,6 @@ public:
}
};
class XL9555_IN : public I2cDevice {
public:
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));
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_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
});
DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY);
}
void InitializeButtons() {

View File

@@ -20,9 +20,6 @@
#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 {
private:
i2c_master_bus_handle_t i2c_bus_;
@@ -294,7 +291,6 @@ private:
GetDisplay()->ShowNotification(Lang::Strings::MAX_VOLUME);
});
}
void InitializeSt7789Display() {
@@ -325,12 +321,7 @@ private:
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,
{
.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(),
});
DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY);
}
public:

View File

@@ -21,9 +21,6 @@
#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 {
private:
i2c_master_bus_handle_t i2c_bus_;
@@ -412,12 +409,7 @@ private:
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,
{
.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(),
});
DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY);
}
public:

View File

@@ -21,9 +21,6 @@
#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 {
private:
i2c_master_bus_handle_t i2c_bus_;
@@ -392,12 +389,7 @@ private:
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,
{
.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(),
});
DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY);
}
public:

View File

@@ -16,9 +16,6 @@
#define TAG "atk_dnesp32s3"
LV_FONT_DECLARE(font_puhui_20_4);
LV_FONT_DECLARE(font_awesome_20_4);
class XL9555 : public I2cDevice {
public:
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 {
private:
i2c_master_bus_handle_t i2c_bus_;
@@ -131,16 +127,7 @@ private:
esp_lcd_panel_swap_xy(panel, DISPLAY_SWAP_XY);
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,
{
.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
});
DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY);
}
// 初始化摄像头ov2640

View File

@@ -20,9 +20,6 @@
#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 {
private:
i2c_master_bus_handle_t i2c_bus_;
@@ -167,12 +164,7 @@ private:
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,
{
.text_font = &font_puhui_16_4,
.icon_font = &font_awesome_16_4,
.emoji_font = font_emoji_32_init(),
});
DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY);
}
public:

View File

@@ -19,9 +19,6 @@
#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 {
private:
i2c_master_bus_handle_t i2c_bus_;
@@ -177,12 +174,7 @@ private:
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,
{
.text_font = &font_puhui_16_4,
.icon_font = &font_awesome_16_4,
.emoji_font = font_emoji_32_init(),
});
DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY);
}
public:

View File

@@ -22,7 +22,7 @@ idf.py menuconfig
分别配置如下选项:
- `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`
- `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"
class AtomEchoS3rBaseBoard : public WifiBoard {
private:
i2c_master_bus_handle_t i2c_bus_;

View File

@@ -5,7 +5,7 @@
"name": "atom-echos3r",
"sdkconfig_append": [
"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 {
private:
i2c_master_bus_handle_t i2c_bus_;
@@ -87,7 +86,6 @@ private:
pi4ioe_->SetSpeakerMute(false);
}
void InitializeButtons() {
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**

View File

@@ -16,9 +16,6 @@
#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[] = {
// {cmd, { data }, data_size, delay_ms}
{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_disp_on_off(panel_handle, true));
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,
{
.text_font = &font_puhui_16_4,
.icon_font = &font_awesome_16_4,
.emoji_font = font_emoji_32_init(),
});
DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY);
}
void InitializeButtons() {

View File

@@ -7,7 +7,7 @@
"CONFIG_SPIRAM=n",
"CONFIG_USE_AFE=n",
"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``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`
`S` 保存,按 `Q` 退出。

View File

@@ -5,7 +5,7 @@
"name": "atoms3r-cam-m12-echo-base",
"sdkconfig_append": [
"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 配置:**

View File

@@ -23,9 +23,6 @@
#define PI4IOE_REG_IO_OUT 0x05
#define PI4IOE_REG_IO_PULLUP 0x0D
LV_FONT_DECLARE(font_puhui_16_4);
LV_FONT_DECLARE(font_awesome_16_4);
class Pi4ioe : public I2cDevice {
public:
Pi4ioe(i2c_master_bus_handle_t i2c_bus, uint8_t addr) : I2cDevice(i2c_bus, addr) {
@@ -114,6 +111,7 @@ private:
Display* display_ = nullptr;
Button boot_button_;
bool is_echo_base_connected_ = false;
void InitializeI2c() {
// Initialize I2C peripheral
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));
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,
{
.text_font = &font_puhui_16_4,
.icon_font = &font_awesome_16_4,
.emoji_font = font_emoji_32_init(),
});
DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY);
}
void InitializeButtons() {

View File

@@ -5,7 +5,7 @@
"name": "atoms3r-echo-base",
"sdkconfig_append": [
"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"
LV_FONT_DECLARE(font_puhui_14_1);
LV_FONT_DECLARE(font_awesome_14_1);
class CompactWifiBoardLCD : public WifiBoard {
private:
Button boot_button_;
@@ -115,7 +112,6 @@ private:
esp_lcd_panel_reset(panel);
esp_lcd_panel_init(panel);
esp_lcd_panel_invert_color(panel, DISPLAY_INVERT_COLOR);
esp_lcd_panel_swap_xy(panel, DISPLAY_SWAP_XY);
@@ -124,16 +120,9 @@ private:
panel_config.vendor_config = &gc9107_vendor_config;
#endif
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_14_1,
.icon_font = &font_awesome_14_1,
.emoji_font = font_emoji_32_init(),
});
DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY);
}
void InitializeButtons() {
// 配置 GPIO

View File

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

View File

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

View File

@@ -60,9 +60,6 @@ static const gc9a01_lcd_init_cmd_t gc9107_lcd_init_cmds[] = {
#define TAG "CompactWifiBoardLCD"
LV_FONT_DECLARE(font_puhui_16_4);
LV_FONT_DECLARE(font_awesome_16_4);
class CompactWifiBoardLCD : public WifiBoard {
private:
@@ -115,7 +112,6 @@ private:
esp_lcd_panel_reset(panel);
esp_lcd_panel_init(panel);
esp_lcd_panel_invert_color(panel, DISPLAY_INVERT_COLOR);
esp_lcd_panel_swap_xy(panel, DISPLAY_SWAP_XY);
@@ -124,20 +120,9 @@ private:
panel_config.vendor_config = &gc9107_vendor_config;
#endif
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,
#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
});
DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY);
}
void InitializeButtons() {
boot_button_.OnClick([this]() {
auto& app = Application::GetInstance();

View File

@@ -61,9 +61,6 @@ static const gc9a01_lcd_init_cmd_t gc9107_lcd_init_cmds[] = {
#define TAG "CompactWifiBoardS3Cam"
LV_FONT_DECLARE(font_puhui_16_4);
LV_FONT_DECLARE(font_awesome_16_4);
class CompactWifiBoardS3Cam : public WifiBoard {
private:
@@ -117,7 +114,6 @@ private:
esp_lcd_panel_reset(panel);
esp_lcd_panel_init(panel);
esp_lcd_panel_invert_color(panel, DISPLAY_INVERT_COLOR);
esp_lcd_panel_swap_xy(panel, DISPLAY_SWAP_XY);
@@ -126,16 +122,7 @@ private:
panel_config.vendor_config = &gc9107_vendor_config;
#endif
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,
#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
});
DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY);
}
void InitializeCamera() {

View File

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

View File

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

View File

@@ -3,6 +3,7 @@
#include "display.h"
#include "board.h"
#include "system_info.h"
#include "lvgl_display.h"
#include <esp_log.h>
#include <esp_heap_caps.h>
@@ -23,48 +24,6 @@ Esp32Camera::Esp32Camera(const camera_config_t& config) {
if (s->id.PID == GC0308_PID) {
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() {
@@ -72,10 +31,6 @@ Esp32Camera::~Esp32Camera() {
esp_camera_fb_return(fb_);
fb_ = nullptr;
}
if (preview_image_.data) {
heap_caps_free((void*)preview_image_.data);
preview_image_.data = nullptr;
}
esp_camera_deinit();
}
@@ -89,6 +44,7 @@ bool Esp32Camera::Capture() {
encoder_thread_.join();
}
auto start_time = esp_timer_get_time();
int frames_to_get = 2;
// Try to get a stable frame
for (int i = 0; i < frames_to_get; i++) {
@@ -101,28 +57,36 @@ bool Esp32Camera::Capture() {
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) {
// 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 dst = (uint16_t*)preview_image_.data;
auto dst = (uint16_t*)img_dsc->data;
size_t pixel_count = fb_->len / 2;
for (size_t i = 0; i < pixel_count; i++) {
// 交换每个16位字内的字节
dst[i] = __builtin_bswap16(src[i]);
}
display->SetPreviewImage(&preview_image_);
display->SetPreviewImage(img_dsc);
}
return true;
}
@@ -185,14 +149,14 @@ bool Esp32Camera::SetVFlip(bool enabled) {
*/
std::string Esp32Camera::Explain(const std::string& question) {
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
QueueHandle_t jpeg_queue = xQueueCreate(40, sizeof(JpegChunk));
if (jpeg_queue == nullptr) {
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
@@ -235,7 +199,7 @@ std::string Esp32Camera::Explain(const std::string& question) {
}
}
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) {
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();

View File

@@ -19,7 +19,6 @@ struct JpegChunk {
class Esp32Camera : public Camera {
private:
camera_fb_t* fb_ = nullptr;
lv_img_dsc_t preview_image_;
std::string explain_url_;
std::string explain_token_;
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_song_name_;
bool song_name_displayed_;
std::atomic<bool> stop_flag_{false}; // 停止播放标志位
// 歌词相关
std::string current_lyric_url_;

View File

@@ -153,7 +153,10 @@ std::string Ml307Board::GetDeviceStatusJson() {
}
auto display = board.GetDisplay();
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);

View File

@@ -216,7 +216,10 @@ std::string WifiBoard::GetDeviceStatusJson() {
}
auto display = board.GetDisplay();
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);

View File

@@ -21,9 +21,6 @@
#define TAG "DF-K10"
LV_FONT_DECLARE(font_puhui_20_4);
LV_FONT_DECLARE(font_awesome_20_4);
class Df_K10Board : public WifiBoard {
private:
i2c_master_bus_handle_t i2c_bus_;
@@ -104,6 +101,7 @@ private:
ESP_LOGE(TAG, "Set direction failed: %s", esp_err_to_name(ret));
}
}
void InitializeButtons() {
instance_ = this;
@@ -233,12 +231,7 @@ private:
ESP_ERROR_CHECK(esp_lcd_panel_disp_on_off(panel, true));
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_20_4,
.icon_font = &font_awesome_20_4,
.emoji_font = font_emoji_64_init(),
});
DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY);
}
// 物联网初始化,添加对 AI 可见设备
@@ -258,7 +251,7 @@ public:
InitializeCamera();
}
virtual Led* GetLed() override {
virtual Led* GetLed() override {
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);
assert(in_codec_if_ != NULL);
esp_codec_dev_cfg_t codec_es7243e_dev_cfg = {
.dev_type = ESP_CODEC_DEV_TYPE_IN,
.codec_if = in_codec_if_,

View File

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

View File

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

View File

@@ -19,9 +19,6 @@
#define TAG "DuChatX"
LV_FONT_DECLARE(font_puhui_16_4);
LV_FONT_DECLARE(font_awesome_16_4);
class DuChatX : public WifiBoard {
private:
Button boot_button_;
@@ -101,12 +98,7 @@ private:
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);
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(),
});
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);
}
void InitializeButtons() {

View File

@@ -28,8 +28,6 @@
#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;
static const st77916_lcd_init_cmd_t vendor_specific_init_yysj[] = {
{0xF0, (uint8_t []){0x28}, 1, 0},
@@ -562,11 +560,7 @@ private:
#if USE_LVGL_DEFAULT
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_20_4,
.icon_font = &font_awesome_20_4,
.emoji_font = font_emoji_64_init(),
});
DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY);
#else
display_ = new anim::EmoteDisplay(panel, panel_io);
#endif

View File

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

View File

@@ -24,9 +24,6 @@
// 控制器初始化函数声明
void InitializeElectronBotController();
LV_FONT_DECLARE(font_puhui_20_4);
LV_FONT_DECLARE(font_awesome_20_4);
class ElectronBot : public WifiBoard {
private:
Display* display_;
@@ -73,12 +70,7 @@ private:
display_ = new ElectronEmojiDisplay(io_handle, panel_handle, 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(),
});
DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY);
}
void InitializeButtons() {

View File

@@ -1,4 +1,5 @@
#include "electron_emoji_display.h"
#include "lvgl_theme.h"
#include <esp_log.h>
#include <font_awesome.h>
@@ -7,7 +8,6 @@
#include <cstring>
#include <string>
#define TAG "ElectronEmojiDisplay"
// 表情映射表 - 将多种表情映射到现有6个GIF
@@ -51,9 +51,8 @@ const ElectronEmojiDisplay::EmotionMap ElectronEmojiDisplay::emotion_maps_[] = {
ElectronEmojiDisplay::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, bool mirror_y,
bool swap_xy, DisplayFonts fonts)
: SpiLcdDisplay(panel_io, panel, width, height, offset_x, offset_y, mirror_x, mirror_y, swap_xy,
fonts),
bool swap_xy)
: SpiLcdDisplay(panel_io, panel, width, height, offset_x, offset_y, mirror_x, mirror_y, swap_xy),
emotion_gif_(nullptr) {
SetupGifContainer();
}
@@ -61,8 +60,8 @@ ElectronEmojiDisplay::ElectronEmojiDisplay(esp_lcd_panel_io_handle_t panel_io,
void ElectronEmojiDisplay::SetupGifContainer() {
DisplayLockGuard lock(this);
if (emotion_label_) {
lv_obj_del(emotion_label_);
if (emoji_label_) {
lv_obj_del(emoji_label_);
}
if (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_center(content_);
emotion_label_ = lv_label_create(content_);
lv_label_set_text(emotion_label_, "");
lv_obj_set_width(emotion_label_, 0);
lv_obj_set_style_border_width(emotion_label_, 0, 0);
lv_obj_add_flag(emotion_label_, LV_OBJ_FLAG_HIDDEN);
emoji_label_ = lv_label_create(content_);
lv_label_set_text(emoji_label_, "");
lv_obj_set_width(emoji_label_, 0);
lv_obj_set_style_border_width(emoji_label_, 0, 0);
lv_obj_add_flag(emoji_label_, LV_OBJ_FLAG_HIDDEN);
emotion_gif_ = lv_gif_create(content_);
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);
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) {
@@ -145,26 +148,3 @@ void ElectronEmojiDisplay::SetChatMessage(const char* role, const char* 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,
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;
@@ -33,9 +33,6 @@ public:
// 重写聊天消息设置方法
virtual void SetChatMessage(const char* role, const char* content) override;
// 重写图标设置方法
virtual void SetIcon(const char* icon) override;
private:
void SetupGifContainer();

View File

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

View File

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

View File

@@ -14,9 +14,6 @@
#define TAG "EspBox3Board"
LV_FONT_DECLARE(font_puhui_20_4);
LV_FONT_DECLARE(font_awesome_20_4);
// Init ili9341 by custom cmd
static const ili9341_lcd_init_cmd_t vendor_specific_init[] = {
{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_disp_on_off(panel, true);
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_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
});
DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY);
}
public:

View File

@@ -3,7 +3,9 @@
"builds": [
{
"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"
LV_FONT_DECLARE(font_puhui_20_4);
LV_FONT_DECLARE(font_awesome_20_4);
/* ADC Buttons */
typedef enum {
BSP_ADC_BUTTON_PREV,
@@ -191,16 +188,7 @@ private:
esp_lcd_panel_mirror(panel, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y);
esp_lcd_panel_disp_on_off(panel, true);
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_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
});
DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY);
}
public:

View File

@@ -14,9 +14,6 @@
#define TAG "EspBoxBoard"
LV_FONT_DECLARE(font_puhui_20_4);
LV_FONT_DECLARE(font_awesome_20_4);
// Init ili9341 by custom cmd
static const ili9341_lcd_init_cmd_t vendor_specific_init[] = {
{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_disp_on_off(panel, true);
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_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
});
DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY);
}
public:

View File

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

View File

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

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