import { Response } from "express"; import { eventManager, logger } from "../app"; import { LivebeatRequest } from "../lib/request"; import { IBeat } from "../models/beat/beat.interface"; import { Beat } from "../models/beat/beat.model."; import { ISeverity } from "../models/notifications/notification.interface"; import { Phone } from "../models/phone/phone.model"; const timeouts: Map = new Map(); export async function GetBeatStats(req: LivebeatRequest, res: Response) { const phones = await Phone.find({ user: req.user?._id }); const perPhone: any = {}; let totalBeats = 0; for (let i = 0; i < phones.length; i++) { const beatCount = await Beat.countDocuments({ phone: phones[i] }); perPhone[phones[i]._id] = {}; perPhone[phones[i]._id] = beatCount; totalBeats += beatCount; } res.status(200).send({ totalBeats, perPhone }); } export async function GetBeat(req: LivebeatRequest, res: Response) { const from: number = Number(req.query.from || 0); const to: number = Number(req.query.to || Date.now() / 1000); const limit: number = Number(req.query.limit || 10000); const sort: number = Number(req.query.sort || 1); // Either -1 or 1 const phoneId = req.query.phoneId; // Grab default phone if non was provided. const phone = req.query.phone === undefined ? await Phone.findOne({ user: req.user?._id }) : await Phone.findOne({ _id: phoneId, user: req.user?._id }); let beats: IBeat[] = []; //console.log(from, to); //console.log(`Search from ${new Date(from).toString()} to ${new Date(to * 1000).toString()}`); if (phone !== null) { beats = await Beat.find( { phone: phone._id, createdAt: { $gte: new Date((from)), $lte: new Date(to * 1000) } }).sort({ _id: sort }).limit(limit); res.status(200).send(beats); } else { res.status(404).send({ message: 'Phone not found' }); } } export async function AddBeat(req: LivebeatRequest, res: Response) { const beat = req.body as IBeat; const androidId = req.headers.deviceId as string; if (androidId === undefined) { res.status(401).send({ message: 'Device id is missing' }); } // Get phone const phone = await Phone.findOne({ androidId }); if (phone == undefined) { logger.warning(`Received beat from unknown device with id ${androidId}`); return; } let newBeat; if (beat.coordinate !== undefined && beat.accuracy !== undefined) { logger.info(`New beat from ${phone.displayName} => ${beat.coordinate[0]}, ${beat.coordinate[1]} | Height: ${beat.coordinate[3]}m | Speed: ${beat.coordinate[4]} | Accuracy: ${beat.accuracy}% | Battery: ${beat.battery}%`); newBeat = await Beat.create({ phone: phone._id, // [latitude, longitude, altitude] coordinate: [beat.coordinate[0], beat.coordinate[1], beat.coordinate[2]], accuracy: beat.coordinate[3], speed: beat.coordinate[4], battery: beat.battery, createdAt: Date.now() }); } newBeat = await Beat.create({ phone: phone._id, battery: beat.battery, createdAt: Date.now() }); // Broadcast if device became active if (timeouts.has(phone.id)) { clearTimeout(timeouts.get(phone.id)!!); } else { phone.active = true; await phone.save(); eventManager.push('phone_alive', phone.toJSON(), phone.user); } const timeoutTimer = setTimeout(async () => { eventManager.push('phone_dead', phone.toJSON(), phone.user, ISeverity.WARN); timeouts.delete(phone.id); phone.active = false; await phone.save(); }, 60_000); timeouts.set(phone.id, timeoutTimer); eventManager.push('beat', newBeat.toJSON(), phone.user); }