Compare commits
7 Commits
60bf0f236c
...
5271e5ad81
| Author | SHA1 | Date | |
|---|---|---|---|
|
5271e5ad81
|
|||
|
1d28b43264
|
|||
|
da04fad520
|
|||
|
84e4b30b6a
|
|||
|
95a8a377e8
|
|||
|
23355190ca
|
|||
|
2dbd491b81
|
3
Cargo.lock
generated
3
Cargo.lock
generated
@@ -99,8 +99,6 @@ dependencies = [
|
|||||||
"dotenvy",
|
"dotenvy",
|
||||||
"git-version",
|
"git-version",
|
||||||
"google_home",
|
"google_home",
|
||||||
"hostname",
|
|
||||||
"inventory",
|
|
||||||
"mlua",
|
"mlua",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"rumqttc",
|
"rumqttc",
|
||||||
@@ -152,6 +150,7 @@ dependencies = [
|
|||||||
"dyn-clone",
|
"dyn-clone",
|
||||||
"futures",
|
"futures",
|
||||||
"google_home",
|
"google_home",
|
||||||
|
"hostname",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"inventory",
|
"inventory",
|
||||||
"mlua",
|
"mlua",
|
||||||
|
|||||||
@@ -77,8 +77,6 @@ config = { version = "0.15.15", default-features = false, features = [
|
|||||||
dotenvy = { workspace = true }
|
dotenvy = { workspace = true }
|
||||||
git-version = "0.3.9"
|
git-version = "0.3.9"
|
||||||
google_home = { workspace = true }
|
google_home = { workspace = true }
|
||||||
hostname = { workspace = true }
|
|
||||||
inventory = { workspace = true }
|
|
||||||
mlua = { workspace = true }
|
mlua = { workspace = true }
|
||||||
reqwest = { workspace = true }
|
reqwest = { workspace = true }
|
||||||
rumqttc = { workspace = true }
|
rumqttc = { workspace = true }
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ macro_rules! register_device {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn register_with_lua(lua: &mlua::Lua) -> mlua::Result<mlua::Table> {
|
pub fn create_module(lua: &mlua::Lua) -> mlua::Result<mlua::Table> {
|
||||||
let devices = lua.create_table()?;
|
let devices = lua.create_table()?;
|
||||||
|
|
||||||
register_device!(lua, devices, AirFilter);
|
register_device!(lua, devices, AirFilter);
|
||||||
@@ -60,4 +60,4 @@ pub fn register_with_lua(lua: &mlua::Lua) -> mlua::Result<mlua::Table> {
|
|||||||
Ok(devices)
|
Ok(devices)
|
||||||
}
|
}
|
||||||
|
|
||||||
inventory::submit! {Module::new("devices", register_with_lua)}
|
inventory::submit! {Module::new("devices", create_module)}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ bytes = { workspace = true }
|
|||||||
dyn-clone = { workspace = true }
|
dyn-clone = { workspace = true }
|
||||||
futures = { workspace = true }
|
futures = { workspace = true }
|
||||||
google_home = { workspace = true }
|
google_home = { workspace = true }
|
||||||
|
hostname = { workspace = true }
|
||||||
indexmap = { workspace = true }
|
indexmap = { workspace = true }
|
||||||
inventory = { workspace = true }
|
inventory = { workspace = true }
|
||||||
mlua = { workspace = true }
|
mlua = { workspace = true }
|
||||||
|
|||||||
@@ -1,11 +1 @@
|
|||||||
pub mod serialization;
|
pub mod serialization;
|
||||||
mod timeout;
|
|
||||||
|
|
||||||
pub use timeout::Timeout;
|
|
||||||
|
|
||||||
pub fn register_with_lua(lua: &mlua::Lua) -> mlua::Result<()> {
|
|
||||||
lua.globals()
|
|
||||||
.set("Timeout", lua.create_proxy::<Timeout>()?)?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
#![allow(incomplete_features)]
|
#![allow(incomplete_features)]
|
||||||
#![feature(iterator_try_collect)]
|
#![feature(iterator_try_collect)]
|
||||||
|
|
||||||
|
use tracing::debug;
|
||||||
|
|
||||||
pub mod action_callback;
|
pub mod action_callback;
|
||||||
pub mod config;
|
pub mod config;
|
||||||
pub mod device;
|
pub mod device;
|
||||||
@@ -34,4 +36,15 @@ impl Module {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn load_modules(lua: &mlua::Lua) -> mlua::Result<()> {
|
||||||
|
debug!("Loading modules...");
|
||||||
|
for module in inventory::iter::<Module> {
|
||||||
|
debug!(name = module.get_name(), "Registering");
|
||||||
|
let table = module.register(lua)?;
|
||||||
|
lua.register_module(module.get_name(), table)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
inventory::collect!(Module);
|
inventory::collect!(Module);
|
||||||
|
|||||||
@@ -1 +1,3 @@
|
|||||||
pub mod traits;
|
pub mod traits;
|
||||||
|
|
||||||
|
mod utils;
|
||||||
|
|||||||
31
automation_lib/src/lua/utils/mod.rs
Normal file
31
automation_lib/src/lua/utils/mod.rs
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
mod timeout;
|
||||||
|
|
||||||
|
use std::time::{SystemTime, UNIX_EPOCH};
|
||||||
|
|
||||||
|
pub use timeout::Timeout;
|
||||||
|
|
||||||
|
use crate::Module;
|
||||||
|
|
||||||
|
fn create_module(lua: &mlua::Lua) -> mlua::Result<mlua::Table> {
|
||||||
|
let utils = lua.create_table()?;
|
||||||
|
|
||||||
|
utils.set("Timeout", lua.create_proxy::<Timeout>()?)?;
|
||||||
|
|
||||||
|
let get_hostname = lua.create_function(|_lua, ()| {
|
||||||
|
hostname::get()
|
||||||
|
.map(|name| name.to_str().unwrap_or("unknown").to_owned())
|
||||||
|
.map_err(mlua::ExternalError::into_lua_err)
|
||||||
|
})?;
|
||||||
|
utils.set("get_hostname", get_hostname)?;
|
||||||
|
let get_epoch = lua.create_function(|_lua, ()| {
|
||||||
|
Ok(SystemTime::now()
|
||||||
|
.duration_since(UNIX_EPOCH)
|
||||||
|
.expect("Time is after UNIX EPOCH")
|
||||||
|
.as_millis())
|
||||||
|
})?;
|
||||||
|
utils.set("get_epoch", get_epoch)?;
|
||||||
|
|
||||||
|
Ok(utils)
|
||||||
|
}
|
||||||
|
|
||||||
|
inventory::submit! {Module::new("utils", create_module)}
|
||||||
10
config.lua
10
config.lua
@@ -259,7 +259,7 @@ device_manager:add(devices.IkeaRemote.new({
|
|||||||
}))
|
}))
|
||||||
|
|
||||||
local function kettle_timeout()
|
local function kettle_timeout()
|
||||||
local timeout = Timeout.new()
|
local timeout = utils.Timeout.new()
|
||||||
|
|
||||||
return function(self, state)
|
return function(self, state)
|
||||||
if state.state and state.power < 100 then
|
if state.state and state.power < 100 then
|
||||||
@@ -308,7 +308,7 @@ device_manager:add(devices.IkeaRemote.new({
|
|||||||
}))
|
}))
|
||||||
|
|
||||||
local function off_timeout(duration)
|
local function off_timeout(duration)
|
||||||
local timeout = Timeout.new()
|
local timeout = utils.Timeout.new()
|
||||||
|
|
||||||
return function(self, state)
|
return function(self, state)
|
||||||
if state.state then
|
if state.state then
|
||||||
@@ -371,7 +371,7 @@ local workbench_light = devices.LightColorTemperature.new({
|
|||||||
turn_off_when_away(workbench_light)
|
turn_off_when_away(workbench_light)
|
||||||
device_manager:add(workbench_light)
|
device_manager:add(workbench_light)
|
||||||
|
|
||||||
local delay_color_temp = Timeout.new()
|
local delay_color_temp = utils.Timeout.new()
|
||||||
device_manager:add(devices.IkeaRemote.new({
|
device_manager:add(devices.IkeaRemote.new({
|
||||||
name = "Remote",
|
name = "Remote",
|
||||||
room = "Workbench",
|
room = "Workbench",
|
||||||
@@ -424,7 +424,7 @@ device_manager:add(devices.HueSwitch.new({
|
|||||||
}))
|
}))
|
||||||
|
|
||||||
local hallway_light_automation = {
|
local hallway_light_automation = {
|
||||||
timeout = Timeout.new(),
|
timeout = utils.Timeout.new(),
|
||||||
forced = false,
|
forced = false,
|
||||||
switch_callback = function(self)
|
switch_callback = function(self)
|
||||||
return function(_, on)
|
return function(_, on)
|
||||||
@@ -512,7 +512,7 @@ hallway_light_automation.group = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
local function presence(duration)
|
local function presence(duration)
|
||||||
local timeout = Timeout.new()
|
local timeout = utils.Timeout.new()
|
||||||
|
|
||||||
return function(_, open)
|
return function(_, open)
|
||||||
if open then
|
if open then
|
||||||
|
|||||||
32
src/main.rs
32
src/main.rs
@@ -7,13 +7,11 @@ mod web;
|
|||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::process;
|
use std::process;
|
||||||
use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
|
||||||
|
|
||||||
use ::config::{Environment, File};
|
use ::config::{Environment, File};
|
||||||
use automation_lib::config::{FulfillmentConfig, MqttConfig};
|
use automation_lib::config::{FulfillmentConfig, MqttConfig};
|
||||||
use automation_lib::device_manager::DeviceManager;
|
use automation_lib::device_manager::DeviceManager;
|
||||||
use automation_lib::mqtt::{self, WrappedAsyncClient};
|
use automation_lib::mqtt::{self, WrappedAsyncClient};
|
||||||
use automation_lib::{Module, helpers};
|
|
||||||
use axum::extract::{FromRef, State};
|
use axum::extract::{FromRef, State};
|
||||||
use axum::http::StatusCode;
|
use axum::http::StatusCode;
|
||||||
use axum::routing::post;
|
use axum::routing::post;
|
||||||
@@ -141,12 +139,7 @@ async fn app() -> anyhow::Result<()> {
|
|||||||
})?;
|
})?;
|
||||||
lua.globals().set("print", print)?;
|
lua.globals().set("print", print)?;
|
||||||
|
|
||||||
debug!("Loading modules...");
|
automation_lib::load_modules(&lua)?;
|
||||||
for module in inventory::iter::<Module> {
|
|
||||||
debug!(name = module.get_name(), "Registering");
|
|
||||||
let table = module.register(&lua)?;
|
|
||||||
lua.register_module(module.get_name(), table)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
let mqtt = lua.create_table()?;
|
let mqtt = lua.create_table()?;
|
||||||
let event_channel = device_manager.event_channel();
|
let event_channel = device_manager.event_channel();
|
||||||
@@ -168,29 +161,6 @@ async fn app() -> anyhow::Result<()> {
|
|||||||
lua.register_module("variables", lua.to_value(&config.variables)?)?;
|
lua.register_module("variables", lua.to_value(&config.variables)?)?;
|
||||||
lua.register_module("secrets", lua.to_value(&config.secrets)?)?;
|
lua.register_module("secrets", lua.to_value(&config.secrets)?)?;
|
||||||
|
|
||||||
let utils = lua.create_table()?;
|
|
||||||
let get_hostname = lua.create_function(|_lua, ()| {
|
|
||||||
hostname::get()
|
|
||||||
.map(|name| name.to_str().unwrap_or("unknown").to_owned())
|
|
||||||
.map_err(mlua::ExternalError::into_lua_err)
|
|
||||||
})?;
|
|
||||||
utils.set("get_hostname", get_hostname)?;
|
|
||||||
let get_epoch = lua.create_function(|_lua, ()| {
|
|
||||||
Ok(SystemTime::now()
|
|
||||||
.duration_since(UNIX_EPOCH)
|
|
||||||
.expect("Time is after UNIX EPOCH")
|
|
||||||
.as_millis())
|
|
||||||
})?;
|
|
||||||
utils.set("get_epoch", get_epoch)?;
|
|
||||||
let sleep = lua.create_async_function(async |_lua, duration: u64| {
|
|
||||||
tokio::time::sleep(Duration::from_millis(duration)).await;
|
|
||||||
Ok(())
|
|
||||||
})?;
|
|
||||||
utils.set("sleep", sleep)?;
|
|
||||||
lua.register_module("utils", utils)?;
|
|
||||||
|
|
||||||
helpers::register_with_lua(&lua)?;
|
|
||||||
|
|
||||||
let entrypoint = Path::new(&config.entrypoint);
|
let entrypoint = Path::new(&config.entrypoint);
|
||||||
let fulfillment_config: mlua::Value = lua.load(entrypoint).eval_async().await?;
|
let fulfillment_config: mlua::Value = lua.load(entrypoint).eval_async().await?;
|
||||||
let fulfillment_config: FulfillmentConfig = lua.from_value(fulfillment_config)?;
|
let fulfillment_config: FulfillmentConfig = lua.from_value(fulfillment_config)?;
|
||||||
|
|||||||
Reference in New Issue
Block a user