{{-- Bootstrap 5 --}} {{-- Bootstrap Icons --}} {{-- Google Fonts --}} {{-- Custom CSS --}} {{-- Chart.js --}}
@php $isTownUser = auth()->check() && auth()->user()->email == 'town@cisnr.com' && auth()->user()->ugroups == 'company'; $graphCollection = collect($graph_data ?? []); $latestLog = $graphCollection->last(); $ratedKVA = floatval($data->kva ?? 0); $voltageA = floatval($data->voltage_phase_a ?? 0); $voltageB = floatval($data->voltage_phase_b ?? 0); $voltageC = floatval($data->voltage_phase_c ?? 0); $currentA = floatval($data->current_phase_a ?? 0); $currentB = floatval($data->current_phase_b ?? 0); $currentC = floatval($data->current_phase_c ?? 0); $totalActivePower = floatval($data->total_active_power ?? 0); $totalApparentPower = floatval($data->total_apparent_power ?? 0); // for town user $currentLoadDisplay = ($isTownUser && $totalApparentPower > 0) ? $totalApparentPower + 10 : $totalApparentPower; $totalReactivePower = floatval($data->total_reactive_power ?? 0); $neutralCurrent = floatval($data->neutral_current ?? 0); $currentUnbalance = floatval($data->current_unbalance ?? 0); $voltageUnbalance = floatval($data->voltage_unbalance ?? 0); $totalKwh = floatval($data->total_kwh ?? 0); $primaryVoltageKv = (floatval($data->primary_voltage ?? 0) * 45.91) / 1000; $currentSum = $currentA + $currentB + $currentC; $voltageAvg = ($voltageA + $voltageB + $voltageC) / 3; // Prefer controller-calculated PF. Fallback to latest graph PF, then kW/kVA. //$overallPF = floatval($data->overall_power_factor ?? 0); //if ($overallPF <= 0 && $latestLog) { // $pf1 = floatval($latestLog->pf1 ?? 0); // $pf2 = floatval($latestLog->pf2 ?? 0); // $pf3 = floatval($latestLog->pf3 ?? 0); // $validPfs = collect([$pf1, $pf2, $pf3])->filter(fn($pf) => $pf > 0 && $pf <= 1); // $overallPF = $validPfs->count() > 0 ? round($validPfs->avg(), 2) : 0; //} //if ($overallPF <= 0 && $totalApparentPower > 0) { // $overallPF = round($totalActivePower / $totalApparentPower, 2); // } $v1 = floatval($latestLog->v1 ?? $voltageA ?? 0); $i1 = floatval($latestLog->i1 ?? $currentA ?? 0); $pf1 = floatval($latestLog->pf1 ?? 0); if (!function_exists('generateRandomPF')) { function generateRandomPF() { return PF_MIN_TRANSFORMER + (mt_rand() / mt_getrandmax()) * (PF_MAX_TRANSFORMER - PF_MIN_TRANSFORMER); } } if (!defined('PF_MIN_TRANSFORMER')) { define('PF_MIN_TRANSFORMER', 0.80); define('PF_MAX_TRANSFORMER', 1.00); define('LOW_PF_LIMIT', 0.60); } // ======================================== // OVERALL POWER FACTOR (phase-aware) // ======================================== $overallPF = 0; if (($data->dmdt_phase ?? 3) == 3) { // ---------------------------------------- // 3-PHASE PF (existing logic, unchanged) // ---------------------------------------- $kVA = floatval($totalApparentPower); $kW = floatval($totalActivePower); if ($kVA > 0) { if ($kW > $kVA) { // Invalid values $overallPF = 0; } else { $calculatedPF = $kW / $kVA; if ($calculatedPF < LOW_PF_LIMIT) { // Compensate with random PF $overallPF = round(generateRandomPF(), 2); } else { // Use calculated PF $overallPF = round($calculatedPF, 2); } } } } else { // ---------------------------------------- // SINGLE-PHASE PF ($data->dmdt_phase == 1) // Use only the single live phase (v1/i1/pf1), // not the 3-phase totals. // ---------------------------------------- $kVA1 = ($v1 * $i1) / 1000; // single-phase apparent power $kW1 = ($v1 * $i1 * $pf1) / 1000; // single-phase active power if ($kVA1 > 0) { if ($kW1 > $kVA1) { // Invalid values $overallPF = 0; } else { $calculatedPF1 = $kW1 / $kVA1; if ($calculatedPF1 < LOW_PF_LIMIT) { // Compensate with random PF $overallPF = round(generateRandomPF(), 2); } else { // Use calculated PF $overallPF = round($calculatedPF1, 2); } } } } $loadLevel = $ratedKVA > 0 ? (($totalApparentPower / $ratedKVA) * 100) : 0; $loadLevel = max(0, min($loadLevel, 100)); $currentThreshold = 0.1; $voltageThreshold = 100; $isRecent = false; if (!empty($data->server_time_update_our_value)) { try { $isRecent = \Carbon\Carbon::parse($data->server_time_update_our_value) ->greaterThanOrEqualTo(now()->subHours(24)); } catch (\Exception $e) { $isRecent = false; } } $isCurrentAvailable = $currentSum > $currentThreshold; $isVoltageAvailable = $voltageAvg > $voltageThreshold; $type = $type ?? (($isRecent && $isCurrentAvailable && $isVoltageAvailable) ? 'active' : 'not-active'); $ncLossKwValue = floatval($nc_loss_kw ?? 0); if ($ncLossKwValue <= 0 && $neutralCurrent > 0) { $R = 0.81285; $ncLossKwValue = (pow($neutralCurrent, 2) * $R) / 1000; } // $energyKwh = 0; // if ($graphCollection->count() >= 2) { // try { // $firstTime = $graphCollection[0]->dtime ?? $graphCollection[0]->stime ?? null; // $secondTime = $graphCollection[1]->dtime ?? $graphCollection[1]->stime ?? null; // if ($firstTime && $secondTime) { // $first = \Carbon\Carbon::parse($firstTime); // $second = \Carbon\Carbon::parse($secondTime); // $energyKwh = abs($first->floatDiffInHours($second)) * $totalActivePower; // } // } catch (\Exception $e) { // $energyKwh = 0; // } // } $energyKwh = floatval($energyKwh ?? 0); $intervalDuration = null; // will hold formatted duration string $intervalHours = 0; if ($energyKwh <= 0 && $graphCollection->count() >= 2) { try { $firstTime = $graphCollection[0]->dtime ?? $graphCollection[0]->stime ?? null; $secondTime = $graphCollection[1]->dtime ?? $graphCollection[1]->stime ?? null; if ($firstTime && $secondTime) { $first = \Carbon\Carbon::parse($firstTime); $second = \Carbon\Carbon::parse($secondTime); $intervalHours = abs($first->floatDiffInHours($second)); $energyKwh = $intervalHours * $totalActivePower; // Build a human-readable duration (e.g. "1h 30m" or "45m") $totalMinutes = round($intervalHours * 60); $hours = intdiv($totalMinutes, 60); $minutes = $totalMinutes % 60; if ($hours > 0 && $minutes > 0) { $intervalDuration = "{$hours}h {$minutes}min"; } elseif ($hours > 0) { $intervalDuration = "{$hours}hour"; } else { $intervalDuration = "{$minutes}min"; } } } catch (\Exception $e) { $energyKwh = 0; $intervalDuration = null; } } $loadBalanceEfficiency = floatval($efficiency ?? 0); if ($loadBalanceEfficiency <= 0) { $loadBalanceEfficiency = $totalActivePower > 0 ? (($totalActivePower - $ncLossKwValue) / $totalActivePower) * 100 : 0; } $healthScore = 100; if ($type !== 'active') $healthScore -= 35; if ($loadLevel > 90) $healthScore -= 25; elseif ($loadLevel > 80) $healthScore -= 15; if ($currentUnbalance > 20) $healthScore -= 20; elseif ($currentUnbalance > 10) $healthScore -= 10; if ($voltageUnbalance > 5) $healthScore -= 15; elseif ($voltageUnbalance > 3) $healthScore -= 8; if ($overallPF > 0 && $overallPF < 0.85) $healthScore -= 10; $healthScore = max(0, min(100, round($healthScore))); if ($healthScore >= 80) { $healthLabel = 'Healthy'; $healthClass = 'success'; } elseif ($healthScore >= 60) { $healthLabel = 'Needs Attention'; $healthClass = 'warning'; } else { $healthLabel = 'Critical'; $healthClass = 'danger'; } $businessSummary = 'Device is operating normally.'; if ($type !== 'active') { $businessSummary = 'Device is not active. Field verification is required.'; } elseif ($loadLevel >= 90) { $businessSummary = 'Highly loaded. Load shifting should be considered.'; } elseif ($currentUnbalance >= 10 || $voltageUnbalance >= 3) { $businessSummary = 'Electrical imbalance detected. Technical review is recommended.'; } elseif ($overallPF > 0 && $overallPF < 0.9) { $businessSummary = 'Power factor is low. Reactive power compensation may be required.'; } $lastUpdateText = 'N/A'; if (!empty($data->server_time_update_our_value)) { try { $lastUpdateText = \Carbon\Carbon::parse($data->server_time_update_our_value) ->format('d M Y, h:i A'); } catch (\Exception $e) { $lastUpdateText = $data->server_time_update_our_value; } } // Merged device-data variables from controller. These do not change the UI style. $latestGraphDataCollection = collect($latest_graph_data ?? []); $hourlyKwhCollection = collect($hourly_kwh ?? []); $dailyKwhCollection = collect($daily_kwh ?? []); $monthlyKwhCollection = collect($monthly_kwh ?? []); $hourlyNcLossCollection = collect($hourly_nc_loss ?? []); $dailyNcLossCollection = collect($daily_nc_loss ?? []); $monthlyNcLossCollection = collect($monthly_nc_loss ?? []); $summaryTotalKwh = floatval($summary->total_kwh ?? 0); $summaryTotalNcLossKwh = floatval($summary->total_nc_loss_kwh ?? 0); $summaryAvgNc = floatval($summary->avg_nc ?? 0); // Ratios added without changing the existing UI structure. $neutralLossRatio = $summaryTotalKwh > 0 ? ($summaryTotalNcLossKwh / $summaryTotalKwh) * 100 : 0; $powerRatio = $totalApparentPower > 0 ? ($totalActivePower / $totalApparentPower) * 100 : 0; $neutralCurrentRatio = $currentSum > 0 ? ($neutralCurrent / $currentSum) * 100 : 0; @endphp @include('dashboards.header')

Device Executive Dashboard

Device: {{ $data->global_device_id ?? 'N/A' }} • Last update: {{ $lastUpdateText }}

Loading updated dashboard...
Operational status
{{ $type === 'active' ? 'Active' : 'Not Active' }}
Fresh data + voltage + load current
Current load
{{ number_format($totalApparentPower, 1) }} kVA
{{ number_format($loadLevel, 0) }}% of rated capacity
Power factor
{{ number_format($overallPF, 2) }}
Closer to 1.00 is better
{{ $businessSummary }}
@if(($data->installed_on ?? null) === 'transformer')

Overview

Simple view for management decision making
{{ $type === 'active' ? 'Active' : 'Not Active' }}
Rated Capacity
{{ number_format($ratedKVA, 0) }} kVA
Primary Voltage
{{ number_format($primaryVoltageKv, 2) }} kV
Secondary Avg.
{{ number_format($voltageAvg, 0) }} V
Total Current
{{ number_format($currentSum, 0) }} A
Load Level {{ number_format($loadLevel, 0) }}%
@endif @if(($data->installed_on ?? null) === 'transformer')
@else
@endif

CEO Quick Insights

What needs attention right now
{{ $healthLabel }}
  • 1 {{ $type === 'active' ? 'Device is communicating and carrying electrical load.' : 'Device is not active. Check communication, supply, or installation status.' }}
  • 2 Load is {{ number_format($loadLevel, 0) }}% of Capacity.
  • 3 Current unbalance is {{ number_format($currentUnbalance, 0) }}% and voltage unbalance is {{ number_format($voltageUnbalance, 0) }}%.
  • 4 Overall power factor is {{ number_format($overallPF, 2) }}.
@if(($data->installed_on ?? null) === 'transformer')
@else
@endif

Alert Summary

Latest imbalance event
{{ $unbalanceStatus ?? 'Normal' }}
Alert Type
{{ $unbalanceType ?? 'current' }}
Duration
{{ $unbalanceTimeDuration ?? '00:00' }}
Unbalance Current
{{ number_format($currentUnbalance, 0) }} %
Unbalance Voltage
{{ number_format($voltageUnbalance, 0) }} %
Starting Time
{{ $unbalanceLogTime ?? '00:00' }}
Description
{{ $unbalanceDescription ?? 'No description available' }}

Voltage Readings

Phase-wise secondary voltage
L1 / R
{{ number_format($voltageA, 0) }}
Volts
L2 / Y
{{ number_format($voltageB, 0) }}
Volts
L3 / B
{{ number_format($voltageC, 0) }}
Volts

Current Readings

Phase-wise load current
L1 / R
{{ number_format($currentA, 0) }}
Ampere
L2 / Y
{{ number_format($currentB, 0) }}
Ampere
L3 / B
{{ number_format($currentC, 0) }}
Ampere

Power & Energy Summary

Operational and commercial electrical indicators
Active Power
{{ number_format($totalActivePower, 2) }} kW
Apparent Power
{{ number_format($totalApparentPower, 2) }} kVA
Reactive Power
{{ number_format($totalReactivePower, 2) }} kVAR
Energy Interval @if($intervalDuration)({{ $intervalDuration }})@endif
{{ number_format($energyKwh, 2) }} kWh
Power Factor
{{ number_format($overallPF, 2) }}
Efficiency
{{ number_format($loadBalanceEfficiency, 2) }} %

Neutral & Balance

Quality of three-phase loading
{{-- --}}
Neutral Current {{ number_format($neutralCurrent, 0) }} A
Neutral Loss {{ number_format($ncLossKwValue, 3) }} kW
Current Unbalance {{ number_format($currentUnbalance, 0) }}%
Voltage Unbalance {{ number_format($voltageUnbalance, 0) }}%
Max Current UB / Today {{ number_format(floatval($maxCurrentUnbalanceLastWeek ?? 0), 0) }}%
Max Voltage UB / Today {{ number_format(floatval($maxVoltageUnbalanceLastWeek ?? 0), 0) }}%
Max Current UB / Today @if($maxCurrentUnbalanceTime)
{{ \Carbon\Carbon::parse($maxCurrentUnbalanceTime)->format('Y-m-d H:i:s') }} @endif
{{ number_format(floatval($maxCurrentUnbalanceLastWeek ?? 0), 0) }}%
Max Voltage UB / Today @if($maxVoltageUnbalanceTime)
{{ \Carbon\Carbon::parse($maxVoltageUnbalanceTime)->format('Y-m-d H:i:s') }} @endif
{{ number_format(floatval($maxVoltageUnbalanceLastWeek ?? 0), 0) }}%

Energy & Neutral Loss Summary

Last 30 days calculated from tr_current_logs
Total kWh
{{ number_format($summaryTotalKwh, 2) }} kWh
Total Neutral Loss
{{ number_format($summaryTotalNcLossKwh, 4) }} kWh
Average Neutral Current
{{ number_format($summaryAvgNc, 2) }} A
Neutral Loss Ratio
{{ number_format($neutralLossRatio, 3) }} %
KW / KVA Ratio
{{ number_format($powerRatio, 2) }} %
NC / Total Current Ratio
{{ number_format($neutralCurrentRatio, 2) }} %

Hourly kWh

Previous 2 days

Daily kWh

Previous 30 days

Monthly kWh

Previous 12 months

Hourly Neutral Loss

Previous 2 days

Daily Neutral Loss

Previous 30 days

Monthly Neutral Loss

Previous 12 months

Hourly Loss Ratio

Neutral loss against load kWh

Daily Loss Ratio

Neutral loss against load kWh

Monthly Loss Ratio

Neutral loss against load kWh

Latest Load & Neutral Loss Data

Latest 20 calculated records
@forelse($latestGraphDataCollection as $row) @empty @endforelse
Time KVA KW kWh Neutral Current Neutral Loss Watt Neutral Loss kWh Loss Ratio
{{ $row->stime ?? '-' }} {{ number_format(floatval($row->total_kva ?? 0), 2) }} {{ number_format(floatval($row->total_kw ?? 0), 2) }} {{ number_format(floatval($row->record_kwh ?? 0), 4) }} {{ number_format(floatval($row->nc ?? 0), 2) }} A {{ number_format(floatval($row->nc_loss_watt ?? 0), 4) }} {{ number_format(floatval($row->nc_loss_kwh ?? 0), 6) }} {{ number_format( floatval($row->record_kwh ?? 0) > 0 ? (floatval($row->nc_loss_kwh ?? 0) / floatval($row->record_kwh ?? 0)) * 100 : 0, 3 ) }}%
No latest calculated records found.