From 3ad15d61c97fac4c2718178bedbee3dfa5965e37 Mon Sep 17 00:00:00 2001 From: Luke Jones Date: Mon, 29 Jun 2020 10:03:27 +1200 Subject: [PATCH] Dbus expand (#24) * Dbus changes - Changed "FanMode", "ChargeLimit" to "SetFanMode", "SetChargeLimit" - Added dbus signals "FanModeChanged", "ChargeLimitChanged" - Added dbus methods "GetFanMode", "GetChargeLimit" * Refactor of internal loop and tokio tasks * Add support for ROG Strix G712LV_G712LV * Correctly read the config before writing changes --- CHANGELOG.md | 13 ++- Cargo.lock | 165 ++++++++++++++++++++++++------------ README.md | 70 ++++++++------- debian/changelog | 20 +++++ rog-client/src/aura_dbus.rs | 6 +- rog-core/Cargo.toml | 2 +- rog-core/src/daemon.rs | 71 +++++++++++----- rog-core/src/laptops.rs | 97 +++++++++++---------- rog-core/src/led_control.rs | 1 + rog-core/src/main.rs | 2 +- rog-core/src/rog_dbus.rs | 91 ++++++++++++++------ rog-core/src/rogcore.rs | 19 ++--- 12 files changed, 364 insertions(+), 193 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index deeb9a70..c000d4f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,17 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] + +## [0.12.2] - 2020-29-06 +### Changed +- "FanMode", "ChargeLimit" to "SetFanMode", "SetChargeLimit" + +### Added +- Dbus signals "FanModeChanged", "ChargeLimitChanged" +- Dbus methods "GetFanMode", "GetChargeLimit" +- Support for ROG Strix G712 + +## [0.12.0] - 2020-26-06 ### Changed - Add modes for FX531 LEDs - Change where USB reset is called @@ -76,4 +87,4 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Internal structure changes to reduce the possibility of mutex await deadlocks when - writing to the LED endpoint \ No newline at end of file + writing to the LED endpoint diff --git a/Cargo.lock b/Cargo.lock index 35627db9..c93eef0b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,15 +2,15 @@ # It is not intended for manual editing. [[package]] name = "adler32" -version = "1.0.4" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d2e7343e7fc9de883d1b0341e0b13970f764c14101234857d2ddafa1cb1cac2" +checksum = "567b077b825e468cc974f0020d4082ee6e03132512f207ef1a02fd5d00d1f32d" [[package]] name = "aho-corasick" -version = "0.7.10" +version = "0.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8716408b8bc624ed7f65d223ddb9ac2d044c0547b6fa4b0d554f3a9540496ada" +checksum = "043164d8ba5c4c3035fec9bbee8647c0261d788f3474306f93bb65901cae0e86" dependencies = [ "memchr", ] @@ -21,7 +21,7 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" dependencies = [ - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -32,7 +32,7 @@ checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ "hermit-abi", "libc", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -82,15 +82,18 @@ checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" [[package]] name = "bytes" -version = "0.5.4" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "130aac562c0dd69c56b3b1cc8ffd2e17be31d0b6c25b61c96b76231aa23e39e1" +checksum = "118cf036fbb97d0816e3c34b2d7a1e8cfc60f68fcf63d550ddbe9bd5f59c213b" +dependencies = [ + "loom", +] [[package]] name = "cc" -version = "1.0.54" +version = "1.0.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bbb73db36c1246e9034e307d0fba23f9a2e251faa47ade70c1bd252220c8311" +checksum = "b1be3409f94d7bdceeb5f5fac551039d9b3f00e25da7a74fc4d33400a0d96368" [[package]] name = "cexpr" @@ -144,9 +147,9 @@ dependencies = [ [[package]] name = "dbus" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b17a12ffaff26515889b006fc029493a3e340366a137c13cec2cdd545ea3b8" +checksum = "5cd9e78c210146a1860f897db03412fd5091fd73100778e43ee255cca252cf32" dependencies = [ "futures", "libc", @@ -220,7 +223,7 @@ dependencies = [ "cfg-if", "libc", "redox_syscall", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -340,6 +343,19 @@ dependencies = [ "slab", ] +[[package]] +name = "generator" +version = "0.6.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "add72f17bb81521258fcc8a7a3245b1e184e916bfbe34f0ea89558f440df5c68" +dependencies = [ + "cc", + "libc", + "log", + "rustc_version", + "winapi 0.3.9", +] + [[package]] name = "glob" version = "0.3.0" @@ -368,9 +384,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.1.13" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91780f809e750b0a89f5544be56617ff6b1227ee485bcb06ebe10cdf89bd3b71" +checksum = "b9586eedd4ce6b3c498bc3b4dd92fc9f11166aa908a914071953768066c67909" dependencies = [ "libc", ] @@ -459,7 +475,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2b111a074963af1d37a139918ac6d49ad1d0d5e47f72fd55388619691a7d753" dependencies = [ "cc", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -485,6 +501,17 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "loom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ecc775857611e1df29abba5c41355cdf540e7e9d4acfdf0f355eefee82330b7" +dependencies = [ + "cfg-if", + "generator", + "scoped-tls", +] + [[package]] name = "memchr" version = "2.3.3" @@ -530,14 +557,14 @@ checksum = "2ba7c918ac76704fb42afcbbb43891e72731f3dcca3bef2a19786297baf14af7" dependencies = [ "cfg-if", "libc", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] name = "nom" -version = "5.1.1" +version = "5.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b471253da97532da4b61552249c521e01e736071f71c1a4f7ebbfbf0a06aad6" +checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af" dependencies = [ "memchr", "version_check", @@ -573,18 +600,18 @@ checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" [[package]] name = "pin-project" -version = "0.4.20" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e75373ff9037d112bb19bc61333a06a159eaeb217660dcfbea7d88e1db823919" +checksum = "12e3a6cdbfe94a5e4572812a0201f8c0ed98c1c452c7b8563ce2276988ef9c17" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "0.4.20" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10b4b44893d3c370407a1d6a5cfde7c41ae0478e31c516c85f67eb3adc51be6d" +checksum = "6a0ffd45cf79d88737d7cc85bfd5d2894bee1139b356e616fe85dc389c61aaf7" dependencies = [ "proc-macro2", "quote", @@ -611,9 +638,9 @@ checksum = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677" [[package]] name = "proc-macro-error" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98e9e4b82e0ef281812565ea4751049f1bdcdfccda7d3f459f2e138a40c08678" +checksum = "fc175e9777c3116627248584e8f8b3e2987405cabe1c0adf7d1dd28f09dc7880" dependencies = [ "proc-macro-error-attr", "proc-macro2", @@ -624,9 +651,9 @@ dependencies = [ [[package]] name = "proc-macro-error-attr" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f5444ead4e9935abd7f27dc51f7e852a0569ac888096d5ec2499470794e2e53" +checksum = "3cc9795ca17eb581285ec44936da7fc2335a3f34f2ddd13118b6f4d515435c50" dependencies = [ "proc-macro2", "quote", @@ -643,9 +670,9 @@ checksum = "7e0456befd48169b9f13ef0f0ad46d492cf9d2dbb918bcf38e01eed4ce3ec5e4" [[package]] name = "proc-macro-nested" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0afe1bd463b9e9ed51d0e0f0b50b6b146aec855c56fd182bb242388710a9b6de" +checksum = "eba180dafb9038b050a4c280019bbedf9f2467b61e5d892dcad585bb57aadc5a" [[package]] name = "proc-macro2" @@ -716,7 +743,7 @@ dependencies = [ [[package]] name = "rog-daemon" -version = "0.11.1" +version = "0.12.2" dependencies = [ "dbus", "dbus-tokio", @@ -753,10 +780,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] -name = "rustversion" -version = "1.0.2" +name = "rustc_version" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3bba175698996010c4f6dce5e7f173b6eb781fce25d2cfc45e27091ce0b79f6" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver", +] + +[[package]] +name = "rustversion" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9bdc5e856e51e685846fb6c13a1f5e5432946c2c90501bdc76a1319f19e29da" dependencies = [ "proc-macro2", "quote", @@ -764,16 +800,37 @@ dependencies = [ ] [[package]] -name = "serde" -version = "1.0.111" +name = "scoped-tls" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9124df5b40cbd380080b2cc6ab894c040a3070d995f5c9dc77e18c34a8ae37d" +checksum = "332ffa32bf586782a3efaeb58f127980944bbc8c4d6913a86107ac2a5ab24b28" + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + +[[package]] +name = "serde" +version = "1.0.114" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5317f7588f0a5078ee60ef675ef96735a1442132dc645eb1d12c018620ed8cd3" [[package]] name = "serde_derive" -version = "1.0.111" +version = "1.0.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f2c3ac8e6ca1e9c80b8be1023940162bf81ae3cffbb1809474152f2ce1eb250" +checksum = "2a0be94b04690fbaed37cddffc5c134bf537c8e3329d53e982fe04c374978f8e" dependencies = [ "proc-macro2", "quote", @@ -811,9 +868,9 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] name = "syn" -version = "1.0.30" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93a56fabc59dce20fe48b6c832cc249c713e7ed88fa28b0ee0a3bfcaae5fe4e2" +checksum = "e8d5d96e8cbb005d6959f119f773bfaebb5684296108fb32600c00cde305b2cd" dependencies = [ "proc-macro2", "quote", @@ -860,9 +917,9 @@ checksum = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60" [[package]] name = "tar" -version = "0.4.28" +version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c058ad0bd6ccb84faa24cc44d4fc99bee8a5d7ba9ff33aa4d993122d1aeeac2" +checksum = "c8a4c1d0bee3230179544336c15eefb563cf0302955d962e456542323e8c2e8a" dependencies = [ "filetime", "libc", @@ -890,18 +947,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.19" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b13f926965ad00595dd129fa12823b04bbf866e9085ab0a5f2b05b850fbfc344" +checksum = "7dfdd070ccd8ccb78f4ad66bf1982dc37f620ef696c6b5028fe2ed83dd3d0d08" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.19" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "893582086c2f98cde18f906265a65b5030a074b1046c674ae898be6519a7f479" +checksum = "bd80fc12f73063ac132ac92aceea36734f04a1d93c1240c6944e23a3b8841793" dependencies = [ "proc-macro2", "quote", @@ -991,15 +1048,15 @@ checksum = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479" [[package]] name = "unicode-xid" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" +checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" [[package]] name = "vcpkg" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55d1e41d56121e07f1e223db0a4def204e45c85425f6a16d462fd07c8d10d74c" +checksum = "6454029bf181f092ad1b853286f23e2c507d8e8194d01d92da4a55c274a5508c" [[package]] name = "vec_map" @@ -1030,9 +1087,9 @@ checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" [[package]] name = "winapi" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" dependencies = [ "winapi-i686-pc-windows-gnu", "winapi-x86_64-pc-windows-gnu", @@ -1056,7 +1113,7 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" dependencies = [ - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -1090,5 +1147,5 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fe5c30ade05e61656247b2e334a031dfd0cc466fadef865bdcdea8d537951bf1" dependencies = [ - "winapi 0.3.8", + "winapi 0.3.9", ] diff --git a/README.md b/README.md index 718e8739..13f265a0 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,42 @@ # ROG-Core -rog-core is a utility for Linux to control many aspects (eventually) of the ASUS ROG laptops like the Zephyrus GX502GW. +rog-core is a utility for Linux to control many aspects (eventually) of the ASUS +ROG laptops like the Zephyrus GX502GW. -One of the benefits of this app (for me at least) is that you *don't* require a kernel with correct support for the -laptop, or custom patched modules. The app reads and writes direct to the device interrupts, and can be customised -(in source) quite extensively to do what you want such as directly controlling your laptop backlight rather than -emitting a key-press for the DE to handle. There is also the possibility of rebinding fn keys to be macros which emit a -series of keyboard presses. +One of the benefits of this app (for me at least) is that you *don't* require a +kernel with correct support for the laptop keyboard EC. The app +reads and writes direct to the device interrupts, and can be customised (in +source) quite extensively to do what you want such as directly controlling your +laptop backlight rather than emitting a key-press for the DE to handle. There is +also the possibility of rebinding fn keys to be macros which emit a series of +keyboard presses. -The laptop I currently have is the GX502RW and so I'll be using that for the basis of this app. If I get wireshark -captures from others with different ROG laptops then I should be able to add them. - -I'm now looking at the kernel source to see if I can add the inputs correctly so they show up as proper evdev events. +Other laptop functions such as fan modes or battery charge limiting will need +kernel level support. ## Discord [Discord server link](https://discord.gg/uKxdua) +## SUPPORTED LAPTOPS + +- GM501 (multizone needs testing, if you have this laptop please create an issue in the repo) +- GX502 +- GX531 +- G712 +- G531 +- GA14/GA401 *is* supported, including the AniMe display. You will need kernel [patches](https://lab.retarded.farm/zappel/asus-rog-zephyrus-g14/-/tree/master/kernel_patches). +- GA15/GA502 appears to have most things working + +**Please help test or provide info for:** + +- GL703(0x1869) +- GL553(0x1854) GL753 (attempted support from researching 2nd-hand info, multizone may work) + +**Laptop support is added on a per-case basis** as the EC for the keyboard varies +a little between models, e.g, some RGB modes are missing, or it's a single colour. +As far as I can see, the EC does not give us a way to find what modes are supported. + ## Implemented - [X] Setting/modifying built-in LED modes @@ -38,22 +58,7 @@ I'm now looking at the kernel source to see if I can add the inputs correctly so + [ ] Mic mute - unsure which key should be emitted for this to work. The key by itself emits a code. - [X] Logging - required for journalctl - [X] AniMatrix display on G14 models that include it - -## SUPPORTED LAPTOPS - -- GM501 (multizone needs testing) -- GX502 -- GX531 -- G531GT -- GA14/GA401 *is* supported, including the AniMe display. You will need kernel [patches](https://lab.retarded.farm/zappel/asus-rog-zephyrus-g14/-/tree/master/kernel_patches). -- GA15/GA502 appears to have most things working - -**Please help test or provide info for:** - -- GL703(0x1869) -- GL553(0x1854) GL753 (attempted support from researching 2nd-hand info, multizone may work) - -**Laptop support is added on a per-case basis as the EC for the keyboard varies a little between models, e.g, some RGB modes are missing, or it's a single colour** +- [X] Set battery charge limit (with kernel supporting this) ## Requirements for compiling @@ -207,13 +212,16 @@ If the daemon service is enabled then on boot the following will be reloaded fro - LED brightness - Last used built-in mode -- fan-boost/thermal mode +- fan-boost/thermal mode +- battery charging limit -The daemon also saves the settings per mode as the keyboard does not do this itself - this means cycling through modes -with the Aura keys will use the settings that were used via CLI. +The daemon also saves the settings per mode as the keyboard does not do this +itself - this means cycling through modes with the Aura keys will use the +settings that were used via CLI. -Daemon mode creates a config file at `/etc/rogcore.conf` which you can edit a little of. Most parts will be byte arrays, -but you can adjust things like `mode_performance`. +Daemon mode creates a config file at `/etc/rogcore.conf` which you can edit a +little of. Most parts will be byte arrays, but you can adjust things like +`mode_performance`. ### DBUS Input diff --git a/debian/changelog b/debian/changelog index 8f6c32e5..c6c74a19 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,23 @@ +rog-core (0.12.2) focal; urgency=medium + + * Changed "FanMode", "ChargeLimit" to "SetFanMode", "SetChargeLimit" + * Added dbus signals "FanModeChanged", "ChargeLimitChanged" + * Added dbus methods "GetFanMode", "GetChargeLimit" + * Added support for ROG Strix G712 + + -- Luke Jones Mon, 29 Jun 2020 09:54:25 +1200 + +rog-core (0.12.0) focal; urgency=medium + + * Add modes for FX531 LEDs + * Change where USB reset is called + * Add support for G531GT + * Remove duplicated code: it looks like there is at least *some* consistency + in Consumer-Device keycodes that ASUS uses + * `bat_charge_limit = 100` must be appended to the top of `/etc/rogcore.conf` + + -- Luke Jones Fri, 26 Jun 2020 16:47:03 +1200 + rog-core (0.11.1) focal; urgency=medium * Use DBUS_NAME instead of DBUS_IFACE when requesting the name diff --git a/rog-client/src/aura_dbus.rs b/rog-client/src/aura_dbus.rs index 4346b191..49615b40 100644 --- a/rog-client/src/aura_dbus.rs +++ b/rog-client/src/aura_dbus.rs @@ -110,8 +110,8 @@ impl AuraDbusWriter { #[inline] pub fn write_fan_mode(&self, level: u8) -> Result> { - let msg = - Message::new_method_call(DBUS_NAME, DBUS_PATH, DBUS_IFACE, "FanMode")?.append1(level); + let msg = Message::new_method_call(DBUS_NAME, DBUS_PATH, DBUS_IFACE, "SetFanMode")? + .append1(level); let r = self .connection .send_with_reply_and_block(msg, Duration::from_millis(5000))?; @@ -123,7 +123,7 @@ impl AuraDbusWriter { #[inline] pub fn write_charge_limit(&self, level: u8) -> Result> { - let msg = Message::new_method_call(DBUS_NAME, DBUS_PATH, DBUS_IFACE, "ChargeLimit")? + let msg = Message::new_method_call(DBUS_NAME, DBUS_PATH, DBUS_IFACE, "SetChargeLimit")? .append1(level); let r = self .connection diff --git a/rog-core/Cargo.toml b/rog-core/Cargo.toml index c0c912cd..0ee05008 100644 --- a/rog-core/Cargo.toml +++ b/rog-core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rog-daemon" -version = "0.11.1" +version = "0.12.2" license = "MPL-2.0" readme = "README.md" authors = ["Luke "] diff --git a/rog-core/src/daemon.rs b/rog-core/src/daemon.rs index 11ae0b74..3b60af8e 100644 --- a/rog-core/src/daemon.rs +++ b/rog-core/src/daemon.rs @@ -66,15 +66,6 @@ pub async fn start_daemon() -> Result<(), Box> { .do_command(AuraCommand::ReloadLast, &mut config) .await?; - // Possible Animatrix - let mut animatrix_writer = None; - if laptop.support_animatrix() { - if let Ok(dev) = AniMeWriter::new() { - animatrix_writer = Some(dev); - info!("Device has an AniMe Matrix display"); - } - } - // Set up the mutexes let config = Arc::new(Mutex::new(config)); let (resource, connection) = connection::new_system_sync()?; @@ -95,7 +86,9 @@ pub async fn start_daemon() -> Result<(), Box> { fan_mode, charge_limit, effect_cancel_signal, - ) = dbus_create_tree(); + fanmode_signal, + charge_limit_signal, + ) = dbus_create_tree(config.clone()); // We add the tree to the connection so that incoming method calls will be handled. tree.start_receive_send(&*connection); @@ -107,6 +100,21 @@ pub async fn start_daemon() -> Result<(), Box> { laptop.key_filter().to_owned(), ); + // Possible Animatrix + if laptop.support_animatrix() { + if let Ok(mut animatrix_writer) = AniMeWriter::new() { + info!("Device has an AniMe Matrix display"); + tokio::spawn(async move { + while let Some(image) = animatrix_recv.recv().await { + animatrix_writer + .do_command(AnimatrixCommand::WriteImage(image)) + .await + .unwrap_or_else(|err| warn!("{:?}", err)); + } + }); + } + } + let config1 = config.clone(); // start the keyboard reader and laptop-action loop tokio::spawn(async move { @@ -140,14 +148,36 @@ pub async fn start_daemon() -> Result<(), Box> { } }); - // If animatrix is supported, try doing a write + let connection1 = connection.clone(); + let config1 = config.clone(); tokio::spawn(async move { - if let Some(writer) = animatrix_writer.as_mut() { - while let Some(image) = animatrix_recv.recv().await { - writer - .do_command(AnimatrixCommand::WriteImage(image)) - .await - .unwrap_or_else(|err| warn!("{:?}", err)); + // Some small things we need to track, without passing all sorts of stuff around + let mut last_fan_mode = config1.lock().await.fan_mode; + let mut last_charge_limit = config1.lock().await.bat_charge_limit; + loop { + // Use tokio sleep to not hold up other threads + tokio::time::delay_for(std::time::Duration::from_millis(500)).await; + + let config = config1.lock().await; + if config.fan_mode != last_fan_mode { + last_fan_mode = config.fan_mode; + connection1 + .send( + fanmode_signal + .msg(&DBUS_PATH.into(), &DBUS_IFACE.into()) + .append1(last_fan_mode), + ) + .unwrap_or_else(|_| 0); + } + if config.bat_charge_limit != last_charge_limit { + last_charge_limit = config.bat_charge_limit; + connection1 + .send( + charge_limit_signal + .msg(&DBUS_PATH.into(), &DBUS_IFACE.into()) + .append1(last_charge_limit), + ) + .unwrap_or_else(|_| 0); } } }); @@ -156,7 +186,6 @@ pub async fn start_daemon() -> Result<(), Box> { loop { connection.process_all(); - // Check if a key press issued a command while let Some(command) = aura_command_recv.recv().await { let mut config = config.lock().await; match command { @@ -170,11 +199,7 @@ pub async fn start_daemon() -> Result<(), Box> { .await .unwrap_or_else(|err| warn!("{:?}", err)); connection - .send( - effect_cancel_signal - .msg(&DBUS_PATH.into(), &DBUS_IFACE.into()) - .append1(true), - ) + .send(effect_cancel_signal.msg(&DBUS_PATH.into(), &DBUS_IFACE.into())) .unwrap_or_else(|_| 0); } } diff --git a/rog-core/src/laptops.rs b/rog-core/src/laptops.rs index 1eb3b8ca..0876e05f 100644 --- a/rog-core/src/laptops.rs +++ b/rog-core/src/laptops.rs @@ -41,6 +41,11 @@ pub(crate) fn match_laptop() -> LaptopBase { fn choose_1866_device(prod: u16) -> LaptopBase { let dmi = sysfs_class::DmiId::default(); let board_name = dmi.board_name().expect("Could not get board_name"); + let prod_name = dmi.product_name().expect("Could not get board_name"); + + info!("Product name: {}", prod_name.trim()); + info!("Board name: {}", board_name.trim()); + let mut laptop = LaptopBase { usb_vendor: 0x0B05, usb_product: prod, @@ -55,50 +60,56 @@ fn choose_1866_device(prod: u16) -> LaptopBase { support_animatrix: false, //backlight: Backlight::new("intel_backlight").unwrap(), }; - match &board_name.as_str()[..5] { - "GA401" => { - // Has no RGB control - laptop.support_animatrix = true; - } - "GA502" => { - // Has no RGB control - } - "GX502" => { - laptop.supported_modes = vec![ - BuiltInModeByte::Single, - BuiltInModeByte::Breathing, - BuiltInModeByte::Strobe, - BuiltInModeByte::Rainbow, - BuiltInModeByte::Star, - BuiltInModeByte::Rain, - BuiltInModeByte::Highlight, - BuiltInModeByte::Laser, - BuiltInModeByte::Ripple, - BuiltInModeByte::Pulse, - BuiltInModeByte::Comet, - BuiltInModeByte::Flash, - ]; - } - "GM501" => { - laptop.supported_modes = vec![ - BuiltInModeByte::Single, - BuiltInModeByte::Breathing, - BuiltInModeByte::Strobe, - BuiltInModeByte::Rainbow, - ]; - } - "GX531" | "G531G" => { - laptop.supported_modes = vec![ - BuiltInModeByte::Single, - BuiltInModeByte::Breathing, - BuiltInModeByte::Strobe, - BuiltInModeByte::Rainbow, - BuiltInModeByte::Pulse, - ]; - } - _ => panic!("Unsupported laptop: {}, please request support at\nhttps://github.com/flukejones/rog-core", board_name), + + // GA401 + if board_name.starts_with("GA401") { + info!("No RGB control available"); + laptop.support_animatrix = true; + // GA502 + } else if board_name.starts_with("GA502") { + info!("No RGB control available"); + // GX502, G712 + } else if board_name.starts_with("GX502") { + laptop.supported_modes = vec![ + BuiltInModeByte::Single, + BuiltInModeByte::Breathing, + BuiltInModeByte::Strobe, + BuiltInModeByte::Rainbow, + BuiltInModeByte::Star, + BuiltInModeByte::Rain, + BuiltInModeByte::Highlight, + BuiltInModeByte::Laser, + BuiltInModeByte::Ripple, + BuiltInModeByte::Pulse, + BuiltInModeByte::Comet, + BuiltInModeByte::Flash, + ]; + // GM501 + } else if board_name.starts_with("GM501") { + laptop.supported_modes = vec![ + BuiltInModeByte::Single, + BuiltInModeByte::Breathing, + BuiltInModeByte::Strobe, + BuiltInModeByte::Rainbow, + ]; + // G531 + } else if board_name.starts_with("GX531") + || board_name.starts_with("G531") + || board_name.starts_with("G712") + { + laptop.supported_modes = vec![ + BuiltInModeByte::Single, + BuiltInModeByte::Breathing, + BuiltInModeByte::Strobe, + BuiltInModeByte::Rainbow, + BuiltInModeByte::Pulse, + ]; + } else { + panic!( + "Unsupported laptop, please request support at\nhttps://github.com/flukejones/rog-core" + ); } - info!("Board name: {}", board_name.as_str().trim()); + laptop } diff --git a/rog-core/src/led_control.rs b/rog-core/src/led_control.rs index e96f2bdc..8407dc94 100644 --- a/rog-core/src/led_control.rs +++ b/rog-core/src/led_control.rs @@ -16,6 +16,7 @@ use std::marker::PhantomData; use std::ptr::NonNull; use std::time::Duration; +#[derive(Clone)] pub enum AuraCommand { BrightInc, BrightDec, diff --git a/rog-core/src/main.rs b/rog-core/src/main.rs index c51d3d1c..dc5cedee 100644 --- a/rog-core/src/main.rs +++ b/rog-core/src/main.rs @@ -8,7 +8,7 @@ use rog_client::{ AuraDbusWriter, LED_MSG_LEN, }; -static VERSION: &str = "0.11.1"; +static VERSION: &str = "0.12.2"; #[derive(Debug, Options)] struct CLIStart { diff --git a/rog-core/src/rog_dbus.rs b/rog-core/src/rog_dbus.rs index e4a0be30..17b52ede 100644 --- a/rog-core/src/rog_dbus.rs +++ b/rog-core/src/rog_dbus.rs @@ -1,3 +1,4 @@ +use crate::config::Config; use crate::daemon::DbusU8Type; use crate::led_control::AuraCommand; use crate::rogcore::FanLevel; @@ -10,7 +11,7 @@ use tokio::sync::{ Mutex, }; -pub(super) fn dbus_create_ledmsg_method(sender: Mutex>) -> Method { +pub(super) fn dbus_set_ledmsg(sender: Mutex>) -> Method { let factory = Factory::new_sync::<()>(); factory // method for ledmessage @@ -35,9 +36,7 @@ pub(super) fn dbus_create_ledmsg_method(sender: Mutex>) -> M .inarg::, _>("bytearray") } -pub(super) fn dbus_create_ledmultizone_method( - sender: Mutex>, -) -> Method { +pub(super) fn dbus_set_ledmultizone(sender: Mutex>) -> Method { let factory = Factory::new_sync::<()>(); factory // method for ledmessage @@ -68,9 +67,7 @@ pub(super) fn dbus_create_ledmultizone_method( .annotate("org.freedesktop.DBus.Method.NoReply", "true") } -pub(super) fn dbus_create_ledeffect_method( - sender: Mutex>, -) -> Method { +pub(super) fn dbus_set_ledeffect(sender: Mutex>) -> Method { let factory = Factory::new_sync::<()>(); factory // method for ledmessage @@ -114,7 +111,7 @@ pub(super) fn dbus_create_ledeffect_method( .annotate("org.freedesktop.DBus.Method.NoReply", "true") } -pub(super) fn dbus_create_animatrix_method( +pub(super) fn dbus_set_animatrix( sender: Mutex>>>, // need mutex only to get interior mutability in MTSync ) -> Method { let factory = Factory::new_sync::<()>(); @@ -138,11 +135,11 @@ pub(super) fn dbus_create_animatrix_method( .annotate("org.freedesktop.DBus.Method.NoReply", "true") } -pub(super) fn dbus_create_fan_mode_method(data: DbusU8Type) -> Method { +pub(super) fn dbus_set_fan_mode(data: DbusU8Type) -> Method { let factory = Factory::new_sync::<()>(); factory // method for ledmessage - .method("FanMode", (), { + .method("SetFanMode", (), { move |m| { if let Ok(mut lock) = data.try_lock() { let mut iter = m.msg.iter_init(); @@ -162,11 +159,43 @@ pub(super) fn dbus_create_fan_mode_method(data: DbusU8Type) -> Method("byte") } -pub(super) fn dbus_create_charge_limit_method(data: DbusU8Type) -> Method { +pub(super) fn dbus_get_fan_mode(config: Arc>) -> Method { + let factory = Factory::new_sync::<()>(); + factory + .method("GetFanMode", (), { + move |m| { + if let Ok(lock) = config.try_lock() { + let mret = m.msg.method_return().append1(lock.fan_mode); + Ok(vec![mret]) + } else { + Err(MethodErr::failed("Could not lock config for access")) + } + } + }) + .outarg::<&str, _>("value") +} + +pub(super) fn dbus_get_charge_limit(config: Arc>) -> Method { + let factory = Factory::new_sync::<()>(); + factory + .method("GetChargeLimit", (), { + move |m| { + if let Ok(lock) = config.try_lock() { + let mret = m.msg.method_return().append1(lock.bat_charge_limit); + Ok(vec![mret]) + } else { + Err(MethodErr::failed("Could not lock config for access")) + } + } + }) + .outarg::<&str, _>("value") +} + +pub(super) fn dbus_set_charge_limit(data: DbusU8Type) -> Method { let factory = Factory::new_sync::<()>(); factory // method for ledmessage - .method("ChargeLimit", (), { + .method("SetChargeLimit", (), { move |m| { if let Ok(mut lock) = data.try_lock() { let mut iter = m.msg.iter_init(); @@ -187,7 +216,9 @@ pub(super) fn dbus_create_charge_limit_method(data: DbusU8Type) -> Method ( +pub(super) fn dbus_create_tree( + config: Arc>, +) -> ( Tree, Sender, Receiver, @@ -195,6 +226,8 @@ pub(super) fn dbus_create_tree() -> ( DbusU8Type, DbusU8Type, Arc>, + Arc>, + Arc>, ) { let (aura_command_send, aura_command_recv) = channel::(1); let (animatrix_send, animatrix_recv) = channel::>>(1); @@ -204,6 +237,12 @@ pub(super) fn dbus_create_tree() -> ( let factory = Factory::new_sync::<()>(); let effect_cancel_sig = Arc::new(factory.signal("LedCancelEffect", ())); + let fanmode_changed_sig = Arc::new(factory.signal("FanModeChanged", ()).sarg::("value")); + let chrg_limit_changed_sig = Arc::new( + factory + .signal("ChargeLimitChanged", ()) + .sarg::("value"), + ); let tree = factory .tree(()) @@ -211,19 +250,17 @@ pub(super) fn dbus_create_tree() -> ( factory.object_path(DBUS_PATH, ()).introspectable().add( factory .interface(DBUS_IFACE, ()) - .add_m(dbus_create_ledmsg_method(Mutex::new( - aura_command_send.clone(), - ))) - .add_m(dbus_create_ledmultizone_method(Mutex::new( - aura_command_send.clone(), - ))) - .add_m(dbus_create_ledeffect_method(Mutex::new( - aura_command_send.clone(), - ))) - .add_m(dbus_create_animatrix_method(Mutex::new(animatrix_send))) - .add_m(dbus_create_fan_mode_method(fan_mode.clone())) - .add_m(dbus_create_charge_limit_method(charge_limit.clone())) - .add_s(effect_cancel_sig.clone()), + .add_m(dbus_set_ledmsg(Mutex::new(aura_command_send.clone()))) + .add_m(dbus_set_ledmultizone(Mutex::new(aura_command_send.clone()))) + .add_m(dbus_set_ledeffect(Mutex::new(aura_command_send.clone()))) + .add_m(dbus_set_animatrix(Mutex::new(animatrix_send))) + .add_m(dbus_set_fan_mode(fan_mode.clone())) + .add_m(dbus_set_charge_limit(charge_limit.clone())) + .add_m(dbus_get_fan_mode(config.clone())) + .add_m(dbus_get_charge_limit(config)) + .add_s(effect_cancel_sig.clone()) + .add_s(fanmode_changed_sig.clone()) + .add_s(chrg_limit_changed_sig.clone()), ), ) .add(factory.object_path("/", ()).introspectable()); @@ -235,5 +272,7 @@ pub(super) fn dbus_create_tree() -> ( fan_mode, charge_limit, effect_cancel_sig, + fanmode_changed_sig, + chrg_limit_changed_sig, ) } diff --git a/rog-core/src/rogcore.rs b/rog-core/src/rogcore.rs index c919bcc0..bb581c69 100644 --- a/rog-core/src/rogcore.rs +++ b/rog-core/src/rogcore.rs @@ -154,8 +154,10 @@ impl RogCore { } pub fn fan_mode_step(&mut self, config: &mut Config) -> Result<(), Box> { + // re-read the config here in case a user changed the pstate settings + config.read(); + let mut n = config.fan_mode; - info!("Current fan mode: {:?}", FanLevel::from(n)); // wrap around the step number if n < 2 { n += 1; @@ -170,18 +172,15 @@ impl RogCore { mode: FanLevel, config: &mut Config, ) -> Result<(), Box> { - // re-read the config here in case a user changed the pstate settings - config.read(); // Set CPU pstate if let Ok(pstate) = intel_pstate::PState::new() { - info!("Setting pstate for Intel CPU"); match mode { FanLevel::Normal => { pstate.set_min_perf_pct(config.mode_performance.normal.min_percentage)?; pstate.set_max_perf_pct(config.mode_performance.normal.max_percentage)?; pstate.set_no_turbo(config.mode_performance.normal.no_turbo)?; info!( - "CPU Power: min-freq: {:?}, max-freq: {:?}, turbo: {:?}", + "Intel CPU Power: min: {:?}%, max: {:?}%, turbo: {:?}", config.mode_performance.normal.min_percentage, config.mode_performance.normal.max_percentage, !config.mode_performance.normal.no_turbo @@ -192,7 +191,7 @@ impl RogCore { pstate.set_max_perf_pct(config.mode_performance.boost.max_percentage)?; pstate.set_no_turbo(config.mode_performance.boost.no_turbo)?; info!( - "CPU Power: min-freq: {:?}, max-freq: {:?}, turbo: {:?}", + "Intel CPU Power: min: {:?}%, max: {:?}%, turbo: {:?}", config.mode_performance.boost.min_percentage, config.mode_performance.boost.max_percentage, !config.mode_performance.boost.no_turbo @@ -203,7 +202,7 @@ impl RogCore { pstate.set_max_perf_pct(config.mode_performance.silent.max_percentage)?; pstate.set_no_turbo(config.mode_performance.silent.no_turbo)?; info!( - "CPU Power: min-freq: {:?}, max-freq: {:?}, turbo: {:?}", + "Intel CPU Power: min: {:?}%, max: {:?}%, turbo: {:?}", config.mode_performance.silent.min_percentage, config.mode_performance.silent.max_percentage, !config.mode_performance.silent.no_turbo @@ -230,7 +229,7 @@ impl RogCore { file.write_all(boost.as_bytes()).unwrap_or_else(|err| { error!("Could not write to {}, {:?}", AMD_BOOST_PATH, err) }); - info!("CPU Power: turbo: {:?}", boost); + info!("AMD CPU Turbo: {:?}", boost); } FanLevel::Boost => { let boost = if config.mode_performance.boost.no_turbo { @@ -241,7 +240,7 @@ impl RogCore { file.write_all(boost.as_bytes()).unwrap_or_else(|err| { error!("Could not write to {}, {:?}", AMD_BOOST_PATH, err) }); - info!("CPU Power: turbo: {:?}", boost); + info!("AMD CPU Turbo: {:?}", boost); } FanLevel::Silent => { let boost = if config.mode_performance.silent.no_turbo { @@ -252,7 +251,7 @@ impl RogCore { file.write_all(boost.as_bytes()).unwrap_or_else(|err| { error!("Could not write to {}, {:?}", AMD_BOOST_PATH, err) }); - info!("CPU Power: turbo: {:?}", boost); + info!("AMD CPU Turbo: {:?}", boost); } } }