tjbot-ce 3.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- tjbot/__init__.py +29 -0
- tjbot/camera/__init__.py +17 -0
- tjbot/camera/camera.py +168 -0
- tjbot/config/__init__.py +49 -0
- tjbot/config/config_types.py +251 -0
- tjbot/config/tjbot_config.py +357 -0
- tjbot/config/vendor/model-registry.yaml +275 -0
- tjbot/config/vendor/tjbot-config.schema.yaml +792 -0
- tjbot/config/vendor/tjbot.default.toml +452 -0
- tjbot/led/__init__.py +19 -0
- tjbot/led/led_common_anode.py +47 -0
- tjbot/led/led_neopixel.py +248 -0
- tjbot/led/led_neopixel_spi.py +107 -0
- tjbot/led/led_neopixel_ws281x.py +156 -0
- tjbot/microphone/__init__.py +17 -0
- tjbot/microphone/microphone.py +263 -0
- tjbot/rpi_drivers/__init__.py +28 -0
- tjbot/rpi_drivers/rpi3_driver.py +170 -0
- tjbot/rpi_drivers/rpi4_driver.py +108 -0
- tjbot/rpi_drivers/rpi5_driver.py +97 -0
- tjbot/rpi_drivers/rpi_detect.py +56 -0
- tjbot/rpi_drivers/rpi_driver.py +430 -0
- tjbot/servo/__init__.py +24 -0
- tjbot/servo/servo_constants.py +26 -0
- tjbot/servo/servo_lgpio.py +152 -0
- tjbot/speaker/__init__.py +18 -0
- tjbot/speaker/audio_player.py +45 -0
- tjbot/speaker/speaker.py +123 -0
- tjbot/stt/__init__.py +27 -0
- tjbot/stt/backends/__init__.py +25 -0
- tjbot/stt/backends/azure_stt.py +351 -0
- tjbot/stt/backends/google_cloud_stt.py +357 -0
- tjbot/stt/backends/sherpa_onnx_stt.py +490 -0
- tjbot/stt/backends/watson_stt.py +339 -0
- tjbot/stt/stt.py +112 -0
- tjbot/stt/stt_engine.py +138 -0
- tjbot/stt/stt_utils.py +155 -0
- tjbot/tjbot.py +723 -0
- tjbot/tts/__init__.py +18 -0
- tjbot/tts/backends/__init__.py +25 -0
- tjbot/tts/backends/azure_tts.py +121 -0
- tjbot/tts/backends/google_cloud_tts.py +147 -0
- tjbot/tts/backends/ibm_watson_tts.py +99 -0
- tjbot/tts/backends/sherpa_onnx_tts.py +164 -0
- tjbot/tts/tts.py +74 -0
- tjbot/tts/tts_engine.py +87 -0
- tjbot/utils/__init__.py +51 -0
- tjbot/utils/colors.py +147 -0
- tjbot/utils/colors.yaml +47 -0
- tjbot/utils/constants.py +31 -0
- tjbot/utils/credentials.py +95 -0
- tjbot/utils/errors.py +35 -0
- tjbot/utils/logging.py +115 -0
- tjbot/utils/model_registry.py +317 -0
- tjbot/utils/sherpa_runtime.py +65 -0
- tjbot/utils/utils.py +42 -0
- tjbot/vision/__init__.py +37 -0
- tjbot/vision/backends/__init__.py +19 -0
- tjbot/vision/backends/azure_vision.py +169 -0
- tjbot/vision/backends/google_cloud_vision.py +248 -0
- tjbot/vision/backends/onnx.py +736 -0
- tjbot/vision/vision.py +70 -0
- tjbot/vision/vision_engine.py +195 -0
- tjbot_ce-3.0.0.dist-info/METADATA +422 -0
- tjbot_ce-3.0.0.dist-info/RECORD +67 -0
- tjbot_ce-3.0.0.dist-info/WHEEL +4 -0
- tjbot_ce-3.0.0.dist-info/licenses/LICENSE +201 -0
tjbot/__init__.py
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Copyright 2026-present TJBot Contributors. All Rights Reserved.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
from typing import TYPE_CHECKING
|
|
16
|
+
|
|
17
|
+
if TYPE_CHECKING:
|
|
18
|
+
from .tjbot import TJBot
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def __getattr__(name: str):
|
|
22
|
+
if name == "TJBot":
|
|
23
|
+
from .tjbot import TJBot
|
|
24
|
+
|
|
25
|
+
return TJBot
|
|
26
|
+
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
__all__ = ["TJBot"]
|
tjbot/camera/__init__.py
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Copyright 2026-present TJBot Contributors. All Rights Reserved.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
from .camera import CameraController
|
|
16
|
+
|
|
17
|
+
__all__ = ["CameraController"]
|
tjbot/camera/camera.py
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# Copyright 2026-present TJBot Contributors. All Rights Reserved.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
import os
|
|
16
|
+
import subprocess
|
|
17
|
+
import tempfile
|
|
18
|
+
from typing import Tuple, Optional
|
|
19
|
+
import logging
|
|
20
|
+
from ..utils.errors import TJBotError
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
logger = logging.getLogger(__name__)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class CameraController:
|
|
27
|
+
"""
|
|
28
|
+
TJBot Camera Controller.
|
|
29
|
+
Handles camera initialization and photo capture using rpicam-still.
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
def __init__(self):
|
|
33
|
+
self.resolution: Tuple[int, int] = (1920, 1080)
|
|
34
|
+
self.vertical_flip = False
|
|
35
|
+
self.horizontal_flip = False
|
|
36
|
+
self.capture_timeout = 500
|
|
37
|
+
self.zero_shutter_lag = False
|
|
38
|
+
|
|
39
|
+
def initialize(
|
|
40
|
+
self,
|
|
41
|
+
resolution: Tuple[int, int],
|
|
42
|
+
vertical_flip: bool,
|
|
43
|
+
horizontal_flip: bool,
|
|
44
|
+
capture_timeout: int = 500,
|
|
45
|
+
zero_shutter_lag: bool = False,
|
|
46
|
+
) -> None:
|
|
47
|
+
"""
|
|
48
|
+
Initialize camera settings.
|
|
49
|
+
:param resolution: (width, height) tuple.
|
|
50
|
+
:param vertical_flip: Whether to flip vertically.
|
|
51
|
+
:param horizontal_flip: Whether to flip horizontally.
|
|
52
|
+
"""
|
|
53
|
+
self.resolution = resolution
|
|
54
|
+
self.vertical_flip = vertical_flip
|
|
55
|
+
self.horizontal_flip = horizontal_flip
|
|
56
|
+
self.capture_timeout = capture_timeout
|
|
57
|
+
self.zero_shutter_lag = zero_shutter_lag
|
|
58
|
+
|
|
59
|
+
logger.debug(
|
|
60
|
+
"Initialized camera with config: resolution=%sx%s, vertical_flip=%s, horizontal_flip=%s, capture_timeout=%sms, zero_shutter_lag=%s",
|
|
61
|
+
resolution[0],
|
|
62
|
+
resolution[1],
|
|
63
|
+
vertical_flip,
|
|
64
|
+
horizontal_flip,
|
|
65
|
+
capture_timeout,
|
|
66
|
+
zero_shutter_lag,
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
def build_camera_args(
|
|
70
|
+
self, output_path: str, encoding: Optional[str] = None
|
|
71
|
+
) -> list[str]:
|
|
72
|
+
"""
|
|
73
|
+
Build rpicam-still command arguments.
|
|
74
|
+
:param output_path: Output path or '-' for stdout.
|
|
75
|
+
:param encoding: Optional encoding format (for example 'jpg').
|
|
76
|
+
:return: List of command-line arguments.
|
|
77
|
+
"""
|
|
78
|
+
args = [
|
|
79
|
+
"--output",
|
|
80
|
+
output_path,
|
|
81
|
+
"--width",
|
|
82
|
+
str(self.resolution[0]),
|
|
83
|
+
"--height",
|
|
84
|
+
str(self.resolution[1]),
|
|
85
|
+
"--nopreview",
|
|
86
|
+
"--camera",
|
|
87
|
+
"0",
|
|
88
|
+
]
|
|
89
|
+
|
|
90
|
+
if encoding:
|
|
91
|
+
args.extend(["--encoding", encoding])
|
|
92
|
+
|
|
93
|
+
if self.vertical_flip:
|
|
94
|
+
args.append("--vflip")
|
|
95
|
+
if self.horizontal_flip:
|
|
96
|
+
args.append("--hflip")
|
|
97
|
+
|
|
98
|
+
if self.capture_timeout == 0:
|
|
99
|
+
args.append("--immediate")
|
|
100
|
+
else:
|
|
101
|
+
args.extend(["--timeout", str(self.capture_timeout)])
|
|
102
|
+
|
|
103
|
+
if self.zero_shutter_lag:
|
|
104
|
+
args.append("--zsl")
|
|
105
|
+
|
|
106
|
+
logger.debug("Built camera args: %s", " ".join(args))
|
|
107
|
+
return args
|
|
108
|
+
|
|
109
|
+
def capture_photo(self, at_path: Optional[str] = None) -> str:
|
|
110
|
+
"""
|
|
111
|
+
Capture a photo by invoking rpicam-still.
|
|
112
|
+
:param at_path: Optional path to save the photo. If None, a temporary file will be used.
|
|
113
|
+
:return: Path to the saved photo.
|
|
114
|
+
"""
|
|
115
|
+
if not at_path:
|
|
116
|
+
fd, at_path = tempfile.mkstemp(prefix="tjbot", suffix=".jpg")
|
|
117
|
+
os.close(fd)
|
|
118
|
+
|
|
119
|
+
logger.info("Capturing image at path: %s", at_path)
|
|
120
|
+
cmd = ["rpicam-still", *self.build_camera_args(at_path)]
|
|
121
|
+
|
|
122
|
+
try:
|
|
123
|
+
result = subprocess.run(
|
|
124
|
+
cmd,
|
|
125
|
+
check=True,
|
|
126
|
+
stdout=subprocess.PIPE,
|
|
127
|
+
stderr=subprocess.PIPE,
|
|
128
|
+
)
|
|
129
|
+
logger.debug(
|
|
130
|
+
"rpicam-still stdout: %s", result.stdout.decode(errors="replace")
|
|
131
|
+
)
|
|
132
|
+
return at_path
|
|
133
|
+
except (subprocess.CalledProcessError, FileNotFoundError) as err:
|
|
134
|
+
stderr = ""
|
|
135
|
+
if isinstance(err, subprocess.CalledProcessError):
|
|
136
|
+
stderr = (err.stderr or b"").decode(errors="replace")
|
|
137
|
+
message = stderr or str(err)
|
|
138
|
+
logger.error("rpicam-still error: %s", message)
|
|
139
|
+
raise TJBotError(message) from err
|
|
140
|
+
|
|
141
|
+
def capture_photo_buffer(self) -> bytes:
|
|
142
|
+
"""
|
|
143
|
+
Capture a photo and return it as bytes.
|
|
144
|
+
:return: Photo bytes.
|
|
145
|
+
"""
|
|
146
|
+
logger.info("Capturing image to buffer")
|
|
147
|
+
cmd = ["rpicam-still", *self.build_camera_args("-", "jpg")]
|
|
148
|
+
|
|
149
|
+
try:
|
|
150
|
+
result = subprocess.run(
|
|
151
|
+
cmd,
|
|
152
|
+
check=True,
|
|
153
|
+
stdout=subprocess.PIPE,
|
|
154
|
+
stderr=subprocess.PIPE,
|
|
155
|
+
)
|
|
156
|
+
logger.debug("Captured image buffer (%s bytes)", len(result.stdout))
|
|
157
|
+
return result.stdout
|
|
158
|
+
except (subprocess.CalledProcessError, FileNotFoundError) as err:
|
|
159
|
+
stderr = ""
|
|
160
|
+
if isinstance(err, subprocess.CalledProcessError):
|
|
161
|
+
stderr = (err.stderr or b"").decode(errors="replace")
|
|
162
|
+
message = stderr or str(err)
|
|
163
|
+
logger.error("rpicam-still error: %s", message)
|
|
164
|
+
raise TJBotError(message) from err
|
|
165
|
+
|
|
166
|
+
def cleanup(self) -> None:
|
|
167
|
+
"""Clean up resources (no-op for direct process invocation)."""
|
|
168
|
+
logger.debug("CameraController cleanup (no-op for rpicam-still)")
|
tjbot/config/__init__.py
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Copyright 2026-present TJBot Contributors. All Rights Reserved.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
from .config_types import (
|
|
16
|
+
TJBotConfigSchema,
|
|
17
|
+
LogConfig,
|
|
18
|
+
HardwareConfig,
|
|
19
|
+
ListenConfig,
|
|
20
|
+
SeeConfig,
|
|
21
|
+
SeeBackendConfig,
|
|
22
|
+
SeeBackendLocalConfig,
|
|
23
|
+
SeeBackendGoogleCloudConfig,
|
|
24
|
+
SeeBackendAzureConfig,
|
|
25
|
+
ShineConfig,
|
|
26
|
+
SpeakConfig,
|
|
27
|
+
WaveConfig,
|
|
28
|
+
STTBackendConfig,
|
|
29
|
+
TTSBackendConfig,
|
|
30
|
+
)
|
|
31
|
+
from .tjbot_config import TJBotConfig
|
|
32
|
+
|
|
33
|
+
__all__ = [
|
|
34
|
+
"TJBotConfig",
|
|
35
|
+
"TJBotConfigSchema",
|
|
36
|
+
"LogConfig",
|
|
37
|
+
"HardwareConfig",
|
|
38
|
+
"ListenConfig",
|
|
39
|
+
"SeeConfig",
|
|
40
|
+
"SeeBackendConfig",
|
|
41
|
+
"SeeBackendLocalConfig",
|
|
42
|
+
"SeeBackendGoogleCloudConfig",
|
|
43
|
+
"SeeBackendAzureConfig",
|
|
44
|
+
"ShineConfig",
|
|
45
|
+
"SpeakConfig",
|
|
46
|
+
"WaveConfig",
|
|
47
|
+
"STTBackendConfig",
|
|
48
|
+
"TTSBackendConfig",
|
|
49
|
+
]
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
# Copyright 2026-present TJBot Contributors. All Rights Reserved.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
from typing import Any, Dict, List, Literal, Optional, Tuple
|
|
16
|
+
|
|
17
|
+
from pydantic import BaseModel, ConfigDict, Field
|
|
18
|
+
from ..utils.logging import TJBotLogLevel
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class TJBotBaseModel(BaseModel):
|
|
22
|
+
model_config = ConfigDict(populate_by_name=True)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class LogConfig(TJBotBaseModel):
|
|
26
|
+
level: Optional[TJBotLogLevel] = "info"
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class VADConfig(TJBotBaseModel):
|
|
30
|
+
enabled: Optional[bool] = True
|
|
31
|
+
model: Optional[str] = None
|
|
32
|
+
model_url: Optional[str] = Field(default=None, alias="modelUrl")
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class STTBackendLocalConfig(TJBotBaseModel):
|
|
36
|
+
model: Optional[str] = None
|
|
37
|
+
model_url: Optional[str] = Field(default=None, alias="modelUrl")
|
|
38
|
+
vad: Optional[VADConfig] = None
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class STTBackendIBMWatsonConfig(TJBotBaseModel):
|
|
42
|
+
model: Optional[str] = None
|
|
43
|
+
inactivity_timeout: Optional[int] = Field(default=None, alias="inactivityTimeout")
|
|
44
|
+
background_audio_suppression: Optional[float] = Field(
|
|
45
|
+
default=None, alias="backgroundAudioSuppression"
|
|
46
|
+
)
|
|
47
|
+
interim_results: Optional[bool] = Field(default=None, alias="interimResults")
|
|
48
|
+
credentials_path: Optional[str] = Field(default=None, alias="credentialsPath")
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class STTBackendGoogleCloudConfig(TJBotBaseModel):
|
|
52
|
+
model: Optional[str] = None
|
|
53
|
+
language_code: Optional[str] = Field(default=None, alias="languageCode")
|
|
54
|
+
credentials_path: Optional[str] = Field(default=None, alias="credentialsPath")
|
|
55
|
+
encoding: Optional[str] = None
|
|
56
|
+
sample_rate_hertz: Optional[int] = Field(default=None, alias="sampleRateHertz")
|
|
57
|
+
audio_channel_count: Optional[int] = Field(default=None, alias="audioChannelCount")
|
|
58
|
+
enable_automatic_punctuation: Optional[bool] = Field(
|
|
59
|
+
default=None, alias="enableAutomaticPunctuation"
|
|
60
|
+
)
|
|
61
|
+
interim_results: Optional[bool] = Field(default=None, alias="interimResults")
|
|
62
|
+
region: Optional[str] = None
|
|
63
|
+
profanity_filter: Optional[bool] = Field(default=None, alias="profanityFilter")
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class STTBackendAzureConfig(TJBotBaseModel):
|
|
67
|
+
language: Optional[str] = None
|
|
68
|
+
credentials_path: Optional[str] = Field(default=None, alias="credentialsPath")
|
|
69
|
+
interim_results: Optional[bool] = Field(default=None, alias="interimResults")
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
class STTBackendConfig(TJBotBaseModel):
|
|
73
|
+
type: Optional[
|
|
74
|
+
Literal["none", "local", "ibm-watson-stt", "google-cloud-stt", "azure-stt"]
|
|
75
|
+
] = "local"
|
|
76
|
+
local: Optional[STTBackendLocalConfig] = None
|
|
77
|
+
ibm_watson_stt: Optional[STTBackendIBMWatsonConfig] = Field(
|
|
78
|
+
default=None, alias="ibm-watson-stt"
|
|
79
|
+
)
|
|
80
|
+
google_cloud_stt: Optional[STTBackendGoogleCloudConfig] = Field(
|
|
81
|
+
default=None, alias="google-cloud-stt"
|
|
82
|
+
)
|
|
83
|
+
azure_stt: Optional[STTBackendAzureConfig] = Field(default=None, alias="azure-stt")
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
class ListenConfig(TJBotBaseModel):
|
|
87
|
+
device: Optional[str] = None
|
|
88
|
+
microphone_rate: Optional[int] = Field(default=44100, alias="microphoneRate")
|
|
89
|
+
microphone_channels: Optional[int] = Field(default=2, alias="microphoneChannels")
|
|
90
|
+
model: Optional[str] = None
|
|
91
|
+
backend: Optional[STTBackendConfig] = None
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
class SeeBackendLocalConfig(TJBotBaseModel):
|
|
95
|
+
object_detection_model: Optional[str] = Field(
|
|
96
|
+
default=None, alias="objectDetectionModel"
|
|
97
|
+
)
|
|
98
|
+
image_classification_model: Optional[str] = Field(
|
|
99
|
+
default=None, alias="imageClassificationModel"
|
|
100
|
+
)
|
|
101
|
+
face_detection_model: Optional[str] = Field(
|
|
102
|
+
default=None, alias="faceDetectionModel"
|
|
103
|
+
)
|
|
104
|
+
object_detection_confidence: Optional[float] = Field(
|
|
105
|
+
default=None, alias="objectDetectionConfidence"
|
|
106
|
+
)
|
|
107
|
+
image_classification_confidence: Optional[float] = Field(
|
|
108
|
+
default=None, alias="imageClassificationConfidence"
|
|
109
|
+
)
|
|
110
|
+
face_detection_confidence: Optional[float] = Field(
|
|
111
|
+
default=None, alias="faceDetectionConfidence"
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
class SeeBackendGoogleCloudConfig(TJBotBaseModel):
|
|
116
|
+
credentials_path: Optional[str] = Field(default=None, alias="credentialsPath")
|
|
117
|
+
object_detection_confidence: Optional[float] = Field(
|
|
118
|
+
default=None, alias="objectDetectionConfidence"
|
|
119
|
+
)
|
|
120
|
+
image_classification_confidence: Optional[float] = Field(
|
|
121
|
+
default=None, alias="imageClassificationConfidence"
|
|
122
|
+
)
|
|
123
|
+
face_detection_confidence: Optional[float] = Field(
|
|
124
|
+
default=None, alias="faceDetectionConfidence"
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
class SeeBackendAzureConfig(TJBotBaseModel):
|
|
129
|
+
credentials_path: Optional[str] = Field(default=None, alias="credentialsPath")
|
|
130
|
+
object_detection_confidence: Optional[float] = Field(
|
|
131
|
+
default=None, alias="objectDetectionConfidence"
|
|
132
|
+
)
|
|
133
|
+
image_classification_confidence: Optional[float] = Field(
|
|
134
|
+
default=None, alias="imageClassificationConfidence"
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
class SeeBackendConfig(TJBotBaseModel):
|
|
139
|
+
type: Optional[Literal["none", "local", "google-cloud-vision", "azure-vision"]] = (
|
|
140
|
+
"none"
|
|
141
|
+
)
|
|
142
|
+
local: Optional[SeeBackendLocalConfig] = None
|
|
143
|
+
google_cloud_vision: Optional[SeeBackendGoogleCloudConfig] = Field(
|
|
144
|
+
default=None, alias="google-cloud-vision"
|
|
145
|
+
)
|
|
146
|
+
azure_vision: Optional[SeeBackendAzureConfig] = Field(
|
|
147
|
+
default=None, alias="azure-vision"
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
class SeeConfig(TJBotBaseModel):
|
|
152
|
+
camera_resolution: Optional[Tuple[int, int]] = Field(
|
|
153
|
+
default=(1920, 1080), alias="cameraResolution"
|
|
154
|
+
)
|
|
155
|
+
vertical_flip: Optional[bool] = Field(default=False, alias="verticalFlip")
|
|
156
|
+
horizontal_flip: Optional[bool] = Field(default=False, alias="horizontalFlip")
|
|
157
|
+
capture_timeout: Optional[int] = Field(default=None, alias="captureTimeout")
|
|
158
|
+
zero_shutter_lag: Optional[bool] = Field(default=None, alias="zeroShutterLag")
|
|
159
|
+
backend: Optional[SeeBackendConfig] = None
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
class LEDNeopixelConfig(TJBotBaseModel):
|
|
163
|
+
gpio_pin: Optional[int] = Field(default=None, alias="gpioPin")
|
|
164
|
+
spi_interface: Optional[str] = Field(default=None, alias="spiInterface")
|
|
165
|
+
use_grb_format: Optional[bool] = Field(default=False, alias="useGRBFormat")
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
class LEDCommonAnodeConfig(TJBotBaseModel):
|
|
169
|
+
red_pin: Optional[int] = Field(default=None, alias="redPin")
|
|
170
|
+
green_pin: Optional[int] = Field(default=None, alias="greenPin")
|
|
171
|
+
blue_pin: Optional[int] = Field(default=None, alias="bluePin")
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
class ShineConfig(TJBotBaseModel):
|
|
175
|
+
has_neopixel_led: Optional[bool] = Field(default=False, alias="hasNeopixelLED")
|
|
176
|
+
has_common_anode_led: Optional[bool] = Field(
|
|
177
|
+
default=False, alias="hasCommonAnodeLED"
|
|
178
|
+
)
|
|
179
|
+
neopixel: Optional[LEDNeopixelConfig] = None
|
|
180
|
+
common_anode: Optional[LEDCommonAnodeConfig] = Field(
|
|
181
|
+
default=None, alias="commonanode"
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
class TTSBackendLocalConfig(TJBotBaseModel):
|
|
186
|
+
model: Optional[str] = None
|
|
187
|
+
model_url: Optional[str] = Field(default=None, alias="modelUrl")
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
class TTSBackendIBMWatsonConfig(TJBotBaseModel):
|
|
191
|
+
voice: Optional[str] = None
|
|
192
|
+
credentials_path: Optional[str] = Field(default=None, alias="credentialsPath")
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
class TTSBackendGoogleCloudConfig(TJBotBaseModel):
|
|
196
|
+
voice: Optional[str] = None
|
|
197
|
+
language_code: Optional[str] = Field(default=None, alias="languageCode")
|
|
198
|
+
credentials_path: Optional[str] = Field(default=None, alias="credentialsPath")
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
class TTSBackendAzureConfig(TJBotBaseModel):
|
|
202
|
+
voice: Optional[str] = None
|
|
203
|
+
credentials_path: Optional[str] = Field(default=None, alias="credentialsPath")
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
class TTSBackendConfig(TJBotBaseModel):
|
|
207
|
+
type: Optional[
|
|
208
|
+
Literal["none", "local", "ibm-watson-tts", "google-cloud-tts", "azure-tts"]
|
|
209
|
+
] = "local"
|
|
210
|
+
local: Optional[TTSBackendLocalConfig] = None
|
|
211
|
+
ibm_watson_tts: Optional[TTSBackendIBMWatsonConfig] = Field(
|
|
212
|
+
default=None, alias="ibm-watson-tts"
|
|
213
|
+
)
|
|
214
|
+
google_cloud_tts: Optional[TTSBackendGoogleCloudConfig] = Field(
|
|
215
|
+
default=None, alias="google-cloud-tts"
|
|
216
|
+
)
|
|
217
|
+
azure_tts: Optional[TTSBackendAzureConfig] = Field(default=None, alias="azure-tts")
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
class SpeakConfig(TJBotBaseModel):
|
|
221
|
+
device: Optional[str] = None
|
|
222
|
+
backend: Optional[TTSBackendConfig] = None
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
class WaveConfig(TJBotBaseModel):
|
|
226
|
+
gpio_chip: Optional[int] = Field(default=0, alias="gpioChip")
|
|
227
|
+
servo_pin: Optional[int] = Field(default=18, alias="servoPin")
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
class HardwareConfig(TJBotBaseModel):
|
|
231
|
+
speaker: Optional[bool] = False
|
|
232
|
+
microphone: Optional[bool] = False
|
|
233
|
+
led: Optional[bool] = False
|
|
234
|
+
servo: Optional[bool] = False
|
|
235
|
+
camera: Optional[bool] = False
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
STTEngineConfig = Dict[str, Any]
|
|
239
|
+
TTSEngineConfig = Dict[str, Any]
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
class TJBotConfigSchema(TJBotBaseModel):
|
|
243
|
+
log: Optional[LogConfig] = Field(default_factory=LogConfig)
|
|
244
|
+
hardware: Optional[HardwareConfig] = Field(default_factory=HardwareConfig)
|
|
245
|
+
listen: Optional[ListenConfig] = Field(default_factory=ListenConfig)
|
|
246
|
+
see: Optional[SeeConfig] = Field(default_factory=SeeConfig)
|
|
247
|
+
shine: Optional[ShineConfig] = Field(default_factory=ShineConfig)
|
|
248
|
+
speak: Optional[SpeakConfig] = Field(default_factory=SpeakConfig)
|
|
249
|
+
wave: Optional[WaveConfig] = Field(default_factory=WaveConfig)
|
|
250
|
+
recipe: Optional[Dict[str, Any]] = Field(default_factory=dict)
|
|
251
|
+
models: Optional[List[Dict[str, Any]]] = Field(default_factory=list)
|