A skill server for Rhasspy written in Rust that uses the Hermes MQTT protocol. It is mainly meant for personal use as it currently hardcodes a number of intents, but can also act as an example.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

68 lines
2.2 KiB

use rhasspy_skill_server::{Intent, Response};
use rumqttc::{AsyncClient, Event, MqttOptions, Packet, QoS};
#[derive(Default, Debug)]
struct Context;
async fn handle(_context: &mut Context, intent: Intent) -> Option<Response> {
println!(
">>> Detected intent: {} (confidence: {})",
intent.name, intent.confidence
);
match intent.name.as_ref() {
"test" => {
let choice = intent.slots.get("choice").unwrap();
Some(
Response::new(intent.session_id)
.with_text(format!("De test is geslaagd: {}", choice.value)),
)
}
_ => {
println!("??? Ignoring unsupported intent: {:?}", intent.name);
None
}
}
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error + 'static>> {
let mut mqttoptions = MqttOptions::new("rhasspy-skill-server", "void", 1883);
mqttoptions.set_keep_alive(5);
let (client, mut eventloop) = AsyncClient::new(mqttoptions, 10);
client.subscribe("hermes/intent/#", QoS::AtMostOnce).await?;
let mut context = Context::default();
loop {
let event = eventloop.poll().await?;
if let Event::Incoming(Packet::Publish(published)) = event {
let result: Result<Intent, _> = serde_json::from_slice(published.payload.as_ref());
let response = match result {
Ok(intent) => handle(&mut context, intent).await,
Err(e) => {
println!(
"!!! Could not parse intent payload: {} at\n{:?}",
e, published.payload
);
continue;
}
};
if let Some(response) = response {
let result = client
.publish(
"hermes/dialogueManager/endSession",
QoS::AtMostOnce,
false,
response,
)
.await;
match result {
Ok(_) => println!("<<< Reacted with a response!"),
Err(e) => println!("!!! Could not publish intent payload: {}", e),
}
}
}
}
}