Bump api version minor, Add VA subscription flags
This commit is contained in:
parent
6435be617d
commit
676c8eb7f2
|
@ -218,7 +218,8 @@ message DeviceInfoResponse {
|
|||
|
||||
string friendly_name = 13;
|
||||
|
||||
uint32 voice_assistant_version = 14;
|
||||
uint32 legacy_voice_assistant_version = 14;
|
||||
uint32 voice_assistant_feature_flags = 17;
|
||||
|
||||
string suggested_area = 16;
|
||||
}
|
||||
|
@ -1448,12 +1449,18 @@ message BluetoothDeviceClearCacheResponse {
|
|||
}
|
||||
|
||||
// ==================== VOICE ASSISTANT ====================
|
||||
enum VoiceAssistantSubscribeFlag {
|
||||
VOICE_ASSISTANT_SUBSCRIBE_NONE = 0;
|
||||
VOICE_ASSISTANT_SUBSCRIBE_API_AUDIO = 1;
|
||||
}
|
||||
|
||||
message SubscribeVoiceAssistantRequest {
|
||||
option (id) = 89;
|
||||
option (source) = SOURCE_CLIENT;
|
||||
option (ifdef) = "USE_VOICE_ASSISTANT";
|
||||
|
||||
bool subscribe = 1;
|
||||
uint32 flags = 2;
|
||||
}
|
||||
|
||||
message VoiceAssistantAudioSettings {
|
||||
|
@ -1521,6 +1528,7 @@ message VoiceAssistantAudio {
|
|||
option (ifdef) = "USE_VOICE_ASSISTANT";
|
||||
|
||||
bytes data = 1;
|
||||
bool end = 2;
|
||||
}
|
||||
|
||||
// ==================== ALARM CONTROL PANEL ====================
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -125,8 +125,10 @@ from .model import (
|
|||
)
|
||||
from .model import VoiceAssistantAudioSettings as VoiceAssistantAudioSettingsModel
|
||||
from .model import (
|
||||
VoiceAssistantAudioData,
|
||||
VoiceAssistantCommand,
|
||||
VoiceAssistantEventType,
|
||||
VoiceAssistantSubscriptionFlag,
|
||||
message_types_to_names,
|
||||
)
|
||||
from .model_conversions import (
|
||||
|
@ -1227,11 +1229,19 @@ class APIClient:
|
|||
|
||||
def subscribe_voice_assistant(
|
||||
self,
|
||||
*,
|
||||
handle_start: Callable[
|
||||
[str, int, VoiceAssistantAudioSettingsModel, str | None],
|
||||
Coroutine[Any, Any, int | None],
|
||||
],
|
||||
handle_stop: Callable[[], Coroutine[Any, Any, None]],
|
||||
handle_stop: Callable[[], Coroutine[Any, Any, None]] | None = None,
|
||||
handle_audio: (
|
||||
Callable[
|
||||
[bytes],
|
||||
Coroutine[Any, Any, None],
|
||||
]
|
||||
| None
|
||||
) = None,
|
||||
) -> Callable[[], None]:
|
||||
"""Subscribes to voice assistant messages from the device.
|
||||
|
||||
|
@ -1274,20 +1284,43 @@ class APIClient:
|
|||
start_task.add_done_callback(_started)
|
||||
# We hold a reference to the start_task in unsub function
|
||||
# so we don't need to add it to the background tasks.
|
||||
else:
|
||||
elif handle_stop is not None:
|
||||
self._create_background_task(handle_stop())
|
||||
|
||||
connection.send_message(SubscribeVoiceAssistantRequest(subscribe=True))
|
||||
remove_callbacks = []
|
||||
flags = 0
|
||||
if handle_audio is not None:
|
||||
flags |= VoiceAssistantSubscriptionFlag.API_AUDIO
|
||||
|
||||
remove_callback = connection.add_message_callback(
|
||||
_on_voice_assistant_request, (VoiceAssistantRequest,)
|
||||
def _on_voice_assistant_audio(msg: VoiceAssistantRequest) -> None:
|
||||
audio = VoiceAssistantAudioData.from_pb(msg)
|
||||
if audio.end:
|
||||
self._create_background_task(handle_stop())
|
||||
else:
|
||||
self._create_background_task(handle_audio(audio.data))
|
||||
|
||||
remove_callbacks.append(
|
||||
connection.add_message_callback(
|
||||
_on_voice_assistant_audio, (VoiceAssistantAudio,)
|
||||
)
|
||||
)
|
||||
|
||||
connection.send_message(
|
||||
SubscribeVoiceAssistantRequest(subscribe=True, flags=flags)
|
||||
)
|
||||
|
||||
remove_callbacks.append(
|
||||
connection.add_message_callback(
|
||||
_on_voice_assistant_request, (VoiceAssistantRequest,)
|
||||
)
|
||||
)
|
||||
|
||||
def unsub() -> None:
|
||||
nonlocal start_task
|
||||
|
||||
if self._connection is not None:
|
||||
remove_callback()
|
||||
for remove_callback in remove_callbacks:
|
||||
remove_callback()
|
||||
self._connection.send_message(
|
||||
SubscribeVoiceAssistantRequest(subscribe=False)
|
||||
)
|
||||
|
@ -1297,31 +1330,6 @@ class APIClient:
|
|||
|
||||
return unsub
|
||||
|
||||
def subscribe_voice_assistant_audio(
|
||||
self,
|
||||
handle_audio: Callable[
|
||||
[VoiceAssistantAudio],
|
||||
Coroutine[Any, Any, None],
|
||||
],
|
||||
) -> Callable[[], None]:
|
||||
connection = self._get_connection()
|
||||
|
||||
audio_task: asyncio.Task[int | None] | None = None
|
||||
|
||||
def _on_voice_assistant_audio(msg: VoiceAssistantRequest) -> None:
|
||||
nonlocal audio_task
|
||||
|
||||
audio = VoiceAssistantAudio.from_pb(msg)
|
||||
self._create_background_task(handle_audio(audio))
|
||||
|
||||
connection.send_message(SubscribeVoiceAssistantRequest(subscribe=True))
|
||||
|
||||
remove_callback = connection.add_message_callback(
|
||||
_on_voice_assistant_audio, (VoiceAssistantAudio,)
|
||||
)
|
||||
|
||||
return remove_callback
|
||||
|
||||
def _create_background_task(self, coro: Coroutine[Any, Any, None]) -> None:
|
||||
"""Create a background task and add it to the background tasks set."""
|
||||
task = asyncio.create_task(coro)
|
||||
|
@ -1342,6 +1350,10 @@ class APIClient:
|
|||
)
|
||||
self._get_connection().send_message(req)
|
||||
|
||||
def send_voice_assistant_audio(self, data: bytes) -> None:
|
||||
req = VoiceAssistantAudio(data=data)
|
||||
self._get_connection().send_message(req)
|
||||
|
||||
def alarm_control_panel_command(
|
||||
self,
|
||||
key: int,
|
||||
|
|
|
@ -145,7 +145,7 @@ CONNECTION_STATE_CLOSED = ConnectionState.CLOSED
|
|||
def _make_hello_request(client_info: str) -> HelloRequest:
|
||||
"""Make a HelloRequest."""
|
||||
return HelloRequest(
|
||||
client_info=client_info, api_version_major=1, api_version_minor=9
|
||||
client_info=client_info, api_version_major=1, api_version_minor=10
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -120,6 +120,16 @@ class BluetoothProxySubscriptionFlag(enum.IntFlag):
|
|||
RAW_ADVERTISEMENTS = 1 << 0
|
||||
|
||||
|
||||
class VoiceAssistantFeature(enum.IntFlag):
|
||||
VOICE_ASSISTANT = 1 << 0
|
||||
SPEAKER = 1 << 1
|
||||
API_AUDIO = 1 << 2
|
||||
|
||||
|
||||
class VoiceAssistantSubscriptionFlag(enum.IntFlag):
|
||||
API_AUDIO = 1 << 2
|
||||
|
||||
|
||||
@_frozen_dataclass_decorator
|
||||
class DeviceInfo(APIModelBase):
|
||||
uses_password: bool = False
|
||||
|
@ -134,7 +144,8 @@ class DeviceInfo(APIModelBase):
|
|||
project_name: str = ""
|
||||
project_version: str = ""
|
||||
webserver_port: int = 0
|
||||
voice_assistant_version: int = 0
|
||||
legacy_voice_assistant_version: int = 0
|
||||
voice_assistant_feature_flags: int = 0
|
||||
legacy_bluetooth_proxy_version: int = 0
|
||||
bluetooth_proxy_feature_flags: int = 0
|
||||
suggested_area: str = ""
|
||||
|
@ -155,6 +166,16 @@ class DeviceInfo(APIModelBase):
|
|||
return flags
|
||||
return self.bluetooth_proxy_feature_flags
|
||||
|
||||
def voice_assistant_feature_flags_compat(self, api_version: APIVersion) -> int:
|
||||
if api_version < APIVersion(1, 10):
|
||||
flags: int = 0
|
||||
if self.legacy_voice_assistant_version >= 1:
|
||||
flags |= VoiceAssistantFeature.VOICE_ASSISTANT
|
||||
if self.legacy_voice_assistant_version == 2:
|
||||
flags |= VoiceAssistantFeature.SPEAKER
|
||||
return flags
|
||||
return self.voice_assistant_feature_flags
|
||||
|
||||
|
||||
class EntityCategory(APIIntEnum):
|
||||
NONE = 0
|
||||
|
@ -1152,6 +1173,12 @@ class VoiceAssistantCommand(APIModelBase):
|
|||
wake_word_phrase: str = ""
|
||||
|
||||
|
||||
@_frozen_dataclass_decorator
|
||||
class VoiceAssistantAudioData(APIModelBase):
|
||||
data: bytes = field(default_factory=bytes) # pylint: disable=invalid-field-call
|
||||
end: bool = False
|
||||
|
||||
|
||||
class LogLevel(APIIntEnum):
|
||||
LOG_LEVEL_NONE = 0
|
||||
LOG_LEVEL_ERROR = 1
|
||||
|
|
Loading…
Reference in New Issue