Compare commits
2 Commits
88a1c15f39
...
2540b32902
| Author | SHA1 | Date | |
|---|---|---|---|
|
2540b32902
|
|||
|
06b3154733
|
35
Cargo.lock
generated
35
Cargo.lock
generated
@@ -128,6 +128,7 @@ dependencies = [
|
|||||||
"eui48",
|
"eui48",
|
||||||
"google_home",
|
"google_home",
|
||||||
"inventory",
|
"inventory",
|
||||||
|
"lua_typed",
|
||||||
"mlua",
|
"mlua",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"rumqttc",
|
"rumqttc",
|
||||||
@@ -345,6 +346,15 @@ dependencies = [
|
|||||||
"winnow",
|
"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]]
|
[[package]]
|
||||||
name = "core-foundation"
|
name = "core-foundation"
|
||||||
version = "0.9.4"
|
version = "0.9.4"
|
||||||
@@ -1094,6 +1104,25 @@ dependencies = [
|
|||||||
"cc",
|
"cc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lua_typed"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "git+https://git.huizinga.dev/Dreaded_X/lua_typed#cef241546e679190472b1ea7e5904cf8102f7f4b"
|
||||||
|
dependencies = [
|
||||||
|
"lua_typed_macro",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lua_typed_macro"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "git+https://git.huizinga.dev/Dreaded_X/lua_typed#cef241546e679190472b1ea7e5904cf8102f7f4b"
|
||||||
|
dependencies = [
|
||||||
|
"convert_case",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.106",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "luajit-src"
|
name = "luajit-src"
|
||||||
version = "210.6.1+f9140a6"
|
version = "210.6.1+f9140a6"
|
||||||
@@ -2256,6 +2285,12 @@ version = "1.0.18"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-segmentation"
|
||||||
|
version = "1.12.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "untrusted"
|
name = "untrusted"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ indexmap = { version = "2.11.0", features = ["serde"] }
|
|||||||
inventory = "0.3.21"
|
inventory = "0.3.21"
|
||||||
itertools = "0.14.0"
|
itertools = "0.14.0"
|
||||||
json_value_merge = "2.0.1"
|
json_value_merge = "2.0.1"
|
||||||
|
lua_typed = { git = "https://git.huizinga.dev/Dreaded_X/lua_typed" }
|
||||||
mlua = { version = "0.11.3", features = [
|
mlua = { version = "0.11.3", features = [
|
||||||
"lua54",
|
"lua54",
|
||||||
"vendored",
|
"vendored",
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ dyn-clone = { workspace = true }
|
|||||||
eui48 = { workspace = true }
|
eui48 = { workspace = true }
|
||||||
google_home = { workspace = true }
|
google_home = { workspace = true }
|
||||||
inventory = { workspace = true }
|
inventory = { workspace = true }
|
||||||
|
lua_typed = { workspace = true }
|
||||||
mlua = { workspace = true }
|
mlua = { workspace = true }
|
||||||
reqwest = { workspace = true }
|
reqwest = { workspace = true }
|
||||||
rumqttc = { workspace = true }
|
rumqttc = { workspace = true }
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ mod zigbee;
|
|||||||
|
|
||||||
use automation_lib::Module;
|
use automation_lib::Module;
|
||||||
use automation_lib::device::{Device, LuaDeviceCreate};
|
use automation_lib::device::{Device, LuaDeviceCreate};
|
||||||
|
use lua_typed::Typed;
|
||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
|
|
||||||
macro_rules! register_device {
|
macro_rules! register_device {
|
||||||
@@ -64,3 +65,12 @@ pub fn create_module(lua: &mlua::Lua) -> mlua::Result<mlua::Table> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inventory::submit! {Module::new("devices", create_module)}
|
inventory::submit! {Module::new("devices", create_module)}
|
||||||
|
|
||||||
|
pub fn generate_definitions() {
|
||||||
|
println!("{}", ntfy::Priority::generate_full().unwrap());
|
||||||
|
println!("{}", ntfy::ActionType::generate_full().unwrap());
|
||||||
|
println!("{}", ntfy::Action::generate_full().unwrap());
|
||||||
|
println!("{}", ntfy::Notification::generate_full().unwrap());
|
||||||
|
println!("{}", ntfy::Config::generate_full().unwrap());
|
||||||
|
println!("{}", ntfy::Ntfy::generate_full().unwrap());
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,12 +4,13 @@ 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_macro::{Device, LuaDeviceConfig};
|
use automation_macro::{Device, LuaDeviceConfig};
|
||||||
|
use lua_typed::Typed;
|
||||||
use mlua::LuaSerdeExt;
|
use mlua::LuaSerdeExt;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_repr::*;
|
use serde_repr::*;
|
||||||
use tracing::{error, trace, warn};
|
use tracing::{error, trace, warn};
|
||||||
|
|
||||||
#[derive(Debug, Serialize_repr, Deserialize, Clone, Copy)]
|
#[derive(Debug, Serialize_repr, Deserialize, Clone, Copy, Typed)]
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
#[serde(rename_all = "snake_case")]
|
#[serde(rename_all = "snake_case")]
|
||||||
pub enum Priority {
|
pub enum Priority {
|
||||||
@@ -20,7 +21,7 @@ pub enum Priority {
|
|||||||
Max,
|
Max,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone, Typed)]
|
||||||
#[serde(rename_all = "snake_case", tag = "action")]
|
#[serde(rename_all = "snake_case", tag = "action")]
|
||||||
pub enum ActionType {
|
pub enum ActionType {
|
||||||
Broadcast {
|
Broadcast {
|
||||||
@@ -31,7 +32,7 @@ pub enum ActionType {
|
|||||||
// Http
|
// Http
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone, Typed)]
|
||||||
pub struct Action {
|
pub struct Action {
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
pub action: ActionType,
|
pub action: ActionType,
|
||||||
@@ -39,14 +40,14 @@ pub struct Action {
|
|||||||
pub clear: Option<bool>,
|
pub clear: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize, Typed)]
|
||||||
struct NotificationFinal {
|
struct NotificationFinal {
|
||||||
topic: String,
|
topic: String,
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
inner: Notification,
|
inner: Notification,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Clone, Deserialize)]
|
#[derive(Debug, Serialize, Clone, Deserialize, Typed)]
|
||||||
pub struct Notification {
|
pub struct Notification {
|
||||||
title: String,
|
title: String,
|
||||||
message: Option<String>,
|
message: Option<String>,
|
||||||
@@ -67,7 +68,7 @@ impl Notification {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, LuaDeviceConfig)]
|
#[derive(Debug, Clone, LuaDeviceConfig, Typed)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
#[device_config(default("https://ntfy.sh".into()))]
|
#[device_config(default("https://ntfy.sh".into()))]
|
||||||
pub url: String,
|
pub url: String,
|
||||||
@@ -96,6 +97,21 @@ impl Ntfy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Typed for Ntfy {
|
||||||
|
fn type_name() -> String {
|
||||||
|
"Ntfy".into()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn generate_header() -> Option<String> {
|
||||||
|
Some("---@class Ntfy\n".into())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn generate_members() -> Option<String> {
|
||||||
|
Some("---@async\n---@param notification Notification\nfunction Ntfy:send_notification(notification) end".into(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl LuaDeviceCreate for Ntfy {
|
impl LuaDeviceCreate for Ntfy {
|
||||||
type Config = Config;
|
type Config = Config;
|
||||||
|
|||||||
@@ -89,9 +89,9 @@ impl From<StateColorTemperature> for StateBrightness {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Device)]
|
#[derive(Debug, Clone, Device)]
|
||||||
#[device(traits(OnOff for <StateOnOff>, <StateBrightness>, <StateColorTemperature>))]
|
#[device(traits(OnOff for LightOnOff, LightBrightness, LightColorTemperature))]
|
||||||
#[device(traits(Brightness for <StateBrightness>, <StateColorTemperature>))]
|
#[device(traits(Brightness for LightBrightness, LightColorTemperature))]
|
||||||
#[device(traits(ColorSetting for <StateColorTemperature>))]
|
#[device(traits(ColorSetting for LightColorTemperature))]
|
||||||
pub struct Light<T: LightState> {
|
pub struct Light<T: LightState> {
|
||||||
config: Config<T>,
|
config: Config<T>,
|
||||||
|
|
||||||
@@ -144,7 +144,7 @@ impl<T: LightState> Device for Light<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl OnMqtt for Light<StateOnOff> {
|
impl OnMqtt for LightOnOff {
|
||||||
async fn on_mqtt(&self, message: Publish) {
|
async fn on_mqtt(&self, message: Publish) {
|
||||||
// Check if the message is from the device itself or from a remote
|
// Check if the message is from the device itself or from a remote
|
||||||
if matches(&message.topic, &self.config.mqtt.topic) {
|
if matches(&message.topic, &self.config.mqtt.topic) {
|
||||||
@@ -177,7 +177,7 @@ impl OnMqtt for Light<StateOnOff> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl OnMqtt for Light<StateBrightness> {
|
impl OnMqtt for LightBrightness {
|
||||||
async fn on_mqtt(&self, message: Publish) {
|
async fn on_mqtt(&self, message: Publish) {
|
||||||
// Check if the message is from the deviec itself or from a remote
|
// Check if the message is from the deviec itself or from a remote
|
||||||
if matches(&message.topic, &self.config.mqtt.topic) {
|
if matches(&message.topic, &self.config.mqtt.topic) {
|
||||||
@@ -216,7 +216,7 @@ impl OnMqtt for Light<StateBrightness> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl OnMqtt for Light<StateColorTemperature> {
|
impl OnMqtt for LightColorTemperature {
|
||||||
async fn on_mqtt(&self, message: Publish) {
|
async fn on_mqtt(&self, message: Publish) {
|
||||||
// Check if the message is from the deviec itself or from a remote
|
// Check if the message is from the deviec itself or from a remote
|
||||||
if matches(&message.topic, &self.config.mqtt.topic) {
|
if matches(&message.topic, &self.config.mqtt.topic) {
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ impl From<StatePower> for StateOnOff {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Device)]
|
#[derive(Debug, Clone, Device)]
|
||||||
#[device(traits(OnOff for <StateOnOff>, <StatePower>))]
|
#[device(traits(OnOff for OutletOnOff, OutletPower))]
|
||||||
pub struct Outlet<T: OutletState> {
|
pub struct Outlet<T: OutletState> {
|
||||||
config: Config<T>,
|
config: Config<T>,
|
||||||
|
|
||||||
@@ -131,7 +131,7 @@ impl<T: OutletState> Device for Outlet<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl OnMqtt for Outlet<StateOnOff> {
|
impl OnMqtt for OutletOnOff {
|
||||||
async fn on_mqtt(&self, message: Publish) {
|
async fn on_mqtt(&self, message: Publish) {
|
||||||
// Check if the message is from the device itself or from a remote
|
// Check if the message is from the device itself or from a remote
|
||||||
if matches(&message.topic, &self.config.mqtt.topic) {
|
if matches(&message.topic, &self.config.mqtt.topic) {
|
||||||
@@ -164,7 +164,7 @@ impl OnMqtt for Outlet<StateOnOff> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl OnMqtt for Outlet<StatePower> {
|
impl OnMqtt for OutletPower {
|
||||||
async fn on_mqtt(&self, message: Publish) {
|
async fn on_mqtt(&self, message: Publish) {
|
||||||
// Check if the message is from the deviec itself or from a remote
|
// Check if the message is from the deviec itself or from a remote
|
||||||
if matches(&message.topic, &self.config.mqtt.topic) {
|
if matches(&message.topic, &self.config.mqtt.topic) {
|
||||||
|
|||||||
@@ -35,14 +35,14 @@ impl Parse for Attr {
|
|||||||
|
|
||||||
struct TraitAttr {
|
struct TraitAttr {
|
||||||
traits: Traits,
|
traits: Traits,
|
||||||
generics: Generics,
|
aliases: Aliases,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Parse for TraitAttr {
|
impl Parse for TraitAttr {
|
||||||
fn parse(input: ParseStream) -> syn::Result<Self> {
|
fn parse(input: ParseStream) -> syn::Result<Self> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
traits: input.parse()?,
|
traits: input.parse()?,
|
||||||
generics: input.parse()?,
|
aliases: input.parse()?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -78,15 +78,15 @@ impl ToTokens for Traits {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct Generics(Vec<syn::AngleBracketedGenericArguments>);
|
struct Aliases(Vec<syn::Ident>);
|
||||||
|
|
||||||
impl Generics {
|
impl Aliases {
|
||||||
fn has_generics(&self) -> bool {
|
fn has_aliases(&self) -> bool {
|
||||||
!self.0.is_empty()
|
!self.0.is_empty()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Parse for Generics {
|
impl Parse for Aliases {
|
||||||
fn parse(input: ParseStream) -> syn::Result<Self> {
|
fn parse(input: ParseStream) -> syn::Result<Self> {
|
||||||
if !input.peek(Token![for]) {
|
if !input.peek(Token![for]) {
|
||||||
if input.is_empty() {
|
if input.is_empty() {
|
||||||
@@ -100,7 +100,7 @@ impl Parse for Generics {
|
|||||||
|
|
||||||
input
|
input
|
||||||
.call(Punctuated::<_, Token![,]>::parse_separated_nonempty)
|
.call(Punctuated::<_, Token![,]>::parse_separated_nonempty)
|
||||||
.map(|generics| generics.into_iter().collect())
|
.map(|aliases| aliases.into_iter().collect())
|
||||||
.map(Self)
|
.map(Self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -125,7 +125,7 @@ impl ToTokens for AddMethodsAttr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct Implementation {
|
struct Implementation {
|
||||||
generics: Option<syn::AngleBracketedGenericArguments>,
|
name: syn::Ident,
|
||||||
traits: Traits,
|
traits: Traits,
|
||||||
add_methods: Vec<AddMethodsAttr>,
|
add_methods: Vec<AddMethodsAttr>,
|
||||||
}
|
}
|
||||||
@@ -133,13 +133,13 @@ struct Implementation {
|
|||||||
impl quote::ToTokens for Implementation {
|
impl quote::ToTokens for Implementation {
|
||||||
fn to_tokens(&self, tokens: &mut TokenStream2) {
|
fn to_tokens(&self, tokens: &mut TokenStream2) {
|
||||||
let Self {
|
let Self {
|
||||||
generics,
|
name,
|
||||||
traits,
|
traits,
|
||||||
add_methods,
|
add_methods,
|
||||||
} = &self;
|
} = &self;
|
||||||
|
|
||||||
tokens.extend(quote! {
|
tokens.extend(quote! {
|
||||||
#generics {
|
impl mlua::UserData for #name {
|
||||||
fn add_methods<M: mlua::UserDataMethods<Self>>(methods: &mut M) {
|
fn add_methods<M: mlua::UserDataMethods<Self>>(methods: &mut M) {
|
||||||
methods.add_async_function("new", async |_lua, config| {
|
methods.add_async_function("new", async |_lua, config| {
|
||||||
let device: Self = LuaDeviceCreate::create(config)
|
let device: Self = LuaDeviceCreate::create(config)
|
||||||
@@ -169,18 +169,18 @@ impl quote::ToTokens for Implementation {
|
|||||||
|
|
||||||
struct Implementations(Vec<Implementation>);
|
struct Implementations(Vec<Implementation>);
|
||||||
|
|
||||||
impl From<Vec<Attr>> for Implementations {
|
impl Implementations {
|
||||||
fn from(attributes: Vec<Attr>) -> Self {
|
fn from_attr(attributes: Vec<Attr>, name: syn::Ident) -> Self {
|
||||||
let mut add_methods = Vec::new();
|
let mut add_methods = Vec::new();
|
||||||
let mut all = Traits::default();
|
let mut all = Traits::default();
|
||||||
let mut implementations: HashMap<_, Traits> = HashMap::new();
|
let mut implementations: HashMap<_, Traits> = HashMap::new();
|
||||||
for attribute in attributes {
|
for attribute in attributes {
|
||||||
match attribute {
|
match attribute {
|
||||||
Attr::Trait(attribute) => {
|
Attr::Trait(attribute) => {
|
||||||
if attribute.generics.has_generics() {
|
if attribute.aliases.has_aliases() {
|
||||||
for generic in &attribute.generics.0 {
|
for alias in &attribute.aliases.0 {
|
||||||
implementations
|
implementations
|
||||||
.entry(Some(generic.clone()))
|
.entry(Some(alias.clone()))
|
||||||
.or_default()
|
.or_default()
|
||||||
.extend(&attribute.traits);
|
.extend(&attribute.traits);
|
||||||
}
|
}
|
||||||
@@ -203,8 +203,8 @@ impl From<Vec<Attr>> for Implementations {
|
|||||||
Self(
|
Self(
|
||||||
implementations
|
implementations
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(generics, traits)| Implementation {
|
.map(|(alias, traits)| Implementation {
|
||||||
generics,
|
name: alias.unwrap_or(name.clone()),
|
||||||
traits,
|
traits,
|
||||||
add_methods: add_methods.clone(),
|
add_methods: add_methods.clone(),
|
||||||
})
|
})
|
||||||
@@ -213,9 +213,7 @@ impl From<Vec<Attr>> for Implementations {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn device(input: &DeriveInput) -> TokenStream2 {
|
pub fn device(input: DeriveInput) -> TokenStream2 {
|
||||||
let name = &input.ident;
|
|
||||||
|
|
||||||
let Implementations(imp) = match input
|
let Implementations(imp) = match input
|
||||||
.attrs
|
.attrs
|
||||||
.iter()
|
.iter()
|
||||||
@@ -223,13 +221,13 @@ pub fn device(input: &DeriveInput) -> TokenStream2 {
|
|||||||
.map(Attribute::parse_args)
|
.map(Attribute::parse_args)
|
||||||
.try_collect::<Vec<_>>()
|
.try_collect::<Vec<_>>()
|
||||||
{
|
{
|
||||||
Ok(result) => result.into(),
|
Ok(attr) => Implementations::from_attr(attr, input.ident),
|
||||||
Err(err) => return err.into_compile_error(),
|
Err(err) => return err.into_compile_error(),
|
||||||
};
|
};
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
#(
|
#(
|
||||||
impl mlua::UserData for #name #imp
|
#imp
|
||||||
)*
|
)*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,5 +69,5 @@ pub fn lua_serialize(input: proc_macro::TokenStream) -> proc_macro::TokenStream
|
|||||||
#[proc_macro_derive(Device, attributes(device))]
|
#[proc_macro_derive(Device, attributes(device))]
|
||||||
pub fn device(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
pub fn device(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||||
let ast = parse_macro_input!(input as DeriveInput);
|
let ast = parse_macro_input!(input as DeriveInput);
|
||||||
device::device(&ast).into()
|
device::device(ast).into()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,17 +2,21 @@ local devices = require("automation:devices")
|
|||||||
local device_manager = require("automation:device_manager")
|
local device_manager = require("automation:device_manager")
|
||||||
local utils = require("automation:utils")
|
local utils = require("automation:utils")
|
||||||
local secrets = require("automation:secrets")
|
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)
|
print(_VERSION)
|
||||||
|
|
||||||
local host = utils.get_hostname()
|
local host = utils.get_hostname()
|
||||||
print("Running @" .. host)
|
print("Running @" .. host)
|
||||||
|
|
||||||
|
--- @param topic string
|
||||||
|
--- @return string
|
||||||
local function mqtt_z2m(topic)
|
local function mqtt_z2m(topic)
|
||||||
return "zigbee2mqtt/" .. topic
|
return "zigbee2mqtt/" .. topic
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- @param topic string
|
||||||
|
--- @return string
|
||||||
local function mqtt_automation(topic)
|
local function mqtt_automation(topic)
|
||||||
return "automation/" .. topic
|
return "automation/" .. topic
|
||||||
end
|
end
|
||||||
|
|||||||
42
definitions.bak/automation:devices.lua
Normal file
42
definitions.bak/automation:devices.lua
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
Normal file
6
definitions.bak/automation:secrets.lua
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
---@meta
|
||||||
|
|
||||||
|
---@type table<string, string|nil>
|
||||||
|
local secrets
|
||||||
|
|
||||||
|
return secrets
|
||||||
27
definitions.bak/automation:utils.lua
Normal file
27
definitions.bak/automation:utils.lua
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
Normal file
6
definitions.bak/automation:variables.lua
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
---@meta
|
||||||
|
|
||||||
|
---@type table<string, string|nil>
|
||||||
|
local variables
|
||||||
|
|
||||||
|
return variables
|
||||||
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