From d3d9a19f525f3fae3f272de8896599840f4fd9b5 Mon Sep 17 00:00:00 2001 From: Dreaded_X Date: Wed, 15 Oct 2025 03:39:10 +0200 Subject: [PATCH] feat(config)!: Move mqtt module to actual separate module The automation:mqtt module now gets loaded in a similar way as the automation:devices and automation:utils modules. This leads to a breaking change where instantiating a new mqtt client the device manager needs to be explicitly passed in. --- automation_lib/src/device_manager.rs | 3 ++- automation_lib/src/mqtt.rs | 29 ++++++++++++++++++++++++++-- config.lua | 2 +- src/main.rs | 19 +----------------- 4 files changed, 31 insertions(+), 22 deletions(-) diff --git a/automation_lib/src/device_manager.rs b/automation_lib/src/device_manager.rs index 29b7b54..fe755f2 100644 --- a/automation_lib/src/device_manager.rs +++ b/automation_lib/src/device_manager.rs @@ -5,6 +5,7 @@ use std::sync::Arc; use futures::Future; use futures::future::join_all; use lua_typed::Typed; +use mlua::FromLua; use tokio::sync::{RwLock, RwLockReadGuard}; use tokio_cron_scheduler::{Job, JobScheduler}; use tracing::{debug, instrument, trace}; @@ -14,7 +15,7 @@ use crate::event::{Event, EventChannel, OnMqtt}; pub type DeviceMap = HashMap>; -#[derive(Clone)] +#[derive(Clone, FromLua)] pub struct DeviceManager { devices: Arc>, event_channel: EventChannel, diff --git a/automation_lib/src/mqtt.rs b/automation_lib/src/mqtt.rs index b9fbbe9..a464a45 100644 --- a/automation_lib/src/mqtt.rs +++ b/automation_lib/src/mqtt.rs @@ -1,11 +1,13 @@ use std::ops::{Deref, DerefMut}; use lua_typed::Typed; -use mlua::FromLua; +use mlua::{FromLua, LuaSerdeExt}; use rumqttc::{AsyncClient, Event, EventLoop, Incoming}; use tracing::{debug, warn}; +use crate::Module; use crate::config::MqttConfig; +use crate::device_manager::DeviceManager; use crate::event::{self, EventChannel}; #[derive(Debug, Clone, FromLua)] @@ -39,9 +41,10 @@ impl Typed for WrappedAsyncClient { let type_name = Self::type_name(); output += &format!("mqtt.{type_name} = {{}}\n"); + output += &format!("---@param device_manager {}\n", DeviceManager::type_name()); output += &format!("---@param config {}\n", MqttConfig::type_name()); output += &format!("---@return {type_name}\n"); - output += "function mqtt.new(config) end\n"; + output += "function mqtt.new(device_manager, config) end\n"; Some(output) } @@ -108,3 +111,25 @@ pub fn start(mut eventloop: EventLoop, event_channel: &EventChannel) { } }); } + +fn create_module(lua: &mlua::Lua) -> mlua::Result { + let mqtt = lua.create_table()?; + let mqtt_new = lua.create_function( + move |lua, (device_manager, config): (DeviceManager, mlua::Value)| { + let event_channel = device_manager.event_channel(); + let config: MqttConfig = lua.from_value(config)?; + + // Create a mqtt client + // TODO: When starting up, the devices are not yet created, this could lead to a device being out of sync + let (client, eventloop) = AsyncClient::new(config.into(), 100); + start(eventloop, &event_channel); + + Ok(WrappedAsyncClient(client)) + }, + )?; + mqtt.set("new", mqtt_new)?; + + Ok(mqtt) +} + +inventory::submit! {Module::new("automation:mqtt", create_module)} diff --git a/config.lua b/config.lua index 9f7d396..785403e 100644 --- a/config.lua +++ b/config.lua @@ -21,7 +21,7 @@ local fulfillment = { openid_url = "https://login.huizinga.dev/api/oidc", } -local mqtt_client = require("automation:mqtt").new({ +local mqtt_client = require("automation:mqtt").new(device_manager, { host = ((host == "zeus" or host == "hephaestus") and "olympus.lan.huizinga.dev") or "mosquitto", port = 8883, client_name = "automation-" .. host, diff --git a/src/main.rs b/src/main.rs index 2432065..34424e2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,9 +9,8 @@ use std::path::Path; use std::process; use ::config::{Environment, File}; -use automation_lib::config::{FulfillmentConfig, MqttConfig}; +use automation_lib::config::FulfillmentConfig; use automation_lib::device_manager::DeviceManager; -use automation_lib::mqtt::{self, WrappedAsyncClient}; use axum::extract::{FromRef, State}; use axum::http::StatusCode; use axum::routing::post; @@ -19,7 +18,6 @@ use axum::{Json, Router}; use config::Config; use google_home::{GoogleHome, Request, Response}; use mlua::LuaSerdeExt; -use rumqttc::AsyncClient; use tokio::net::TcpListener; use tracing::{debug, error, info, warn}; use web::{ApiError, User}; @@ -138,21 +136,6 @@ async fn app() -> anyhow::Result<()> { automation_lib::load_modules(&lua)?; - let mqtt = lua.create_table()?; - let event_channel = device_manager.event_channel(); - let mqtt_new = lua.create_function(move |lua, config: mlua::Value| { - let config: MqttConfig = lua.from_value(config)?; - - // Create a mqtt client - // TODO: When starting up, the devices are not yet created, this could lead to a device being out of sync - let (client, eventloop) = AsyncClient::new(config.into(), 100); - mqtt::start(eventloop, &event_channel); - - Ok(WrappedAsyncClient(client)) - })?; - mqtt.set("new", mqtt_new)?; - lua.register_module("automation:mqtt", mqtt)?; - lua.register_module("automation:device_manager", device_manager.clone())?; lua.register_module("automation:variables", lua.to_value(&config.variables)?)?;