Enhance SSE Statistics and Home Assistant Type Management
- Improved SSE statistics endpoint with comprehensive error handling and structured response - Refined Home Assistant type exports in interfaces - Updated SSE manager to provide more detailed subscription statistics - Added timestamp and success status to SSE stats endpoint - Introduced .env.development configuration file with detailed model and processor settings
This commit is contained in:
@@ -171,10 +171,35 @@ router.get('/subscribe_events', middleware.wsRateLimiter, (req, res) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// SSE stats endpoint
|
/**
|
||||||
|
* SSE Statistics Endpoint
|
||||||
|
* Returns detailed statistics about SSE connections and subscriptions.
|
||||||
|
*
|
||||||
|
* @route GET /get_sse_stats
|
||||||
|
* @authentication Required - Bearer token
|
||||||
|
* @returns {Object} Statistics object containing:
|
||||||
|
* - total_clients: Total number of connected clients
|
||||||
|
* - authenticated_clients: Number of authenticated clients
|
||||||
|
* - total_subscriptions: Total number of active subscriptions
|
||||||
|
* - clients_by_connection_time: Client counts by connection duration
|
||||||
|
* - total_entities_tracked: Number of entities being tracked
|
||||||
|
* - subscriptions: Lists of entity, event, and domain subscriptions
|
||||||
|
*/
|
||||||
router.get('/get_sse_stats', middleware.authenticate, (_req, res) => {
|
router.get('/get_sse_stats', middleware.authenticate, (_req, res) => {
|
||||||
const stats = sseManager.getStatistics();
|
try {
|
||||||
res.json(stats);
|
const stats = sseManager.getStatistics();
|
||||||
|
res.json({
|
||||||
|
success: true,
|
||||||
|
timestamp: new Date().toISOString(),
|
||||||
|
data: stats
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
res.status(500).json({
|
||||||
|
success: false,
|
||||||
|
message: error instanceof Error ? error.message : 'Unknown error occurred',
|
||||||
|
timestamp: new Date().toISOString()
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default router;
|
export default router;
|
||||||
@@ -30,31 +30,19 @@ export interface CommandParams {
|
|||||||
humidity?: number;
|
humidity?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Re-export Home Assistant types
|
||||||
|
export type {
|
||||||
|
HassInstance,
|
||||||
|
HassStates,
|
||||||
|
HassServices,
|
||||||
|
HassConnection,
|
||||||
|
HassService,
|
||||||
|
HassEvent,
|
||||||
|
HassEntity,
|
||||||
|
HassState
|
||||||
|
} from './hass.js';
|
||||||
|
|
||||||
// Home Assistant interfaces
|
// Home Assistant interfaces
|
||||||
export interface HassEntity {
|
|
||||||
entity_id: string;
|
|
||||||
state: string;
|
|
||||||
attributes: Record<string, any>;
|
|
||||||
last_changed?: string;
|
|
||||||
last_updated?: string;
|
|
||||||
context?: {
|
|
||||||
id: string;
|
|
||||||
parent_id?: string;
|
|
||||||
user_id?: string;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface HassState {
|
|
||||||
entity_id: string;
|
|
||||||
state: string;
|
|
||||||
attributes: {
|
|
||||||
friendly_name?: string;
|
|
||||||
description?: string;
|
|
||||||
[key: string]: any;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add-on interfaces
|
|
||||||
export interface HassAddon {
|
export interface HassAddon {
|
||||||
name: string;
|
name: string;
|
||||||
slug: string;
|
slug: string;
|
||||||
@@ -180,6 +168,3 @@ export interface AutomationConfigParams {
|
|||||||
action: any[];
|
action: any[];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Re-export all Home Assistant types
|
|
||||||
export * from './hass.js';
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import { EventEmitter } from 'events';
|
import { EventEmitter } from 'events';
|
||||||
import { HassEntity, HassEvent, StateChangedEvent } from '../types/hass.js';
|
import { HassEntity, HassEvent } from '../interfaces/hass.js';
|
||||||
import { TokenManager } from '../security/index.js';
|
import { TokenManager } from '../security/index.js';
|
||||||
|
|
||||||
interface RateLimit {
|
interface RateLimit {
|
||||||
@@ -345,17 +345,29 @@ export class SSEManager extends EventEmitter {
|
|||||||
less_than_1h: 0,
|
less_than_1h: 0,
|
||||||
more_than_1h: 0
|
more_than_1h: 0
|
||||||
},
|
},
|
||||||
total_entities_tracked: this.entityStates.size
|
total_entities_tracked: this.entityStates.size,
|
||||||
|
subscriptions: {
|
||||||
|
entities: new Set<string>(),
|
||||||
|
events: new Set<string>(),
|
||||||
|
domains: new Set<string>()
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const client of this.clients.values()) {
|
for (const client of this.clients.values()) {
|
||||||
if (client.authenticated) stats.authenticated_clients++;
|
if (client.authenticated) stats.authenticated_clients++;
|
||||||
|
|
||||||
|
// Count subscriptions
|
||||||
stats.total_subscriptions +=
|
stats.total_subscriptions +=
|
||||||
client.subscriptions.entities.size +
|
client.subscriptions.entities.size +
|
||||||
client.subscriptions.events.size +
|
client.subscriptions.events.size +
|
||||||
client.subscriptions.domains.size;
|
client.subscriptions.domains.size;
|
||||||
|
|
||||||
|
// Add to subscription sets
|
||||||
|
client.subscriptions.entities.forEach(entity => stats.subscriptions.entities.add(entity));
|
||||||
|
client.subscriptions.events.forEach(event => stats.subscriptions.events.add(event));
|
||||||
|
client.subscriptions.domains.forEach(domain => stats.subscriptions.domains.add(domain));
|
||||||
|
|
||||||
|
// Calculate connection duration
|
||||||
const connectionDuration = now - client.connectionTime;
|
const connectionDuration = now - client.connectionTime;
|
||||||
if (connectionDuration < 60000) stats.clients_by_connection_time.less_than_1m++;
|
if (connectionDuration < 60000) stats.clients_by_connection_time.less_than_1m++;
|
||||||
else if (connectionDuration < 300000) stats.clients_by_connection_time.less_than_5m++;
|
else if (connectionDuration < 300000) stats.clients_by_connection_time.less_than_5m++;
|
||||||
@@ -363,7 +375,15 @@ export class SSEManager extends EventEmitter {
|
|||||||
else stats.clients_by_connection_time.more_than_1h++;
|
else stats.clients_by_connection_time.more_than_1h++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return stats;
|
// Convert Sets to Arrays for JSON serialization
|
||||||
|
return {
|
||||||
|
...stats,
|
||||||
|
subscriptions: {
|
||||||
|
entities: Array.from(stats.subscriptions.entities),
|
||||||
|
events: Array.from(stats.subscriptions.events),
|
||||||
|
domains: Array.from(stats.subscriptions.domains)
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user