feat: WIP
All checks were successful
Build and deploy / build (push) Successful in 10m34s
Build and deploy / Deploy container (push) Has been skipped

This commit is contained in:
2025-09-17 00:17:31 +02:00
parent 06b3154733
commit 175066a4c7
12 changed files with 219 additions and 10 deletions

View File

@@ -14,6 +14,7 @@ dyn-clone = { workspace = true }
eui48 = { workspace = true }
google_home = { workspace = true }
inventory = { workspace = true }
lua_typed = { workspace = true }
mlua = { workspace = true }
reqwest = { workspace = true }
rumqttc = { workspace = true }

View File

@@ -27,15 +27,15 @@ macro_rules! register_device {
pub(crate) use register_device;
type RegisterFn = fn(lua: &mlua::Lua) -> mlua::Result<mlua::AnyUserData>;
type RegisterDeviceFn = fn(lua: &mlua::Lua) -> mlua::Result<mlua::AnyUserData>;
pub struct RegisteredDevice {
name: &'static str,
register_fn: RegisterFn,
register_fn: RegisterDeviceFn,
}
impl RegisteredDevice {
pub const fn new(name: &'static str, register_fn: RegisterFn) -> Self {
pub const fn new(name: &'static str, register_fn: RegisterDeviceFn) -> Self {
Self { name, register_fn }
}
@@ -64,3 +64,28 @@ pub fn create_module(lua: &mlua::Lua) -> mlua::Result<mlua::Table> {
}
inventory::submit! {Module::new("devices", create_module)}
macro_rules! register_type {
($ty:ty) => {
::inventory::submit!(crate::RegisteredType(
<$ty as ::lua_typed::Typed>::generate_full
));
};
}
pub(crate) use register_type;
type RegisterTypeFn = fn() -> Option<String>;
pub struct RegisteredType(RegisterTypeFn);
inventory::collect!(RegisteredType);
pub fn generate_definitions() {
println!("---@meta\n\nlocal devices\n");
for ty in inventory::iter::<RegisteredType> {
let def = ty.0().unwrap();
println!("{def}");
}
println!("return devices")
}

View File

@@ -4,12 +4,13 @@ use std::convert::Infallible;
use async_trait::async_trait;
use automation_lib::device::{Device, LuaDeviceCreate};
use automation_macro::{Device, LuaDeviceConfig};
use lua_typed::Typed;
use mlua::LuaSerdeExt;
use serde::{Deserialize, Serialize};
use serde_repr::*;
use tracing::{error, trace, warn};
#[derive(Debug, Serialize_repr, Deserialize, Clone, Copy)]
#[derive(Debug, Serialize_repr, Deserialize, Clone, Copy, Typed)]
#[repr(u8)]
#[serde(rename_all = "snake_case")]
pub enum Priority {
@@ -19,8 +20,9 @@ pub enum Priority {
High,
Max,
}
crate::register_type!(Priority);
#[derive(Debug, Serialize, Deserialize, Clone)]
#[derive(Debug, Serialize, Deserialize, Clone, Typed)]
#[serde(rename_all = "snake_case", tag = "action")]
pub enum ActionType {
Broadcast {
@@ -31,22 +33,23 @@ pub enum ActionType {
// Http
}
#[derive(Debug, Serialize, Deserialize, Clone)]
#[derive(Debug, Serialize, Deserialize, Clone, Typed)]
pub struct Action {
#[serde(flatten)]
pub action: ActionType,
pub label: String,
pub clear: Option<bool>,
}
crate::register_type!(Action);
#[derive(Serialize, Deserialize)]
#[derive(Serialize, Deserialize, Typed)]
struct NotificationFinal {
topic: String,
#[serde(flatten)]
inner: Notification,
}
#[derive(Debug, Serialize, Clone, Deserialize)]
#[derive(Debug, Serialize, Clone, Deserialize, Typed)]
pub struct Notification {
title: String,
message: Option<String>,
@@ -57,6 +60,7 @@ pub struct Notification {
#[serde(skip_serializing_if = "Vec::is_empty", default = "Default::default")]
actions: Vec<Action>,
}
crate::register_type!(Notification);
impl Notification {
fn finalize(self, topic: &str) -> NotificationFinal {
@@ -67,12 +71,14 @@ impl Notification {
}
}
#[derive(Debug, Clone, LuaDeviceConfig)]
#[derive(Debug, Clone, LuaDeviceConfig, Typed)]
#[typed(as = "NtfyConfig")]
pub struct Config {
#[device_config(default("https://ntfy.sh".into()))]
pub url: String,
pub topic: String,
}
crate::register_type!(Config);
#[derive(Debug, Clone, Device)]
#[device(add_methods(Self::add_methods))]
@@ -80,6 +86,7 @@ pub struct Ntfy {
config: Config,
}
crate::register_device!(Ntfy);
crate::register_type!(Ntfy);
impl Ntfy {
fn add_methods<M: mlua::UserDataMethods<Self>>(methods: &mut M) {
@@ -96,6 +103,21 @@ impl Ntfy {
}
}
impl Typed for Ntfy {
fn type_name() -> String {
"Ntfy".into()
}
fn generate_header() -> Option<String> {
Some("---@class Ntfy\nlocal Ntfy\n".into())
}
fn generate_members() -> Option<String> {
Some("---@async\n---@param notification Notification\nfunction Ntfy:send_notification(notification) end\n".into(),
)
}
}
#[async_trait]
impl LuaDeviceCreate for Ntfy {
type Config = Config;