feat!: Improve device type registration
Instead of one function that contains all the device types available in `automation_devices` a global registry is used were each device can register itself.
This commit is contained in:
@@ -24,6 +24,7 @@ pub struct Config {
|
|||||||
pub struct AirFilter {
|
pub struct AirFilter {
|
||||||
config: Config,
|
config: Config,
|
||||||
}
|
}
|
||||||
|
crate::register_device!(AirFilter);
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ pub struct ContactSensor {
|
|||||||
config: Config,
|
config: Config,
|
||||||
state: Arc<RwLock<State>>,
|
state: Arc<RwLock<State>>,
|
||||||
}
|
}
|
||||||
|
crate::register_device!(ContactSensor);
|
||||||
|
|
||||||
impl ContactSensor {
|
impl ContactSensor {
|
||||||
async fn state(&self) -> RwLockReadGuard<'_, State> {
|
async fn state(&self) -> RwLockReadGuard<'_, State> {
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ pub struct Config {
|
|||||||
pub struct HueBridge {
|
pub struct HueBridge {
|
||||||
config: Config,
|
config: Config,
|
||||||
}
|
}
|
||||||
|
crate::register_device!(HueBridge);
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize)]
|
||||||
struct FlagMessage {
|
struct FlagMessage {
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ pub struct Config {
|
|||||||
pub struct HueGroup {
|
pub struct HueGroup {
|
||||||
config: Config,
|
config: Config,
|
||||||
}
|
}
|
||||||
|
crate::register_device!(HueGroup);
|
||||||
|
|
||||||
// Couple of helper function to get the correct urls
|
// Couple of helper function to get the correct urls
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ struct State {
|
|||||||
pub struct HueSwitch {
|
pub struct HueSwitch {
|
||||||
config: Config,
|
config: Config,
|
||||||
}
|
}
|
||||||
|
crate::register_device!(HueSwitch);
|
||||||
|
|
||||||
impl Device for HueSwitch {
|
impl Device for HueSwitch {
|
||||||
fn get_id(&self) -> String {
|
fn get_id(&self) -> String {
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ pub struct Config {
|
|||||||
pub struct IkeaRemote {
|
pub struct IkeaRemote {
|
||||||
config: Config,
|
config: Config,
|
||||||
}
|
}
|
||||||
|
crate::register_device!(IkeaRemote);
|
||||||
|
|
||||||
impl Device for IkeaRemote {
|
impl Device for IkeaRemote {
|
||||||
fn get_id(&self) -> String {
|
fn get_id(&self) -> String {
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ pub struct Config {
|
|||||||
pub struct KasaOutlet {
|
pub struct KasaOutlet {
|
||||||
config: Config,
|
config: Config,
|
||||||
}
|
}
|
||||||
|
crate::register_device!(KasaOutlet);
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl LuaDeviceCreate for KasaOutlet {
|
impl LuaDeviceCreate for KasaOutlet {
|
||||||
|
|||||||
@@ -14,48 +14,51 @@ mod zigbee;
|
|||||||
|
|
||||||
use automation_lib::Module;
|
use automation_lib::Module;
|
||||||
use automation_lib::device::{Device, LuaDeviceCreate};
|
use automation_lib::device::{Device, LuaDeviceCreate};
|
||||||
use zigbee::light::{LightBrightness, LightColorTemperature, LightOnOff};
|
use tracing::debug;
|
||||||
use zigbee::outlet::{OutletOnOff, OutletPower};
|
|
||||||
|
|
||||||
pub use self::air_filter::AirFilter;
|
|
||||||
pub use self::contact_sensor::ContactSensor;
|
|
||||||
pub use self::hue_bridge::HueBridge;
|
|
||||||
pub use self::hue_group::HueGroup;
|
|
||||||
pub use self::hue_switch::HueSwitch;
|
|
||||||
pub use self::ikea_remote::IkeaRemote;
|
|
||||||
pub use self::kasa_outlet::KasaOutlet;
|
|
||||||
pub use self::light_sensor::LightSensor;
|
|
||||||
pub use self::ntfy::*;
|
|
||||||
pub use self::presence::Presence;
|
|
||||||
pub use self::wake_on_lan::WakeOnLAN;
|
|
||||||
pub use self::washer::Washer;
|
|
||||||
|
|
||||||
macro_rules! register_device {
|
macro_rules! register_device {
|
||||||
($lua:expr, $table:expr, $device:ty) => {
|
($device:ty) => {
|
||||||
$table.set(stringify!($device), $lua.create_proxy::<$device>()?)?;
|
::inventory::submit!(crate::RegisteredDevice::new(
|
||||||
|
stringify!($device),
|
||||||
|
::mlua::Lua::create_proxy::<$device>
|
||||||
|
));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) use register_device;
|
||||||
|
|
||||||
|
type RegisterFn = fn(lua: &mlua::Lua) -> mlua::Result<mlua::AnyUserData>;
|
||||||
|
|
||||||
|
pub struct RegisteredDevice {
|
||||||
|
name: &'static str,
|
||||||
|
register_fn: RegisterFn,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RegisteredDevice {
|
||||||
|
pub const fn new(name: &'static str, register_fn: RegisterFn) -> Self {
|
||||||
|
Self { name, register_fn }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn get_name(&self) -> &'static str {
|
||||||
|
self.name
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn register(&self, lua: &mlua::Lua) -> mlua::Result<mlua::AnyUserData> {
|
||||||
|
(self.register_fn)(lua)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inventory::collect!(RegisteredDevice);
|
||||||
|
|
||||||
pub fn create_module(lua: &mlua::Lua) -> mlua::Result<mlua::Table> {
|
pub fn create_module(lua: &mlua::Lua) -> mlua::Result<mlua::Table> {
|
||||||
let devices = lua.create_table()?;
|
let devices = lua.create_table()?;
|
||||||
|
|
||||||
register_device!(lua, devices, AirFilter);
|
debug!("Loading devices...");
|
||||||
register_device!(lua, devices, ContactSensor);
|
for device in inventory::iter::<RegisteredDevice> {
|
||||||
register_device!(lua, devices, HueBridge);
|
debug!(name = device.get_name(), "Registering device");
|
||||||
register_device!(lua, devices, HueGroup);
|
let proxy = device.register(lua)?;
|
||||||
register_device!(lua, devices, HueSwitch);
|
devices.set(device.get_name(), proxy)?;
|
||||||
register_device!(lua, devices, IkeaRemote);
|
}
|
||||||
register_device!(lua, devices, KasaOutlet);
|
|
||||||
register_device!(lua, devices, LightBrightness);
|
|
||||||
register_device!(lua, devices, LightColorTemperature);
|
|
||||||
register_device!(lua, devices, LightOnOff);
|
|
||||||
register_device!(lua, devices, LightSensor);
|
|
||||||
register_device!(lua, devices, Ntfy);
|
|
||||||
register_device!(lua, devices, OutletOnOff);
|
|
||||||
register_device!(lua, devices, OutletPower);
|
|
||||||
register_device!(lua, devices, Presence);
|
|
||||||
register_device!(lua, devices, WakeOnLAN);
|
|
||||||
register_device!(lua, devices, Washer);
|
|
||||||
|
|
||||||
Ok(devices)
|
Ok(devices)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ pub struct LightSensor {
|
|||||||
config: Config,
|
config: Config,
|
||||||
state: Arc<RwLock<State>>,
|
state: Arc<RwLock<State>>,
|
||||||
}
|
}
|
||||||
|
crate::register_device!(LightSensor);
|
||||||
|
|
||||||
impl LightSensor {
|
impl LightSensor {
|
||||||
async fn state(&self) -> RwLockReadGuard<'_, State> {
|
async fn state(&self) -> RwLockReadGuard<'_, State> {
|
||||||
|
|||||||
@@ -97,6 +97,7 @@ pub struct Config {
|
|||||||
pub struct Ntfy {
|
pub struct Ntfy {
|
||||||
config: Config,
|
config: Config,
|
||||||
}
|
}
|
||||||
|
crate::register_device!(Ntfy);
|
||||||
|
|
||||||
impl Ntfy {
|
impl Ntfy {
|
||||||
fn add_methods<M: mlua::UserDataMethods<Self>>(methods: &mut M) {
|
fn add_methods<M: mlua::UserDataMethods<Self>>(methods: &mut M) {
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ pub struct Presence {
|
|||||||
config: Config,
|
config: Config,
|
||||||
state: Arc<RwLock<State>>,
|
state: Arc<RwLock<State>>,
|
||||||
}
|
}
|
||||||
|
crate::register_device!(Presence);
|
||||||
|
|
||||||
impl Presence {
|
impl Presence {
|
||||||
async fn state(&self) -> RwLockReadGuard<'_, State> {
|
async fn state(&self) -> RwLockReadGuard<'_, State> {
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ pub struct Config {
|
|||||||
pub struct WakeOnLAN {
|
pub struct WakeOnLAN {
|
||||||
config: Config,
|
config: Config,
|
||||||
}
|
}
|
||||||
|
crate::register_device!(WakeOnLAN);
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl LuaDeviceCreate for WakeOnLAN {
|
impl LuaDeviceCreate for WakeOnLAN {
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ pub struct Washer {
|
|||||||
config: Config,
|
config: Config,
|
||||||
state: Arc<RwLock<State>>,
|
state: Arc<RwLock<State>>,
|
||||||
}
|
}
|
||||||
|
crate::register_device!(Washer);
|
||||||
|
|
||||||
impl Washer {
|
impl Washer {
|
||||||
async fn state(&self) -> RwLockReadGuard<'_, State> {
|
async fn state(&self) -> RwLockReadGuard<'_, State> {
|
||||||
|
|||||||
@@ -99,8 +99,13 @@ pub struct Light<T: LightState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub type LightOnOff = Light<StateOnOff>;
|
pub type LightOnOff = Light<StateOnOff>;
|
||||||
|
crate::register_device!(LightOnOff);
|
||||||
|
|
||||||
pub type LightBrightness = Light<StateBrightness>;
|
pub type LightBrightness = Light<StateBrightness>;
|
||||||
|
crate::register_device!(LightBrightness);
|
||||||
|
|
||||||
pub type LightColorTemperature = Light<StateColorTemperature>;
|
pub type LightColorTemperature = Light<StateColorTemperature>;
|
||||||
|
crate::register_device!(LightColorTemperature);
|
||||||
|
|
||||||
impl<T: LightState> Light<T> {
|
impl<T: LightState> Light<T> {
|
||||||
async fn state(&self) -> RwLockReadGuard<'_, T> {
|
async fn state(&self) -> RwLockReadGuard<'_, T> {
|
||||||
|
|||||||
@@ -89,7 +89,10 @@ pub struct Outlet<T: OutletState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub type OutletOnOff = Outlet<StateOnOff>;
|
pub type OutletOnOff = Outlet<StateOnOff>;
|
||||||
|
crate::register_device!(OutletOnOff);
|
||||||
|
|
||||||
pub type OutletPower = Outlet<StatePower>;
|
pub type OutletPower = Outlet<StatePower>;
|
||||||
|
crate::register_device!(OutletPower);
|
||||||
|
|
||||||
impl<T: OutletState> Outlet<T> {
|
impl<T: OutletState> Outlet<T> {
|
||||||
async fn state(&self) -> RwLockReadGuard<'_, T> {
|
async fn state(&self) -> RwLockReadGuard<'_, T> {
|
||||||
|
|||||||
@@ -37,9 +37,8 @@ impl Module {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn load_modules(lua: &mlua::Lua) -> mlua::Result<()> {
|
pub fn load_modules(lua: &mlua::Lua) -> mlua::Result<()> {
|
||||||
debug!("Loading modules...");
|
|
||||||
for module in inventory::iter::<Module> {
|
for module in inventory::iter::<Module> {
|
||||||
debug!(name = module.get_name(), "Registering");
|
debug!(name = module.get_name(), "Loading module");
|
||||||
let table = module.register(lua)?;
|
let table = module.register(lua)?;
|
||||||
lua.register_module(module.get_name(), table)?;
|
lua.register_module(module.get_name(), table)?;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user