Skip to content

Commit b8c1086

Browse files
committed
Added Nabu VPE components
1 parent f7c3732 commit b8c1086

File tree

6 files changed

+304
-0
lines changed

6 files changed

+304
-0
lines changed

esphome/modular-onju.yaml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,31 @@ packages:
1010
onju_leds: !include onju-modules/leds.yaml
1111
onju_controls: !include onju-modules/controls.yaml
1212
# audio_gnumpi: !include onju-modules/audio-gnumpi.yaml
13+
audio_nabu: !include onju-modules/audio-nabu.yaml
1314
# onju_va_mww: !include onju-modules/micro_wake_word.yaml
15+
va_nabu: !include onju-modules/voice_assistant-nabu.yaml
16+
17+
# TEMP https://discord.com/channels/429907082951524364/1324733194980950106
18+
esp32:
19+
framework:
20+
version: 4.4.8
21+
platform_version: 5.4.0
22+
23+
binary_sensor:
24+
- id: !extend action
25+
on_click:
26+
then:
27+
- logger.log:
28+
tag: "action_click"
29+
format: "Voice assistant is running: %s"
30+
args: ['id(va).is_running() ? "yes" : "no"']
31+
- if:
32+
condition: media_player.is_playing
33+
then:
34+
- media_player.stop
35+
- if:
36+
condition: voice_assistant.is_running
37+
then:
38+
- voice_assistant.stop:
39+
else:
40+
- voice_assistant.start:

esphome/onju-modules/audio-nabu.yaml

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
packages:
2+
onju_microphone: !include microphone.yaml
3+
onju_media_player: !include media_player.yaml
4+
5+
external_components:
6+
- source:
7+
type: git
8+
url: https://github.com/esphome/home-assistant-voice-pe
9+
ref: dev
10+
components:
11+
- media_player
12+
- microphone
13+
- nabu
14+
- nabu_microphone
15+
i2s_audio:
16+
- id: i2s_output
17+
i2s_lrclk_pin:
18+
number: GPIO13
19+
allow_other_uses: true
20+
i2s_bclk_pin:
21+
number: GPIO18
22+
allow_other_uses: true
23+
24+
- id: i2s_input
25+
i2s_lrclk_pin:
26+
number: GPIO13
27+
allow_other_uses: true
28+
i2s_bclk_pin:
29+
number: GPIO18
30+
allow_other_uses: true
31+
32+
speaker:
33+
- platform: i2s_audio
34+
sample_rate: 16000
35+
i2s_mode: primary
36+
i2s_dout_pin: GPIO12
37+
bits_per_sample: 32bit
38+
i2s_audio_id: i2s_output
39+
dac_type: external
40+
channel: stereo
41+
timeout: never
42+
buffer_duration: 100ms
43+
44+
microphone:
45+
- id: !remove onju_microphone
46+
- platform: nabu_microphone
47+
i2s_din_pin: GPIO17
48+
adc_type: external
49+
pdm: false
50+
sample_rate: 16000
51+
bits_per_sample: 32bit
52+
i2s_mode: primary
53+
i2s_audio_id: i2s_input
54+
channel_0:
55+
id: onju_microphone
56+
amplify_shift: 2
57+
channel_1:
58+
id: comm_mic
59+
amplify_shift: 2
60+
61+
media_player:
62+
- id: !extend onju_out
63+
platform: nabu
64+
speaker:
65+
sample_rate: 16000
66+
volume_increment: 0.05
67+
volume_min: 0.4
68+
volume_max: 0.85
69+
files:
70+
- id: wake_word_triggered_sound
71+
file: ${wakeup_sound_url}
72+
73+
switch:
74+
# TODO
75+
- platform: gpio
76+
id: dac_mute
77+
name: DAC mute
78+
restore_mode: ALWAYS_OFF
79+
pin:
80+
number: GPIO21
81+
inverted: True
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
substitutions:
2+
wakeup_sound_url: "https://github.com/tetele/onju-voice-satellite/raw/main/res/wakeup.mp3" # New Notification #7 by UNIVERSFIELD https://freesound.org/people/UNIVERSFIELD/sounds/736267/
3+
error_sound_url: "https://github.com/tetele/onju-voice-satellite/raw/main/res/error.mp3" # Error #8 by UNIVERSFIELD https://freesound.org/people/UNIVERSFIELD/sounds/734442/
4+
timer_finished_sound_url: "https://github.com/tetele/onju-voice-satellite/raw/main/res/timer_finished.mp3" # New Notification #6 by UNIVERSFIELD https://freesound.org/people/UNIVERSFIELD/sounds/734445/
5+
6+
media_player:
7+
- id: onju_out
8+
name: None
9+
on_state:
10+
then:
11+
- lambda: |-
12+
static float old_volume = -1;
13+
float new_volume = id(onju_out).volume;
14+
if(abs(new_volume-old_volume) > 0.0001) {
15+
if(old_volume != -1) {
16+
id(show_volume) = true;
17+
id(control_led)->execute();
18+
}
19+
}
20+
old_volume = new_volume;
21+
22+
globals:
23+
- id: show_volume
24+
type: bool
25+
restore_value: no
26+
initial_value: "false"
27+
28+
light:
29+
- id: !extend top_led
30+
effects:
31+
- addressable_lambda:
32+
name: show_volume
33+
update_interval: 50ms
34+
lambda: |-
35+
int int_volume = int(id(onju_out).volume * 100.0f * it.size());
36+
int full_leds = int_volume / 100;
37+
int last_brightness = int_volume % 100;
38+
int i = 0;
39+
for(; i < full_leds; i++) {
40+
it[i] = Color::WHITE;
41+
}
42+
if(i < 4) {
43+
it[i++] = Color(64, 64, 64).fade_to_white(last_brightness*256/100);
44+
}
45+
for(; i < it.size(); i++) {
46+
it[i] = Color(64, 64, 64);
47+
}
48+
49+
script:
50+
- id: set_volume
51+
mode: restart
52+
parameters:
53+
volume: float
54+
then:
55+
- media_player.volume_set:
56+
id: onju_out
57+
volume: !lambda return clamp(id(onju_out).volume+volume, 0.0f, 1.0f);
58+
- lambda: |
59+
id(show_volume) = true;
60+
- script.execute: control_led
61+
62+
- id: !extend control_led_volume_touched
63+
then:
64+
- if:
65+
condition:
66+
lambda: "return id(show_volume);"
67+
then:
68+
- light.turn_on:
69+
id: top_led
70+
effect: show_volume
71+
- delay: 1s
72+
- lambda: |
73+
id(show_volume) = false;
74+
- script.execute: control_led
75+
else:
76+
- light.turn_off: top_led
77+
78+
binary_sensor:
79+
- id: !extend volume_down
80+
on_press:
81+
then:
82+
- script.execute:
83+
id: set_volume
84+
volume: -0.05
85+
- delay: 750ms
86+
- while:
87+
condition:
88+
binary_sensor.is_on: volume_down
89+
then:
90+
- script.execute:
91+
id: set_volume
92+
volume: -0.05
93+
- delay: 150ms
94+
95+
- id: !extend volume_up
96+
on_press:
97+
then:
98+
- script.execute:
99+
id: set_volume
100+
volume: 0.05
101+
- delay: 750ms
102+
- while:
103+
condition:
104+
binary_sensor.is_on: volume_up
105+
then:
106+
- script.execute:
107+
id: set_volume
108+
volume: 0.05
109+
- delay: 150ms

esphome/onju-modules/microphone.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
microphone:
2+
- id: onju_microphone
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
packages:
2+
onju_voice_assistant: !include voice_assistant.yaml
3+
4+
external_components:
5+
- source:
6+
type: git
7+
url: https://github.com/tetele/home-assistant-voice-pe
8+
ref: fix-mww-guarding
9+
components:
10+
- voice_assistant
11+
# refresh: 0s
12+
13+
voice_assistant:
14+
microphone: onju_microphone
15+
media_player: onju_out
16+
use_wake_word: false
17+
noise_suppression_level: 0
18+
auto_gain: 0 dbfs
19+
volume_multiplier: 1
20+
on_end:
21+
then:
22+
- lambda: id(voice_assistant_phase) = ${voice_assist_idle_phase_id};
23+
- script.execute: control_led
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
globals:
2+
- id: !extend voice_assistant_phase
3+
initial_value: ${voice_assist_not_ready_phase_id} # used to make the leds not blink when the va component is not loaded
4+
5+
api:
6+
services:
7+
- service: start_va
8+
then:
9+
- voice_assistant.start
10+
- service: stop_va
11+
then:
12+
- voice_assistant.stop
13+
14+
voice_assistant:
15+
id: va
16+
microphone: onju_microphone
17+
use_wake_word: false
18+
# TODO
19+
on_listening:
20+
- lambda: id(voice_assistant_phase) = ${voice_assist_waiting_for_command_phase_id};
21+
- script.execute: control_led
22+
on_stt_vad_start:
23+
- lambda: id(voice_assistant_phase) = ${voice_assist_listening_for_command_phase_id};
24+
- script.execute: control_led
25+
on_stt_vad_end:
26+
- lambda: id(voice_assistant_phase) = ${voice_assist_thinking_phase_id};
27+
- script.execute: control_led
28+
on_tts_start:
29+
- lambda: id(voice_assistant_phase) = ${voice_assist_replying_phase_id};
30+
- script.execute: control_led
31+
on_client_connected:
32+
- lambda: id(init_in_progress) = false;
33+
- lambda: id(voice_assistant_phase) = ${voice_assist_idle_phase_id};
34+
- script.execute: control_led
35+
on_client_disconnected:
36+
- voice_assistant.stop:
37+
- lambda: id(voice_assistant_phase) = ${voice_assist_not_ready_phase_id};
38+
- script.execute: control_led
39+
on_error:
40+
- if:
41+
condition:
42+
and:
43+
- lambda: return !id(init_in_progress);
44+
- lambda: return code != "duplicate_wake_up_detected";
45+
then:
46+
- lambda: id(voice_assistant_phase) = ${voice_assist_error_phase_id};
47+
- script.execute: control_led
48+
49+
script:
50+
- id: turn_on_wake_word
51+
then: []
52+
- id: turn_off_wake_word
53+
then: []
54+
55+
56+
# TODO
57+
binary_sensor:
58+
- id: !extend mute_switch
59+
on_press:
60+
- script.execute: turn_off_wake_word
61+
on_release:
62+
- script.execute: turn_on_wake_word

0 commit comments

Comments
 (0)