forked from xiaozhi/xiaozhi-esp32
Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cc5d724506 | ||
|
|
bba26ef69c | ||
|
|
7fcd40dbe7 | ||
|
|
48a1c5da29 | ||
|
|
2a02dd65be | ||
|
|
845b760db3 | ||
|
|
f86637cf1c | ||
|
|
363073658a | ||
|
|
da228f2582 | ||
|
|
36476f05cd | ||
|
|
90602d3802 | ||
|
|
b2e1c5bb5c | ||
|
|
d58d55cfe7 | ||
|
|
cd23e0f155 | ||
|
|
26d9ff283f | ||
|
|
fb85019c3c | ||
|
|
4859d57fea | ||
|
|
03394fe38d |
112
.github/workflows/build.yml
vendored
112
.github/workflows/build.yml
vendored
@@ -1,32 +1,106 @@
|
||||
name: Build and Test
|
||||
name: Build Boards
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- ci/* # for ci test
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build:
|
||||
prepare:
|
||||
name: Determine boards to build
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
outputs:
|
||||
boards: ${{ steps.select.outputs.boards }}
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Espressif IoT Development Framework (ESP-IDF)
|
||||
# You may pin to the exact commit or the version.
|
||||
# uses: espressif/esp-idf-ci-action@8cd22ae10042fadc37890e81e9988a9113e7b506
|
||||
uses: espressif/esp-idf-ci-action@v1.1.0
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
# Relative path under $GITHUB_WORKSPACE to place the repository
|
||||
#path: # optional, default is
|
||||
# Version of ESP-IDF docker image to use
|
||||
esp_idf_version: release-v5.4
|
||||
# ESP32 variant to build for
|
||||
target: esp32s3
|
||||
# Command to run inside the docker container (default: builds the project)
|
||||
# command: # optional, default is idf.py build
|
||||
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Install jq
|
||||
run: sudo apt-get update && sudo apt-get install -y jq
|
||||
|
||||
- id: list
|
||||
name: Get all board list
|
||||
run: |
|
||||
echo "all_boards=$(python scripts/release.py --list-boards --json)" >> $GITHUB_OUTPUT
|
||||
|
||||
- id: select
|
||||
name: Select boards based on changes
|
||||
env:
|
||||
ALL_BOARDS: ${{ steps.list.outputs.all_boards }}
|
||||
run: |
|
||||
EVENT_NAME="${{ github.event_name }}"
|
||||
|
||||
# For push to main branch, build all boards
|
||||
if [[ "$EVENT_NAME" == "push" ]]; then
|
||||
echo "boards=$ALL_BOARDS" >> $GITHUB_OUTPUT
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# For pull_request
|
||||
BASE_SHA="${{ github.event.pull_request.base.sha }}"
|
||||
HEAD_SHA="${{ github.event.pull_request.head.sha }}"
|
||||
echo "Base: $BASE_SHA, Head: $HEAD_SHA"
|
||||
|
||||
CHANGED=$(git diff --name-only $BASE_SHA $HEAD_SHA || true)
|
||||
echo "Changed files:\n$CHANGED"
|
||||
|
||||
NEED_ALL=0
|
||||
declare -A AFFECTED
|
||||
while IFS= read -r file; do
|
||||
if [[ "$file" == main/* && "$file" != main/boards/* ]]; then
|
||||
NEED_ALL=1
|
||||
fi
|
||||
|
||||
if [[ "$file" == main/boards/* ]]; then
|
||||
board=$(echo "$file" | cut -d '/' -f3)
|
||||
AFFECTED[$board]=1
|
||||
fi
|
||||
done <<< "$CHANGED"
|
||||
|
||||
if [[ "$NEED_ALL" -eq 1 ]]; then
|
||||
echo "boards=$ALL_BOARDS" >> $GITHUB_OUTPUT
|
||||
else
|
||||
if [[ ${#AFFECTED[@]} -eq 0 ]]; then
|
||||
echo "boards=[]" >> $GITHUB_OUTPUT
|
||||
else
|
||||
JSON=$(printf '%s\n' "${!AFFECTED[@]}" | sort -u | jq -R -s -c 'split("\n")[:-1]')
|
||||
echo "boards=$JSON" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
fi
|
||||
|
||||
build:
|
||||
name: Build ${{ matrix.board }}
|
||||
needs: prepare
|
||||
if: ${{ needs.prepare.outputs.boards != '[]' }}
|
||||
strategy:
|
||||
fail-fast: false # 单个 board 失败不影响其它 board
|
||||
matrix:
|
||||
board: ${{ fromJson(needs.prepare.outputs.boards) }}
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: espressif/idf:release-v5.4
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Build current board
|
||||
shell: bash
|
||||
run: |
|
||||
source $IDF_PATH/export.sh
|
||||
python scripts/release.py ${{ matrix.board }}
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: xiaozhi_${{ matrix.board }}_${{ github.sha }}.bin
|
||||
path: build/merged-binary.bin
|
||||
if-no-files-found: error
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -15,4 +15,5 @@ main/mmap_generate_emoji.h
|
||||
.cache
|
||||
main/mmap_generate_emoji.h
|
||||
*.pyc
|
||||
*.bin
|
||||
*.bin
|
||||
mmap_generate_*.h
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
# CMakeLists in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
set(PROJECT_VER "1.8.4")
|
||||
set(PROJECT_VER "1.8.6")
|
||||
|
||||
# Add this line to disable the specific warning
|
||||
add_compile_options(-Wno-missing-field-initializers)
|
||||
|
||||
208
docs/sonic_wifi_config.html
Normal file
208
docs/sonic_wifi_config.html
Normal file
@@ -0,0 +1,208 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>小智声波配网</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<style>
|
||||
body {
|
||||
font-family: "Segoe UI", "PingFang SC", sans-serif;
|
||||
background: #f0f2f5;
|
||||
margin: 0;
|
||||
padding: 2rem 1rem;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
.card {
|
||||
background: #fff;
|
||||
padding: 2rem 1.5rem;
|
||||
border-radius: 16px;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
|
||||
max-width: 400px;
|
||||
width: 100%;
|
||||
}
|
||||
h2 {
|
||||
text-align: center;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
label {
|
||||
font-weight: bold;
|
||||
display: block;
|
||||
margin: 1rem 0 0.3rem;
|
||||
}
|
||||
input[type="text"],
|
||||
input[type="password"] {
|
||||
width: 100%;
|
||||
padding: 0.75rem;
|
||||
font-size: 1rem;
|
||||
border-radius: 8px;
|
||||
border: 1px solid #ccc;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
input[type="checkbox"] {
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
.checkbox-container {
|
||||
margin-top: 1rem;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
button {
|
||||
width: 100%;
|
||||
margin-top: 1rem;
|
||||
padding: 0.8rem;
|
||||
font-size: 1rem;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
background-color: #4a90e2;
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.2s;
|
||||
}
|
||||
button:hover {
|
||||
background-color: #357ab8;
|
||||
}
|
||||
button:active {
|
||||
background-color: #2f6ea2;
|
||||
}
|
||||
audio {
|
||||
margin-top: 1.5rem;
|
||||
width: 100%;
|
||||
outline: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="card">
|
||||
<h2>📶 小智声波配网</h2>
|
||||
<label for="ssid">WiFi 名称</label>
|
||||
<input id="ssid" type="text" value="" placeholder="请输入 WiFi 名称" />
|
||||
|
||||
<label for="pwd">WiFi 密码</label>
|
||||
<input id="pwd" type="password" value="" placeholder="请输入 WiFi 密码" />
|
||||
|
||||
<div class="checkbox-container">
|
||||
<label><input type="checkbox" id="loopCheck" checked /> 自动循环播放声波</label>
|
||||
</div>
|
||||
|
||||
<button onclick="generate()">🎵 生成并播放声波</button>
|
||||
<button onclick="stopPlay()">⏹️ 停止播放</button>
|
||||
<audio id="player" controls></audio>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const MARK = 1800;
|
||||
const SPACE = 1500;
|
||||
const SAMPLE_RATE = 44100;
|
||||
const BIT_RATE = 100;
|
||||
const START_BYTES = [0x01, 0x02];
|
||||
const END_BYTES = [0x03, 0x04];
|
||||
let loopTimer = null;
|
||||
|
||||
function checksum(data) {
|
||||
return data.reduce((sum, b) => (sum + b) & 0xff, 0);
|
||||
}
|
||||
|
||||
function toBits(byte) {
|
||||
const bits = [];
|
||||
for (let i = 7; i >= 0; i--) bits.push((byte >> i) & 1);
|
||||
return bits;
|
||||
}
|
||||
|
||||
function afskModulate(bits) {
|
||||
const samplesPerBit = SAMPLE_RATE / BIT_RATE;
|
||||
const totalSamples = Math.floor(bits.length * samplesPerBit);
|
||||
const buffer = new Float32Array(totalSamples);
|
||||
for (let i = 0; i < bits.length; i++) {
|
||||
const freq = bits[i] ? MARK : SPACE;
|
||||
for (let j = 0; j < samplesPerBit; j++) {
|
||||
const t = (i * samplesPerBit + j) / SAMPLE_RATE;
|
||||
buffer[i * samplesPerBit + j] = Math.sin(2 * Math.PI * freq * t);
|
||||
}
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
function floatTo16BitPCM(floatSamples) {
|
||||
const buffer = new Uint8Array(floatSamples.length * 2);
|
||||
for (let i = 0; i < floatSamples.length; i++) {
|
||||
const s = Math.max(-1, Math.min(1, floatSamples[i]));
|
||||
const val = s < 0 ? s * 0x8000 : s * 0x7fff;
|
||||
buffer[i * 2] = val & 0xff;
|
||||
buffer[i * 2 + 1] = (val >> 8) & 0xff;
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
function buildWav(pcm) {
|
||||
const wavHeader = new Uint8Array(44);
|
||||
const dataLen = pcm.length;
|
||||
const fileLen = 36 + dataLen;
|
||||
|
||||
const writeStr = (offset, str) => {
|
||||
for (let i = 0; i < str.length; i++) wavHeader[offset + i] = str.charCodeAt(i);
|
||||
};
|
||||
const write32 = (offset, value) => {
|
||||
wavHeader[offset] = value & 0xff;
|
||||
wavHeader[offset + 1] = (value >> 8) & 0xff;
|
||||
wavHeader[offset + 2] = (value >> 16) & 0xff;
|
||||
wavHeader[offset + 3] = (value >> 24) & 0xff;
|
||||
};
|
||||
const write16 = (offset, value) => {
|
||||
wavHeader[offset] = value & 0xff;
|
||||
wavHeader[offset + 1] = (value >> 8) & 0xff;
|
||||
};
|
||||
|
||||
writeStr(0, 'RIFF');
|
||||
write32(4, fileLen);
|
||||
writeStr(8, 'WAVE');
|
||||
writeStr(12, 'fmt ');
|
||||
write32(16, 16);
|
||||
write16(20, 1);
|
||||
write16(22, 1);
|
||||
write32(24, SAMPLE_RATE);
|
||||
write32(28, SAMPLE_RATE * 2);
|
||||
write16(32, 2);
|
||||
write16(34, 16);
|
||||
writeStr(36, 'data');
|
||||
write32(40, dataLen);
|
||||
|
||||
return new Blob([wavHeader, pcm], { type: 'audio/wav' });
|
||||
}
|
||||
|
||||
function generate() {
|
||||
stopPlay();
|
||||
const ssid = document.getElementById('ssid').value.trim();
|
||||
const pwd = document.getElementById('pwd').value.trim();
|
||||
const dataStr = ssid + '\n' + pwd;
|
||||
const textBytes = Array.from(new TextEncoder().encode(dataStr));
|
||||
const fullBytes = [...START_BYTES, ...textBytes, checksum(textBytes), ...END_BYTES];
|
||||
|
||||
let bits = [];
|
||||
fullBytes.forEach((b) => (bits = bits.concat(toBits(b))));
|
||||
|
||||
const floatBuf = afskModulate(bits);
|
||||
const pcmBuf = floatTo16BitPCM(floatBuf);
|
||||
const wavBlob = buildWav(pcmBuf);
|
||||
|
||||
const audio = document.getElementById('player');
|
||||
audio.src = URL.createObjectURL(wavBlob);
|
||||
audio.load();
|
||||
audio.play();
|
||||
|
||||
// 修改了这里:使用 'ended' 事件来实现循环播放
|
||||
if (document.getElementById('loopCheck').checked) {
|
||||
audio.onended = function() {
|
||||
audio.currentTime = 0; // 从头开始
|
||||
audio.play(); // 重新播放
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function stopPlay() {
|
||||
const audio = document.getElementById('player');
|
||||
audio.pause();
|
||||
audio.onended = null; // 清除事件监听
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -245,13 +245,49 @@ elseif(CONFIG_LANGUAGE_EN_US)
|
||||
set(LANG_DIR "en-US")
|
||||
elseif(CONFIG_LANGUAGE_JA_JP)
|
||||
set(LANG_DIR "ja-JP")
|
||||
elseif(CONFIG_LANGUAGE_KO_KR)
|
||||
set(LANG_DIR "ko-KR")
|
||||
elseif(CONFIG_LANGUAGE_VI_VN)
|
||||
set(LANG_DIR "vi-VN")
|
||||
elseif(CONFIG_LANGUAGE_TH_TH)
|
||||
set(LANG_DIR "th-TH")
|
||||
elseif(CONFIG_LANGUAGE_DE_DE)
|
||||
set(LANG_DIR "de-DE")
|
||||
elseif(CONFIG_LANGUAGE_FR_FR)
|
||||
set(LANG_DIR "fr-FR")
|
||||
elseif(CONFIG_LANGUAGE_ES_ES)
|
||||
set(LANG_DIR "es-ES")
|
||||
elseif(CONFIG_LANGUAGE_IT_IT)
|
||||
set(LANG_DIR "it-IT")
|
||||
elseif(CONFIG_LANGUAGE_RU_RU)
|
||||
set(LANG_DIR "ru-RU")
|
||||
elseif(CONFIG_LANGUAGE_AR_SA)
|
||||
set(LANG_DIR "ar-SA")
|
||||
elseif(CONFIG_LANGUAGE_HI_IN)
|
||||
set(LANG_DIR "hi-IN")
|
||||
elseif(CONFIG_LANGUAGE_PT_PT)
|
||||
set(LANG_DIR "pt-PT")
|
||||
elseif(CONFIG_LANGUAGE_PL_PL)
|
||||
set(LANG_DIR "pl-PL")
|
||||
elseif(CONFIG_LANGUAGE_CS_CZ)
|
||||
set(LANG_DIR "cs-CZ")
|
||||
elseif(CONFIG_LANGUAGE_FI_FI)
|
||||
set(LANG_DIR "fi-FI")
|
||||
elseif(CONFIG_LANGUAGE_TR_TR)
|
||||
set(LANG_DIR "tr-TR")
|
||||
elseif(CONFIG_LANGUAGE_ID_ID)
|
||||
set(LANG_DIR "id-ID")
|
||||
elseif(CONFIG_LANGUAGE_UK_UA)
|
||||
set(LANG_DIR "uk-UA")
|
||||
elseif(CONFIG_LANGUAGE_RO_RO)
|
||||
set(LANG_DIR "ro-RO")
|
||||
endif()
|
||||
|
||||
# 定义生成路径
|
||||
set(LANG_JSON "${CMAKE_CURRENT_SOURCE_DIR}/assets/${LANG_DIR}/language.json")
|
||||
set(LANG_JSON "${CMAKE_CURRENT_SOURCE_DIR}/assets/locales/${LANG_DIR}/language.json")
|
||||
set(LANG_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/assets/lang_config.h")
|
||||
file(GLOB LANG_SOUNDS ${CMAKE_CURRENT_SOURCE_DIR}/assets/${LANG_DIR}/*.p3)
|
||||
file(GLOB COMMON_SOUNDS ${CMAKE_CURRENT_SOURCE_DIR}/assets/common/*.p3)
|
||||
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(CONFIG_IDF_TARGET_ESP32)
|
||||
@@ -281,7 +317,7 @@ target_compile_definitions(${COMPONENT_LIB}
|
||||
add_custom_command(
|
||||
OUTPUT ${LANG_HEADER}
|
||||
COMMAND python ${PROJECT_DIR}/scripts/gen_lang.py
|
||||
--input "${LANG_JSON}"
|
||||
--language "${LANG_DIR}"
|
||||
--output "${LANG_HEADER}"
|
||||
DEPENDS
|
||||
${LANG_JSON}
|
||||
@@ -335,4 +371,25 @@ spiffs_create_partition_assets(
|
||||
FLASH_IN_PROJECT
|
||||
MMAP_FILE_SUPPORT_FORMAT ".aaf"
|
||||
)
|
||||
endif()
|
||||
|
||||
if(CONFIG_BOARD_TYPE_ECHOEAR)
|
||||
|
||||
idf_build_get_property(build_components BUILD_COMPONENTS)
|
||||
foreach(COMPONENT ${build_components})
|
||||
if(COMPONENT MATCHES "esp_emote_gfx" OR COMPONENT MATCHES "espressif2022__esp_emote_gfx")
|
||||
set(EMOTE_GFX_COMPONENT ${COMPONENT})
|
||||
idf_component_get_property(EMOTE_GFX_COMPONENT_PATH ${EMOTE_GFX_COMPONENT} COMPONENT_DIR)
|
||||
set(SPIFFS_DIR "${EMOTE_GFX_COMPONENT_PATH}/emoji_normal")
|
||||
break()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
spiffs_create_partition_assets(
|
||||
assets_A
|
||||
${SPIFFS_DIR}
|
||||
FLASH_IN_PROJECT
|
||||
MMAP_FILE_SUPPORT_FORMAT ".aaf, ttf, bin"
|
||||
IMPORT_INC_PATH ${CMAKE_CURRENT_SOURCE_DIR}/boards/${BOARD_TYPE}
|
||||
)
|
||||
endif()
|
||||
@@ -21,6 +21,42 @@ choice
|
||||
bool "English"
|
||||
config LANGUAGE_JA_JP
|
||||
bool "Japanese"
|
||||
config LANGUAGE_KO_KR
|
||||
bool "Korean"
|
||||
config LANGUAGE_VI_VN
|
||||
bool "Vietnamese"
|
||||
config LANGUAGE_TH_TH
|
||||
bool "Thai"
|
||||
config LANGUAGE_DE_DE
|
||||
bool "German"
|
||||
config LANGUAGE_FR_FR
|
||||
bool "French"
|
||||
config LANGUAGE_ES_ES
|
||||
bool "Spanish"
|
||||
config LANGUAGE_IT_IT
|
||||
bool "Italian"
|
||||
config LANGUAGE_RU_RU
|
||||
bool "Russian"
|
||||
config LANGUAGE_AR_SA
|
||||
bool "Arabic"
|
||||
config LANGUAGE_HI_IN
|
||||
bool "Hindi"
|
||||
config LANGUAGE_PT_PT
|
||||
bool "Portuguese"
|
||||
config LANGUAGE_PL_PL
|
||||
bool "Polish"
|
||||
config LANGUAGE_CS_CZ
|
||||
bool "Czech"
|
||||
config LANGUAGE_FI_FI
|
||||
bool "Finnish"
|
||||
config LANGUAGE_TR_TR
|
||||
bool "Turkish"
|
||||
config LANGUAGE_ID_ID
|
||||
bool "Indonesian"
|
||||
config LANGUAGE_UK_UA
|
||||
bool "Ukrainian"
|
||||
config LANGUAGE_RO_RO
|
||||
bool "Romanian"
|
||||
endchoice
|
||||
|
||||
choice BOARD_TYPE
|
||||
|
||||
@@ -85,9 +85,9 @@ void Application::CheckNewVersion(Ota& ota) {
|
||||
return;
|
||||
}
|
||||
|
||||
char buffer[128];
|
||||
char buffer[256];
|
||||
snprintf(buffer, sizeof(buffer), Lang::Strings::CHECK_NEW_VERSION_FAILED, retry_delay, ota.GetCheckVersionUrl().c_str());
|
||||
Alert(Lang::Strings::ERROR, buffer, "sad", Lang::Sounds::P3_EXCLAMATION);
|
||||
Alert(Lang::Strings::ERROR, buffer, "sad", Lang::Sounds::OGG_EXCLAMATION);
|
||||
|
||||
ESP_LOGW(TAG, "Check new version failed, retry in %d seconds (%d/%d)", retry_delay, retry_count, MAX_RETRY);
|
||||
for (int i = 0; i < retry_delay; i++) {
|
||||
@@ -103,7 +103,7 @@ void Application::CheckNewVersion(Ota& ota) {
|
||||
retry_delay = 10; // 重置重试延迟时间
|
||||
|
||||
if (ota.HasNewVersion()) {
|
||||
Alert(Lang::Strings::OTA_UPGRADE, Lang::Strings::UPGRADING, "happy", Lang::Sounds::P3_UPGRADE);
|
||||
Alert(Lang::Strings::OTA_UPGRADE, Lang::Strings::UPGRADING, "happy", Lang::Sounds::OGG_UPGRADE);
|
||||
|
||||
vTaskDelay(pdMS_TO_TICKS(3000));
|
||||
|
||||
@@ -118,9 +118,11 @@ void Application::CheckNewVersion(Ota& ota) {
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
|
||||
bool upgrade_success = ota.StartUpgrade([display](int progress, size_t speed) {
|
||||
char buffer[64];
|
||||
snprintf(buffer, sizeof(buffer), "%d%% %uKB/s", progress, speed / 1024);
|
||||
display->SetChatMessage("system", buffer);
|
||||
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) {
|
||||
@@ -128,7 +130,7 @@ void Application::CheckNewVersion(Ota& ota) {
|
||||
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, "sad", Lang::Sounds::P3_EXCLAMATION);
|
||||
Alert(Lang::Strings::ERROR, Lang::Strings::UPGRADE_FAILED, "sad", Lang::Sounds::OGG_EXCLAMATION);
|
||||
vTaskDelay(pdMS_TO_TICKS(3000));
|
||||
// Continue to normal operation (don't break, just fall through)
|
||||
} else {
|
||||
@@ -180,20 +182,20 @@ void Application::ShowActivationCode(const std::string& code, const std::string&
|
||||
const std::string_view& sound;
|
||||
};
|
||||
static const std::array<digit_sound, 10> digit_sounds{{
|
||||
digit_sound{'0', Lang::Sounds::P3_0},
|
||||
digit_sound{'1', Lang::Sounds::P3_1},
|
||||
digit_sound{'2', Lang::Sounds::P3_2},
|
||||
digit_sound{'3', Lang::Sounds::P3_3},
|
||||
digit_sound{'4', Lang::Sounds::P3_4},
|
||||
digit_sound{'5', Lang::Sounds::P3_5},
|
||||
digit_sound{'6', Lang::Sounds::P3_6},
|
||||
digit_sound{'7', Lang::Sounds::P3_7},
|
||||
digit_sound{'8', Lang::Sounds::P3_8},
|
||||
digit_sound{'9', Lang::Sounds::P3_9}
|
||||
digit_sound{'0', Lang::Sounds::OGG_0},
|
||||
digit_sound{'1', Lang::Sounds::OGG_1},
|
||||
digit_sound{'2', Lang::Sounds::OGG_2},
|
||||
digit_sound{'3', Lang::Sounds::OGG_3},
|
||||
digit_sound{'4', Lang::Sounds::OGG_4},
|
||||
digit_sound{'5', Lang::Sounds::OGG_5},
|
||||
digit_sound{'6', Lang::Sounds::OGG_6},
|
||||
digit_sound{'7', Lang::Sounds::OGG_7},
|
||||
digit_sound{'8', Lang::Sounds::OGG_8},
|
||||
digit_sound{'9', Lang::Sounds::OGG_9}
|
||||
}};
|
||||
|
||||
// This sentence uses 9KB of SRAM, so we need to wait for it to finish
|
||||
Alert(Lang::Strings::ACTIVATION, message.c_str(), "happy", Lang::Sounds::P3_ACTIVATION);
|
||||
Alert(Lang::Strings::ACTIVATION, message.c_str(), "happy", Lang::Sounds::OGG_ACTIVATION);
|
||||
|
||||
for (const auto& digit : code) {
|
||||
auto it = std::find_if(digit_sounds.begin(), digit_sounds.end(),
|
||||
@@ -469,7 +471,7 @@ void Application::Start() {
|
||||
auto message = cJSON_GetObjectItem(root, "message");
|
||||
auto emotion = cJSON_GetObjectItem(root, "emotion");
|
||||
if (cJSON_IsString(status) && cJSON_IsString(message) && cJSON_IsString(emotion)) {
|
||||
Alert(status->valuestring, message->valuestring, emotion->valuestring, Lang::Sounds::P3_VIBRATION);
|
||||
Alert(status->valuestring, message->valuestring, emotion->valuestring, Lang::Sounds::OGG_VIBRATION);
|
||||
} else {
|
||||
ESP_LOGW(TAG, "Alert command requires status, message and emotion");
|
||||
}
|
||||
@@ -499,14 +501,11 @@ void Application::Start() {
|
||||
display->ShowNotification(message.c_str());
|
||||
display->SetChatMessage("system", "");
|
||||
// Play the success sound to indicate the device is ready
|
||||
audio_service_.PlaySound(Lang::Sounds::P3_SUCCESS);
|
||||
audio_service_.PlaySound(Lang::Sounds::OGG_SUCCESS);
|
||||
}
|
||||
|
||||
// Print heap stats
|
||||
SystemInfo::PrintHeapStats();
|
||||
|
||||
// Enter the main event loop
|
||||
MainEventLoop();
|
||||
}
|
||||
|
||||
void Application::OnClockTimer() {
|
||||
@@ -547,7 +546,7 @@ void Application::MainEventLoop() {
|
||||
MAIN_EVENT_ERROR, pdTRUE, pdFALSE, portMAX_DELAY);
|
||||
if (bits & MAIN_EVENT_ERROR) {
|
||||
SetDeviceState(kDeviceStateIdle);
|
||||
Alert(Lang::Strings::ERROR, last_error_message_.c_str(), "sad", Lang::Sounds::P3_EXCLAMATION);
|
||||
Alert(Lang::Strings::ERROR, last_error_message_.c_str(), "sad", Lang::Sounds::OGG_EXCLAMATION);
|
||||
}
|
||||
|
||||
if (bits & MAIN_EVENT_SEND_AUDIO) {
|
||||
@@ -609,7 +608,7 @@ void Application::OnWakeWordDetected() {
|
||||
#else
|
||||
SetListeningMode(aec_mode_ == kAecOff ? kListeningModeAutoStop : kListeningModeRealtime);
|
||||
// Play the pop up sound to indicate the wake word is detected
|
||||
audio_service_.PlaySound(Lang::Sounds::P3_POPUP);
|
||||
audio_service_.PlaySound(Lang::Sounds::OGG_POPUP);
|
||||
#endif
|
||||
} else if (device_state_ == kDeviceStateSpeaking) {
|
||||
AbortSpeaking(kAbortReasonWakeWordDetected);
|
||||
|
||||
@@ -41,6 +41,7 @@ public:
|
||||
Application& operator=(const Application&) = delete;
|
||||
|
||||
void Start();
|
||||
void MainEventLoop();
|
||||
DeviceState GetDeviceState() const { return device_state_; }
|
||||
bool IsVoiceDetected() const { return audio_service_.IsVoiceDetected(); }
|
||||
void Schedule(std::function<void()> callback);
|
||||
@@ -80,7 +81,6 @@ private:
|
||||
int clock_ticks_ = 0;
|
||||
TaskHandle_t check_new_version_task_handle_ = nullptr;
|
||||
|
||||
void MainEventLoop();
|
||||
void OnWakeWordDetected();
|
||||
void CheckNewVersion(Ota& ota);
|
||||
void ShowActivationCode(const std::string& code, const std::string& message);
|
||||
|
||||
BIN
main/assets/common/exclamation.ogg
Normal file
BIN
main/assets/common/exclamation.ogg
Normal file
Binary file not shown.
Binary file not shown.
BIN
main/assets/common/low_battery.ogg
Normal file
BIN
main/assets/common/low_battery.ogg
Normal file
Binary file not shown.
Binary file not shown.
BIN
main/assets/common/popup.ogg
Normal file
BIN
main/assets/common/popup.ogg
Normal file
Binary file not shown.
Binary file not shown.
BIN
main/assets/common/success.ogg
Normal file
BIN
main/assets/common/success.ogg
Normal file
Binary file not shown.
Binary file not shown.
BIN
main/assets/common/vibration.ogg
Normal file
BIN
main/assets/common/vibration.ogg
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
main/assets/locales/ar-SA/0.ogg
Normal file
BIN
main/assets/locales/ar-SA/0.ogg
Normal file
Binary file not shown.
BIN
main/assets/locales/ar-SA/1.ogg
Normal file
BIN
main/assets/locales/ar-SA/1.ogg
Normal file
Binary file not shown.
BIN
main/assets/locales/ar-SA/2.ogg
Normal file
BIN
main/assets/locales/ar-SA/2.ogg
Normal file
Binary file not shown.
BIN
main/assets/locales/ar-SA/3.ogg
Normal file
BIN
main/assets/locales/ar-SA/3.ogg
Normal file
Binary file not shown.
BIN
main/assets/locales/ar-SA/4.ogg
Normal file
BIN
main/assets/locales/ar-SA/4.ogg
Normal file
Binary file not shown.
BIN
main/assets/locales/ar-SA/5.ogg
Normal file
BIN
main/assets/locales/ar-SA/5.ogg
Normal file
Binary file not shown.
BIN
main/assets/locales/ar-SA/6.ogg
Normal file
BIN
main/assets/locales/ar-SA/6.ogg
Normal file
Binary file not shown.
BIN
main/assets/locales/ar-SA/7.ogg
Normal file
BIN
main/assets/locales/ar-SA/7.ogg
Normal file
Binary file not shown.
BIN
main/assets/locales/ar-SA/8.ogg
Normal file
BIN
main/assets/locales/ar-SA/8.ogg
Normal file
Binary file not shown.
BIN
main/assets/locales/ar-SA/9.ogg
Normal file
BIN
main/assets/locales/ar-SA/9.ogg
Normal file
Binary file not shown.
BIN
main/assets/locales/ar-SA/activation.ogg
Normal file
BIN
main/assets/locales/ar-SA/activation.ogg
Normal file
Binary file not shown.
BIN
main/assets/locales/ar-SA/err_pin.ogg
Normal file
BIN
main/assets/locales/ar-SA/err_pin.ogg
Normal file
Binary file not shown.
BIN
main/assets/locales/ar-SA/err_reg.ogg
Normal file
BIN
main/assets/locales/ar-SA/err_reg.ogg
Normal file
Binary file not shown.
58
main/assets/locales/ar-SA/language.json
Normal file
58
main/assets/locales/ar-SA/language.json
Normal file
@@ -0,0 +1,58 @@
|
||||
{
|
||||
"language": {
|
||||
"type" :"ar-SA"
|
||||
},
|
||||
"strings": {
|
||||
"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...",
|
||||
|
||||
"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 مُشغل"
|
||||
}
|
||||
}
|
||||
BIN
main/assets/locales/ar-SA/upgrade.ogg
Normal file
BIN
main/assets/locales/ar-SA/upgrade.ogg
Normal file
Binary file not shown.
BIN
main/assets/locales/ar-SA/welcome.ogg
Normal file
BIN
main/assets/locales/ar-SA/welcome.ogg
Normal file
Binary file not shown.
BIN
main/assets/locales/ar-SA/wificonfig.ogg
Normal file
BIN
main/assets/locales/ar-SA/wificonfig.ogg
Normal file
Binary file not shown.
BIN
main/assets/locales/cs-CZ/0.ogg
Normal file
BIN
main/assets/locales/cs-CZ/0.ogg
Normal file
Binary file not shown.
BIN
main/assets/locales/cs-CZ/1.ogg
Normal file
BIN
main/assets/locales/cs-CZ/1.ogg
Normal file
Binary file not shown.
BIN
main/assets/locales/cs-CZ/2.ogg
Normal file
BIN
main/assets/locales/cs-CZ/2.ogg
Normal file
Binary file not shown.
BIN
main/assets/locales/cs-CZ/3.ogg
Normal file
BIN
main/assets/locales/cs-CZ/3.ogg
Normal file
Binary file not shown.
BIN
main/assets/locales/cs-CZ/4.ogg
Normal file
BIN
main/assets/locales/cs-CZ/4.ogg
Normal file
Binary file not shown.
BIN
main/assets/locales/cs-CZ/5.ogg
Normal file
BIN
main/assets/locales/cs-CZ/5.ogg
Normal file
Binary file not shown.
BIN
main/assets/locales/cs-CZ/6.ogg
Normal file
BIN
main/assets/locales/cs-CZ/6.ogg
Normal file
Binary file not shown.
BIN
main/assets/locales/cs-CZ/7.ogg
Normal file
BIN
main/assets/locales/cs-CZ/7.ogg
Normal file
Binary file not shown.
BIN
main/assets/locales/cs-CZ/8.ogg
Normal file
BIN
main/assets/locales/cs-CZ/8.ogg
Normal file
Binary file not shown.
BIN
main/assets/locales/cs-CZ/9.ogg
Normal file
BIN
main/assets/locales/cs-CZ/9.ogg
Normal file
Binary file not shown.
BIN
main/assets/locales/cs-CZ/activation.ogg
Normal file
BIN
main/assets/locales/cs-CZ/activation.ogg
Normal file
Binary file not shown.
BIN
main/assets/locales/cs-CZ/err_pin.ogg
Normal file
BIN
main/assets/locales/cs-CZ/err_pin.ogg
Normal file
Binary file not shown.
BIN
main/assets/locales/cs-CZ/err_reg.ogg
Normal file
BIN
main/assets/locales/cs-CZ/err_reg.ogg
Normal file
Binary file not shown.
58
main/assets/locales/cs-CZ/language.json
Normal file
58
main/assets/locales/cs-CZ/language.json
Normal file
@@ -0,0 +1,58 @@
|
||||
{
|
||||
"language": {
|
||||
"type" :"cs-CZ"
|
||||
},
|
||||
"strings": {
|
||||
"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...",
|
||||
|
||||
"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"
|
||||
}
|
||||
}
|
||||
BIN
main/assets/locales/cs-CZ/upgrade.ogg
Normal file
BIN
main/assets/locales/cs-CZ/upgrade.ogg
Normal file
Binary file not shown.
BIN
main/assets/locales/cs-CZ/welcome.ogg
Normal file
BIN
main/assets/locales/cs-CZ/welcome.ogg
Normal file
Binary file not shown.
BIN
main/assets/locales/cs-CZ/wificonfig.ogg
Normal file
BIN
main/assets/locales/cs-CZ/wificonfig.ogg
Normal file
Binary file not shown.
BIN
main/assets/locales/de-DE/0.ogg
Normal file
BIN
main/assets/locales/de-DE/0.ogg
Normal file
Binary file not shown.
BIN
main/assets/locales/de-DE/1.ogg
Normal file
BIN
main/assets/locales/de-DE/1.ogg
Normal file
Binary file not shown.
BIN
main/assets/locales/de-DE/2.ogg
Normal file
BIN
main/assets/locales/de-DE/2.ogg
Normal file
Binary file not shown.
BIN
main/assets/locales/de-DE/3.ogg
Normal file
BIN
main/assets/locales/de-DE/3.ogg
Normal file
Binary file not shown.
BIN
main/assets/locales/de-DE/4.ogg
Normal file
BIN
main/assets/locales/de-DE/4.ogg
Normal file
Binary file not shown.
BIN
main/assets/locales/de-DE/5.ogg
Normal file
BIN
main/assets/locales/de-DE/5.ogg
Normal file
Binary file not shown.
BIN
main/assets/locales/de-DE/6.ogg
Normal file
BIN
main/assets/locales/de-DE/6.ogg
Normal file
Binary file not shown.
BIN
main/assets/locales/de-DE/7.ogg
Normal file
BIN
main/assets/locales/de-DE/7.ogg
Normal file
Binary file not shown.
BIN
main/assets/locales/de-DE/8.ogg
Normal file
BIN
main/assets/locales/de-DE/8.ogg
Normal file
Binary file not shown.
BIN
main/assets/locales/de-DE/9.ogg
Normal file
BIN
main/assets/locales/de-DE/9.ogg
Normal file
Binary file not shown.
BIN
main/assets/locales/de-DE/activation.ogg
Normal file
BIN
main/assets/locales/de-DE/activation.ogg
Normal file
Binary file not shown.
BIN
main/assets/locales/de-DE/err_pin.ogg
Normal file
BIN
main/assets/locales/de-DE/err_pin.ogg
Normal file
Binary file not shown.
BIN
main/assets/locales/de-DE/err_reg.ogg
Normal file
BIN
main/assets/locales/de-DE/err_reg.ogg
Normal file
Binary file not shown.
58
main/assets/locales/de-DE/language.json
Normal file
58
main/assets/locales/de-DE/language.json
Normal file
@@ -0,0 +1,58 @@
|
||||
{
|
||||
"language": {
|
||||
"type" :"de-DE"
|
||||
},
|
||||
"strings": {
|
||||
"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...",
|
||||
|
||||
"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"
|
||||
}
|
||||
}
|
||||
BIN
main/assets/locales/de-DE/upgrade.ogg
Normal file
BIN
main/assets/locales/de-DE/upgrade.ogg
Normal file
Binary file not shown.
BIN
main/assets/locales/de-DE/welcome.ogg
Normal file
BIN
main/assets/locales/de-DE/welcome.ogg
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user