From 90b7ce1dd9d363c1460f5223f17ed366aa00f56a Mon Sep 17 00:00:00 2001 From: Luca Haid Date: Tue, 13 Feb 2024 18:54:40 +0100 Subject: [PATCH] added module for managing raspberry displays --- Layout/default/RaspberryDisplay/Index.php | 273 ++++++++++++++++++ Layout/default/menu.php | 3 + .../RaspberryDisplay/RaspberryDisplay.php | 6 + .../RaspberryDisplayController.php | 119 ++++++++ .../RaspberryDisplayModel.php | 103 +++++++ composer.json | 13 +- config/config.sample.php | 6 +- ...0213083717_add_raspberry_display_table.php | 40 +++ 8 files changed, 556 insertions(+), 7 deletions(-) create mode 100644 Layout/default/RaspberryDisplay/Index.php create mode 100644 application/RaspberryDisplay/RaspberryDisplay.php create mode 100644 application/RaspberryDisplay/RaspberryDisplayController.php create mode 100644 application/RaspberryDisplay/RaspberryDisplayModel.php create mode 100644 db/migrations/20240213083717_add_raspberry_display_table.php diff --git a/Layout/default/RaspberryDisplay/Index.php b/Layout/default/RaspberryDisplay/Index.php new file mode 100644 index 000000000..d59ee43f2 --- /dev/null +++ b/Layout/default/RaspberryDisplay/Index.php @@ -0,0 +1,273 @@ + + + +
+
+
+
+ +
+

Raspberry Displays

+
+
+
+ + + + + + + + + + +
+ +
+
+
+
+ Loading... +
+
+
+
+
+ +
+

8322 Studenzen NOC Displays

+
+ + +
+
+
+ + +
+
+
+ {{ display.display_url | cleanupURL }} + +
+ +
+
+ + +
+
+ +
+ +
+ + +
+ + + | + + +
+ + + +
+ +
+ + +
+ {{ display.display_label }} +
+
+
+
+
+ + diff --git a/Layout/default/menu.php b/Layout/default/menu.php index 08026235e..1fd173f5c 100644 --- a/Layout/default/menu.php +++ b/Layout/default/menu.php @@ -26,6 +26,9 @@ "> Dashboard
diff --git a/application/RaspberryDisplay/RaspberryDisplay.php b/application/RaspberryDisplay/RaspberryDisplay.php new file mode 100644 index 000000000..02acaa680 --- /dev/null +++ b/application/RaspberryDisplay/RaspberryDisplay.php @@ -0,0 +1,6 @@ +loadMe(); + $this->me = $me; + $this->layout()->set("me", $me); + } + + protected function restartRaspberryPi($id) { + $display = RaspberryDisplayModel::get($id); + + $ssh = new SSH2($display->ip_address, $this->port); + $ssh->login($this->username, $this->password); + $ssh->exec('sudo reboot now'); + return true; + } + + protected function getDisplaysApi(): array + { + $displays = RaspberryDisplayModel::getAll(); + $result = []; + foreach ($displays as $display) { + $result[] = [ + "display_label" => $display->display_label, + "hostname" => $display->hostname, + "ip" => $display->ip_address, + "display_url" => $display->display_url, + "auto_refresh_enabled" => $display->auto_refresh_enabled === "1", + "margin_hot_fix_enabled" => $display->margin_hot_fix_enabled === "1", + "custom_style" => $display->custom_style, + "id" => $display->id, + ]; + } + return $result; + } + + protected function change() + { + $displayID = $this->request->displayID; + $field = $this->request->field; + $value = $this->request->value; + $value = $value === "true" ? 1 : ($value === "false" ? 0 : $value); + $display = RaspberryDisplayModel::get($displayID); + if ($display === null) { + return false; + } + $display->$field = $value; + $display->save(); + return true; + } + + protected function getConfig() { + $ip = $_SERVER['REMOTE_ADDR']; + $hostname = $this->request->hostname; + + $displays = RaspberryDisplayModel::getByHostnameAndIp($hostname, $ip); + + if ($displays === null) { + die("No display found for this hostname and ip:" . $hostname . " X " . $ip); + } + + return array_map(function ($display) { + return [ + "display_url" => $display->data->display_url, + "auto_refresh_enabled" => $display->data->auto_refresh_enabled === "1", + "margin_hot_fix_enabled" => $display->data->margin_hot_fix_enabled === "1", + "id" => $display->id, + ]; + } + , $displays); + } + protected function apiAction() { + $do = $this->request->do; + + if (!$this->me->is("employee") && !in_array($do, ["getDisplays", "change", "reboot"])) { + $this->redirect("dashboard"); + } + + $return = match ($do) { + "getDisplays" => $this->getDisplaysApi(), + "change" => $this->change(), + "reboot" => $this->restartRaspberryPi($this->request->displayID), + "getConfig" => $this->getConfig(), + default => false, + }; + + $data = []; + + if ($return === true) { + $data = ["status" => "success"]; + $this->returnJson($data); + } + + if(!is_array($return) || !count($return)) { + $data = ["status" => "error"]; + $this->returnJson($data); + } + $data['status'] = "OK"; + $data['result'] = $return; + $this->returnJson($data); + } + + protected function indexAction(): void + { + $this->layout()->setTemplate("RaspberryDisplay/Index"); + } + + +} \ No newline at end of file diff --git a/application/RaspberryDisplay/RaspberryDisplayModel.php b/application/RaspberryDisplay/RaspberryDisplayModel.php new file mode 100644 index 000000000..2ec6a4ee9 --- /dev/null +++ b/application/RaspberryDisplay/RaspberryDisplayModel.php @@ -0,0 +1,103 @@ + $value) { + if (property_exists(get_called_class(), $field)) { + $this->$field = $value; + } + } + } + + public static function get($id) + { + $db = FronkDB::singleton(); + + $res = $db->select("RaspberryDisplay", "*", "id = $id"); + if ($db->num_rows($res)) { + return new RaspberryDisplay($db->fetch_object($res)); + } + return null; + } + + public static function getByHostnameAndIp($hostname, $ip) + { + $db = FronkDB::singleton(); + + $res = $db->select("RaspberryDisplay", "*", "hostname = '$hostname' AND ip_address = '$ip'"); + //fetch 2 rows + + if ($db->num_rows($res)) { + while ($data = $db->fetch_object($res)) { + $items[] = new RaspberryDisplay($data); + } + return $items; + } + + } + + public static function create(array $data) + { + $model = new RaspberryDisplay(); + + foreach ($data as $field => $value) { + if (property_exists(get_called_class(), $field)) { + $model->$field = $value; + } + } + + $me = new User(); + $me->loadMe(); + + if ($model->create_by === null) { + $model->create_by = $me->id; + } + if ($model->edit_by === null) { + $model->edit_by = $me->id; + } + + return $model; + } + + public static function getAll() + { + $items = []; + + $db = FronkDB::singleton(); + + $res = $db->select("RaspberryDisplay", "id, display_label, hostname, ip_address,custom_style, display_url, auto_refresh_enabled, margin_hot_fix_enabled"); + if ($db->num_rows($res)) { + while ($data = $db->fetch_object($res)) { + $items[] = new RaspberryDisplay($data); + } + } + return $items; + + } + + public static function save(RaspberryDisplay $model) + { + $db = FronkDB::singleton(); + + $data = $model->data; + + if ($model->id) { + $db->update("RaspberryDisplay", $data, "id=" . $model->id); + } else { + $model->create = date("U"); + $model->edit = date("U"); + $model->id = $db->insert("RaspberryDisplay", $data); + } + + return $model; + } +} \ No newline at end of file diff --git a/composer.json b/composer.json index e4bb66219..3c82036fe 100644 --- a/composer.json +++ b/composer.json @@ -1,8 +1,9 @@ { - "require": { - "phpoffice/phpspreadsheet": "^1.23", - "robmorgan/phinx": "^0.13.4", - "textalk/websocket": "^1.6", - "chillerlan/php-qrcode": "dev-main" - } + "require": { + "phpoffice/phpspreadsheet": "^1.23", + "robmorgan/phinx": "^0.13.4", + "textalk/websocket": "^1.6", + "chillerlan/php-qrcode": "dev-main", + "phpseclib/phpseclib": "^3.0" + } } diff --git a/config/config.sample.php b/config/config.sample.php index 6c68ba51b..ac1d60149 100644 --- a/config/config.sample.php +++ b/config/config.sample.php @@ -686,4 +686,8 @@ define("PDFTOTEXT_BIN_PATH", "/usr/bin/pdftotext"); define("TT_MBI_API_ENABLE", true); //Enable API Calls define("TT_MBI_API_URL", "https://x.x.x.x/api/"); define("TT_MBI_API_VERSION", "v01"); -define("TT_MBI_API_KEY", ""); \ No newline at end of file +define("TT_MBI_API_KEY", ""); + +//Raspberry Display Configuration +define("XINON_RASPBERRY_DISPLAY_SSH_USER", ""); +define("XINON_RASPBERRY_DISPLAY_SSH_PASS", ""); \ No newline at end of file diff --git a/db/migrations/20240213083717_add_raspberry_display_table.php b/db/migrations/20240213083717_add_raspberry_display_table.php new file mode 100644 index 000000000..f13890033 --- /dev/null +++ b/db/migrations/20240213083717_add_raspberry_display_table.php @@ -0,0 +1,40 @@ +getEnvironment() == "thetool") { + $table = $this->table('RaspberryDisplay'); + $table->addColumn('display_label', 'string', ['limit' => 255]) + ->addColumn('hostname', 'string', ['limit' => 255]) + ->addColumn('ip_address', 'string', ['limit' => 15]) + ->addColumn('display_url', 'string', ['limit' => 255]) + ->addColumn('auto_refresh_enabled', 'boolean', ['default' => false]) + ->addColumn('margin_hot_fix_enabled', 'boolean', ['default' => false]) + ->addColumn('custom_style', 'string', ['limit' => 255, 'null' => true]) + ->addColumn('created_at', 'timestamp', ['default' => 'CURRENT_TIMESTAMP']) + ->addColumn('updated_at', 'timestamp', ['default' => 'CURRENT_TIMESTAMP', 'update' => 'CURRENT_TIMESTAMP']) + ->create(); + + } + + if($this->getEnvironment() == "addressdb") { + + } + } + + public function down(): void + { + if($this->getEnvironment() == "thetool") { + $this->table('RaspberryDisplay')->drop(); + } + + if($this->getEnvironment() == "addressdb") { + + } + } +}