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 {
|
||||
config: Config,
|
||||
}
|
||||
crate::register_device!(AirFilter);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum Error {
|
||||
|
||||
@@ -54,6 +54,7 @@ pub struct ContactSensor {
|
||||
config: Config,
|
||||
state: Arc<RwLock<State>>,
|
||||
}
|
||||
crate::register_device!(ContactSensor);
|
||||
|
||||
impl ContactSensor {
|
||||
async fn state(&self) -> RwLockReadGuard<'_, State> {
|
||||
|
||||
@@ -35,6 +35,7 @@ pub struct Config {
|
||||
pub struct HueBridge {
|
||||
config: Config,
|
||||
}
|
||||
crate::register_device!(HueBridge);
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
struct FlagMessage {
|
||||
|
||||
@@ -24,6 +24,7 @@ pub struct Config {
|
||||
pub struct HueGroup {
|
||||
config: Config,
|
||||
}
|
||||
crate::register_device!(HueGroup);
|
||||
|
||||
// Couple of helper function to get the correct urls
|
||||
#[async_trait]
|
||||
|
||||
@@ -59,6 +59,7 @@ struct State {
|
||||
pub struct HueSwitch {
|
||||
config: Config,
|
||||
}
|
||||
crate::register_device!(HueSwitch);
|
||||
|
||||
impl Device for HueSwitch {
|
||||
fn get_id(&self) -> String {
|
||||
|
||||
@@ -33,6 +33,7 @@ pub struct Config {
|
||||
pub struct IkeaRemote {
|
||||
config: Config,
|
||||
}
|
||||
crate::register_device!(IkeaRemote);
|
||||
|
||||
impl Device for IkeaRemote {
|
||||
fn get_id(&self) -> String {
|
||||
|
||||
@@ -26,6 +26,7 @@ pub struct Config {
|
||||
pub struct KasaOutlet {
|
||||
config: Config,
|
||||
}
|
||||
crate::register_device!(KasaOutlet);
|
||||
|
||||
#[async_trait]
|
||||
impl LuaDeviceCreate for KasaOutlet {
|
||||
|
||||
@@ -14,48 +14,51 @@ mod zigbee;
|
||||
|
||||
use automation_lib::Module;
|
||||
use automation_lib::device::{Device, LuaDeviceCreate};
|
||||
use zigbee::light::{LightBrightness, LightColorTemperature, LightOnOff};
|
||||
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;
|
||||
use tracing::debug;
|
||||
|
||||
macro_rules! register_device {
|
||||
($lua:expr, $table:expr, $device:ty) => {
|
||||
$table.set(stringify!($device), $lua.create_proxy::<$device>()?)?;
|
||||
($device:ty) => {
|
||||
::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> {
|
||||
let devices = lua.create_table()?;
|
||||
|
||||
register_device!(lua, devices, AirFilter);
|
||||
register_device!(lua, devices, ContactSensor);
|
||||
register_device!(lua, devices, HueBridge);
|
||||
register_device!(lua, devices, HueGroup);
|
||||
register_device!(lua, devices, HueSwitch);
|
||||
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);
|
||||
debug!("Loading devices...");
|
||||
for device in inventory::iter::<RegisteredDevice> {
|
||||
debug!(name = device.get_name(), "Registering device");
|
||||
let proxy = device.register(lua)?;
|
||||
devices.set(device.get_name(), proxy)?;
|
||||
}
|
||||
|
||||
Ok(devices)
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@ pub struct LightSensor {
|
||||
config: Config,
|
||||
state: Arc<RwLock<State>>,
|
||||
}
|
||||
crate::register_device!(LightSensor);
|
||||
|
||||
impl LightSensor {
|
||||
async fn state(&self) -> RwLockReadGuard<'_, State> {
|
||||
|
||||
@@ -97,6 +97,7 @@ pub struct Config {
|
||||
pub struct Ntfy {
|
||||
config: Config,
|
||||
}
|
||||
crate::register_device!(Ntfy);
|
||||
|
||||
impl Ntfy {
|
||||
fn add_methods<M: mlua::UserDataMethods<Self>>(methods: &mut M) {
|
||||
|
||||
@@ -39,6 +39,7 @@ pub struct Presence {
|
||||
config: Config,
|
||||
state: Arc<RwLock<State>>,
|
||||
}
|
||||
crate::register_device!(Presence);
|
||||
|
||||
impl Presence {
|
||||
async fn state(&self) -> RwLockReadGuard<'_, State> {
|
||||
|
||||
@@ -32,6 +32,7 @@ pub struct Config {
|
||||
pub struct WakeOnLAN {
|
||||
config: Config,
|
||||
}
|
||||
crate::register_device!(WakeOnLAN);
|
||||
|
||||
#[async_trait]
|
||||
impl LuaDeviceCreate for WakeOnLAN {
|
||||
|
||||
@@ -38,6 +38,7 @@ pub struct Washer {
|
||||
config: Config,
|
||||
state: Arc<RwLock<State>>,
|
||||
}
|
||||
crate::register_device!(Washer);
|
||||
|
||||
impl Washer {
|
||||
async fn state(&self) -> RwLockReadGuard<'_, State> {
|
||||
|
||||
@@ -99,8 +99,13 @@ pub struct Light<T: LightState> {
|
||||
}
|
||||
|
||||
pub type LightOnOff = Light<StateOnOff>;
|
||||
crate::register_device!(LightOnOff);
|
||||
|
||||
pub type LightBrightness = Light<StateBrightness>;
|
||||
crate::register_device!(LightBrightness);
|
||||
|
||||
pub type LightColorTemperature = Light<StateColorTemperature>;
|
||||
crate::register_device!(LightColorTemperature);
|
||||
|
||||
impl<T: LightState> Light<T> {
|
||||
async fn state(&self) -> RwLockReadGuard<'_, T> {
|
||||
|
||||
@@ -89,7 +89,10 @@ pub struct Outlet<T: OutletState> {
|
||||
}
|
||||
|
||||
pub type OutletOnOff = Outlet<StateOnOff>;
|
||||
crate::register_device!(OutletOnOff);
|
||||
|
||||
pub type OutletPower = Outlet<StatePower>;
|
||||
crate::register_device!(OutletPower);
|
||||
|
||||
impl<T: OutletState> Outlet<T> {
|
||||
async fn state(&self) -> RwLockReadGuard<'_, T> {
|
||||
|
||||
@@ -37,9 +37,8 @@ impl Module {
|
||||
}
|
||||
|
||||
pub fn load_modules(lua: &mlua::Lua) -> mlua::Result<()> {
|
||||
debug!("Loading modules...");
|
||||
for module in inventory::iter::<Module> {
|
||||
debug!(name = module.get_name(), "Registering");
|
||||
debug!(name = module.get_name(), "Loading module");
|
||||
let table = module.register(lua)?;
|
||||
lua.register_module(module.get_name(), table)?;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user