Compare commits
10 Commits
ef7a8da96b
...
moasta
| Author | SHA1 | Date | |
|---|---|---|---|
| b1dcf894bb | |||
| aae371b330 | |||
| fb21f1cda1 | |||
| 8fb605e3cb | |||
| 24c6fa629d | |||
|
|
0dba2464b2 | ||
| 14b9edf59c | |||
| 8840a465e5 | |||
| 66a393b5d3 | |||
| 010762445a |
BIN
13Versuch2.FCStd
BIN
13Versuch2.FCStd
Binary file not shown.
6
README.md
Normal file
6
README.md
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# Design documents cooling solution Radeon Instinct MI50
|
||||||
|
|
||||||
|
## Stecker im Duct
|
||||||
|
|
||||||
|
- z-Versatz der DatumPlaneSteckerEnde muss auf überstehende Länge des Stromsteckers aus dem Kartengehäuse angepasst werden
|
||||||
|
|
||||||
BIN
SteckerImDuct.FCStd
Normal file
BIN
SteckerImDuct.FCStd
Normal file
Binary file not shown.
BIN
SteckerImDuct2Karten.FCStd
Normal file
BIN
SteckerImDuct2Karten.FCStd
Normal file
Binary file not shown.
BIN
SteckerImDuct2KartenVar2.FCStd
Normal file
BIN
SteckerImDuct2KartenVar2.FCStd
Normal file
Binary file not shown.
932
fancontrol/Cargo.lock
generated
Normal file
932
fancontrol/Cargo.lock
generated
Normal file
@@ -0,0 +1,932 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 4
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ahash"
|
||||||
|
version = "0.8.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"once_cell",
|
||||||
|
"version_check",
|
||||||
|
"zerocopy",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "allocator-api2"
|
||||||
|
version = "0.2.21"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "android_system_properties"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "arraydeque"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7d902e3d592a523def97af8f317b08ce16b7ab854c1985a0c671e6f15cebc236"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-trait"
|
||||||
|
version = "0.1.89"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "autocfg"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "base64"
|
||||||
|
version = "0.21.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "2.10.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3"
|
||||||
|
dependencies = [
|
||||||
|
"serde_core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "block-buffer"
|
||||||
|
version = "0.10.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
|
||||||
|
dependencies = [
|
||||||
|
"generic-array",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bumpalo"
|
||||||
|
version = "3.19.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cc"
|
||||||
|
version = "1.2.44"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "37521ac7aabe3d13122dc382493e20c9416f299d2ccd5b3a5340a2570cdeb0f3"
|
||||||
|
dependencies = [
|
||||||
|
"find-msvc-tools",
|
||||||
|
"shlex",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "1.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "chrono"
|
||||||
|
version = "0.4.42"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2"
|
||||||
|
dependencies = [
|
||||||
|
"iana-time-zone",
|
||||||
|
"js-sys",
|
||||||
|
"num-traits",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"windows-link",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "config"
|
||||||
|
version = "0.14.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "68578f196d2a33ff61b27fae256c3164f65e36382648e30666dde05b8cc9dfdf"
|
||||||
|
dependencies = [
|
||||||
|
"async-trait",
|
||||||
|
"convert_case",
|
||||||
|
"json5",
|
||||||
|
"nom",
|
||||||
|
"pathdiff",
|
||||||
|
"ron",
|
||||||
|
"rust-ini",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"toml 0.8.23",
|
||||||
|
"yaml-rust2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "const-random"
|
||||||
|
version = "0.1.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359"
|
||||||
|
dependencies = [
|
||||||
|
"const-random-macro",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "const-random-macro"
|
||||||
|
version = "0.1.16"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom",
|
||||||
|
"once_cell",
|
||||||
|
"tiny-keccak",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "convert_case"
|
||||||
|
version = "0.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-segmentation",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "core-foundation-sys"
|
||||||
|
version = "0.8.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cpufeatures"
|
||||||
|
version = "0.2.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crunchy"
|
||||||
|
version = "0.2.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crypto-common"
|
||||||
|
version = "0.1.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
|
||||||
|
dependencies = [
|
||||||
|
"generic-array",
|
||||||
|
"typenum",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "digest"
|
||||||
|
version = "0.10.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
|
||||||
|
dependencies = [
|
||||||
|
"block-buffer",
|
||||||
|
"crypto-common",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dlv-list"
|
||||||
|
version = "0.5.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "442039f5147480ba31067cb00ada1adae6892028e40e45fc5de7b7df6dcc1b5f"
|
||||||
|
dependencies = [
|
||||||
|
"const-random",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "encoding_rs"
|
||||||
|
version = "0.8.35"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "equivalent"
|
||||||
|
version = "1.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fancontrol"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"chrono",
|
||||||
|
"config",
|
||||||
|
"serde",
|
||||||
|
"signal-hook",
|
||||||
|
"tempdir",
|
||||||
|
"toml 0.5.11",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "find-msvc-tools"
|
||||||
|
version = "0.1.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "52051878f80a721bb68ebfbc930e07b65ba72f2da88968ea5c06fd6ca3d3a127"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fuchsia-cprng"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "generic-array"
|
||||||
|
version = "0.14.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4bb6743198531e02858aeaea5398fcc883e71851fcbcb5a2f773e2fb6cb1edf2"
|
||||||
|
dependencies = [
|
||||||
|
"typenum",
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "getrandom"
|
||||||
|
version = "0.2.16"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"wasi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashbrown"
|
||||||
|
version = "0.14.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
|
||||||
|
dependencies = [
|
||||||
|
"ahash",
|
||||||
|
"allocator-api2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashbrown"
|
||||||
|
version = "0.16.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashlink"
|
||||||
|
version = "0.8.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7"
|
||||||
|
dependencies = [
|
||||||
|
"hashbrown 0.14.5",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "iana-time-zone"
|
||||||
|
version = "0.1.64"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb"
|
||||||
|
dependencies = [
|
||||||
|
"android_system_properties",
|
||||||
|
"core-foundation-sys",
|
||||||
|
"iana-time-zone-haiku",
|
||||||
|
"js-sys",
|
||||||
|
"log",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"windows-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "iana-time-zone-haiku"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "indexmap"
|
||||||
|
version = "2.12.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6717a8d2a5a929a1a2eb43a12812498ed141a0bcfb7e8f7844fbdbe4303bba9f"
|
||||||
|
dependencies = [
|
||||||
|
"equivalent",
|
||||||
|
"hashbrown 0.16.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itoa"
|
||||||
|
version = "1.0.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "js-sys"
|
||||||
|
version = "0.3.82"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b011eec8cc36da2aab2d5cff675ec18454fad408585853910a202391cf9f8e65"
|
||||||
|
dependencies = [
|
||||||
|
"once_cell",
|
||||||
|
"wasm-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "json5"
|
||||||
|
version = "0.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "96b0db21af676c1ce64250b5f40f3ce2cf27e4e47cb91ed91eb6fe9350b430c1"
|
||||||
|
dependencies = [
|
||||||
|
"pest",
|
||||||
|
"pest_derive",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libc"
|
||||||
|
version = "0.2.177"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "log"
|
||||||
|
version = "0.4.28"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memchr"
|
||||||
|
version = "2.7.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "minimal-lexical"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nom"
|
||||||
|
version = "7.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
"minimal-lexical",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-traits"
|
||||||
|
version = "0.2.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "once_cell"
|
||||||
|
version = "1.21.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ordered-multimap"
|
||||||
|
version = "0.7.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "49203cdcae0030493bad186b28da2fa25645fa276a51b6fec8010d281e02ef79"
|
||||||
|
dependencies = [
|
||||||
|
"dlv-list",
|
||||||
|
"hashbrown 0.14.5",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pathdiff"
|
||||||
|
version = "0.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pest"
|
||||||
|
version = "2.8.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "989e7521a040efde50c3ab6bbadafbe15ab6dc042686926be59ac35d74607df4"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
"ucd-trie",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pest_derive"
|
||||||
|
version = "2.8.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "187da9a3030dbafabbbfb20cb323b976dc7b7ce91fcd84f2f74d6e31d378e2de"
|
||||||
|
dependencies = [
|
||||||
|
"pest",
|
||||||
|
"pest_generator",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pest_generator"
|
||||||
|
version = "2.8.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "49b401d98f5757ebe97a26085998d6c0eecec4995cad6ab7fc30ffdf4b052843"
|
||||||
|
dependencies = [
|
||||||
|
"pest",
|
||||||
|
"pest_meta",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pest_meta"
|
||||||
|
version = "2.8.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "72f27a2cfee9f9039c4d86faa5af122a0ac3851441a34865b8a043b46be0065a"
|
||||||
|
dependencies = [
|
||||||
|
"pest",
|
||||||
|
"sha2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.103"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.41"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand"
|
||||||
|
version = "0.4.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293"
|
||||||
|
dependencies = [
|
||||||
|
"fuchsia-cprng",
|
||||||
|
"libc",
|
||||||
|
"rand_core 0.3.1",
|
||||||
|
"rdrand",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_core"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
|
||||||
|
dependencies = [
|
||||||
|
"rand_core 0.4.2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_core"
|
||||||
|
version = "0.4.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rdrand"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
|
||||||
|
dependencies = [
|
||||||
|
"rand_core 0.3.1",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "remove_dir_all"
|
||||||
|
version = "0.5.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
|
||||||
|
dependencies = [
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ron"
|
||||||
|
version = "0.8.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94"
|
||||||
|
dependencies = [
|
||||||
|
"base64",
|
||||||
|
"bitflags",
|
||||||
|
"serde",
|
||||||
|
"serde_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rust-ini"
|
||||||
|
version = "0.20.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3e0698206bcb8882bf2a9ecb4c1e7785db57ff052297085a6efd4fe42302068a"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"ordered-multimap",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustversion"
|
||||||
|
version = "1.0.22"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ryu"
|
||||||
|
version = "1.0.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde"
|
||||||
|
version = "1.0.228"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
|
||||||
|
dependencies = [
|
||||||
|
"serde_core",
|
||||||
|
"serde_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_core"
|
||||||
|
version = "1.0.228"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
|
||||||
|
dependencies = [
|
||||||
|
"serde_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_derive"
|
||||||
|
version = "1.0.228"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_json"
|
||||||
|
version = "1.0.145"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c"
|
||||||
|
dependencies = [
|
||||||
|
"itoa",
|
||||||
|
"memchr",
|
||||||
|
"ryu",
|
||||||
|
"serde",
|
||||||
|
"serde_core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_spanned"
|
||||||
|
version = "0.6.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sha2"
|
||||||
|
version = "0.10.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"cpufeatures",
|
||||||
|
"digest",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "shlex"
|
||||||
|
version = "1.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "signal-hook"
|
||||||
|
version = "0.3.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d881a16cf4426aa584979d30bd82cb33429027e42122b169753d6ef1085ed6e2"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"signal-hook-registry",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "signal-hook-registry"
|
||||||
|
version = "1.4.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b2a4719bff48cee6b39d12c020eeb490953ad2443b7055bd0b21fca26bd8c28b"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "2.0.108"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "da58917d35242480a05c2897064da0a80589a2a0476c9a3f2fdc83b53502e917"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tempdir"
|
||||||
|
version = "0.3.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8"
|
||||||
|
dependencies = [
|
||||||
|
"rand",
|
||||||
|
"remove_dir_all",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tiny-keccak"
|
||||||
|
version = "2.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237"
|
||||||
|
dependencies = [
|
||||||
|
"crunchy",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml"
|
||||||
|
version = "0.5.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml"
|
||||||
|
version = "0.8.23"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
"serde_spanned",
|
||||||
|
"toml_datetime",
|
||||||
|
"toml_edit",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml_datetime"
|
||||||
|
version = "0.6.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml_edit"
|
||||||
|
version = "0.22.27"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a"
|
||||||
|
dependencies = [
|
||||||
|
"indexmap",
|
||||||
|
"serde",
|
||||||
|
"serde_spanned",
|
||||||
|
"toml_datetime",
|
||||||
|
"toml_write",
|
||||||
|
"winnow",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml_write"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "typenum"
|
||||||
|
version = "1.19.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ucd-trie"
|
||||||
|
version = "0.1.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-ident"
|
||||||
|
version = "1.0.22"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-segmentation"
|
||||||
|
version = "1.12.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "version_check"
|
||||||
|
version = "0.9.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasi"
|
||||||
|
version = "0.11.1+wasi-snapshot-preview1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen"
|
||||||
|
version = "0.2.105"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "da95793dfc411fbbd93f5be7715b0578ec61fe87cb1a42b12eb625caa5c5ea60"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"once_cell",
|
||||||
|
"rustversion",
|
||||||
|
"wasm-bindgen-macro",
|
||||||
|
"wasm-bindgen-shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-macro"
|
||||||
|
version = "0.2.105"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "04264334509e04a7bf8690f2384ef5265f05143a4bff3889ab7a3269adab59c2"
|
||||||
|
dependencies = [
|
||||||
|
"quote",
|
||||||
|
"wasm-bindgen-macro-support",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-macro-support"
|
||||||
|
version = "0.2.105"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "420bc339d9f322e562942d52e115d57e950d12d88983a14c79b86859ee6c7ebc"
|
||||||
|
dependencies = [
|
||||||
|
"bumpalo",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"wasm-bindgen-shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-shared"
|
||||||
|
version = "0.2.105"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "76f218a38c84bcb33c25ec7059b07847d465ce0e0a76b995e134a45adcb6af76"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi"
|
||||||
|
version = "0.3.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||||
|
dependencies = [
|
||||||
|
"winapi-i686-pc-windows-gnu",
|
||||||
|
"winapi-x86_64-pc-windows-gnu",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-i686-pc-windows-gnu"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-x86_64-pc-windows-gnu"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-core"
|
||||||
|
version = "0.62.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb"
|
||||||
|
dependencies = [
|
||||||
|
"windows-implement",
|
||||||
|
"windows-interface",
|
||||||
|
"windows-link",
|
||||||
|
"windows-result",
|
||||||
|
"windows-strings",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-implement"
|
||||||
|
version = "0.60.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-interface"
|
||||||
|
version = "0.59.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-link"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-result"
|
||||||
|
version = "0.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5"
|
||||||
|
dependencies = [
|
||||||
|
"windows-link",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-strings"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091"
|
||||||
|
dependencies = [
|
||||||
|
"windows-link",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winnow"
|
||||||
|
version = "0.7.13"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "yaml-rust2"
|
||||||
|
version = "0.8.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8902160c4e6f2fb145dbe9d6760a75e3c9522d8bf796ed7047c85919ac7115f8"
|
||||||
|
dependencies = [
|
||||||
|
"arraydeque",
|
||||||
|
"encoding_rs",
|
||||||
|
"hashlink",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zerocopy"
|
||||||
|
version = "0.8.27"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c"
|
||||||
|
dependencies = [
|
||||||
|
"zerocopy-derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zerocopy-derive"
|
||||||
|
version = "0.8.27"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
18
fancontrol/Cargo.toml
Normal file
18
fancontrol/Cargo.toml
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
[package]
|
||||||
|
name = "fancontrol"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "amd_gpu_control"
|
||||||
|
path = "src/main.rs"
|
||||||
|
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
config = "0.14"
|
||||||
|
toml = "0.5"
|
||||||
|
tempdir = "0.3"
|
||||||
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
#tokio = { version = "1", features = ["full"] }
|
||||||
|
chrono = "0.4"
|
||||||
|
signal-hook = "0.3"
|
||||||
10
fancontrol/README.md
Normal file
10
fancontrol/README.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
# Pwm fan control for Instinct cards
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
- Build with `cargo build --release`
|
||||||
|
- copy `target/release/amd_gpu_control` to `/usr/local/bin/`
|
||||||
|
- copy the systemd service file `instinct_control.service` to `/etc/systemd/system/`
|
||||||
|
- copy the config file `config.toml` to `/etc/instinct_control/` and customize
|
||||||
|
- verify pwm devices by hand
|
||||||
|
- ensure only root can write the config to prevent path injection
|
||||||
|
- `systemctl enable instinct_control.service`
|
||||||
28
fancontrol/config.toml
Normal file
28
fancontrol/config.toml
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
# one device section per card to be controlled
|
||||||
|
[[device]]
|
||||||
|
# name for log display
|
||||||
|
name = "Higher Instinct"
|
||||||
|
# pci id, determine with lspci
|
||||||
|
pci_id = "0b:00.0"
|
||||||
|
# parameters for fan control, device to be used and index of the pwm channel in the
|
||||||
|
# corresponding hmon device
|
||||||
|
fan_control = {device = "nct6775.656", pwm_number = 1}
|
||||||
|
#fan_control = {ipmi_command = "external command line"} # currently not implemented.
|
||||||
|
|
||||||
|
[[device]]
|
||||||
|
name = "Lower Instinct"
|
||||||
|
pci_id = "0e:00.0"
|
||||||
|
fan_control = {device = "nct6775.656", pwm_number = 3}
|
||||||
|
|
||||||
|
[global]
|
||||||
|
# # Delay before fan is spun down when temperature falls below threshold for current level
|
||||||
|
# spindown_hysteresis_seconds = 30
|
||||||
|
# # If specifying any of the following, give all 4 of them and make sure pwm_steps has one entry more than the others
|
||||||
|
# pwm_steps = [51, 102, 153, 180, 204, 225, 255]
|
||||||
|
pwm_steps = [63, 80, 102, 153, 180, 204, 225, 255]
|
||||||
|
# thresholds_t_edge = [70.0, 80.0, 90.0, 92.0, 94.0, 96.0]
|
||||||
|
thresholds_t_edge = [48.0, 70.0, 80.0, 90.0, 92.0, 94.0, 96.0]
|
||||||
|
# thresholds_t_junction = [75.0, 92.0, 94.0, 97.0, 98.0, 100.0]
|
||||||
|
thresholds_t_junction = [50.0, 75.0, 85.0, 92.0, 95.0, 98.0, 100.0]
|
||||||
|
# thresholds_t_memory = [75.0, 85.0, 90.0, 91.0, 92.0, 94.0]
|
||||||
|
thresholds_t_memory = [48.0, 75.0, 85.0, 90.0, 91.0, 92.0, 94.0]
|
||||||
18
fancontrol/instinct_control.service
Normal file
18
fancontrol/instinct_control.service
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=AMD Instinct custom fan control
|
||||||
|
After=sysinit.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
User=root
|
||||||
|
Group=root
|
||||||
|
|
||||||
|
|
||||||
|
ExecStart=/usr/local/bin/amd_gpu_control --config /etc/instinct_control/config.toml
|
||||||
|
|
||||||
|
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=2
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
# Enable auto-start at boot
|
||||||
|
WantedBy=multi-user.target
|
||||||
474
fancontrol/src/main.rs
Normal file
474
fancontrol/src/main.rs
Normal file
@@ -0,0 +1,474 @@
|
|||||||
|
use config::{Config as ConfigBuilder, File};
|
||||||
|
use serde::Deserialize;
|
||||||
|
use signal_hook::{consts, flag};
|
||||||
|
use std::env;
|
||||||
|
use std::fs;
|
||||||
|
use std::io::Write;
|
||||||
|
use std::path::Path;
|
||||||
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
use std::sync::Arc;
|
||||||
|
use std::thread;
|
||||||
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug)]
|
||||||
|
struct Config {
|
||||||
|
#[serde(default)]
|
||||||
|
global: GlobalConfig,
|
||||||
|
device: Vec<DeviceConfig>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug, Clone)]
|
||||||
|
struct GlobalConfig {
|
||||||
|
#[serde(default = "default_hysteresis")]
|
||||||
|
spindown_hysteresis_seconds: u32,
|
||||||
|
#[serde(default = "default_pwm_steps")]
|
||||||
|
pwm_steps: Vec<u8>,
|
||||||
|
#[serde(default = "default_thresholds_t_edge")]
|
||||||
|
thresholds_t_edge: Vec<f32>,
|
||||||
|
#[serde(default = "default_thresholds_t_junction")]
|
||||||
|
thresholds_t_junction: Vec<f32>,
|
||||||
|
#[serde(default = "default_thresholds_t_memory")]
|
||||||
|
thresholds_t_memory: Vec<f32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for GlobalConfig {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
spindown_hysteresis_seconds: 30,
|
||||||
|
pwm_steps: vec![51, 102, 153, 180, 204, 225, 255],
|
||||||
|
thresholds_t_edge: vec![70.0, 80.0, 90.0, 92.0, 94.0, 96.0],
|
||||||
|
thresholds_t_junction: vec![75.0, 92.0, 94.0, 97.0, 98.0, 100.0],
|
||||||
|
thresholds_t_memory: vec![75.0, 85.0, 90.0, 91.0, 92.0, 94.0],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// somewhat boilerplaty, but want to support partial specification of global options while keeping defaults in one place.
|
||||||
|
fn default_hysteresis() -> u32 {
|
||||||
|
GlobalConfig::default().spindown_hysteresis_seconds
|
||||||
|
}
|
||||||
|
|
||||||
|
fn default_pwm_steps() -> Vec<u8> {
|
||||||
|
GlobalConfig::default().pwm_steps
|
||||||
|
}
|
||||||
|
|
||||||
|
fn default_thresholds_t_edge() -> Vec<f32> {
|
||||||
|
GlobalConfig::default().thresholds_t_edge
|
||||||
|
}
|
||||||
|
|
||||||
|
fn default_thresholds_t_junction() -> Vec<f32> {
|
||||||
|
GlobalConfig::default().thresholds_t_junction
|
||||||
|
}
|
||||||
|
|
||||||
|
fn default_thresholds_t_memory() -> Vec<f32> {
|
||||||
|
GlobalConfig::default().thresholds_t_memory
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_global_config(gc: &GlobalConfig) -> bool {
|
||||||
|
if !gc.pwm_steps.iter().is_sorted() {
|
||||||
|
eprintln!("pwm steps not monotonic");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if !gc.thresholds_t_edge.iter().is_sorted() {
|
||||||
|
eprintln!("t_edge thresholds not sorted");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if !gc.thresholds_t_junction.iter().is_sorted() {
|
||||||
|
eprintln!("t_junction thresholds not sorted");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if !gc.thresholds_t_memory.iter().is_sorted() {
|
||||||
|
eprintln!("t_memory thresholds not sorted");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if gc.thresholds_t_edge.len() != gc.thresholds_t_junction.len()
|
||||||
|
|| gc.thresholds_t_junction.len() != gc.thresholds_t_memory.len()
|
||||||
|
|| gc.thresholds_t_edge.len() + 1 != gc.pwm_steps.len()
|
||||||
|
{
|
||||||
|
eprintln!("Temperature threshold vectors need to be all of same length and number of pwm steps needs to be one more.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug)]
|
||||||
|
struct DeviceConfig {
|
||||||
|
name: String,
|
||||||
|
pci_id: String,
|
||||||
|
fan_control: FanControlType,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
pub enum FanControlType {
|
||||||
|
Ipmi { ipmi_command: String },
|
||||||
|
Pwm { device: String, pwm_number: u32 },
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct ExpandedDeviceConfig {
|
||||||
|
device: String,
|
||||||
|
power: PowerPath,
|
||||||
|
pwm: PwmPath,
|
||||||
|
temperature: TemperatureFiles,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Debug)]
|
||||||
|
struct TemperatureFiles {
|
||||||
|
junction: String,
|
||||||
|
overall: String,
|
||||||
|
memory: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug)]
|
||||||
|
struct PwmPath {
|
||||||
|
file: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug)]
|
||||||
|
struct PowerPath {
|
||||||
|
file: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct PwmControlState {
|
||||||
|
value: u8, // 1 manual control
|
||||||
|
}
|
||||||
|
|
||||||
|
const MANUAL_CONTROL_STATE: PwmControlState = PwmControlState { value: 1 };
|
||||||
|
|
||||||
|
fn find_hwmon_for_device(pci_addr_or_device_name: &str) -> Result<String, String> {
|
||||||
|
let hwmon_dir = Path::new("/sys/class/hwmon");
|
||||||
|
|
||||||
|
for entry in fs::read_dir(hwmon_dir).map_err(|e| format!("HWMON read error: {}", e))? {
|
||||||
|
let entry = entry.map_err(|e| format!("HWMON entry error: {}", e))?;
|
||||||
|
let path = entry.path();
|
||||||
|
|
||||||
|
if !path.is_dir() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let device_path = path.join("device");
|
||||||
|
if !device_path.exists() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let target = fs::read_link(&device_path).map_err(|e| format!("Link read error: {}", e))?;
|
||||||
|
|
||||||
|
if target.to_string_lossy().contains(pci_addr_or_device_name) {
|
||||||
|
return Ok(path
|
||||||
|
.to_str()
|
||||||
|
.map(|s| s.to_string())
|
||||||
|
.ok_or("Invalid hwmon name")?);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Err(format!(
|
||||||
|
"HWMON not found for device: {}",
|
||||||
|
pci_addr_or_device_name
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn determine_min_pwm_setpoint(
|
||||||
|
global_options: &GlobalConfig,
|
||||||
|
t_edge: f32,
|
||||||
|
t_junction: f32,
|
||||||
|
t_memory: f32,
|
||||||
|
previous_setpoint: u8,
|
||||||
|
) -> u8 {
|
||||||
|
fn lookup_pwm_level(value: f32, levels: &Vec<u8>, thresholds: &Vec<f32>) -> u8 {
|
||||||
|
let mut level = levels[0];
|
||||||
|
for (i, &th) in thresholds.iter().enumerate() {
|
||||||
|
if value >= th {
|
||||||
|
level = levels[i + 1];
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
level
|
||||||
|
}
|
||||||
|
|
||||||
|
let l_edge = lookup_pwm_level(
|
||||||
|
t_edge,
|
||||||
|
&global_options.pwm_steps,
|
||||||
|
&global_options.thresholds_t_edge,
|
||||||
|
);
|
||||||
|
let l_junction = lookup_pwm_level(
|
||||||
|
t_junction,
|
||||||
|
&global_options.pwm_steps,
|
||||||
|
&global_options.thresholds_t_junction,
|
||||||
|
);
|
||||||
|
let l_memory = lookup_pwm_level(
|
||||||
|
t_memory,
|
||||||
|
&global_options.pwm_steps,
|
||||||
|
&global_options.thresholds_t_memory,
|
||||||
|
);
|
||||||
|
let l_previous_minus_one = *global_options
|
||||||
|
.pwm_steps
|
||||||
|
.iter()
|
||||||
|
.filter(|x| **x < previous_setpoint)
|
||||||
|
.max()
|
||||||
|
.unwrap_or(&0);
|
||||||
|
[l_edge, l_junction, l_memory, l_previous_minus_one]
|
||||||
|
.into_iter()
|
||||||
|
.max()
|
||||||
|
.unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn monitor_temperatures(
|
||||||
|
config: ExpandedDeviceConfig,
|
||||||
|
global_options: GlobalConfig,
|
||||||
|
shutdown_flag: Arc<AtomicBool>,
|
||||||
|
) {
|
||||||
|
let initial_power_limit = read_power_limit(&config.power.file).unwrap_or(0.0);
|
||||||
|
let mut current_power_limit = initial_power_limit;
|
||||||
|
|
||||||
|
let junction_temp = read_temperature(&config.temperature.junction).unwrap_or(105.0);
|
||||||
|
let overall_temp = read_temperature(&config.temperature.overall).unwrap_or(105.0);
|
||||||
|
let memory_temp = read_temperature(&config.temperature.memory).unwrap_or(94.0);
|
||||||
|
|
||||||
|
let mut fan_level =
|
||||||
|
determine_min_pwm_setpoint(&global_options, overall_temp, junction_temp, memory_temp, 0);
|
||||||
|
let mut time_fan_level_set: Instant = Instant::now();
|
||||||
|
|
||||||
|
// Set initial fan speed
|
||||||
|
let original_pwm_mode = enable_pwm_control_and_set_init(&config.pwm.file, fan_level).unwrap();
|
||||||
|
|
||||||
|
loop {
|
||||||
|
if shutdown_flag.load(Ordering::SeqCst) {
|
||||||
|
// Set fan to 100% on exit
|
||||||
|
restore_pwm_mode(&config.pwm.file, original_pwm_mode).unwrap();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
let junction_temp = read_temperature(&config.temperature.junction).unwrap_or(105.0);
|
||||||
|
let overall_temp = read_temperature(&config.temperature.overall).unwrap_or(105.0);
|
||||||
|
let memory_temp = read_temperature(&config.temperature.memory).unwrap_or(94.0);
|
||||||
|
|
||||||
|
// Check if any temperature is above critical thresholds
|
||||||
|
if junction_temp >= 102.0 || memory_temp >= 94.0 {
|
||||||
|
current_power_limit = current_power_limit - 3.0;
|
||||||
|
println!(
|
||||||
|
"High temperature detected, reducing power limit by 3 watt to {}",
|
||||||
|
current_power_limit
|
||||||
|
);
|
||||||
|
set_power_limit(&config.power.file, current_power_limit).unwrap();
|
||||||
|
}
|
||||||
|
let new_fan_level = determine_min_pwm_setpoint(
|
||||||
|
&global_options,
|
||||||
|
overall_temp,
|
||||||
|
junction_temp,
|
||||||
|
memory_temp,
|
||||||
|
fan_level,
|
||||||
|
);
|
||||||
|
if new_fan_level < fan_level
|
||||||
|
&& time_fan_level_set.elapsed()
|
||||||
|
< Duration::from_secs(global_options.spindown_hysteresis_seconds.into())
|
||||||
|
{
|
||||||
|
//println!("Temperature lower but waiting for hysteresis time to expire before applying");
|
||||||
|
} else if new_fan_level == fan_level {
|
||||||
|
// reset hysteris
|
||||||
|
time_fan_level_set = Instant::now();
|
||||||
|
} else {
|
||||||
|
println!("Adjusting PWM from {} to {}", fan_level, new_fan_level);
|
||||||
|
fan_level = new_fan_level;
|
||||||
|
time_fan_level_set = Instant::now();
|
||||||
|
set_pwm(&config.pwm.file, fan_level).unwrap();
|
||||||
|
}
|
||||||
|
thread::sleep(Duration::from_millis(1000));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_temperature(path: &str) -> Result<f32, std::io::Error> {
|
||||||
|
let content = fs::read_to_string(path)?;
|
||||||
|
let value: f32 = content
|
||||||
|
.trim()
|
||||||
|
.parse()
|
||||||
|
.map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))?;
|
||||||
|
Ok(value as f32 * 1e-3)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn enable_pwm_control_and_set_init(
|
||||||
|
path: &str,
|
||||||
|
value: u8,
|
||||||
|
) -> Result<PwmControlState, std::io::Error> {
|
||||||
|
println!("Reading old status from {}", format!("{}_enable", path));
|
||||||
|
let old_status_text = fs::read_to_string(format!("{}_enable", path))?;
|
||||||
|
let old_status_val: u8 = old_status_text.trim().parse().map_err(|_e| {
|
||||||
|
std::io::Error::new(std::io::ErrorKind::Other, "Failed to parse old pwm status.")
|
||||||
|
})?;
|
||||||
|
println!(
|
||||||
|
"Read old status {} from {}",
|
||||||
|
old_status_val,
|
||||||
|
format!("{}_enable", path)
|
||||||
|
);
|
||||||
|
let old_status = PwmControlState {
|
||||||
|
value: old_status_val,
|
||||||
|
};
|
||||||
|
|
||||||
|
std::fs::write(
|
||||||
|
format!("{}_enable", path),
|
||||||
|
format!("{}", MANUAL_CONTROL_STATE.value),
|
||||||
|
)?;
|
||||||
|
if let Err(e) = std::fs::write(path, format!("{}", value)) {
|
||||||
|
eprintln!("Failed to write initial PWM value, restoring previous control state.");
|
||||||
|
std::fs::write(format!("{}_enable", path), format!("{}", old_status.value))?;
|
||||||
|
return Err(e.into());
|
||||||
|
}
|
||||||
|
println!("Took over fan control and set PWM to {}", value);
|
||||||
|
Ok(old_status)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn restore_pwm_mode(path: &str, previous_mode: PwmControlState) -> Result<(), std::io::Error> {
|
||||||
|
println!("Restoring PWM control mode to {}", previous_mode.value);
|
||||||
|
std::fs::write(
|
||||||
|
format!("{}_enable", path),
|
||||||
|
format!("{}", previous_mode.value),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_pwm(path: &str, value: u8) -> Result<(), std::io::Error> {
|
||||||
|
//let mut file = fs::File::create(path)?;
|
||||||
|
std::fs::write(path, format!("{}", value))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_power_limit(path: &str) -> Result<f32, std::io::Error> {
|
||||||
|
let content = fs::read_to_string(path)?;
|
||||||
|
let value: f32 = content
|
||||||
|
.trim()
|
||||||
|
.parse()
|
||||||
|
.map(|x: f32| x * 1e-6)
|
||||||
|
.map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))?;
|
||||||
|
Ok(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_power_limit(path: &str, value: f32) -> Result<(), std::io::Error> {
|
||||||
|
let mut file = fs::File::create(path)?;
|
||||||
|
writeln!(file, "{}", (value * 1e6) as u32)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn find_temperature_sensors(card_hwmon: &str) -> Result<TemperatureFiles, std::io::Error> {
|
||||||
|
let mut sensor_idx: [u8; 3] = Default::default(); // index 0 unused by sysfs
|
||||||
|
(0..20).for_each(|i| {
|
||||||
|
let label_path = format!("{:}/temp{}_label", card_hwmon, i);
|
||||||
|
if let Ok(label) = fs::read_to_string(&label_path) {
|
||||||
|
let label = label.trim();
|
||||||
|
println!("Read label {:} for temp {:}", &label, i);
|
||||||
|
match label {
|
||||||
|
"edge" => sensor_idx[0] = i,
|
||||||
|
"junction" => sensor_idx[1] = i,
|
||||||
|
"mem" => sensor_idx[2] = i,
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
println!("Determined sensor indices {:?}", sensor_idx);
|
||||||
|
let overall = format!("{:}/temp{:}_input", card_hwmon, sensor_idx[0]);
|
||||||
|
let junction = format!("{:}/temp{:}_input", card_hwmon, sensor_idx[1]);
|
||||||
|
let memory = format!("{:}/temp{:}_input", card_hwmon, sensor_idx[2]);
|
||||||
|
if !Path::new(&overall).exists() {
|
||||||
|
Err(std::io::Error::new(
|
||||||
|
std::io::ErrorKind::NotFound,
|
||||||
|
format!("Overall temp file {:} not found", overall),
|
||||||
|
))
|
||||||
|
} else if !Path::new(&junction).exists() {
|
||||||
|
Err(std::io::Error::new(
|
||||||
|
std::io::ErrorKind::NotFound,
|
||||||
|
format!("Overall temp file {:} not found", junction),
|
||||||
|
))
|
||||||
|
} else if !Path::new(&memory).exists() {
|
||||||
|
Err(std::io::Error::new(
|
||||||
|
std::io::ErrorKind::NotFound,
|
||||||
|
format!("Overall temp file {:} not found", memory),
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
Ok(TemperatureFiles {
|
||||||
|
junction,
|
||||||
|
overall,
|
||||||
|
memory,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_and_expand_config(config: &Config) -> Vec<ExpandedDeviceConfig> {
|
||||||
|
config
|
||||||
|
.device
|
||||||
|
.iter()
|
||||||
|
.map(|dev| -> ExpandedDeviceConfig {
|
||||||
|
println!("Checking config for {:}...", &dev.name);
|
||||||
|
let card_hwmon =
|
||||||
|
find_hwmon_for_device(&dev.pci_id).expect("Hwmon not found, aborting...");
|
||||||
|
let (fan_device, fan_number) = match &dev.fan_control {
|
||||||
|
FanControlType::Pwm { device, pwm_number } => (device, pwm_number),
|
||||||
|
_ => unimplemented!("IPMI fan control not yet fully implementd."),
|
||||||
|
};
|
||||||
|
|
||||||
|
let pwm_hwmon = find_hwmon_for_device(&fan_device)
|
||||||
|
.expect("Hwmon not found for fan control device, aborting...");
|
||||||
|
let power_file = format!("{:}/power1_cap", card_hwmon);
|
||||||
|
let pwm_file = format!("{:}/pwm{:}", pwm_hwmon, fan_number);
|
||||||
|
assert!(
|
||||||
|
Path::new(&power_file).exists(),
|
||||||
|
"Power limit control file {:} not found.",
|
||||||
|
power_file
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
Path::new(&pwm_file).exists(),
|
||||||
|
"Pwm control file {:} not found.",
|
||||||
|
pwm_file
|
||||||
|
);
|
||||||
|
let temperature =
|
||||||
|
find_temperature_sensors(&card_hwmon).expect("Temperature sensor not found.");
|
||||||
|
ExpandedDeviceConfig {
|
||||||
|
device: dev.name.clone(),
|
||||||
|
power: PowerPath { file: power_file },
|
||||||
|
pwm: PwmPath { file: pwm_file },
|
||||||
|
temperature,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let shutdown_flag = Arc::new(AtomicBool::new(false));
|
||||||
|
|
||||||
|
// Do clean shutdown on all catchable termination signals
|
||||||
|
let signals = [
|
||||||
|
consts::SIGABRT,
|
||||||
|
consts::SIGALRM,
|
||||||
|
consts::SIGBUS,
|
||||||
|
consts::SIGINT,
|
||||||
|
consts::SIGQUIT,
|
||||||
|
consts::SIGTERM,
|
||||||
|
];
|
||||||
|
for sig in signals.iter() {
|
||||||
|
flag::register(*sig, shutdown_flag.clone()).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
let args: Vec<String> = env::args().collect();
|
||||||
|
let mut config_path = "config.toml".to_string();
|
||||||
|
|
||||||
|
for i in 0..args.len() {
|
||||||
|
if args[i] == "--config" && i + 1 < args.len() {
|
||||||
|
config_path = args[i + 1].clone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let settings = ConfigBuilder::builder()
|
||||||
|
.add_source(File::with_name(&config_path))
|
||||||
|
.build()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let config: Config = settings.try_deserialize().unwrap();
|
||||||
|
println!("Config {:?}", config);
|
||||||
|
assert!(check_global_config(&config.global), "Global options invalid. Make sure thresholds are monotonic and pwm steps one more than thresholds.");
|
||||||
|
let expanded_configs = check_and_expand_config(&config);
|
||||||
|
let join_handles = expanded_configs
|
||||||
|
.into_iter()
|
||||||
|
.map(|ec| {
|
||||||
|
println!("Spawning fan control thread for device {:}", &ec.device);
|
||||||
|
let gc = config.global.clone();
|
||||||
|
let shutdown_flag = shutdown_flag.clone();
|
||||||
|
std::thread::spawn(|| monitor_temperatures(ec, gc, shutdown_flag))
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
join_handles.into_iter().for_each(|h| h.join().unwrap());
|
||||||
|
}
|
||||||
BIN
stl_export_2_karten_var2/DuctOben.stl
Normal file
BIN
stl_export_2_karten_var2/DuctOben.stl
Normal file
Binary file not shown.
BIN
stl_export_2_karten_var2/DuctUnten.stl
Normal file
BIN
stl_export_2_karten_var2/DuctUnten.stl
Normal file
Binary file not shown.
7
throttle_powerlimit/README.md
Normal file
7
throttle_powerlimit/README.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# Vibe coded script to override thermal limit at bootup
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
- put throttle_instinct.sh into /usr/local/bin
|
||||||
|
- put throttle_instinct.service into /etc/systemd/system
|
||||||
|
- enable with `systemctl enable throttle_instinct.service`
|
||||||
|
- if required, adjust the desired power limit in the shell script
|
||||||
13
throttle_powerlimit/throttle_instinct.service
Normal file
13
throttle_powerlimit/throttle_instinct.service
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Throttle Instinct MI50 GPU to a desired power cap
|
||||||
|
After=sysinit.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
# Set the power limit in watts via environment variable (default: 120W)
|
||||||
|
Environment="POWER_LIMIT_WATTS=120"
|
||||||
|
ExecStart=/usr/local/bin/throttle_instinct.sh
|
||||||
|
RemainAfterExit=yes
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
75
throttle_powerlimit/throttle_instinct.sh
Executable file
75
throttle_powerlimit/throttle_instinct.sh
Executable file
@@ -0,0 +1,75 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Check if running as root
|
||||||
|
if [ "$EUID" -ne 0 ]; then
|
||||||
|
echo "Error: This script must be run as root (sudo or with appropriate privileges)" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Allow power limit to be set via environment variable or use default
|
||||||
|
watt_limit=${POWER_LIMIT_WATTS:-225}
|
||||||
|
|
||||||
|
# Iterate through hwmon devices instead of DRM cards
|
||||||
|
# This only processes devices that have hwmon capabilities
|
||||||
|
devices_found=0
|
||||||
|
|
||||||
|
for hwmon in /sys/class/hwmon/hwmon*; do
|
||||||
|
# Skip if hwmon device doesn't exist or has no device link
|
||||||
|
if [ ! -d "$hwmon" ] || [ ! -e "$hwmon/device" ]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if power1_cap exists (this device supports power limiting)
|
||||||
|
power_cap_file="$hwmon/power1_cap"
|
||||||
|
if [ ! -e "$power_cap_file" ]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Resolve the PCI device path
|
||||||
|
device_path=$(readlink -f "$hwmon/device")
|
||||||
|
|
||||||
|
# Read vendor and device IDs from sysfs
|
||||||
|
if [ ! -e "$device_path/vendor" ] || [ ! -e "$device_path/device" ]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
vendor_id=$(cat "$device_path/vendor" 2>/dev/null)
|
||||||
|
device_id=$(cat "$device_path/device" 2>/dev/null)
|
||||||
|
|
||||||
|
# Check if this is a target GPU
|
||||||
|
# AMD Vega 20 / MI50: 0x1002:0x66a0 or 0x1002:0x66a1
|
||||||
|
# Test device: 0x1234:0x1111
|
||||||
|
if { [ "$vendor_id" == "0x1002" ] &&
|
||||||
|
{ [ "$device_id" == "0x66a0" ] || [ "$device_id" == "0x66a1" ]; }; }; then
|
||||||
|
|
||||||
|
# Read GPU and driver information
|
||||||
|
# Try to get the product name first, fallback to hwmon name
|
||||||
|
gpu_name=$(cat "$device_path/product_name" 2>/dev/null)
|
||||||
|
if [ -z "$gpu_name" ]; then
|
||||||
|
gpu_name=$(cat "$hwmon/name" 2>/dev/null || echo "unknown")
|
||||||
|
fi
|
||||||
|
driver_link=$(readlink "$device_path/driver" 2>/dev/null)
|
||||||
|
driver_name=$(basename "$driver_link" 2>/dev/null || echo "unknown")
|
||||||
|
|
||||||
|
printf "Target GPU detected at %s (%s)\n" "$device_path" "$hwmon"
|
||||||
|
printf "\tGPU: %s | Driver: %s\n" "$gpu_name" "$driver_name"
|
||||||
|
printf "\tSetting power limit to %d W\n" "$watt_limit"
|
||||||
|
|
||||||
|
# Set power limit (convert watts to microwatts)
|
||||||
|
if echo "${watt_limit}000000" > "$power_cap_file" 2>/dev/null; then
|
||||||
|
printf "\tSuccessfully set power limit\n"
|
||||||
|
devices_found=$((devices_found + 1))
|
||||||
|
else
|
||||||
|
printf "\tError: Failed to write to %s\n" "$power_cap_file" >&2
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ $devices_found -eq 0 ]; then
|
||||||
|
echo "Warning: No target GPUs with power limiting capability found" >&2
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Successfully configured power limits for $devices_found device(s)"
|
||||||
Reference in New Issue
Block a user