247 lines
10 KiB
PHP
247 lines
10 KiB
PHP
<?php
|
|
|
|
class RaspberryDisplayController extends mfBaseController {
|
|
|
|
protected function init(): void {
|
|
$me = new User();
|
|
$me->loadMe();
|
|
$this->me = $me;
|
|
$this->layout()->set("me", $me);
|
|
}
|
|
|
|
protected function apiAction() {
|
|
if (!$this->me->is("employee")) {
|
|
$this->returnJson(["status" => "error", "message" => "Unauthorized"]);
|
|
return;
|
|
}
|
|
|
|
$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]);
|
|
}
|
|
}
|
|
|
|
protected function getDisplaysApi(): array {
|
|
$grouped = [];
|
|
foreach (RaspberryDisplayModel::getAll() as $display) {
|
|
$grouped[$display->group_name][] = [
|
|
"id" => (int)$display->id,
|
|
"display_label" => $display->display_label,
|
|
"hostname" => $display->hostname,
|
|
"ip_address" => $display->ip_address,
|
|
"display_url" => $display->display_url,
|
|
"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,
|
|
];
|
|
}
|
|
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 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 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 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 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;
|
|
}
|
|
|
|
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 {
|
|
if (!$this->me->is("employee")) {
|
|
$this->redirect("dashboard");
|
|
return;
|
|
}
|
|
|
|
$this->layout()->set("vueViewName", "RaspberryDisplay");
|
|
$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/Vue3");
|
|
}
|
|
}
|