From 3d1f5fb38d69a8bde59cdee79e503ac510f705e1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Pleva=C4=8D?= <lukas@plevac.eu>
Date: Fri, 6 Oct 2023 09:26:51 +0200
Subject: [PATCH] Added basic station view

---
 station/config.py                   |   4 +-
 station/planner.py                  |   2 +-
 web/CONTROLLERS/dashboard.php       |   1 +
 web/CONTROLLERS/station.php         |  42 ++++++++
 web/VIEWS/blocks/receiver-item.html |   6 ++
 web/VIEWS/blocks/station-item.html  |   2 +-
 web/VIEWS/station.html              | 156 ++++++++++++++++++++++++++++
 web/index.php                       |   1 +
 8 files changed, 210 insertions(+), 4 deletions(-)
 create mode 100644 web/CONTROLLERS/station.php
 create mode 100644 web/VIEWS/blocks/receiver-item.html
 create mode 100644 web/VIEWS/station.html

diff --git a/station/config.py b/station/config.py
index a713fb4..29d7882 100644
--- a/station/config.py
+++ b/station/config.py
@@ -1,4 +1,4 @@
 masterUrl     = "http://10.0.0.8"
-apiKey        = "5b20d5f4-11ce-4125-86fb-601e66143388"
-pullInterval  = 120 # in sec
+apiKey        = "783439f5-be14-4877-a396-6d8bc4783c3c"
+pullInterval  = 120  # in sec
 planInterval  = 1200 # in sec
\ No newline at end of file
diff --git a/station/planner.py b/station/planner.py
index 31f6839..0a43a90 100644
--- a/station/planner.py
+++ b/station/planner.py
@@ -29,7 +29,7 @@ def plan(lat, lon, alt, tle, transmitter, receiver, priority, name, delta = time
         start = ob[0]
         end   = ob[1]
 
-        if start <= last:
+        if start <= (last + timedelta(seconds=60)): # must be minute after last
             print(f"[INFO] alredy planed {name} at {start}")
             continue
 
diff --git a/web/CONTROLLERS/dashboard.php b/web/CONTROLLERS/dashboard.php
index 7d66fd4..7d4a253 100644
--- a/web/CONTROLLERS/dashboard.php
+++ b/web/CONTROLLERS/dashboard.php
@@ -75,6 +75,7 @@
     $stations                     = (new \wsos\database\core\table(\DAL\station::class))->getAll()->values;
     foreach ($stations as $station) {
         $context["stations"][] = [
+            "id"           => $station->id->get(),
             "name"         => $station->name->get(),
             "observations" => $observationTable->count("receiver.station.id == ?", [$station->id->get()]),
             "lastSeen"     => $station->lastSeen->strDelta()
diff --git a/web/CONTROLLERS/station.php b/web/CONTROLLERS/station.php
new file mode 100644
index 0000000..03375bd
--- /dev/null
+++ b/web/CONTROLLERS/station.php
@@ -0,0 +1,42 @@
+<?php
+    $container = new \wsos\structs\container();
+
+    $templates = $container->get("templateLoader");
+    $router    = $container->get("router");
+    $context   = $container->get("context");
+    $auth      = $container->get("auth");
+
+    // to show this page user must be logined
+    $auth->requireLogin();
+
+    //get station ID
+    $stationId = $router->getArgs()[0];
+
+    //get correct observation
+    $context["station"] = new \DAL\station(new \wsos\database\types\uuid($stationId));
+    $context["station"]->fetch();
+
+    $observationsTable   = new \wsos\database\core\table(\DAL\observation::class);
+    $ob                  = new \DAL\observation();
+
+    $context["receivers"] = new \wsos\database\core\table(\DAL\receiver::class);
+    $context["receivers"] = $context["receivers"]->query(
+        "station.id == ?", [$stationId]
+    )->values;
+
+    $context["station"] = [
+        "id"          => $context["station"]->id->get(),
+        "name"        => $context["station"]->name->get(),
+        "apiKey"      => $context["station"]->apiKey->get(),
+        "lat"         => $context["station"]->locator->get()["gps"]["lat"],
+        "lon"         => $context["station"]->locator->get()["gps"]["lon"],
+        "alt"         => $context["station"]->locator->get()["gps"]["alt"],
+        "lastSeen"    => $context["station"]->lastSeen->strDelta(),
+        "description" => $context["station"]->description->get(),
+        "success"     => $observationsTable->count("status==? && receiver.station.id == ?", [$ob->status->getVal("success"), $stationId]),
+        "fail"        => $observationsTable->count("status==? && receiver.station.id == ?", [$ob->status->getVal("fail"), $stationId])
+    ];
+
+    $templates->load("station.html");    
+    $templates->render($context);
+    $templates->show();
\ No newline at end of file
diff --git a/web/VIEWS/blocks/receiver-item.html b/web/VIEWS/blocks/receiver-item.html
new file mode 100644
index 0000000..ebc2591
--- /dev/null
+++ b/web/VIEWS/blocks/receiver-item.html
@@ -0,0 +1,6 @@
+<tr>
+    <td>{% BIND item.centerFrequency %}Hz</td>
+    <td>{% BIND item.bandwidth %}Hz</td>
+    <td>{% BIND item.gain %}</td>
+    <td></td>
+</tr>
\ No newline at end of file
diff --git a/web/VIEWS/blocks/station-item.html b/web/VIEWS/blocks/station-item.html
index 716a94b..ceb7c16 100644
--- a/web/VIEWS/blocks/station-item.html
+++ b/web/VIEWS/blocks/station-item.html
@@ -1,4 +1,4 @@
-<tr>
+<tr onclick="location.href = '/station/{% BIND item.id %}'">
     <td>{% BIND item.name %}</td>
     <td>{% BIND item.observations %}</td>
     <td>{% BIND item.lastSeen %} ago</td>
diff --git a/web/VIEWS/station.html b/web/VIEWS/station.html
new file mode 100644
index 0000000..fe7722f
--- /dev/null
+++ b/web/VIEWS/station.html
@@ -0,0 +1,156 @@
+<!doctype html>
+<html lang="en">
+{% INCLUDE layout/head.html %}
+
+<body>
+  <div class="page">
+    {% BINDINCLUDE layout/header.html logined %}
+
+    <div class="page-header d-print-none mt-4">
+      <div class="container-xl">
+        <div class="row g-2 align-items-center">
+          <div class="col">
+            <div class="page-pretitle">
+              {% BIND station.id %}
+            </div>
+            <h2 class="page-title">
+              Station {% BIND station.name %}
+            </h2>
+          </div>
+        </div>
+      </div>
+    </div>
+
+    <div class="page-body">
+      <div class="container-xl">
+        <div class="row row-deck row-cards">
+
+          <div class="col-12">
+            <div class="row row-cards">
+              <div class="col-12">
+                <div class="card">
+                  <div class="card-header">
+                    <h3 class="card-title">Base info</h3>
+                  </div>
+                  <div class="card-body">
+                    <div class="datagrid">
+                      <div class="datagrid-item">
+                        <div class="datagrid-title">Name</div>
+                        <div class="datagrid-content">
+                          {% BIND station.name %}
+                        </div>
+                      </div>
+                      <div class="datagrid-item">
+                        <div class="datagrid-title">GPS LAT</div>
+                        <div class="datagrid-content"><a
+                            href="https://www.google.com/maps/place/{% BIND station.lat %},{% BIND station.lon %}">
+                            {% BIND station.lat %}
+                          </a></div>
+                      </div>
+                      <div class="datagrid-item">
+                        <div class="datagrid-title">GPS LON</div>
+                        <div class="datagrid-content"><a
+                            href="https://www.google.com/maps/place/{% BIND station.lat %},{% BIND station.lon %}">
+                            {% BIND station.lon %}
+                          </a></div>
+                      </div>
+                      <div class="datagrid-item">
+                        <div class="datagrid-title">GPS ALT</div>
+                        <div class="datagrid-content">{% BIND station.alt %}m</div>
+                      </div>
+                      <div class="datagrid-item">
+                        <div class="datagrid-title">Last seen</div>
+                        <div class="datagrid-content">ago {% BIND station.lastSeen %}</div>
+                      </div>
+                      <div class="datagrid-item">
+                        <div class="datagrid-title">API Key</div>
+                        <div class="datagrid-content">
+                          <span class="status" style="font-size: 10px;">{% BIND station.apiKey %}</span>
+                        </div>
+                      </div>
+                      <div class="datagrid-item">
+                        <div class="datagrid-title">Success observations</div>
+                        <div class="datagrid-content">{% BIND station.success %}</div>
+                      </div>
+                      <div class="datagrid-item">
+                        <div class="datagrid-title">Fail observations</div>
+                        <div class="datagrid-content">{% BIND station.fail %}</div>
+                      </div>
+                      </div>
+                      <hr>
+                      <div class="col-12">
+                        <div class="datagrid-title">Description</div>
+                        <div class="datagrid-content">{% BIND station.description %}</div>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div>
+            </div>
+
+            <div class="col-lg-6">
+              <div class="row row-cards">
+                <div class="col-12">
+                  <div class="card">
+                    <div class="card-header">
+                      <h3 class="card-title">Station receivers</h3>
+                    </div>
+                    <div class="table-responsive scrollable" style="height: 400px">
+                      <table class="table card-table table-vcenter text-nowrap datatable table-hover">
+                        <thead>
+                          <tr>
+                            <th>Frequency</th>
+                            <th>Bandwidth</th>
+                            <th>Gain</th>
+                            <th>Actions</th>
+                          </tr>
+                        </thead>
+                        <tbody>
+                          {% FOREACH receivers RENDER blocks/receiver-item.html %}
+                        </tbody>
+                      </table>
+                    </div>
+                  </div>
+                </div>
+              </div>
+            </div>
+
+            <div class="col-lg-6">
+              <div class="row row-cards">
+                <div class="col-12">
+                  <div class="card">
+                    <div class="card-header">
+                      <h3 class="card-title">Station rotators</h3>
+                    </div>
+                    <div class="table-responsive scrollable" style="height: 400px">
+                      <table class="table card-table table-vcenter text-nowrap datatable table-hover">
+                        <thead>
+                          <tr>
+                            <th>Driver</th>
+                            <th>Port/Host</th>
+                            <th>Actions</th>
+                          </tr>
+                        </thead>
+                        <tbody>
+                          
+                        </tbody>
+                      </table>
+                    </div>
+                  </div>
+                </div>
+              </div>
+            </div>
+
+            
+            
+          </div>
+        </div>
+
+        <!-- Tabler Core -->
+        <script src="/dist/js/tabler.min.js?1668287865" defer=""></script>
+      </div>
+    </div>
+  </div>
+</body>
+
+</html>
\ No newline at end of file
diff --git a/web/index.php b/web/index.php
index a8297e5..90e8f1a 100644
--- a/web/index.php
+++ b/web/index.php
@@ -22,6 +22,7 @@
             "datatypes"    => ["controller" => __DIR__ . "/CONTROLLERS/datatypes.php",    "name" => "Data Types",   "icon" => "/static/icons/file-analytics.svg", "menu" => true],
             */
             "observation"  => ["controller" => __DIR__ . "/CONTROLLERS/observation.php",  "name" => "Observation view",                                           "menu" => false],
+            "station"      => ["controller" => __DIR__ . "/CONTROLLERS/station.php",      "name" => "Station view",                                               "menu" => false],
             "login"        => ["controller" => __DIR__ . "/CONTROLLERS/login.php",        "name" => "Login",                                                      "menu" => false],
             "api"          => ["controller" => __DIR__ . "/API/main.php",                 "name" => "api",                                                        "menu" => false],
         ],