Files
wifi-densepose/ui/services/pose.service.js

303 lines
7.6 KiB
JavaScript

// Pose Service for WiFi-DensePose UI
import { API_CONFIG } from '../config/api.config.js';
import { apiService } from './api.service.js';
import { wsService } from './websocket.service.js';
export class PoseService {
constructor() {
this.streamConnection = null;
this.eventConnection = null;
this.poseSubscribers = [];
this.eventSubscribers = [];
}
// Get current pose estimation
async getCurrentPose(options = {}) {
const params = {
zone_ids: options.zoneIds?.join(','),
confidence_threshold: options.confidenceThreshold,
max_persons: options.maxPersons,
include_keypoints: options.includeKeypoints,
include_segmentation: options.includeSegmentation
};
// Remove undefined values
Object.keys(params).forEach(key =>
params[key] === undefined && delete params[key]
);
return apiService.get(API_CONFIG.ENDPOINTS.POSE.CURRENT, params);
}
// Analyze pose (requires auth)
async analyzePose(request) {
return apiService.post(API_CONFIG.ENDPOINTS.POSE.ANALYZE, request);
}
// Get zone occupancy
async getZoneOccupancy(zoneId) {
const endpoint = API_CONFIG.ENDPOINTS.POSE.ZONE_OCCUPANCY.replace('{zone_id}', zoneId);
return apiService.get(endpoint);
}
// Get zones summary
async getZonesSummary() {
return apiService.get(API_CONFIG.ENDPOINTS.POSE.ZONES_SUMMARY);
}
// Get historical data (requires auth)
async getHistoricalData(request) {
return apiService.post(API_CONFIG.ENDPOINTS.POSE.HISTORICAL, request);
}
// Get recent activities
async getActivities(options = {}) {
const params = {
zone_id: options.zoneId,
limit: options.limit || 50
};
// Remove undefined values
Object.keys(params).forEach(key =>
params[key] === undefined && delete params[key]
);
return apiService.get(API_CONFIG.ENDPOINTS.POSE.ACTIVITIES, params);
}
// Calibrate system (requires auth)
async calibrate() {
return apiService.post(API_CONFIG.ENDPOINTS.POSE.CALIBRATE);
}
// Get calibration status (requires auth)
async getCalibrationStatus() {
return apiService.get(API_CONFIG.ENDPOINTS.POSE.CALIBRATION_STATUS);
}
// Get pose statistics
async getStats(hours = 24) {
return apiService.get(API_CONFIG.ENDPOINTS.POSE.STATS, { hours });
}
// Start pose stream
startPoseStream(options = {}) {
if (this.streamConnection) {
console.warn('Pose stream already active');
return this.streamConnection;
}
const params = {
zone_ids: options.zoneIds?.join(','),
min_confidence: options.minConfidence || 0.5,
max_fps: options.maxFps || 30,
token: options.token || apiService.authToken
};
// Remove undefined values
Object.keys(params).forEach(key =>
params[key] === undefined && delete params[key]
);
this.streamConnection = wsService.connect(
API_CONFIG.ENDPOINTS.STREAM.WS_POSE,
params,
{
onOpen: () => {
console.log('Pose stream connected');
this.notifyPoseSubscribers({ type: 'connected' });
},
onMessage: (data) => {
this.handlePoseMessage(data);
},
onError: (error) => {
console.error('Pose stream error:', error);
this.notifyPoseSubscribers({ type: 'error', error });
},
onClose: () => {
console.log('Pose stream disconnected');
this.streamConnection = null;
this.notifyPoseSubscribers({ type: 'disconnected' });
}
}
);
return this.streamConnection;
}
// Stop pose stream
stopPoseStream() {
if (this.streamConnection) {
wsService.disconnect(this.streamConnection);
this.streamConnection = null;
}
}
// Subscribe to pose updates
subscribeToPoseUpdates(callback) {
this.poseSubscribers.push(callback);
// Return unsubscribe function
return () => {
const index = this.poseSubscribers.indexOf(callback);
if (index > -1) {
this.poseSubscribers.splice(index, 1);
}
};
}
// Handle pose stream messages
handlePoseMessage(data) {
const { type, payload } = data;
switch (type) {
case 'pose_data':
this.notifyPoseSubscribers({
type: 'pose_update',
data: payload
});
break;
case 'historical_data':
this.notifyPoseSubscribers({
type: 'historical_update',
data: payload
});
break;
case 'zone_statistics':
this.notifyPoseSubscribers({
type: 'zone_stats',
data: payload
});
break;
case 'system_event':
this.notifyPoseSubscribers({
type: 'system_event',
data: payload
});
break;
default:
console.log('Unknown pose message type:', type);
}
}
// Notify pose subscribers
notifyPoseSubscribers(update) {
this.poseSubscribers.forEach(callback => {
try {
callback(update);
} catch (error) {
console.error('Error in pose subscriber:', error);
}
});
}
// Start event stream
startEventStream(options = {}) {
if (this.eventConnection) {
console.warn('Event stream already active');
return this.eventConnection;
}
const params = {
event_types: options.eventTypes?.join(','),
zone_ids: options.zoneIds?.join(','),
token: options.token || apiService.authToken
};
// Remove undefined values
Object.keys(params).forEach(key =>
params[key] === undefined && delete params[key]
);
this.eventConnection = wsService.connect(
API_CONFIG.ENDPOINTS.STREAM.WS_EVENTS,
params,
{
onOpen: () => {
console.log('Event stream connected');
this.notifyEventSubscribers({ type: 'connected' });
},
onMessage: (data) => {
this.handleEventMessage(data);
},
onError: (error) => {
console.error('Event stream error:', error);
this.notifyEventSubscribers({ type: 'error', error });
},
onClose: () => {
console.log('Event stream disconnected');
this.eventConnection = null;
this.notifyEventSubscribers({ type: 'disconnected' });
}
}
);
return this.eventConnection;
}
// Stop event stream
stopEventStream() {
if (this.eventConnection) {
wsService.disconnect(this.eventConnection);
this.eventConnection = null;
}
}
// Subscribe to events
subscribeToEvents(callback) {
this.eventSubscribers.push(callback);
// Return unsubscribe function
return () => {
const index = this.eventSubscribers.indexOf(callback);
if (index > -1) {
this.eventSubscribers.splice(index, 1);
}
};
}
// Handle event stream messages
handleEventMessage(data) {
this.notifyEventSubscribers({
type: 'event',
data
});
}
// Notify event subscribers
notifyEventSubscribers(update) {
this.eventSubscribers.forEach(callback => {
try {
callback(update);
} catch (error) {
console.error('Error in event subscriber:', error);
}
});
}
// Update stream configuration
updateStreamConfig(connectionId, config) {
wsService.sendCommand(connectionId, 'update_config', config);
}
// Get stream status
requestStreamStatus(connectionId) {
wsService.sendCommand(connectionId, 'get_status');
}
// Clean up
dispose() {
this.stopPoseStream();
this.stopEventStream();
this.poseSubscribers = [];
this.eventSubscribers = [];
}
}
// Create singleton instance
export const poseService = new PoseService();