Compare commits
3 Commits
295491c5fc
...
f7ba602762
| Author | SHA1 | Date | |
|---|---|---|---|
|
f7ba602762
|
|||
|
929007d8c2
|
|||
|
b191d67ae2
|
7
Cargo.lock
generated
7
Cargo.lock
generated
@@ -96,7 +96,6 @@ dependencies = [
|
|||||||
"automation_lib",
|
"automation_lib",
|
||||||
"axum",
|
"axum",
|
||||||
"config",
|
"config",
|
||||||
"dotenvy",
|
|
||||||
"git-version",
|
"git-version",
|
||||||
"google_home",
|
"google_home",
|
||||||
"mlua",
|
"mlua",
|
||||||
@@ -433,12 +432,6 @@ dependencies = [
|
|||||||
"syn 2.0.106",
|
"syn 2.0.106",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "dotenvy"
|
|
||||||
version = "0.15.7"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dyn-clone"
|
name = "dyn-clone"
|
||||||
version = "1.0.20"
|
version = "1.0.20"
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ automation_lib = { path = "./automation_lib" }
|
|||||||
automation_macro = { path = "./automation_macro" }
|
automation_macro = { path = "./automation_macro" }
|
||||||
axum = "0.8.4"
|
axum = "0.8.4"
|
||||||
bytes = "1.10.1"
|
bytes = "1.10.1"
|
||||||
dotenvy = "0.15.7"
|
|
||||||
dyn-clone = "1.0.20"
|
dyn-clone = "1.0.20"
|
||||||
eui48 = { version = "1.1.0", features = [
|
eui48 = { version = "1.1.0", features = [
|
||||||
"disp_hexstring",
|
"disp_hexstring",
|
||||||
@@ -75,7 +74,6 @@ config = { version = "0.15.15", default-features = false, features = [
|
|||||||
"async",
|
"async",
|
||||||
"toml",
|
"toml",
|
||||||
] }
|
] }
|
||||||
dotenvy = { workspace = true }
|
|
||||||
git-version = "0.3.9"
|
git-version = "0.3.9"
|
||||||
google_home = { workspace = true }
|
google_home = { workspace = true }
|
||||||
mlua = { workspace = true }
|
mlua = { workspace = true }
|
||||||
|
|||||||
@@ -3,18 +3,21 @@ use std::net::SocketAddr;
|
|||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use automation_lib::device::{Device, LuaDeviceCreate};
|
use automation_lib::device::{Device, LuaDeviceCreate};
|
||||||
|
use automation_lib::lua::traits::PartialUserData;
|
||||||
use automation_macro::{Device, LuaDeviceConfig};
|
use automation_macro::{Device, LuaDeviceConfig};
|
||||||
use lua_typed::Typed;
|
use lua_typed::Typed;
|
||||||
use mlua::LuaSerdeExt;
|
use mlua::LuaSerdeExt;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use tracing::{error, trace, warn};
|
use tracing::{error, trace, warn};
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize, Typed)]
|
||||||
#[serde(rename_all = "snake_case")]
|
#[serde(rename_all = "snake_case")]
|
||||||
|
#[typed(rename_all = "snake_case")]
|
||||||
pub enum Flag {
|
pub enum Flag {
|
||||||
Presence,
|
Presence,
|
||||||
Darkness,
|
Darkness,
|
||||||
}
|
}
|
||||||
|
crate::register_type!(Flag);
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize, Typed)]
|
#[derive(Debug, Clone, Deserialize, Typed)]
|
||||||
pub struct FlagIDs {
|
pub struct FlagIDs {
|
||||||
@@ -36,12 +39,36 @@ pub struct Config {
|
|||||||
crate::register_type!(Config);
|
crate::register_type!(Config);
|
||||||
|
|
||||||
#[derive(Debug, Clone, Device)]
|
#[derive(Debug, Clone, Device)]
|
||||||
#[device(add_methods = Self::add_methods)]
|
#[device(extra_user_data = SetFlag)]
|
||||||
pub struct HueBridge {
|
pub struct HueBridge {
|
||||||
config: Config,
|
config: Config,
|
||||||
}
|
}
|
||||||
crate::register_device!(HueBridge);
|
crate::register_device!(HueBridge);
|
||||||
|
|
||||||
|
struct SetFlag;
|
||||||
|
impl PartialUserData<HueBridge> for SetFlag {
|
||||||
|
fn add_methods<M: mlua::UserDataMethods<HueBridge>>(methods: &mut M) {
|
||||||
|
methods.add_async_method(
|
||||||
|
"set_flag",
|
||||||
|
async |lua, this, (flag, value): (mlua::Value, bool)| {
|
||||||
|
let flag: Flag = lua.from_value(flag)?;
|
||||||
|
|
||||||
|
this.set_flag(flag, value).await;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn definitions() -> Option<String> {
|
||||||
|
Some(format!(
|
||||||
|
"---@async\n---@param flag {}\n---@param value boolean\nfunction {}:set_flag(flag, value) end\n",
|
||||||
|
<Flag as Typed>::type_name(),
|
||||||
|
<HueBridge as Typed>::type_name(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize)]
|
||||||
struct FlagMessage {
|
struct FlagMessage {
|
||||||
flag: bool,
|
flag: bool,
|
||||||
@@ -89,19 +116,6 @@ impl HueBridge {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_methods<M: mlua::UserDataMethods<Self>>(methods: &mut M) {
|
|
||||||
methods.add_async_method(
|
|
||||||
"set_flag",
|
|
||||||
async |lua, this, (flag, value): (mlua::Value, bool)| {
|
|
||||||
let flag: Flag = lua.from_value(flag)?;
|
|
||||||
|
|
||||||
this.set_flag(flag, value).await;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Device for HueBridge {
|
impl Device for HueBridge {
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ use tracing::debug;
|
|||||||
macro_rules! register_device {
|
macro_rules! register_device {
|
||||||
($device:ty) => {
|
($device:ty) => {
|
||||||
::inventory::submit!(crate::RegisteredDevice::new(
|
::inventory::submit!(crate::RegisteredDevice::new(
|
||||||
stringify!($device),
|
<$device as ::lua_typed::Typed>::type_name,
|
||||||
::mlua::Lua::create_proxy::<$device>
|
::mlua::Lua::create_proxy::<$device>
|
||||||
));
|
));
|
||||||
|
|
||||||
@@ -30,20 +30,24 @@ macro_rules! register_device {
|
|||||||
|
|
||||||
pub(crate) use register_device;
|
pub(crate) use register_device;
|
||||||
|
|
||||||
|
type DeviceNameFn = fn() -> String;
|
||||||
type RegisterDeviceFn = fn(lua: &mlua::Lua) -> mlua::Result<mlua::AnyUserData>;
|
type RegisterDeviceFn = fn(lua: &mlua::Lua) -> mlua::Result<mlua::AnyUserData>;
|
||||||
|
|
||||||
pub struct RegisteredDevice {
|
pub struct RegisteredDevice {
|
||||||
name: &'static str,
|
name_fn: DeviceNameFn,
|
||||||
register_fn: RegisterDeviceFn,
|
register_fn: RegisterDeviceFn,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RegisteredDevice {
|
impl RegisteredDevice {
|
||||||
pub const fn new(name: &'static str, register_fn: RegisterDeviceFn) -> Self {
|
pub const fn new(name_fn: DeviceNameFn, register_fn: RegisterDeviceFn) -> Self {
|
||||||
Self { name, register_fn }
|
Self {
|
||||||
|
name_fn,
|
||||||
|
register_fn,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const fn get_name(&self) -> &'static str {
|
pub fn get_name(&self) -> String {
|
||||||
self.name
|
(self.name_fn)()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn register(&self, lua: &mlua::Lua) -> mlua::Result<mlua::AnyUserData> {
|
pub fn register(&self, lua: &mlua::Lua) -> mlua::Result<mlua::AnyUserData> {
|
||||||
@@ -58,9 +62,10 @@ pub fn create_module(lua: &mlua::Lua) -> mlua::Result<mlua::Table> {
|
|||||||
|
|
||||||
debug!("Loading devices...");
|
debug!("Loading devices...");
|
||||||
for device in inventory::iter::<RegisteredDevice> {
|
for device in inventory::iter::<RegisteredDevice> {
|
||||||
debug!(name = device.get_name(), "Registering device");
|
let name = device.get_name();
|
||||||
|
debug!(name, "Registering device");
|
||||||
let proxy = device.register(lua)?;
|
let proxy = device.register(lua)?;
|
||||||
devices.set(device.get_name(), proxy)?;
|
devices.set(name, proxy)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(devices)
|
Ok(devices)
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ use std::convert::Infallible;
|
|||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use automation_lib::device::{Device, LuaDeviceCreate};
|
use automation_lib::device::{Device, LuaDeviceCreate};
|
||||||
|
use automation_lib::lua::traits::PartialUserData;
|
||||||
use automation_macro::{Device, LuaDeviceConfig};
|
use automation_macro::{Device, LuaDeviceConfig};
|
||||||
use lua_typed::Typed;
|
use lua_typed::Typed;
|
||||||
use mlua::LuaSerdeExt;
|
use mlua::LuaSerdeExt;
|
||||||
@@ -90,14 +91,15 @@ pub struct Config {
|
|||||||
crate::register_type!(Config);
|
crate::register_type!(Config);
|
||||||
|
|
||||||
#[derive(Debug, Clone, Device)]
|
#[derive(Debug, Clone, Device)]
|
||||||
#[device(add_methods = Self::add_methods)]
|
#[device(extra_user_data = SendNotification)]
|
||||||
pub struct Ntfy {
|
pub struct Ntfy {
|
||||||
config: Config,
|
config: Config,
|
||||||
}
|
}
|
||||||
crate::register_device!(Ntfy);
|
crate::register_device!(Ntfy);
|
||||||
|
|
||||||
impl Ntfy {
|
struct SendNotification;
|
||||||
fn add_methods<M: mlua::UserDataMethods<Self>>(methods: &mut M) {
|
impl PartialUserData<Ntfy> for SendNotification {
|
||||||
|
fn add_methods<M: mlua::UserDataMethods<Ntfy>>(methods: &mut M) {
|
||||||
methods.add_async_method(
|
methods.add_async_method(
|
||||||
"send_notification",
|
"send_notification",
|
||||||
async |lua, this, notification: mlua::Value| {
|
async |lua, this, notification: mlua::Value| {
|
||||||
@@ -109,6 +111,14 @@ impl Ntfy {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn definitions() -> Option<String> {
|
||||||
|
Some(format!(
|
||||||
|
"---@async\n---@param notification {}\nfunction {}:send_notification(notification) end\n",
|
||||||
|
<Notification as Typed>::type_name(),
|
||||||
|
<Ntfy as Typed>::type_name(),
|
||||||
|
))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ use automation_lib::action_callback::ActionCallback;
|
|||||||
use automation_lib::config::MqttDeviceConfig;
|
use automation_lib::config::MqttDeviceConfig;
|
||||||
use automation_lib::device::{Device, LuaDeviceCreate};
|
use automation_lib::device::{Device, LuaDeviceCreate};
|
||||||
use automation_lib::event::OnMqtt;
|
use automation_lib::event::OnMqtt;
|
||||||
|
use automation_lib::lua::traits::PartialUserData;
|
||||||
use automation_lib::messages::PresenceMessage;
|
use automation_lib::messages::PresenceMessage;
|
||||||
use automation_lib::mqtt::WrappedAsyncClient;
|
use automation_lib::mqtt::WrappedAsyncClient;
|
||||||
use automation_macro::{Device, LuaDeviceConfig};
|
use automation_macro::{Device, LuaDeviceConfig};
|
||||||
@@ -39,13 +40,29 @@ pub struct State {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Device)]
|
#[derive(Debug, Clone, Device)]
|
||||||
#[device(add_methods = Self::add_methods)]
|
#[device(extra_user_data = OverallPresence)]
|
||||||
pub struct Presence {
|
pub struct Presence {
|
||||||
config: Config,
|
config: Config,
|
||||||
state: Arc<RwLock<State>>,
|
state: Arc<RwLock<State>>,
|
||||||
}
|
}
|
||||||
crate::register_device!(Presence);
|
crate::register_device!(Presence);
|
||||||
|
|
||||||
|
struct OverallPresence;
|
||||||
|
impl PartialUserData<Presence> for OverallPresence {
|
||||||
|
fn add_methods<M: mlua::UserDataMethods<Presence>>(methods: &mut M) {
|
||||||
|
methods.add_async_method("overall_presence", async |_lua, this, ()| {
|
||||||
|
Ok(this.state().await.current_overall_presence)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn definitions() -> Option<String> {
|
||||||
|
Some(format!(
|
||||||
|
"---@async\n---@return boolean\nfunction {}:overall_presence() end\n",
|
||||||
|
<Presence as Typed>::type_name(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Presence {
|
impl Presence {
|
||||||
async fn state(&self) -> RwLockReadGuard<'_, State> {
|
async fn state(&self) -> RwLockReadGuard<'_, State> {
|
||||||
self.state.read().await
|
self.state.read().await
|
||||||
@@ -54,12 +71,6 @@ impl Presence {
|
|||||||
async fn state_mut(&self) -> RwLockWriteGuard<'_, State> {
|
async fn state_mut(&self) -> RwLockWriteGuard<'_, State> {
|
||||||
self.state.write().await
|
self.state.write().await
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_methods<M: mlua::UserDataMethods<Self>>(methods: &mut M) {
|
|
||||||
methods.add_async_method("overall_presence", async |_lua, this, ()| {
|
|
||||||
Ok(this.state().await.current_overall_presence)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
|
|||||||
@@ -8,6 +8,10 @@ pub trait PartialUserData<T> {
|
|||||||
fn interface_name() -> Option<&'static str> {
|
fn interface_name() -> Option<&'static str> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn definitions() -> Option<String> {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Device;
|
pub struct Device;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use proc_macro2::TokenStream as TokenStream2;
|
use proc_macro2::TokenStream as TokenStream2;
|
||||||
use quote::{ToTokens, quote};
|
use quote::quote;
|
||||||
use syn::parse::{Parse, ParseStream};
|
use syn::parse::{Parse, ParseStream};
|
||||||
use syn::punctuated::Punctuated;
|
use syn::punctuated::Punctuated;
|
||||||
use syn::spanned::Spanned;
|
use syn::spanned::Spanned;
|
||||||
@@ -9,7 +9,7 @@ use syn::{Attribute, DeriveInput, Token, parenthesized};
|
|||||||
|
|
||||||
enum Attr {
|
enum Attr {
|
||||||
Trait(TraitAttr),
|
Trait(TraitAttr),
|
||||||
AddMethods(AddMethodsAttr),
|
ExtraUserData(ExtraUserDataAttr),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Attr {
|
impl Attr {
|
||||||
@@ -20,9 +20,9 @@ impl Attr {
|
|||||||
let input;
|
let input;
|
||||||
_ = parenthesized!(input in meta.input);
|
_ = parenthesized!(input in meta.input);
|
||||||
parsed = Some(Attr::Trait(input.parse()?));
|
parsed = Some(Attr::Trait(input.parse()?));
|
||||||
} else if meta.path.is_ident("add_methods") {
|
} else if meta.path.is_ident("extra_user_data") {
|
||||||
let value = meta.value()?;
|
let value = meta.value()?;
|
||||||
parsed = Some(Attr::AddMethods(value.parse()?));
|
parsed = Some(Attr::ExtraUserData(value.parse()?));
|
||||||
} else {
|
} else {
|
||||||
return Err(syn::Error::new(meta.path.span(), "Unknown attribute"));
|
return Err(syn::Error::new(meta.path.span(), "Unknown attribute"));
|
||||||
}
|
}
|
||||||
@@ -95,28 +95,18 @@ impl Parse for Aliases {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct AddMethodsAttr(syn::Path);
|
struct ExtraUserDataAttr(syn::Ident);
|
||||||
|
|
||||||
impl Parse for AddMethodsAttr {
|
impl Parse for ExtraUserDataAttr {
|
||||||
fn parse(input: ParseStream) -> syn::Result<Self> {
|
fn parse(input: ParseStream) -> syn::Result<Self> {
|
||||||
Ok(Self(input.parse()?))
|
Ok(Self(input.parse()?))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToTokens for AddMethodsAttr {
|
|
||||||
fn to_tokens(&self, tokens: &mut TokenStream2) {
|
|
||||||
let Self(path) = self;
|
|
||||||
|
|
||||||
tokens.extend(quote! {
|
|
||||||
#path
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Implementation {
|
struct Implementation {
|
||||||
name: syn::Ident,
|
name: syn::Ident,
|
||||||
traits: Traits,
|
traits: Traits,
|
||||||
add_methods: Vec<AddMethodsAttr>,
|
extra_user_data: Vec<ExtraUserDataAttr>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl quote::ToTokens for Implementation {
|
impl quote::ToTokens for Implementation {
|
||||||
@@ -124,9 +114,10 @@ impl quote::ToTokens for Implementation {
|
|||||||
let Self {
|
let Self {
|
||||||
name,
|
name,
|
||||||
traits,
|
traits,
|
||||||
add_methods,
|
extra_user_data,
|
||||||
} = &self;
|
} = &self;
|
||||||
let Traits(traits) = traits;
|
let Traits(traits) = traits;
|
||||||
|
let extra_user_data: Vec<_> = extra_user_data.iter().map(|tr| tr.0.clone()).collect();
|
||||||
|
|
||||||
tokens.extend(quote! {
|
tokens.extend(quote! {
|
||||||
impl mlua::UserData for #name {
|
impl mlua::UserData for #name {
|
||||||
@@ -151,7 +142,7 @@ impl quote::ToTokens for Implementation {
|
|||||||
)*
|
)*
|
||||||
|
|
||||||
#(
|
#(
|
||||||
#add_methods(methods);
|
<#extra_user_data as ::automation_lib::lua::traits::PartialUserData<#name>>::add_methods(methods);
|
||||||
)*
|
)*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -178,7 +169,7 @@ impl quote::ToTokens for Implementation {
|
|||||||
format!(": {interfaces}")
|
format!(": {interfaces}")
|
||||||
};
|
};
|
||||||
|
|
||||||
Some(format!("---@class {type_name}{interfaces}\nlocal {type_name}"))
|
Some(format!("---@class {type_name}{interfaces}\nlocal {type_name}\n"))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_members() -> Option<String> {
|
fn generate_members() -> Option<String> {
|
||||||
@@ -191,6 +182,15 @@ impl quote::ToTokens for Implementation {
|
|||||||
output += &format!("---@return {type_name}\n");
|
output += &format!("---@return {type_name}\n");
|
||||||
output += &format!("function devices.{type_name}.new(config) end\n");
|
output += &format!("function devices.{type_name}.new(config) end\n");
|
||||||
|
|
||||||
|
output += &<::automation_lib::lua::traits::Device as ::automation_lib::lua::traits::PartialUserData<#name>>::definitions().unwrap_or("".into());
|
||||||
|
|
||||||
|
#(
|
||||||
|
output += &<::automation_lib::lua::traits::#traits as ::automation_lib::lua::traits::PartialUserData<#name>>::definitions().unwrap_or("".into());
|
||||||
|
)*
|
||||||
|
#(
|
||||||
|
output += &<#extra_user_data as ::automation_lib::lua::traits::PartialUserData<#name>>::definitions().unwrap_or("".into());
|
||||||
|
)*
|
||||||
|
|
||||||
|
|
||||||
Some(output)
|
Some(output)
|
||||||
}
|
}
|
||||||
@@ -220,7 +220,7 @@ impl Implementations {
|
|||||||
all.extend(&attribute.traits);
|
all.extend(&attribute.traits);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Attr::AddMethods(attribute) => add_methods.push(attribute),
|
Attr::ExtraUserData(attribute) => add_methods.push(attribute),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -238,7 +238,7 @@ impl Implementations {
|
|||||||
.map(|(alias, traits)| Implementation {
|
.map(|(alias, traits)| Implementation {
|
||||||
name: alias.unwrap_or(name.clone()),
|
name: alias.unwrap_or(name.clone()),
|
||||||
traits,
|
traits,
|
||||||
add_methods: add_methods.clone(),
|
extra_user_data: add_methods.clone(),
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ use axum::http::StatusCode;
|
|||||||
use axum::routing::post;
|
use axum::routing::post;
|
||||||
use axum::{Json, Router};
|
use axum::{Json, Router};
|
||||||
use config::Config;
|
use config::Config;
|
||||||
use dotenvy::dotenv;
|
|
||||||
use google_home::{GoogleHome, Request, Response};
|
use google_home::{GoogleHome, Request, Response};
|
||||||
use mlua::LuaSerdeExt;
|
use mlua::LuaSerdeExt;
|
||||||
use rumqttc::AsyncClient;
|
use rumqttc::AsyncClient;
|
||||||
@@ -75,8 +74,6 @@ async fn fulfillment(
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn app() -> anyhow::Result<()> {
|
async fn app() -> anyhow::Result<()> {
|
||||||
dotenv().ok();
|
|
||||||
|
|
||||||
tracing_subscriber::fmt::init();
|
tracing_subscriber::fmt::init();
|
||||||
|
|
||||||
info!(version = VERSION, "automation_rs");
|
info!(version = VERSION, "automation_rs");
|
||||||
|
|||||||
Reference in New Issue
Block a user