diff --git a/assets/images/printer-icon.png b/assets/images/printer-icon.png
new file mode 100644
index 0000000..e5f9b72
Binary files /dev/null and b/assets/images/printer-icon.png differ
diff --git a/composer.json b/composer.json
new file mode 100644
index 0000000..bed37d9
--- /dev/null
+++ b/composer.json
@@ -0,0 +1,5 @@
+{
+ "require": {
+ "php-mqtt/client": "^2.2"
+ }
+}
diff --git a/composer.lock b/composer.lock
new file mode 100644
index 0000000..50aecb7
--- /dev/null
+++ b/composer.lock
@@ -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"
+}
diff --git a/public/logout.php b/public/logout.php
index 8aed3f1..a027511 100644
--- a/public/logout.php
+++ b/public/logout.php
@@ -2,6 +2,6 @@
session_start();
session_unset();
session_destroy();
-header("Location: /login.php");
+header("Location: login.php");
exit();
?>
diff --git a/public/viewPrinters.php b/public/viewPrinters.php
new file mode 100644
index 0000000..361da5e
--- /dev/null
+++ b/public/viewPrinters.php
@@ -0,0 +1,249 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ TOD Dashboard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Printer Dashboard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/header.php b/src/header.php
index 028c450..5c2b9fc 100644
--- a/src/header.php
+++ b/src/header.php
@@ -70,7 +70,7 @@
- Logout
+ Logout
diff --git a/src/login.php b/src/login.php
index 8904eb1..3a36dfa 100644
--- a/src/login.php
+++ b/src/login.php
@@ -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';
diff --git a/src/nav.php b/src/nav.php
index 7d05d3c..92f93a1 100644
--- a/src/nav.php
+++ b/src/nav.php
@@ -28,131 +28,10 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
+
diff --git a/src/printers/addPrinter.php b/src/printers/addPrinter.php
index f5e0c1b..4508111 100644
--- a/src/printers/addPrinter.php
+++ b/src/printers/addPrinter.php
@@ -1,12 +1,21 @@
'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!']);
diff --git a/src/printers/getPrinters.php b/src/printers/getPrinters.php
new file mode 100644
index 0000000..ddd3be1
--- /dev/null
+++ b/src/printers/getPrinters.php
@@ -0,0 +1,79 @@
+ '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()]);
+}
+?>
diff --git a/src/printers/mqttConnect.php b/src/printers/mqttConnect.php
new file mode 100644
index 0000000..8da2b2e
--- /dev/null
+++ b/src/printers/mqttConnect.php
@@ -0,0 +1,105 @@
+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()]));
+}
+?>
diff --git a/src/session_check.php b/src/session_check.php
index 5ffae5d..f34a1fb 100644
--- a/src/session_check.php
+++ b/src/session_check.php
@@ -1,7 +1,7 @@
diff --git a/template.php b/template.php
index 33993bc..5537d50 100644
--- a/template.php
+++ b/template.php
@@ -38,7 +38,7 @@
-
+