Compare commits

..

27 Commits

Author SHA1 Message Date
815ea5bb78
Run the main binary by default
All checks were successful
Build and deploy automation_rs / Build automation_rs (push) Successful in 6m27s
Build and deploy automation_rs / Build Docker image (push) Successful in 35s
Build and deploy automation_rs / Deploy Docker container (push) Has been skipped
2024-05-07 00:11:57 +02:00
105a58cbb8
Make sure the generated lua definitions are up to date 2024-05-07 00:11:57 +02:00
cebdac2fe0
Further work on automatically generating lua type definitions 2024-05-07 00:11:57 +02:00
5b96cca5c9
Started work on generating definitions 2024-05-07 00:11:57 +02:00
794b8eef19
Quickly hacked in is_on function on devices in lua
All checks were successful
Build and deploy automation_rs / Build automation_rs (push) Successful in 5m48s
Build and deploy automation_rs / Build Docker image (push) Successful in 47s
Build and deploy automation_rs / Deploy Docker container (push) Successful in 30s
In order to get feature parity with pre-lua the is_on function is
manually implemented on all wrapped devices in lua
This implementation will need to be improved in the future.
2024-05-07 00:05:38 +02:00
c7fc25d239
Fix: Scheduled function can not run async functions
Since Lua is not Send, this turned out to be a bit more complicated.
In order to make it work the async function needs to be pinned to a
single thread.
It works now, but the implementation looks a bit messy. Not sure it can
be improved through.
2024-05-07 00:05:38 +02:00
bf3d757710
Added lua function to get the current hostname
This makes it possible to set options depending on what machine we are
running
2024-05-07 00:05:38 +02:00
bb15558ab2
Fixed typo in README.md and added mosquitto as word 2024-05-07 00:05:37 +02:00
02d6630ac6
Started work on reimplementing schedules 2024-05-07 00:05:37 +02:00
456d7a359b
Fixed spelling mistakes 2024-05-07 00:05:37 +02:00
2ff59872b2
Moved last config items to lua + small cleanup 2024-05-07 00:05:37 +02:00
2a3b14267b
Fixed visibility of device configs 2024-05-07 00:05:37 +02:00
44a40d4dfa
LuaDevice macro now uses LuaDeviceCreate trait to create devices from configs 2024-05-07 00:05:37 +02:00
9f636a2572
mqtt client is now created in lua 2024-05-07 00:05:37 +02:00
fcd0b370d6
DeviceManager no longer handles subscribing and filtering topics, each device has to do this themselves now 2024-05-07 00:05:37 +02:00
3e4ea8952a
Improved how devices are created, ntfy and presence are now treated like any other device 2024-05-07 00:05:36 +02:00
5069d1b0e7
Moved schedule config from yml to lua 2024-05-07 00:05:36 +02:00
3225dbdda9
Set lua warning function 2024-05-07 00:05:36 +02:00
20feaa6308
Slight macro cleanup 2024-05-07 00:05:36 +02:00
55237a2ba2
Improved the internals of the LuaDeviceConfig macro and improve the
usability of the macro
2024-05-07 00:05:36 +02:00
024b9c9dbc
Use helper types to process config input into the right type 2024-05-07 00:05:36 +02:00
51f689b199
Added helper type to convert from ip addr to socketaddr with the correct port 2024-05-07 00:05:36 +02:00
a2ee2ad71d
Added rename option to macro 2024-05-07 00:05:36 +02:00
f4a1b507e5
Everything needed to construct a new device is passed in through lua 2024-05-07 00:05:36 +02:00
bfc73c7bd3
Device config is now done through lua 2024-05-07 00:05:36 +02:00
f50bc4bd0c
Replaced impl_cast with a new and improved trait
With this trait the impl_cast macros are no longer needed, simplifying
everything.
This commit also improved how the actual casting itself is handled.
2024-05-07 00:05:32 +02:00
3689a52afd
Replaced impl_cast with a new and improved trait
All checks were successful
Build and deploy automation_rs / Build automation_rs (push) Successful in 4m0s
Build and deploy automation_rs / Build Docker image (push) Successful in 52s
Build and deploy automation_rs / Deploy Docker container (push) Successful in 28s
With this trait the impl_cast macros are no longer needed, simplifying
everything.
This commit also improved how the actual casting itself is handled.
2024-05-05 00:33:21 +02:00
4 changed files with 97 additions and 33 deletions

57
Cargo.lock generated
View File

@ -17,6 +17,18 @@ 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 = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "ahash"
version = "0.8.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
dependencies = [
"cfg-if",
"once_cell",
"version_check",
"zerocopy",
]
[[package]] [[package]]
name = "aho-corasick" name = "aho-corasick"
version = "1.0.2" version = "1.0.2"
@ -26,6 +38,12 @@ dependencies = [
"memchr", "memchr",
] ]
[[package]]
name = "allocator-api2"
version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f"
[[package]] [[package]]
name = "android-tzdata" name = "android-tzdata"
version = "0.1.1" version = "0.1.1"
@ -103,8 +121,10 @@ dependencies = [
"thiserror", "thiserror",
"tokio", "tokio",
"tokio-cron-scheduler", "tokio-cron-scheduler",
"tokio-util",
"tracing", "tracing",
"tracing-subscriber", "tracing-subscriber",
"uuid",
"wakey", "wakey",
] ]
@ -659,6 +679,10 @@ name = "hashbrown"
version = "0.14.0" version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a"
dependencies = [
"ahash",
"allocator-api2",
]
[[package]] [[package]]
name = "hdrhistogram" name = "hdrhistogram"
@ -1943,16 +1967,19 @@ dependencies = [
[[package]] [[package]]
name = "tokio-util" name = "tokio-util"
version = "0.7.8" version = "0.7.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1"
dependencies = [ dependencies = [
"bytes", "bytes",
"futures-core", "futures-core",
"futures-io",
"futures-sink", "futures-sink",
"futures-util",
"hashbrown 0.14.0",
"pin-project-lite", "pin-project-lite",
"slab",
"tokio", "tokio",
"tracing",
] ]
[[package]] [[package]]
@ -2130,9 +2157,9 @@ dependencies = [
[[package]] [[package]]
name = "uuid" name = "uuid"
version = "1.5.0" version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88ad59a7560b41a70d191093a945f0b87bc1deeda46fb237479708a1d6b6cdfc" checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0"
dependencies = [ dependencies = [
"getrandom", "getrandom",
] ]
@ -2484,3 +2511,23 @@ name = "winsafe"
version = "0.0.19" version = "0.0.19"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904" checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904"
[[package]]
name = "zerocopy"
version = "0.7.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.7.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.60",
]

View File

@ -43,16 +43,11 @@ enum_dispatch = "0.3.12"
indexmap = { version = "2.0.0", features = ["serde"] } indexmap = { version = "2.0.0", features = ["serde"] }
serde_yaml = "0.9.27" serde_yaml = "0.9.27"
tokio-cron-scheduler = "0.9.4" tokio-cron-scheduler = "0.9.4"
mlua = { version = "0.9.7", features = [ mlua = { version = "0.9.7", features = ["lua54", "vendored", "macros", "serialize", "async", "send"] }
"lua54",
"vendored",
"macros",
"serialize",
"async",
"send",
] }
once_cell = "1.19.0" once_cell = "1.19.0"
hostname = "0.4.0" hostname = "0.4.0"
tokio-util = { version = "0.7.11", features = ["full"] }
uuid = "1.8.0"
[patch.crates-io] [patch.crates-io]
wakey = { git = "https://git.huizinga.dev/Dreaded_X/wakey" } wakey = { git = "https://git.huizinga.dev/Dreaded_X/wakey" }

View File

@ -137,8 +137,7 @@ automation.device_manager:add(IkeaOutlet.new({
topic = mqtt_z2m("workbench/outlet"), topic = mqtt_z2m("workbench/outlet"),
client = mqtt_client, client = mqtt_client,
})) }))
local hallway_lights = HueGroup.new({
local hallway_lights = automation.device_manager:add(HueGroup.new({
identifier = "hallway_lights", identifier = "hallway_lights",
ip = hue_ip, ip = hue_ip,
login = hue_token, login = hue_token,
@ -149,7 +148,8 @@ local hallway_lights = automation.device_manager:add(HueGroup.new({
{ topic = mqtt_z2m("hallway/remote") }, { topic = mqtt_z2m("hallway/remote") },
}, },
client = mqtt_client, client = mqtt_client,
})) })
automation.device_manager:add(hallway_lights)
automation.device_manager:add(ContactSensor.new({ automation.device_manager:add(ContactSensor.new({
identifier = "hallway_frontdoor", identifier = "hallway_frontdoor",
@ -173,6 +173,9 @@ local bedroom_air_filter = AirFilter.new({
}) })
automation.device_manager:add(bedroom_air_filter) automation.device_manager:add(bedroom_air_filter)
automation.device_manager:schedule("0/1 * * * * *", function() automation.device_manager:schedule("0 0 19 * * *", function()
print("Device: " .. bedroom_air_filter:get_id()) bedroom_air_filter:set_on(true)
end)
automation.device_manager:schedule("0 0 20 * * *", function()
bedroom_air_filter:set_on(false)
end) end)

View File

@ -1,11 +1,15 @@
use std::collections::HashMap; use std::collections::HashMap;
use std::ops::{Deref, DerefMut}; use std::ops::{Deref, DerefMut};
use std::pin::Pin;
use std::sync::Arc; use std::sync::Arc;
use futures::future::join_all; use futures::future::join_all;
use futures::Future;
use google_home::traits::OnOff;
use mlua::FromLua; use mlua::FromLua;
use tokio::sync::{RwLock, RwLockReadGuard}; use tokio::sync::{RwLock, RwLockReadGuard};
use tokio_cron_scheduler::{Job, JobScheduler}; use tokio_cron_scheduler::{Job, JobScheduler};
use tokio_util::task::LocalPoolHandle;
use tracing::{debug, instrument, trace}; use tracing::{debug, instrument, trace};
use crate::devices::Device; use crate::devices::Device;
@ -39,6 +43,17 @@ impl mlua::UserData for WrappedDevice {
methods.add_async_method("get_id", |_lua, this, _: ()| async { methods.add_async_method("get_id", |_lua, this, _: ()| async {
Ok(crate::devices::Device::get_id(this.0.read().await.as_ref())) Ok(crate::devices::Device::get_id(this.0.read().await.as_ref()))
}); });
methods.add_async_method("set_on", |_lua, this, on: bool| async move {
let mut device = this.0.write().await;
let device = device.as_mut();
if let Some(device) = device.cast_mut() as Option<&mut dyn OnOff> {
device.set_on(on).await.unwrap()
};
Ok(())
});
} }
} }
@ -180,6 +195,23 @@ impl DeviceManager {
} }
} }
fn run_schedule(
uuid: uuid::Uuid,
_: tokio_cron_scheduler::JobScheduler,
) -> Pin<Box<dyn Future<Output = ()> + Send>> {
Box::pin(async move {
// Lua is not Send, so we need to make sure that the task stays on the same thread
let pool = LocalPoolHandle::new(1);
pool.spawn_pinned(move || async move {
let lua = LUA.lock().await;
let f: mlua::Function = lua.named_registry_value(uuid.to_string().as_str()).unwrap();
f.call_async::<_, ()>(()).await.unwrap();
})
.await
.unwrap();
})
}
impl mlua::UserData for DeviceManager { impl mlua::UserData for DeviceManager {
fn add_methods<'lua, M: mlua::UserDataMethods<'lua, Self>>(methods: &mut M) { fn add_methods<'lua, M: mlua::UserDataMethods<'lua, Self>>(methods: &mut M) {
methods.add_async_method("add", |_lua, this, device: WrappedDevice| async move { methods.add_async_method("add", |_lua, this, device: WrappedDevice| async move {
@ -192,22 +224,9 @@ impl mlua::UserData for DeviceManager {
"schedule", "schedule",
|lua, this, (schedule, f): (String, mlua::Function)| async move { |lua, this, (schedule, f): (String, mlua::Function)| async move {
debug!("schedule = {schedule}"); debug!("schedule = {schedule}");
let uuid = this let job = Job::new_async(schedule.as_str(), run_schedule).unwrap();
.scheduler
.add(
Job::new_async(schedule.as_str(), |uuid, _lock| {
Box::pin(async move {
let lua = LUA.lock().await;
let f: mlua::Function =
lua.named_registry_value(uuid.to_string().as_str()).unwrap();
f.call::<_, ()>(()).unwrap(); let uuid = this.scheduler.add(job).await.unwrap();
})
})
.unwrap(),
)
.await
.unwrap();
// Store the function in the registry // Store the function in the registry
lua.set_named_registry_value(uuid.to_string().as_str(), f) lua.set_named_registry_value(uuid.to_string().as_str(), f)