How do I call a method from interface org.freedesktop.DBus.Properties with zbus in Rust?

611 views Asked by At

I have the following code snippet here:

// The connection I am borrowing:
// let connection = zbus::Connection::system().await?;
pub async fn to_ac(connection: &zbus::Connection) -> Result<(), zbus::Error> {
  // keycall works just fine, no issues
  /*
  let keycall = connection.call_method(Some("org.freedesktop.UPower"), "/org/freedesktop/UPower/KbdBacklight", Some("org.freedesktop.UPower.KbdBacklight"), "SetBrightness", &3)
    .await.expect("keyboard code broken");
    */
// I do not know if my body tuple works or not, because it won't let me call this method.
  let profilecall = connection.call_method(Some("net.hadess.PowerProfiles"), "/net/hadess/PowerProfiles", Some("org.freedesktop.DBus.Properties"), "Set", &("net.hadess.PowerProfiles", "ActiveProfile", "balanced"))
    .await.expect("powerprofile code broken");
  println!("{:?}", profilecall);
  println!("AC function ran");
  Ok(())
}

When I run it, I get this

thread 'main' panicked at 'powerprofile code broken: MethodError(OwnedErrorName(ErrorName(Str(Owned("org.freedesktop.DBus.Error.UnknownMethod")))), Some("No such interface “org.freedesktop.DBus.Properties” on object at path /net/hadess/PowerProfiles"), Msg { type: Error, sender: UniqueName(Str(Borrowed(":1.6"))), reply-serial: 7, body: Signature("s") })', src/powermodes.rs:25:12

I know it is a valid interface from running busctl introspect "net.hadess.PowerProfiles" "/net/hadess/PowerProfiles" in my terminal. I get the following output

NAME                                TYPE      SIGNATURE RESULT/VALUE                             FLAGS
net.hadess.PowerProfiles            interface -         -                                        -
.HoldProfile                        method    sss       u                                        -
.ReleaseProfile                     method    u         -                                        -
.Actions                            property  as        1 "trickle_charge"                       emits-c>
.ActiveProfile                      property  s         "performance"                            emits-c>
.ActiveProfileHolds                 property  aa{sv}    0                                        emits-c>
.PerformanceDegraded                property  s         ""                                       emits-c>
.PerformanceInhibited               property  s         ""                                       emits-c>
.Profiles                           property  aa{sv}    3 2 "Profile" s "power-saver" "Driver" … emits-c>
.ProfileReleased                    signal    u         -                                        -
org.freedesktop.DBus.Introspectable interface -         -                                        -
.Introspect                         method    -         s                                        -
org.freedesktop.DBus.Peer           interface -         -                                        -
.GetMachineId                       method    -         s                                        -
.Ping                               method    -         -                                        -
org.freedesktop.DBus.Properties     interface -         -                                        -
.Get                                method    ss        v                                        -
.GetAll                             method    s         a{sv}                                    -
.Set                                method    ssv       -                                        -
.PropertiesChanged                  signal    sa{sv}as  -                                        -

Why won't zbus let me use this interface?

The method assigned to profilecall should call a method (org.freedesktop.DBus.Properties.Set) from interface (org.freedesktop.DBus.Properties) on (net.hadess.PowerProfiles). It should change the power profile to balanced.

1

There are 1 answers

0
vlk On

uno20001#3061 on Discord finally figured it out, the working code is

pub async fn to_ac(connection: &zbus::Connection) -> Result<(), zbus::Error> {
  /*
  let keycall = connection.call_method(Some("org.freedesktop.UPower"), "/org/freedesktop/UPower/KbdBacklight", Some("org.freedesktop.UPower.KbdBacklight"), "SetBrightness", &3)
    .await.expect("keyboard code broken");
    */
  let profilecall = connection.call_method(Some("net.hadess.PowerProfiles"), "/net/hadess/PowerProfiles", Some("org.freedesktop.DBus.Properties"), "Set", &("net.hadess.PowerProfiles", "ActiveProfile", zbus::zvariant::Value::new("balanced")))
    .await.expect("powerprofile code broken");
  println!("{:?}", profilecall);
  println!("AC function ran");
  Ok(())
}

They ran power-profiles-daemon with G_DBUS_DEBUG=all and noticed the wrong code had a different message signature from the gdbus call (sss vs. ssv)