ewilken / hap-rs

Rust implementation of the Apple HomeKit Accessory Protocol (HAP)
Apache License 2.0
197 stars 35 forks source link

Add accessory from other threads. #26

Closed ht-hieu closed 3 years ago

ht-hieu commented 4 years ago

Hi,

I am a Rust beginner and want to use Rust to implement a HomeKit to MQTT bridge. Currently, I want to receive a list of devices in JSON format from MQTT broker and create accessories accordingly. But I am struggling to get it done.

The MQTT client is running on a separate thread, so it cannot mutate the IpTransport struct. I tried with Mutex like this

let mut ip_transport = Arc::new(Mutex::new(IpTransport::new(config).unwrap()));

and run the event loop by using this command

ip_transport.lock().unwrap().start().unwrap();

But the command never release the mutex and doesn't led me add a new accessory. Note that, I added an accessory by using this command:

transport_clone.lock().unwrap().add_accessory(sw).unwrap();

I tried channels but I don't have any idea about how to receive from a channel continuously without spawning a new Thread.

Could you give me any advice to get what I want? Thank you so much.

ewilken commented 3 years ago

Hey! Sorry for the late answer!

Just added an example for adding new accessories to a bridge after server start with the new syntax of the crate:

let server = IpServer::new(config, storage).unwrap();
server.add_accessory(bridge).await.unwrap();
server.add_accessory(lightbulb).await.unwrap();

let handle = server.run_handle();

let stream_of_new_accessories = async {
    tokio::time::delay_for(std::time::Duration::from_secs(60)).await;

    for i in 0..20 {
        let lightbulb = LightbulbAccessory::new(i + 3, AccessoryInformation {
            name: format!("Another Lightbulb {}", i + 1),
            ..Default::default()
        })
        .unwrap();

        server.add_accessory(lightbulb).await.unwrap();

        tokio::time::delay_for(std::time::Duration::from_secs(2)).await;
    }
};

futures::join!(handle, stream_of_new_accessories);
cargo run --example adding_accessories_dynamically --release