lazy commit
This commit is contained in:
BIN
assets/images/printer-icon.png
Normal file
BIN
assets/images/printer-icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 76 KiB |
5
composer.json
Normal file
5
composer.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"require": {
|
||||
"php-mqtt/client": "^2.2"
|
||||
}
|
||||
}
|
||||
189
composer.lock
generated
Normal file
189
composer.lock
generated
Normal file
@@ -0,0 +1,189 @@
|
||||
{
|
||||
"_readme": [
|
||||
"This file locks the dependencies of your project to a known state",
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "447c16b903c1f7b070e4b4bfb41716da",
|
||||
"packages": [
|
||||
{
|
||||
"name": "myclabs/php-enum",
|
||||
"version": "1.8.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/myclabs/php-enum.git",
|
||||
"reference": "a867478eae49c9f59ece437ae7f9506bfaa27483"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/myclabs/php-enum/zipball/a867478eae49c9f59ece437ae7f9506bfaa27483",
|
||||
"reference": "a867478eae49c9f59ece437ae7f9506bfaa27483",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"php": "^7.3 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^9.5",
|
||||
"squizlabs/php_codesniffer": "1.*",
|
||||
"vimeo/psalm": "^4.6.2"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"MyCLabs\\Enum\\": "src/"
|
||||
},
|
||||
"classmap": [
|
||||
"stubs/Stringable.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "PHP Enum contributors",
|
||||
"homepage": "https://github.com/myclabs/php-enum/graphs/contributors"
|
||||
}
|
||||
],
|
||||
"description": "PHP Enum implementation",
|
||||
"homepage": "http://github.com/myclabs/php-enum",
|
||||
"keywords": [
|
||||
"enum"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/myclabs/php-enum/issues",
|
||||
"source": "https://github.com/myclabs/php-enum/tree/1.8.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/mnapoli",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/myclabs/php-enum",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-08-04T09:53:51+00:00"
|
||||
},
|
||||
{
|
||||
"name": "php-mqtt/client",
|
||||
"version": "v2.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-mqtt/client.git",
|
||||
"reference": "8042ad93e72da8666e27168dc90670e45bdea274"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-mqtt/client/zipball/8042ad93e72da8666e27168dc90670e45bdea274",
|
||||
"reference": "8042ad93e72da8666e27168dc90670e45bdea274",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"myclabs/php-enum": "^1.7",
|
||||
"php": "^8.0",
|
||||
"psr/log": "^1.1|^2.0|^3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/php-invoker": "^3.0",
|
||||
"phpunit/phpunit": "^9.0",
|
||||
"squizlabs/php_codesniffer": "^3.5"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-redis": "Required for the RedisRepository"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"PhpMqtt\\Client\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Marvin Mall",
|
||||
"email": "marvin-mall@msn.com",
|
||||
"role": "developer"
|
||||
}
|
||||
],
|
||||
"description": "An MQTT client written in and for PHP.",
|
||||
"keywords": [
|
||||
"client",
|
||||
"mqtt",
|
||||
"publish",
|
||||
"subscribe"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/php-mqtt/client/issues",
|
||||
"source": "https://github.com/php-mqtt/client/tree/v2.2.0"
|
||||
},
|
||||
"time": "2024-11-24T20:54:32+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/log",
|
||||
"version": "3.0.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-fig/log.git",
|
||||
"reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3",
|
||||
"reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.0.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "3.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Psr\\Log\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "PHP-FIG",
|
||||
"homepage": "https://www.php-fig.org/"
|
||||
}
|
||||
],
|
||||
"description": "Common interface for logging libraries",
|
||||
"homepage": "https://github.com/php-fig/log",
|
||||
"keywords": [
|
||||
"log",
|
||||
"psr",
|
||||
"psr-3"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/php-fig/log/tree/3.0.2"
|
||||
},
|
||||
"time": "2024-09-11T13:17:53+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [],
|
||||
"aliases": [],
|
||||
"minimum-stability": "stable",
|
||||
"stability-flags": {},
|
||||
"prefer-stable": false,
|
||||
"prefer-lowest": false,
|
||||
"platform": {},
|
||||
"platform-dev": {},
|
||||
"plugin-api-version": "2.6.0"
|
||||
}
|
||||
@@ -2,6 +2,6 @@
|
||||
session_start();
|
||||
session_unset();
|
||||
session_destroy();
|
||||
header("Location: /login.php");
|
||||
header("Location: login.php");
|
||||
exit();
|
||||
?>
|
||||
|
||||
249
public/viewPrinters.php
Normal file
249
public/viewPrinters.php
Normal file
@@ -0,0 +1,249 @@
|
||||
<?php include '../src/session_check.php'; ?>
|
||||
|
||||
<html lang="en" data-bs-theme="light">
|
||||
<head>
|
||||
<!-- Required meta tags -->
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<!--favicon-->
|
||||
<link rel="icon" href="../assets/images/favicon-32x32.png" type="image/png">
|
||||
<!--plugins-->
|
||||
<link href="../assets/plugins/vectormap/jquery-jvectormap-2.0.2.css" rel="stylesheet">
|
||||
<link href="../assets/plugins/simplebar/css/simplebar.css" rel="stylesheet">
|
||||
<link href="../assets/plugins/perfect-scrollbar/css/perfect-scrollbar.css" rel="stylesheet">
|
||||
<link href="../assets/plugins/metismenu/css/metisMenu.min.css" rel="stylesheet">
|
||||
<!-- loader-->
|
||||
<link href="../assets/css/pace.min.css" rel="stylesheet"/>
|
||||
<script src="../assets/js/pace.min.js"></script>
|
||||
<!-- Bootstrap CSS -->
|
||||
<link href="../assets/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="../assets/css/bootstrap-extended.css" rel="stylesheet">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500&display=swap" rel="stylesheet">
|
||||
|
||||
<link href="../assets/sass/app.css" rel="stylesheet">
|
||||
<link href="../assets/css/icons.css" rel="stylesheet">
|
||||
<link href='https://unpkg.com/boxicons@2.1.4/css/boxicons.min.css' rel='stylesheet'>
|
||||
<!-- Theme Style CSS -->
|
||||
<link rel="stylesheet" href="../assets/sass/dark-theme.css">
|
||||
<link rel="stylesheet" href="../assets/sass/semi-dark.css">
|
||||
<link rel="stylesheet" href="../assets/sass/bordered-theme.css">
|
||||
|
||||
<title>TOD Dashboard</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!--wrapper-->
|
||||
<div class="wrapper">
|
||||
<!--sidebar wrapper -->
|
||||
<?php include '../src/nav.php'; ?>
|
||||
<!--end sidebar wrapper -->
|
||||
<!--start header -->
|
||||
<?php include '../src/header.php'; ?>
|
||||
<!--end header -->
|
||||
|
||||
<!--start page wrapper -->
|
||||
<div class="page-wrapper">
|
||||
<div class="page-content">
|
||||
<!--start page content -->
|
||||
|
||||
|
||||
<!-- Breadcrumb -->
|
||||
<div class="page-breadcrumb d-none d-sm-flex align-items-center mb-3">
|
||||
<div class="breadcrumb-title pe-3">Printer Dashboard</div>
|
||||
<div class="ps-3">
|
||||
<nav aria-label="breadcrumb">
|
||||
<ol class="breadcrumb mb-0 p-0">
|
||||
<li class="breadcrumb-item"><a href="index.php"><i class="bx bx-home-alt"></i></a></li>
|
||||
<li class="breadcrumb-item active" aria-current="page">Your Printers</li>
|
||||
</ol>
|
||||
</nav>
|
||||
</div>
|
||||
<div class="ms-auto">
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-primary dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">
|
||||
Refresh Interval: <span id="selectedIntervalText">60s</span>
|
||||
</button>
|
||||
<ul class="dropdown-menu dropdown-menu-end" id="intervalDropdown">
|
||||
<li><a class="dropdown-item set-interval" data-interval="5000" href="#">5 seconds</a></li>
|
||||
<li><a class="dropdown-item set-interval" data-interval="10000" href="#">10 seconds</a></li>
|
||||
<li><a class="dropdown-item set-interval" data-interval="30000" href="#">30 seconds</a></li>
|
||||
<li><a class="dropdown-item set-interval" data-interval="60000" href="#">60 seconds</a></li>
|
||||
<li><a class="dropdown-item set-interval" data-interval="off" href="#">Off</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- End Breadcrumb -->
|
||||
|
||||
<div class="container">
|
||||
<div class="main-body">
|
||||
<div id="alertContainer" class="container mt-3">
|
||||
<!-- Alerts will be dynamically inserted here -->
|
||||
</div>
|
||||
<div class="row" id="printerContainer">
|
||||
<!-- Printer cards will be dynamically inserted here -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!--end page content -->
|
||||
</div>
|
||||
</div>
|
||||
<!--end page wrapper -->
|
||||
|
||||
<!--start overlay-->
|
||||
<div class="overlay mobile-toggle-icon"></div>
|
||||
<!--end overlay-->
|
||||
<!--Start Back To Top Button-->
|
||||
<a href="javaScript:;" class="back-to-top"><i class='bx bxs-up-arrow-alt'></i></a>
|
||||
<!--End Back To Top Button-->
|
||||
</div>
|
||||
<!--end wrapper-->
|
||||
|
||||
|
||||
<!-- search modal -->
|
||||
<div class="modal" id="SearchModal" tabindex="-1">
|
||||
<div class="modal-dialog modal-dialog-centered modal-dialog-scrollable modal-fullscreen-md-down">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header gap-2">
|
||||
<div class="position-relative popup-search w-100">
|
||||
<input class="form-control form-control-lg ps-5 border border-3 border-primary" type="search" placeholder="Search">
|
||||
<span class="position-absolute top-50 search-show ms-3 translate-middle-y start-0 top-50 fs-4"><i class='bx bx-search'></i></span>
|
||||
</div>
|
||||
<button type="button" class="btn-close d-md-none" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- end search modal -->
|
||||
|
||||
<!-- Bootstrap JS -->
|
||||
<script src="../assets/js/bootstrap.bundle.min.js"></script>
|
||||
<!--plugins-->
|
||||
<script src="../assets/js/jquery.min.js"></script>
|
||||
<script src="../assets/plugins/simplebar/js/simplebar.min.js"></script>
|
||||
<script src="../assets/plugins/metismenu/js/metisMenu.min.js"></script>
|
||||
<script src="../assets/plugins/perfect-scrollbar/js/perfect-scrollbar.js"></script>
|
||||
<script src="../assets/plugins/apexcharts-bundle/js/apexcharts.min.js"></script>
|
||||
<!--app JS-->
|
||||
<script src="../assets/js/app.js"></script>
|
||||
|
||||
<script src="../assets/js/index.js"></script>
|
||||
<script src="../assets/plugins/peity/jquery.peity.min.js"></script>
|
||||
<script>
|
||||
$(".data-attributes span").peity("donut")
|
||||
</script>
|
||||
|
||||
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
let refreshInterval = 60000; // Default interval of 10s
|
||||
let intervalHandler;
|
||||
|
||||
// Load printers asynchronously
|
||||
async function loadPrinters() {
|
||||
try {
|
||||
const response = await $.ajax({
|
||||
url: '../src/printers/getPrinters.php',
|
||||
method: 'GET',
|
||||
dataType: 'json',
|
||||
cache: false
|
||||
});
|
||||
|
||||
let container = $('#printerContainer');
|
||||
|
||||
if (response.status === 'success' && response.data.length > 0) {
|
||||
response.data.forEach(function(printer) {
|
||||
let existingCard = container.find(`.printer-card[data-serial="${printer.serialNumber}"]`);
|
||||
|
||||
let trayHTML = '';
|
||||
printer.trays.forEach(tray => {
|
||||
let trayColor = `#${tray.color.slice(0, 6)}`;
|
||||
trayHTML += `
|
||||
<div class="tray-slot text-center">
|
||||
<div class="tray-circle" style="background-color: ${trayColor}; width: 40px; height: 40px; border-radius: 50%;"></div>
|
||||
<p>Slot ${parseInt(tray.id) + 1}</p>
|
||||
</div>`;
|
||||
});
|
||||
|
||||
let printerCard = `
|
||||
<div class="col-lg-4 printer-card" data-serial="${printer.serialNumber}">
|
||||
<div class="card mb-4">
|
||||
<div class="card-body text-center">
|
||||
<img src="../assets/images/printer-icon.png" alt="Printer" class="rounded-circle p-1" width="110">
|
||||
<div class="mt-3">
|
||||
<h4>${printer.printerName}</h4>
|
||||
<p class="text-secondary mb-1">Current Job: <span>${printer.jobName}</span></p>
|
||||
<p class="text-muted font-size-sm">
|
||||
Bed Temp: <span>${printer.bedTemp}°C</span> |
|
||||
Nozzle Temp: <span>${printer.nozzleTemp}°C</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="d-flex justify-content-center gap-4 mt-3">
|
||||
${trayHTML}
|
||||
</div>
|
||||
<div class="mt-4 w-100">
|
||||
<label for="humidityBar${printer.serialNumber}" class="form-label">AMS Humidity</label>
|
||||
<div class="progress" style="height: 20px;">
|
||||
<div id="humidityBar${printer.serialNumber}" class="progress-bar" role="progressbar"
|
||||
style="width: ${printer.humidity * 20}%;"
|
||||
aria-valuemin="1"
|
||||
aria-valuemax="5">
|
||||
${printer.humidity}/5
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>`;
|
||||
|
||||
if (existingCard.length) {
|
||||
existingCard.replaceWith(printerCard);
|
||||
} else {
|
||||
container.append(printerCard);
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.log('Failed to load printers:', error);
|
||||
}
|
||||
}
|
||||
|
||||
// Polling function
|
||||
function startPolling(interval) {
|
||||
clearInterval(intervalHandler);
|
||||
if (interval !== 'off') {
|
||||
intervalHandler = setInterval(loadPrinters, interval);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle refresh dropdown
|
||||
$('.set-interval').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
let selectedInterval = $(this).data('interval');
|
||||
|
||||
if (selectedInterval === 'off') {
|
||||
clearInterval(intervalHandler);
|
||||
console.log("Auto-refresh turned off.");
|
||||
} else {
|
||||
refreshInterval = parseInt(selectedInterval);
|
||||
startPolling(refreshInterval);
|
||||
console.log(`Refresh interval set to ${refreshInterval / 1000} seconds.`);
|
||||
}
|
||||
$('#selectedIntervalText').text(selectedInterval === 'off' ? 'Off' : `${selectedInterval / 1000}s`);
|
||||
});
|
||||
|
||||
loadPrinters();
|
||||
startPolling(refreshInterval); // Start polling immediately
|
||||
});
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -70,7 +70,7 @@
|
||||
<li>
|
||||
<div class="dropdown-divider mb-0"></div>
|
||||
</li>
|
||||
<li><a class="dropdown-item d-flex align-items-center" href="logout.php"><i class="bx bx-log-out-circle"></i><span>Logout</span></a>
|
||||
<li><a class="dropdown-item d-flex align-items-center" href="../public/logout.php"><i class="bx bx-log-out-circle"></i><span>Logout</span></a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -12,7 +12,7 @@ if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
|
||||
if ($user && password_verify($password, $user['password']) && !$user['disabled']) {
|
||||
// Store user ID, username, and role in session
|
||||
$_SESSION['user_id'] = $user['id'];
|
||||
$_SESSION['userId'] = $user['id'];
|
||||
$_SESSION['username'] = $user['username'];
|
||||
$_SESSION['role'] = $user['role']; // Store user role
|
||||
echo 'success';
|
||||
|
||||
125
src/nav.php
125
src/nav.php
@@ -28,131 +28,10 @@
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<a href="javascript:;" class="has-arrow">
|
||||
<div class="parent-icon"><i class="bx bx-category"></i>
|
||||
</div>
|
||||
<div class="menu-title">Application</div>
|
||||
</a>
|
||||
<ul>
|
||||
<li> <a href="app-emailbox.html"><i class='bx bx-radio-circle'></i>Email</a>
|
||||
</li>
|
||||
<li> <a href="app-chat-box.html"><i class='bx bx-radio-circle'></i>Chat Box</a>
|
||||
</li>
|
||||
<li> <a href="app-file-manager.html"><i class='bx bx-radio-circle'></i>File Manager</a>
|
||||
</li>
|
||||
<li> <a href="app-contact-list.html"><i class='bx bx-radio-circle'></i>Contatcs</a>
|
||||
</li>
|
||||
<li> <a href="app-to-do.html"><i class='bx bx-radio-circle'></i>Todo List</a>
|
||||
</li>
|
||||
<li> <a href="app-invoice.html"><i class='bx bx-radio-circle'></i>Invoice</a>
|
||||
</li>
|
||||
<li> <a href="app-fullcalender.html"><i class='bx bx-radio-circle'></i>Calendar</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="menu-label">UI Elements</li>
|
||||
<li>
|
||||
<a href="widgets.html">
|
||||
<div class="parent-icon"><i class='bx bx-cookie'></i>
|
||||
</div>
|
||||
<div class="menu-title">Widgets</div>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="javascript:;" class="has-arrow">
|
||||
<div class="parent-icon"><i class='bx bx-cart'></i>
|
||||
</div>
|
||||
<div class="menu-title">eCommerce</div>
|
||||
</a>
|
||||
<ul>
|
||||
<li> <a href="ecommerce-products.html"><i class='bx bx-radio-circle'></i>Products</a>
|
||||
</li>
|
||||
<li> <a href="ecommerce-products-details.html"><i class='bx bx-radio-circle'></i>Product Details</a>
|
||||
</li>
|
||||
<li> <a href="ecommerce-add-new-products.html"><i class='bx bx-radio-circle'></i>Add New Products</a>
|
||||
</li>
|
||||
<li> <a href="ecommerce-orders.html"><i class='bx bx-radio-circle'></i>Orders</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<a class="has-arrow" href="javascript:;">
|
||||
<div class="parent-icon"><i class='bx bx-bookmark-heart'></i>
|
||||
</div>
|
||||
<div class="menu-title">Components</div>
|
||||
</a>
|
||||
<ul>
|
||||
<li> <a href="component-alerts.html"><i class='bx bx-radio-circle'></i>Alerts</a>
|
||||
</li>
|
||||
<li> <a href="component-accordions.html"><i class='bx bx-radio-circle'></i>Accordions</a>
|
||||
</li>
|
||||
<li> <a href="component-badges.html"><i class='bx bx-radio-circle'></i>Badges</a>
|
||||
</li>
|
||||
<li> <a href="component-buttons.html"><i class='bx bx-radio-circle'></i>Buttons</a>
|
||||
</li>
|
||||
<li> <a href="component-cards.html"><i class='bx bx-radio-circle'></i>Cards</a>
|
||||
</li>
|
||||
<li> <a href="component-carousels.html"><i class='bx bx-radio-circle'></i>Carousels</a>
|
||||
</li>
|
||||
<li> <a href="component-list-groups.html"><i class='bx bx-radio-circle'></i>List Groups</a>
|
||||
</li>
|
||||
<li> <a href="component-media-object.html"><i class='bx bx-radio-circle'></i>Media Objects</a>
|
||||
</li>
|
||||
<li> <a href="component-modals.html"><i class='bx bx-radio-circle'></i>Modals</a>
|
||||
</li>
|
||||
<li> <a href="component-navs-tabs.html"><i class='bx bx-radio-circle'></i>Navs & Tabs</a>
|
||||
</li>
|
||||
<li> <a href="component-navbar.html"><i class='bx bx-radio-circle'></i>Navbar</a>
|
||||
</li>
|
||||
<li> <a href="component-paginations.html"><i class='bx bx-radio-circle'></i>Pagination</a>
|
||||
</li>
|
||||
<li> <a href="component-popovers-tooltips.html"><i class='bx bx-radio-circle'></i>Popovers & Tooltips</a>
|
||||
</li>
|
||||
<li> <a href="component-progress-bars.html"><i class='bx bx-radio-circle'></i>Progress</a>
|
||||
</li>
|
||||
<li> <a href="component-spinners.html"><i class='bx bx-radio-circle'></i>Spinners</a>
|
||||
</li>
|
||||
<li> <a href="component-notifications.html"><i class='bx bx-radio-circle'></i>Notifications</a>
|
||||
</li>
|
||||
<li> <a href="component-avtars-chips.html"><i class='bx bx-radio-circle'></i>Avatrs & Chips</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<a class="has-arrow" href="javascript:;">
|
||||
<div class="parent-icon"><i class="bx bx-repeat"></i>
|
||||
</div>
|
||||
<div class="menu-title">Content</div>
|
||||
</a>
|
||||
<ul>
|
||||
<li> <a href="content-grid-system.html"><i class='bx bx-radio-circle'></i>Grid System</a>
|
||||
</li>
|
||||
<li> <a href="content-typography.html"><i class='bx bx-radio-circle'></i>Typography</a>
|
||||
</li>
|
||||
<li> <a href="content-text-utilities.html"><i class='bx bx-radio-circle'></i>Text Utilities</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<a class="has-arrow" href="javascript:;">
|
||||
<div class="parent-icon"> <i class="bx bx-donate-blood"></i>
|
||||
</div>
|
||||
<div class="menu-title">Icons</div>
|
||||
</a>
|
||||
<ul>
|
||||
<li> <a href="icons-line-icons.html"><i class='bx bx-radio-circle'></i>Line Icons</a>
|
||||
</li>
|
||||
<li> <a href="icons-boxicons.html"><i class='bx bx-radio-circle'></i>Boxicons</a>
|
||||
</li>
|
||||
<li> <a href="icons-feather-icons.html"><i class='bx bx-radio-circle'></i>Feather Icons</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<a href="form-froala-editor.html">
|
||||
<a href="viewPrinters.php">
|
||||
<div class="parent-icon"><i class='bx bx-code-alt'></i>
|
||||
</div>
|
||||
<div class="menu-title">Froala Editor</div>
|
||||
<div class="menu-title">Printer Dashboard</div>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -1,12 +1,21 @@
|
||||
<?php
|
||||
session_start(); // Ensure session is started to get logged-in user ID
|
||||
require '../db.php';
|
||||
require_once '../envLoader.php';
|
||||
loadEnv(__DIR__ . '/../../.env');
|
||||
|
||||
header('Content-Type: application/json');
|
||||
|
||||
// Check if the user is logged in
|
||||
if (!isset($_SESSION['userId'])) {
|
||||
echo json_encode(['status' => 'error', 'message' => 'User not authenticated.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$userId = $_SESSION['userId']; // Retrieve user ID from session
|
||||
|
||||
// Handle POST Request
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
header('Content-Type: application/json'); // Return JSON response
|
||||
|
||||
// Collect and sanitize form data
|
||||
$printerName = filter_input(INPUT_POST, 'printerName', FILTER_SANITIZE_STRING);
|
||||
$printerIp = filter_input(INPUT_POST, 'printerIp', FILTER_VALIDATE_IP);
|
||||
@@ -19,10 +28,10 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
}
|
||||
|
||||
try {
|
||||
// Prepare SQL insert statement
|
||||
// Prepare SQL insert statement with user ID
|
||||
$stmt = $pdo->prepare("
|
||||
INSERT INTO bambuPrinters (printerName, printerIp, mqttPassword, serialNumber)
|
||||
VALUES (:printerName, :printerIp, :mqttPassword, :serialNumber)
|
||||
INSERT INTO bambuPrinters (printerName, printerIp, mqttPassword, serialNumber, userId)
|
||||
VALUES (:printerName, :printerIp, :mqttPassword, :serialNumber, :userId)
|
||||
");
|
||||
|
||||
// Execute the query with bound parameters
|
||||
@@ -30,7 +39,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
':printerName' => $printerName,
|
||||
':printerIp' => $printerIp,
|
||||
':mqttPassword' => $accessCode,
|
||||
':serialNumber' => $serialNumber
|
||||
':serialNumber' => $serialNumber,
|
||||
':userId' => $userId
|
||||
]);
|
||||
|
||||
echo json_encode(['status' => 'success', 'message' => 'Printer successfully added!']);
|
||||
|
||||
79
src/printers/getPrinters.php
Normal file
79
src/printers/getPrinters.php
Normal file
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
session_start();
|
||||
require '../db.php';
|
||||
header('Content-Type: application/json');
|
||||
|
||||
if (!isset($_SESSION['userId'])) {
|
||||
echo json_encode(['status' => 'error', 'message' => 'User not authenticated.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$userId = $_SESSION['userId'];
|
||||
|
||||
try {
|
||||
// Subquery to fetch latest telemetry for each printer
|
||||
$stmt = $pdo->prepare("
|
||||
SELECT p.*, t.telemetry, t.recordedAt
|
||||
FROM bambuPrinters p
|
||||
LEFT JOIN printerTelemetry t
|
||||
ON t.id = (
|
||||
SELECT id FROM printerTelemetry
|
||||
WHERE printerId = p.id
|
||||
ORDER BY recordedAt DESC
|
||||
LIMIT 1
|
||||
)
|
||||
WHERE p.userId = :userId
|
||||
");
|
||||
|
||||
$stmt->execute([':userId' => $userId]);
|
||||
$printers = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
$result = [];
|
||||
foreach ($printers as $printer) {
|
||||
$telemetry = json_decode($printer['telemetry'], true);
|
||||
|
||||
$bedTemp = isset($telemetry['print']['bed_temper']) ? $telemetry['print']['bed_temper'] : 'N/A';
|
||||
$nozzleTemp = isset($telemetry['print']['device']['nozzle']['0']['temp'])
|
||||
? $telemetry['print']['device']['nozzle']['0']['temp']
|
||||
: 'N/A';
|
||||
$jobName = isset($telemetry['subtask_name']) ? $telemetry['subtask_name'] : 'No job running';
|
||||
$status = isset($telemetry['print']['gcode_state']) ? $telemetry['print']['gcode_state'] : 'Unknown';
|
||||
|
||||
// AMS Data
|
||||
$humidity = isset($telemetry['print']['ams']['ams'][0]['humidity'])
|
||||
? $telemetry['print']['ams']['ams'][0]['humidity']
|
||||
: 0;
|
||||
$trays = isset($telemetry['print']['ams']['ams'][0]['tray'])
|
||||
? $telemetry['print']['ams']['ams'][0]['tray']
|
||||
: [];
|
||||
|
||||
// Structure tray data for direct output
|
||||
$trayData = [];
|
||||
foreach ($trays as $tray) {
|
||||
$trayData[] = [
|
||||
'id' => $tray['id'],
|
||||
'color' => isset($tray['tray_color']) ? $tray['tray_color'] : 'ccc'
|
||||
];
|
||||
}
|
||||
|
||||
$result[] = [
|
||||
'printerId' => $printer['id'],
|
||||
'printerName' => $printer['printerName'],
|
||||
'serialNumber' => $printer['serialNumber'],
|
||||
'printerIp' => $printer['printerIp'],
|
||||
'bedTemp' => $bedTemp,
|
||||
'nozzleTemp' => $nozzleTemp,
|
||||
'jobName' => $jobName,
|
||||
'status' => $status,
|
||||
'humidity' => $humidity,
|
||||
'trays' => $trayData,
|
||||
'recordedAt' => $printer['recordedAt'] ?? 'Never'
|
||||
];
|
||||
}
|
||||
|
||||
echo json_encode(['status' => 'success', 'data' => $result]);
|
||||
|
||||
} catch (PDOException $e) {
|
||||
echo json_encode(['status' => 'error', 'message' => 'Failed to fetch printers: ' . $e->getMessage()]);
|
||||
}
|
||||
?>
|
||||
105
src/printers/mqttConnect.php
Normal file
105
src/printers/mqttConnect.php
Normal file
@@ -0,0 +1,105 @@
|
||||
<?php
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
|
||||
require '/mnt/www-live/TechOdyssey_Designs_Dashboard/vendor/autoload.php';
|
||||
require '/mnt/www-live/TechOdyssey_Designs_Dashboard/src/db.php';
|
||||
require_once '/mnt/www-live/TechOdyssey_Designs_Dashboard/src/envLoader.php';
|
||||
loadEnv(__DIR__ . '/../../.env');
|
||||
|
||||
use PhpMqtt\Client\MqttClient;
|
||||
use PhpMqtt\Client\ConnectionSettings;
|
||||
|
||||
session_start();
|
||||
|
||||
// Enable asynchronous signal handling
|
||||
pcntl_async_signals(true);
|
||||
|
||||
// MQTT Configuration from .env
|
||||
$mqttPort = $_ENV['MQTT_PORT'];
|
||||
$mqttUsername = $_ENV['MQTT_USERNAME'];
|
||||
$clientId = 'printer_monitor_' . uniqid();
|
||||
|
||||
// Fetch printers associated with the logged-in user
|
||||
try {
|
||||
$stmt = $pdo->prepare("SELECT * FROM bambuPrinters");
|
||||
$stmt->execute();
|
||||
$printers = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
} catch (PDOException $e) {
|
||||
die(json_encode(['status' => 'error', 'message' => 'Failed to fetch printers.']));
|
||||
}
|
||||
|
||||
// Process 2 messages per printer
|
||||
$maxMessagesPerPrinter = 2;
|
||||
|
||||
try {
|
||||
foreach ($printers as $printer) {
|
||||
echo "Connecting to " . $printer['printerName'] . " (" . $printer['serialNumber'] . ")...\n";
|
||||
echo "IP Address: " . $printer['printerIp'] . "\n";
|
||||
echo "MQTT Password: " . $printer['mqttPassword'] . "\n";
|
||||
|
||||
$mqttPassword = $printer['mqttPassword']; // Use mqttPassword from DB
|
||||
$printerIp = $printer['printerIp']; // Printer IP from DB
|
||||
$messageCount = 0; // Reset counter per printer
|
||||
|
||||
$mqtt = new MqttClient($printerIp, $mqttPort, $clientId);
|
||||
|
||||
// Handle SIGINT (CTRL + C) to gracefully exit
|
||||
pcntl_signal(SIGINT, function () use ($mqtt) {
|
||||
echo "Interrupt received. Disconnecting MQTT...\n";
|
||||
$mqtt->interrupt();
|
||||
});
|
||||
|
||||
$connectionSettings = (new ConnectionSettings())
|
||||
->setUsername($mqttUsername)
|
||||
->setPassword($mqttPassword)
|
||||
->setKeepAliveInterval(60)
|
||||
->setUseTls(true)
|
||||
->setTlsVerifyPeer(false)
|
||||
->setTlsVerifyPeerName(false);
|
||||
|
||||
// Establish Connection
|
||||
$mqtt->connect($connectionSettings, true);
|
||||
|
||||
// Subscribe to the printer's report topic
|
||||
$topic = "device/{$printer['serialNumber']}/report";
|
||||
|
||||
$mqtt->subscribe($topic, function (string $topic, string $message) use (
|
||||
$printer, $pdo, &$messageCount, $maxMessagesPerPrinter, $mqtt
|
||||
) {
|
||||
echo "[" . $printer['printerName'] . "] [$topic] $message\n";
|
||||
|
||||
// Store full JSON telemetry report
|
||||
try {
|
||||
$stmt = $pdo->prepare("
|
||||
INSERT INTO printerTelemetry
|
||||
(printerId, telemetry)
|
||||
VALUES
|
||||
(:printerId, :telemetry)
|
||||
");
|
||||
$stmt->execute([
|
||||
':printerId' => $printer['id'],
|
||||
':telemetry' => $message
|
||||
]);
|
||||
} catch (PDOException $e) {
|
||||
error_log("Failed to insert telemetry: " . $e->getMessage());
|
||||
}
|
||||
|
||||
$messageCount++;
|
||||
|
||||
// Stop loop after 2 messages for this printer
|
||||
if ($messageCount >= $maxMessagesPerPrinter) {
|
||||
echo "Processed $maxMessagesPerPrinter messages for " . $printer['printerName'] . ". Disconnecting...\n";
|
||||
$mqtt->interrupt();
|
||||
}
|
||||
}, 0);
|
||||
|
||||
// Start Listening for Messages
|
||||
$mqtt->loop(true); // Loop until interrupted after processing 2 messages
|
||||
$mqtt->disconnect();
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
die(json_encode(['status' => 'error', 'message' => 'MQTT connection failed. ' . $e->getMessage()]));
|
||||
}
|
||||
?>
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
session_start();
|
||||
if (!isset($_SESSION['user_id'])) {
|
||||
header("Location: public/login.php");
|
||||
if (!isset($_SESSION['userId'])) {
|
||||
header("Location: login.php");
|
||||
exit();
|
||||
}
|
||||
?>
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
<?php include '../src/nav.php'; ?>
|
||||
<!--end sidebar wrapper -->
|
||||
<!--start header -->
|
||||
<?php include '../src/nav.php'; ?>
|
||||
<?php include '../src/header.php'; ?>
|
||||
<!--end header -->
|
||||
|
||||
<!--start page wrapper -->
|
||||
|
||||
Reference in New Issue
Block a user