1use ados_protocol::camera_control::{
4 CameraControlRequest, CameraControlResult, CAMERA_CONTROL_CAPABILITY, CAMERA_CONTROL_METHOD,
5 ENGINE_WAIT_MS,
6};
7
8use super::*;
9
10const CAMERA_CONTROL_TIMEOUT: Duration = Duration::from_millis(ENGINE_WAIT_MS + 1_000);
14
15impl PluginIpcClient {
16 pub async fn peripheral_register_driver(
22 &self,
23 kind: &str,
24 driver_ref: &str,
25 ) -> Result<Value, ClientError> {
26 let cap = driver_kind_capability(kind)
27 .ok_or_else(|| ClientError::Rpc(format!("unknown driver kind: {kind}")))?;
28 let args = Value::Map(vec![
29 (Value::from("kind"), Value::from(kind)),
30 (Value::from("driver_ref"), Value::from(driver_ref)),
31 ]);
32 Ok(self
33 .send_request("peripheral.register_driver", cap, args)
34 .await?
35 .args)
36 }
37
38 pub async fn peripheral_unregister_driver(
41 &self,
42 handle_id: &str,
43 ) -> Result<Value, ClientError> {
44 let args = Value::Map(vec![(Value::from("handle_id"), Value::from(handle_id))]);
45 Ok(self
46 .send_request("peripheral.unregister_driver", "", args)
47 .await?
48 .args)
49 }
50
51 pub async fn camera_claim(
53 &self,
54 device_path: &str,
55 exclusive: bool,
56 ) -> Result<Value, ClientError> {
57 let args = Value::Map(vec![
58 (Value::from("device_path"), Value::from(device_path)),
59 (Value::from("exclusive"), Value::Boolean(exclusive)),
60 ]);
61 Ok(self
62 .send_request("camera.claim", "sensor.camera.register", args)
63 .await?
64 .args)
65 }
66
67 pub async fn camera_release(&self, device_path: &str) -> Result<Value, ClientError> {
69 let args = Value::Map(vec![(Value::from("device_path"), Value::from(device_path))]);
70 Ok(self
71 .send_request("camera.release", "sensor.camera.register", args)
72 .await?
73 .args)
74 }
75
76 pub async fn camera_get_frame(
79 &self,
80 device_path: &str,
81 format: &str,
82 timeout_ms: i64,
83 ) -> Result<Value, ClientError> {
84 let args = Value::Map(vec![
85 (Value::from("device_path"), Value::from(device_path)),
86 (Value::from("format"), Value::from(format)),
87 (Value::from("timeout_ms"), Value::from(timeout_ms)),
88 ]);
89 Ok(self
90 .send_request("camera.get_frame", "sensor.camera.register", args)
91 .await?
92 .args)
93 }
94
95 pub async fn camera_set_controls(
104 &self,
105 req: &CameraControlRequest,
106 ) -> Result<CameraControlResult, ClientError> {
107 let reply = self
108 .send_request_within(
109 CAMERA_CONTROL_METHOD,
110 CAMERA_CONTROL_CAPABILITY,
111 req.to_args(),
112 CAMERA_CONTROL_TIMEOUT,
113 )
114 .await?;
115 decode_typed_reply(reply.args, CAMERA_CONTROL_METHOD)
116 }
117}
118
119impl PluginIpcClient {
120 pub fn register_button_callback(&self, callback: EventCallback) {
122 register_callback(&self.button_callbacks, VISION_ANY_CAMERA, callback);
123 }
124}
125
126impl PluginIpcClient {
127 pub async fn button_subscribe(&self) -> Result<Value, ClientError> {
129 Ok(self
130 .send_request(
131 ados_protocol::buttons::SUBSCRIBE,
132 ados_protocol::buttons::SUBSCRIBE,
133 Value::Map(vec![]),
134 )
135 .await?
136 .args)
137 }
138
139 pub async fn gpio_output_set(
141 &self,
142 chip: i64,
143 pin: i64,
144 high: bool,
145 ) -> Result<Value, ClientError> {
146 let args = Value::Map(vec![
147 (Value::from("chip"), Value::Integer(chip.into())),
148 (Value::from("pin"), Value::Integer(pin.into())),
149 (
150 Value::from("level"),
151 Value::from(if high { "high" } else { "low" }),
152 ),
153 ]);
154 Ok(self
155 .send_request("gpio.output.set", "hardware.gpio_out", args)
156 .await?
157 .args)
158 }
159
160 pub async fn gpio_buzzer_beep(
166 &self,
167 chip: i64,
168 pin: i64,
169 on_ms: i64,
170 cycles: i64,
171 off_ms: Option<i64>,
172 freq_hz: Option<i64>,
173 ) -> Result<Value, ClientError> {
174 let mut entries = vec![
175 (Value::from("chip"), Value::Integer(chip.into())),
176 (Value::from("pin"), Value::Integer(pin.into())),
177 (Value::from("on_ms"), Value::Integer(on_ms.into())),
178 (Value::from("cycles"), Value::Integer(cycles.into())),
179 ];
180 if let Some(v) = off_ms {
181 entries.push((Value::from("off_ms"), Value::Integer(v.into())));
182 }
183 if let Some(v) = freq_hz {
184 entries.push((Value::from("freq_hz"), Value::Integer(v.into())));
185 }
186 Ok(self
187 .send_request("gpio.buzzer.beep", "hardware.gpio_out", Value::Map(entries))
188 .await?
189 .args)
190 }
191
192 pub async fn display_page_set(
198 &self,
199 title: &str,
200 rows: &[(String, String)],
201 zones: &[(i64, i64, i64, i64, String, String)],
202 ) -> Result<Value, ClientError> {
203 let rows_v: Vec<Value> = rows
204 .iter()
205 .map(|(label, value)| {
206 Value::Map(vec![
207 (Value::from("label"), Value::from(label.as_str())),
208 (Value::from("value"), Value::from(value.as_str())),
209 ])
210 })
211 .collect();
212 let zones_v: Vec<Value> = zones
213 .iter()
214 .map(|(x, y, w, h, key, label)| {
215 Value::Map(vec![
216 (Value::from("x"), Value::Integer((*x).into())),
217 (Value::from("y"), Value::Integer((*y).into())),
218 (Value::from("w"), Value::Integer((*w).into())),
219 (Value::from("h"), Value::Integer((*h).into())),
220 (Value::from("key"), Value::from(key.as_str())),
221 (Value::from("label"), Value::from(label.as_str())),
222 ])
223 })
224 .collect();
225 let args = Value::Map(vec![
226 (Value::from("title"), Value::from(title)),
227 (Value::from("rows"), Value::Array(rows_v)),
228 (Value::from("zones"), Value::Array(zones_v)),
229 ]);
230 Ok(self
231 .send_request("display.page.set", "display.oled.page", args)
232 .await?
233 .args)
234 }
235
236 pub async fn radio_aux_stream_open(&self) -> Result<Value, ClientError> {
238 Ok(self
239 .send_request(
240 "radio.aux_stream.open",
241 "radio.aux_stream",
242 Value::Map(vec![]),
243 )
244 .await?
245 .args)
246 }
247
248 pub async fn radio_aux_stream_close(&self) -> Result<Value, ClientError> {
250 Ok(self
251 .send_request(
252 "radio.aux_stream.close",
253 "radio.aux_stream",
254 Value::Map(vec![]),
255 )
256 .await?
257 .args)
258 }
259
260 pub async fn radio_aux_stream_send(
268 &self,
269 channel: u8,
270 payload: &[u8],
271 ) -> Result<Value, ClientError> {
272 let args = Value::Map(vec![
273 (Value::from("channel"), Value::Integer(channel.into())),
274 (Value::from("payload"), Value::Binary(payload.to_vec())),
275 ]);
276 Ok(self
277 .send_request("radio.aux_stream.send", "radio.aux_stream", args)
278 .await?
279 .args)
280 }
281
282 pub async fn radio_aux_stream_subscribe(&self) -> Result<Value, ClientError> {
290 Ok(self
291 .send_request(
292 "radio.aux_stream.subscribe",
293 "radio.aux_stream",
294 Value::Map(vec![]),
295 )
296 .await?
297 .args)
298 }
299
300 pub fn register_aux_callback(&self, callback: EventCallback) {
304 register_callback(&self.aux_callbacks, VISION_ANY_CAMERA, callback);
305 }
306}