feat: dynamic count of machines, use config
This commit is contained in:
@@ -1 +1,2 @@
|
|||||||
/target
|
/target
|
||||||
|
config.toml
|
||||||
Generated
+285
-27
@@ -32,6 +32,23 @@ dependencies = [
|
|||||||
"num-traits",
|
"num-traits",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[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.92"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "82f6aeea286b8eb4dd3431a1be1b59d290ace00f5bfd8e2a159bc2a05e2c1667"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 3.0.4",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "atomic"
|
name = "atomic"
|
||||||
version = "0.6.1"
|
version = "0.6.1"
|
||||||
@@ -102,6 +119,9 @@ name = "bitflags"
|
|||||||
version = "2.13.1"
|
version = "2.13.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da"
|
checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da"
|
||||||
|
dependencies = [
|
||||||
|
"serde_core",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "block-buffer"
|
name = "block-buffer"
|
||||||
@@ -147,9 +167,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.4.3"
|
version = "1.4.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "509591b7bcd67f4ef775afad7662703b4935daaa6ec0e5605cfb1090b32a2b6d"
|
checksum = "0ad534f4357a5264cce5019c989cf66a4f0dc4e0d1b1d15f8aacec0ff7360273"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"find-msvc-tools",
|
"find-msvc-tools",
|
||||||
"jobserver",
|
"jobserver",
|
||||||
@@ -203,6 +223,55 @@ dependencies = [
|
|||||||
"static_assertions",
|
"static_assertions",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "config"
|
||||||
|
version = "0.15.25"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b85f248a4de22d204ceabc6299d89d2c70fbd7f09fea53c06c852369652d8139"
|
||||||
|
dependencies = [
|
||||||
|
"async-trait",
|
||||||
|
"convert_case 0.6.0",
|
||||||
|
"json5",
|
||||||
|
"pathdiff",
|
||||||
|
"ron",
|
||||||
|
"rust-ini",
|
||||||
|
"serde-untagged",
|
||||||
|
"serde_core",
|
||||||
|
"serde_json",
|
||||||
|
"toml",
|
||||||
|
"winnow",
|
||||||
|
"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 0.2.17",
|
||||||
|
"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]]
|
[[package]]
|
||||||
name = "convert_case"
|
name = "convert_case"
|
||||||
version = "0.10.0"
|
version = "0.10.0"
|
||||||
@@ -280,6 +349,12 @@ dependencies = [
|
|||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crunchy"
|
||||||
|
version = "0.2.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crypto-common"
|
name = "crypto-common"
|
||||||
version = "0.1.7"
|
version = "0.1.7"
|
||||||
@@ -302,9 +377,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "darling"
|
name = "darling"
|
||||||
version = "0.24.0"
|
version = "0.24.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "88490bf1b990d87eaaa7ac8aa887f629a08e7359765b4911faf63c3763347d23"
|
checksum = "ed17f5901b6630b993ca003def43f2f8ef4014fc13b047b57aad617ff32bc2ec"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"darling_core",
|
"darling_core",
|
||||||
"darling_macro",
|
"darling_macro",
|
||||||
@@ -312,26 +387,26 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "darling_core"
|
name = "darling_core"
|
||||||
version = "0.24.0"
|
version = "0.24.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "084e274f91c482280130e1e34e0b8d6e66776a060d7b6de7b84289ca778868c4"
|
checksum = "6837e2cf7485aaae18f86181d2f0e9a7ed297a025e220aeabf63fdebd3a2ddff"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ident_case",
|
"ident_case",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"strsim",
|
"strsim",
|
||||||
"syn 3.0.3",
|
"syn 3.0.4",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "darling_macro"
|
name = "darling_macro"
|
||||||
version = "0.24.0"
|
version = "0.24.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "68f5792fa0d41cd2325ce0ffa64f0a340eaebd4971a3a0c5e1ffd2cc488a355e"
|
checksum = "2ac7135c3ef02b2f7833bbeb1be5ba7f966dcde8a87c6b87f65a778d71a02785"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"darling_core",
|
"darling_core",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 3.0.3",
|
"syn 3.0.4",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -364,7 +439,7 @@ version = "2.1.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "799a97264921d8623a957f6c3b9011f3b5492f557bbb7a5a19b7fa6d06ba8dcb"
|
checksum = "799a97264921d8623a957f6c3b9011f3b5492f557bbb7a5a19b7fa6d06ba8dcb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"convert_case",
|
"convert_case 0.10.0",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"rustc_version",
|
"rustc_version",
|
||||||
@@ -381,6 +456,15 @@ dependencies = [
|
|||||||
"crypto-common",
|
"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]]
|
[[package]]
|
||||||
name = "document-features"
|
name = "document-features"
|
||||||
version = "0.2.12"
|
version = "0.2.12"
|
||||||
@@ -398,9 +482,18 @@ checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "either"
|
name = "either"
|
||||||
version = "1.17.0"
|
version = "1.18.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9e5e8f6c15a24b9a3ee5efec809ccd006d3b30e8b3bb63c39af737c7f87daa1d"
|
checksum = "252afb9ae5eaa683babdc6a068b3f5726eb19e05070c731f9b2a23a7c3e8ed34"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "encoding_rs"
|
||||||
|
version = "0.8.35"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "equivalent"
|
name = "equivalent"
|
||||||
@@ -408,6 +501,17 @@ version = "1.0.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "erased-serde"
|
||||||
|
version = "0.4.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d2add8a07dd6a8d93ff627029c51de145e12686fbc36ecb298ac22e74cf02dec"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
"serde_core",
|
||||||
|
"typeid",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "errno"
|
name = "errno"
|
||||||
version = "0.3.14"
|
version = "0.3.14"
|
||||||
@@ -557,7 +661,7 @@ checksum = "9fb9654ba8355388abeb8dcb4fc62f511300867002afc858860463bdd9fe0c44"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 3.0.3",
|
"syn 3.0.4",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -634,6 +738,12 @@ dependencies = [
|
|||||||
"rand_core 0.10.1",
|
"rand_core 0.10.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashbrown"
|
||||||
|
version = "0.14.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "hashbrown"
|
||||||
version = "0.16.1"
|
version = "0.16.1"
|
||||||
@@ -656,6 +766,15 @@ dependencies = [
|
|||||||
"foldhash",
|
"foldhash",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashlink"
|
||||||
|
version = "0.11.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "824e001ac4f3012dd16a264bec811403a67ca9deb6c102fc5049b32c4574b35f"
|
||||||
|
dependencies = [
|
||||||
|
"hashbrown 0.16.1",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "heck"
|
name = "heck"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
@@ -693,7 +812,7 @@ dependencies = [
|
|||||||
"indoc",
|
"indoc",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 3.0.3",
|
"syn 3.0.4",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -732,6 +851,17 @@ dependencies = [
|
|||||||
"wasm-bindgen",
|
"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]]
|
[[package]]
|
||||||
name = "kasuari"
|
name = "kasuari"
|
||||||
version = "0.4.12"
|
version = "0.4.12"
|
||||||
@@ -799,9 +929,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "log"
|
name = "log"
|
||||||
version = "0.4.33"
|
version = "0.4.34"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad"
|
checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lru"
|
name = "lru"
|
||||||
@@ -827,6 +957,7 @@ name = "machinetui"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
"config",
|
||||||
"crossterm",
|
"crossterm",
|
||||||
"futures",
|
"futures",
|
||||||
"rand 0.10.2",
|
"rand 0.10.2",
|
||||||
@@ -956,6 +1087,16 @@ dependencies = [
|
|||||||
"num-traits",
|
"num-traits",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[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]]
|
[[package]]
|
||||||
name = "palette"
|
name = "palette"
|
||||||
version = "0.7.7"
|
version = "0.7.7"
|
||||||
@@ -1012,6 +1153,12 @@ dependencies = [
|
|||||||
"windows-link",
|
"windows-link",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pathdiff"
|
||||||
|
version = "0.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pest"
|
name = "pest"
|
||||||
version = "2.9.0"
|
version = "2.9.0"
|
||||||
@@ -1345,6 +1492,20 @@ dependencies = [
|
|||||||
"windows-sys 0.52.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ron"
|
||||||
|
version = "0.12.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "81116b9531d61eabc41aeb228e4b6b2435bcca3233b98cf3b3077d4e6e9debb3"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.13.1",
|
||||||
|
"once_cell",
|
||||||
|
"serde",
|
||||||
|
"serde_derive",
|
||||||
|
"typeid",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rumqttc"
|
name = "rumqttc"
|
||||||
version = "0.25.1"
|
version = "0.25.1"
|
||||||
@@ -1366,6 +1527,16 @@ dependencies = [
|
|||||||
"tokio-util",
|
"tokio-util",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rust-ini"
|
||||||
|
version = "0.21.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "796e8d2b6696392a43bea58116b667fb4c29727dc5abd27d6acf338bb4f688c7"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"ordered-multimap",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc_version"
|
name = "rustc_version"
|
||||||
version = "0.4.1"
|
version = "0.4.1"
|
||||||
@@ -1398,7 +1569,7 @@ dependencies = [
|
|||||||
"log",
|
"log",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"rustls-pki-types",
|
"rustls-pki-types",
|
||||||
"rustls-webpki 0.103.14",
|
"rustls-webpki 0.103.15",
|
||||||
"subtle",
|
"subtle",
|
||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
@@ -1446,9 +1617,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls-webpki"
|
name = "rustls-webpki"
|
||||||
version = "0.103.14"
|
version = "0.103.15"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0527518605e68109d875e248ea259b6758801cf165e4b2c2733ae3b51f12535a"
|
checksum = "f3c3cf1d8b1e7d4927e2d154c3fcb02979afb9939629c62cd9048d4f07b60ac2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aws-lc-rs",
|
"aws-lc-rs",
|
||||||
"ring",
|
"ring",
|
||||||
@@ -1522,6 +1693,18 @@ dependencies = [
|
|||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde-untagged"
|
||||||
|
version = "0.1.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f9faf48a4a2d2693be24c6289dbe26552776eb7737074e6722891fadbe6c5058"
|
||||||
|
dependencies = [
|
||||||
|
"erased-serde",
|
||||||
|
"serde",
|
||||||
|
"serde_core",
|
||||||
|
"typeid",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_core"
|
name = "serde_core"
|
||||||
version = "1.0.229"
|
version = "1.0.229"
|
||||||
@@ -1539,7 +1722,7 @@ checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 3.0.3",
|
"syn 3.0.4",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1555,6 +1738,15 @@ dependencies = [
|
|||||||
"zmij",
|
"zmij",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_spanned"
|
||||||
|
version = "1.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6662b5879511e06e8999a8a235d848113e942c9124f211511b16466ee2995f26"
|
||||||
|
dependencies = [
|
||||||
|
"serde_core",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sha2"
|
name = "sha2"
|
||||||
version = "0.10.9"
|
version = "0.10.9"
|
||||||
@@ -1703,9 +1895,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "3.0.3"
|
version = "3.0.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3"
|
checksum = "e6275cddf4610d1775e6d1fe9469b2e77d0f39fd98fb7450901b821e0c53649f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -1825,7 +2017,7 @@ checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 3.0.3",
|
"syn 3.0.4",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1860,6 +2052,15 @@ dependencies = [
|
|||||||
"time-core",
|
"time-core",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tiny-keccak"
|
||||||
|
version = "2.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237"
|
||||||
|
dependencies = [
|
||||||
|
"crunchy",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio"
|
name = "tokio"
|
||||||
version = "1.53.1"
|
version = "1.53.1"
|
||||||
@@ -1885,7 +2086,7 @@ checksum = "78773a2a397f451582ce068015985c33193cf6dea8b74d2a639fe457b2f07b0e"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 3.0.3",
|
"syn 3.0.4",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1923,6 +2124,43 @@ dependencies = [
|
|||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml"
|
||||||
|
version = "1.1.4+spec-1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3aace63f4bbcdfc2c965b059de67119c89c4017a70d633be6c104910f67056f5"
|
||||||
|
dependencies = [
|
||||||
|
"serde_core",
|
||||||
|
"serde_spanned",
|
||||||
|
"toml_datetime",
|
||||||
|
"toml_parser",
|
||||||
|
"winnow",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml_datetime"
|
||||||
|
version = "1.1.1+spec-1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7"
|
||||||
|
dependencies = [
|
||||||
|
"serde_core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml_parser"
|
||||||
|
version = "1.1.3+spec-1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1d38ac1cf9b95face32296c0a3ede1fdc270627c9d9c02a7274dd6d960dc4d56"
|
||||||
|
dependencies = [
|
||||||
|
"winnow",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "typeid"
|
||||||
|
version = "1.0.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typenum"
|
name = "typenum"
|
||||||
version = "1.20.1"
|
version = "1.20.1"
|
||||||
@@ -1978,9 +2216,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "uuid"
|
name = "uuid"
|
||||||
version = "1.24.1"
|
version = "1.25.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2cefc03fd367c0c6d4305de1b312cf00248c4114f4a0418ce6a6af769e3b0bd9"
|
checksum = "f053576934f05a761a402421fbbe3d425d9366f75f978806a037b3ca481abecc"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atomic",
|
"atomic",
|
||||||
"getrandom 0.4.3",
|
"getrandom 0.4.3",
|
||||||
@@ -2245,12 +2483,32 @@ version = "0.52.6"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winnow"
|
||||||
|
version = "1.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "23b97319f7b8343df12cc98938e5c3eb436064524c8d2b4e30a1d3a36eecdf81"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wit-bindgen"
|
name = "wit-bindgen"
|
||||||
version = "0.57.1"
|
version = "0.57.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e"
|
checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "yaml-rust2"
|
||||||
|
version = "0.11.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b36710ce3a279cfce8465dbab826f161675a262950b922cb2c3663852dfe9eb0"
|
||||||
|
dependencies = [
|
||||||
|
"arraydeque",
|
||||||
|
"encoding_rs",
|
||||||
|
"hashlink",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zeroize"
|
name = "zeroize"
|
||||||
version = "1.9.0"
|
version = "1.9.0"
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ edition = "2024"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0.104"
|
anyhow = "1.0.104"
|
||||||
|
config = "0.15.25"
|
||||||
crossterm = { version = "0.29.0", features = ["event-stream"] }
|
crossterm = { version = "0.29.0", features = ["event-stream"] }
|
||||||
futures = "0.3.34"
|
futures = "0.3.34"
|
||||||
rand = "0.10.2"
|
rand = "0.10.2"
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
use anyhow::Result;
|
||||||
|
use rumqttc::MqttOptions;
|
||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
|
pub struct ConfigData {
|
||||||
|
pub mqtt: MqttConfig,
|
||||||
|
#[serde(rename = "machine", default)]
|
||||||
|
pub machines: Vec<MachineConfig>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
|
pub struct MqttConfig {
|
||||||
|
pub device_id: String,
|
||||||
|
pub host: String,
|
||||||
|
pub port: u16,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
|
pub struct MachineConfig {
|
||||||
|
pub name: String,
|
||||||
|
pub topic: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn load() -> Result<ConfigData> {
|
||||||
|
let source = config::File::with_name("config").format(config::FileFormat::Toml);
|
||||||
|
let config = config::Config::builder().add_source(source).build()?;
|
||||||
|
Ok(config.try_deserialize()?)
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MqttConfig {
|
||||||
|
pub fn as_options(&self) -> MqttOptions {
|
||||||
|
MqttOptions::new(&self.device_id, &self.host, self.port)
|
||||||
|
}
|
||||||
|
}
|
||||||
+18
-26
@@ -1,11 +1,11 @@
|
|||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use rumqttc::{AsyncClient, Event, MqttOptions, Packet, Publish, QoS};
|
use rumqttc::{AsyncClient, Event, Packet, Publish, QoS};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use time::{OffsetDateTime, PrimitiveDateTime};
|
use time::{OffsetDateTime, PrimitiveDateTime};
|
||||||
|
|
||||||
use crate::{data, events};
|
use crate::{config::ConfigData, data, events};
|
||||||
|
|
||||||
time::serde::format_description!(
|
time::serde::format_description!(
|
||||||
tasmota_time,
|
tasmota_time,
|
||||||
@@ -13,11 +13,8 @@ time::serde::format_description!(
|
|||||||
"[year]-[month]-[day]T[hour]:[minute]:[second]"
|
"[year]-[month]-[day]T[hour]:[minute]:[second]"
|
||||||
);
|
);
|
||||||
|
|
||||||
const MACHINE1_TOPIC: &str = "tele/tasmota_F68B94/SENSOR";
|
|
||||||
const MACHINE2_TOPIC: &str = "tele/tasmota_F81A3C/SENSOR";
|
|
||||||
|
|
||||||
pub struct MachineData {
|
pub struct MachineData {
|
||||||
pub name: String,
|
pub topic: String,
|
||||||
pub voltage: f32,
|
pub voltage: f32,
|
||||||
pub current: f32,
|
pub current: f32,
|
||||||
pub last_updated: OffsetDateTime,
|
pub last_updated: OffsetDateTime,
|
||||||
@@ -40,12 +37,12 @@ pub struct TasmotaEnergyData {
|
|||||||
current: f32,
|
current: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn publish_to_machine_data(name: String, publish: Publish) -> Result<data::MachineData> {
|
fn publish_to_machine_data(topic: String, publish: Publish) -> Result<data::MachineData> {
|
||||||
let data = publish.payload.to_vec();
|
let data = publish.payload.to_vec();
|
||||||
let data: TasmotaData = serde_json::from_slice(&data)?;
|
let data: TasmotaData = serde_json::from_slice(&data)?;
|
||||||
|
|
||||||
Ok(data::MachineData {
|
Ok(data::MachineData {
|
||||||
name,
|
topic,
|
||||||
voltage: data.energy.voltage,
|
voltage: data.energy.voltage,
|
||||||
current: data.energy.current,
|
current: data.energy.current,
|
||||||
last_updated: data.time.assume_utc(),
|
last_updated: data.time.assume_utc(),
|
||||||
@@ -65,36 +62,31 @@ fn start_timestamp_task(event_sender: events::EventSender) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn start_data_fetch_task(event_sender: events::EventSender) -> Result<()> {
|
async fn start_data_fetch_task(
|
||||||
let options = MqttOptions::new("machinetui", "192.168.178.251", 1883);
|
config: &ConfigData,
|
||||||
|
event_sender: events::EventSender,
|
||||||
|
) -> Result<()> {
|
||||||
|
let options = config.mqtt.as_options();
|
||||||
let (client, mut event_loop) = AsyncClient::new(options, 10);
|
let (client, mut event_loop) = AsyncClient::new(options, 10);
|
||||||
|
|
||||||
client.subscribe(MACHINE1_TOPIC, QoS::AtLeastOnce).await?;
|
for machine in &config.machines {
|
||||||
client.subscribe(MACHINE2_TOPIC, QoS::AtLeastOnce).await?;
|
client.subscribe(&machine.topic, QoS::AtLeastOnce).await?;
|
||||||
|
}
|
||||||
|
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
|
// Keep client alive
|
||||||
let _client = client;
|
let _client = client;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
match event_loop.poll().await {
|
match event_loop.poll().await {
|
||||||
Ok(Event::Incoming(Packet::Publish(publish))) => match publish.topic.as_str() {
|
Ok(Event::Incoming(Packet::Publish(publish))) => match publish.topic.as_str() {
|
||||||
MACHINE1_TOPIC => {
|
topic => {
|
||||||
let machine_data =
|
let machine_data = publish_to_machine_data(topic.into(), publish).unwrap();
|
||||||
publish_to_machine_data("machine 1".into(), publish).unwrap();
|
|
||||||
event_sender
|
event_sender
|
||||||
.send(events::Event::MachineUpdate(machine_data))
|
.send(events::Event::MachineUpdate(machine_data))
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
MACHINE2_TOPIC => {
|
|
||||||
let machine_data =
|
|
||||||
publish_to_machine_data("machine 2".into(), publish).unwrap();
|
|
||||||
event_sender
|
|
||||||
.send(events::Event::MachineUpdate(machine_data))
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
},
|
},
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
Err(_err) => {}
|
Err(_err) => {}
|
||||||
@@ -105,8 +97,8 @@ async fn start_data_fetch_task(event_sender: events::EventSender) -> Result<()>
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn start(event_sender: events::EventSender) -> Result<()> {
|
pub async fn start(config: &ConfigData, event_sender: events::EventSender) -> Result<()> {
|
||||||
start_timestamp_task(event_sender.clone());
|
start_timestamp_task(event_sender.clone());
|
||||||
start_data_fetch_task(event_sender).await?;
|
start_data_fetch_task(config, event_sender).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-4
@@ -1,16 +1,21 @@
|
|||||||
use anyhow::Result;
|
mod config;
|
||||||
|
|
||||||
mod data;
|
mod data;
|
||||||
mod events;
|
mod events;
|
||||||
mod interaction;
|
mod interaction;
|
||||||
mod tui;
|
mod tui;
|
||||||
|
|
||||||
|
use anyhow::Result;
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<()> {
|
async fn main() -> Result<()> {
|
||||||
|
let config = config::load()?;
|
||||||
let (event_sender, event_receiver) = events::channel();
|
let (event_sender, event_receiver) = events::channel();
|
||||||
|
|
||||||
data::start(event_sender.clone()).await?;
|
data::start(&config, event_sender.clone()).await?;
|
||||||
tokio::try_join!(tui::start(event_receiver), interaction::start(event_sender))?;
|
tokio::try_join!(
|
||||||
|
tui::start(&config, event_receiver),
|
||||||
|
interaction::start(event_sender)
|
||||||
|
)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
+89
-45
@@ -1,71 +1,96 @@
|
|||||||
|
use std::collections::{HashMap, VecDeque};
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use ratatui::{
|
use ratatui::{
|
||||||
prelude::*,
|
prelude::*,
|
||||||
symbols::border,
|
symbols::border,
|
||||||
widgets::{Block, Padding, Paragraph},
|
widgets::{Axis, Block, Chart, Dataset, GraphType, Padding, Paragraph},
|
||||||
};
|
};
|
||||||
use time::{OffsetDateTime, format_description::BorrowedFormatItem, macros::format_description};
|
use time::{OffsetDateTime, format_description::BorrowedFormatItem, macros::format_description};
|
||||||
|
|
||||||
use crate::{data, events};
|
use crate::{
|
||||||
|
config::ConfigData,
|
||||||
|
data::{self},
|
||||||
|
events,
|
||||||
|
};
|
||||||
|
|
||||||
const TIME_FORMAT: &'static [BorrowedFormatItem] = format_description!("[hour]:[minute]:[second]");
|
const TIME_FORMAT: &'static [BorrowedFormatItem] = format_description!("[hour]:[minute]:[second]");
|
||||||
|
const HISTORY_LEN: usize = 120;
|
||||||
|
|
||||||
pub struct App {
|
pub struct App<'a> {
|
||||||
pub timestamp: OffsetDateTime,
|
pub timestamp: OffsetDateTime,
|
||||||
pub machines: Vec<data::MachineData>,
|
pub machines: HashMap<String, data::MachineData>,
|
||||||
|
pub history: HashMap<String, VecDeque<(f64, f64)>>,
|
||||||
|
|
||||||
|
config: &'a ConfigData,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl App {
|
impl<'a> App<'a> {
|
||||||
pub fn new() -> Self {
|
pub fn new(config: &'a ConfigData) -> Self {
|
||||||
Self {
|
Self {
|
||||||
timestamp: OffsetDateTime::now_local().unwrap(),
|
timestamp: OffsetDateTime::now_local().unwrap(),
|
||||||
machines: vec![
|
machines: HashMap::new(),
|
||||||
data::MachineData {
|
history: HashMap::new(),
|
||||||
name: "machine 1".into(),
|
config,
|
||||||
voltage: 0f32,
|
|
||||||
current: 0f32,
|
|
||||||
last_updated: OffsetDateTime::now_utc(),
|
|
||||||
},
|
|
||||||
data::MachineData {
|
|
||||||
name: "machine 2".into(),
|
|
||||||
voltage: 0f32,
|
|
||||||
current: 0f32,
|
|
||||||
last_updated: OffsetDateTime::now_utc(),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Widget for &App {
|
impl<'a> Widget for &App<'a> {
|
||||||
fn render(self, area: Rect, buf: &mut Buffer)
|
fn render(self, area: Rect, buf: &mut Buffer)
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
let [headline_area, machines_area, _] = Layout::vertical([
|
let [headline_area, machines_area, chart_area] = Layout::vertical([
|
||||||
Constraint::Length(3),
|
Constraint::Length(3),
|
||||||
Constraint::Length(6),
|
Constraint::Length(6),
|
||||||
Constraint::Min(0),
|
Constraint::Min(0),
|
||||||
])
|
])
|
||||||
.areas(area);
|
.areas(area);
|
||||||
|
|
||||||
let [machine1_area, machine2_area] =
|
|
||||||
Layout::horizontal([Constraint::Fill(1), Constraint::Fill(1)]).areas(machines_area);
|
|
||||||
|
|
||||||
Headline {
|
Headline {
|
||||||
timestamp: &self.timestamp,
|
timestamp: &self.timestamp,
|
||||||
}
|
}
|
||||||
.render(headline_area, buf);
|
.render(headline_area, buf);
|
||||||
|
|
||||||
MachineData {
|
let machine_area_const = vec![Constraint::Fill(1); self.config.machines.len()];
|
||||||
data: &self.machines[0],
|
let machine_areas = Layout::horizontal(machine_area_const).split(machines_area);
|
||||||
}
|
let machine_zip = self
|
||||||
.render(machine1_area, buf);
|
.config
|
||||||
|
.machines
|
||||||
|
.iter()
|
||||||
|
.zip(machine_areas.iter().copied());
|
||||||
|
|
||||||
MachineData {
|
for (machine_config, machine_area) in machine_zip {
|
||||||
data: &self.machines[1],
|
let machine_data = self.machines.get(&machine_config.topic);
|
||||||
|
|
||||||
|
MachineData {
|
||||||
|
name: &machine_config.name,
|
||||||
|
data: machine_data,
|
||||||
|
}
|
||||||
|
.render(machine_area, buf);
|
||||||
}
|
}
|
||||||
.render(machine2_area, buf);
|
|
||||||
|
let datasets: Vec<Dataset<'_>> = self
|
||||||
|
.history
|
||||||
|
.iter()
|
||||||
|
.map(|(name, data)| {
|
||||||
|
let data = data.as_slices().0;
|
||||||
|
Dataset::default()
|
||||||
|
.name(Line::from(name.as_str()))
|
||||||
|
.marker(symbols::Marker::Braille)
|
||||||
|
.graph_type(GraphType::Line)
|
||||||
|
.style(Color::Cyan)
|
||||||
|
.data(data)
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let chart = Chart::new(datasets)
|
||||||
|
.block(Block::bordered().title("Current usage (A)"))
|
||||||
|
.x_axis(Axis::default().bounds([0.0, HISTORY_LEN as f64]))
|
||||||
|
.y_axis(Axis::default().bounds([0.0, 10f64]));
|
||||||
|
|
||||||
|
chart.render(chart_area, buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,7 +127,8 @@ impl<'a> Widget for &Headline<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct MachineData<'a> {
|
pub struct MachineData<'a> {
|
||||||
data: &'a data::MachineData,
|
name: &'a str,
|
||||||
|
data: Option<&'a data::MachineData>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Widget for &MachineData<'a> {
|
impl<'a> Widget for &MachineData<'a> {
|
||||||
@@ -117,6 +143,20 @@ impl<'a> Widget for &MachineData<'a> {
|
|||||||
let block_area = block.inner(area);
|
let block_area = block.inner(area);
|
||||||
block.render(area, buf);
|
block.render(area, buf);
|
||||||
|
|
||||||
|
let machine = match self.data {
|
||||||
|
Some(data) => data,
|
||||||
|
None => {
|
||||||
|
// Render no data
|
||||||
|
let area_const = [Constraint::Length(1), Constraint::Min(0)];
|
||||||
|
let [name_area, no_data_area] = Layout::vertical(area_const).areas(block_area);
|
||||||
|
|
||||||
|
let text = format!("Name: {}", self.name).bold().fg(Color::Blue);
|
||||||
|
Paragraph::new(text).render(name_area, buf);
|
||||||
|
Paragraph::new("no data").render(no_data_area, buf);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let layout_const = [
|
let layout_const = [
|
||||||
Constraint::Length(1),
|
Constraint::Length(1),
|
||||||
Constraint::Length(1),
|
Constraint::Length(1),
|
||||||
@@ -127,18 +167,18 @@ impl<'a> Widget for &MachineData<'a> {
|
|||||||
Layout::vertical(layout_const).areas(block_area);
|
Layout::vertical(layout_const).areas(block_area);
|
||||||
|
|
||||||
let format = format_description!("[year]-[month]-[day] [hour]:[month]:[second]");
|
let format = format_description!("[year]-[month]-[day] [hour]:[month]:[second]");
|
||||||
let last_updated = self.data.last_updated.format(format).unwrap();
|
let last_updated = machine.last_updated.format(format).unwrap();
|
||||||
|
|
||||||
let text = format!("Name: {}", self.data.name).bold().fg(Color::Blue);
|
let text = format!("Name: {}", self.name).bold().fg(Color::Blue);
|
||||||
Paragraph::new(text).render(name_area, buf);
|
Paragraph::new(text).render(name_area, buf);
|
||||||
let text = Line::from(vec![
|
let text = Line::from(vec![
|
||||||
"Voltage: ".bold(),
|
"Voltage: ".bold(),
|
||||||
format!("{:.0} V", self.data.voltage).into(),
|
format!("{:.0} V", machine.voltage).into(),
|
||||||
]);
|
]);
|
||||||
Paragraph::new(text).render(voltage_area, buf);
|
Paragraph::new(text).render(voltage_area, buf);
|
||||||
let text = Line::from(vec![
|
let text = Line::from(vec![
|
||||||
"Current: ".bold(),
|
"Current: ".bold(),
|
||||||
format!("{:.03} A", self.data.current).into(),
|
format!("{:.03} A", machine.current).into(),
|
||||||
]);
|
]);
|
||||||
Paragraph::new(text).render(current_area, buf);
|
Paragraph::new(text).render(current_area, buf);
|
||||||
let text = Line::from(vec!["Last updated: ".bold(), last_updated.into()]);
|
let text = Line::from(vec!["Last updated: ".bold(), last_updated.into()]);
|
||||||
@@ -146,12 +186,12 @@ impl<'a> Widget for &MachineData<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn start(event_receiver: events::EventReceiver) -> Result<()> {
|
pub async fn start(config: &ConfigData, event_receiver: events::EventReceiver) -> Result<()> {
|
||||||
let mut event_receiver = event_receiver;
|
let mut event_receiver = event_receiver;
|
||||||
let mut terminal = ratatui::init();
|
let mut terminal = ratatui::init();
|
||||||
|
|
||||||
let mut running = true;
|
let mut running = true;
|
||||||
let mut app = App::new();
|
let mut app = App::new(config);
|
||||||
|
|
||||||
while running {
|
while running {
|
||||||
// render tui
|
// render tui
|
||||||
@@ -163,12 +203,16 @@ pub async fn start(event_receiver: events::EventReceiver) -> Result<()> {
|
|||||||
match event_receiver.recv().await {
|
match event_receiver.recv().await {
|
||||||
Some(events::Event::Timestamp(t)) => app.timestamp = t,
|
Some(events::Event::Timestamp(t)) => app.timestamp = t,
|
||||||
Some(events::Event::MachineUpdate(data)) => {
|
Some(events::Event::MachineUpdate(data)) => {
|
||||||
for machine in &mut app.machines {
|
let name = data.topic.clone();
|
||||||
if machine.name == data.name {
|
let current = data.current;
|
||||||
machine.voltage = data.voltage;
|
|
||||||
machine.current = data.current;
|
app.machines.insert(name.clone(), data);
|
||||||
machine.last_updated = data.last_updated;
|
|
||||||
}
|
let history = app.history.entry(name).or_default();
|
||||||
|
let x = history.len() as f64;
|
||||||
|
history.push_back((x, current as f64));
|
||||||
|
if history.len() > HISTORY_LEN {
|
||||||
|
history.pop_front();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(events::Event::Exit) => running = false,
|
Some(events::Event::Exit) => running = false,
|
||||||
|
|||||||
Reference in New Issue
Block a user