mirror of
https://github.com/rzuasti/oott.git
synced 2026-07-08 19:21:54 +02:00
Record originating scanner on device events
So that consumers of the events API can tell whether a sighting came from the ARP scanner or the mDNS listener. Adds a DeviceEventScanner enum (Arp / Mdns) plumbed from each scanner's call site through to a new scanner column on device_events, exposed via the existing events endpoint and OpenAPI schema. Pre-existing rows are backfilled with 'ARP' since that was the only scanner before mDNS. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
0e43194492
commit
d6cf9be412
@@ -0,0 +1 @@
|
|||||||
|
ALTER TABLE device_events ADD COLUMN scanner TEXT NOT NULL DEFAULT 'ARP' COLLATE NOCASE;
|
||||||
@@ -12,13 +12,14 @@ pub fn insert(event: DeviceEvent) -> Result<i64, DbError> {
|
|||||||
let mac_address = normalize_mac(&event.mac_address);
|
let mac_address = normalize_mac(&event.mac_address);
|
||||||
|
|
||||||
match conn.execute(
|
match conn.execute(
|
||||||
"INSERT INTO device_events (mac_address, created_on, event_type, ipv4_address, vendor) VALUES (?1, ?2, ?3, ?4, ?5)",
|
"INSERT INTO device_events (mac_address, created_on, event_type, ipv4_address, vendor, scanner) VALUES (?1, ?2, ?3, ?4, ?5, ?6)",
|
||||||
params![
|
params![
|
||||||
mac_address,
|
mac_address,
|
||||||
event.created_on.to_rfc3339_opts(chrono::SecondsFormat::Nanos, false),
|
event.created_on.to_rfc3339_opts(chrono::SecondsFormat::Nanos, false),
|
||||||
event.event_type,
|
event.event_type,
|
||||||
event.ipv4_address,
|
event.ipv4_address,
|
||||||
event.vendor
|
event.vendor,
|
||||||
|
event.scanner
|
||||||
],
|
],
|
||||||
) {
|
) {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
@@ -42,7 +43,7 @@ pub fn list(
|
|||||||
let conn = db::get_db_connection();
|
let conn = db::get_db_connection();
|
||||||
|
|
||||||
let mut sql_statement =
|
let mut sql_statement =
|
||||||
"SELECT id, mac_address, created_on, event_type, ipv4_address, vendor FROM device_events WHERE 1=1"
|
"SELECT id, mac_address, created_on, event_type, ipv4_address, vendor, scanner FROM device_events WHERE 1=1"
|
||||||
.to_string();
|
.to_string();
|
||||||
|
|
||||||
let mut params: Vec<rusqlite::types::Value> = Vec::new();
|
let mut params: Vec<rusqlite::types::Value> = Vec::new();
|
||||||
@@ -83,6 +84,7 @@ pub fn list(
|
|||||||
event_type: row.get(3)?,
|
event_type: row.get(3)?,
|
||||||
ipv4_address: row.get(4)?,
|
ipv4_address: row.get(4)?,
|
||||||
vendor: row.get(5)?,
|
vendor: row.get(5)?,
|
||||||
|
scanner: row.get(6)?,
|
||||||
})
|
})
|
||||||
})?
|
})?
|
||||||
.collect::<Result<_, _>>()?;
|
.collect::<Result<_, _>>()?;
|
||||||
@@ -113,7 +115,7 @@ fn read(id: i64) -> Option<DeviceEvent> {
|
|||||||
let conn = db::get_db_connection();
|
let conn = db::get_db_connection();
|
||||||
|
|
||||||
let result: Result<DeviceEvent, rusqlite::Error> = conn.query_one(
|
let result: Result<DeviceEvent, rusqlite::Error> = conn.query_one(
|
||||||
"SELECT id, mac_address, created_on, event_type, ipv4_address, vendor FROM device_events WHERE id=?1",
|
"SELECT id, mac_address, created_on, event_type, ipv4_address, vendor, scanner FROM device_events WHERE id=?1",
|
||||||
params![id],
|
params![id],
|
||||||
|row| {
|
|row| {
|
||||||
Ok(DeviceEvent {
|
Ok(DeviceEvent {
|
||||||
@@ -123,6 +125,7 @@ fn read(id: i64) -> Option<DeviceEvent> {
|
|||||||
event_type: row.get(3)?,
|
event_type: row.get(3)?,
|
||||||
ipv4_address: row.get(4)?,
|
ipv4_address: row.get(4)?,
|
||||||
vendor: row.get(5)?,
|
vendor: row.get(5)?,
|
||||||
|
scanner: row.get(6)?,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@@ -146,7 +149,10 @@ mod tests {
|
|||||||
use chrono::Utc;
|
use chrono::Utc;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::{model::device_events::DeviceEventType, tests_common};
|
use crate::{
|
||||||
|
model::device_events::{DeviceEventScanner, DeviceEventType},
|
||||||
|
tests_common,
|
||||||
|
};
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_insert() {
|
async fn test_insert() {
|
||||||
@@ -159,6 +165,7 @@ mod tests {
|
|||||||
DeviceEventType::NewDevice,
|
DeviceEventType::NewDevice,
|
||||||
"192.168.0.1".to_string(),
|
"192.168.0.1".to_string(),
|
||||||
"Vendor 1".to_string(),
|
"Vendor 1".to_string(),
|
||||||
|
DeviceEventScanner::Arp,
|
||||||
))
|
))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@@ -173,6 +180,7 @@ mod tests {
|
|||||||
assert_eq!(event.event_type, DeviceEventType::NewDevice);
|
assert_eq!(event.event_type, DeviceEventType::NewDevice);
|
||||||
assert_eq!(event.ipv4_address, "192.168.0.1");
|
assert_eq!(event.ipv4_address, "192.168.0.1");
|
||||||
assert_eq!(event.vendor, "Vendor 1");
|
assert_eq!(event.vendor, "Vendor 1");
|
||||||
|
assert_eq!(event.scanner, DeviceEventScanner::Arp);
|
||||||
|
|
||||||
let inserted_id = insert(DeviceEvent::new(
|
let inserted_id = insert(DeviceEvent::new(
|
||||||
"bb:bb:bb:bb:bb:bb".to_string(),
|
"bb:bb:bb:bb:bb:bb".to_string(),
|
||||||
@@ -180,11 +188,13 @@ mod tests {
|
|||||||
DeviceEventType::DeviceSeen,
|
DeviceEventType::DeviceSeen,
|
||||||
"192.168.0.2".to_string(),
|
"192.168.0.2".to_string(),
|
||||||
"Vendor 2".to_string(),
|
"Vendor 2".to_string(),
|
||||||
|
DeviceEventScanner::Mdns,
|
||||||
))
|
))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let event = read(inserted_id).unwrap();
|
let event = read(inserted_id).unwrap();
|
||||||
assert_eq!(event.event_type, DeviceEventType::DeviceSeen);
|
assert_eq!(event.event_type, DeviceEventType::DeviceSeen);
|
||||||
|
assert_eq!(event.scanner, DeviceEventScanner::Mdns);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
@@ -243,6 +253,7 @@ mod tests {
|
|||||||
DeviceEventType::NewDevice,
|
DeviceEventType::NewDevice,
|
||||||
"10.0.0.200".to_string(),
|
"10.0.0.200".to_string(),
|
||||||
"Old Vendor".to_string(),
|
"Old Vendor".to_string(),
|
||||||
|
DeviceEventScanner::Arp,
|
||||||
))
|
))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@@ -252,6 +263,7 @@ mod tests {
|
|||||||
DeviceEventType::DeviceSeen,
|
DeviceEventType::DeviceSeen,
|
||||||
"10.0.0.200".to_string(),
|
"10.0.0.200".to_string(),
|
||||||
"Old Vendor".to_string(),
|
"Old Vendor".to_string(),
|
||||||
|
DeviceEventScanner::Arp,
|
||||||
))
|
))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@@ -285,6 +297,7 @@ mod tests {
|
|||||||
DeviceEventType::NewDevice,
|
DeviceEventType::NewDevice,
|
||||||
"10.0.0.1".to_string(),
|
"10.0.0.1".to_string(),
|
||||||
"Vendor C".to_string(),
|
"Vendor C".to_string(),
|
||||||
|
DeviceEventScanner::Arp,
|
||||||
))
|
))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
insert(DeviceEvent::new(
|
insert(DeviceEvent::new(
|
||||||
@@ -295,6 +308,7 @@ mod tests {
|
|||||||
DeviceEventType::DeviceSeen,
|
DeviceEventType::DeviceSeen,
|
||||||
"10.0.0.1".to_string(),
|
"10.0.0.1".to_string(),
|
||||||
"Vendor C".to_string(),
|
"Vendor C".to_string(),
|
||||||
|
DeviceEventScanner::Arp,
|
||||||
))
|
))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
insert(DeviceEvent::new(
|
insert(DeviceEvent::new(
|
||||||
@@ -305,6 +319,7 @@ mod tests {
|
|||||||
DeviceEventType::DeviceSeen,
|
DeviceEventType::DeviceSeen,
|
||||||
"10.0.0.1".to_string(),
|
"10.0.0.1".to_string(),
|
||||||
"Vendor C".to_string(),
|
"Vendor C".to_string(),
|
||||||
|
DeviceEventScanner::Arp,
|
||||||
))
|
))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@@ -337,6 +352,7 @@ mod tests {
|
|||||||
DeviceEventType::NewDevice,
|
DeviceEventType::NewDevice,
|
||||||
"10.0.0.1".to_string(),
|
"10.0.0.1".to_string(),
|
||||||
"Vendor F".to_string(),
|
"Vendor F".to_string(),
|
||||||
|
DeviceEventScanner::Arp,
|
||||||
))
|
))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
insert(DeviceEvent::new(
|
insert(DeviceEvent::new(
|
||||||
@@ -347,6 +363,7 @@ mod tests {
|
|||||||
DeviceEventType::DeviceSeen,
|
DeviceEventType::DeviceSeen,
|
||||||
"10.0.0.1".to_string(),
|
"10.0.0.1".to_string(),
|
||||||
"Vendor F".to_string(),
|
"Vendor F".to_string(),
|
||||||
|
DeviceEventScanner::Arp,
|
||||||
))
|
))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@@ -379,6 +396,7 @@ mod tests {
|
|||||||
DeviceEventType::NewDevice,
|
DeviceEventType::NewDevice,
|
||||||
"10.0.0.1".to_string(),
|
"10.0.0.1".to_string(),
|
||||||
"Vendor D".to_string(),
|
"Vendor D".to_string(),
|
||||||
|
DeviceEventScanner::Arp,
|
||||||
))
|
))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
insert(DeviceEvent::new(
|
insert(DeviceEvent::new(
|
||||||
@@ -387,6 +405,7 @@ mod tests {
|
|||||||
DeviceEventType::DeviceSeen,
|
DeviceEventType::DeviceSeen,
|
||||||
"10.0.0.1".to_string(),
|
"10.0.0.1".to_string(),
|
||||||
"Vendor D".to_string(),
|
"Vendor D".to_string(),
|
||||||
|
DeviceEventScanner::Arp,
|
||||||
))
|
))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use std::error::Error;
|
|||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use crate::db;
|
use crate::db;
|
||||||
use crate::model::device_events::{DeviceEvent, DeviceEventType};
|
use crate::model::device_events::{DeviceEvent, DeviceEventScanner, DeviceEventType};
|
||||||
use crate::model::devices::Device;
|
use crate::model::devices::Device;
|
||||||
use crate::model::notifications::Notification;
|
use crate::model::notifications::Notification;
|
||||||
use crate::model::notifications::NotificationType;
|
use crate::model::notifications::NotificationType;
|
||||||
@@ -52,13 +52,17 @@ fn send_notification(notification: Notification) -> Result<(), Box<dyn Error>> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn trigger_new_device(device: Device) -> Result<(), Box<dyn Error>> {
|
pub fn trigger_new_device(
|
||||||
|
device: Device,
|
||||||
|
scanner: DeviceEventScanner,
|
||||||
|
) -> Result<(), Box<dyn Error>> {
|
||||||
let event = DeviceEvent::new(
|
let event = DeviceEvent::new(
|
||||||
device.mac_address.clone(),
|
device.mac_address.clone(),
|
||||||
Utc::now(),
|
Utc::now(),
|
||||||
DeviceEventType::NewDevice,
|
DeviceEventType::NewDevice,
|
||||||
device.ipv4_address.clone(),
|
device.ipv4_address.clone(),
|
||||||
device.vendor.clone(),
|
device.vendor.clone(),
|
||||||
|
scanner,
|
||||||
);
|
);
|
||||||
if let Err(err) = db::device_events::insert(event) {
|
if let Err(err) = db::device_events::insert(event) {
|
||||||
error!(
|
error!(
|
||||||
@@ -89,6 +93,7 @@ pub fn trigger_new_device(device: Device) -> Result<(), Box<dyn Error>> {
|
|||||||
pub fn trigger_existing_device(
|
pub fn trigger_existing_device(
|
||||||
existing_device: Device,
|
existing_device: Device,
|
||||||
new_device: Device,
|
new_device: Device,
|
||||||
|
scanner: DeviceEventScanner,
|
||||||
) -> Result<(), Box<dyn Error>> {
|
) -> Result<(), Box<dyn Error>> {
|
||||||
let event = DeviceEvent::new(
|
let event = DeviceEvent::new(
|
||||||
new_device.mac_address.clone(),
|
new_device.mac_address.clone(),
|
||||||
@@ -96,6 +101,7 @@ pub fn trigger_existing_device(
|
|||||||
DeviceEventType::DeviceSeen,
|
DeviceEventType::DeviceSeen,
|
||||||
new_device.ipv4_address.clone(),
|
new_device.ipv4_address.clone(),
|
||||||
new_device.vendor.clone(),
|
new_device.vendor.clone(),
|
||||||
|
scanner,
|
||||||
);
|
);
|
||||||
if let Err(err) = db::device_events::insert(event) {
|
if let Err(err) = db::device_events::insert(event) {
|
||||||
error!(
|
error!(
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ pub struct DeviceEvent {
|
|||||||
pub event_type: DeviceEventType,
|
pub event_type: DeviceEventType,
|
||||||
pub ipv4_address: String,
|
pub ipv4_address: String,
|
||||||
pub vendor: String,
|
pub vendor: String,
|
||||||
|
pub scanner: DeviceEventScanner,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DeviceEvent {
|
impl DeviceEvent {
|
||||||
@@ -24,6 +25,7 @@ impl DeviceEvent {
|
|||||||
event_type: DeviceEventType,
|
event_type: DeviceEventType,
|
||||||
ipv4_address: String,
|
ipv4_address: String,
|
||||||
vendor: String,
|
vendor: String,
|
||||||
|
scanner: DeviceEventScanner,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
id: -1,
|
id: -1,
|
||||||
@@ -32,6 +34,7 @@ impl DeviceEvent {
|
|||||||
event_type,
|
event_type,
|
||||||
ipv4_address,
|
ipv4_address,
|
||||||
vendor,
|
vendor,
|
||||||
|
scanner,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -40,13 +43,14 @@ impl fmt::Display for DeviceEvent {
|
|||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"id={}, mac_address={}, created_on={}, event_type={}, ipv4_address={}, vendor={}",
|
"id={}, mac_address={}, created_on={}, event_type={}, ipv4_address={}, vendor={}, scanner={}",
|
||||||
self.id,
|
self.id,
|
||||||
self.mac_address,
|
self.mac_address,
|
||||||
self.created_on,
|
self.created_on,
|
||||||
self.event_type,
|
self.event_type,
|
||||||
self.ipv4_address,
|
self.ipv4_address,
|
||||||
self.vendor,
|
self.vendor,
|
||||||
|
self.scanner,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -109,3 +113,56 @@ impl FromSql for DeviceEventType {
|
|||||||
.map_err(|e| FromSqlError::Other(Box::new(e)))
|
.map_err(|e| FromSqlError::Other(Box::new(e)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, ToSchema)]
|
||||||
|
pub enum DeviceEventScanner {
|
||||||
|
Arp,
|
||||||
|
Mdns,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for DeviceEventScanner {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
Self::Arp => write!(f, "ARP"),
|
||||||
|
Self::Mdns => write!(f, "mDNS"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct DeviceEventScannerParseError;
|
||||||
|
|
||||||
|
impl fmt::Display for DeviceEventScannerParseError {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(f, "Error parsing device event scanner")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Error for DeviceEventScannerParseError {}
|
||||||
|
|
||||||
|
impl FromStr for DeviceEventScanner {
|
||||||
|
type Err = DeviceEventScannerParseError;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
match s {
|
||||||
|
"ARP" => Ok(DeviceEventScanner::Arp),
|
||||||
|
"mDNS" => Ok(DeviceEventScanner::Mdns),
|
||||||
|
_ => Err(DeviceEventScannerParseError),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToSql for DeviceEventScanner {
|
||||||
|
fn to_sql(&self) -> rusqlite::Result<ToSqlOutput<'_>> {
|
||||||
|
Ok(self.to_string().into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromSql for DeviceEventScanner {
|
||||||
|
fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
|
||||||
|
value
|
||||||
|
.as_str()?
|
||||||
|
.parse()
|
||||||
|
.map_err(|e| FromSqlError::Other(Box::new(e)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ use super::finder;
|
|||||||
use super::status;
|
use super::status;
|
||||||
use crate::db;
|
use crate::db;
|
||||||
use crate::events;
|
use crate::events;
|
||||||
|
use crate::model::device_events::DeviceEventScanner;
|
||||||
use crate::settings::get_settings;
|
use crate::settings::get_settings;
|
||||||
use chrono::Utc;
|
use chrono::Utc;
|
||||||
use log::{debug, info};
|
use log::{debug, info};
|
||||||
@@ -38,7 +39,12 @@ pub async fn scan() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
device.device_type.clone(),
|
device.device_type.clone(),
|
||||||
device.name.clone(),
|
device.name.clone(),
|
||||||
)?;
|
)?;
|
||||||
events::trigger_existing_device(recorded_device, device.clone()).ok(); // Ignoring errors here, do not stop loop if notification delivery fails
|
events::trigger_existing_device(
|
||||||
|
recorded_device,
|
||||||
|
device.clone(),
|
||||||
|
DeviceEventScanner::Arp,
|
||||||
|
)
|
||||||
|
.ok(); // Ignoring errors here, do not stop loop if notification delivery fails
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
// If it doesn't exist insert it
|
// If it doesn't exist insert it
|
||||||
@@ -48,7 +54,7 @@ pub async fn scan() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
db::devices::insert(device.clone())?;
|
db::devices::insert(device.clone())?;
|
||||||
events::trigger_new_device(device.clone()).ok(); // Ignoring errors here, do not stop loop if notification delivery fails
|
events::trigger_new_device(device.clone(), DeviceEventScanner::Arp).ok(); // Ignoring errors here, do not stop loop if notification delivery fails
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ use crate::data::mac_vendor_finder;
|
|||||||
use crate::data::vendor_device_type_finder;
|
use crate::data::vendor_device_type_finder;
|
||||||
use crate::db;
|
use crate::db;
|
||||||
use crate::events;
|
use crate::events;
|
||||||
|
use crate::model::device_events::DeviceEventScanner;
|
||||||
use crate::model::devices::Device;
|
use crate::model::devices::Device;
|
||||||
use crate::settings::get_settings;
|
use crate::settings::get_settings;
|
||||||
|
|
||||||
@@ -105,7 +106,7 @@ async fn process_announcement(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Ignoring errors: do not stop the listener if notification delivery fails
|
// Ignoring errors: do not stop the listener if notification delivery fails
|
||||||
events::trigger_existing_device(recorded, device).ok();
|
events::trigger_existing_device(recorded, device, DeviceEventScanner::Mdns).ok();
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
debug!("New device {mac} discovered via mDNS; inserting");
|
debug!("New device {mac} discovered via mDNS; inserting");
|
||||||
@@ -113,7 +114,7 @@ async fn process_announcement(
|
|||||||
error!("Failed to insert mDNS device {mac}: {err}");
|
error!("Failed to insert mDNS device {mac}: {err}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
events::trigger_new_device(device).ok();
|
events::trigger_new_device(device, DeviceEventScanner::Mdns).ok();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
|
|
||||||
use crate::model::device_events::{DeviceEvent, DeviceEventType};
|
use crate::model::device_events::{DeviceEvent, DeviceEventScanner, DeviceEventType};
|
||||||
use crate::model::devices::{Device, DeviceSummary};
|
use crate::model::devices::{Device, DeviceSummary};
|
||||||
use crate::model::notifications::{Notification, NotificationType};
|
use crate::model::notifications::{Notification, NotificationType};
|
||||||
use crate::settings::get_settings;
|
use crate::settings::get_settings;
|
||||||
@@ -63,6 +63,7 @@ pub mod utils;
|
|||||||
UpdateDevicePayload,
|
UpdateDevicePayload,
|
||||||
DeviceEvent,
|
DeviceEvent,
|
||||||
DeviceEventType,
|
DeviceEventType,
|
||||||
|
DeviceEventScanner,
|
||||||
ArpScannerStatusResponse,
|
ArpScannerStatusResponse,
|
||||||
MdnsScannerStatusResponse,
|
MdnsScannerStatusResponse,
|
||||||
)),
|
)),
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
INSERT INTO device_events (id, mac_address, created_on, event_type, ipv4_address, vendor)
|
INSERT INTO device_events (id, mac_address, created_on, event_type, ipv4_address, vendor, scanner)
|
||||||
VALUES (1, 'aa:aa:aa:aa:aa:aa', '2026-01-01T11:11:11+00:00', 'NewDevice', '192.168.0.1', 'Vendor 1');
|
VALUES (1, 'aa:aa:aa:aa:aa:aa', '2026-01-01T11:11:11+00:00', 'NewDevice', '192.168.0.1', 'Vendor 1', 'ARP');
|
||||||
INSERT INTO device_events (id, mac_address, created_on, event_type, ipv4_address, vendor)
|
INSERT INTO device_events (id, mac_address, created_on, event_type, ipv4_address, vendor, scanner)
|
||||||
VALUES (2, 'bb:bb:bb:bb:bb:bb', '2026-02-03T13:14:15+00:00', 'DeviceSeen', '192.168.0.2', 'Vendor 2');
|
VALUES (2, 'bb:bb:bb:bb:bb:bb', '2026-02-03T13:14:15+00:00', 'DeviceSeen', '192.168.0.2', 'Vendor 2', 'mDNS');
|
||||||
INSERT INTO device_events (id, mac_address, created_on, event_type, ipv4_address, vendor)
|
INSERT INTO device_events (id, mac_address, created_on, event_type, ipv4_address, vendor, scanner)
|
||||||
VALUES (3, 'aa:aa:aa:aa:aa:aa', '2026-03-10T09:00:00+00:00', 'DeviceSeen', '192.168.0.1', 'Vendor 1');
|
VALUES (3, 'aa:aa:aa:aa:aa:aa', '2026-03-10T09:00:00+00:00', 'DeviceSeen', '192.168.0.1', 'Vendor 1', 'ARP');
|
||||||
|
|||||||
Reference in New Issue
Block a user