diff --git a/web/API/main.php b/web/API/main.php index b463cf0..9acd417 100644 --- a/web/API/main.php +++ b/web/API/main.php @@ -13,7 +13,10 @@ //register API functions include_once(__DIR__ . "/observations.php"); include_once(__DIR__ . "/stations.php"); + include_once(__DIR__ . "/targets.php"); include_once(__DIR__ . "/crons.php"); + include_once(__DIR__ . "/transmitters.php"); + include_once(__DIR__ . "/receivers.php"); //init API $api->serve($router->getArgs()); \ No newline at end of file diff --git a/web/API/receivers.php b/web/API/receivers.php new file mode 100644 index 0000000..636fa18 --- /dev/null +++ b/web/API/receivers.php @@ -0,0 +1,67 @@ +id->set($params["id"]); + + $receiver->fetch(); + + /** + * Create array of autoPlan with names + */ + + $autoplan = new \wsos\structs\vector(); + foreach ($receiver->autoPlan->get() as $transmitterId) { + $transmitter = new \DAL\transmitter(); + $transmitter->id->set($transmitterId); + $transmitter->fetch(); + + $autoplan->append([ + "id" => $transmitter->id->get(), + "target" => $transmitter->target->get()->name->get(), + "modulation" => $transmitter->modulation->get()->name->get(), + "dataType" => $transmitter->dataType->get()->name->get(), + "freq" => $transmitter->centerFrequency->get(), + ]); + } + + return [ + "id" => $receiver->id->get(), + "freq" => $receiver->centerFrequency->get(), + "band" => $receiver->bandwidth->get(), + "params" => $receiver->params->get(), + "gain" => $receiver->gain->get(), + "autoPlan" => $autoplan, + "antenna" => $receiver->antenna->get()->id->get(), + "station" => $receiver->station->get()->id->get() + ]; + } + + function save($params) { + + $receiver = new \DAL\receiver(); + + if ($params["id"] <> "null") { + $receiver->id->set($params["id"]); + + // try fetch from DB? + $receiver->fetch(); + } + + $receiver->centerFrequency->set($params["freq"]); + $receiver->bandwidth->set($params["band"]); + $receiver->gain->set($params["gain"]); + $receiver->params->set(json_decode($params["params"])); + $receiver->autoPlan->set(json_decode($params["autoPlan"])); + $receiver->station->set($params["station"]); + $receiver->antenna->set($params["antenna"]); + + + $receiver->commit(); + + return [ + "id" => $receiver->id->get() + ]; + } \ No newline at end of file diff --git a/web/API/targets.php b/web/API/targets.php index 5e913aa..61f4c78 100644 --- a/web/API/targets.php +++ b/web/API/targets.php @@ -12,3 +12,17 @@ "locator" => $target->locator->get() ]; } + + function add($params) { + + $target = new \DAL\target(); + + $target->name->set($params["name"]); + $target->type->set($params["type"]); + $target->orbit->set($params["orbit"]); + $target->locator->set($params["locator"]); + + $target->commit(); + + return ["id" => $target->id->get()]; + } diff --git a/web/API/transmitters.php b/web/API/transmitters.php new file mode 100644 index 0000000..749e19b --- /dev/null +++ b/web/API/transmitters.php @@ -0,0 +1,49 @@ +id->set($params["id"]); + + $transmitter->fetch(); + + return [ + "id" => $transmitter->id->get(), + "freq" => $transmitter->centerFrequency->get(), + "band" => $transmitter->bandwidth->get(), + "priority" => $transmitter->priority->get(), + "pipe" => $transmitter->processPipe->get()->id->get(), + "dataType" => $transmitter->dataType->get()->id->get(), + "modulation" => $transmitter->modulation->get()->id->get(), + "antenna" => $transmitter->antenna->get()->id->get(), + "target" => $transmitter->target->get()->id->get(), + ]; + } + + function save($params) { + + $transmitter = new \DAL\transmitter(); + + if ($params["id"] <> "null") { + $transmitter->id->set($params["id"]); + + // try fetch from DB? + $transmitter->fetch(); + } + + $transmitter->centerFrequency->set($params["freq"]); + $transmitter->bandwidth->set($params["band"]); + $transmitter->priority->set($params["priority"]); + $transmitter->processPipe->set($params["pipe"]); + $transmitter->dataType->set($params["dataType"]); + $transmitter->modulation->set($params["modulation"]); + $transmitter->antenna->set($params["antenna"]); + $transmitter->target->set($params["target"]); + + $transmitter->commit(); + + return [ + "id" => $transmitter->id->get() + ]; + } \ No newline at end of file diff --git a/web/CONTROLLERS/station.php b/web/CONTROLLERS/station.php index 03375bd..022f6b8 100644 --- a/web/CONTROLLERS/station.php +++ b/web/CONTROLLERS/station.php @@ -37,6 +37,9 @@ "fail" => $observationsTable->count("status==? && receiver.station.id == ?", [$ob->status->getVal("fail"), $stationId]) ]; + $context["transmitters"] = new \wsos\database\core\table(\DAL\transmitter::class); + $context["antennas"] = new \wsos\database\core\table(\DAL\antenna::class); + $templates->load("station.html"); $templates->render($context); $templates->show(); \ No newline at end of file diff --git a/web/CONTROLLERS/target.php b/web/CONTROLLERS/target.php new file mode 100644 index 0000000..b578b34 --- /dev/null +++ b/web/CONTROLLERS/target.php @@ -0,0 +1,53 @@ +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 target ID + $targetID = $router->getArgs()[0]; + + //get correct observation + $context["target"] = new \DAL\target(new \wsos\database\types\uuid($targetID)); + $context["target"]->fetch(); + + $observationsTable = new \wsos\database\core\table(\DAL\observation::class); + $dummy_ob = new \DAL\observation(); + + $context["transmitters"] = new \wsos\database\core\table(\DAL\transmitter::class); + $context["transmitters"] = $context["transmitters"]->query( + "target.id == ?", [$targetID] + )->values; + + $locatorsKey = array_keys($context["target"]->locator->get()); + + $last = (new \wsos\database\core\table(\DAL\observation::class))->query("(transmitter.target.id == ?) && (status == ?)", [$targetID, $dummy_ob->status->getVal("success")], "DESC end", 1); + $last = $last->len() > 0 ? $last->values[0]->end->strDelta() . " ago" : "never"; + + $context["target"] = [ + "id" => $context["target"]->id->get(), + "name" => $context["target"]->name->get(), + "locatorsKey" => count($locatorsKey) > 0 ? $locatorsKey : ["none"], + "locators" => $context["target"]->locator->get(), + "type" => $context["target"]->type->get()->name->get(), + "description" => $context["target"]->description->get(), + "orbit" => $context["target"]->orbit->get(), + "transmitters" => count($context["transmitters"]), + "lastObservation" => $last, + "success" => $observationsTable->count("(status==?) && (transmitter.target.id == ?)", [$dummy_ob ->status->getVal("success"), $targetID]), + "fail" => $observationsTable->count("(status==?) && (transmitter.target.id == ?)", [$dummy_ob ->status->getVal("fail"), $targetID]) + ]; + + $context["pipes"] = new \wsos\database\core\table(\DAL\processPipe::class); + $context["dataTypes"] = new \wsos\database\core\table(\DAL\dataType::class); + $context["modulations"] = new \wsos\database\core\table(\DAL\modulation::class); + $context["antennas"] = new \wsos\database\core\table(\DAL\antenna::class); + + $templates->load("target.html"); + $templates->render($context); + $templates->show(); \ No newline at end of file diff --git a/web/CONTROLLERS/targets.php b/web/CONTROLLERS/targets.php index f6efe3b..a7eaafa 100644 --- a/web/CONTROLLERS/targets.php +++ b/web/CONTROLLERS/targets.php @@ -13,12 +13,13 @@ $targets = (new \wsos\database\core\table(\DAL\target::class))->getAll(); // create planed template observations - $ob = new \DAL\observation(); + $dummy_ob = new \DAL\observation(); + $dummy_target = new \DAL\target(); foreach ($targets->values as $target) { - $last = (new \wsos\database\core\table(\DAL\observation::class))->query("transmitter.target.id == ? && status == ?", [$target->id->get(), $ob->status->getVal("success")], "DESC end", 1); - $last = $last->len() > 0 ? "ago " . $last->values[0]->end->strDelta() : "never"; + $last = (new \wsos\database\core\table(\DAL\observation::class))->query("(transmitter.target.id == ?) && (status == ?)", [$target->id->get(), $dummy_ob->status->getVal("success")], "DESC end", 1); + $last = $last->len() > 0 ? $last->values[0]->end->strDelta() . " ago" : "never"; $observations = (new \wsos\database\core\table(\DAL\observation::class))->count("transmitter.target.id == ?", [$target->id->get()]); @@ -32,7 +33,9 @@ ]); } - $context["targets"] = $context["targets"]->values; + $context["targets"] = $context["targets"]->values; + $context["types"] = new \wsos\database\core\table(\DAL\targetType::class); + $context["orbit_types"] = $dummy_target->orbit->getOptions()->values; $templates->load("targets.html"); diff --git a/web/VIEWS/blocks/receiver-item.html b/web/VIEWS/blocks/receiver-item.html index ebc2591..e2db4ac 100644 --- a/web/VIEWS/blocks/receiver-item.html +++ b/web/VIEWS/blocks/receiver-item.html @@ -1,6 +1,6 @@ - + {% BIND item.centerFrequency %}Hz {% BIND item.bandwidth %}Hz + {% BIND item.antenna.name %} {% BIND item.gain %} - \ No newline at end of file diff --git a/web/VIEWS/blocks/transmitter-item.html b/web/VIEWS/blocks/transmitter-item.html new file mode 100644 index 0000000..b66f4ce --- /dev/null +++ b/web/VIEWS/blocks/transmitter-item.html @@ -0,0 +1,6 @@ + + {% BIND item.centerFrequency %}Hz + {% BIND item.bandwidth %}Hz + {% BIND item.modulation.name %} + {% BIND item.dataType.name %} + \ No newline at end of file diff --git a/web/VIEWS/station.html b/web/VIEWS/station.html index 71cfaed..0a28852 100644 --- a/web/VIEWS/station.html +++ b/web/VIEWS/station.html @@ -88,12 +88,18 @@ + +

Station receivers

+
@@ -101,8 +107,8 @@ + - @@ -121,6 +127,9 @@

Station rotators

+
Frequency BandwidthAntenna GainActions
@@ -195,6 +204,157 @@ + + + + diff --git a/web/VIEWS/target.html b/web/VIEWS/target.html new file mode 100644 index 0000000..d3169ef --- /dev/null +++ b/web/VIEWS/target.html @@ -0,0 +1,282 @@ + + +{% INCLUDE layout/head.html %} + + +
+ {% BINDINCLUDE layout/header.html logined %} + + + +
+
+
+ +
+
+
+
+
+

Base info

+
+
+
+
+
Name
+
+ {% BIND target.name %} +
+
+
+
Type
+
+ {% BIND target.type %} +
+
+
+
Orbit
+
+ {% BIND target.orbit %} +
+
+
+
Transmitters count
+
{% BIND target.transmitters %}
+
+
+
Last observation
+
{% BIND target.lastObservation %}
+
+
+
Locators
+
+ + {% FOREACH target.locatorsKey USE '(\ BIND item \)' %} +
+
+
+
Success observations
+
{% BIND target.success %}
+
+
+
Fail observations
+
{% BIND target.fail %}
+
+
+
+
+
Description
+
{% BIND target.description %}
+
+
+
+
+
+
+ + + +
+
+
+
+
+

Target transmitters

+ +
+
+
+ + + + + + + + + + {% FOREACH transmitters RENDER blocks/transmitter-item.html %} + +
FrequencyBandwidthModulationData Type
+
+
+
+
+
+ +
+
+
+
+
+

Target position

+
+
+ + + + + + + + + + stationId + +
DriverPort/HostActions
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/web/VIEWS/targets.html b/web/VIEWS/targets.html index 29f70d9..6e94a05 100644 --- a/web/VIEWS/targets.html +++ b/web/VIEWS/targets.html @@ -71,25 +71,10 @@ @@ -121,7 +140,7 @@ - + \ No newline at end of file diff --git a/web/index.php b/web/index.php index 124267a..96303a9 100644 --- a/web/index.php +++ b/web/index.php @@ -23,6 +23,7 @@ */ "observation" => ["controller" => __DIR__ . "/CONTROLLERS/observation.php", "name" => "Observation view", "menu" => false], "station" => ["controller" => __DIR__ . "/CONTROLLERS/station.php", "name" => "Station view", "menu" => false], + "target" => ["controller" => __DIR__ . "/CONTROLLERS/target.php", "name" => "Target", "menu" => false], "login" => ["controller" => __DIR__ . "/CONTROLLERS/login.php", "name" => "Login", "menu" => false], "api" => ["controller" => __DIR__ . "/API/main.php", "name" => "api", "menu" => false], ], diff --git a/web/seeds.php b/web/seeds.php index 2e22d5e..80223f4 100644 --- a/web/seeds.php +++ b/web/seeds.php @@ -24,9 +24,9 @@ $msumrType->name->set("MSU-MR"); $msumrType->commit(); - $telemetryType = new \DAL\dataType(); - $telemetryType->name->set("Telemetry"); - $telemetryType->commit(); + $beaconType = new \DAL\dataType(); + $beaconType->name->set("Beacon"); + $beaconType->commit(); /** * Antennas seeds @@ -350,7 +350,7 @@ $maxvalierCW = new \DAL\transmitter(); $maxvalierCW->target->set($maxvalier); - $maxvalierCW->dataType->set($telemetryType); + $maxvalierCW->dataType->set($beaconType); $maxvalierCW->bandwidth->set(120000); $maxvalierCW->centerFrequency->set(145960000); $maxvalierCW->modulation->set($cw); diff --git a/web/static/js/station.js b/web/static/js/station.js index 306935d..4f64d1c 100644 --- a/web/static/js/station.js +++ b/web/static/js/station.js @@ -1,3 +1,5 @@ +var openReceiver = null; + function updateStation(id) { var station = new FormData(); @@ -25,6 +27,99 @@ function updateStation(id) { xhttp.send(station); } +function addAutoPlan() { + var sel = document.getElementById("select-transmitter"); + + // not not add is added + if (getAutoPlaned().includes(sel.value)) return; + + var text = sel.options[sel.selectedIndex].text; + + document.getElementById("receiver-auto-plan").innerHTML += + '' + text + ''; +} + +function getAutoPlaned() { + var list = []; + + var area = document.getElementById("receiver-auto-plan"); + var transmitters = area.getElementsByClassName("status"); + + for (var i = 0; i < transmitters.length; i++) { + list.push(transmitters[i].getAttribute("name")); + } + + return list; +} + +function loadReceiver(id) { + var receiver = new FormData(); + + receiver.append("id", id); + + var xhttp = new XMLHttpRequest(); + xhttp.onreadystatechange = function() { + if (this.readyState == 4 && this.status == 200) { + var data = JSON.parse(this.responseText); + + document.getElementById("receiver-freq").value = data.freq; + document.getElementById("receiver-band").value = data.band; + document.getElementById("receiver-antenna").value = data.antenna; + document.getElementById("receiver-gain").value = data.gain; + document.getElementById("receiver-params").value = JSON.stringify(data.params); + + var block = ""; + + for (var i = 0; i < data.autoPlan.values.length; i++) { + block += '' + + data.autoPlan.values[i].target + " - " + + data.autoPlan.values[i].modulation + " - " + + data.autoPlan.values[i].dataType + " @ " + + data.autoPlan.values[i].freq + 'Hz'; + } + + document.getElementById("receiver-auto-plan").innerHTML = block; + + document.getElementById("receiverModal").click(); + openReceiver = data.id; + } + }; + + xhttp.open("POST", "/api/receiver/get", true); + xhttp.send(receiver); +} + +function saveReceiver(stationID) { + var receiver = new FormData(); + + var freq = document.getElementById("receiver-freq").value; + var band = document.getElementById("receiver-band").value; + var antenna = document.getElementById("receiver-antenna").value; + var gain = document.getElementById("receiver-gain").value; + var params = document.getElementById("receiver-params").value; + var autoPlan = JSON.stringify(getAutoPlaned()); + var id = openReceiver; + + receiver.append('id', id); + receiver.append('freq', freq); + receiver.append('band', band); + receiver.append('antenna', antenna); + receiver.append('gain', gain); + receiver.append('params', params); + receiver.append('autoPlan', autoPlan); + receiver.append('station', stationID); + + var xhttp = new XMLHttpRequest(); + xhttp.onreadystatechange = function() { + if (this.readyState == 4 && this.status == 200) { + location.reload(); + } + }; + + xhttp.open("POST", "/api/receiver/save", true); + xhttp.send(receiver); +} + function deleteStation(id) { var station = new FormData(); diff --git a/web/static/js/target.js b/web/static/js/target.js new file mode 100644 index 0000000..6b5de65 --- /dev/null +++ b/web/static/js/target.js @@ -0,0 +1,64 @@ +var openTransmitter = null; + +function save(targetID) { + var transmitter = new FormData(); + + var freq = document.getElementById("transmitter-freq").value; + var band = document.getElementById("transmitter-band").value; + var antenna = document.getElementById("transmitter-antenna").value; + var modulation = document.getElementById("transmitter-modulation").value; + var datatype = document.getElementById("transmitter-datatype").value; + var priority = document.getElementById("transmitter-priority").value; + var pipe = document.getElementById("transmitter-pipe").value; + var id = openTransmitter; + + transmitter.append('id', id); + transmitter.append('freq', freq); + transmitter.append('band', band); + transmitter.append('antenna', antenna); + transmitter.append('modulation', modulation); + transmitter.append('dataType', datatype); + transmitter.append('priority', priority); + transmitter.append('pipe', pipe); + transmitter.append('target', targetID); + + var xhttp = new XMLHttpRequest(); + xhttp.onreadystatechange = function() { + if (this.readyState == 4 && this.status == 200) { + location.reload(); + } + }; + + xhttp.open("POST", "/api/transmitter/save", true); + xhttp.send(transmitter); +} + +function loadTransmitter(id) { + var xhttp = new XMLHttpRequest(); + + var transmitter = new FormData(); + + transmitter.append('id', id); + + xhttp.open("POST", "/api/transmitter/get", true); + + xhttp.onreadystatechange = function() { + if (this.readyState == 4 && this.status == 200) { + var data = JSON.parse(this.responseText); + + document.getElementById("transmitter-freq").value = data.freq; + document.getElementById("transmitter-band").value = data.band; + document.getElementById("transmitter-antenna").value = data.antenna; + document.getElementById("transmitter-modulation").value = data.modulation; + document.getElementById("transmitter-datatype").value = data.dataType; + document.getElementById("transmitter-priority").value = data.priority; + document.getElementById("transmitter-pipe").value = data.pipe; + + document.getElementById("transmitterModal").click(); + openTransmitter = data.id; + } + }; + + + xhttp.send(transmitter); +} \ No newline at end of file diff --git a/web/static/js/targets.js b/web/static/js/targets.js new file mode 100644 index 0000000..8555a67 --- /dev/null +++ b/web/static/js/targets.js @@ -0,0 +1,52 @@ +function add() { + var target = new FormData(); + + var name = document.getElementById("target-name").value; + var type = document.getElementById("target-type").value; + var orbit = document.getElementById("target-orbit").value; + var locator = document.getElementById("target-locator-type").value; + + if (locator == "tle-locator") { + locator = { + "tle": { + "line1": document.getElementById("tle-locator-line1").value, + "line2": document.getElementById("tle-locator-line2").value + } + }; + } else { + locator = {}; + } + + locator = JSON.stringify(locator); + + + target.append('name', name); + target.append('type', type); + target.append('orbit', orbit); + target.append('locator', locator); + + var xhttp = new XMLHttpRequest(); + xhttp.onreadystatechange = function() { + if (this.readyState == 4 && this.status == 200) { + location.href = "/target/" + JSON.parse(this.responseText).id; + } + }; + + xhttp.open("POST", "/api/target/add", true); + xhttp.send(target); +} + +function locatorChange() { + var locatorType = document.getElementById("target-locator-type").value; + + //hide all locators options + var locators = document.getElementsByClassName("locatorType"); + + for (var i = 0; i < locators.length; i++) { + locators[i].style.display = "none"; + } + + if (locatorType != "none") { + document.getElementById(locatorType).style.display = "block"; + } +} \ No newline at end of file