feat: WIP
This commit is contained in:
35
Cargo.lock
generated
35
Cargo.lock
generated
@@ -128,6 +128,7 @@ dependencies = [
|
||||
"eui48",
|
||||
"google_home",
|
||||
"inventory",
|
||||
"lua_typed",
|
||||
"mlua",
|
||||
"reqwest",
|
||||
"rumqttc",
|
||||
@@ -345,6 +346,15 @@ dependencies = [
|
||||
"winnow",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "convert_case"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baaaa0ecca5b51987b9423ccdc971514dd8b0bb7b4060b983d3664dad3f1f89f"
|
||||
dependencies = [
|
||||
"unicode-segmentation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation"
|
||||
version = "0.9.4"
|
||||
@@ -1094,6 +1104,25 @@ dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lua_typed"
|
||||
version = "0.1.0"
|
||||
source = "git+https://git.huizinga.dev/Dreaded_X/lua_typed#a5f4b672167335c60d9e50e0e7afc932a755b4cf"
|
||||
dependencies = [
|
||||
"lua_typed_macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lua_typed_macro"
|
||||
version = "0.1.0"
|
||||
source = "git+https://git.huizinga.dev/Dreaded_X/lua_typed#a5f4b672167335c60d9e50e0e7afc932a755b4cf"
|
||||
dependencies = [
|
||||
"convert_case",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.106",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "luajit-src"
|
||||
version = "210.6.1+f9140a6"
|
||||
@@ -2256,6 +2285,12 @@ version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-segmentation"
|
||||
version = "1.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493"
|
||||
|
||||
[[package]]
|
||||
name = "untrusted"
|
||||
version = "0.9.0"
|
||||
|
||||
@@ -37,6 +37,7 @@ indexmap = { version = "2.11.0", features = ["serde"] }
|
||||
inventory = "0.3.21"
|
||||
itertools = "0.14.0"
|
||||
json_value_merge = "2.0.1"
|
||||
lua_typed = { git = "https://git.huizinga.dev/Dreaded_X/lua_typed" }
|
||||
mlua = { version = "0.11.3", features = [
|
||||
"lua54",
|
||||
"vendored",
|
||||
|
||||
@@ -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 }
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
@@ -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,24 @@ impl Ntfy {
|
||||
}
|
||||
}
|
||||
|
||||
impl Typed for Ntfy {
|
||||
fn type_name() -> String {
|
||||
"Ntfy".into()
|
||||
}
|
||||
|
||||
fn generate_header() -> Option<String> {
|
||||
let type_name = <Self as Typed>::type_name();
|
||||
Some(format!("---@class {type_name}\nlocal {type_name}\n"))
|
||||
}
|
||||
|
||||
fn generate_members() -> Option<String> {
|
||||
Some(format!(
|
||||
"---@async\n---@param notification Notification\nfunction {}:send_notification(notification) end\n",
|
||||
<Self as Typed>::type_name(),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl LuaDeviceCreate for Ntfy {
|
||||
type Config = Config;
|
||||
|
||||
@@ -2,17 +2,21 @@ local devices = require("automation:devices")
|
||||
local device_manager = require("automation:device_manager")
|
||||
local utils = require("automation:utils")
|
||||
local secrets = require("automation:secrets")
|
||||
local debug = require("automation:variables").debug or false
|
||||
local debug = require("automation:variables").debug and true or false
|
||||
|
||||
print(_VERSION)
|
||||
|
||||
local host = utils.get_hostname()
|
||||
print("Running @" .. host)
|
||||
|
||||
--- @param topic string
|
||||
--- @return string
|
||||
local function mqtt_z2m(topic)
|
||||
return "zigbee2mqtt/" .. topic
|
||||
end
|
||||
|
||||
--- @param topic string
|
||||
--- @return string
|
||||
local function mqtt_automation(topic)
|
||||
return "automation/" .. topic
|
||||
end
|
||||
@@ -30,6 +34,7 @@ local mqtt_client = require("automation:mqtt").new({
|
||||
tls = host == "zeus" or host == "hephaestus",
|
||||
})
|
||||
|
||||
--- @type Ntfy
|
||||
local ntfy = devices.Ntfy.new({
|
||||
topic = secrets.ntfy_topic,
|
||||
})
|
||||
|
||||
42
definitions.bak/automation:devices.lua.bak
Normal file
42
definitions.bak/automation:devices.lua.bak
Normal file
@@ -0,0 +1,42 @@
|
||||
---@meta
|
||||
|
||||
local devices
|
||||
|
||||
---@class Action
|
||||
---@field action
|
||||
---| "broadcast"
|
||||
---| "view"
|
||||
---@field extras table<string, string> | nil
|
||||
---@field label string | nil
|
||||
---@field clear boolean|nil
|
||||
|
||||
---@alias Priority
|
||||
---| "min"
|
||||
---| "low"
|
||||
---| "default"
|
||||
---| "high"
|
||||
---| "max"
|
||||
|
||||
---@class Notification
|
||||
---@field title string
|
||||
---@field message string | nil
|
||||
-- NOTE: It might be possible to specify this down to the actual possible values
|
||||
---@field tags string[] | nil
|
||||
---@field priority Priority | nil
|
||||
---@field actions Action[] | nil
|
||||
|
||||
---@class Ntfy
|
||||
local Ntfy
|
||||
---@async
|
||||
---@param notification Notification
|
||||
function Ntfy:send_notification(notification) end
|
||||
|
||||
---@class NtfyConfig
|
||||
---@field topic string
|
||||
|
||||
devices.Ntfy = {}
|
||||
---@param config NtfyConfig
|
||||
---@return Ntfy
|
||||
function devices.Ntfy.new(config) end
|
||||
|
||||
return devices
|
||||
6
definitions.bak/automation:secrets.lua.bak
Normal file
6
definitions.bak/automation:secrets.lua.bak
Normal file
@@ -0,0 +1,6 @@
|
||||
---@meta
|
||||
|
||||
---@type table<string, string|nil>
|
||||
local secrets
|
||||
|
||||
return secrets
|
||||
27
definitions.bak/automation:utils.lua.bak
Normal file
27
definitions.bak/automation:utils.lua.bak
Normal file
@@ -0,0 +1,27 @@
|
||||
---@meta
|
||||
|
||||
local utils
|
||||
|
||||
---@class Timeout
|
||||
local Timeout
|
||||
---@async
|
||||
---@param timeout number
|
||||
---@param callback fun()
|
||||
function Timeout:start(timeout, callback) end
|
||||
---@async
|
||||
function Timeout:cancel() end
|
||||
---@async
|
||||
---@return boolean
|
||||
function Timeout:is_waiting() end
|
||||
|
||||
utils.Timeout = {}
|
||||
---@return Timeout
|
||||
function utils.Timeout.new() end
|
||||
|
||||
--- @return string hostname
|
||||
function utils.get_hostname() end
|
||||
|
||||
--- @return number epoch
|
||||
function utils.get_epoch() end
|
||||
|
||||
return utils
|
||||
6
definitions.bak/automation:variables.lua.bak
Normal file
6
definitions.bak/automation:variables.lua.bak
Normal file
@@ -0,0 +1,6 @@
|
||||
---@meta
|
||||
|
||||
---@type table<string, string|nil>
|
||||
local variables
|
||||
|
||||
return variables
|
||||
36
definitions/automation:devices.lua
Normal file
36
definitions/automation:devices.lua
Normal file
@@ -0,0 +1,36 @@
|
||||
---@meta
|
||||
|
||||
local devices
|
||||
|
||||
---@class Ntfy
|
||||
local Ntfy
|
||||
---@async
|
||||
---@param notification Notification
|
||||
function Ntfy:send_notification(notification) end
|
||||
|
||||
---@alias Priority
|
||||
---| "min"
|
||||
---| "low"
|
||||
---| "default"
|
||||
---| "high"
|
||||
---| "max"
|
||||
|
||||
---@class Notification
|
||||
---@field title string
|
||||
---@field message string?
|
||||
---@field tags string[]?
|
||||
---@field priority Priority?
|
||||
---@field actions Action[]?
|
||||
|
||||
---@class NtfyConfig
|
||||
---@field url string
|
||||
---@field topic string
|
||||
|
||||
---@class Action
|
||||
---@field action
|
||||
---| "broadcast"
|
||||
---@field extras table<string, string>?
|
||||
---@field label string
|
||||
---@field clear boolean?
|
||||
|
||||
return devices
|
||||
3
src/bin/generate_definitions.rs
Normal file
3
src/bin/generate_definitions.rs
Normal file
@@ -0,0 +1,3 @@
|
||||
fn main() {
|
||||
automation_devices::generate_definitions()
|
||||
}
|
||||
Reference in New Issue
Block a user