homebridge-unifi-occupancy-lite
Version:
Lightweight UniFi occupancy sensor plugin for Homebridge using API tokens only. Works with UDM Pro/SE, UDM, UDR and other UniFi OS devices.
115 lines (114 loc) • 3.83 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.WifiPoint = exports.Resident = exports.Device = void 0;
class Device {
constructor(config) {
this.isOnline = false;
this.trafficBytes = 0;
this.name = config.name;
this.hostname = config.hostname;
this.ip = config.ip;
this.mac = config.mac;
this.minTrafficAmount = config.minTrafficAmount;
}
/**
* Check if this device matches the given UniFi client
*/
matchesClient(client) {
// Check MAC address first (most reliable)
if (this.mac && client.mac && this.mac.toLowerCase() === client.mac.toLowerCase()) {
return true;
}
// Check IP address
if (this.ip && client.ip && this.ip === client.ip) {
return true;
}
// Check hostname
if (this.hostname && client.hostname &&
this.hostname.toLowerCase() === client.hostname.toLowerCase()) {
return true;
}
// Check if hostname matches device name
if (this.hostname && client.name &&
this.hostname.toLowerCase() === client.name.toLowerCase()) {
return true;
}
return false;
}
/**
* Update device status from UniFi client data
*/
updateFromClient(client, trafficData) {
// Accept both wired and wireless connections
this.isOnline = true;
this.lastSeen = new Date();
// Set access point MAC from client data
this.currentAccessPoint = client.ap_mac || client.sw_mac || client.uplink_mac || client.access_point_mac;
// Update traffic data if available
if (trafficData) {
this.trafficBytes = trafficData.rx_bytes + trafficData.tx_bytes;
}
// If minTrafficAmount is set, check if device has enough traffic
if (this.minTrafficAmount && this.minTrafficAmount > 0) {
const trafficKB = this.trafficBytes / 1024;
const hasEnoughTraffic = trafficKB >= this.minTrafficAmount;
this.isOnline = this.isOnline && hasEnoughTraffic;
}
}
}
exports.Device = Device;
class Resident {
constructor(config) {
this.devices = [];
this.isHome = false;
this.name = config.name;
this.devices = config.devices.map(deviceConfig => new Device(deviceConfig));
}
/**
* Update resident status based on device presence
*/
updatePresence() {
this.isHome = this.devices.some(device => device.isOnline);
}
/**
* Get devices connected to specific access point
*/
getDevicesAtAccessPoint(accessPointMac) {
return this.devices.filter(device => device.isOnline && device.currentAccessPoint === accessPointMac);
}
}
exports.Resident = Resident;
class WifiPoint {
constructor(config) {
this.hasResidents = false;
this.name = config.name;
this.ip = config.ip;
this.mac = config.mac;
}
/**
* Check if this wifi point matches the given access point
*/
matchesAccessPoint(accessPoint) {
// Check MAC address
if (this.mac && accessPoint.mac &&
this.mac.toLowerCase() === accessPoint.mac.toLowerCase()) {
return true;
}
// Check IP address
if (this.ip && accessPoint.ip && this.ip === accessPoint.ip) {
return true;
}
return false;
}
/**
* Update presence based on residents at this access point
*/
updatePresence(residents) {
if (!this.mac) {
this.hasResidents = false;
return;
}
this.hasResidents = residents.some(resident => resident.getDevicesAtAccessPoint(this.mac).length > 0);
}
}
exports.WifiPoint = WifiPoint;