Struct Client

Source
pub struct Client { /* private fields */ }
Expand description

Client used to authenticate and interact with Hive.

Implementations§

Source§

impl Client

Source

pub async fn get_actions(&self) -> Result<Vec<Action<'_>>, ApiError>

Get all of the Quick Actions setup in the Hive account.

§Examples
use hive_client::authentication::{TrustedDevice, User};

let client = hive_client::Client::new("Home Automation").await;

let trusted_device = Some(TrustedDevice::new(
    "device_password",
    "device_group_key",
    "device_key"
));

client.login(User::new("example@example.com", "example", trusted_device))
    .await
    .expect("Login should succeed");

let actions = client.get_actions()
    .await
    .expect("Quick action should be retrieved");

// Activate a quick action
let mut turn_off_heating = actions.into_iter()
    .find(|action| action.data.id == "1234-5678-000-0000")
    .expect("Quick action to turn off heating should exist");

let activated = turn_off_heating.activate().await;

assert!(activated.is_ok());
§Errors

Returns an error if the list of Quick Actions could not be retrieved.

Source§

impl Client

Source

pub async fn login( &self, user: User, ) -> Result<Option<Arc<TrustedDevice>>, AuthenticationError>

Login to Hive as a User.

This user may optionally have a trusted device associated with their account.

If provided, this induces a simpler login flow, which does not require Two Factor Authentication (ChallengeResponse::SmsMfa).

If not provided, a new device will be automatically confirmed with Hive during the login flow.

§Examples
§Login with a trusted device

If the user has previously logged in and set the Client as a trusted device , the trusted device can be provided to skip some authentication challenges.

use hive_client::authentication::{TrustedDevice, User};

let client = hive_client::Client::new("Home Automation").await;

let trusted_device = Some(TrustedDevice::new(
    "device_password",
    "device_group_key",
    "device_key"
));

let attempt = client.login(User::new("example@example.com", "example", trusted_device)).await;

// Login shouldn't require any additional challenges, as a remembered device was provided.
assert!(attempt.is_ok());
§Login without a trusted device
use hive_client::authentication::{ChallengeResponse, TrustedDevice, User};
use hive_client::AuthenticationError;

let mut client = hive_client::Client::new("Home Automation").await;

let attempt = client.login(User::new("example@example.com", "example", None)).await;

match attempt {
    Ok(trusted_device) => {
       // Login was successful.
       //
       // If a trusted device has been returned this can be used to authenticate in the future.
    },
    Err(AuthenticationError::NextChallenge(challenge)) => {
       // Hive prompted for a challenge to be responded to before
       // authentication can be completed.

       // Handle the challenge accordingly, and respond to the challenge.
       let sms_code = "123456";
       let response = client.respond_to_challenge(ChallengeResponse::SmsMfa(sms_code.to_string())).await;

       assert!(response.is_ok());
    },
    Err(_) => {
      // Login failed, respond accordingly.
    }
}
§Errors

Returns an error if Hive did not immediately return an active session.

This can happen if the credentials are invalid, or if Hive prompt for a challenge in order to process (AuthenticationError::NextChallenge).

In the latter case, the caller must generate a ChallengeResponse and call Client::respond_to_challenge to continue with the authentication process.

Source

pub async fn respond_to_challenge( &mut self, challenge_response: ChallengeResponse, ) -> Result<Option<Arc<TrustedDevice>>, AuthenticationError>

Respond to a challenge issued by Hive during the authentication process.

This is typically used to handle Two Factor Authentication (2FA) challenges, but could be any challenge issued by Hive that requires a response from the user (Client::login)

§Examples
use hive_client::authentication::{ChallengeResponse, TrustedDevice, User};
use hive_client::AuthenticationError;

let mut client = hive_client::Client::new("Home Automation").await;

let attempt = client.login(User::new("example@example.com", "example", None)).await;

match attempt {
    Ok(trusted_device) => {
        // Login was successful.
        //
        // If a trusted device has been returned this can be used to authenticate in the future.
    },
    Err(AuthenticationError::NextChallenge(challenge)) => {
        // Hive prompted for a challenge to be responded to before
        // authentication can be completed.

        // Handle the challenge accordingly, and respond to the challenge.
        let sms_code = "123456";
        let response = client.respond_to_challenge(ChallengeResponse::SmsMfa(sms_code.to_string())).await;

        if let Ok(trusted_device) = response {
            // Login was successful.
            //
            // If a trusted device has been returned this can be used to authenticate in the future.
        } else {
            // Challenge failed, respond accordingly.
        }
    },
    Err(_) => {
        // Login failed, respond accordingly.
    }
}
§Errors

Returns an error if the challenge submission was unsuccessful. If this happens, the caller must check the error type and handle it accordingly.

Source

pub async fn logout(&mut self)

Logout from Hive.

Note: This only clears the client, it does not perform any operations on the Hive Account.

§Examples
use hive_client::authentication::{TrustedDevice, User};

let mut client = hive_client::Client::new("Home Automation").await;

let trusted_device = Some(TrustedDevice::new(
    "device_password",
    "device_group_key",
    "device_key"
));

let attempt = client.login(User::new("example@example.com", "example", trusted_device)).await;

// Login shouldn't require any additional challenges, as a remembered device was provided.
assert!(attempt.is_ok());

client.logout().await;
Source§

impl Client

Source

pub async fn get_devices(&self) -> Result<Vec<Device>, ApiError>

Get all of the devices associated with the Hive account.

This can include Hubs, Thermostats, Boilers, and other devices.

§Examples
use hive_client::authentication::{TrustedDevice, User};
use hive_client::products::{Product, ProductData, State, States};

let client = hive_client::Client::new("Home Automation").await;

let trusted_device = Some(TrustedDevice::new(
    "device_password",
    "device_group_key",
    "device_key"
));

let attempt = client.login(User::new("example@example.com", "example", trusted_device)).await;

if let Ok(_) = attempt {
    // Login was successful

    let devices = client.get_devices()
        .await
        .expect("Devices should be retrieved");
     
    println!("{:?}", devices);
}
§Errors

Returns an error if the list of devices could not be retrieved.

Source§

impl Client

Source

pub async fn get_products(&self) -> Result<Vec<Product<'_>>, ApiError>

Get all of the Hive products setup in the Hive account.

For example, the Heating or Hot Water products.

§Examples
use hive_client::authentication::{TrustedDevice, User};
use hive_client::products::{Product, ProductData, State, States};

let client = hive_client::Client::new("Home Automation").await;

let trusted_device = Some(TrustedDevice::new(
    "device_password",
    "device_group_key",
    "device_key"
));

let attempt = client.login(User::new("example@example.com", "example", trusted_device)).await;

if let Ok(_) = attempt {
    // Login was successful

    let products = client.get_products()
        .await
        .expect("Products should be retrieved");
     
    println!("{:?}", products);
}
§Errors

Returns an error if the list of products could not be retrieved.

Source§

impl Client

Source

pub async fn get_weather(&self, postcode: &str) -> Result<Weather, ApiError>

Get the current weather according to Hive, for a given postcode.

§Examples
use hive_client::authentication::{TrustedDevice, User};
use hive_client::{weather::WeatherData};
use hive_client::weather::Temperature::Celsius;
use hive_client::weather::Weather;

let client = hive_client::Client::new("Home Automation").await;

let trusted_device = Some(TrustedDevice::new(
    "device_password",
    "device_group_key",
    "device_key"
));

client.login(User::new("example@example.com", "example", trusted_device))
    .await
    .expect("Login should succeed");

let Weather { data: WeatherData { temperature, ..}} = client.get_weather("SW1A 1AA")
    .await
    .expect("Weather should be retrieved");

println!("The current temperature is: {temperature}");
§Errors

Returns an error if the whether data could not be retrieved.

Source§

impl Client

Source

pub async fn new(friendly_name: &str) -> Self

Create a new client.

The friendly name is used to identify the client in the Trusted Device page of the Hive app if the user is authenticating for the first time (does not have a trusted device during Client::login)

Trait Implementations§

Source§

impl Debug for Client

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl !Freeze for Client

§

impl !RefUnwindSafe for Client

§

impl Send for Client

§

impl Sync for Client

§

impl Unpin for Client

§

impl !UnwindSafe for Client

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<Unshared, Shared> IntoShared<Shared> for Unshared
where Shared: FromUnshared<Unshared>,

Source§

fn into_shared(self) -> Shared

Creates a shared type from an unshared type.
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<T> ErasedDestructor for T
where T: 'static,

Source§

impl<T> MaybeSendSync for T