Compare commits
6 Commits
64c4a47c6f
...
88a7acd55d
| Author | SHA1 | Date | |
|---|---|---|---|
|
88a7acd55d
|
|||
|
3b7579878b
|
|||
|
46c32c3605
|
|||
|
d1e7988117
|
|||
|
93b0a526b1
|
|||
|
7bb5e65c1c
|
235
Cargo.lock
generated
235
Cargo.lock
generated
@@ -36,12 +36,6 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "android-tzdata"
|
|
||||||
version = "0.1.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "android_system_properties"
|
name = "android_system_properties"
|
||||||
version = "0.1.5"
|
version = "0.1.5"
|
||||||
@@ -94,11 +88,13 @@ dependencies = [
|
|||||||
"async-trait",
|
"async-trait",
|
||||||
"automation_devices",
|
"automation_devices",
|
||||||
"automation_lib",
|
"automation_lib",
|
||||||
|
"automation_macro",
|
||||||
"axum",
|
"axum",
|
||||||
"config",
|
"config",
|
||||||
"git-version",
|
"git-version",
|
||||||
"google_home",
|
"google_home",
|
||||||
"inventory",
|
"inventory",
|
||||||
|
"lua_typed",
|
||||||
"mlua",
|
"mlua",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"rumqttc",
|
"rumqttc",
|
||||||
@@ -106,6 +102,7 @@ dependencies = [
|
|||||||
"serde_json",
|
"serde_json",
|
||||||
"thiserror 2.0.16",
|
"thiserror 2.0.16",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"tokio-cron-scheduler",
|
||||||
"tracing",
|
"tracing",
|
||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
]
|
]
|
||||||
@@ -152,7 +149,6 @@ dependencies = [
|
|||||||
"futures",
|
"futures",
|
||||||
"google_home",
|
"google_home",
|
||||||
"hostname",
|
"hostname",
|
||||||
"indexmap",
|
|
||||||
"inventory",
|
"inventory",
|
||||||
"lua_typed",
|
"lua_typed",
|
||||||
"mlua",
|
"mlua",
|
||||||
@@ -161,9 +157,7 @@ dependencies = [
|
|||||||
"serde_json",
|
"serde_json",
|
||||||
"thiserror 2.0.16",
|
"thiserror 2.0.16",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-cron-scheduler",
|
|
||||||
"tracing",
|
"tracing",
|
||||||
"uuid",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -322,16 +316,25 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "chrono"
|
name = "chrono"
|
||||||
version = "0.4.41"
|
version = "0.4.42"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d"
|
checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"android-tzdata",
|
|
||||||
"iana-time-zone",
|
"iana-time-zone",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
"windows-link",
|
"windows-link 0.2.1",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "chrono-tz"
|
||||||
|
version = "0.10.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a6139a8597ed92cf816dfb33f5dd6cf0bb93a6adc938f11039f371bc5bcd26c3"
|
||||||
|
dependencies = [
|
||||||
|
"chrono",
|
||||||
|
"phf",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -374,11 +377,48 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "croner"
|
name = "croner"
|
||||||
version = "2.2.0"
|
version = "3.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c344b0690c1ad1c7176fe18eb173e0c927008fdaaa256e40dfd43ddd149c0843"
|
checksum = "4c007081651a19b42931f86f7d4f74ee1c2a7d0cd2c6636a81695b5ffd4e9990"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
|
"derive_builder",
|
||||||
|
"strum",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "darling"
|
||||||
|
version = "0.20.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee"
|
||||||
|
dependencies = [
|
||||||
|
"darling_core",
|
||||||
|
"darling_macro",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "darling_core"
|
||||||
|
version = "0.20.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e"
|
||||||
|
dependencies = [
|
||||||
|
"fnv",
|
||||||
|
"ident_case",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"strsim",
|
||||||
|
"syn 2.0.106",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "darling_macro"
|
||||||
|
version = "0.20.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead"
|
||||||
|
dependencies = [
|
||||||
|
"darling_core",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.106",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -422,6 +462,37 @@ dependencies = [
|
|||||||
"thiserror 2.0.16",
|
"thiserror 2.0.16",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "derive_builder"
|
||||||
|
version = "0.20.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "507dfb09ea8b7fa618fcf76e953f4f5e192547945816d5358edffe39f6f94947"
|
||||||
|
dependencies = [
|
||||||
|
"derive_builder_macro",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "derive_builder_core"
|
||||||
|
version = "0.20.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2d5bcf7b024d6835cfb3d473887cd966994907effbe9227e8c8219824d06c4e8"
|
||||||
|
dependencies = [
|
||||||
|
"darling",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.106",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "derive_builder_macro"
|
||||||
|
version = "0.20.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c"
|
||||||
|
dependencies = [
|
||||||
|
"derive_builder_core",
|
||||||
|
"syn 2.0.106",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "displaydoc"
|
name = "displaydoc"
|
||||||
version = "0.2.5"
|
version = "0.2.5"
|
||||||
@@ -466,12 +537,6 @@ version = "0.1.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c7f84e12ccf0a7ddc17a6c41c93326024c42920d7ee630d04950e6926645c0fe"
|
checksum = "c7f84e12ccf0a7ddc17a6c41c93326024c42920d7ee630d04950e6926645c0fe"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "equivalent"
|
|
||||||
version = "1.0.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "erased-serde"
|
name = "erased-serde"
|
||||||
version = "0.4.6"
|
version = "0.4.6"
|
||||||
@@ -701,10 +766,10 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "heck"
|
||||||
version = "0.15.5"
|
version = "0.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
|
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hex"
|
name = "hex"
|
||||||
@@ -720,7 +785,7 @@ checksum = "a56f203cd1c76362b69e3863fd987520ac36cf70a8c92627449b2f64a8cf7d65"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"libc",
|
"libc",
|
||||||
"windows-link",
|
"windows-link 0.1.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -834,9 +899,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iana-time-zone"
|
name = "iana-time-zone"
|
||||||
version = "0.1.63"
|
version = "0.1.64"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8"
|
checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"android_system_properties",
|
"android_system_properties",
|
||||||
"core-foundation-sys",
|
"core-foundation-sys",
|
||||||
@@ -942,6 +1007,12 @@ dependencies = [
|
|||||||
"zerovec",
|
"zerovec",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ident_case"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "idna"
|
name = "idna"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
@@ -963,17 +1034,6 @@ dependencies = [
|
|||||||
"icu_properties",
|
"icu_properties",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "indexmap"
|
|
||||||
version = "2.11.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f2481980430f9f78649238835720ddccc57e52df14ffce1c6f37391d61b563e9"
|
|
||||||
dependencies = [
|
|
||||||
"equivalent",
|
|
||||||
"hashbrown",
|
|
||||||
"serde",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "inventory"
|
name = "inventory"
|
||||||
version = "0.3.21"
|
version = "0.3.21"
|
||||||
@@ -1102,16 +1162,17 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "lua_typed"
|
name = "lua_typed"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://git.huizinga.dev/Dreaded_X/lua_typed#08f5c4533a93131e8eda6702c062fb841d14d4e1"
|
source = "git+https://git.huizinga.dev/Dreaded_X/lua_typed#f6a684291432aae2ef7109712882e7e3ed758d08"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"eui48",
|
"eui48",
|
||||||
"lua_typed_macro",
|
"lua_typed_macro",
|
||||||
|
"mlua",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lua_typed_macro"
|
name = "lua_typed_macro"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://git.huizinga.dev/Dreaded_X/lua_typed#08f5c4533a93131e8eda6702c062fb841d14d4e1"
|
source = "git+https://git.huizinga.dev/Dreaded_X/lua_typed#f6a684291432aae2ef7109712882e7e3ed758d08"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"convert_case",
|
"convert_case",
|
||||||
"itertools",
|
"itertools",
|
||||||
@@ -1207,9 +1268,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mlua"
|
name = "mlua"
|
||||||
version = "0.11.3"
|
version = "0.11.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5b3dd94c3c4dea0049b22296397040840a8f6b5b5229f438434ba82df402b42d"
|
checksum = "9be1c2bfc684b8a228fbaebf954af7a47a98ec27721986654a4cc2c40a20cc7e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bstr",
|
"bstr",
|
||||||
"either",
|
"either",
|
||||||
@@ -1347,6 +1408,24 @@ version = "2.3.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
|
checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "phf"
|
||||||
|
version = "0.12.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "913273894cec178f401a31ec4b656318d95473527be05c0752cc41cdc32be8b7"
|
||||||
|
dependencies = [
|
||||||
|
"phf_shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "phf_shared"
|
||||||
|
version = "0.12.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "06005508882fb681fd97892ecff4b7fd0fee13ef1aa569f8695dae7ab9099981"
|
||||||
|
dependencies = [
|
||||||
|
"siphasher",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-project-lite"
|
name = "pin-project-lite"
|
||||||
version = "0.2.16"
|
version = "0.2.16"
|
||||||
@@ -1899,6 +1978,12 @@ version = "1.3.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "siphasher"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "slab"
|
name = "slab"
|
||||||
version = "0.4.11"
|
version = "0.4.11"
|
||||||
@@ -1936,6 +2021,33 @@ version = "1.2.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
|
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "strsim"
|
||||||
|
version = "0.11.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "strum"
|
||||||
|
version = "0.27.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf"
|
||||||
|
dependencies = [
|
||||||
|
"strum_macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "strum_macros"
|
||||||
|
version = "0.27.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7"
|
||||||
|
dependencies = [
|
||||||
|
"heck",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.106",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "subtle"
|
name = "subtle"
|
||||||
version = "2.6.1"
|
version = "2.6.1"
|
||||||
@@ -2078,11 +2190,12 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-cron-scheduler"
|
name = "tokio-cron-scheduler"
|
||||||
version = "0.14.0"
|
version = "0.15.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5c71ce8f810abc9fabebccc30302a952f9e89c6cf246fafaf170fef164063141"
|
checksum = "bb73c4033ddcbbf81fd828293fd41a0145cde2cbc30dd782227c5081a523214d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
|
"chrono-tz",
|
||||||
"croner",
|
"croner",
|
||||||
"num-derive",
|
"num-derive",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
@@ -2477,22 +2590,22 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-core"
|
name = "windows-core"
|
||||||
version = "0.61.2"
|
version = "0.62.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3"
|
checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-implement",
|
"windows-implement",
|
||||||
"windows-interface",
|
"windows-interface",
|
||||||
"windows-link",
|
"windows-link 0.2.1",
|
||||||
"windows-result",
|
"windows-result",
|
||||||
"windows-strings",
|
"windows-strings",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-implement"
|
name = "windows-implement"
|
||||||
version = "0.60.0"
|
version = "0.60.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836"
|
checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -2501,9 +2614,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-interface"
|
name = "windows-interface"
|
||||||
version = "0.59.1"
|
version = "0.59.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8"
|
checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -2517,21 +2630,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a"
|
checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-result"
|
name = "windows-link"
|
||||||
version = "0.3.4"
|
version = "0.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6"
|
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-result"
|
||||||
|
version = "0.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-link",
|
"windows-link 0.2.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-strings"
|
name = "windows-strings"
|
||||||
version = "0.4.2"
|
version = "0.5.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57"
|
checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-link",
|
"windows-link 0.2.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ futures = "0.3.31"
|
|||||||
google_home = { path = "./google_home/google_home" }
|
google_home = { path = "./google_home/google_home" }
|
||||||
google_home_macro = { path = "./google_home/google_home_macro" }
|
google_home_macro = { path = "./google_home/google_home_macro" }
|
||||||
hostname = "0.4.1"
|
hostname = "0.4.1"
|
||||||
indexmap = { version = "2.11.0", features = ["serde"] }
|
|
||||||
inventory = "0.3.21"
|
inventory = "0.3.21"
|
||||||
itertools = "0.14.0"
|
itertools = "0.14.0"
|
||||||
json_value_merge = "2.0.1"
|
json_value_merge = "2.0.1"
|
||||||
@@ -59,10 +58,9 @@ serde_repr = "0.1.20"
|
|||||||
syn = { version = "2.0.106" }
|
syn = { version = "2.0.106" }
|
||||||
thiserror = "2.0.16"
|
thiserror = "2.0.16"
|
||||||
tokio = { version = "1", features = ["rt-multi-thread"] }
|
tokio = { version = "1", features = ["rt-multi-thread"] }
|
||||||
tokio-cron-scheduler = "0.14.0"
|
tokio-cron-scheduler = "0.15.0"
|
||||||
tracing = "0.1.41"
|
tracing = "0.1.41"
|
||||||
tracing-subscriber = "0.3.20"
|
tracing-subscriber = "0.3.20"
|
||||||
uuid = "1.18.1"
|
|
||||||
wakey = "0.3.0"
|
wakey = "0.3.0"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
@@ -70,6 +68,7 @@ anyhow = { workspace = true }
|
|||||||
async-trait = { workspace = true }
|
async-trait = { workspace = true }
|
||||||
automation_devices = { workspace = true }
|
automation_devices = { workspace = true }
|
||||||
automation_lib = { workspace = true }
|
automation_lib = { workspace = true }
|
||||||
|
automation_macro = { path = "./automation_macro" }
|
||||||
axum = { workspace = true }
|
axum = { workspace = true }
|
||||||
config = { version = "0.15.15", default-features = false, features = [
|
config = { version = "0.15.15", default-features = false, features = [
|
||||||
"async",
|
"async",
|
||||||
@@ -77,6 +76,7 @@ config = { version = "0.15.15", default-features = false, features = [
|
|||||||
] }
|
] }
|
||||||
git-version = "0.3.9"
|
git-version = "0.3.9"
|
||||||
google_home = { workspace = true }
|
google_home = { workspace = true }
|
||||||
|
lua_typed = { workspace = true }
|
||||||
inventory = { workspace = true }
|
inventory = { workspace = true }
|
||||||
mlua = { workspace = true }
|
mlua = { workspace = true }
|
||||||
reqwest = { workspace = true }
|
reqwest = { workspace = true }
|
||||||
@@ -85,6 +85,7 @@ serde = { workspace = true }
|
|||||||
serde_json = { workspace = true }
|
serde_json = { workspace = true }
|
||||||
thiserror = { workspace = true }
|
thiserror = { workspace = true }
|
||||||
tokio = { workspace = true }
|
tokio = { workspace = true }
|
||||||
|
tokio-cron-scheduler = { workspace = true }
|
||||||
tracing = { workspace = true }
|
tracing = { workspace = true }
|
||||||
tracing-subscriber = { workspace = true }
|
tracing-subscriber = { workspace = true }
|
||||||
|
|
||||||
|
|||||||
@@ -70,13 +70,35 @@ pub fn create_module(lua: &mlua::Lua) -> mlua::Result<mlua::Table> {
|
|||||||
Ok(devices)
|
Ok(devices)
|
||||||
}
|
}
|
||||||
|
|
||||||
type RegisterTypeFn = fn() -> Option<String>;
|
type TypeNameFn = fn() -> String;
|
||||||
|
type TypeDefinitionFn = fn() -> Option<String>;
|
||||||
|
|
||||||
pub struct RegisteredType(RegisterTypeFn);
|
pub struct RegisteredType {
|
||||||
|
name_fn: TypeNameFn,
|
||||||
|
definition_fn: TypeDefinitionFn,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RegisteredType {
|
||||||
|
pub const fn new(name_fn: TypeNameFn, definition_fn: TypeDefinitionFn) -> Self {
|
||||||
|
Self {
|
||||||
|
name_fn,
|
||||||
|
definition_fn,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_name(&self) -> String {
|
||||||
|
(self.name_fn)()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn register(&self) -> Option<String> {
|
||||||
|
(self.definition_fn)()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! register_type {
|
macro_rules! register_type {
|
||||||
($ty:ty) => {
|
($ty:ty) => {
|
||||||
::inventory::submit!(crate::RegisteredType(
|
::inventory::submit!(crate::RegisteredType::new(
|
||||||
|
<$ty as ::lua_typed::Typed>::type_name,
|
||||||
<$ty as ::lua_typed::Typed>::generate_full
|
<$ty as ::lua_typed::Typed>::generate_full
|
||||||
));
|
));
|
||||||
};
|
};
|
||||||
@@ -88,9 +110,12 @@ inventory::collect!(RegisteredType);
|
|||||||
fn generate_definitions() -> String {
|
fn generate_definitions() -> String {
|
||||||
let mut output = String::new();
|
let mut output = String::new();
|
||||||
|
|
||||||
|
let mut types: Vec<_> = inventory::iter::<RegisteredType>.into_iter().collect();
|
||||||
|
types.sort_by_key(|ty| ty.get_name());
|
||||||
|
|
||||||
output += "---@meta\n\nlocal devices\n\n";
|
output += "---@meta\n\nlocal devices\n\n";
|
||||||
for ty in inventory::iter::<RegisteredType> {
|
for ty in types {
|
||||||
if let Some(def) = ty.0() {
|
if let Some(def) = (ty.definition_fn)() {
|
||||||
output += &(def + "\n");
|
output += &(def + "\n");
|
||||||
} else {
|
} else {
|
||||||
// NOTE: Due to how this works the typed is erased, so we don't know the cause
|
// NOTE: Due to how this works the typed is erased, so we don't know the cause
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ dyn-clone = { workspace = true }
|
|||||||
futures = { workspace = true }
|
futures = { workspace = true }
|
||||||
google_home = { workspace = true }
|
google_home = { workspace = true }
|
||||||
hostname = { workspace = true }
|
hostname = { workspace = true }
|
||||||
indexmap = { workspace = true }
|
|
||||||
inventory = { workspace = true }
|
inventory = { workspace = true }
|
||||||
lua_typed = { workspace = true }
|
lua_typed = { workspace = true }
|
||||||
mlua = { workspace = true }
|
mlua = { workspace = true }
|
||||||
@@ -20,6 +19,4 @@ serde = { workspace = true }
|
|||||||
serde_json = { workspace = true }
|
serde_json = { workspace = true }
|
||||||
thiserror = { workspace = true }
|
thiserror = { workspace = true }
|
||||||
tokio = { workspace = true }
|
tokio = { workspace = true }
|
||||||
tokio-cron-scheduler = { workspace = true }
|
|
||||||
tracing = { workspace = true }
|
tracing = { workspace = true }
|
||||||
uuid = { workspace = true }
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ use std::fmt::Debug;
|
|||||||
|
|
||||||
use automation_cast::Cast;
|
use automation_cast::Cast;
|
||||||
use dyn_clone::DynClone;
|
use dyn_clone::DynClone;
|
||||||
|
use lua_typed::Typed;
|
||||||
use mlua::ObjectLike;
|
use mlua::ObjectLike;
|
||||||
|
|
||||||
use crate::event::OnMqtt;
|
use crate::event::OnMqtt;
|
||||||
@@ -26,7 +27,7 @@ impl mlua::FromLua for Box<dyn Device> {
|
|||||||
fn from_lua(value: mlua::Value, _lua: &mlua::Lua) -> mlua::Result<Self> {
|
fn from_lua(value: mlua::Value, _lua: &mlua::Lua) -> mlua::Result<Self> {
|
||||||
match value {
|
match value {
|
||||||
mlua::Value::UserData(ud) => {
|
mlua::Value::UserData(ud) => {
|
||||||
let ud = if ud.is::<Box<dyn Device>>() {
|
let ud = if ud.is::<Self>() {
|
||||||
ud
|
ud
|
||||||
} else {
|
} else {
|
||||||
ud.call_method::<_>("__box", ())?
|
ud.call_method::<_>("__box", ())?
|
||||||
@@ -35,10 +36,19 @@ impl mlua::FromLua for Box<dyn Device> {
|
|||||||
let b = ud.borrow::<Self>()?.clone();
|
let b = ud.borrow::<Self>()?.clone();
|
||||||
Ok(b)
|
Ok(b)
|
||||||
}
|
}
|
||||||
_ => Err(mlua::Error::RuntimeError("Expected user data".into())),
|
_ => Err(mlua::Error::runtime(format!(
|
||||||
|
"Expected user data, instead found: {}",
|
||||||
|
value.type_name()
|
||||||
|
))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl mlua::UserData for Box<dyn Device> {}
|
impl mlua::UserData for Box<dyn Device> {}
|
||||||
|
|
||||||
|
impl Typed for Box<dyn Device> {
|
||||||
|
fn type_name() -> String {
|
||||||
|
"DeviceInterface".into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
dyn_clone::clone_trait_object!(Device);
|
dyn_clone::clone_trait_object!(Device);
|
||||||
|
|||||||
@@ -1,13 +1,10 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::pin::Pin;
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use futures::Future;
|
|
||||||
use futures::future::join_all;
|
use futures::future::join_all;
|
||||||
use lua_typed::Typed;
|
use lua_typed::Typed;
|
||||||
use mlua::FromLua;
|
use mlua::FromLua;
|
||||||
use tokio::sync::{RwLock, RwLockReadGuard};
|
use tokio::sync::{RwLock, RwLockReadGuard};
|
||||||
use tokio_cron_scheduler::{Job, JobScheduler};
|
|
||||||
use tracing::{debug, instrument, trace};
|
use tracing::{debug, instrument, trace};
|
||||||
|
|
||||||
use crate::device::Device;
|
use crate::device::Device;
|
||||||
@@ -19,7 +16,6 @@ pub type DeviceMap = HashMap<String, Box<dyn Device>>;
|
|||||||
pub struct DeviceManager {
|
pub struct DeviceManager {
|
||||||
devices: Arc<RwLock<DeviceMap>>,
|
devices: Arc<RwLock<DeviceMap>>,
|
||||||
event_channel: EventChannel,
|
event_channel: EventChannel,
|
||||||
scheduler: JobScheduler,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DeviceManager {
|
impl DeviceManager {
|
||||||
@@ -29,7 +25,6 @@ impl DeviceManager {
|
|||||||
let device_manager = Self {
|
let device_manager = Self {
|
||||||
devices: Arc::new(RwLock::new(HashMap::new())),
|
devices: Arc::new(RwLock::new(HashMap::new())),
|
||||||
event_channel,
|
event_channel,
|
||||||
scheduler: JobScheduler::new().await.unwrap(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
tokio::spawn({
|
tokio::spawn({
|
||||||
@@ -45,8 +40,6 @@ impl DeviceManager {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
device_manager.scheduler.start().await.unwrap();
|
|
||||||
|
|
||||||
device_manager
|
device_manager
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,42 +98,6 @@ impl mlua::UserData for DeviceManager {
|
|||||||
Ok(())
|
Ok(())
|
||||||
});
|
});
|
||||||
|
|
||||||
methods.add_async_method(
|
|
||||||
"schedule",
|
|
||||||
async |lua, this, (schedule, f): (String, mlua::Function)| {
|
|
||||||
debug!("schedule = {schedule}");
|
|
||||||
// This creates a function, that returns the actual job we want to run
|
|
||||||
let create_job = {
|
|
||||||
let lua = lua.clone();
|
|
||||||
|
|
||||||
move |uuid: uuid::Uuid,
|
|
||||||
_: tokio_cron_scheduler::JobScheduler|
|
|
||||||
-> Pin<Box<dyn Future<Output = ()> + Send>> {
|
|
||||||
let lua = lua.clone();
|
|
||||||
|
|
||||||
// Create the actual function we want to run on a schedule
|
|
||||||
let future = async move {
|
|
||||||
let f: mlua::Function =
|
|
||||||
lua.named_registry_value(uuid.to_string().as_str()).unwrap();
|
|
||||||
f.call_async::<()>(()).await.unwrap();
|
|
||||||
};
|
|
||||||
|
|
||||||
Box::pin(future)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let job = Job::new_async(schedule.as_str(), create_job).unwrap();
|
|
||||||
|
|
||||||
let uuid = this.scheduler.add(job).await.unwrap();
|
|
||||||
|
|
||||||
// Store the function in the registry
|
|
||||||
lua.set_named_registry_value(uuid.to_string().as_str(), f)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
methods.add_method("event_channel", |_lua, this, ()| Ok(this.event_channel()))
|
methods.add_method("event_channel", |_lua, this, ()| Ok(this.event_channel()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ pub mod helpers;
|
|||||||
pub mod lua;
|
pub mod lua;
|
||||||
pub mod messages;
|
pub mod messages;
|
||||||
pub mod mqtt;
|
pub mod mqtt;
|
||||||
pub mod schedule;
|
|
||||||
|
|
||||||
type RegisterFn = fn(lua: &mlua::Lua) -> mlua::Result<mlua::Table>;
|
type RegisterFn = fn(lua: &mlua::Lua) -> mlua::Result<mlua::Table>;
|
||||||
type DefinitionsFn = fn() -> String;
|
type DefinitionsFn = fn() -> String;
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
use indexmap::IndexMap;
|
|
||||||
use serde::Deserialize;
|
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Hash, PartialEq, Eq, Clone, Copy)]
|
|
||||||
#[serde(rename_all = "snake_case")]
|
|
||||||
pub enum Action {
|
|
||||||
On,
|
|
||||||
Off,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub type Schedule = IndexMap<String, IndexMap<Action, Vec<String>>>;
|
|
||||||
|
|
||||||
// #[derive(Debug, Deserialize)]
|
|
||||||
// pub struct Schedule {
|
|
||||||
// pub when: String,
|
|
||||||
// pub actions: IndexMap<Action, Vec<String>>,
|
|
||||||
// }
|
|
||||||
104
config.lua
104
config.lua
@@ -30,6 +30,11 @@ local mqtt_client = require("automation:mqtt").new(device_manager, {
|
|||||||
tls = host == "zeus" or host == "hephaestus",
|
tls = host == "zeus" or host == "hephaestus",
|
||||||
})
|
})
|
||||||
|
|
||||||
|
local devs = {}
|
||||||
|
function devs:add(device)
|
||||||
|
table.insert(self, device)
|
||||||
|
end
|
||||||
|
|
||||||
local ntfy_topic = secrets.ntfy_topic
|
local ntfy_topic = secrets.ntfy_topic
|
||||||
if ntfy_topic == nil then
|
if ntfy_topic == nil then
|
||||||
error("Ntfy topic is not specified")
|
error("Ntfy topic is not specified")
|
||||||
@@ -37,7 +42,7 @@ end
|
|||||||
local ntfy = devices.Ntfy.new({
|
local ntfy = devices.Ntfy.new({
|
||||||
topic = ntfy_topic,
|
topic = ntfy_topic,
|
||||||
})
|
})
|
||||||
device_manager:add(ntfy)
|
devs:add(ntfy)
|
||||||
|
|
||||||
--- @type {[string]: number}
|
--- @type {[string]: number}
|
||||||
local low_battery = {}
|
local low_battery = {}
|
||||||
@@ -52,7 +57,7 @@ local function check_battery(device, battery)
|
|||||||
low_battery[id] = nil
|
low_battery[id] = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
device_manager:schedule("0 0 21 */1 * *", function()
|
local function notify_low_battery()
|
||||||
-- Don't send notifications if there are now devices with low battery
|
-- Don't send notifications if there are now devices with low battery
|
||||||
if next(low_battery) == nil then
|
if next(low_battery) == nil then
|
||||||
print("No devices with low battery")
|
print("No devices with low battery")
|
||||||
@@ -71,7 +76,7 @@ device_manager:schedule("0 0 21 */1 * *", function()
|
|||||||
tags = { "battery" },
|
tags = { "battery" },
|
||||||
priority = "default",
|
priority = "default",
|
||||||
})
|
})
|
||||||
end)
|
end
|
||||||
|
|
||||||
--- @class OnPresence
|
--- @class OnPresence
|
||||||
--- @field [integer] fun(presence: boolean)
|
--- @field [integer] fun(presence: boolean)
|
||||||
@@ -92,7 +97,7 @@ local presence_system = devices.Presence.new({
|
|||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
device_manager:add(presence_system)
|
devs:add(presence_system)
|
||||||
on_presence:add(function(presence)
|
on_presence:add(function(presence)
|
||||||
ntfy:send_notification({
|
ntfy:send_notification({
|
||||||
title = "Presence",
|
title = "Presence",
|
||||||
@@ -166,7 +171,7 @@ local on_light = {}
|
|||||||
function on_light:add(f)
|
function on_light:add(f)
|
||||||
self[#self + 1] = f
|
self[#self + 1] = f
|
||||||
end
|
end
|
||||||
device_manager:add(devices.LightSensor.new({
|
devs:add(devices.LightSensor.new({
|
||||||
identifier = "living_light_sensor",
|
identifier = "living_light_sensor",
|
||||||
topic = mqtt_z2m("living/light"),
|
topic = mqtt_z2m("living/light"),
|
||||||
client = mqtt_client,
|
client = mqtt_client,
|
||||||
@@ -202,7 +207,7 @@ local hue_bridge = devices.HueBridge.new({
|
|||||||
darkness = 43,
|
darkness = 43,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
device_manager:add(hue_bridge)
|
devs:add(hue_bridge)
|
||||||
on_light:add(function(light)
|
on_light:add(function(light)
|
||||||
hue_bridge:set_flag("darkness", not light)
|
hue_bridge:set_flag("darkness", not light)
|
||||||
end)
|
end)
|
||||||
@@ -217,7 +222,7 @@ local kitchen_lights = devices.HueGroup.new({
|
|||||||
group_id = 7,
|
group_id = 7,
|
||||||
scene_id = "7MJLG27RzeRAEVJ",
|
scene_id = "7MJLG27RzeRAEVJ",
|
||||||
})
|
})
|
||||||
device_manager:add(kitchen_lights)
|
devs:add(kitchen_lights)
|
||||||
local living_lights = devices.HueGroup.new({
|
local living_lights = devices.HueGroup.new({
|
||||||
identifier = "living_lights",
|
identifier = "living_lights",
|
||||||
ip = hue_ip,
|
ip = hue_ip,
|
||||||
@@ -225,7 +230,7 @@ local living_lights = devices.HueGroup.new({
|
|||||||
group_id = 1,
|
group_id = 1,
|
||||||
scene_id = "SNZw7jUhQ3cXSjkj",
|
scene_id = "SNZw7jUhQ3cXSjkj",
|
||||||
})
|
})
|
||||||
device_manager:add(living_lights)
|
devs:add(living_lights)
|
||||||
local living_lights_relax = devices.HueGroup.new({
|
local living_lights_relax = devices.HueGroup.new({
|
||||||
identifier = "living_lights",
|
identifier = "living_lights",
|
||||||
ip = hue_ip,
|
ip = hue_ip,
|
||||||
@@ -233,9 +238,9 @@ local living_lights_relax = devices.HueGroup.new({
|
|||||||
group_id = 1,
|
group_id = 1,
|
||||||
scene_id = "eRJ3fvGHCcb6yNw",
|
scene_id = "eRJ3fvGHCcb6yNw",
|
||||||
})
|
})
|
||||||
device_manager:add(living_lights_relax)
|
devs:add(living_lights_relax)
|
||||||
|
|
||||||
device_manager:add(devices.HueSwitch.new({
|
devs:add(devices.HueSwitch.new({
|
||||||
name = "Switch",
|
name = "Switch",
|
||||||
room = "Living",
|
room = "Living",
|
||||||
client = mqtt_client,
|
client = mqtt_client,
|
||||||
@@ -252,7 +257,7 @@ device_manager:add(devices.HueSwitch.new({
|
|||||||
battery_callback = check_battery,
|
battery_callback = check_battery,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
device_manager:add(devices.WakeOnLAN.new({
|
devs:add(devices.WakeOnLAN.new({
|
||||||
name = "Zeus",
|
name = "Zeus",
|
||||||
room = "Living Room",
|
room = "Living Room",
|
||||||
topic = mqtt_automation("appliance/living_room/zeus"),
|
topic = mqtt_automation("appliance/living_room/zeus"),
|
||||||
@@ -268,7 +273,7 @@ local living_mixer = devices.OutletOnOff.new({
|
|||||||
client = mqtt_client,
|
client = mqtt_client,
|
||||||
})
|
})
|
||||||
turn_off_when_away(living_mixer)
|
turn_off_when_away(living_mixer)
|
||||||
device_manager:add(living_mixer)
|
devs:add(living_mixer)
|
||||||
local living_speakers = devices.OutletOnOff.new({
|
local living_speakers = devices.OutletOnOff.new({
|
||||||
name = "Speakers",
|
name = "Speakers",
|
||||||
room = "Living Room",
|
room = "Living Room",
|
||||||
@@ -276,9 +281,9 @@ local living_speakers = devices.OutletOnOff.new({
|
|||||||
client = mqtt_client,
|
client = mqtt_client,
|
||||||
})
|
})
|
||||||
turn_off_when_away(living_speakers)
|
turn_off_when_away(living_speakers)
|
||||||
device_manager:add(living_speakers)
|
devs:add(living_speakers)
|
||||||
|
|
||||||
device_manager:add(devices.IkeaRemote.new({
|
devs:add(devices.IkeaRemote.new({
|
||||||
name = "Remote",
|
name = "Remote",
|
||||||
room = "Living Room",
|
room = "Living Room",
|
||||||
client = mqtt_client,
|
client = mqtt_client,
|
||||||
@@ -329,14 +334,14 @@ local kettle = devices.OutletPower.new({
|
|||||||
callback = kettle_timeout(),
|
callback = kettle_timeout(),
|
||||||
})
|
})
|
||||||
turn_off_when_away(kettle)
|
turn_off_when_away(kettle)
|
||||||
device_manager:add(kettle)
|
devs:add(kettle)
|
||||||
|
|
||||||
--- @param on boolean
|
--- @param on boolean
|
||||||
local function set_kettle(_, on)
|
local function set_kettle(_, on)
|
||||||
kettle:set_on(on)
|
kettle:set_on(on)
|
||||||
end
|
end
|
||||||
|
|
||||||
device_manager:add(devices.IkeaRemote.new({
|
devs:add(devices.IkeaRemote.new({
|
||||||
name = "Remote",
|
name = "Remote",
|
||||||
room = "Bedroom",
|
room = "Bedroom",
|
||||||
client = mqtt_client,
|
client = mqtt_client,
|
||||||
@@ -346,7 +351,7 @@ device_manager:add(devices.IkeaRemote.new({
|
|||||||
battery_callback = check_battery,
|
battery_callback = check_battery,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
device_manager:add(devices.IkeaRemote.new({
|
devs:add(devices.IkeaRemote.new({
|
||||||
name = "Remote",
|
name = "Remote",
|
||||||
room = "Kitchen",
|
room = "Kitchen",
|
||||||
client = mqtt_client,
|
client = mqtt_client,
|
||||||
@@ -379,9 +384,9 @@ local bathroom_light = devices.LightOnOff.new({
|
|||||||
client = mqtt_client,
|
client = mqtt_client,
|
||||||
callback = off_timeout(debug and 60 or 45 * 60),
|
callback = off_timeout(debug and 60 or 45 * 60),
|
||||||
})
|
})
|
||||||
device_manager:add(bathroom_light)
|
devs:add(bathroom_light)
|
||||||
|
|
||||||
device_manager:add(devices.Washer.new({
|
devs:add(devices.Washer.new({
|
||||||
identifier = "bathroom_washer",
|
identifier = "bathroom_washer",
|
||||||
topic = mqtt_z2m("bathroom/washer"),
|
topic = mqtt_z2m("bathroom/washer"),
|
||||||
client = mqtt_client,
|
client = mqtt_client,
|
||||||
@@ -396,7 +401,7 @@ device_manager:add(devices.Washer.new({
|
|||||||
end,
|
end,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
device_manager:add(devices.OutletOnOff.new({
|
devs:add(devices.OutletOnOff.new({
|
||||||
name = "Charger",
|
name = "Charger",
|
||||||
room = "Workbench",
|
room = "Workbench",
|
||||||
topic = mqtt_z2m("workbench/charger"),
|
topic = mqtt_z2m("workbench/charger"),
|
||||||
@@ -411,7 +416,7 @@ local workbench_outlet = devices.OutletOnOff.new({
|
|||||||
client = mqtt_client,
|
client = mqtt_client,
|
||||||
})
|
})
|
||||||
turn_off_when_away(workbench_outlet)
|
turn_off_when_away(workbench_outlet)
|
||||||
device_manager:add(workbench_outlet)
|
devs:add(workbench_outlet)
|
||||||
|
|
||||||
local workbench_light = devices.LightColorTemperature.new({
|
local workbench_light = devices.LightColorTemperature.new({
|
||||||
name = "Light",
|
name = "Light",
|
||||||
@@ -420,10 +425,10 @@ local workbench_light = devices.LightColorTemperature.new({
|
|||||||
client = mqtt_client,
|
client = mqtt_client,
|
||||||
})
|
})
|
||||||
turn_off_when_away(workbench_light)
|
turn_off_when_away(workbench_light)
|
||||||
device_manager:add(workbench_light)
|
devs:add(workbench_light)
|
||||||
|
|
||||||
local delay_color_temp = utils.Timeout.new()
|
local delay_color_temp = utils.Timeout.new()
|
||||||
device_manager:add(devices.IkeaRemote.new({
|
devs:add(devices.IkeaRemote.new({
|
||||||
name = "Remote",
|
name = "Remote",
|
||||||
room = "Workbench",
|
room = "Workbench",
|
||||||
client = mqtt_client,
|
client = mqtt_client,
|
||||||
@@ -453,7 +458,7 @@ local hallway_top_light = devices.HueGroup.new({
|
|||||||
group_id = 83,
|
group_id = 83,
|
||||||
scene_id = "QeufkFDICEHWeKJ7",
|
scene_id = "QeufkFDICEHWeKJ7",
|
||||||
})
|
})
|
||||||
device_manager:add(devices.HueSwitch.new({
|
devs:add(devices.HueSwitch.new({
|
||||||
name = "SwitchBottom",
|
name = "SwitchBottom",
|
||||||
room = "Hallway",
|
room = "Hallway",
|
||||||
client = mqtt_client,
|
client = mqtt_client,
|
||||||
@@ -463,7 +468,7 @@ device_manager:add(devices.HueSwitch.new({
|
|||||||
end,
|
end,
|
||||||
battery_callback = check_battery,
|
battery_callback = check_battery,
|
||||||
}))
|
}))
|
||||||
device_manager:add(devices.HueSwitch.new({
|
devs:add(devices.HueSwitch.new({
|
||||||
name = "SwitchTop",
|
name = "SwitchTop",
|
||||||
room = "Hallway",
|
room = "Hallway",
|
||||||
client = mqtt_client,
|
client = mqtt_client,
|
||||||
@@ -546,7 +551,7 @@ local hallway_storage = devices.LightBrightness.new({
|
|||||||
callback = hallway_light_automation:light_callback(),
|
callback = hallway_light_automation:light_callback(),
|
||||||
})
|
})
|
||||||
turn_off_when_away(hallway_storage)
|
turn_off_when_away(hallway_storage)
|
||||||
device_manager:add(hallway_storage)
|
devs:add(hallway_storage)
|
||||||
|
|
||||||
local hallway_bottom_lights = devices.HueGroup.new({
|
local hallway_bottom_lights = devices.HueGroup.new({
|
||||||
identifier = "hallway_bottom_lights",
|
identifier = "hallway_bottom_lights",
|
||||||
@@ -555,7 +560,7 @@ local hallway_bottom_lights = devices.HueGroup.new({
|
|||||||
group_id = 81,
|
group_id = 81,
|
||||||
scene_id = "3qWKxGVadXFFG4o",
|
scene_id = "3qWKxGVadXFFG4o",
|
||||||
})
|
})
|
||||||
device_manager:add(hallway_bottom_lights)
|
devs:add(hallway_bottom_lights)
|
||||||
|
|
||||||
hallway_light_automation.group = {
|
hallway_light_automation.group = {
|
||||||
set_on = function(on)
|
set_on = function(on)
|
||||||
@@ -591,7 +596,7 @@ local function presence(duration)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
device_manager:add(devices.IkeaRemote.new({
|
devs:add(devices.IkeaRemote.new({
|
||||||
name = "Remote",
|
name = "Remote",
|
||||||
room = "Hallway",
|
room = "Hallway",
|
||||||
client = mqtt_client,
|
client = mqtt_client,
|
||||||
@@ -611,7 +616,7 @@ local hallway_frontdoor = devices.ContactSensor.new({
|
|||||||
},
|
},
|
||||||
battery_callback = check_battery,
|
battery_callback = check_battery,
|
||||||
})
|
})
|
||||||
device_manager:add(hallway_frontdoor)
|
devs:add(hallway_frontdoor)
|
||||||
window_sensors:add(hallway_frontdoor)
|
window_sensors:add(hallway_frontdoor)
|
||||||
hallway_light_automation.door = hallway_frontdoor
|
hallway_light_automation.door = hallway_frontdoor
|
||||||
|
|
||||||
@@ -624,7 +629,7 @@ local hallway_trash = devices.ContactSensor.new({
|
|||||||
callback = hallway_light_automation:trash_callback(),
|
callback = hallway_light_automation:trash_callback(),
|
||||||
battery_callback = check_battery,
|
battery_callback = check_battery,
|
||||||
})
|
})
|
||||||
device_manager:add(hallway_trash)
|
devs:add(hallway_trash)
|
||||||
hallway_light_automation.trash = hallway_trash
|
hallway_light_automation.trash = hallway_trash
|
||||||
|
|
||||||
local guest_light = devices.LightOnOff.new({
|
local guest_light = devices.LightOnOff.new({
|
||||||
@@ -634,14 +639,14 @@ local guest_light = devices.LightOnOff.new({
|
|||||||
client = mqtt_client,
|
client = mqtt_client,
|
||||||
})
|
})
|
||||||
turn_off_when_away(guest_light)
|
turn_off_when_away(guest_light)
|
||||||
device_manager:add(guest_light)
|
devs:add(guest_light)
|
||||||
|
|
||||||
local bedroom_air_filter = devices.AirFilter.new({
|
local bedroom_air_filter = devices.AirFilter.new({
|
||||||
name = "Air Filter",
|
name = "Air Filter",
|
||||||
room = "Bedroom",
|
room = "Bedroom",
|
||||||
url = "http://10.0.0.103",
|
url = "http://10.0.0.103",
|
||||||
})
|
})
|
||||||
device_manager:add(bedroom_air_filter)
|
devs:add(bedroom_air_filter)
|
||||||
|
|
||||||
local bedroom_lights = devices.HueGroup.new({
|
local bedroom_lights = devices.HueGroup.new({
|
||||||
identifier = "bedroom_lights",
|
identifier = "bedroom_lights",
|
||||||
@@ -650,7 +655,7 @@ local bedroom_lights = devices.HueGroup.new({
|
|||||||
group_id = 3,
|
group_id = 3,
|
||||||
scene_id = "PvRs-lGD4VRytL9",
|
scene_id = "PvRs-lGD4VRytL9",
|
||||||
})
|
})
|
||||||
device_manager:add(bedroom_lights)
|
devs:add(bedroom_lights)
|
||||||
local bedroom_lights_relax = devices.HueGroup.new({
|
local bedroom_lights_relax = devices.HueGroup.new({
|
||||||
identifier = "bedroom_lights",
|
identifier = "bedroom_lights",
|
||||||
ip = hue_ip,
|
ip = hue_ip,
|
||||||
@@ -658,9 +663,9 @@ local bedroom_lights_relax = devices.HueGroup.new({
|
|||||||
group_id = 3,
|
group_id = 3,
|
||||||
scene_id = "60tfTyR168v2csz",
|
scene_id = "60tfTyR168v2csz",
|
||||||
})
|
})
|
||||||
device_manager:add(bedroom_lights_relax)
|
devs:add(bedroom_lights_relax)
|
||||||
|
|
||||||
device_manager:add(devices.HueSwitch.new({
|
devs:add(devices.HueSwitch.new({
|
||||||
name = "Switch",
|
name = "Switch",
|
||||||
room = "Bedroom",
|
room = "Bedroom",
|
||||||
client = mqtt_client,
|
client = mqtt_client,
|
||||||
@@ -682,7 +687,7 @@ local balcony = devices.ContactSensor.new({
|
|||||||
client = mqtt_client,
|
client = mqtt_client,
|
||||||
battery_callback = check_battery,
|
battery_callback = check_battery,
|
||||||
})
|
})
|
||||||
device_manager:add(balcony)
|
devs:add(balcony)
|
||||||
window_sensors:add(balcony)
|
window_sensors:add(balcony)
|
||||||
local living_window = devices.ContactSensor.new({
|
local living_window = devices.ContactSensor.new({
|
||||||
name = "Window",
|
name = "Window",
|
||||||
@@ -691,7 +696,7 @@ local living_window = devices.ContactSensor.new({
|
|||||||
client = mqtt_client,
|
client = mqtt_client,
|
||||||
battery_callback = check_battery,
|
battery_callback = check_battery,
|
||||||
})
|
})
|
||||||
device_manager:add(living_window)
|
devs:add(living_window)
|
||||||
window_sensors:add(living_window)
|
window_sensors:add(living_window)
|
||||||
local bedroom_window = devices.ContactSensor.new({
|
local bedroom_window = devices.ContactSensor.new({
|
||||||
name = "Window",
|
name = "Window",
|
||||||
@@ -700,7 +705,7 @@ local bedroom_window = devices.ContactSensor.new({
|
|||||||
client = mqtt_client,
|
client = mqtt_client,
|
||||||
battery_callback = check_battery,
|
battery_callback = check_battery,
|
||||||
})
|
})
|
||||||
device_manager:add(bedroom_window)
|
devs:add(bedroom_window)
|
||||||
window_sensors:add(bedroom_window)
|
window_sensors:add(bedroom_window)
|
||||||
local guest_window = devices.ContactSensor.new({
|
local guest_window = devices.ContactSensor.new({
|
||||||
name = "Window",
|
name = "Window",
|
||||||
@@ -709,7 +714,7 @@ local guest_window = devices.ContactSensor.new({
|
|||||||
client = mqtt_client,
|
client = mqtt_client,
|
||||||
battery_callback = check_battery,
|
battery_callback = check_battery,
|
||||||
})
|
})
|
||||||
device_manager:add(guest_window)
|
devs:add(guest_window)
|
||||||
window_sensors:add(guest_window)
|
window_sensors:add(guest_window)
|
||||||
|
|
||||||
local storage_light = devices.LightBrightness.new({
|
local storage_light = devices.LightBrightness.new({
|
||||||
@@ -719,9 +724,9 @@ local storage_light = devices.LightBrightness.new({
|
|||||||
client = mqtt_client,
|
client = mqtt_client,
|
||||||
})
|
})
|
||||||
turn_off_when_away(storage_light)
|
turn_off_when_away(storage_light)
|
||||||
device_manager:add(storage_light)
|
devs:add(storage_light)
|
||||||
|
|
||||||
device_manager:add(devices.ContactSensor.new({
|
devs:add(devices.ContactSensor.new({
|
||||||
name = "Door",
|
name = "Door",
|
||||||
room = "Storage",
|
room = "Storage",
|
||||||
sensor_type = "Door",
|
sensor_type = "Door",
|
||||||
@@ -737,16 +742,19 @@ device_manager:add(devices.ContactSensor.new({
|
|||||||
battery_callback = check_battery,
|
battery_callback = check_battery,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
device_manager:schedule("0 0 19 * * *", function()
|
|
||||||
bedroom_air_filter:set_on(true)
|
|
||||||
end)
|
|
||||||
device_manager:schedule("0 0 20 * * *", function()
|
|
||||||
bedroom_air_filter:set_on(false)
|
|
||||||
end)
|
|
||||||
|
|
||||||
---@type Config
|
---@type Config
|
||||||
return {
|
return {
|
||||||
fulfillment = {
|
fulfillment = {
|
||||||
openid_url = "https://login.huizinga.dev/api/oidc",
|
openid_url = "https://login.huizinga.dev/api/oidc",
|
||||||
},
|
},
|
||||||
|
devices = devs,
|
||||||
|
schedule = {
|
||||||
|
["0 0 19 * * *"] = function()
|
||||||
|
bedroom_air_filter:set_on(true)
|
||||||
|
end,
|
||||||
|
["0 0 20 * * *"] = function()
|
||||||
|
bedroom_air_filter:set_on(false)
|
||||||
|
end,
|
||||||
|
["0 0 21 */1 * *"] = notify_low_battery,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,8 +5,4 @@ local DeviceManager
|
|||||||
---@param device DeviceInterface
|
---@param device DeviceInterface
|
||||||
function DeviceManager:add(device) end
|
function DeviceManager:add(device) end
|
||||||
|
|
||||||
---@param cron string
|
|
||||||
---@param callback fun()
|
|
||||||
function DeviceManager:schedule(cron, callback) end
|
|
||||||
|
|
||||||
return DeviceManager
|
return DeviceManager
|
||||||
|
|||||||
@@ -3,17 +3,13 @@
|
|||||||
|
|
||||||
local devices
|
local devices
|
||||||
|
|
||||||
---@class KasaOutletConfig
|
---@class Action
|
||||||
---@field identifier string
|
---@field action
|
||||||
---@field ip string
|
---| "broadcast"
|
||||||
local KasaOutletConfig
|
---@field extras table<string, string>?
|
||||||
|
---@field label string
|
||||||
---@class KasaOutlet: DeviceInterface, OnOffInterface
|
---@field clear boolean?
|
||||||
local KasaOutlet
|
local Action
|
||||||
devices.KasaOutlet = {}
|
|
||||||
---@param config KasaOutletConfig
|
|
||||||
---@return KasaOutlet
|
|
||||||
function devices.KasaOutlet.new(config) end
|
|
||||||
|
|
||||||
---@class AirFilter: DeviceInterface, OnOffInterface
|
---@class AirFilter: DeviceInterface, OnOffInterface
|
||||||
local AirFilter
|
local AirFilter
|
||||||
@@ -28,21 +24,73 @@ function devices.AirFilter.new(config) end
|
|||||||
---@field url string
|
---@field url string
|
||||||
local AirFilterConfig
|
local AirFilterConfig
|
||||||
|
|
||||||
---@class Presence: DeviceInterface
|
---@class ConfigLightLightStateBrightness
|
||||||
local Presence
|
---@field name string
|
||||||
devices.Presence = {}
|
---@field room string?
|
||||||
---@param config PresenceConfig
|
|
||||||
---@return Presence
|
|
||||||
function devices.Presence.new(config) end
|
|
||||||
---@async
|
|
||||||
---@return boolean
|
|
||||||
function Presence:overall_presence() end
|
|
||||||
|
|
||||||
---@class PresenceConfig
|
|
||||||
---@field topic string
|
---@field topic string
|
||||||
---@field callback fun(_: Presence, _: boolean) | fun(_: Presence, _: boolean)[]?
|
---@field callback fun(_: LightBrightness, _: LightStateBrightness) | fun(_: LightBrightness, _: LightStateBrightness)[]?
|
||||||
|
---@field client AsyncClient?
|
||||||
|
local ConfigLightLightStateBrightness
|
||||||
|
|
||||||
|
---@class ConfigLightLightStateColorTemperature
|
||||||
|
---@field name string
|
||||||
|
---@field room string?
|
||||||
|
---@field topic string
|
||||||
|
---@field callback fun(_: LightColorTemperature, _: LightStateColorTemperature) | fun(_: LightColorTemperature, _: LightStateColorTemperature)[]?
|
||||||
|
---@field client AsyncClient?
|
||||||
|
local ConfigLightLightStateColorTemperature
|
||||||
|
|
||||||
|
---@class ConfigLightLightStateOnOff
|
||||||
|
---@field name string
|
||||||
|
---@field room string?
|
||||||
|
---@field topic string
|
||||||
|
---@field callback fun(_: LightOnOff, _: LightStateOnOff) | fun(_: LightOnOff, _: LightStateOnOff)[]?
|
||||||
|
---@field client AsyncClient?
|
||||||
|
local ConfigLightLightStateOnOff
|
||||||
|
|
||||||
|
---@class ConfigOutletOutletStateOnOff
|
||||||
|
---@field name string
|
||||||
|
---@field room string?
|
||||||
|
---@field topic string
|
||||||
|
---@field outlet_type OutletType?
|
||||||
|
---@field callback fun(_: OutletOnOff, _: OutletStateOnOff) | fun(_: OutletOnOff, _: OutletStateOnOff)[]?
|
||||||
---@field client AsyncClient
|
---@field client AsyncClient
|
||||||
local PresenceConfig
|
local ConfigOutletOutletStateOnOff
|
||||||
|
|
||||||
|
---@class ConfigOutletOutletStatePower
|
||||||
|
---@field name string
|
||||||
|
---@field room string?
|
||||||
|
---@field topic string
|
||||||
|
---@field outlet_type OutletType?
|
||||||
|
---@field callback fun(_: OutletPower, _: OutletStatePower) | fun(_: OutletPower, _: OutletStatePower)[]?
|
||||||
|
---@field client AsyncClient
|
||||||
|
local ConfigOutletOutletStatePower
|
||||||
|
|
||||||
|
---@class ContactSensor: DeviceInterface, OpenCloseInterface
|
||||||
|
local ContactSensor
|
||||||
|
devices.ContactSensor = {}
|
||||||
|
---@param config ContactSensorConfig
|
||||||
|
---@return ContactSensor
|
||||||
|
function devices.ContactSensor.new(config) end
|
||||||
|
|
||||||
|
---@class ContactSensorConfig
|
||||||
|
---@field name string
|
||||||
|
---@field room string?
|
||||||
|
---@field topic string
|
||||||
|
---@field sensor_type SensorType?
|
||||||
|
---@field callback fun(_: ContactSensor, _: boolean) | fun(_: ContactSensor, _: boolean)[]?
|
||||||
|
---@field battery_callback fun(_: ContactSensor, _: number) | fun(_: ContactSensor, _: number)[]?
|
||||||
|
---@field client AsyncClient?
|
||||||
|
local ContactSensorConfig
|
||||||
|
|
||||||
|
---@alias Flag
|
||||||
|
---| "presence"
|
||||||
|
---| "darkness"
|
||||||
|
|
||||||
|
---@class FlagIDs
|
||||||
|
---@field presence integer
|
||||||
|
---@field darkness integer
|
||||||
|
local FlagIDs
|
||||||
|
|
||||||
---@class HueBridge: DeviceInterface
|
---@class HueBridge: DeviceInterface
|
||||||
local HueBridge
|
local HueBridge
|
||||||
@@ -55,11 +103,6 @@ function devices.HueBridge.new(config) end
|
|||||||
---@param value boolean
|
---@param value boolean
|
||||||
function HueBridge:set_flag(flag, value) end
|
function HueBridge:set_flag(flag, value) end
|
||||||
|
|
||||||
---@class FlagIDs
|
|
||||||
---@field presence integer
|
|
||||||
---@field darkness integer
|
|
||||||
local FlagIDs
|
|
||||||
|
|
||||||
---@class HueBridgeConfig
|
---@class HueBridgeConfig
|
||||||
---@field identifier string
|
---@field identifier string
|
||||||
---@field ip string
|
---@field ip string
|
||||||
@@ -67,49 +110,6 @@ local FlagIDs
|
|||||||
---@field flags FlagIDs
|
---@field flags FlagIDs
|
||||||
local HueBridgeConfig
|
local HueBridgeConfig
|
||||||
|
|
||||||
---@alias Flag
|
|
||||||
---| "presence"
|
|
||||||
---| "darkness"
|
|
||||||
|
|
||||||
---@class WasherConfig
|
|
||||||
---@field identifier string
|
|
||||||
---@field topic string
|
|
||||||
---@field threshold number
|
|
||||||
---@field done_callback fun(_: Washer) | fun(_: Washer)[]?
|
|
||||||
---@field client AsyncClient
|
|
||||||
local WasherConfig
|
|
||||||
|
|
||||||
---@class Washer: DeviceInterface
|
|
||||||
local Washer
|
|
||||||
devices.Washer = {}
|
|
||||||
---@param config WasherConfig
|
|
||||||
---@return Washer
|
|
||||||
function devices.Washer.new(config) end
|
|
||||||
|
|
||||||
---@class LightSensor: DeviceInterface
|
|
||||||
local LightSensor
|
|
||||||
devices.LightSensor = {}
|
|
||||||
---@param config LightSensorConfig
|
|
||||||
---@return LightSensor
|
|
||||||
function devices.LightSensor.new(config) end
|
|
||||||
|
|
||||||
---@class LightSensorConfig
|
|
||||||
---@field identifier string
|
|
||||||
---@field topic string
|
|
||||||
---@field min integer
|
|
||||||
---@field max integer
|
|
||||||
---@field callback fun(_: LightSensor, _: boolean) | fun(_: LightSensor, _: boolean)[]?
|
|
||||||
---@field client AsyncClient
|
|
||||||
local LightSensorConfig
|
|
||||||
|
|
||||||
---@class HueGroupConfig
|
|
||||||
---@field identifier string
|
|
||||||
---@field ip string
|
|
||||||
---@field login string
|
|
||||||
---@field group_id integer
|
|
||||||
---@field scene_id string
|
|
||||||
local HueGroupConfig
|
|
||||||
|
|
||||||
---@class HueGroup: DeviceInterface, OnOffInterface
|
---@class HueGroup: DeviceInterface, OnOffInterface
|
||||||
local HueGroup
|
local HueGroup
|
||||||
devices.HueGroup = {}
|
devices.HueGroup = {}
|
||||||
@@ -117,203 +117,13 @@ devices.HueGroup = {}
|
|||||||
---@return HueGroup
|
---@return HueGroup
|
||||||
function devices.HueGroup.new(config) end
|
function devices.HueGroup.new(config) end
|
||||||
|
|
||||||
---@class IkeaRemote: DeviceInterface
|
---@class HueGroupConfig
|
||||||
local IkeaRemote
|
---@field identifier string
|
||||||
devices.IkeaRemote = {}
|
---@field ip string
|
||||||
---@param config IkeaRemoteConfig
|
---@field login string
|
||||||
---@return IkeaRemote
|
---@field group_id integer
|
||||||
function devices.IkeaRemote.new(config) end
|
---@field scene_id string
|
||||||
|
local HueGroupConfig
|
||||||
---@class IkeaRemoteConfig
|
|
||||||
---@field name string
|
|
||||||
---@field room string?
|
|
||||||
---@field single_button boolean?
|
|
||||||
---@field topic string
|
|
||||||
---@field client AsyncClient
|
|
||||||
---@field callback fun(_: IkeaRemote, _: boolean) | fun(_: IkeaRemote, _: boolean)[]?
|
|
||||||
---@field battery_callback fun(_: IkeaRemote, _: number) | fun(_: IkeaRemote, _: number)[]?
|
|
||||||
local IkeaRemoteConfig
|
|
||||||
|
|
||||||
---@class WolConfig
|
|
||||||
---@field name string
|
|
||||||
---@field room string?
|
|
||||||
---@field topic string
|
|
||||||
---@field mac_address string
|
|
||||||
---@field broadcast_ip string?
|
|
||||||
---@field client AsyncClient
|
|
||||||
local WolConfig
|
|
||||||
|
|
||||||
---@class WakeOnLAN: DeviceInterface
|
|
||||||
local WakeOnLAN
|
|
||||||
devices.WakeOnLAN = {}
|
|
||||||
---@param config WolConfig
|
|
||||||
---@return WakeOnLAN
|
|
||||||
function devices.WakeOnLAN.new(config) end
|
|
||||||
|
|
||||||
---@class ConfigOutletOutletStateOnOff
|
|
||||||
---@field name string
|
|
||||||
---@field room string?
|
|
||||||
---@field topic string
|
|
||||||
---@field outlet_type OutletType?
|
|
||||||
---@field callback fun(_: OutletOnOff, _: OutletStateOnOff) | fun(_: OutletOnOff, _: OutletStateOnOff)[]?
|
|
||||||
---@field client AsyncClient
|
|
||||||
local ConfigOutletOutletStateOnOff
|
|
||||||
|
|
||||||
---@class OutletStatePower
|
|
||||||
---@field state boolean
|
|
||||||
---@field power number
|
|
||||||
local OutletStatePower
|
|
||||||
|
|
||||||
---@class ConfigOutletOutletStatePower
|
|
||||||
---@field name string
|
|
||||||
---@field room string?
|
|
||||||
---@field topic string
|
|
||||||
---@field outlet_type OutletType?
|
|
||||||
---@field callback fun(_: OutletPower, _: OutletStatePower) | fun(_: OutletPower, _: OutletStatePower)[]?
|
|
||||||
---@field client AsyncClient
|
|
||||||
local ConfigOutletOutletStatePower
|
|
||||||
|
|
||||||
---@alias OutletType
|
|
||||||
---| "Outlet"
|
|
||||||
---| "Kettle"
|
|
||||||
|
|
||||||
---@class OutletStateOnOff
|
|
||||||
---@field state boolean
|
|
||||||
local OutletStateOnOff
|
|
||||||
|
|
||||||
---@class OutletOnOff: DeviceInterface, OnOffInterface
|
|
||||||
local OutletOnOff
|
|
||||||
devices.OutletOnOff = {}
|
|
||||||
---@param config ConfigOutletOutletStateOnOff
|
|
||||||
---@return OutletOnOff
|
|
||||||
function devices.OutletOnOff.new(config) end
|
|
||||||
|
|
||||||
---@class OutletPower: DeviceInterface, OnOffInterface
|
|
||||||
local OutletPower
|
|
||||||
devices.OutletPower = {}
|
|
||||||
---@param config ConfigOutletOutletStatePower
|
|
||||||
---@return OutletPower
|
|
||||||
function devices.OutletPower.new(config) end
|
|
||||||
|
|
||||||
---@class ContactSensorConfig
|
|
||||||
---@field name string
|
|
||||||
---@field room string?
|
|
||||||
---@field topic string
|
|
||||||
---@field sensor_type SensorType?
|
|
||||||
---@field callback fun(_: ContactSensor, _: boolean) | fun(_: ContactSensor, _: boolean)[]?
|
|
||||||
---@field battery_callback fun(_: ContactSensor, _: number) | fun(_: ContactSensor, _: number)[]?
|
|
||||||
---@field client AsyncClient?
|
|
||||||
local ContactSensorConfig
|
|
||||||
|
|
||||||
---@alias SensorType
|
|
||||||
---| "Door"
|
|
||||||
---| "Drawer"
|
|
||||||
---| "Window"
|
|
||||||
|
|
||||||
---@class ContactSensor: DeviceInterface, OpenCloseInterface
|
|
||||||
local ContactSensor
|
|
||||||
devices.ContactSensor = {}
|
|
||||||
---@param config ContactSensorConfig
|
|
||||||
---@return ContactSensor
|
|
||||||
function devices.ContactSensor.new(config) end
|
|
||||||
|
|
||||||
---@class LightStateOnOff
|
|
||||||
---@field state boolean
|
|
||||||
local LightStateOnOff
|
|
||||||
|
|
||||||
---@class ConfigLightLightStateColorTemperature
|
|
||||||
---@field name string
|
|
||||||
---@field room string?
|
|
||||||
---@field topic string
|
|
||||||
---@field callback fun(_: LightColorTemperature, _: LightStateColorTemperature) | fun(_: LightColorTemperature, _: LightStateColorTemperature)[]?
|
|
||||||
---@field client AsyncClient?
|
|
||||||
local ConfigLightLightStateColorTemperature
|
|
||||||
|
|
||||||
---@class LightStateBrightness
|
|
||||||
---@field state boolean
|
|
||||||
---@field brightness number
|
|
||||||
local LightStateBrightness
|
|
||||||
|
|
||||||
---@class LightStateColorTemperature
|
|
||||||
---@field state boolean
|
|
||||||
---@field brightness number
|
|
||||||
---@field color_temp integer
|
|
||||||
local LightStateColorTemperature
|
|
||||||
|
|
||||||
---@class LightBrightness: DeviceInterface, OnOffInterface, BrightnessInterface
|
|
||||||
local LightBrightness
|
|
||||||
devices.LightBrightness = {}
|
|
||||||
---@param config ConfigLightLightStateBrightness
|
|
||||||
---@return LightBrightness
|
|
||||||
function devices.LightBrightness.new(config) end
|
|
||||||
|
|
||||||
---@class LightColorTemperature: DeviceInterface, OnOffInterface, BrightnessInterface, ColorSettingInterface
|
|
||||||
local LightColorTemperature
|
|
||||||
devices.LightColorTemperature = {}
|
|
||||||
---@param config ConfigLightLightStateColorTemperature
|
|
||||||
---@return LightColorTemperature
|
|
||||||
function devices.LightColorTemperature.new(config) end
|
|
||||||
|
|
||||||
---@class ConfigLightLightStateOnOff
|
|
||||||
---@field name string
|
|
||||||
---@field room string?
|
|
||||||
---@field topic string
|
|
||||||
---@field callback fun(_: LightOnOff, _: LightStateOnOff) | fun(_: LightOnOff, _: LightStateOnOff)[]?
|
|
||||||
---@field client AsyncClient?
|
|
||||||
local ConfigLightLightStateOnOff
|
|
||||||
|
|
||||||
---@class ConfigLightLightStateBrightness
|
|
||||||
---@field name string
|
|
||||||
---@field room string?
|
|
||||||
---@field topic string
|
|
||||||
---@field callback fun(_: LightBrightness, _: LightStateBrightness) | fun(_: LightBrightness, _: LightStateBrightness)[]?
|
|
||||||
---@field client AsyncClient?
|
|
||||||
local ConfigLightLightStateBrightness
|
|
||||||
|
|
||||||
---@class LightOnOff: DeviceInterface, OnOffInterface
|
|
||||||
local LightOnOff
|
|
||||||
devices.LightOnOff = {}
|
|
||||||
---@param config ConfigLightLightStateOnOff
|
|
||||||
---@return LightOnOff
|
|
||||||
function devices.LightOnOff.new(config) end
|
|
||||||
|
|
||||||
---@class Action
|
|
||||||
---@field action
|
|
||||||
---| "broadcast"
|
|
||||||
---@field extras table<string, string>?
|
|
||||||
---@field label string
|
|
||||||
---@field clear boolean?
|
|
||||||
local Action
|
|
||||||
|
|
||||||
---@class NtfyConfig
|
|
||||||
---@field url string?
|
|
||||||
---@field topic string
|
|
||||||
local NtfyConfig
|
|
||||||
|
|
||||||
---@class Notification
|
|
||||||
---@field title string
|
|
||||||
---@field message string?
|
|
||||||
---@field tags string[]?
|
|
||||||
---@field priority Priority?
|
|
||||||
---@field actions Action[]?
|
|
||||||
local Notification
|
|
||||||
|
|
||||||
---@alias Priority
|
|
||||||
---| "min"
|
|
||||||
---| "low"
|
|
||||||
---| "default"
|
|
||||||
---| "high"
|
|
||||||
---| "max"
|
|
||||||
|
|
||||||
---@class Ntfy: DeviceInterface
|
|
||||||
local Ntfy
|
|
||||||
devices.Ntfy = {}
|
|
||||||
---@param config NtfyConfig
|
|
||||||
---@return Ntfy
|
|
||||||
function devices.Ntfy.new(config) end
|
|
||||||
---@async
|
|
||||||
---@param notification Notification
|
|
||||||
function Ntfy:send_notification(notification) end
|
|
||||||
|
|
||||||
---@class HueSwitch: DeviceInterface
|
---@class HueSwitch: DeviceInterface
|
||||||
local HueSwitch
|
local HueSwitch
|
||||||
@@ -334,4 +144,194 @@ function devices.HueSwitch.new(config) end
|
|||||||
---@field battery_callback fun(_: HueSwitch, _: number) | fun(_: HueSwitch, _: number)[]?
|
---@field battery_callback fun(_: HueSwitch, _: number) | fun(_: HueSwitch, _: number)[]?
|
||||||
local HueSwitchConfig
|
local HueSwitchConfig
|
||||||
|
|
||||||
|
---@class IkeaRemote: DeviceInterface
|
||||||
|
local IkeaRemote
|
||||||
|
devices.IkeaRemote = {}
|
||||||
|
---@param config IkeaRemoteConfig
|
||||||
|
---@return IkeaRemote
|
||||||
|
function devices.IkeaRemote.new(config) end
|
||||||
|
|
||||||
|
---@class IkeaRemoteConfig
|
||||||
|
---@field name string
|
||||||
|
---@field room string?
|
||||||
|
---@field single_button boolean?
|
||||||
|
---@field topic string
|
||||||
|
---@field client AsyncClient
|
||||||
|
---@field callback fun(_: IkeaRemote, _: boolean) | fun(_: IkeaRemote, _: boolean)[]?
|
||||||
|
---@field battery_callback fun(_: IkeaRemote, _: number) | fun(_: IkeaRemote, _: number)[]?
|
||||||
|
local IkeaRemoteConfig
|
||||||
|
|
||||||
|
---@class KasaOutlet: DeviceInterface, OnOffInterface
|
||||||
|
local KasaOutlet
|
||||||
|
devices.KasaOutlet = {}
|
||||||
|
---@param config KasaOutletConfig
|
||||||
|
---@return KasaOutlet
|
||||||
|
function devices.KasaOutlet.new(config) end
|
||||||
|
|
||||||
|
---@class KasaOutletConfig
|
||||||
|
---@field identifier string
|
||||||
|
---@field ip string
|
||||||
|
local KasaOutletConfig
|
||||||
|
|
||||||
|
---@class LightBrightness: DeviceInterface, OnOffInterface, BrightnessInterface
|
||||||
|
local LightBrightness
|
||||||
|
devices.LightBrightness = {}
|
||||||
|
---@param config ConfigLightLightStateBrightness
|
||||||
|
---@return LightBrightness
|
||||||
|
function devices.LightBrightness.new(config) end
|
||||||
|
|
||||||
|
---@class LightColorTemperature: DeviceInterface, OnOffInterface, BrightnessInterface, ColorSettingInterface
|
||||||
|
local LightColorTemperature
|
||||||
|
devices.LightColorTemperature = {}
|
||||||
|
---@param config ConfigLightLightStateColorTemperature
|
||||||
|
---@return LightColorTemperature
|
||||||
|
function devices.LightColorTemperature.new(config) end
|
||||||
|
|
||||||
|
---@class LightOnOff: DeviceInterface, OnOffInterface
|
||||||
|
local LightOnOff
|
||||||
|
devices.LightOnOff = {}
|
||||||
|
---@param config ConfigLightLightStateOnOff
|
||||||
|
---@return LightOnOff
|
||||||
|
function devices.LightOnOff.new(config) end
|
||||||
|
|
||||||
|
---@class LightSensor: DeviceInterface
|
||||||
|
local LightSensor
|
||||||
|
devices.LightSensor = {}
|
||||||
|
---@param config LightSensorConfig
|
||||||
|
---@return LightSensor
|
||||||
|
function devices.LightSensor.new(config) end
|
||||||
|
|
||||||
|
---@class LightSensorConfig
|
||||||
|
---@field identifier string
|
||||||
|
---@field topic string
|
||||||
|
---@field min integer
|
||||||
|
---@field max integer
|
||||||
|
---@field callback fun(_: LightSensor, _: boolean) | fun(_: LightSensor, _: boolean)[]?
|
||||||
|
---@field client AsyncClient
|
||||||
|
local LightSensorConfig
|
||||||
|
|
||||||
|
---@class LightStateBrightness
|
||||||
|
---@field state boolean
|
||||||
|
---@field brightness number
|
||||||
|
local LightStateBrightness
|
||||||
|
|
||||||
|
---@class LightStateColorTemperature
|
||||||
|
---@field state boolean
|
||||||
|
---@field brightness number
|
||||||
|
---@field color_temp integer
|
||||||
|
local LightStateColorTemperature
|
||||||
|
|
||||||
|
---@class LightStateOnOff
|
||||||
|
---@field state boolean
|
||||||
|
local LightStateOnOff
|
||||||
|
|
||||||
|
---@class Notification
|
||||||
|
---@field title string
|
||||||
|
---@field message string?
|
||||||
|
---@field tags string[]?
|
||||||
|
---@field priority Priority?
|
||||||
|
---@field actions Action[]?
|
||||||
|
local Notification
|
||||||
|
|
||||||
|
---@class Ntfy: DeviceInterface
|
||||||
|
local Ntfy
|
||||||
|
devices.Ntfy = {}
|
||||||
|
---@param config NtfyConfig
|
||||||
|
---@return Ntfy
|
||||||
|
function devices.Ntfy.new(config) end
|
||||||
|
---@async
|
||||||
|
---@param notification Notification
|
||||||
|
function Ntfy:send_notification(notification) end
|
||||||
|
|
||||||
|
---@class NtfyConfig
|
||||||
|
---@field url string?
|
||||||
|
---@field topic string
|
||||||
|
local NtfyConfig
|
||||||
|
|
||||||
|
---@class OutletOnOff: DeviceInterface, OnOffInterface
|
||||||
|
local OutletOnOff
|
||||||
|
devices.OutletOnOff = {}
|
||||||
|
---@param config ConfigOutletOutletStateOnOff
|
||||||
|
---@return OutletOnOff
|
||||||
|
function devices.OutletOnOff.new(config) end
|
||||||
|
|
||||||
|
---@class OutletPower: DeviceInterface, OnOffInterface
|
||||||
|
local OutletPower
|
||||||
|
devices.OutletPower = {}
|
||||||
|
---@param config ConfigOutletOutletStatePower
|
||||||
|
---@return OutletPower
|
||||||
|
function devices.OutletPower.new(config) end
|
||||||
|
|
||||||
|
---@class OutletStateOnOff
|
||||||
|
---@field state boolean
|
||||||
|
local OutletStateOnOff
|
||||||
|
|
||||||
|
---@class OutletStatePower
|
||||||
|
---@field state boolean
|
||||||
|
---@field power number
|
||||||
|
local OutletStatePower
|
||||||
|
|
||||||
|
---@alias OutletType
|
||||||
|
---| "Outlet"
|
||||||
|
---| "Kettle"
|
||||||
|
|
||||||
|
---@class Presence: DeviceInterface
|
||||||
|
local Presence
|
||||||
|
devices.Presence = {}
|
||||||
|
---@param config PresenceConfig
|
||||||
|
---@return Presence
|
||||||
|
function devices.Presence.new(config) end
|
||||||
|
---@async
|
||||||
|
---@return boolean
|
||||||
|
function Presence:overall_presence() end
|
||||||
|
|
||||||
|
---@class PresenceConfig
|
||||||
|
---@field topic string
|
||||||
|
---@field callback fun(_: Presence, _: boolean) | fun(_: Presence, _: boolean)[]?
|
||||||
|
---@field client AsyncClient
|
||||||
|
local PresenceConfig
|
||||||
|
|
||||||
|
---@alias Priority
|
||||||
|
---| "min"
|
||||||
|
---| "low"
|
||||||
|
---| "default"
|
||||||
|
---| "high"
|
||||||
|
---| "max"
|
||||||
|
|
||||||
|
---@alias SensorType
|
||||||
|
---| "Door"
|
||||||
|
---| "Drawer"
|
||||||
|
---| "Window"
|
||||||
|
|
||||||
|
---@class WakeOnLAN: DeviceInterface
|
||||||
|
local WakeOnLAN
|
||||||
|
devices.WakeOnLAN = {}
|
||||||
|
---@param config WolConfig
|
||||||
|
---@return WakeOnLAN
|
||||||
|
function devices.WakeOnLAN.new(config) end
|
||||||
|
|
||||||
|
---@class Washer: DeviceInterface
|
||||||
|
local Washer
|
||||||
|
devices.Washer = {}
|
||||||
|
---@param config WasherConfig
|
||||||
|
---@return Washer
|
||||||
|
function devices.Washer.new(config) end
|
||||||
|
|
||||||
|
---@class WasherConfig
|
||||||
|
---@field identifier string
|
||||||
|
---@field topic string
|
||||||
|
---@field threshold number
|
||||||
|
---@field done_callback fun(_: Washer) | fun(_: Washer)[]?
|
||||||
|
---@field client AsyncClient
|
||||||
|
local WasherConfig
|
||||||
|
|
||||||
|
---@class WolConfig
|
||||||
|
---@field name string
|
||||||
|
---@field room string?
|
||||||
|
---@field topic string
|
||||||
|
---@field mac_address string
|
||||||
|
---@field broadcast_ip string?
|
||||||
|
---@field client AsyncClient
|
||||||
|
local WolConfig
|
||||||
|
|
||||||
return devices
|
return devices
|
||||||
|
|||||||
14
definitions/config.lua
Normal file
14
definitions/config.lua
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
-- DO NOT MODIFY, FILE IS AUTOMATICALLY GENERATED
|
||||||
|
---@meta
|
||||||
|
|
||||||
|
---@class FulfillmentConfig
|
||||||
|
---@field openid_url string
|
||||||
|
---@field ip string?
|
||||||
|
---@field port integer?
|
||||||
|
local FulfillmentConfig
|
||||||
|
|
||||||
|
---@class Config
|
||||||
|
---@field fulfillment FulfillmentConfig
|
||||||
|
---@field devices DeviceInterface[]?
|
||||||
|
---@field schedule table<string, fun() | fun()[]>?
|
||||||
|
local Config
|
||||||
@@ -6,6 +6,7 @@ use std::process;
|
|||||||
|
|
||||||
use ::config::{Environment, File};
|
use ::config::{Environment, File};
|
||||||
use automation::config::{Config, Setup};
|
use automation::config::{Config, Setup};
|
||||||
|
use automation::schedule::start_scheduler;
|
||||||
use automation::secret::EnvironmentSecretFile;
|
use automation::secret::EnvironmentSecretFile;
|
||||||
use automation::version::VERSION;
|
use automation::version::VERSION;
|
||||||
use automation::web::{ApiError, User};
|
use automation::web::{ApiError, User};
|
||||||
@@ -136,8 +137,13 @@ async fn app() -> anyhow::Result<()> {
|
|||||||
lua.register_module("automation:secrets", lua.to_value(&setup.secrets)?)?;
|
lua.register_module("automation:secrets", lua.to_value(&setup.secrets)?)?;
|
||||||
|
|
||||||
let entrypoint = Path::new(&setup.entrypoint);
|
let entrypoint = Path::new(&setup.entrypoint);
|
||||||
let config: mlua::Value = lua.load(entrypoint).eval_async().await?;
|
let config: Config = lua.load(entrypoint).eval_async().await?;
|
||||||
let config: Config = lua.from_value(config)?;
|
|
||||||
|
for device in config.devices {
|
||||||
|
device_manager.add(device).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
start_scheduler(config.schedule).await?;
|
||||||
|
|
||||||
// Create google home fulfillment route
|
// Create google home fulfillment route
|
||||||
let fulfillment = Router::new().route("/google_home", post(fulfillment));
|
let fulfillment = Router::new().route("/google_home", post(fulfillment));
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
use std::fs::{self, File};
|
use std::fs::{self, File};
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
|
||||||
|
use automation::config::{Config, FulfillmentConfig};
|
||||||
use automation_lib::Module;
|
use automation_lib::Module;
|
||||||
|
use lua_typed::Typed;
|
||||||
use tracing::{info, warn};
|
use tracing::{info, warn};
|
||||||
|
|
||||||
extern crate automation_devices;
|
extern crate automation_devices;
|
||||||
@@ -24,6 +26,17 @@ fn write_definitions(filename: &str, definitions: &str) -> std::io::Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn config_definitions() -> String {
|
||||||
|
let mut output = "---@meta\n\n".to_string();
|
||||||
|
|
||||||
|
output +=
|
||||||
|
&FulfillmentConfig::generate_full().expect("FulfillmentConfig should have a definition");
|
||||||
|
output += "\n";
|
||||||
|
output += &Config::generate_full().expect("Config should have a definition");
|
||||||
|
|
||||||
|
output
|
||||||
|
}
|
||||||
|
|
||||||
fn main() -> std::io::Result<()> {
|
fn main() -> std::io::Result<()> {
|
||||||
tracing_subscriber::fmt::init();
|
tracing_subscriber::fmt::init();
|
||||||
|
|
||||||
@@ -38,5 +51,7 @@ fn main() -> std::io::Result<()> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
write_definitions("config.lua", &config_definitions())?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::net::{Ipv4Addr, SocketAddr};
|
use std::net::{Ipv4Addr, SocketAddr};
|
||||||
|
|
||||||
|
use automation_lib::action_callback::ActionCallback;
|
||||||
|
use automation_lib::device::Device;
|
||||||
|
use automation_macro::LuaDeviceConfig;
|
||||||
|
use lua_typed::Typed;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
@@ -17,18 +21,26 @@ fn default_entrypoint() -> String {
|
|||||||
"./config.lua".into()
|
"./config.lua".into()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize, Typed)]
|
||||||
pub struct FulfillmentConfig {
|
pub struct FulfillmentConfig {
|
||||||
pub openid_url: String,
|
pub openid_url: String,
|
||||||
#[serde(default = "default_fulfillment_ip")]
|
#[serde(default = "default_fulfillment_ip")]
|
||||||
|
#[typed(default)]
|
||||||
pub ip: Ipv4Addr,
|
pub ip: Ipv4Addr,
|
||||||
#[serde(default = "default_fulfillment_port")]
|
#[serde(default = "default_fulfillment_port")]
|
||||||
|
#[typed(default)]
|
||||||
pub port: u16,
|
pub port: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, LuaDeviceConfig, Typed)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
pub fulfillment: FulfillmentConfig,
|
pub fulfillment: FulfillmentConfig,
|
||||||
|
#[device_config(from_lua, default)]
|
||||||
|
#[typed(default)]
|
||||||
|
pub devices: Vec<Box<dyn Device>>,
|
||||||
|
#[device_config(from_lua, default)]
|
||||||
|
#[typed(default)]
|
||||||
|
pub schedule: HashMap<String, ActionCallback<()>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<FulfillmentConfig> for SocketAddr {
|
impl From<FulfillmentConfig> for SocketAddr {
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
pub mod config;
|
pub mod config;
|
||||||
|
pub mod schedule;
|
||||||
pub mod secret;
|
pub mod secret;
|
||||||
pub mod version;
|
pub mod version;
|
||||||
pub mod web;
|
pub mod web;
|
||||||
|
|||||||
29
src/schedule.rs
Normal file
29
src/schedule.rs
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
use std::collections::HashMap;
|
||||||
|
use std::pin::Pin;
|
||||||
|
|
||||||
|
use automation_lib::action_callback::ActionCallback;
|
||||||
|
use tokio_cron_scheduler::{Job, JobScheduler, JobSchedulerError};
|
||||||
|
|
||||||
|
pub async fn start_scheduler(
|
||||||
|
schedule: HashMap<String, ActionCallback<()>>,
|
||||||
|
) -> Result<(), JobSchedulerError> {
|
||||||
|
let scheduler = JobScheduler::new().await?;
|
||||||
|
|
||||||
|
for (s, f) in schedule {
|
||||||
|
let job = {
|
||||||
|
move |_uuid, _lock| -> Pin<Box<dyn Future<Output = ()> + Send>> {
|
||||||
|
let f = f.clone();
|
||||||
|
|
||||||
|
Box::pin(async move {
|
||||||
|
f.call(()).await;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let job = Job::new_async(s, job)?;
|
||||||
|
|
||||||
|
scheduler.add(job).await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
scheduler.start().await
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user