TKK_E32211395/website/resources/views/dashboard/index.blade.php

528 lines
21 KiB
PHP

@extends('dashboard.layouts.main')
@section('container')
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fetch/3.0.0/fetch.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap4-toggle@3.6.1/css/bootstrap4-toggle.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap4-toggle@3.6.1/js/bootstrap4-toggle.min.js"></script>
<div class="container-fluid pt-4 px-4">
<!-- Input untuk memilih token Blynk -->
<!-- <div class="card mb-4">
<div class="card-header">
<h4>Lokasi</h4>
</div>
<div class="card-body"> -->
<div class="input-group rounded-pill overflow-hidden mb-4">
<span class="input-group-text border-0 bg-lightgray">Pilih Lokasi</span>
<select class="form-select border-0 bg-light" name="blynkTokenInput" id="blynkTokenInput">
<option value="">Nama Lokasi</option>
@foreach($lokasi_monitoring as $lokasi)
<option value="{{ $lokasi->blynk_token }}" data-nama_lokasi="{{ $lokasi->nama_lokasi }}" data-alamat="{{ $lokasi->alamat }}" data-deskripsi="{{ $lokasi->deskripsi }}" data-owner="{{ $lokasi->user->name }}">{{ $lokasi->nama_lokasi }}</option>
@endforeach
</select>
<button id="btnPilih" class="btn btn-warning border-0"><i class="bx bx-search"></i> Cari</button>
</div>
<!-- </div>
</div> -->
<!-- Location Information -->
<div id="lokasiInfo" class="card mb-4">
<div class="card-header">
<h4>Informasi Lokasi</h4>
</div>
<div class="card-body rounded-bottom p-4">
<div class="d-flex align-items-center mb-3">
<i class="fa-solid fa-industry me-3"></i>
<p class="mb-0"><strong>Nama Lokasi:</strong> <span id="lokasiNama"></span></p>
</div>
<div class="d-flex align-items-center mb-3">
<i class="fa-solid fa-map-marker-alt me-3"></i>
<p class="mb-0"><strong>Alamat:</strong> <span id="lokasiAlamat"></span></p>
</div>
<div class="d-flex align-items-center mb-3">
<i class="fa-solid fa-clipboard me-3"></i>
<p class="mb-0"><strong>Deskripsi:</strong> <span id="lokasiDeskripsi"></span></p>
</div>
<div class="d-flex align-items-center mb-3">
<i class="fa-solid fa-user me-3"></i>
<p class="mb-0"><strong>Pemilik Kebun:</strong> <span id="lokasiOwner"></span></p>
</div>
</div>
</div>
<!-- Monitoring RealTime -->
<div class="card mb-4">
<div class="card-header">
<h4>Monitoring RealTime</h4>
</div>
<div class="card-body">
<div class="row g-4">
@php
$monitoring = [
['icon' => 'fa-bolt', 'label' => 'Voltage', 'id' => 'voltage', 'unit' => 'VA'],
['icon' => 'fa-bolt', 'label' => 'Power', 'id' => 'power', 'unit' => 'W'],
['icon' => 'fa-bolt', 'label' => 'Power Factor', 'id' => 'power_factor', 'unit' => ''],
['icon' => 'fa-bolt', 'label' => 'Energy', 'id' => 'energy', 'unit' => 'kWh'],
['icon' => 'fa-bolt', 'label' => 'Current', 'id' => 'current', 'unit' => 'A'],
['icon' => 'fa-money-bill', 'label' => 'Perkiraan Biaya Permenit', 'id' => 'biaya', 'unit' => 'Rupiah'],
];
@endphp
@foreach ($monitoring as $item)
<div class="col-sm-6 col-xl-3">
<div class="bg-light rounded-pill d-flex align-items-center justify-content-between p-4">
<i class="fa-solid {{ $item['icon'] }} fa-2xl text-warning"></i>
<div class="ms-3">
<p class="mb-2">{{ $item['label'] }}</p>
<h6 class="mb-0"><span id="{{ $item['id'] }}"></span> {{ $item['unit'] }}</h6>
</div>
</div>
</div>
@endforeach
</div>
</div>
</div>
<!-- Monitoring Kontrol -->
<div class="card mb-4">
<div class="card-header">
<h4>Monitoring Kontrol</h4>
</div>
<div class="card-body">
<div class="row g-4">
@php
$controls = [
['icon' => 'fa-plug', 'label' => 'Saklar', 'id' => 'otomatis'],
];
@endphp
@foreach ($controls as $control)
<div class="col-sm-6 col-xl-3">
<div class="bg-light rounded-pill p-4">
<div class="form-group mb-0">
<i class="fa-solid {{ $control['icon'] }} fa-1xl text-warning"></i>
<label for="{{ $control['id'] }}">{{ $control['label'] }}</label>
<input type="checkbox" checked data-toggle="toggle" data-on="On" data-off="Off" data-onstyle="primary" data-offstyle="danger" id="{{ $control['id'] }}" onchange="updateSaklar()">
</div>
</div>
</div>
@endforeach
</div>
</div>
</div>
<div class="container-fluid pt-4 px-4">
<div class="bg-light text-center rounded p-4">
<h6 class="mb-4">Data Sensor Chart</h6>
<form id="dataForm">
<div class="row align-items-center">
<div class="col-md-6 mb-2 mb-md-0">
<select id="lokasiDropdown" name="lokasi_id" class="form-control" required>
<option value="" disabled selected>Pilih Lokasi</option>
</select>
</div>
<div class="col-md-4 mb-2 mb-md-0">
<select id="range" name="range" class="form-control">
<option value="1jam">1 Jam</option>
<option value="1hari">1 Hari</option>
<option value="1minggu">1 Minggu</option>
<option value="1bulan">1 Bulan</option>
</select>
</div>
<div class="col-md-2">
<button type="submit" class="btn btn-warning btn-block">Search</button>
</div>
</div>
</form>
<canvas id="dataChart" class="mt-4"></canvas>
<div class="mt-4">
<h5>Total Biaya Per Hari: <span id="totalBiaya"></span> Rupiah</h5>
</div>
</div>
</div>
<!-- Table Update -->
<div class="container-fluid pt-4 px-4">
<div class="bg-light text-center rounded p-4">
<div class="d-flex align-items-center justify-content-between mb-4">
<h6 class="mb-0">Riwayat Monitoring Terbaru</h6>
<a href="/dashboard/controls" class="text-warning">Lihat Semua</a>
</div>
<div class="table-responsive">
<table class="table text-start align-middle table-bordered table-hover mb-0">
<thead>
<tr class="text-dark">
<th scope="col">Tanggal</th>
<th scope="col">Pukul</th>
<th scope="col">Voltage(VA)</th>
<th scope="col">Power(W)</th>
<th scope="col">Power Factor</th>
<th scope="col">Energy(kWh)</th>
<th scope="col">Current(A)</th>
<th scope="col">Biaya(Rp)</th>
</tr>
</thead>
<tbody>
@foreach($sensor_data as $data)
<tr>
<td>{{ $data->created_at->format('Y-m-d') }}</td>
<td>{{ $data->created_at->format('H:i') }}</td>
<td>{{ $data->voltage }}</td>
<td>{{ $data->power }}</td>
<td>{{ $data->power_factor }}</td>
<td>{{ $data->energy }}</td>
<td>{{ $data->current }}</td>
<td>{{ $data->biaya }}</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
</div>
@include('dashboard.realtime')
<!-- Table Update End -->
<script>
document.addEventListener('DOMContentLoaded', function() {
fetchLokasi();
});
function fetchLokasi() {
fetch('/get-lokasi-by-user')
.then(response => response.json())
.then(data => {
const lokasiDropdown = document.getElementById('lokasiDropdown');
lokasiDropdown.innerHTML = ''; // Clear previous options
// Add initial option
const initialOption = document.createElement('option');
initialOption.value = '';
initialOption.disabled = true;
initialOption.selected = true;
initialOption.textContent = 'Pilih Lokasi';
lokasiDropdown.appendChild(initialOption);
// Add options for each lokasi
data.forEach(lokasi => {
const option = document.createElement('option');
option.value = lokasi.id;
option.textContent = lokasi.nama_lokasi;
lokasiDropdown.appendChild(option);
});
})
.catch(error => console.error('Error fetching lokasi data:', error));
}
let chartInstance = null;
document.getElementById('dataForm').addEventListener('submit', function(event) {
event.preventDefault();
fetchData();
});
function fetchData() {
const lokasiId = document.getElementById('lokasiDropdown').value;
const range = document.getElementById('range').value;
fetch(`/get-data?lokasi_id=${lokasiId}&range=${range}`)
.then(response => response.json())
.then(data => {
renderChart(data, range);
})
.catch(error => console.error('Error fetching data:', error));
}
function renderChart(data, range) {
if (!data || data.length === 0) {
alert('No data available');
return;
}
const labels = data.map(item => range === '1jam' ? item.created_at : item.date);
const voltage = data.map(item => item.avg_voltage);
const power = data.map(item => item.avg_power);
const powerFactor = data.map(item => item.avg_power_factor);
const energy = data.map(item => item.avg_energy);
const current = data.map(item => item.avg_current);
const biaya = data.map(item => item.sum_biaya);
const ctx = document.getElementById('dataChart').getContext('2d');
// Clear previous chart instance
if (chartInstance) {
chartInstance.destroy();
}
chartInstance = new Chart(ctx, {
type: 'bar',
data: {
labels: labels,
datasets: [
{
label: 'Voltage',
data: voltage,
backgroundColor: 'rgba(75, 192, 192, 0.2)',
borderColor: 'rgba(75, 192, 192, 1)',
borderWidth: 1
},
{
label: 'Power',
data: power,
backgroundColor: 'rgba(54, 162, 235, 0.2)',
borderColor: 'rgba(54, 162, 235, 1)',
borderWidth: 1
},
{
label: 'Power Factor',
data: powerFactor,
backgroundColor: 'rgba(255, 206, 86, 0.2)',
borderColor: 'rgba(255, 206, 86, 1)',
borderWidth: 1
},
{
label: 'Energy',
data: energy,
backgroundColor: 'rgba(153, 102, 255, 0.2)',
borderColor: 'rgba(153, 102, 255, 1)',
borderWidth: 1
},
{
label: 'Current',
data: current,
backgroundColor: 'rgba(255, 159, 64, 0.2)',
borderColor: 'rgba(255, 159, 64, 1)',
borderWidth: 1
},
{
label: 'Biaya',
data: biaya,
backgroundColor: 'rgba(255, 99, 132, 0.2)',
borderColor: 'rgba(255, 99, 132, 1)',
borderWidth: 1
}
]
},
options: {
scales: {
y: {
beginAtZero: true
}
}
}
});
// Display total biaya only when range is '1bulan'
if (range === '1bulan') {
const totalBiaya = biaya.reduce((sum, currentBiaya) => sum + currentBiaya, 0);
const formattedBiaya = Math.floor(totalBiaya).toLocaleString('en-US', { maximumFractionDigits: 0 });
document.getElementById('totalBiaya').textContent = formattedBiaya;
document.getElementById('totalBiayaContainer').style.display = 'block'; // Show total biaya container
} else {
document.getElementById('totalBiayaContainer').style.display = 'none'; // Hide total biaya container if range is not '1bulan'
}
}
</script>
<script>
let previousToken = localStorage.getItem('previousToken');
let pollingIntervalId = null;
let currentToken = null;
function updateLokasiInfo(token) {
const selectedOption = $('#blynkTokenInput option:selected');
$('#lokasiNama').text(selectedOption.data('nama_lokasi'));
$('#lokasiAlamat').text(selectedOption.data('alamat'));
$('#lokasiDeskripsi').text(selectedOption.data('deskripsi'));
$('#lokasiOwner').text(selectedOption.data('owner'));
$('#lokasiInfo').show();
}
document.getElementById('btnPilih').addEventListener('click', function() {
var selectedToken = document.getElementById('blynkTokenInput').value;
if (selectedToken === "") {
resetBlynkDataToZero(); // Panggil reset jika token kosong
selectedToken = "Data Buatan";
}
if (selectedToken !== previousToken) {
console.log('Token Blynk yang baru dipilih:', selectedToken);
if (previousToken) {
localStorage.removeItem(previousToken);
}
localStorage.setItem('previousToken', selectedToken);
previousToken = selectedToken;
currentToken = selectedToken;
if (pollingIntervalId !== null) {
clearInterval(pollingIntervalId);
pollingIntervalId = null;
}
updateBlynkData(selectedToken);
} else {
console.log('Token Blynk yang dipilih sama dengan token sebelumnya:', selectedToken);
}
updateLokasiInfo(selectedToken);
updateBlynkValues(selectedToken);
if (previousToken) {
updateBlynkData(previousToken);
}
});
// Call the function to fetch daily cost when the page loads
//document.addEventListener('DOMContentLoaded', fetchDailyCost);
function resetBlynkDataToZero() {
console.log('Resetting Blynk data to 0');
document.getElementById('voltage').textContent = '0';
document.getElementById('power').textContent = '0';
document.getElementById('power_factor').textContent = '0';
document.getElementById('energy').textContent = '0';
document.getElementById('current').textContent = '0';
document.getElementById('biaya').textContent = '0';
$('#otomatis').bootstrapToggle('off');
}
function updateBlynkData(token) {
currentToken = token;
const pollingInterval = 1000;
updateLokasiInfo(token);
pollingIntervalId = setInterval(() => {
fetchBlynkData('v2', token, 'voltage');
fetchBlynkData('v3', token, 'current');
fetchBlynkData('v4', token, 'power_factor');
fetchBlynkData('v5', token, 'power');
fetchBlynkData('v6', token, 'energy');
fetchBlynkData('v7', token, 'biaya');
fetchBlynkData('v1', token, 'otomatis', (value) => $('#otomatis').bootstrapToggle(value === '1' ? 'on' : 'off'));
}, pollingInterval);
}
function fetchBlynkData(pin, token, elementId, transform = (value) => value) {
if (token !== currentToken) {
return;
}
const apiUrl = `https://blynk.cloud/external/api/get?token=${token}&pin=${pin}`;
console.log(`Fetching data from ${apiUrl}`);
fetch(apiUrl, { method: 'GET' })
.then(response => {
console.log(`Response status for pin ${pin}: ${response.status}`);
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.text();
})
.then(data => {
console.log(`Data for pin ${pin}: ${data}`);
if (token === currentToken) {
const transformedValue = transform(data);
document.getElementById(elementId).textContent = transformedValue;
console.log(`Updated element ${elementId} with value: ${transformedValue}`);
}
})
.catch(error => {
console.error(`Failed to fetch data for pin ${pin}:`, error);
});
}
function updateBlynkValues(token) {
getBlynkValue('v1', token);
getBlynkValueString('v2', token);
getBlynkValueString('v3', token);
getBlynkValueString('v4', token);
getBlynkValueString('v5', token);
getBlynkValueString('v6', token);
getBlynkValueString('v7', token);
}
$(document).ready(function() {
// Reset page state on refresh
$('#blynkTokenInput').val('');
resetBlynkDataToZero();
$('#blynkTokenInput').on('change', function() {
const selectedToken = $(this).val();
updateBlynkData(selectedToken);
});
$('#otomatis').change(function() {
updateSaklar();
});
});
function updateSaklar() {
let token = localStorage.getItem('previousToken');
if (!token) {
console.error('Token Blynk tidak tersedia di local storage.');
return;
}
let otomatisStatus = document.getElementById('otomatis').checked ? 1 : 0;
updateBlynkPin(token, 'v1', otomatisStatus);
}
function updateBlynkPin(token, pin, value) {
const apiUrl = `https://blynk.cloud/external/api/update?token=${token}&${pin}=${value}`;
console.log(`Updating pin ${pin} to ${value} with URL ${apiUrl}`);
fetch(apiUrl, { method: 'GET' })
.then(response => {
console.log(`Update response for pin ${pin}: ${response.status}`);
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.text();
})
.then(data => {
console.log(`Pin ${pin} updated to ${value}`);
})
.catch(error => {
console.error(`Failed to update pin ${pin}:`, error);
});
}
function getBlynkValue(pin, token) {
const apiUrl = `https://blynk.cloud/external/api/get?token=${token}&pin=${pin}`;
console.log(`Getting value for pin ${pin} from URL ${apiUrl}`);
fetch(apiUrl, { method: 'GET' })
.then(response => {
console.log(`Get value response for pin ${pin}: ${response.status}`);
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.text();
})
.then(data => {
console.log(`Value from Blynk for pin ${pin}: ${data}`);
})
.catch(error => {
console.error(`Failed to get value for pin ${pin}:`, error);
});
}
function getBlynkValueString(pin, token) {
const apiUrl = `https://blynk.cloud/external/api/get?token=${token}&pin=${pin}`;
console.log(`Getting value for pin ${pin} from URL ${apiUrl}`);
fetch(apiUrl, { method: 'GET' })
.then(response => {
console.log(`Get value response for pin ${pin}: ${response.status}`);
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.text();
})
.then(data => {
console.log(`Value from Blynk for pin ${pin}: ${data}`);
})
.catch(error => {
console.error(`Failed to get value for pin ${pin}:`, error);
});
}
</script>
@endsection