mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 15:12:06 +00:00 
			
		
		
		
	Merge remote-tracking branch 'upstream/dev' into integration
This commit is contained in:
		
							
								
								
									
										2
									
								
								.github/actions/restore-python/action.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/actions/restore-python/action.yml
									
									
									
									
										vendored
									
									
								
							| @@ -22,7 +22,7 @@ runs: | ||||
|         python-version: ${{ inputs.python-version }} | ||||
|     - name: Restore Python virtual environment | ||||
|       id: cache-venv | ||||
|       uses: actions/cache/restore@v4.2.4 | ||||
|       uses: actions/cache/restore@v4.3.0 | ||||
|       with: | ||||
|         path: venv | ||||
|         # yamllint disable-line rule:line-length | ||||
|   | ||||
							
								
								
									
										10
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							| @@ -47,7 +47,7 @@ jobs: | ||||
|           python-version: ${{ env.DEFAULT_PYTHON }} | ||||
|       - name: Restore Python virtual environment | ||||
|         id: cache-venv | ||||
|         uses: actions/cache@v4.2.4 | ||||
|         uses: actions/cache@v4.3.0 | ||||
|         with: | ||||
|           path: venv | ||||
|           # yamllint disable-line rule:line-length | ||||
| @@ -162,7 +162,7 @@ jobs: | ||||
|           token: ${{ secrets.CODECOV_TOKEN }} | ||||
|       - name: Save Python virtual environment cache | ||||
|         if: github.ref == 'refs/heads/dev' | ||||
|         uses: actions/cache/save@v4.2.4 | ||||
|         uses: actions/cache/save@v4.3.0 | ||||
|         with: | ||||
|           path: venv | ||||
|           key: ${{ runner.os }}-${{ steps.restore-python.outputs.python-version }}-venv-${{ needs.common.outputs.cache-key }} | ||||
| @@ -223,7 +223,7 @@ jobs: | ||||
|           python-version: "3.13" | ||||
|       - name: Restore Python virtual environment | ||||
|         id: cache-venv | ||||
|         uses: actions/cache@v4.2.4 | ||||
|         uses: actions/cache@v4.3.0 | ||||
|         with: | ||||
|           path: venv | ||||
|           key: ${{ runner.os }}-${{ steps.python.outputs.python-version }}-venv-${{ needs.common.outputs.cache-key }} | ||||
| @@ -301,14 +301,14 @@ jobs: | ||||
|  | ||||
|       - name: Cache platformio | ||||
|         if: github.ref == 'refs/heads/dev' | ||||
|         uses: actions/cache@v4.2.4 | ||||
|         uses: actions/cache@v4.3.0 | ||||
|         with: | ||||
|           path: ~/.platformio | ||||
|           key: platformio-${{ matrix.pio_cache_key }}-${{ hashFiles('platformio.ini') }} | ||||
|  | ||||
|       - name: Cache platformio | ||||
|         if: github.ref != 'refs/heads/dev' | ||||
|         uses: actions/cache/restore@v4.2.4 | ||||
|         uses: actions/cache/restore@v4.3.0 | ||||
|         with: | ||||
|           path: ~/.platformio | ||||
|           key: platformio-${{ matrix.pio_cache_key }}-${{ hashFiles('platformio.ini') }} | ||||
|   | ||||
| @@ -1865,10 +1865,22 @@ message VoiceAssistantWakeWord { | ||||
|   repeated string trained_languages = 3; | ||||
| } | ||||
|  | ||||
| message VoiceAssistantExternalWakeWord { | ||||
|   string id = 1; | ||||
|   string wake_word = 2; | ||||
|   repeated string trained_languages = 3; | ||||
|   string model_type = 4; | ||||
|   uint32 model_size = 5; | ||||
|   string model_hash = 6; | ||||
|   string url = 7; | ||||
| } | ||||
|  | ||||
| message VoiceAssistantConfigurationRequest { | ||||
|   option (id) = 121; | ||||
|   option (source) = SOURCE_CLIENT; | ||||
|   option (ifdef) = "USE_VOICE_ASSISTANT"; | ||||
|  | ||||
|   repeated VoiceAssistantExternalWakeWord external_wake_words = 1; | ||||
| } | ||||
|  | ||||
| message VoiceAssistantConfigurationResponse { | ||||
|   | ||||
| @@ -1202,6 +1202,23 @@ bool APIConnection::send_voice_assistant_get_configuration_response(const VoiceA | ||||
|       resp_wake_word.trained_languages.push_back(lang); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // Filter external wake words | ||||
|   for (auto &wake_word : msg.external_wake_words) { | ||||
|     if (wake_word.model_type != "micro") { | ||||
|       // microWakeWord only | ||||
|       continue; | ||||
|     } | ||||
|  | ||||
|     resp.available_wake_words.emplace_back(); | ||||
|     auto &resp_wake_word = resp.available_wake_words.back(); | ||||
|     resp_wake_word.set_id(StringRef(wake_word.id)); | ||||
|     resp_wake_word.set_wake_word(StringRef(wake_word.wake_word)); | ||||
|     for (const auto &lang : wake_word.trained_languages) { | ||||
|       resp_wake_word.trained_languages.push_back(lang); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   resp.active_wake_words = &config.active_wake_words; | ||||
|   resp.max_active_wake_words = config.max_active_wake_words; | ||||
|   return this->send_message(resp, VoiceAssistantConfigurationResponse::MESSAGE_TYPE); | ||||
|   | ||||
| @@ -2397,6 +2397,52 @@ void VoiceAssistantWakeWord::calculate_size(ProtoSize &size) const { | ||||
|     } | ||||
|   } | ||||
| } | ||||
| bool VoiceAssistantExternalWakeWord::decode_varint(uint32_t field_id, ProtoVarInt value) { | ||||
|   switch (field_id) { | ||||
|     case 5: | ||||
|       this->model_size = value.as_uint32(); | ||||
|       break; | ||||
|     default: | ||||
|       return false; | ||||
|   } | ||||
|   return true; | ||||
| } | ||||
| bool VoiceAssistantExternalWakeWord::decode_length(uint32_t field_id, ProtoLengthDelimited value) { | ||||
|   switch (field_id) { | ||||
|     case 1: | ||||
|       this->id = value.as_string(); | ||||
|       break; | ||||
|     case 2: | ||||
|       this->wake_word = value.as_string(); | ||||
|       break; | ||||
|     case 3: | ||||
|       this->trained_languages.push_back(value.as_string()); | ||||
|       break; | ||||
|     case 4: | ||||
|       this->model_type = value.as_string(); | ||||
|       break; | ||||
|     case 6: | ||||
|       this->model_hash = value.as_string(); | ||||
|       break; | ||||
|     case 7: | ||||
|       this->url = value.as_string(); | ||||
|       break; | ||||
|     default: | ||||
|       return false; | ||||
|   } | ||||
|   return true; | ||||
| } | ||||
| bool VoiceAssistantConfigurationRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value) { | ||||
|   switch (field_id) { | ||||
|     case 1: | ||||
|       this->external_wake_words.emplace_back(); | ||||
|       value.decode_to_message(this->external_wake_words.back()); | ||||
|       break; | ||||
|     default: | ||||
|       return false; | ||||
|   } | ||||
|   return true; | ||||
| } | ||||
| void VoiceAssistantConfigurationResponse::encode(ProtoWriteBuffer buffer) const { | ||||
|   for (auto &it : this->available_wake_words) { | ||||
|     buffer.encode_message(1, it, true); | ||||
|   | ||||
| @@ -2456,18 +2456,37 @@ class VoiceAssistantWakeWord final : public ProtoMessage { | ||||
|  | ||||
|  protected: | ||||
| }; | ||||
| class VoiceAssistantConfigurationRequest final : public ProtoMessage { | ||||
| class VoiceAssistantExternalWakeWord final : public ProtoDecodableMessage { | ||||
|  public: | ||||
|   static constexpr uint8_t MESSAGE_TYPE = 121; | ||||
|   static constexpr uint8_t ESTIMATED_SIZE = 0; | ||||
| #ifdef HAS_PROTO_MESSAGE_DUMP | ||||
|   const char *message_name() const override { return "voice_assistant_configuration_request"; } | ||||
| #endif | ||||
|   std::string id{}; | ||||
|   std::string wake_word{}; | ||||
|   std::vector<std::string> trained_languages{}; | ||||
|   std::string model_type{}; | ||||
|   uint32_t model_size{0}; | ||||
|   std::string model_hash{}; | ||||
|   std::string url{}; | ||||
| #ifdef HAS_PROTO_MESSAGE_DUMP | ||||
|   void dump_to(std::string &out) const override; | ||||
| #endif | ||||
|  | ||||
|  protected: | ||||
|   bool decode_length(uint32_t field_id, ProtoLengthDelimited value) override; | ||||
|   bool decode_varint(uint32_t field_id, ProtoVarInt value) override; | ||||
| }; | ||||
| class VoiceAssistantConfigurationRequest final : public ProtoDecodableMessage { | ||||
|  public: | ||||
|   static constexpr uint8_t MESSAGE_TYPE = 121; | ||||
|   static constexpr uint8_t ESTIMATED_SIZE = 34; | ||||
| #ifdef HAS_PROTO_MESSAGE_DUMP | ||||
|   const char *message_name() const override { return "voice_assistant_configuration_request"; } | ||||
| #endif | ||||
|   std::vector<VoiceAssistantExternalWakeWord> external_wake_words{}; | ||||
| #ifdef HAS_PROTO_MESSAGE_DUMP | ||||
|   void dump_to(std::string &out) const override; | ||||
| #endif | ||||
|  | ||||
|  protected: | ||||
|   bool decode_length(uint32_t field_id, ProtoLengthDelimited value) override; | ||||
| }; | ||||
| class VoiceAssistantConfigurationResponse final : public ProtoMessage { | ||||
|  public: | ||||
|   | ||||
| @@ -1824,8 +1824,25 @@ void VoiceAssistantWakeWord::dump_to(std::string &out) const { | ||||
|     dump_field(out, "trained_languages", it, 4); | ||||
|   } | ||||
| } | ||||
| void VoiceAssistantExternalWakeWord::dump_to(std::string &out) const { | ||||
|   MessageDumpHelper helper(out, "VoiceAssistantExternalWakeWord"); | ||||
|   dump_field(out, "id", this->id); | ||||
|   dump_field(out, "wake_word", this->wake_word); | ||||
|   for (const auto &it : this->trained_languages) { | ||||
|     dump_field(out, "trained_languages", it, 4); | ||||
|   } | ||||
|   dump_field(out, "model_type", this->model_type); | ||||
|   dump_field(out, "model_size", this->model_size); | ||||
|   dump_field(out, "model_hash", this->model_hash); | ||||
|   dump_field(out, "url", this->url); | ||||
| } | ||||
| void VoiceAssistantConfigurationRequest::dump_to(std::string &out) const { | ||||
|   out.append("VoiceAssistantConfigurationRequest {}"); | ||||
|   MessageDumpHelper helper(out, "VoiceAssistantConfigurationRequest"); | ||||
|   for (const auto &it : this->external_wake_words) { | ||||
|     out.append("  external_wake_words: "); | ||||
|     it.dump_to(out); | ||||
|     out.append("\n"); | ||||
|   } | ||||
| } | ||||
| void VoiceAssistantConfigurationResponse::dump_to(std::string &out) const { | ||||
|   MessageDumpHelper helper(out, "VoiceAssistantConfigurationResponse"); | ||||
|   | ||||
| @@ -548,7 +548,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type, | ||||
| #ifdef USE_VOICE_ASSISTANT | ||||
|     case VoiceAssistantConfigurationRequest::MESSAGE_TYPE: { | ||||
|       VoiceAssistantConfigurationRequest msg; | ||||
|       // Empty message: no decode needed | ||||
|       msg.decode(msg_data, msg_size); | ||||
| #ifdef HAS_PROTO_MESSAGE_DUMP | ||||
|       ESP_LOGVV(TAG, "on_voice_assistant_configuration_request: %s", msg.dump().c_str()); | ||||
| #endif | ||||
|   | ||||
| @@ -12,7 +12,7 @@ platformio==6.1.18  # When updating platformio, also update /docker/Dockerfile | ||||
| esptool==5.1.0 | ||||
| click==8.1.7 | ||||
| esphome-dashboard==20250904.0 | ||||
| aioesphomeapi==41.9.1 | ||||
| aioesphomeapi==41.10.0 | ||||
| zeroconf==0.147.2 | ||||
| puremagic==1.30 | ||||
| ruamel.yaml==0.18.15 # dashboard_import | ||||
|   | ||||
		Reference in New Issue
	
	Block a user