raspberrydisplay v2 init
This commit is contained in:
@@ -1,11 +1,6 @@
|
||||
<?php
|
||||
|
||||
use phpseclib3\Net\SSH2;
|
||||
|
||||
class RaspberryDisplayController extends mfBaseController {
|
||||
private int $port = 22;
|
||||
private string $username = XINON_RASPBERRY_DISPLAY_SSH_USER;
|
||||
private string $password = XINON_RASPBERRY_DISPLAY_SSH_PASS;
|
||||
|
||||
protected function init(): void {
|
||||
$me = new User();
|
||||
@@ -15,161 +10,237 @@ class RaspberryDisplayController extends mfBaseController {
|
||||
}
|
||||
|
||||
protected function apiAction() {
|
||||
$do = $this->request->do;
|
||||
|
||||
if ($do !== "getConfig" && !$this->me->is("employee")) {
|
||||
$this->redirect("dashboard");
|
||||
if (!$this->me->is("employee")) {
|
||||
$this->returnJson(["status" => "error", "message" => "Unauthorized"]);
|
||||
return;
|
||||
}
|
||||
|
||||
switch ($do) {
|
||||
case "getDisplays":
|
||||
$return = $this->getDisplaysApi();
|
||||
break;
|
||||
case "change":
|
||||
$return = $this->change();
|
||||
break;
|
||||
case "reboot":
|
||||
$return = $this->restartRaspberryPi($this->request->displayID);
|
||||
break;
|
||||
case "rebootAll":
|
||||
$return = $this->restartAllRaspberryPis();
|
||||
break;
|
||||
case "getConfig":
|
||||
$return = $this->getConfig();
|
||||
break;
|
||||
case "displayPower":
|
||||
$return = $this->displayPower();
|
||||
break;
|
||||
default:
|
||||
$return = false;
|
||||
break;
|
||||
$return = match($this->request->do) {
|
||||
"getDisplays" => $this->getDisplaysApi(),
|
||||
"getGroups" => RaspberryDisplayModel::getGroups(),
|
||||
"createDisplay" => $this->createDisplayApi(),
|
||||
"updateDisplay" => $this->updateDisplayApi(),
|
||||
"deleteDisplay" => RaspberryDisplayModel::delete((int)$this->request->id),
|
||||
"updateOrder" => $this->updateOrderApi(),
|
||||
"discoverPi" => $this->discoverPiApi(),
|
||||
"getStatus" => $this->getStatusApi(),
|
||||
"getBatchStatus" => $this->getBatchStatusApi(),
|
||||
"setUrl" => $this->setUrlApi(),
|
||||
"refreshDisplay" => $this->refreshDisplayApi(),
|
||||
"cecPower" => $this->cecPowerApi(),
|
||||
"rebootPi" => $this->rebootPiApi(),
|
||||
"refreshAll" => $this->refreshAllApi(),
|
||||
"powerAll" => $this->powerAllApi(),
|
||||
"rebootAll" => $this->rebootAllApi(),
|
||||
default => null
|
||||
};
|
||||
|
||||
if ($return === null) {
|
||||
$this->returnJson(["status" => "error", "message" => "Unknown action"]);
|
||||
} elseif ($return === true) {
|
||||
$this->returnJson(["status" => "success"]);
|
||||
} elseif ($return === false) {
|
||||
$this->returnJson(["status" => "error", "message" => "Operation failed"]);
|
||||
} else {
|
||||
$this->returnJson(["status" => "OK", "result" => $return]);
|
||||
}
|
||||
|
||||
|
||||
$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 getDisplaysApi(): array {
|
||||
$displays = RaspberryDisplayModel::getAll();
|
||||
$result = [];
|
||||
foreach ($displays as $display) {
|
||||
$result[] = ["display_label" => $display->display_label,
|
||||
$grouped = [];
|
||||
foreach (RaspberryDisplayModel::getAll() as $display) {
|
||||
$grouped[$display->group_name][] = [
|
||||
"id" => (int)$display->id,
|
||||
"display_label" => $display->display_label,
|
||||
"hostname" => $display->hostname,
|
||||
"ip" => $display->ip_address,
|
||||
"ip_address" => $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",
|
||||
"group_name" => $display->group_name,
|
||||
"group_order" => (int)$display->group_order,
|
||||
"monitor_size" => $display->monitor_size,
|
||||
"hdmi_port" => (int)$display->hdmi_port,
|
||||
"agent_port" => (int)$display->agent_port,
|
||||
"custom_style" => $display->custom_style,
|
||||
"id" => $display->id,];
|
||||
];
|
||||
}
|
||||
foreach ($grouped as &$group) {
|
||||
usort($group, fn($a, $b) => $a['group_order'] <=> $b['group_order']);
|
||||
}
|
||||
return $grouped;
|
||||
}
|
||||
|
||||
protected function createDisplayApi(): array|bool {
|
||||
$data = [
|
||||
'display_label' => $this->request->display_label ?? '',
|
||||
'hostname' => $this->request->hostname ?? '',
|
||||
'ip_address' => $this->request->ip_address ?? '',
|
||||
'display_url' => $this->request->display_url ?? '',
|
||||
'group_name' => $this->request->group_name ?? '',
|
||||
'group_order' => (int)($this->request->group_order ?? 0),
|
||||
'monitor_size' => $this->request->monitor_size ?? '27',
|
||||
'hdmi_port' => (int)($this->request->hdmi_port ?? 0),
|
||||
'agent_port' => (int)($this->request->agent_port ?? 5000),
|
||||
'custom_style' => $this->request->custom_style ?? null,
|
||||
];
|
||||
|
||||
if (empty($data['display_label']) || empty($data['ip_address']) || empty($data['group_name'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$display = RaspberryDisplayModel::create($data);
|
||||
$display->create_by = $this->me->id;
|
||||
$display->create = time();
|
||||
RaspberryDisplayModel::save($display);
|
||||
return ['id' => $display->id];
|
||||
}
|
||||
|
||||
protected function updateDisplayApi(): bool {
|
||||
$display = RaspberryDisplayModel::get((int)$this->request->id);
|
||||
if (!$display) return false;
|
||||
|
||||
foreach (['display_label', 'hostname', 'ip_address', 'display_url', 'group_name', 'group_order', 'monitor_size', 'hdmi_port', 'agent_port', 'custom_style'] as $field) {
|
||||
if (isset($this->request->$field)) $display->$field = $this->request->$field;
|
||||
}
|
||||
$display->edit_by = $this->me->id;
|
||||
$display->edit = time();
|
||||
RaspberryDisplayModel::save($display);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function updateOrderApi(): bool {
|
||||
if (!is_array($this->request->orders)) return false;
|
||||
foreach ($this->request->orders as $order) {
|
||||
$display = RaspberryDisplayModel::get((int)$order['id']);
|
||||
if ($display) {
|
||||
$display->group_name = $order['group_name'] ?? $display->group_name;
|
||||
$display->group_order = (int)($order['group_order'] ?? 0);
|
||||
$display->edit_by = $this->me->id;
|
||||
$display->edit = time();
|
||||
RaspberryDisplayModel::save($display);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function discoverPiApi(): array|bool {
|
||||
$ip = $this->request->ip_address ?? '';
|
||||
if (empty($ip)) return false;
|
||||
|
||||
$status = (new NocDisplayAgent($ip, (int)($this->request->agent_port ?? 5000)))->status();
|
||||
if (!$status['success']) {
|
||||
return ['online' => false, 'error' => $status['error'] ?? 'Failed to connect'];
|
||||
}
|
||||
return [
|
||||
'online' => true,
|
||||
'hostname' => $status['hostname'] ?? '',
|
||||
'displays' => $status['displays'] ?? [],
|
||||
'temperature_c' => $status['temperature_c'] ?? null,
|
||||
'cpu_percent' => $status['cpu_percent'] ?? null,
|
||||
'memory' => $status['memory'] ?? null,
|
||||
];
|
||||
}
|
||||
|
||||
protected function getStatusApi(): array|bool {
|
||||
$display = RaspberryDisplayModel::get((int)$this->request->id);
|
||||
if (!$display) return false;
|
||||
return NocDisplayAgent::fromDisplay(['ip_address' => $display->ip_address, 'agent_port' => $display->agent_port])->status();
|
||||
}
|
||||
|
||||
protected function getBatchStatusApi(): array {
|
||||
$seen = [];
|
||||
$results = [];
|
||||
foreach (RaspberryDisplayModel::getAll() as $display) {
|
||||
$key = "{$display->ip_address}:{$display->agent_port}";
|
||||
if (isset($seen[$key])) continue;
|
||||
$seen[$key] = true;
|
||||
$results[$display->ip_address] = NocDisplayAgent::fromDisplay(['ip_address' => $display->ip_address, 'agent_port' => $display->agent_port])->status();
|
||||
}
|
||||
return $results;
|
||||
}
|
||||
|
||||
protected function setUrlApi(): array|bool {
|
||||
$display = RaspberryDisplayModel::get((int)$this->request->id);
|
||||
if (!$display) return false;
|
||||
|
||||
$result = NocDisplayAgent::fromDisplay(['ip_address' => $display->ip_address, 'agent_port' => $display->agent_port])
|
||||
->setUrl((int)$display->hdmi_port, $this->request->url ?? '');
|
||||
|
||||
if ($result['success'] ?? false) {
|
||||
$display->display_url = $this->request->url ?? '';
|
||||
$display->edit_by = $this->me->id;
|
||||
$display->edit = time();
|
||||
RaspberryDisplayModel::save($display);
|
||||
}
|
||||
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 refreshDisplayApi(): array|bool {
|
||||
$display = RaspberryDisplayModel::get((int)$this->request->id);
|
||||
if (!$display) return false;
|
||||
return NocDisplayAgent::fromDisplay(['ip_address' => $display->ip_address, 'agent_port' => $display->agent_port])->refresh((int)$display->hdmi_port);
|
||||
}
|
||||
|
||||
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 cecPowerApi(): array|bool {
|
||||
$display = RaspberryDisplayModel::get((int)$this->request->id);
|
||||
if (!$display) return false;
|
||||
$agent = NocDisplayAgent::fromDisplay(['ip_address' => $display->ip_address, 'agent_port' => $display->agent_port]);
|
||||
return ($this->request->state ?? 'on') === 'on' ? $agent->cecOn((int)$display->hdmi_port) : $agent->cecOff((int)$display->hdmi_port);
|
||||
}
|
||||
|
||||
protected function restartAllRaspberryPis() {
|
||||
$displays = RaspberryDisplayModel::getAll();
|
||||
$ipAddresses = [];
|
||||
foreach ($displays as $display) {
|
||||
if (in_array($display->ip_address, $ipAddresses)) {
|
||||
continue;
|
||||
}
|
||||
$ipAddresses[] = $display->ip_address;
|
||||
$ssh = new SSH2($display->ip_address, $this->port);
|
||||
$ssh->login($this->username, $this->password);
|
||||
$ssh->exec('sudo reboot now');
|
||||
}
|
||||
return true;
|
||||
protected function rebootPiApi(): array|bool {
|
||||
$display = RaspberryDisplayModel::get((int)$this->request->id);
|
||||
if (!$display) return false;
|
||||
return NocDisplayAgent::fromDisplay(['ip_address' => $display->ip_address, 'agent_port' => $display->agent_port])->reboot();
|
||||
}
|
||||
|
||||
protected function getConfig() {
|
||||
$hostname = $this->request->hostname;
|
||||
|
||||
$displays = RaspberryDisplayModel::getByHostname($hostname);
|
||||
|
||||
if ($displays === null) {
|
||||
die("No display found for this hostname and ip:" . $hostname . " X ");
|
||||
protected function refreshAllApi(): array {
|
||||
$results = [];
|
||||
foreach (RaspberryDisplayModel::getAll() as $display) {
|
||||
$results[$display->id] = NocDisplayAgent::fromDisplay(['ip_address' => $display->ip_address, 'agent_port' => $display->agent_port])->refresh((int)$display->hdmi_port);
|
||||
}
|
||||
return $results;
|
||||
}
|
||||
|
||||
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 powerAllApi(): array {
|
||||
$state = $this->request->state ?? 'on';
|
||||
$results = [];
|
||||
foreach (RaspberryDisplayModel::getAll() as $display) {
|
||||
$agent = NocDisplayAgent::fromDisplay(['ip_address' => $display->ip_address, 'agent_port' => $display->agent_port]);
|
||||
$results[$display->id] = $state === 'on' ? $agent->cecOn((int)$display->hdmi_port) : $agent->cecOff((int)$display->hdmi_port);
|
||||
}
|
||||
return $results;
|
||||
}
|
||||
|
||||
protected function rebootAllApi(): array {
|
||||
$seen = [];
|
||||
$results = [];
|
||||
foreach (RaspberryDisplayModel::getAll() as $display) {
|
||||
$key = "{$display->ip_address}:{$display->agent_port}";
|
||||
if (isset($seen[$key])) continue;
|
||||
$seen[$key] = true;
|
||||
$results[$display->ip_address] = NocDisplayAgent::fromDisplay(['ip_address' => $display->ip_address, 'agent_port' => $display->agent_port])->reboot();
|
||||
}
|
||||
return $results;
|
||||
}
|
||||
|
||||
protected function indexAction(): void {
|
||||
$JSGlobals = ["BASE_URL" => self::getUrl("RaspberryDisplay"),
|
||||
"DASHBOARD_URL" => self::getUrl("Dashboard"),
|
||||
"MFAPPNAME" => MFAPPNAME_SLUG,
|
||||
"PAGE_TITLE" => "Raspberry Displays",
|
||||
"PATH" => [
|
||||
["text" => MFAPPNAME_SLUG, "href" => self::getUrl("Dashboard")],
|
||||
["text" => "Raspberry Displays", "href" => self::getUrl("RaspberryDisplay")]
|
||||
]
|
||||
];
|
||||
if (!$this->me->is("employee")) {
|
||||
$this->redirect("dashboard");
|
||||
return;
|
||||
}
|
||||
|
||||
$this->layout()->set("vueViewName", "RaspberryDisplay");
|
||||
$this->layout()->set("JSGlobals", $JSGlobals);
|
||||
$this->layout()->set("JSGlobals", [
|
||||
"BASE_URL" => self::getUrl("RaspberryDisplay"),
|
||||
"DASHBOARD_URL" => self::getUrl("Dashboard"),
|
||||
"MFAPPNAME" => MFAPPNAME_SLUG,
|
||||
"PAGE_TITLE" => "NOC Display Manager",
|
||||
"PATH" => [
|
||||
["text" => MFAPPNAME_SLUG, "href" => self::getUrl("Dashboard")],
|
||||
["text" => "NOC Display Manager", "href" => self::getUrl("RaspberryDisplay")]
|
||||
]
|
||||
]);
|
||||
$this->layout()->set("additionalCSS", ["css/views/RaspberryDisplay.css"]);
|
||||
$this->layout()->setTemplate("VueViews/Vue");
|
||||
$this->layout()->setTemplate("VueViews/Vue3");
|
||||
}
|
||||
|
||||
private function displayPower(): bool
|
||||
{
|
||||
$state = $this->request->state;
|
||||
$displays = RaspberryDisplayModel::getAll();
|
||||
$ipAddresses = [];
|
||||
foreach ($displays as $display) {
|
||||
if (in_array($display->ip_address, $ipAddresses)) {
|
||||
continue;
|
||||
}
|
||||
$ipAddresses[] = $display->ip_address;
|
||||
$ssh = new SSH2($display->ip_address, $this->port);
|
||||
$ssh->login($this->username, $this->password);
|
||||
if ($state === "on") {
|
||||
$ssh->exec('sudo bash /root/on.sh');
|
||||
} else {
|
||||
$ssh->exec('sudo bash /root/off.sh');
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user