tjbot-ce 3.0.1

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.
Files changed (224) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +382 -0
  3. package/dist/camera/camera.d.ts +62 -0
  4. package/dist/camera/camera.d.ts.map +1 -0
  5. package/dist/camera/camera.js +155 -0
  6. package/dist/camera/camera.js.map +1 -0
  7. package/dist/camera/index.d.ts +18 -0
  8. package/dist/camera/index.d.ts.map +1 -0
  9. package/dist/camera/index.js +18 -0
  10. package/dist/camera/index.js.map +1 -0
  11. package/dist/config/config-types.d.ts +75 -0
  12. package/dist/config/config-types.d.ts.map +1 -0
  13. package/dist/config/config-types.generated.d.ts +495 -0
  14. package/dist/config/config-types.generated.d.ts.map +1 -0
  15. package/dist/config/config-types.generated.js +2 -0
  16. package/dist/config/config-types.generated.js.map +1 -0
  17. package/dist/config/config-types.js +175 -0
  18. package/dist/config/config-types.js.map +1 -0
  19. package/dist/config/index.d.ts +20 -0
  20. package/dist/config/index.d.ts.map +1 -0
  21. package/dist/config/index.js +19 -0
  22. package/dist/config/index.js.map +1 -0
  23. package/dist/config/tjbot-config.d.ts +98 -0
  24. package/dist/config/tjbot-config.d.ts.map +1 -0
  25. package/dist/config/tjbot-config.js +309 -0
  26. package/dist/config/tjbot-config.js.map +1 -0
  27. package/dist/config/vendor/colors.yaml +61 -0
  28. package/dist/config/vendor/model-registry.yaml +275 -0
  29. package/dist/config/vendor/tjbot-config.schema.yaml +792 -0
  30. package/dist/config/vendor/tjbot.default.toml +452 -0
  31. package/dist/led/index.d.ts +20 -0
  32. package/dist/led/index.d.ts.map +1 -0
  33. package/dist/led/index.js +20 -0
  34. package/dist/led/index.js.map +1 -0
  35. package/dist/led/led-common-anode.d.ts +38 -0
  36. package/dist/led/led-common-anode.d.ts.map +1 -0
  37. package/dist/led/led-common-anode.js +79 -0
  38. package/dist/led/led-common-anode.js.map +1 -0
  39. package/dist/led/led-neopixel-spi.d.ts +60 -0
  40. package/dist/led/led-neopixel-spi.d.ts.map +1 -0
  41. package/dist/led/led-neopixel-spi.js +216 -0
  42. package/dist/led/led-neopixel-spi.js.map +1 -0
  43. package/dist/led/led-neopixel-ws281x.js +186 -0
  44. package/dist/led/led-neopixel.d.ts +57 -0
  45. package/dist/led/led-neopixel.d.ts.map +1 -0
  46. package/dist/led/led-neopixel.js +235 -0
  47. package/dist/led/led-neopixel.js.map +1 -0
  48. package/dist/microphone/index.d.ts +18 -0
  49. package/dist/microphone/index.d.ts.map +1 -0
  50. package/dist/microphone/index.js +18 -0
  51. package/dist/microphone/index.js.map +1 -0
  52. package/dist/microphone/microphone.d.ts +65 -0
  53. package/dist/microphone/microphone.d.ts.map +1 -0
  54. package/dist/microphone/microphone.js +179 -0
  55. package/dist/microphone/microphone.js.map +1 -0
  56. package/dist/rpi-drivers/index.d.ts +22 -0
  57. package/dist/rpi-drivers/index.d.ts.map +1 -0
  58. package/dist/rpi-drivers/index.js +22 -0
  59. package/dist/rpi-drivers/index.js.map +1 -0
  60. package/dist/rpi-drivers/rpi-detect.d.ts +24 -0
  61. package/dist/rpi-drivers/rpi-detect.d.ts.map +1 -0
  62. package/dist/rpi-drivers/rpi-detect.js +49 -0
  63. package/dist/rpi-drivers/rpi-detect.js.map +1 -0
  64. package/dist/rpi-drivers/rpi-driver.d.ts +116 -0
  65. package/dist/rpi-drivers/rpi-driver.d.ts.map +1 -0
  66. package/dist/rpi-drivers/rpi-driver.js +261 -0
  67. package/dist/rpi-drivers/rpi-driver.js.map +1 -0
  68. package/dist/rpi-drivers/rpi3-driver.d.ts +47 -0
  69. package/dist/rpi-drivers/rpi3-driver.d.ts.map +1 -0
  70. package/dist/rpi-drivers/rpi3-driver.js +145 -0
  71. package/dist/rpi-drivers/rpi3-driver.js.map +1 -0
  72. package/dist/rpi-drivers/rpi4-driver.d.ts +35 -0
  73. package/dist/rpi-drivers/rpi4-driver.d.ts.map +1 -0
  74. package/dist/rpi-drivers/rpi4-driver.js +101 -0
  75. package/dist/rpi-drivers/rpi4-driver.js.map +1 -0
  76. package/dist/rpi-drivers/rpi5-driver.d.ts +33 -0
  77. package/dist/rpi-drivers/rpi5-driver.d.ts.map +1 -0
  78. package/dist/rpi-drivers/rpi5-driver.js +78 -0
  79. package/dist/rpi-drivers/rpi5-driver.js.map +1 -0
  80. package/dist/servo/index.d.ts +19 -0
  81. package/dist/servo/index.d.ts.map +1 -0
  82. package/dist/servo/index.js +19 -0
  83. package/dist/servo/index.js.map +1 -0
  84. package/dist/servo/servo-constants.d.ts +33 -0
  85. package/dist/servo/servo-constants.d.ts.map +1 -0
  86. package/dist/servo/servo-constants.js +34 -0
  87. package/dist/servo/servo-constants.js.map +1 -0
  88. package/dist/servo/servo-lgpio.d.ts +82 -0
  89. package/dist/servo/servo-lgpio.d.ts.map +1 -0
  90. package/dist/servo/servo-lgpio.js +178 -0
  91. package/dist/servo/servo-lgpio.js.map +1 -0
  92. package/dist/speaker/audio-player.d.ts +30 -0
  93. package/dist/speaker/audio-player.d.ts.map +1 -0
  94. package/dist/speaker/audio-player.js +68 -0
  95. package/dist/speaker/audio-player.js.map +1 -0
  96. package/dist/speaker/index.d.ts +18 -0
  97. package/dist/speaker/index.d.ts.map +1 -0
  98. package/dist/speaker/index.js +18 -0
  99. package/dist/speaker/index.js.map +1 -0
  100. package/dist/speaker/speaker.d.ts +53 -0
  101. package/dist/speaker/speaker.d.ts.map +1 -0
  102. package/dist/speaker/speaker.js +125 -0
  103. package/dist/speaker/speaker.js.map +1 -0
  104. package/dist/stt/backends/azure-stt.d.ts +32 -0
  105. package/dist/stt/backends/azure-stt.d.ts.map +1 -0
  106. package/dist/stt/backends/azure-stt.js +227 -0
  107. package/dist/stt/backends/azure-stt.js.map +1 -0
  108. package/dist/stt/backends/google-cloud-stt.d.ts +31 -0
  109. package/dist/stt/backends/google-cloud-stt.d.ts.map +1 -0
  110. package/dist/stt/backends/google-cloud-stt.js +371 -0
  111. package/dist/stt/backends/google-cloud-stt.js.map +1 -0
  112. package/dist/stt/backends/ibm-watson-stt.d.ts +32 -0
  113. package/dist/stt/backends/ibm-watson-stt.d.ts.map +1 -0
  114. package/dist/stt/backends/ibm-watson-stt.js +190 -0
  115. package/dist/stt/backends/ibm-watson-stt.js.map +1 -0
  116. package/dist/stt/backends/sherpa-onnx-stt.d.ts +117 -0
  117. package/dist/stt/backends/sherpa-onnx-stt.d.ts.map +1 -0
  118. package/dist/stt/backends/sherpa-onnx-stt.js +694 -0
  119. package/dist/stt/backends/sherpa-onnx-stt.js.map +1 -0
  120. package/dist/stt/index.d.ts +20 -0
  121. package/dist/stt/index.d.ts.map +1 -0
  122. package/dist/stt/index.js +21 -0
  123. package/dist/stt/index.js.map +1 -0
  124. package/dist/stt/stt-engine.d.ts +68 -0
  125. package/dist/stt/stt-engine.d.ts.map +1 -0
  126. package/dist/stt/stt-engine.js +99 -0
  127. package/dist/stt/stt-engine.js.map +1 -0
  128. package/dist/stt/stt-utils.d.ts +36 -0
  129. package/dist/stt/stt-utils.d.ts.map +1 -0
  130. package/dist/stt/stt-utils.js +112 -0
  131. package/dist/stt/stt-utils.js.map +1 -0
  132. package/dist/stt/stt.d.ts +52 -0
  133. package/dist/stt/stt.d.ts.map +1 -0
  134. package/dist/stt/stt.js +100 -0
  135. package/dist/stt/stt.js.map +1 -0
  136. package/dist/tjbot.d.ts +317 -0
  137. package/dist/tjbot.d.ts.map +1 -0
  138. package/dist/tjbot.js +736 -0
  139. package/dist/tjbot.js.map +1 -0
  140. package/dist/tts/backends/azure-tts.d.ts +30 -0
  141. package/dist/tts/backends/azure-tts.d.ts.map +1 -0
  142. package/dist/tts/backends/azure-tts.js +92 -0
  143. package/dist/tts/backends/azure-tts.js.map +1 -0
  144. package/dist/tts/backends/google-cloud-tts.d.ts +38 -0
  145. package/dist/tts/backends/google-cloud-tts.d.ts.map +1 -0
  146. package/dist/tts/backends/google-cloud-tts.js +116 -0
  147. package/dist/tts/backends/google-cloud-tts.js.map +1 -0
  148. package/dist/tts/backends/ibm-watson-tts.d.ts +42 -0
  149. package/dist/tts/backends/ibm-watson-tts.d.ts.map +1 -0
  150. package/dist/tts/backends/ibm-watson-tts.js +99 -0
  151. package/dist/tts/backends/ibm-watson-tts.js.map +1 -0
  152. package/dist/tts/backends/sherpa-onnx-tts.d.ts +80 -0
  153. package/dist/tts/backends/sherpa-onnx-tts.d.ts.map +1 -0
  154. package/dist/tts/backends/sherpa-onnx-tts.js +237 -0
  155. package/dist/tts/backends/sherpa-onnx-tts.js.map +1 -0
  156. package/dist/tts/index.d.ts +19 -0
  157. package/dist/tts/index.d.ts.map +1 -0
  158. package/dist/tts/index.js +20 -0
  159. package/dist/tts/index.js.map +1 -0
  160. package/dist/tts/tts-engine.d.ts +67 -0
  161. package/dist/tts/tts-engine.d.ts.map +1 -0
  162. package/dist/tts/tts-engine.js +109 -0
  163. package/dist/tts/tts-engine.js.map +1 -0
  164. package/dist/tts/tts.d.ts +47 -0
  165. package/dist/tts/tts.d.ts.map +1 -0
  166. package/dist/tts/tts.js +101 -0
  167. package/dist/tts/tts.js.map +1 -0
  168. package/dist/utils/colors.d.ts +39 -0
  169. package/dist/utils/colors.d.ts.map +1 -0
  170. package/dist/utils/colors.js +155 -0
  171. package/dist/utils/colors.js.map +1 -0
  172. package/dist/utils/constants.d.ts +41 -0
  173. package/dist/utils/constants.d.ts.map +1 -0
  174. package/dist/utils/constants.js +43 -0
  175. package/dist/utils/constants.js.map +1 -0
  176. package/dist/utils/credentials.d.ts +43 -0
  177. package/dist/utils/credentials.d.ts.map +1 -0
  178. package/dist/utils/credentials.js +121 -0
  179. package/dist/utils/credentials.js.map +1 -0
  180. package/dist/utils/errors.d.ts +26 -0
  181. package/dist/utils/errors.d.ts.map +1 -0
  182. package/dist/utils/errors.js +32 -0
  183. package/dist/utils/errors.js.map +1 -0
  184. package/dist/utils/index.d.ts +25 -0
  185. package/dist/utils/index.d.ts.map +1 -0
  186. package/dist/utils/index.js +23 -0
  187. package/dist/utils/index.js.map +1 -0
  188. package/dist/utils/logging.d.ts +44 -0
  189. package/dist/utils/logging.d.ts.map +1 -0
  190. package/dist/utils/logging.js +113 -0
  191. package/dist/utils/logging.js.map +1 -0
  192. package/dist/utils/model-registry.d.ts +142 -0
  193. package/dist/utils/model-registry.d.ts.map +1 -0
  194. package/dist/utils/model-registry.js +391 -0
  195. package/dist/utils/model-registry.js.map +1 -0
  196. package/dist/utils/utils.d.ts +33 -0
  197. package/dist/utils/utils.d.ts.map +1 -0
  198. package/dist/utils/utils.js +50 -0
  199. package/dist/utils/utils.js.map +1 -0
  200. package/dist/vision/backends/azure-vision.d.ts +33 -0
  201. package/dist/vision/backends/azure-vision.d.ts.map +1 -0
  202. package/dist/vision/backends/azure-vision.js +151 -0
  203. package/dist/vision/backends/azure-vision.js.map +1 -0
  204. package/dist/vision/backends/google-cloud-vision.d.ts +32 -0
  205. package/dist/vision/backends/google-cloud-vision.d.ts.map +1 -0
  206. package/dist/vision/backends/google-cloud-vision.js +193 -0
  207. package/dist/vision/backends/google-cloud-vision.js.map +1 -0
  208. package/dist/vision/backends/onnx.d.ts +116 -0
  209. package/dist/vision/backends/onnx.d.ts.map +1 -0
  210. package/dist/vision/backends/onnx.js +781 -0
  211. package/dist/vision/backends/onnx.js.map +1 -0
  212. package/dist/vision/index.d.ts +19 -0
  213. package/dist/vision/index.d.ts.map +1 -0
  214. package/dist/vision/index.js +20 -0
  215. package/dist/vision/index.js.map +1 -0
  216. package/dist/vision/vision-engine.d.ts +131 -0
  217. package/dist/vision/vision-engine.d.ts.map +1 -0
  218. package/dist/vision/vision-engine.js +97 -0
  219. package/dist/vision/vision-engine.js.map +1 -0
  220. package/dist/vision/vision.d.ts +48 -0
  221. package/dist/vision/vision.d.ts.map +1 -0
  222. package/dist/vision/vision.js +83 -0
  223. package/dist/vision/vision.js.map +1 -0
  224. package/package.json +124 -0
@@ -0,0 +1,452 @@
1
+ ################################################################################
2
+ # TJBot Configuration File
3
+ ################################################################################
4
+
5
+ [log]
6
+ # Valid logging levels are 'error', 'warning', 'info', 'verbose', 'debug'
7
+ # Set this to 'error' or 'warning' to reduce log verbosity
8
+ # Set this to 'verbose' or 'debug' to see detailed logs for troubleshooting
9
+ level = 'info'
10
+
11
+ # =============================================================================
12
+ # Hardware Configuration
13
+ # =============================================================================
14
+ # Hardware devices to initialize with TJBot
15
+ # Set to true to enable, false (or omit) to disable
16
+
17
+ [hardware]
18
+ camera = false # Camera for image capture
19
+ led = false # LED (either NeoPixel or Common Anode)
20
+ microphone = false # Microphone for audio input (for STT)
21
+ servo = false # Servo motor for arm/movement
22
+ speaker = false # Speaker for audio playback (including TTS)
23
+
24
+ # =============================================================================
25
+ # Listen
26
+ # =============================================================================
27
+ # Configuration for TJBot's ability to listen and transcribe speech
28
+
29
+ [listen]
30
+ # 'device' specifies the audio device `arecord` will use for audio recording.
31
+ # Leave blank to auto-pick, or run `aplay -l` to list devices.
32
+ device = ''
33
+
34
+ # Microphone sampling rate in Hz (44.1k works; 16k reduces CPU for offline models)
35
+ microphoneRate = 44100
36
+
37
+ # Number of audio channels (1 is typical for mics; 2 also works)
38
+ microphoneChannels = 2
39
+
40
+ [listen.backend]
41
+ # 'type' chooses the STT provider:
42
+ # 'none' -> disable STT
43
+ # 'local' -> on-device Sherpa-ONNX STT
44
+ # 'ibm-watson-stt' -> IBM Cloud STT
45
+ # 'google-cloud-stt' -> Google Cloud STT
46
+ # 'azure-stt' -> Microsoft Azure STT
47
+ type = 'local'
48
+
49
+ [listen.backend.local]
50
+ # DEFAULT MODEL (OFFLINE): Whisper base.en (good accuracy, English-only, ~140MB)
51
+ # See model-registry.yaml for other available models.
52
+ model = 'whisper-base'
53
+
54
+ [listen.backend.local.vad]
55
+ # Voice activity detection (VAD) is used for local OFFLINE models (e.g. whisper, moonshine).
56
+ # When enabled, TJBot uses a VAD model to segment speech and stop on silence.
57
+ # Streaming models (zipformer, paraformer) use built-in endpoint detection instead.
58
+ # We recommend keeping VAD enabled, but you can disable it if desired.
59
+ enabled = true
60
+
61
+ # DEFAULT MODEL: Silero VAD (~350KB)
62
+ # See model-registry.yaml for other available models.
63
+ model = 'silero-vad'
64
+
65
+ [listen.backend.ibm-watson-stt]
66
+ # IBM Watson STT model to use.
67
+ #
68
+ # Full list of IBM Watson STT models:
69
+ # https://cloud.ibm.com/docs/speech-to-text?topic=speech-to-text-models-ng
70
+ model = 'en-US_Multimedia'
71
+
72
+ # 'inactivityTimeout' specifies the number of seconds of silence allowed
73
+ # after which the listening session will automatically end.
74
+ # Set to -1 to disable automatic timeout.
75
+ inactivityTimeout = -1
76
+
77
+ # 'backgroundAudioSuppression' specifies the level of background audio suppression
78
+ # to apply during speech recognition. Ranges from 0.0 to 1.0, where higher values
79
+ # result in more aggressive suppression of background noise.
80
+ backgroundAudioSuppression = 0.4
81
+
82
+ # If true, interim results will be returned during streaming recognition.
83
+ interimResults = false
84
+
85
+ # Path to ibm-credentials.env file containing IBM API credentials
86
+ # If not specified, TJBot will search for the file in this order:
87
+ # 1. Current working directory (./ibm-credentials.env)
88
+ # 2. .tjbot directory (~/.tjbot/ibm-credentials.env)
89
+ credentialsPath = ''
90
+
91
+ [listen.backend.google-cloud-stt]
92
+ # Path to the google-credentials.json file containing Google Cloud API credentials
93
+ # By default, TJBot will search for the file in this order:
94
+ # 1. Current working directory (./google-credentials.json)
95
+ # 2. .tjbot directory (~/.tjbot/google-credentials.json)
96
+ # You only need to set credentialsPath if your credential file is kept elsewhere.
97
+ credentialsPath = ''
98
+
99
+ # Google Cloud Speech-to-Text supports the following models:
100
+ # chirp_3 (supported in regions: us, eu)
101
+ # chirp_2 (supported in regions: us-central1, europe-west4, asia-southeast1)
102
+ # See these pages for more information:
103
+ # https://docs.cloud.google.com/speech-to-text/docs/models/chirp-3
104
+ # https://docs.cloud.google.com/speech-to-text/docs/models/chirp-2
105
+ model = 'chirp_3'
106
+
107
+ # The region in which the STT service operates. It must match a region supported
108
+ # by the model.
109
+ region = 'us'
110
+
111
+ # Google Cloud Speech-to-Text language code (e.g., 'en-US', 'en-GB', 'fr-FR')
112
+ languageCode = 'en-US'
113
+
114
+ # If true, automatically add punctuation to transcriptions (e.g., commas, periods).
115
+ enableAutomaticPunctuation = true
116
+
117
+ # If true, Google Cloud Speech-to-Text will attempt to detect profane words
118
+ # and return only the first letter followed by asterisks in the transcript.
119
+ profanityFilter = true
120
+
121
+ # If true, interim results will be returned during streaming recognition.
122
+ interimResults = false
123
+
124
+ [listen.backend.azure-stt]
125
+ # Path to the azure-credentials.env file containing Azure Speech API credentials
126
+ # By default, TJBot will search for the file in this order:
127
+ # 1. Current working directory (./azure-credentials.env)
128
+ # 2. .tjbot directory (~/.tjbot/azure-credentials.env)
129
+ # You only need to set credentialsPath if your credential file is kept elsewhere.
130
+ credentialsPath = ''
131
+
132
+ # Azure Speech-to-Text language code (e.g., 'en-US', 'en-GB', 'fr-FR')
133
+ language = ''
134
+
135
+ # If true, interim results will be returned during streaming recognition.
136
+ interimResults = false
137
+
138
+ # =============================================================================
139
+ # See
140
+ # =============================================================================
141
+ # Configuration for TJBot's ability to see and recognize objects, faces, and text
142
+
143
+ [see]
144
+ # Camera resolution is width x height
145
+ # Common resolutions: [1920, 1080], [1280, 720], [640, 480]
146
+ cameraResolution = [1920, 1080]
147
+
148
+ # If true, flips the camera image vertically
149
+ verticalFlip = false
150
+
151
+ # If true, flips the camera image horizontally
152
+ horizontalFlip = false
153
+
154
+ # Camera capture timeout in milliseconds
155
+ # This controls how long the camera preview runs before capturing the photo.
156
+ # The preview allows auto-exposure and white balance to stabilize.
157
+ # 500 - Fast capture with minimal preview (recommended for responsive behavior)
158
+ # 1000 - 1 second preview (good balance of speed and quality)
159
+ # 5000 - Full 5 second preview (maximum quality, default if not specified)
160
+ # 0 - Immediate capture with no preview (fastest but may have poor exposure)
161
+ captureTimeout = 500
162
+
163
+ # Enable zero shutter lag for faster repeated captures
164
+ # When enabled, the camera streams continuously in the background so captures
165
+ # use recent frames that are already properly exposed. Best for taking multiple
166
+ # photos in quick succession.
167
+ zeroShutterLag = false
168
+
169
+ [see.backend]
170
+ # 'type' chooses the CV provider:
171
+ # 'none' -> disable computer vision
172
+ # 'local' -> on-device ONNX (OFFLINE)
173
+ # 'google-cloud-vision' -> Google Cloud Vision (CLOUD)
174
+ # 'azure-vision' -> Microsoft Azure Vision (CLOUD)
175
+ type = 'local'
176
+
177
+ [see.backend.local]
178
+ # DEFAULT MODELS (OFFLINE): Specialized quantized models for each vision task
179
+ # All models are downloaded and cached automatically when using local backend
180
+ # See model-registry.yaml for available models for each task
181
+ objectDetectionModel = 'ssd-mobilenet-v2'
182
+ imageClassificationModel = 'mobilenetv3'
183
+ faceDetectionModel = 'scrfd-2.5g'
184
+
185
+ # Confidence thresholds for filtering results
186
+ # Results with confidence scores below these thresholds will be excluded
187
+ # Valid range: 0.0 to 1.0 (0.5 = 50% confidence)
188
+ # Note: SCRFD confidence is direct model score; 0.5 is a good starting threshold
189
+ objectDetectionConfidence = 0.8
190
+ imageClassificationConfidence = 0.8
191
+ faceDetectionConfidence = 0.5
192
+
193
+ [see.backend.google-cloud-vision]
194
+ # Path to the google-credentials.json file containing Google Cloud Vision API credentials
195
+ # By default, TJBot will search for the file in this order:
196
+ # 1. Current working directory (./google-credentials.json)
197
+ # 2. .tjbot directory (~/.tjbot/google-credentials.json)
198
+ # You only need to set credentialsPath if your credential file is kept elsewhere.
199
+ credentialsPath = ''
200
+
201
+ # Confidence thresholds for filtering cloud results client-side after API response
202
+ # Valid range: 0.0 to 1.0
203
+ objectDetectionConfidence = 0.8
204
+ imageClassificationConfidence = 0.8
205
+ faceDetectionConfidence = 0.5
206
+
207
+ [see.backend.azure-vision]
208
+ # Path to the azure-credentials.env file containing Azure Vision API credentials
209
+ # By default, TJBot will search for the file in this order:
210
+ # 1. Current working directory (./azure-credentials.env)
211
+ # 2. .tjbot directory (~/.tjbot/azure-credentials.env)
212
+ # You only need to set credentialsPath if your credential file is kept elsewhere.
213
+ credentialsPath = ''
214
+
215
+ # Confidence thresholds for filtering cloud results client-side after API response
216
+ # Valid range: 0.0 to 1.0
217
+ objectDetectionConfidence = 0.8
218
+ imageClassificationConfidence = 0.8
219
+
220
+ # =============================================================================
221
+ # Shine
222
+ # =============================================================================
223
+ # Configuration for TJBot's ability to shine its LED
224
+
225
+ [shine]
226
+ hasNeopixelLED = false # set to true if your TJBot has a NeoPixel LED
227
+ hasCommonAnodeLED = false # set to true if your TJBot has a Common Anode LED
228
+
229
+ [shine.neopixel]
230
+ # NeoPixel LED Pin Configuration
231
+ #
232
+ # Note: Configuration parameters are model-specific. Each Raspberry Pi driver uses
233
+ # only the parameters relevant to its hardware:
234
+ # - Raspberry Pi 3 & 4: Uses 'gpioPin' (PWM-based NeoPixel control)
235
+ # - Raspberry Pi 5: Uses 'spiInterface' (SPI-based NeoPixel control)
236
+ #
237
+ # Recommended pin set with default TJBot servo pin:
238
+ # - RPi 3/4: NeoPixel on GPIO21, servo on GPIO18
239
+ # - RPi 5: NeoPixel via SPI MOSI (GPIO10), servo on GPIO18
240
+
241
+ # ====== FOR RASPBERRY PI 3 & 4: GPIO PIN ======
242
+ # Available pins: GPIO10, GPIO12, GPIO18, GPIO21
243
+ #
244
+ # GPIO21 is the recommended default when servoPin = 18.
245
+ # This avoids putting both NeoPixel and servo on the same GPIO.
246
+ #
247
+ # GPIO18 also works but requires disabling audio:
248
+ # 1. Edit /boot/config.txt
249
+ # 2. Change: dtparam=audio=on
250
+ # 3. To: dtparam=audio=off
251
+ # 4. Reboot your Pi
252
+ # If you choose gpioPin = 18 for NeoPixel, move servoPin to a different GPIO.
253
+ gpioPin = 21 # GPIO21 / Physical pin 40 (RPi3/4 only)
254
+
255
+ # ====== FOR RASPBERRY PI 5: SPI INTERFACE ======
256
+ # Raspberry Pi 5 uses the Serial Peripheral Interface (SPI) for NeoPixel control.
257
+ # Enable SPI in /boot/firmware/config.txt using:
258
+ # dtparam=spi=on
259
+ # Then reboot your Raspberry Pi for the change to take effect.
260
+ #
261
+ # NeoPixel data is sent on SPI MOSI (GPIO10 / physical pin 19).
262
+ # GPIO8 is SPI chip-select (CE0), not NeoPixel data, and should not be used as
263
+ # the LED data pin.
264
+ #
265
+ # The SPI interface is exposed via the /dev filesystem, and is
266
+ # commonly located at /dev/spidev0.0.
267
+ spiInterface = "/dev/spidev0.0"
268
+
269
+ # Use GRB format for NeoPixel colors. Change this to 'false' if your LED shines
270
+ # green when it is supposed to shine red.
271
+ useGRBFormat = true
272
+
273
+ [shine.commonanode]
274
+ # Common Anode LEDs are connected with three GPIO pins for red, green, and blue.
275
+ redPin = 19 # GPIO19 / Physical pin 35
276
+ greenPin = 13 # GPIO13 / Physical pin 33
277
+ bluePin = 12 # GPIO12 / Physical pin 32
278
+
279
+ # =============================================================================
280
+ # Speak
281
+ # =============================================================================
282
+ # Configuration for TJBot's ability to speak using text-to-speech synthesis
283
+
284
+ [speak]
285
+ # 'device' specifies the audio device `aplay` will use for audio playback
286
+ # in most cases, leaving this blank should just work. if you have difficulty
287
+ # with audio playback, please refer to the TJBot wiki:
288
+ # https://github.com/ibmtjbot/tjbot/wiki/Troubleshooting-TJBot#audio-issues
289
+ # also, you can use `aplay -l` to list available audio output devices
290
+ device = ''
291
+
292
+ [speak.backend]
293
+ # 'type' chooses the TTS provider:
294
+ # 'none' -> disable TTS
295
+ # 'local' -> on-device Sherpa-ONNX TTS
296
+ # 'ibm-watson-tts' -> IBM Cloud TTS
297
+ # 'google-cloud-tts' -> Google Cloud TTS
298
+ # 'azure-tts' -> Microsoft Azure TTS
299
+ type = 'local'
300
+
301
+ [speak.backend.local]
302
+ # DEFAULT MODEL: VITS Piper en_US Ryan medium
303
+ # See model-registry.yaml for other available models.
304
+ model = 'vits-piper-en_US-ryan-medium'
305
+
306
+ [speak.backend.ibm-watson-tts]
307
+ # Path to the ibm-credentials.env file containing IBM Cloud Watson API credentials
308
+ # By default, TJBot will search for the file in this order:
309
+ # 1. Current working directory (./ibm-credentials.env)
310
+ # 2. .tjbot directory (~/.tjbot/ibm-credentials.env)
311
+ # You only need to set credentialsPath if your credential file is kept elsewhere.
312
+ credentialsPath = ''
313
+
314
+ # 'voice' specifies the IBM Watson Text-to-Speech voice to use.
315
+ # Available IBM voices include:
316
+ # en-US_AllisonExpressive
317
+ # en-US_AllisonV3Voice
318
+ # en-US_EllieNatural
319
+ # en-US_EmilyV3Voice
320
+ # en-US_EmmaExpressive
321
+ # en-US_EmmaNatural
322
+ # en-US_EthanNatural
323
+ # en-US_HenryV3Voice
324
+ # en-US_JacksonNatural
325
+ # en-US_KevinV3Voice
326
+ # en-US_LisaExpressive
327
+ # en-US_LisaV3Voice
328
+ # en-US_MichaelExpressive
329
+ # en-US_MichaelV3Voice
330
+ # en-US_OliviaV3Voice
331
+ # en-US_VictoriaNatural
332
+ # For a complete list of available voices, see:
333
+ # https://cloud.ibm.com/docs/text-to-speech?topic=text-to-speech-voices
334
+ voice = 'en-US_MichaelV3Voice'
335
+
336
+ [speak.backend.google-cloud-tts]
337
+ # Path to the google-credentials.json file containing Google Cloud API credentials
338
+ # By default, TJBot will search for the file in this order:
339
+ # 1. Current working directory (./google-credentials.json)
340
+ # 2. .tjbot directory (~/.tjbot/google-credentials.json)
341
+ # You only need to set credentialsPath if your credential file is kept elsewhere.
342
+ credentialsPath = ''
343
+
344
+ # Google Cloud TTS voice name
345
+ # Examples:
346
+ # en-US-Neural2-A
347
+ # en-US-Neural2-C
348
+ # en-US-Neural2-D
349
+ # en-US-Neural2-E
350
+ # en-US-Neural2-F
351
+ # en-US-Neural2-G
352
+ # en-US-Neural2-H
353
+ # en-US-Neural2-I
354
+ # en-US-Neural2-J
355
+ # en-US-Studio-O
356
+ # en-US-Studio-Q
357
+ # For a complete list of available voices, see:
358
+ # https://docs.cloud.google.com/text-to-speech/docs/list-voices-and-types
359
+ voice = 'en-US-Neural2-C'
360
+
361
+ # Google Cloud language code (e.g., 'en-US', 'en-GB', 'fr-FR')
362
+ # This should match the locale prefix of the voice specified above (e.g., 'en-US' for 'en-US-Neural2-A').
363
+ languageCode = 'en-US'
364
+
365
+ [speak.backend.azure-tts]
366
+ # Path to the azure-credentials.env file containing Azure Speech API credentials
367
+ # By default, TJBot will search for the file in this order:
368
+ # 1. Current working directory (./azure-credentials.env)
369
+ # 2. .tjbot directory (~/.tjbot/azure-credentials.env)
370
+ # You only need to set credentialsPath if your credential file is kept elsewhere.
371
+ credentialsPath = ''
372
+
373
+ # Azure TTS voice name
374
+ # Examples:
375
+ # en-US-AmberNeural
376
+ # en-US-AndrewNeural
377
+ # en-US-AriaNeural
378
+ # en-US-AshleyNeural
379
+ # en-US-AvaNeural
380
+ # en-US-BrianNeural
381
+ # en-US-DavisNeural
382
+ # en-US-EmmaNeural
383
+ # en-US-GuyNeural
384
+ # en-US-JennyNeural
385
+ # en-US-RogerNeural
386
+ # en-US-SteffanNeural
387
+ # For a complete list of available voices, see:
388
+ # https://learn.microsoft.com/azure/ai-services/speech-service/language-support?tabs=tts
389
+ voice = 'en-US-EmmaNeural'
390
+
391
+ # =============================================================================
392
+ # Wave
393
+ # =============================================================================
394
+ # Configuration for TJBot's ability to wave its arm using a servo motor
395
+
396
+ [wave]
397
+ # The GPIO pin number for controlling a servo motor connected to TJBot's arm.
398
+ # Recommended default across RPi 3/4/5 is GPIO18.
399
+ # If NeoPixel on RPi 3/4 is also assigned to GPIO18, change one of them.
400
+ servoPin = 18 # GPIO18 / Physical Pin 12
401
+
402
+ # ============================================================================
403
+ # On-Device ML Models
404
+ # ============================================================================
405
+ # TJBot supports on-device ML models for speech and vision tasks using the
406
+ # sherpa-onnx runtime (speech) and onnx runtime (vision). Several models are
407
+ # available by default, defined in the model registry (model-registry.yaml).
408
+ # You can also register additional models here. Models must be in the ONNX
409
+ # format and compatible with the sherpa-onnx or onnx runtimes.
410
+ #
411
+ # On-device models are registered in the [[models]] array. Each model entry
412
+ # includes:
413
+ # type -> Model type (e.g., 'stt', 'tts', 'vad',
414
+ # 'vision.object-recognition')
415
+ # key -> Unique model identifier (e.g., 'sherpa-onnx-whisper-base.en')
416
+ # label -> Human-readable name for the model
417
+ # url -> URL to download the model files (can be file:// for local
418
+ # files)
419
+ # folder -> Folder name to store the model files locally
420
+ # kind -> Model architecture:
421
+ # STT: 'offline', 'offline-whisper', 'streaming-zipformer',
422
+ # 'streaming'
423
+ # TTS: 'vits-piper'
424
+ # Vision: 'detection', 'classification', 'face-detection',
425
+ # 'image-description'
426
+ # required -> List of required files for the model (used to validate the
427
+ # model was downloaded correctly)
428
+ # inputShape -> (Vision models only) Expected input tensor shape [batch,
429
+ # channels, height, width]
430
+ # labelUrl -> (Vision models only) URL to download label/class names file
431
+ #
432
+ # Example: Register a custom STT model
433
+ # [[models]]
434
+ # type = 'stt'
435
+ # key = 'my-custom-stt-model'
436
+ # label = 'My Custom STT Model'
437
+ # url = "file:///path/to/my/model.onnx"
438
+ # folder = "my-custom-stt-model"
439
+ # kind = "offline"
440
+ # required = ["model.onnx", "tokens.txt"]
441
+
442
+ # Example: Register a custom vision classification model
443
+ # [[models]]
444
+ # type = 'vision.classification'
445
+ # key = 'my-vision-classifier'
446
+ # label = 'My Vision Classifier'
447
+ # url = "file:///path/to/my/classifier.zip"
448
+ # folder = "my-vision-classifier"
449
+ # kind = "classification"
450
+ # required = ["model.onnx", "labels.txt"]
451
+ # labelUrl = "file:///path/to/labels.txt"
452
+ # inputShape = [1, 3, 224, 224]
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Copyright 2025 IBM Corp. All Rights Reserved.
3
+ * Copyright 2026-present TJBot Contributors. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ export { LEDCommonAnode } from './led-common-anode.js';
18
+ export { LEDNeopixel } from './led-neopixel.js';
19
+ export { LEDNeopixelSPI } from './led-neopixel-spi.js';
20
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/led/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Copyright 2025 IBM Corp. All Rights Reserved.
3
+ * Copyright 2026-present TJBot Contributors. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ export { LEDCommonAnode } from './led-common-anode.js';
18
+ export { LEDNeopixel } from './led-neopixel.js';
19
+ export { LEDNeopixelSPI } from './led-neopixel-spi.js';
20
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/led/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Copyright 2025 IBM Corp. All Rights Reserved.
3
+ * Copyright 2026-present TJBot Contributors. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ /**
18
+ * LED controller for Common Anode LEDs using GPIO pins with PWM
19
+ */
20
+ export declare class LEDCommonAnode {
21
+ private chipHandle;
22
+ private redPin;
23
+ private greenPin;
24
+ private bluePin;
25
+ constructor(red: number, green: number, blue: number);
26
+ private writePin;
27
+ /**
28
+ * Render the LED to a specific RGB color.
29
+ * Common Anode LEDs are inverted - 0 is ON, 255 is OFF
30
+ * @param rgbColor RGB color as [red, green, blue] where each is 0-255
31
+ */
32
+ render(rgbColor: [number, number, number]): void;
33
+ /**
34
+ * Clean up resources
35
+ */
36
+ cleanup(): void;
37
+ }
38
+ //# sourceMappingURL=led-common-anode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"led-common-anode.d.ts","sourceRoot":"","sources":["../../src/led/led-common-anode.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AA0BH;;GAEG;AACH,qBAAa,cAAc;IACvB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,OAAO,CAAS;gBAEZ,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;IAiBpD,OAAO,CAAC,QAAQ;IAMhB;;;;OAIG;IACH,MAAM,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI;IAOhD;;OAEG;IACH,OAAO,IAAI,IAAI;CAalB"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Copyright 2025 IBM Corp. All Rights Reserved.
3
+ * Copyright 2026-present TJBot Contributors. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ import { createRequire } from 'module';
18
+ import { getLogger } from '../utils/logging.js';
19
+ const logger = getLogger(import.meta.url);
20
+ const require = createRequire(import.meta.url);
21
+ const lgpio = require('lgpio');
22
+ const GPIO_CHIP = 0;
23
+ const LED_PWM_FREQUENCY = 800;
24
+ /**
25
+ * LED controller for Common Anode LEDs using GPIO pins with PWM
26
+ */
27
+ export class LEDCommonAnode {
28
+ chipHandle;
29
+ redPin;
30
+ greenPin;
31
+ bluePin;
32
+ constructor(red, green, blue) {
33
+ this.chipHandle = lgpio.gpiochipOpen(GPIO_CHIP);
34
+ this.redPin = red;
35
+ this.greenPin = green;
36
+ this.bluePin = blue;
37
+ lgpio.gpioClaimOutput(this.chipHandle, this.redPin);
38
+ lgpio.gpioClaimOutput(this.chipHandle, this.greenPin);
39
+ lgpio.gpioClaimOutput(this.chipHandle, this.bluePin);
40
+ this.writePin(this.redPin, 0);
41
+ this.writePin(this.greenPin, 0);
42
+ this.writePin(this.bluePin, 0);
43
+ logger.verbose(`Initialized LEDCommonAnode on pins R:${red} G:${green} B:${blue}`);
44
+ }
45
+ writePin(pin, brightness) {
46
+ const clampedBrightness = Math.max(0, Math.min(255, brightness));
47
+ const highDutyCycle = ((255 - clampedBrightness) / 255) * 100;
48
+ lgpio.txPwm(this.chipHandle, pin, LED_PWM_FREQUENCY, highDutyCycle, 0, 0);
49
+ }
50
+ /**
51
+ * Render the LED to a specific RGB color.
52
+ * Common Anode LEDs are inverted - 0 is ON, 255 is OFF
53
+ * @param rgbColor RGB color as [red, green, blue] where each is 0-255
54
+ */
55
+ render(rgbColor) {
56
+ logger.debug(`rendering Common Anode LED with color RGB(${rgbColor[0]}, ${rgbColor[1]}, ${rgbColor[2]})`);
57
+ this.writePin(this.redPin, rgbColor[0]);
58
+ this.writePin(this.greenPin, rgbColor[1]);
59
+ this.writePin(this.bluePin, rgbColor[2]);
60
+ }
61
+ /**
62
+ * Clean up resources
63
+ */
64
+ cleanup() {
65
+ logger.debug('LEDCommonAnode cleanup');
66
+ try {
67
+ this.writePin(this.redPin, 0);
68
+ this.writePin(this.greenPin, 0);
69
+ this.writePin(this.bluePin, 0);
70
+ lgpio.gpioFree(this.chipHandle, this.redPin);
71
+ lgpio.gpioFree(this.chipHandle, this.greenPin);
72
+ lgpio.gpioFree(this.chipHandle, this.bluePin);
73
+ }
74
+ finally {
75
+ lgpio.gpiochipClose(this.chipHandle);
76
+ }
77
+ }
78
+ }
79
+ //# sourceMappingURL=led-common-anode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"led-common-anode.js","sourceRoot":"","sources":["../../src/led/led-common-anode.ts"],"names":[],"mappings":"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"}