json(Device::select('id','slug','name','type','last_seen_at')->get()); } public function show(string $slug): JsonResponse { $d = Device::where('slug',$slug)->firstOrFail(); return response()->json($d); } public function latest(string $slug): JsonResponse { $d = Device::where('slug',$slug)->firstOrFail(); $sql = "SELECT metric, value, value_text, recorded_at FROM (SELECT metric, value, value_text, recorded_at, ROW_NUMBER() OVER (PARTITION BY metric ORDER BY recorded_at DESC) rn FROM readings WHERE device_id=?) t WHERE rn=1"; $rows = DB::select($sql, [$d->id]); $m = []; foreach ($rows as $r) { $m[$r->metric] = [ 'value' => $r->value !== null ? (float)$r->value : null, 'text' => $r->value_text, 'at' => $r->recorded_at, ]; } return response()->json(['device' => $d->only(['slug','name','last_seen_at']), 'metrics' => $m]); } public function history(string $slug, Request $r): JsonResponse { $d = Device::where('slug',$slug)->firstOrFail(); $metric = $r->query('metric'); $hours = min(168, max(1, (int)$r->query('hours', 24))); $since = now()->subHours($hours); $q = Reading::where('device_id',$d->id)->where('recorded_at','>=',$since); if ($metric) $q->where('metric',$metric); $rows = $q->orderBy('recorded_at')->limit(5000)->get(['metric','value','recorded_at']); return response()->json(['from'=>$since,'count'=>$rows->count(),'data'=>$rows]); } }