From 6b396f57b32dd93e2812639b8e3c8259500250fb Mon Sep 17 00:00:00 2001
From: ArekkusuDesu <17139783+arekkusudesu@users.noreply.github.com>
Date: Mon, 17 Mar 2025 22:49:06 +1300
Subject: [PATCH 1/3] Add PrusaLink as enhanced app
---
PrusaLink/PrusaLink.php | 86 +++++++++++++++++++++++++++++++++++
PrusaLink/app.json | 10 ++++
PrusaLink/config.blade.php | 15 ++++++
PrusaLink/livestats.blade.php | 23 ++++++++++
PrusaLink/prusalink.svg | 1 +
5 files changed, 135 insertions(+)
create mode 100644 PrusaLink/PrusaLink.php
create mode 100644 PrusaLink/app.json
create mode 100644 PrusaLink/config.blade.php
create mode 100644 PrusaLink/livestats.blade.php
create mode 100644 PrusaLink/prusalink.svg
diff --git a/PrusaLink/PrusaLink.php b/PrusaLink/PrusaLink.php
new file mode 100644
index 0000000000..9e9f62a45c
--- /dev/null
+++ b/PrusaLink/PrusaLink.php
@@ -0,0 +1,86 @@
+jar = new \GuzzleHttp\Cookie\CookieJar; // Uncomment if cookies need to be set
+ }
+
+ public function test()
+ {
+ $test = parent::appTest($this->url('api/v1/status'), $this->getAttrs());
+ echo $test->status;
+ }
+
+ public function livestats()
+ {
+ $status = 'inactive';
+ $res = parent::execute($this->url('api/v1/status'), $this->getAttrs());
+ $details = json_decode($res->getBody());
+
+ // Check if time_remaining exists and convert it
+ if (isset($details->job->time_remaining)) {
+ $short_time_remaining = $this->secondsToShortTime($details->job->time_remaining);
+ } else {
+ $short_time_remaining = "N/A";
+ }
+
+ if (isset($details->printer->temp_bed)) {
+ $temp_bed = $details->printer->temp_bed . " °C"; // Append "°C"
+ } else {
+ $temp_bed = "N/A"; // Default value
+ }
+
+ if (isset($details->printer->temp_nozzle)) {
+ $temp_nozzle = $details->printer->temp_nozzle . " °C"; // Append "°C"
+ } else {
+ $temp_nozzle = "N/A"; // Default value
+ }
+
+ $data = [
+ "state" => $details->printer->state ?? "OFFLINE", // Default state as "OFFLINE"
+ "short_time_remaining" => $short_time_remaining,
+ "temp_nozzle" => $temp_nozzle,
+ "temp_bed" => $temp_bed
+ ];
+
+ return parent::getLiveStats($status, $data);
+ }
+
+ private function secondsToShortTime($seconds) {
+ return CarbonInterval::seconds($seconds)
+ ->cascade()
+ ->forHumans([
+ 'short' => true,
+ 'join' => ' ', // Use a space instead of "and" or ","
+ 'maximumUnit' => 2
+ ]);
+ }
+
+ public function url($endpoint)
+ {
+ $api_url = parent::normaliseurl($this->config->url).$endpoint;
+ return $api_url;
+ }
+
+ private function getAttrs()
+ {
+ return [
+ "headers" => [
+ "X-Api-Key" => $this->config->apikey
+ ],
+ ];
+ }
+
+};
\ No newline at end of file
diff --git a/PrusaLink/app.json b/PrusaLink/app.json
new file mode 100644
index 0000000000..727a7cbf7b
--- /dev/null
+++ b/PrusaLink/app.json
@@ -0,0 +1,10 @@
+{
+ "appid": "e5f6e96e960a08fa8f1fe702b45690cbc789ebc9",
+ "name": "PrusaLink",
+ "website": "https://github.com/prusa3d/Prusa-Link-Web/tree/master",
+ "license": "CNRI Python Open Source GPL Compatible License Agreement",
+ "description": "Website for Prusa Printers to Control and get the current Status of the printer\r\nhttps://github.com/prusa3d/Prusa-Link-Web/blob/master/spec/openapi.yaml",
+ "enhanced": true,
+ "tile_background": "dark",
+ "icon": "prusalink.svg"
+}
\ No newline at end of file
diff --git a/PrusaLink/config.blade.php b/PrusaLink/config.blade.php
new file mode 100644
index 0000000000..5dc2116903
--- /dev/null
+++ b/PrusaLink/config.blade.php
@@ -0,0 +1,15 @@
+
{{ __('app.apps.config') }} ({{ __('app.optional') }}) @include('items.enable')
+
+
+ {{ strtoupper(__('app.url')) }}
+ {!! Form::text('config[override_url]', isset($item) ? $item->getconfig()->override_url : null, ['placeholder' => __('app.apps.override'), 'id' => 'override_url', 'class' => 'form-control']) !!}
+
+
+ {{ __('app.apps.apikey') }}
+ {!! Form::input('password', 'config[apikey]', isset($item) ? $item->getconfig()->apikey : null, ['placeholder' => __('app.apps.apikey'), 'data-config' => 'apikey', 'class' => 'form-control config-item']) !!}
+
+
+ Test
+
+
+To obtain the API key: On your printer, navigate to Settings > Network > Prusalink to get the username and password. The API key is the password shown on this screen.
\ No newline at end of file
diff --git a/PrusaLink/livestats.blade.php b/PrusaLink/livestats.blade.php
new file mode 100644
index 0000000000..2fbf84ce82
--- /dev/null
+++ b/PrusaLink/livestats.blade.php
@@ -0,0 +1,23 @@
+
+
+@if ($state != 'OFFLINE')
+
+ Status/ETA
+ {!! $state !!}
+ {!! $short_time_remaining !!}
+
+
+ Temps
+ N: {!! $temp_nozzle !!}
+ B: {!! $temp_bed !!}
+
+@else
+
+ STATUS: {!! $state !!}
+
+@endif
+
\ No newline at end of file
diff --git a/PrusaLink/prusalink.svg b/PrusaLink/prusalink.svg
new file mode 100644
index 0000000000..2e67271e30
--- /dev/null
+++ b/PrusaLink/prusalink.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
From a067196913b880dcf8662d17d109aeaf67d54212 Mon Sep 17 00:00:00 2001
From: ArekkusuDesu <17139783+arekkusudesu@users.noreply.github.com>
Date: Mon, 17 Mar 2025 23:15:53 +1300
Subject: [PATCH 2/3] increase logo size
---
PrusaLink/prusalink.svg | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/PrusaLink/prusalink.svg b/PrusaLink/prusalink.svg
index 2e67271e30..e43021555b 100644
--- a/PrusaLink/prusalink.svg
+++ b/PrusaLink/prusalink.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
From b2f617f36400232f2bfd7d6bf7d00751b85d002d Mon Sep 17 00:00:00 2001
From: ArekkusuDesu <17139783+arekkusudesu@users.noreply.github.com>
Date: Mon, 24 Mar 2025 20:10:05 +1300
Subject: [PATCH 3/3] fix lint
---
PrusaLink/PrusaLink.php | 20 +++++++++-----------
1 file changed, 9 insertions(+), 11 deletions(-)
diff --git a/PrusaLink/PrusaLink.php b/PrusaLink/PrusaLink.php
index 9e9f62a45c..cc58543eea 100644
--- a/PrusaLink/PrusaLink.php
+++ b/PrusaLink/PrusaLink.php
@@ -6,7 +6,6 @@
class PrusaLink extends \App\SupportedApps implements \App\EnhancedApps
{
-
public $config;
//protected $login_first = true; // Uncomment if api requests need to be authed first
@@ -28,7 +27,7 @@ public function livestats()
$status = 'inactive';
$res = parent::execute($this->url('api/v1/status'), $this->getAttrs());
$details = json_decode($res->getBody());
-
+
// Check if time_remaining exists and convert it
if (isset($details->job->time_remaining)) {
$short_time_remaining = $this->secondsToShortTime($details->job->time_remaining);
@@ -51,26 +50,26 @@ public function livestats()
$data = [
"state" => $details->printer->state ?? "OFFLINE", // Default state as "OFFLINE"
"short_time_remaining" => $short_time_remaining,
- "temp_nozzle" => $temp_nozzle,
+ "temp_nozzle" => $temp_nozzle,
"temp_bed" => $temp_bed
];
-
+
return parent::getLiveStats($status, $data);
}
-
+
private function secondsToShortTime($seconds) {
return CarbonInterval::seconds($seconds)
->cascade()
->forHumans([
- 'short' => true,
+ 'short' => true,
'join' => ' ', // Use a space instead of "and" or ","
- 'maximumUnit' => 2
+ 'maximumUnit' => 2
]);
- }
+ }
public function url($endpoint)
{
- $api_url = parent::normaliseurl($this->config->url).$endpoint;
+ $api_url = parent::normaliseurl($this->config->url) . $endpoint;
return $api_url;
}
@@ -82,5 +81,4 @@ private function getAttrs()
],
];
}
-
-};
\ No newline at end of file
+}