kopia lustrzana https://github.com/cyoung/stratux
Replace windoze CRLF with Linux LF in web files
rodzic
22867df1f4
commit
816411b3ee
|
@ -1,21 +1,21 @@
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<span class="panel_label">Developer Mode Items</span>
|
<span class="panel_label">Developer Mode Items</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<div class="panel-group col-sm-6">
|
<div class="panel-group col-sm-6">
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">Restart Stratux application</div>
|
<div class="panel-heading">Restart Stratux application</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<div class="form-group reset-flow">
|
<div class="form-group reset-flow">
|
||||||
<div class="col-xs-12">
|
<div class="col-xs-12">
|
||||||
<a ng-click="postRestart()" ui-turn-off="modalRestartApp" class="btn btn-primary">Restart Application</a>
|
<a ng-click="postRestart()" ui-turn-off="modalRestartApp" class="btn btn-primary">Restart Application</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
|
@ -1,104 +1,104 @@
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
<div class="col-sm-6">
|
<div class="col-sm-6">
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading"><span class="panel_label">GPS</span></div>
|
<div class="panel-heading"><span class="panel_label">GPS</span></div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<span class="col-xs-12">
|
<span class="col-xs-12">
|
||||||
<div class="map-container">
|
<div class="map-container">
|
||||||
<div id="map_display" class="world-map" ng-attr-style="background-position:{{map_pos_x + 'px ' + map_pos_y + 'px'}}; width:{{map_width}}px; height:{{map_height}}px;">
|
<div id="map_display" class="world-map" ng-attr-style="background-position:{{map_pos_x + 'px ' + map_pos_y + 'px'}}; width:{{map_width}}px; height:{{map_height}}px;">
|
||||||
<div class="mark-position" ng-style="{left: map_mark_x+'px', top: map_mark_y+'px'}">
|
<div class="mark-position" ng-style="{left: map_mark_x+'px', top: map_mark_y+'px'}">
|
||||||
<span class="fa fa-crosshairs"></span>
|
<span class="fa fa-crosshairs"></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="separator"></div>
|
<div class="separator"></div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<strong class="col-xs-6 text-center">Location:</strong>
|
<strong class="col-xs-6 text-center">Location:</strong>
|
||||||
<strong class="col-xs-6 text-center">Track:</strong>
|
<strong class="col-xs-6 text-center">Track:</strong>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<span class="col-xs-6 text-center">{{gps_lat}}, {{gps_lon}} ± {{gps_accuracy}} m <br> {{gps_alt}} ± {{gps_vert_accuracy}} ft @ {{gps_vert_speed}} ft/min</span>
|
<span class="col-xs-6 text-center">{{gps_lat}}, {{gps_lon}} ± {{gps_accuracy}} m <br> {{gps_alt}} ± {{gps_vert_accuracy}} ft @ {{gps_vert_speed}} ft/min</span>
|
||||||
<span class="col-xs-6 text-center">{{gps_track}}° @ {{gps_speed}} KTS</span>
|
<span class="col-xs-6 text-center">{{gps_track}}° @ {{gps_speed}} KTS</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<span class="panel_label">Satellites</span>
|
<span class="panel_label">Satellites</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-body towers-page">
|
<div class="panel-body towers-page">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<span class="col-xs-3"><strong>Satellite</strong></span>
|
<span class="col-xs-3"><strong>Satellite</strong></span>
|
||||||
<!--<span class="col-xs-2 text-right"><strong>NMEA Code</strong></span>-->
|
<!--<span class="col-xs-2 text-right"><strong>NMEA Code</strong></span>-->
|
||||||
<span class="col-xs-3 text-right"><strong>Elevation</strong></span>
|
<span class="col-xs-3 text-right"><strong>Elevation</strong></span>
|
||||||
<span class="col-xs-3 text-right"><strong>Azimuth</strong></span>
|
<span class="col-xs-3 text-right"><strong>Azimuth</strong></span>
|
||||||
<span class="col-xs-3 text-right"><strong>Signal</strong></span>
|
<span class="col-xs-3 text-right"><strong>Signal</strong></span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row" ng-repeat="satellite in data_list | orderBy: 'SatelliteNMEA'">
|
<div class="row" ng-repeat="satellite in data_list | orderBy: 'SatelliteNMEA'">
|
||||||
<div class="separator"></div>
|
<div class="separator"></div>
|
||||||
<span class="col-xs-3">{{satellite.SatelliteID}}<span ng-show="satellite.InSolution"> ✅</span></span>
|
<span class="col-xs-3">{{satellite.SatelliteID}}<span ng-show="satellite.InSolution"> ✅</span></span>
|
||||||
<!--<span class="col-xs-2 text-right">{{satellite.SatelliteNMEA}}</span>-->
|
<!--<span class="col-xs-2 text-right">{{satellite.SatelliteNMEA}}</span>-->
|
||||||
<span class="col-xs-3 text-right">{{satellite.Elevation < -5 ? "---" : satellite.Elevation}}°</span>
|
<span class="col-xs-3 text-right">{{satellite.Elevation < -5 ? "---" : satellite.Elevation}}°</span>
|
||||||
<span class="col-xs-3 text-right">{{satellite.Azimuth < 0 ? "---" : satellite.Azimuth}}°</span>
|
<span class="col-xs-3 text-right">{{satellite.Azimuth < 0 ? "---" : satellite.Azimuth}}°</span>
|
||||||
<span class="col-xs-3 text-right">{{satellite.Signal < 1 ? "---" : satellite.Signal}}<span style="font-size:50%"> dB-Hz</span></span>
|
<span class="col-xs-3 text-right">{{satellite.Signal < 1 ? "---" : satellite.Signal}}<span style="font-size:50%"> dB-Hz</span></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="separator"></div>
|
<div class="separator"></div>
|
||||||
<div class="panel-footer">
|
<div class="panel-footer">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<label class="col-xs-6">GPS solution:</label>
|
<label class="col-xs-6">GPS solution:</label>
|
||||||
<span class="col-xs-6">{{SolutionText}}</span>
|
<span class="col-xs-6">{{SolutionText}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<label class="col-xs-6">Summary:</label>
|
<label class="col-xs-6">Summary:</label>
|
||||||
<span class="col-xs-6">{{Satellites}} in solution; {{GPS_satellites_seen}} seen; {{GPS_satellites_tracked}} tracked</span>
|
<span class="col-xs-6">{{Satellites}} in solution; {{GPS_satellites_seen}} seen; {{GPS_satellites_tracked}} tracked</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-6">
|
<div class="col-sm-6">
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading"><span class="panel_label">AHRS</span></div>
|
<div class="panel-heading"><span class="panel_label">AHRS</span></div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<span class="col-xs-12">
|
<span class="col-xs-12">
|
||||||
<div id="ahrs_display">
|
<div id="ahrs_display">
|
||||||
<object id="attitude_indicator" data="../img/ai.svg" type="image/svg+xml">
|
<object id="attitude_indicator" data="../img/ai.svg" type="image/svg+xml">
|
||||||
Your browser doesn't support svg.
|
Your browser doesn't support svg.
|
||||||
</object>
|
</object>
|
||||||
</div>
|
</div>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="separator"></div>
|
<div class="separator"></div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<strong class="col-xs-3 text-center">Heading:</strong>
|
<strong class="col-xs-3 text-center">Heading:</strong>
|
||||||
<strong class="col-xs-3 text-center">Pitch:</strong>
|
<strong class="col-xs-3 text-center">Pitch:</strong>
|
||||||
<strong class="col-xs-3 text-center">Roll:</strong>
|
<strong class="col-xs-3 text-center">Roll:</strong>
|
||||||
<strong class="col-xs-3 text-center">P-Alt:</strong>
|
<strong class="col-xs-3 text-center">P-Alt:</strong>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<span class="col-xs-3 text-center">{{ahrs_heading}}°</span>
|
<span class="col-xs-3 text-center">{{ahrs_heading}}°</span>
|
||||||
<span class="col-xs-3 text-center">{{ahrs_pitch}}°</span>
|
<span class="col-xs-3 text-center">{{ahrs_pitch}}°</span>
|
||||||
<span class="col-xs-3 text-center">{{ahrs_roll}}°</span>
|
<span class="col-xs-3 text-center">{{ahrs_roll}}°</span>
|
||||||
<span class="col-xs-3 text-center">{{ahrs_alt}} ft</span>
|
<span class="col-xs-3 text-center">{{ahrs_alt}} ft</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">Raw GPS / AHRS Data</div>
|
<div class="panel-heading">Raw GPS / AHRS Data</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<pre>{{raw_data}}</pre>
|
<pre>{{raw_data}}</pre>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
-->
|
-->
|
||||||
|
|
|
@ -1,180 +1,180 @@
|
||||||
angular.module('appControllers').controller('GPSCtrl', GPSCtrl); // get the main module contollers set
|
angular.module('appControllers').controller('GPSCtrl', GPSCtrl); // get the main module contollers set
|
||||||
GPSCtrl.$inject = ['$rootScope', '$scope', '$state', '$http', '$interval']; // Inject my dependencies
|
GPSCtrl.$inject = ['$rootScope', '$scope', '$state', '$http', '$interval']; // Inject my dependencies
|
||||||
|
|
||||||
// create our controller function with all necessary logic
|
// create our controller function with all necessary logic
|
||||||
function GPSCtrl($rootScope, $scope, $state, $http, $interval) {
|
function GPSCtrl($rootScope, $scope, $state, $http, $interval) {
|
||||||
$scope.$parent.helppage = 'plates/gps-help.html';
|
$scope.$parent.helppage = 'plates/gps-help.html';
|
||||||
$scope.data_list = [];
|
$scope.data_list = [];
|
||||||
|
|
||||||
var status = {};
|
var status = {};
|
||||||
var display_area_size = -1;
|
var display_area_size = -1;
|
||||||
|
|
||||||
function sizeMap() {
|
function sizeMap() {
|
||||||
var width = 0;
|
var width = 0;
|
||||||
var el = document.getElementById("map_display").parentElement;
|
var el = document.getElementById("map_display").parentElement;
|
||||||
width = el.offsetWidth; // was (- (2 * el.offsetLeft))
|
width = el.offsetWidth; // was (- (2 * el.offsetLeft))
|
||||||
if (width !== display_area_size) {
|
if (width !== display_area_size) {
|
||||||
display_area_size = width;
|
display_area_size = width;
|
||||||
$scope.map_width = width;
|
$scope.map_width = width;
|
||||||
$scope.map_height = width *0.5;
|
$scope.map_height = width *0.5;
|
||||||
}
|
}
|
||||||
return width;
|
return width;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setGeoReferenceMap(la, lo) {
|
function setGeoReferenceMap(la, lo) {
|
||||||
// Mercator projection
|
// Mercator projection
|
||||||
// var map = "img/world.png";
|
// var map = "img/world.png";
|
||||||
var map_width = 2530;
|
var map_width = 2530;
|
||||||
var map_height = 1603;
|
var map_height = 1603;
|
||||||
var map_zero_x = 1192;
|
var map_zero_x = 1192;
|
||||||
var map_zero_y = 1124;
|
var map_zero_y = 1124;
|
||||||
var font_size = 18; // size of font used for marker
|
var font_size = 18; // size of font used for marker
|
||||||
|
|
||||||
sizeMap();
|
sizeMap();
|
||||||
var div_width = $scope.map_width;
|
var div_width = $scope.map_width;
|
||||||
var div_height = $scope.map_height;
|
var div_height = $scope.map_height;
|
||||||
|
|
||||||
|
|
||||||
// longitude: just scale and shift
|
// longitude: just scale and shift
|
||||||
var x = (map_width * (180 + lo) / 360) - (map_width/2 - map_zero_x); // longitude_shift;
|
var x = (map_width * (180 + lo) / 360) - (map_width/2 - map_zero_x); // longitude_shift;
|
||||||
|
|
||||||
// latitude: using the Mercator projection
|
// latitude: using the Mercator projection
|
||||||
la_rad = la * Math.PI / 180; // convert from degrees to radians
|
la_rad = la * Math.PI / 180; // convert from degrees to radians
|
||||||
merc_n = Math.log(Math.tan((la_rad / 2) + (Math.PI / 4))); // do the Mercator projection (w/ equator of 2pi units)
|
merc_n = Math.log(Math.tan((la_rad / 2) + (Math.PI / 4))); // do the Mercator projection (w/ equator of 2pi units)
|
||||||
var y = (map_height / 2) - (map_width * merc_n / (2 * Math.PI)) - (map_height/2 - map_zero_y); // fit it to our map
|
var y = (map_height / 2) - (map_width * merc_n / (2 * Math.PI)) - (map_height/2 - map_zero_y); // fit it to our map
|
||||||
|
|
||||||
// dot = '<div style="position:absolute; width:' + dot_size + 'px; height:' + dot_size + 'px; top:' + y + 'px; left:' + x + 'px; background:#ff7f00;"></div>';
|
// dot = '<div style="position:absolute; width:' + dot_size + 'px; height:' + dot_size + 'px; top:' + y + 'px; left:' + x + 'px; background:#ff7f00;"></div>';
|
||||||
// <img src="map-world-medium.png" style="position:absolute;top:0px;left:0px">
|
// <img src="map-world-medium.png" style="position:absolute;top:0px;left:0px">
|
||||||
$scope.map_pos_x = map_width - Math.round(x - (div_width / 2));
|
$scope.map_pos_x = map_width - Math.round(x - (div_width / 2));
|
||||||
$scope.map_pos_y = map_height - Math.round(y - (div_height / 2));
|
$scope.map_pos_y = map_height - Math.round(y - (div_height / 2));
|
||||||
|
|
||||||
$scope.map_mark_x = Math.round((div_width - (font_size * 0.85)) / 2);
|
$scope.map_mark_x = Math.round((div_width - (font_size * 0.85)) / 2);
|
||||||
$scope.map_mark_y = Math.round((div_height - font_size) / 2);
|
$scope.map_mark_y = Math.round((div_height - font_size) / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function loadStatus(data) { // mySituation
|
function loadStatus(data) { // mySituation
|
||||||
status = angular.fromJson(data);
|
status = angular.fromJson(data);
|
||||||
// consider using angular.extend()
|
// consider using angular.extend()
|
||||||
$scope.raw_data = angular.toJson(data, true); // makes it pretty
|
$scope.raw_data = angular.toJson(data, true); // makes it pretty
|
||||||
|
|
||||||
|
|
||||||
$scope.Satellites = status.Satellites;
|
$scope.Satellites = status.Satellites;
|
||||||
$scope.GPS_satellites_tracked = status.SatellitesTracked;
|
$scope.GPS_satellites_tracked = status.SatellitesTracked;
|
||||||
$scope.GPS_satellites_seen = status.SatellitesSeen;
|
$scope.GPS_satellites_seen = status.SatellitesSeen;
|
||||||
$scope.Quality = status.Quality;
|
$scope.Quality = status.Quality;
|
||||||
|
|
||||||
var solutionText = "No Fix";
|
var solutionText = "No Fix";
|
||||||
if (status.Quality == 2) {
|
if (status.Quality == 2) {
|
||||||
solutionText = "GPS + SBAS (WAAS / EGNOS)";
|
solutionText = "GPS + SBAS (WAAS / EGNOS)";
|
||||||
} else if (status.Quality == 1) {
|
} else if (status.Quality == 1) {
|
||||||
solutionText = "3D GPS"
|
solutionText = "3D GPS"
|
||||||
}
|
}
|
||||||
$scope.SolutionText = solutionText;
|
$scope.SolutionText = solutionText;
|
||||||
|
|
||||||
$scope.gps_accuracy = status.Accuracy.toFixed(1);
|
$scope.gps_accuracy = status.Accuracy.toFixed(1);
|
||||||
$scope.gps_vert_accuracy = (status.AccuracyVert*3.2808).toFixed(1); // accuracy is in meters, need to display in ft
|
$scope.gps_vert_accuracy = (status.AccuracyVert*3.2808).toFixed(1); // accuracy is in meters, need to display in ft
|
||||||
|
|
||||||
|
|
||||||
// NACp should be an integer value in the range of 0 .. 11
|
// NACp should be an integer value in the range of 0 .. 11
|
||||||
// var accuracies = ["≥ 10 NM", "< 10 NM", "< 4 NM", "< 2 NM", "< 1 NM", "< 0.5 NM", "< 0.3 NM", "< 0.1 NM", "< 100 m", "< 30 m", "< 10 m", "< 3 m"];
|
// var accuracies = ["≥ 10 NM", "< 10 NM", "< 4 NM", "< 2 NM", "< 1 NM", "< 0.5 NM", "< 0.3 NM", "< 0.1 NM", "< 100 m", "< 30 m", "< 10 m", "< 3 m"];
|
||||||
// $scope.gps_accuracy = accuracies[status.NACp];
|
// $scope.gps_accuracy = accuracies[status.NACp];
|
||||||
// "LastFixLocalTime":"2015-10-11T16:47:03.523085162Z"
|
// "LastFixLocalTime":"2015-10-11T16:47:03.523085162Z"
|
||||||
|
|
||||||
$scope.gps_lat = status.Lat.toFixed(5); // result is string
|
$scope.gps_lat = status.Lat.toFixed(5); // result is string
|
||||||
$scope.gps_lon = status.Lng.toFixed(5); // result is string
|
$scope.gps_lon = status.Lng.toFixed(5); // result is string
|
||||||
$scope.gps_alt = Math.round(status.Alt);
|
$scope.gps_alt = Math.round(status.Alt);
|
||||||
$scope.gps_track = status.TrueCourse;
|
$scope.gps_track = status.TrueCourse;
|
||||||
$scope.gps_speed = status.GroundSpeed;
|
$scope.gps_speed = status.GroundSpeed;
|
||||||
$scope.gps_vert_speed = status.GPSVertVel.toFixed(1);
|
$scope.gps_vert_speed = status.GPSVertVel.toFixed(1);
|
||||||
|
|
||||||
// "LastGroundTrackTime":"0001-01-01T00:00:00Z"
|
// "LastGroundTrackTime":"0001-01-01T00:00:00Z"
|
||||||
|
|
||||||
/* not currently used
|
/* not currently used
|
||||||
$scope.ahrs_temp = status.Temp;
|
$scope.ahrs_temp = status.Temp;
|
||||||
*/
|
*/
|
||||||
$scope.ahrs_alt = Math.round(status.Pressure_alt);
|
$scope.ahrs_alt = Math.round(status.Pressure_alt);
|
||||||
|
|
||||||
$scope.ahrs_heading = Math.round(status.Gyro_heading);
|
$scope.ahrs_heading = Math.round(status.Gyro_heading);
|
||||||
// pitch and roll are in degrees
|
// pitch and roll are in degrees
|
||||||
$scope.ahrs_pitch = Math.round(status.Pitch);
|
$scope.ahrs_pitch = Math.round(status.Pitch);
|
||||||
$scope.ahrs_roll = Math.round(status.Roll);
|
$scope.ahrs_roll = Math.round(status.Roll);
|
||||||
// "LastAttitudeTime":"2015-10-11T16:47:03.534615187Z"
|
// "LastAttitudeTime":"2015-10-11T16:47:03.534615187Z"
|
||||||
|
|
||||||
setGeoReferenceMap(status.Lat, status.Lng);
|
setGeoReferenceMap(status.Lat, status.Lng);
|
||||||
|
|
||||||
// $scope.$apply();
|
// $scope.$apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getStatus() {
|
function getStatus() {
|
||||||
// Simple GET request example (note: responce is asynchronous)
|
// Simple GET request example (note: responce is asynchronous)
|
||||||
$http.get(URL_GPS_GET).
|
$http.get(URL_GPS_GET).
|
||||||
then(function (response) {
|
then(function (response) {
|
||||||
loadStatus(response.data);
|
loadStatus(response.data);
|
||||||
ahrs.animate(0.1, $scope.ahrs_pitch, $scope.ahrs_roll, $scope.ahrs_heading);
|
ahrs.animate(0.1, $scope.ahrs_pitch, $scope.ahrs_roll, $scope.ahrs_heading);
|
||||||
// $scope.$apply();
|
// $scope.$apply();
|
||||||
}, function (response) {
|
}, function (response) {
|
||||||
$scope.raw_data = "error getting gps / ahrs status";
|
$scope.raw_data = "error getting gps / ahrs status";
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSatellites() {
|
function getSatellites() {
|
||||||
// Simple GET request example (note: response is asynchronous)
|
// Simple GET request example (note: response is asynchronous)
|
||||||
$http.get(URL_SATELLITES_GET).
|
$http.get(URL_SATELLITES_GET).
|
||||||
then(function (response) {
|
then(function (response) {
|
||||||
loadSatellites(response.data);
|
loadSatellites(response.data);
|
||||||
}, function (response) {
|
}, function (response) {
|
||||||
$scope.raw_data = "error getting satellite data";
|
$scope.raw_data = "error getting satellite data";
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function setSatellite(obj, new_satellite) {
|
function setSatellite(obj, new_satellite) {
|
||||||
new_satellite.SatelliteNMEA = obj.SatelliteNMEA;
|
new_satellite.SatelliteNMEA = obj.SatelliteNMEA;
|
||||||
new_satellite.SatelliteID = obj.SatelliteID; // Formatted code indicating source and PRN code. e.g. S138==WAAS satellite 138, G2==GPS satellites 2
|
new_satellite.SatelliteID = obj.SatelliteID; // Formatted code indicating source and PRN code. e.g. S138==WAAS satellite 138, G2==GPS satellites 2
|
||||||
new_satellite.Elevation = obj.Elevation; // Angle above local horizon, -xx to +90
|
new_satellite.Elevation = obj.Elevation; // Angle above local horizon, -xx to +90
|
||||||
new_satellite.Azimuth = obj.Azimuth; // Bearing (degrees true), 0-359
|
new_satellite.Azimuth = obj.Azimuth; // Bearing (degrees true), 0-359
|
||||||
new_satellite.Signal = obj.Signal; // Signal strength, 0 - 99; -99 indicates no reception
|
new_satellite.Signal = obj.Signal; // Signal strength, 0 - 99; -99 indicates no reception
|
||||||
new_satellite.InSolution = obj.InSolution; // is this satellite in the position solution
|
new_satellite.InSolution = obj.InSolution; // is this satellite in the position solution
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadSatellites(data) {
|
function loadSatellites(data) {
|
||||||
if (($scope === undefined) || ($scope === null))
|
if (($scope === undefined) || ($scope === null))
|
||||||
return; // we are getting called once after clicking away from the status page
|
return; // we are getting called once after clicking away from the status page
|
||||||
|
|
||||||
var satellites = data; // it seems the json was already converted to an object list by the http request
|
var satellites = data; // it seems the json was already converted to an object list by the http request
|
||||||
$scope.raw_data = angular.toJson(data, true);
|
$scope.raw_data = angular.toJson(data, true);
|
||||||
|
|
||||||
$scope.data_list.length = 0; // clear array
|
$scope.data_list.length = 0; // clear array
|
||||||
// we need to use an array so AngularJS can perform sorting; it also means we need to loop to find a tower in the towers set
|
// we need to use an array so AngularJS can perform sorting; it also means we need to loop to find a tower in the towers set
|
||||||
for (var key in satellites) {
|
for (var key in satellites) {
|
||||||
//if (satellites[key].Messages_last_minute > 0) {
|
//if (satellites[key].Messages_last_minute > 0) {
|
||||||
var new_satellite = {};
|
var new_satellite = {};
|
||||||
setSatellite(satellites[key], new_satellite);
|
setSatellite(satellites[key], new_satellite);
|
||||||
$scope.data_list.push(new_satellite); // add to start of array
|
$scope.data_list.push(new_satellite); // add to start of array
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
// $scope.$apply();
|
// $scope.$apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
var updateStatus = $interval(function () {
|
var updateStatus = $interval(function () {
|
||||||
// refresh GPS/AHRS status once each 200 milliseconds (aka polling)
|
// refresh GPS/AHRS status once each 200 milliseconds (aka polling)
|
||||||
getStatus();
|
getStatus();
|
||||||
getSatellites();
|
getSatellites();
|
||||||
}, (2 * 100), 0, false);
|
}, (2 * 100), 0, false);
|
||||||
|
|
||||||
$state.get('gps').onEnter = function () {
|
$state.get('gps').onEnter = function () {
|
||||||
// everything gets handled correctly by the controller
|
// everything gets handled correctly by the controller
|
||||||
};
|
};
|
||||||
|
|
||||||
$state.get('gps').onExit = function () {
|
$state.get('gps').onExit = function () {
|
||||||
// stop polling for gps/ahrs status
|
// stop polling for gps/ahrs status
|
||||||
$interval.cancel(updateStatus);
|
$interval.cancel(updateStatus);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// GPS/AHRS Controller tasks go here
|
// GPS/AHRS Controller tasks go here
|
||||||
var ahrs = new ahrsRenderer("ahrs_display");
|
var ahrs = new ahrsRenderer("ahrs_display");
|
||||||
ahrs.init();
|
ahrs.init();
|
||||||
ahrs.orientation(0, 0, 90);
|
ahrs.orientation(0, 0, 90);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
angular.module('appControllers').controller('LogsCtrl', LogsCtrl); // get the main module contollers set
|
angular.module('appControllers').controller('LogsCtrl', LogsCtrl); // get the main module contollers set
|
||||||
LogsCtrl.$inject = ['$scope', '$state', '$http']; // Inject my dependencies
|
LogsCtrl.$inject = ['$scope', '$state', '$http']; // Inject my dependencies
|
||||||
|
|
||||||
// create our controller function with all necessary logic
|
// create our controller function with all necessary logic
|
||||||
function LogsCtrl($scope, $state, $http) {
|
function LogsCtrl($scope, $state, $http) {
|
||||||
$scope.$parent.helppage = 'plates/logs-help.html';
|
$scope.$parent.helppage = 'plates/logs-help.html';
|
||||||
|
|
||||||
// just a couple environment variables that may bve useful for dev/debugging but otherwise not significant
|
// just a couple environment variables that may bve useful for dev/debugging but otherwise not significant
|
||||||
$scope.userAgent = navigator.userAgent;
|
$scope.userAgent = navigator.userAgent;
|
||||||
$scope.deviceViewport = 'screen = ' + window.screen.width + ' x ' + window.screen.height;
|
$scope.deviceViewport = 'screen = ' + window.screen.width + ' x ' + window.screen.height;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,201 +1,201 @@
|
||||||
angular.module('appControllers').controller('SettingsCtrl', SettingsCtrl); // get the main module contollers set
|
angular.module('appControllers').controller('SettingsCtrl', SettingsCtrl); // get the main module contollers set
|
||||||
SettingsCtrl.$inject = ['$rootScope', '$scope', '$state', '$location', '$window', '$http']; // Inject my dependencies
|
SettingsCtrl.$inject = ['$rootScope', '$scope', '$state', '$location', '$window', '$http']; // Inject my dependencies
|
||||||
|
|
||||||
// create our controller function with all necessary logic
|
// create our controller function with all necessary logic
|
||||||
function SettingsCtrl($rootScope, $scope, $state, $location, $window, $http) {
|
function SettingsCtrl($rootScope, $scope, $state, $location, $window, $http) {
|
||||||
|
|
||||||
$scope.$parent.helppage = 'plates/settings-help.html';
|
$scope.$parent.helppage = 'plates/settings-help.html';
|
||||||
|
|
||||||
var toggles = ['UAT_Enabled', 'ES_Enabled', 'Ping_Enabled', 'GPS_Enabled', 'Sensors_Enabled', 'DisplayTrafficSource', 'DEBUG', 'ReplayLog'];
|
var toggles = ['UAT_Enabled', 'ES_Enabled', 'Ping_Enabled', 'GPS_Enabled', 'Sensors_Enabled', 'DisplayTrafficSource', 'DEBUG', 'ReplayLog'];
|
||||||
var settings = {};
|
var settings = {};
|
||||||
for (i = 0; i < toggles.length; i++) {
|
for (i = 0; i < toggles.length; i++) {
|
||||||
settings[toggles[i]] = undefined;
|
settings[toggles[i]] = undefined;
|
||||||
}
|
}
|
||||||
$scope.update_files = '';
|
$scope.update_files = '';
|
||||||
|
|
||||||
function loadSettings(data) {
|
function loadSettings(data) {
|
||||||
settings = angular.fromJson(data);
|
settings = angular.fromJson(data);
|
||||||
// consider using angular.extend()
|
// consider using angular.extend()
|
||||||
$scope.rawSettings = angular.toJson(data, true);
|
$scope.rawSettings = angular.toJson(data, true);
|
||||||
$scope.visible_serialout = false;
|
$scope.visible_serialout = false;
|
||||||
if ((settings.SerialOutputs !== undefined) && (settings.SerialOutputs !== null) && (settings.SerialOutputs['/dev/serialout0'] !== undefined)) {
|
if ((settings.SerialOutputs !== undefined) && (settings.SerialOutputs !== null) && (settings.SerialOutputs['/dev/serialout0'] !== undefined)) {
|
||||||
$scope.Baud = settings.SerialOutputs['/dev/serialout0'].Baud;
|
$scope.Baud = settings.SerialOutputs['/dev/serialout0'].Baud;
|
||||||
$scope.visible_serialout = true;
|
$scope.visible_serialout = true;
|
||||||
}
|
}
|
||||||
$scope.UAT_Enabled = settings.UAT_Enabled;
|
$scope.UAT_Enabled = settings.UAT_Enabled;
|
||||||
$scope.ES_Enabled = settings.ES_Enabled;
|
$scope.ES_Enabled = settings.ES_Enabled;
|
||||||
$scope.Ping_Enabled = settings.Ping_Enabled;
|
$scope.Ping_Enabled = settings.Ping_Enabled;
|
||||||
$scope.GPS_Enabled = settings.GPS_Enabled;
|
$scope.GPS_Enabled = settings.GPS_Enabled;
|
||||||
$scope.Sensors_Enabled = settings.Sensors_Enabled;
|
$scope.Sensors_Enabled = settings.Sensors_Enabled;
|
||||||
$scope.DisplayTrafficSource = settings.DisplayTrafficSource;
|
$scope.DisplayTrafficSource = settings.DisplayTrafficSource;
|
||||||
$scope.DEBUG = settings.DEBUG;
|
$scope.DEBUG = settings.DEBUG;
|
||||||
$scope.ReplayLog = settings.ReplayLog;
|
$scope.ReplayLog = settings.ReplayLog;
|
||||||
$scope.PPM = settings.PPM;
|
$scope.PPM = settings.PPM;
|
||||||
$scope.WatchList = settings.WatchList;
|
$scope.WatchList = settings.WatchList;
|
||||||
$scope.OwnshipModeS = settings.OwnshipModeS;
|
$scope.OwnshipModeS = settings.OwnshipModeS;
|
||||||
$scope.DeveloperMode = settings.DeveloperMode;
|
$scope.DeveloperMode = settings.DeveloperMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSettings() {
|
function getSettings() {
|
||||||
// Simple GET request example (note: responce is asynchronous)
|
// Simple GET request example (note: responce is asynchronous)
|
||||||
$http.get(URL_SETTINGS_GET).
|
$http.get(URL_SETTINGS_GET).
|
||||||
then(function (response) {
|
then(function (response) {
|
||||||
loadSettings(response.data);
|
loadSettings(response.data);
|
||||||
// $scope.$apply();
|
// $scope.$apply();
|
||||||
}, function (response) {
|
}, function (response) {
|
||||||
$scope.rawSettings = "error getting settings";
|
$scope.rawSettings = "error getting settings";
|
||||||
for (i = 0; i < toggles.length; i++) {
|
for (i = 0; i < toggles.length; i++) {
|
||||||
settings[toggles[i]] = false;
|
settings[toggles[i]] = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
function setSettings(msg) {
|
function setSettings(msg) {
|
||||||
// Simple POST request example (note: responce is asynchronous)
|
// Simple POST request example (note: responce is asynchronous)
|
||||||
$http.post(URL_SETTINGS_SET, msg).
|
$http.post(URL_SETTINGS_SET, msg).
|
||||||
then(function (response) {
|
then(function (response) {
|
||||||
loadSettings(response.data);
|
loadSettings(response.data);
|
||||||
// $scope.$apply();
|
// $scope.$apply();
|
||||||
}, function (response) {
|
}, function (response) {
|
||||||
$scope.rawSettings = "error setting settings";
|
$scope.rawSettings = "error setting settings";
|
||||||
for (i = 0; i < toggles.length; i++) {
|
for (i = 0; i < toggles.length; i++) {
|
||||||
settings[toggles[i]] = false;
|
settings[toggles[i]] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getSettings();
|
getSettings();
|
||||||
|
|
||||||
$scope.$watchGroup(toggles, function (newValues, oldValues, scope) {
|
$scope.$watchGroup(toggles, function (newValues, oldValues, scope) {
|
||||||
var newsettings = {}
|
var newsettings = {}
|
||||||
var dirty = false;
|
var dirty = false;
|
||||||
for (i = 0; i < newValues.length; i++) {
|
for (i = 0; i < newValues.length; i++) {
|
||||||
if ((newValues[i] !== undefined) && (settings[toggles[i]] !== undefined)) {
|
if ((newValues[i] !== undefined) && (settings[toggles[i]] !== undefined)) {
|
||||||
if (newValues[i] !== settings[toggles[i]]) {
|
if (newValues[i] !== settings[toggles[i]]) {
|
||||||
settings[toggles[i]] = newValues[i];
|
settings[toggles[i]] = newValues[i];
|
||||||
newsettings[toggles[i]] = newValues[i];
|
newsettings[toggles[i]] = newValues[i];
|
||||||
dirty = true;
|
dirty = true;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (dirty) {
|
if (dirty) {
|
||||||
// console.log(angular.toJson(newsettings));
|
// console.log(angular.toJson(newsettings));
|
||||||
setSettings(angular.toJson(newsettings));
|
setSettings(angular.toJson(newsettings));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$scope.updateppm = function () {
|
$scope.updateppm = function () {
|
||||||
settings["PPM"] = 0
|
settings["PPM"] = 0
|
||||||
if (($scope.PPM !== undefined) && ($scope.PPM !== null) && ($scope.PPM !== settings["PPM"])) {
|
if (($scope.PPM !== undefined) && ($scope.PPM !== null) && ($scope.PPM !== settings["PPM"])) {
|
||||||
settings["PPM"] = parseInt($scope.PPM);
|
settings["PPM"] = parseInt($scope.PPM);
|
||||||
newsettings = {
|
newsettings = {
|
||||||
"PPM": settings["PPM"]
|
"PPM": settings["PPM"]
|
||||||
};
|
};
|
||||||
// console.log(angular.toJson(newsettings));
|
// console.log(angular.toJson(newsettings));
|
||||||
setSettings(angular.toJson(newsettings));
|
setSettings(angular.toJson(newsettings));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.updateBaud = function () {
|
$scope.updateBaud = function () {
|
||||||
settings["Baud"] = 0
|
settings["Baud"] = 0
|
||||||
if (($scope.Baud !== undefined) && ($scope.Baud !== null) && ($scope.Baud !== settings["Baud"])) {
|
if (($scope.Baud !== undefined) && ($scope.Baud !== null) && ($scope.Baud !== settings["Baud"])) {
|
||||||
settings["Baud"] = parseInt($scope.Baud);
|
settings["Baud"] = parseInt($scope.Baud);
|
||||||
newsettings = {
|
newsettings = {
|
||||||
"Baud": settings["Baud"]
|
"Baud": settings["Baud"]
|
||||||
};
|
};
|
||||||
// console.log(angular.toJson(newsettings));
|
// console.log(angular.toJson(newsettings));
|
||||||
setSettings(angular.toJson(newsettings));
|
setSettings(angular.toJson(newsettings));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.updatewatchlist = function () {
|
$scope.updatewatchlist = function () {
|
||||||
if ($scope.WatchList !== settings["WatchList"]) {
|
if ($scope.WatchList !== settings["WatchList"]) {
|
||||||
settings["WatchList"] = "";
|
settings["WatchList"] = "";
|
||||||
if ($scope.WatchList !== undefined) {
|
if ($scope.WatchList !== undefined) {
|
||||||
settings["WatchList"] = $scope.WatchList.toUpperCase();
|
settings["WatchList"] = $scope.WatchList.toUpperCase();
|
||||||
}
|
}
|
||||||
newsettings = {
|
newsettings = {
|
||||||
"WatchList": settings["WatchList"]
|
"WatchList": settings["WatchList"]
|
||||||
};
|
};
|
||||||
// console.log(angular.toJson(newsettings));
|
// console.log(angular.toJson(newsettings));
|
||||||
setSettings(angular.toJson(newsettings));
|
setSettings(angular.toJson(newsettings));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
$scope.updatemodes = function () {
|
$scope.updatemodes = function () {
|
||||||
if ($scope.OwnshipModeS !== settings["OwnshipModeS"]) {
|
if ($scope.OwnshipModeS !== settings["OwnshipModeS"]) {
|
||||||
settings["OwnshipModeS"] = $scope.OwnshipModeS.toUpperCase();
|
settings["OwnshipModeS"] = $scope.OwnshipModeS.toUpperCase();
|
||||||
newsettings = {
|
newsettings = {
|
||||||
"OwnshipModeS": $scope.OwnshipModeS.toUpperCase()
|
"OwnshipModeS": $scope.OwnshipModeS.toUpperCase()
|
||||||
};
|
};
|
||||||
// console.log(angular.toJson(newsettings));
|
// console.log(angular.toJson(newsettings));
|
||||||
setSettings(angular.toJson(newsettings));
|
setSettings(angular.toJson(newsettings));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.postShutdown = function () {
|
$scope.postShutdown = function () {
|
||||||
$window.location.href = "/";
|
$window.location.href = "/";
|
||||||
$location.path('/home');
|
$location.path('/home');
|
||||||
$http.post(URL_SHUTDOWN).
|
$http.post(URL_SHUTDOWN).
|
||||||
then(function (response) {
|
then(function (response) {
|
||||||
// do nothing
|
// do nothing
|
||||||
// $scope.$apply();
|
// $scope.$apply();
|
||||||
}, function (response) {
|
}, function (response) {
|
||||||
// do nothing
|
// do nothing
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.postReboot = function () {
|
$scope.postReboot = function () {
|
||||||
$window.location.href = "/";
|
$window.location.href = "/";
|
||||||
$location.path('/home');
|
$location.path('/home');
|
||||||
$http.post(URL_REBOOT).
|
$http.post(URL_REBOOT).
|
||||||
then(function (response) {
|
then(function (response) {
|
||||||
// do nothing
|
// do nothing
|
||||||
// $scope.$apply();
|
// $scope.$apply();
|
||||||
}, function (response) {
|
}, function (response) {
|
||||||
// do nothing
|
// do nothing
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.setUploadFile = function (files) {
|
$scope.setUploadFile = function (files) {
|
||||||
$scope.update_files = files;
|
$scope.update_files = files;
|
||||||
$scope.$apply();
|
$scope.$apply();
|
||||||
}
|
}
|
||||||
$scope.resetUploadFile = function () {
|
$scope.resetUploadFile = function () {
|
||||||
$scope.update_files = '';
|
$scope.update_files = '';
|
||||||
$scope.$apply();
|
$scope.$apply();
|
||||||
}
|
}
|
||||||
$scope.uploadFile = function () {
|
$scope.uploadFile = function () {
|
||||||
var fd = new FormData();
|
var fd = new FormData();
|
||||||
//Take the first selected file
|
//Take the first selected file
|
||||||
var file = $scope.update_files[0];
|
var file = $scope.update_files[0];
|
||||||
// check for empty string
|
// check for empty string
|
||||||
if (file === undefined || file === null) {
|
if (file === undefined || file === null) {
|
||||||
alert ("update file not selected")
|
alert ("update file not selected")
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var filename = file.name;
|
var filename = file.name;
|
||||||
// check for expected file naming convention
|
// check for expected file naming convention
|
||||||
var re = /^update.*\.sh$/;
|
var re = /^update.*\.sh$/;
|
||||||
if (!re.exec(filename)) {
|
if (!re.exec(filename)) {
|
||||||
alert ("file does not appear to be an update")
|
alert ("file does not appear to be an update")
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fd.append("update_file", file);
|
fd.append("update_file", file);
|
||||||
|
|
||||||
$http.post(URL_UPDATE_UPLOAD, fd, {
|
$http.post(URL_UPDATE_UPLOAD, fd, {
|
||||||
withCredentials: true,
|
withCredentials: true,
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': undefined
|
'Content-Type': undefined
|
||||||
},
|
},
|
||||||
transformRequest: angular.identity
|
transformRequest: angular.identity
|
||||||
}).success(function (data) {
|
}).success(function (data) {
|
||||||
alert("success. wait 60 seconds and refresh home page to verify new version.");
|
alert("success. wait 60 seconds and refresh home page to verify new version.");
|
||||||
window.location.replace("/");
|
window.location.replace("/");
|
||||||
}).error(function (data) {
|
}).error(function (data) {
|
||||||
alert("error");
|
alert("error");
|
||||||
});
|
});
|
||||||
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,241 +1,241 @@
|
||||||
angular.module('appControllers').controller('TrafficCtrl', TrafficCtrl); // get the main module contollers set
|
angular.module('appControllers').controller('TrafficCtrl', TrafficCtrl); // get the main module contollers set
|
||||||
TrafficCtrl.$inject = ['$rootScope', '$scope', '$state', '$http', '$interval']; // Inject my dependencies
|
TrafficCtrl.$inject = ['$rootScope', '$scope', '$state', '$http', '$interval']; // Inject my dependencies
|
||||||
|
|
||||||
// create our controller function with all necessary logic
|
// create our controller function with all necessary logic
|
||||||
function TrafficCtrl($rootScope, $scope, $state, $http, $interval) {
|
function TrafficCtrl($rootScope, $scope, $state, $http, $interval) {
|
||||||
|
|
||||||
$scope.$parent.helppage = 'plates/traffic-help.html';
|
$scope.$parent.helppage = 'plates/traffic-help.html';
|
||||||
$scope.data_list = [];
|
$scope.data_list = [];
|
||||||
$scope.data_list_invalid = [];
|
$scope.data_list_invalid = [];
|
||||||
|
|
||||||
function utcTimeString(epoc) {
|
function utcTimeString(epoc) {
|
||||||
var time = "";
|
var time = "";
|
||||||
var val;
|
var val;
|
||||||
var d = new Date(epoc);
|
var d = new Date(epoc);
|
||||||
val = d.getUTCHours();
|
val = d.getUTCHours();
|
||||||
time += (val < 10 ? "0" + val : "" + val);
|
time += (val < 10 ? "0" + val : "" + val);
|
||||||
val = d.getUTCMinutes();
|
val = d.getUTCMinutes();
|
||||||
time += ":" + (val < 10 ? "0" + val : "" + val);
|
time += ":" + (val < 10 ? "0" + val : "" + val);
|
||||||
val = d.getUTCSeconds();
|
val = d.getUTCSeconds();
|
||||||
time += ":" + (val < 10 ? "0" + val : "" + val);
|
time += ":" + (val < 10 ? "0" + val : "" + val);
|
||||||
time += "Z";
|
time += "Z";
|
||||||
return time;
|
return time;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
|
||||||
function dmsString(val) {
|
function dmsString(val) {
|
||||||
return [0 | val,
|
return [0 | val,
|
||||||
'° ',
|
'° ',
|
||||||
0 | (val < 0 ? val = -val : val) % 1 * 60,
|
0 | (val < 0 ? val = -val : val) % 1 * 60,
|
||||||
"' ",
|
"' ",
|
||||||
0 | val * 60 % 1 * 60,
|
0 | val * 60 % 1 * 60,
|
||||||
'"'].join('');
|
'"'].join('');
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// chop off seconds for space
|
// chop off seconds for space
|
||||||
function dmsString(val) {
|
function dmsString(val) {
|
||||||
var deg;
|
var deg;
|
||||||
var min;
|
var min;
|
||||||
deg = 0 | val;
|
deg = 0 | val;
|
||||||
min = 0 | (val < 0 ? val = -val : val) % 1 * 60;
|
min = 0 | (val < 0 ? val = -val : val) % 1 * 60;
|
||||||
|
|
||||||
return [deg*deg < 100 ? "0" + deg : deg,
|
return [deg*deg < 100 ? "0" + deg : deg,
|
||||||
'° ',
|
'° ',
|
||||||
min < 10 ? "0" + min : min,
|
min < 10 ? "0" + min : min,
|
||||||
"' "].join('');
|
"' "].join('');
|
||||||
}
|
}
|
||||||
|
|
||||||
function setAircraft(obj, new_traffic) {
|
function setAircraft(obj, new_traffic) {
|
||||||
new_traffic.icao_int = obj.Icao_addr;
|
new_traffic.icao_int = obj.Icao_addr;
|
||||||
new_traffic.targettype = obj.TargetType;
|
new_traffic.targettype = obj.TargetType;
|
||||||
new_traffic.signal = obj.SignalLevel;
|
new_traffic.signal = obj.SignalLevel;
|
||||||
new_traffic.addr_symb ='\u2708';
|
new_traffic.addr_symb ='\u2708';
|
||||||
if (new_traffic.targettype > 3) {
|
if (new_traffic.targettype > 3) {
|
||||||
new_traffic.addr_symb ='\ud83d\udce1';
|
new_traffic.addr_symb ='\ud83d\udce1';
|
||||||
}
|
}
|
||||||
new_traffic.icao = obj.Icao_addr.toString(16).toUpperCase();
|
new_traffic.icao = obj.Icao_addr.toString(16).toUpperCase();
|
||||||
new_traffic.tail = obj.Tail;
|
new_traffic.tail = obj.Tail;
|
||||||
new_traffic.reg = obj.Reg;
|
new_traffic.reg = obj.Reg;
|
||||||
if (obj.Squawk == 0) {
|
if (obj.Squawk == 0) {
|
||||||
new_traffic.squawk = "----";
|
new_traffic.squawk = "----";
|
||||||
} else {
|
} else {
|
||||||
new_traffic.squawk = obj.Squawk;
|
new_traffic.squawk = obj.Squawk;
|
||||||
}
|
}
|
||||||
new_traffic.addr_type = obj.Addr_type;
|
new_traffic.addr_type = obj.Addr_type;
|
||||||
new_traffic.lat = dmsString(obj.Lat);
|
new_traffic.lat = dmsString(obj.Lat);
|
||||||
new_traffic.lon = dmsString(obj.Lng);
|
new_traffic.lon = dmsString(obj.Lng);
|
||||||
var n = Math.round(obj.Alt / 25) * 25;
|
var n = Math.round(obj.Alt / 25) * 25;
|
||||||
new_traffic.alt = n.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
new_traffic.alt = n.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
||||||
var s = Math.round(obj.Speed / 5) * 5;
|
var s = Math.round(obj.Speed / 5) * 5;
|
||||||
if (obj.Speed_valid) {
|
if (obj.Speed_valid) {
|
||||||
new_traffic.speed = s.toString();
|
new_traffic.speed = s.toString();
|
||||||
new_traffic.heading = Math.round(obj.Track / 5) * 5;
|
new_traffic.heading = Math.round(obj.Track / 5) * 5;
|
||||||
} else {
|
} else {
|
||||||
new_traffic.speed = "---";
|
new_traffic.speed = "---";
|
||||||
new_traffic.heading = "---";
|
new_traffic.heading = "---";
|
||||||
}
|
}
|
||||||
new_traffic.vspeed = Math.round(obj.Vvel / 100) * 100
|
new_traffic.vspeed = Math.round(obj.Vvel / 100) * 100
|
||||||
var timestamp = Date.parse(obj.Timestamp);
|
var timestamp = Date.parse(obj.Timestamp);
|
||||||
new_traffic.time = utcTimeString(timestamp);
|
new_traffic.time = utcTimeString(timestamp);
|
||||||
new_traffic.age = obj.Age;
|
new_traffic.age = obj.Age;
|
||||||
new_traffic.ageLastAlt = obj.AgeLastAlt;
|
new_traffic.ageLastAlt = obj.AgeLastAlt;
|
||||||
new_traffic.src = obj.Last_source; // 1=ES, 2=UAT
|
new_traffic.src = obj.Last_source; // 1=ES, 2=UAT
|
||||||
new_traffic.bearing = Math.round(obj.Bearing); // degrees true
|
new_traffic.bearing = Math.round(obj.Bearing); // degrees true
|
||||||
new_traffic.dist = (obj.Distance/1852); // nautical miles
|
new_traffic.dist = (obj.Distance/1852); // nautical miles
|
||||||
// return new_aircraft;
|
// return new_aircraft;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function connect($scope) {
|
function connect($scope) {
|
||||||
if (($scope === undefined) || ($scope === null))
|
if (($scope === undefined) || ($scope === null))
|
||||||
return; // we are getting called once after clicking away from the status page
|
return; // we are getting called once after clicking away from the status page
|
||||||
|
|
||||||
if (($scope.socket === undefined) || ($scope.socket === null)) {
|
if (($scope.socket === undefined) || ($scope.socket === null)) {
|
||||||
socket = new WebSocket(URL_TRAFFIC_WS);
|
socket = new WebSocket(URL_TRAFFIC_WS);
|
||||||
$scope.socket = socket; // store socket in scope for enter/exit usage
|
$scope.socket = socket; // store socket in scope for enter/exit usage
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.ConnectState = "Disconnected";
|
$scope.ConnectState = "Disconnected";
|
||||||
|
|
||||||
socket.onopen = function (msg) {
|
socket.onopen = function (msg) {
|
||||||
// $scope.ConnectStyle = "label-success";
|
// $scope.ConnectStyle = "label-success";
|
||||||
$scope.ConnectState = "Connected";
|
$scope.ConnectState = "Connected";
|
||||||
};
|
};
|
||||||
|
|
||||||
socket.onclose = function (msg) {
|
socket.onclose = function (msg) {
|
||||||
// $scope.ConnectStyle = "label-danger";
|
// $scope.ConnectStyle = "label-danger";
|
||||||
$scope.ConnectState = "Disconnected";
|
$scope.ConnectState = "Disconnected";
|
||||||
$scope.$apply();
|
$scope.$apply();
|
||||||
setTimeout(connect, 1000);
|
setTimeout(connect, 1000);
|
||||||
};
|
};
|
||||||
|
|
||||||
socket.onerror = function (msg) {
|
socket.onerror = function (msg) {
|
||||||
// $scope.ConnectStyle = "label-danger";
|
// $scope.ConnectStyle = "label-danger";
|
||||||
$scope.ConnectState = "Problem";
|
$scope.ConnectState = "Problem";
|
||||||
$scope.$apply();
|
$scope.$apply();
|
||||||
};
|
};
|
||||||
|
|
||||||
socket.onmessage = function (msg) {
|
socket.onmessage = function (msg) {
|
||||||
|
|
||||||
|
|
||||||
console.log('Received traffic update.')
|
console.log('Received traffic update.')
|
||||||
|
|
||||||
var message = JSON.parse(msg.data);
|
var message = JSON.parse(msg.data);
|
||||||
$scope.raw_data = angular.toJson(msg.data, true);
|
$scope.raw_data = angular.toJson(msg.data, true);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// we need to use an array so AngularJS can perform sorting; it also means we need to loop to find an aircraft in the traffic set
|
// we need to use an array so AngularJS can perform sorting; it also means we need to loop to find an aircraft in the traffic set
|
||||||
var validIdx = -1;
|
var validIdx = -1;
|
||||||
var invalidIdx = -1;
|
var invalidIdx = -1;
|
||||||
for (var i = 0, len = $scope.data_list.length; i < len; i++) {
|
for (var i = 0, len = $scope.data_list.length; i < len; i++) {
|
||||||
if ($scope.data_list[i].icao_int === message.Icao_addr) {
|
if ($scope.data_list[i].icao_int === message.Icao_addr) {
|
||||||
setAircraft(message, $scope.data_list[i]);
|
setAircraft(message, $scope.data_list[i]);
|
||||||
validIdx = i;
|
validIdx = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var i = 0, len = $scope.data_list_invalid.length; i < len; i++) {
|
for (var i = 0, len = $scope.data_list_invalid.length; i < len; i++) {
|
||||||
if ($scope.data_list_invalid[i].icao_int === message.Icao_addr) {
|
if ($scope.data_list_invalid[i].icao_int === message.Icao_addr) {
|
||||||
setAircraft(message, $scope.data_list_invalid[i]);
|
setAircraft(message, $scope.data_list_invalid[i]);
|
||||||
invalidIdx = i;
|
invalidIdx = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((validIdx < 0) && (message.Position_valid)) {
|
if ((validIdx < 0) && (message.Position_valid)) {
|
||||||
var new_traffic = {};
|
var new_traffic = {};
|
||||||
setAircraft(message, new_traffic);
|
setAircraft(message, new_traffic);
|
||||||
$scope.data_list.unshift(new_traffic); // add to start of valid array.
|
$scope.data_list.unshift(new_traffic); // add to start of valid array.
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((invalidIdx < 0) && (!message.Position_valid)) {
|
if ((invalidIdx < 0) && (!message.Position_valid)) {
|
||||||
var new_traffic = {};
|
var new_traffic = {};
|
||||||
setAircraft(message, new_traffic);
|
setAircraft(message, new_traffic);
|
||||||
$scope.data_list_invalid.unshift(new_traffic); // add to start of invalid array.
|
$scope.data_list_invalid.unshift(new_traffic); // add to start of invalid array.
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle the negative cases of those above - where an aircraft moves from "valid" to "invalid" or vice-versa.
|
// Handle the negative cases of those above - where an aircraft moves from "valid" to "invalid" or vice-versa.
|
||||||
if ((validIdx >= 0) && !message.Position_valid) {
|
if ((validIdx >= 0) && !message.Position_valid) {
|
||||||
// Position is not valid any more. Remove from "valid" table.
|
// Position is not valid any more. Remove from "valid" table.
|
||||||
$scope.data_list.splice(validIdx, 1);
|
$scope.data_list.splice(validIdx, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((invalidIdx >= 0) && message.Position_valid) {
|
if ((invalidIdx >= 0) && message.Position_valid) {
|
||||||
// Position is now valid. Remove from "invalid" table.
|
// Position is now valid. Remove from "invalid" table.
|
||||||
$scope.data_list_invalid.splice(invalidIdx, 1);
|
$scope.data_list_invalid.splice(invalidIdx, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.$apply();
|
$scope.$apply();
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
var getClock = $interval(function () {
|
var getClock = $interval(function () {
|
||||||
$http.get(URL_STATUS_GET).
|
$http.get(URL_STATUS_GET).
|
||||||
then(function (response) {
|
then(function (response) {
|
||||||
globalStatus = angular.fromJson(response.data);
|
globalStatus = angular.fromJson(response.data);
|
||||||
|
|
||||||
var tempClock = new Date(Date.parse(globalStatus.Clock));
|
var tempClock = new Date(Date.parse(globalStatus.Clock));
|
||||||
var clockString = tempClock.toUTCString();
|
var clockString = tempClock.toUTCString();
|
||||||
$scope.Clock = clockString;
|
$scope.Clock = clockString;
|
||||||
|
|
||||||
var tempUptimeClock = new Date(Date.parse(globalStatus.UptimeClock));
|
var tempUptimeClock = new Date(Date.parse(globalStatus.UptimeClock));
|
||||||
var uptimeClockString = tempUptimeClock.toUTCString();
|
var uptimeClockString = tempUptimeClock.toUTCString();
|
||||||
$scope.UptimeClock = uptimeClockString;
|
$scope.UptimeClock = uptimeClockString;
|
||||||
|
|
||||||
var tempLocalClock = new Date;
|
var tempLocalClock = new Date;
|
||||||
$scope.LocalClock = tempLocalClock.toUTCString();
|
$scope.LocalClock = tempLocalClock.toUTCString();
|
||||||
$scope.SecondsFast = (tempClock-tempLocalClock)/1000;
|
$scope.SecondsFast = (tempClock-tempLocalClock)/1000;
|
||||||
|
|
||||||
$scope.GPS_connected = globalStatus.GPS_connected;
|
$scope.GPS_connected = globalStatus.GPS_connected;
|
||||||
|
|
||||||
}, function (response) {
|
}, function (response) {
|
||||||
// nop
|
// nop
|
||||||
});
|
});
|
||||||
}, 500, 0, false);
|
}, 500, 0, false);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// perform cleanup every 10 seconds
|
// perform cleanup every 10 seconds
|
||||||
var clearStaleTraffic = $interval(function () {
|
var clearStaleTraffic = $interval(function () {
|
||||||
// remove stale aircraft = anything more than 59 seconds without a position update
|
// remove stale aircraft = anything more than 59 seconds without a position update
|
||||||
var cutoff = 59;
|
var cutoff = 59;
|
||||||
|
|
||||||
// Clean up "valid position" table.
|
// Clean up "valid position" table.
|
||||||
for (var i = $scope.data_list.length; i > 0; i--) {
|
for (var i = $scope.data_list.length; i > 0; i--) {
|
||||||
if ($scope.data_list[i - 1].age >= cutoff) {
|
if ($scope.data_list[i - 1].age >= cutoff) {
|
||||||
$scope.data_list.splice(i - 1, 1);
|
$scope.data_list.splice(i - 1, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean up "invalid position" table.
|
// Clean up "invalid position" table.
|
||||||
for (var i = $scope.data_list_invalid.length; i > 0; i--) {
|
for (var i = $scope.data_list_invalid.length; i > 0; i--) {
|
||||||
if (($scope.data_list_invalid[i - 1].age >= cutoff) || ($scope.data_list_invalid[i - 1].ageLastAlt >= cutoff)) {
|
if (($scope.data_list_invalid[i - 1].age >= cutoff) || ($scope.data_list_invalid[i - 1].ageLastAlt >= cutoff)) {
|
||||||
$scope.data_list_invalid.splice(i - 1, 1);
|
$scope.data_list_invalid.splice(i - 1, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, (1000 * 10), 0, false);
|
}, (1000 * 10), 0, false);
|
||||||
|
|
||||||
|
|
||||||
$state.get('traffic').onEnter = function () {
|
$state.get('traffic').onEnter = function () {
|
||||||
// everything gets handled correctly by the controller
|
// everything gets handled correctly by the controller
|
||||||
};
|
};
|
||||||
|
|
||||||
$state.get('traffic').onExit = function () {
|
$state.get('traffic').onExit = function () {
|
||||||
// disconnect from the socket
|
// disconnect from the socket
|
||||||
if (($scope.socket !== undefined) && ($scope.socket !== null)) {
|
if (($scope.socket !== undefined) && ($scope.socket !== null)) {
|
||||||
$scope.socket.close();
|
$scope.socket.close();
|
||||||
$scope.socket = null;
|
$scope.socket = null;
|
||||||
}
|
}
|
||||||
// stop stale traffic cleanup
|
// stop stale traffic cleanup
|
||||||
$interval.cancel(clearStaleTraffic);
|
$interval.cancel(clearStaleTraffic);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Traffic Controller tasks
|
// Traffic Controller tasks
|
||||||
connect($scope); // connect - opens a socket and listens for messages
|
connect($scope); // connect - opens a socket and listens for messages
|
||||||
};
|
};
|
|
@ -1,261 +1,261 @@
|
||||||
angular.module('appControllers').controller('WeatherCtrl', WeatherCtrl); // get the main module contollers set
|
angular.module('appControllers').controller('WeatherCtrl', WeatherCtrl); // get the main module contollers set
|
||||||
WeatherCtrl.$inject = ['$rootScope', '$scope', '$state', '$http', '$interval']; // Inject my dependencies
|
WeatherCtrl.$inject = ['$rootScope', '$scope', '$state', '$http', '$interval']; // Inject my dependencies
|
||||||
|
|
||||||
// create our controller function with all necessary logic
|
// create our controller function with all necessary logic
|
||||||
function WeatherCtrl($rootScope, $scope, $state, $http, $interval) {
|
function WeatherCtrl($rootScope, $scope, $state, $http, $interval) {
|
||||||
|
|
||||||
var CONF_WATCHLIST = "KBOS KATL KORD KLAX"; // we default to 4 major airports
|
var CONF_WATCHLIST = "KBOS KATL KORD KLAX"; // we default to 4 major airports
|
||||||
var MAX_DATALIST = 10;
|
var MAX_DATALIST = 10;
|
||||||
|
|
||||||
$scope.$parent.helppage = 'plates/weather-help.html';
|
$scope.$parent.helppage = 'plates/weather-help.html';
|
||||||
$scope.data_list = [];
|
$scope.data_list = [];
|
||||||
$scope.watch_list = [];
|
$scope.watch_list = [];
|
||||||
$scope.data_count = 0;
|
$scope.data_count = 0;
|
||||||
$scope.watch_count = 0;
|
$scope.watch_count = 0;
|
||||||
|
|
||||||
function updateWatchList() {
|
function updateWatchList() {
|
||||||
$scope.watching = CONF_WATCHLIST;
|
$scope.watching = CONF_WATCHLIST;
|
||||||
// Simple GET request example (note: responce is asynchronous)
|
// Simple GET request example (note: responce is asynchronous)
|
||||||
$http.get(URL_SETTINGS_GET).
|
$http.get(URL_SETTINGS_GET).
|
||||||
then(function (response) {
|
then(function (response) {
|
||||||
settings = angular.fromJson(response.data);
|
settings = angular.fromJson(response.data);
|
||||||
$scope.watching = settings.WatchList.toUpperCase();
|
$scope.watching = settings.WatchList.toUpperCase();
|
||||||
}, function (response) {
|
}, function (response) {
|
||||||
// nop
|
// nop
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
function inList(word, sentence) {
|
function inList(word, sentence) {
|
||||||
// since the watch list is just one long string, we cheat and see if the word in anywhere in the 'sentence'
|
// since the watch list is just one long string, we cheat and see if the word in anywhere in the 'sentence'
|
||||||
if ((sentence) && (word)) {
|
if ((sentence) && (word)) {
|
||||||
return sentence.includes(word);
|
return sentence.includes(word);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function parseFlightCondition(msg, body) {
|
function parseFlightCondition(msg, body) {
|
||||||
if ((msg !== "METAR") && (msg !== "SPECI"))
|
if ((msg !== "METAR") && (msg !== "SPECI"))
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
// check the visibility: a value preceeding 'SM' which is either a fraction or a whole number
|
// check the visibility: a value preceeding 'SM' which is either a fraction or a whole number
|
||||||
// we don't care what value of fraction since anything below 1SM is LIFR
|
// we don't care what value of fraction since anything below 1SM is LIFR
|
||||||
|
|
||||||
// BTW: now I know why no one wants to parse METARs - ther can be spaces in the numbers ARGH
|
// BTW: now I know why no one wants to parse METARs - ther can be spaces in the numbers ARGH
|
||||||
// test for special case of 'X X/X'
|
// test for special case of 'X X/X'
|
||||||
var exp = new RegExp("([0-9]) ([0-9])/([0-9])SM");
|
var exp = new RegExp("([0-9]) ([0-9])/([0-9])SM");
|
||||||
var match = exp.exec(body);
|
var match = exp.exec(body);
|
||||||
if ((match !== null) && (match.length === 4)) {
|
if ((match !== null) && (match.length === 4)) {
|
||||||
visability = parseInt(match[1]) + (parseInt(match[2]) / parseInt(match[3]));
|
visability = parseInt(match[1]) + (parseInt(match[2]) / parseInt(match[3]));
|
||||||
} else {
|
} else {
|
||||||
exp = new RegExp("([0-9/]{1,5}?)SM");
|
exp = new RegExp("([0-9/]{1,5}?)SM");
|
||||||
match = exp.exec(body);
|
match = exp.exec(body);
|
||||||
if (match === null)
|
if (match === null)
|
||||||
return "";
|
return "";
|
||||||
// the only way we have 3 or more characters is if the '/' is present which means we need to do extra checking
|
// the only way we have 3 or more characters is if the '/' is present which means we need to do extra checking
|
||||||
if (match[1].length === 3)
|
if (match[1].length === 3)
|
||||||
return "LIFR";
|
return "LIFR";
|
||||||
// do we have a usable visability distance
|
// do we have a usable visability distance
|
||||||
var visability = parseInt(match[1]);
|
var visability = parseInt(match[1]);
|
||||||
if (visability === 0)
|
if (visability === 0)
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
// ceiling is at either the BKN or OVC layer
|
// ceiling is at either the BKN or OVC layer
|
||||||
exp = new RegExp("BKN([0-9]{3})");
|
exp = new RegExp("BKN([0-9]{3})");
|
||||||
match = exp.exec(body);
|
match = exp.exec(body);
|
||||||
if (match === null) {
|
if (match === null) {
|
||||||
exp = new RegExp("OVC([0-9]{3})");
|
exp = new RegExp("OVC([0-9]{3})");
|
||||||
match = exp.exec(body);
|
match = exp.exec(body);
|
||||||
}
|
}
|
||||||
var ceiling = 999;
|
var ceiling = 999;
|
||||||
if (match !== null)
|
if (match !== null)
|
||||||
ceiling = parseInt(match[1]);
|
ceiling = parseInt(match[1]);
|
||||||
|
|
||||||
if ((visability > 5) && (ceiling > 30))
|
if ((visability > 5) && (ceiling > 30))
|
||||||
return "VFR";
|
return "VFR";
|
||||||
if ((visability >= 3) && (ceiling >= 10))
|
if ((visability >= 3) && (ceiling >= 10))
|
||||||
return "MVFR";
|
return "MVFR";
|
||||||
if ((visability >= 1) && (ceiling >= 5))
|
if ((visability >= 1) && (ceiling >= 5))
|
||||||
return "IFR";
|
return "IFR";
|
||||||
return "LIFR";
|
return "LIFR";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function deltaTimeString(epoc) {
|
function deltaTimeString(epoc) {
|
||||||
var time = "";
|
var time = "";
|
||||||
var val;
|
var val;
|
||||||
var d = new Date(epoc);
|
var d = new Date(epoc);
|
||||||
val = d.getUTCDate() - 1; // we got here by subtrracting two dates so we have a delta, not a day of month
|
val = d.getUTCDate() - 1; // we got here by subtrracting two dates so we have a delta, not a day of month
|
||||||
if (val > 0)
|
if (val > 0)
|
||||||
time += (val < 10 ? "0" + val : "" + val) + "d ";
|
time += (val < 10 ? "0" + val : "" + val) + "d ";
|
||||||
val = d.getUTCHours();
|
val = d.getUTCHours();
|
||||||
if (val > 0) {
|
if (val > 0) {
|
||||||
time += (val < 10 ? "0" + val : "" + val) + "h ";
|
time += (val < 10 ? "0" + val : "" + val) + "h ";
|
||||||
} else {
|
} else {
|
||||||
if (time.length > 0)
|
if (time.length > 0)
|
||||||
time += "00h ";
|
time += "00h ";
|
||||||
}
|
}
|
||||||
val = d.getUTCMinutes();
|
val = d.getUTCMinutes();
|
||||||
time += (val < 10 ? "0" + val : "" + val) + "m ";
|
time += (val < 10 ? "0" + val : "" + val) + "m ";
|
||||||
// ADS-B weather is only accurate to minutes
|
// ADS-B weather is only accurate to minutes
|
||||||
// val = d.getUTCSeconds();
|
// val = d.getUTCSeconds();
|
||||||
// time += (val < 10 ? "0" + val : "" + val) + "s";
|
// time += (val < 10 ? "0" + val : "" + val) + "s";
|
||||||
|
|
||||||
return time;
|
return time;
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseShortDatetime(sdt) {
|
function parseShortDatetime(sdt) {
|
||||||
var d = new Date();
|
var d = new Date();
|
||||||
var s = String(sdt);
|
var s = String(sdt);
|
||||||
if (s.length < 7)
|
if (s.length < 7)
|
||||||
return 0;
|
return 0;
|
||||||
d.setUTCDate(parseInt(s.substring(0, 2)));
|
d.setUTCDate(parseInt(s.substring(0, 2)));
|
||||||
d.setUTCHours(parseInt(s.substring(2, 4)));
|
d.setUTCHours(parseInt(s.substring(2, 4)));
|
||||||
if (s.length > 7) { // TAF datetime range
|
if (s.length > 7) { // TAF datetime range
|
||||||
d.setUTCMinutes(0);
|
d.setUTCMinutes(0);
|
||||||
} else {
|
} else {
|
||||||
d.setUTCMinutes(parseInt(s.substring(4, 6)));
|
d.setUTCMinutes(parseInt(s.substring(4, 6)));
|
||||||
}
|
}
|
||||||
d.setUTCSeconds(0);
|
d.setUTCSeconds(0);
|
||||||
d.setUTCMilliseconds(0);
|
d.setUTCMilliseconds(0);
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setDataItem(obj, data_item) {
|
function setDataItem(obj, data_item) {
|
||||||
if (obj.Type === "TAF.AMD") {
|
if (obj.Type === "TAF.AMD") {
|
||||||
data_item.type = "TAF";
|
data_item.type = "TAF";
|
||||||
data_item.update = true;
|
data_item.update = true;
|
||||||
} else {
|
} else {
|
||||||
data_item.type = obj.Type;
|
data_item.type = obj.Type;
|
||||||
data_item.update = false;
|
data_item.update = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
data_item.flight_condition = parseFlightCondition(obj.Type, obj.Data);
|
data_item.flight_condition = parseFlightCondition(obj.Type, obj.Data);
|
||||||
data_item.location = obj.Location;
|
data_item.location = obj.Location;
|
||||||
s = obj.Time;
|
s = obj.Time;
|
||||||
// data_item.time = s.substring(0, 2) + '-' + s.substring(2, 4) + ':' + s.substring(4, 6) + 'Z';
|
// data_item.time = s.substring(0, 2) + '-' + s.substring(2, 4) + ':' + s.substring(4, 6) + 'Z';
|
||||||
// we may not get an accurate base time on the stratux device so we use the device time as our base
|
// we may not get an accurate base time on the stratux device so we use the device time as our base
|
||||||
// var dNow = new Date(obj.LocaltimeReceived);
|
// var dNow = new Date(obj.LocaltimeReceived);
|
||||||
var dNow = new Date();
|
var dNow = new Date();
|
||||||
var dThen = parseShortDatetime(obj.Time);
|
var dThen = parseShortDatetime(obj.Time);
|
||||||
data_item.age = dThen.getTime();
|
data_item.age = dThen.getTime();
|
||||||
var diff_ms = Math.abs(dThen - dNow);
|
var diff_ms = Math.abs(dThen - dNow);
|
||||||
|
|
||||||
// If time is more than two days away, don't attempt to display data age.
|
// If time is more than two days away, don't attempt to display data age.
|
||||||
if (diff_ms > (1000*60*60*24*2)) {
|
if (diff_ms > (1000*60*60*24*2)) {
|
||||||
data_item.time = "?";
|
data_item.time = "?";
|
||||||
} else if (dThen > dNow) {
|
} else if (dThen > dNow) {
|
||||||
data_item.time = deltaTimeString(dThen - dNow) + " from now";
|
data_item.time = deltaTimeString(dThen - dNow) + " from now";
|
||||||
} else {
|
} else {
|
||||||
data_item.time = deltaTimeString(dNow - dThen) + " old";
|
data_item.time = deltaTimeString(dNow - dThen) + " old";
|
||||||
}
|
}
|
||||||
|
|
||||||
// data_item.received = utcTimeString(obj.LocaltimeReceived);
|
// data_item.received = utcTimeString(obj.LocaltimeReceived);
|
||||||
data_item.data = obj.Data;
|
data_item.data = obj.Data;
|
||||||
}
|
}
|
||||||
|
|
||||||
function connect($scope) {
|
function connect($scope) {
|
||||||
if (($scope === undefined) || ($scope === null))
|
if (($scope === undefined) || ($scope === null))
|
||||||
return; // we are getting called once after clicking away from the status page
|
return; // we are getting called once after clicking away from the status page
|
||||||
|
|
||||||
if (($scope.socket === undefined) || ($scope.socket === null)) {
|
if (($scope.socket === undefined) || ($scope.socket === null)) {
|
||||||
socket = new WebSocket(URL_WEATHER_WS);
|
socket = new WebSocket(URL_WEATHER_WS);
|
||||||
$scope.socket = socket; // store socket in scope for enter/exit usage
|
$scope.socket = socket; // store socket in scope for enter/exit usage
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.ConnectState = "Disconnected";
|
$scope.ConnectState = "Disconnected";
|
||||||
|
|
||||||
socket.onopen = function (msg) {
|
socket.onopen = function (msg) {
|
||||||
// $scope.ConnectStyle = "label-success";
|
// $scope.ConnectStyle = "label-success";
|
||||||
$scope.ConnectState = "Connected";
|
$scope.ConnectState = "Connected";
|
||||||
};
|
};
|
||||||
|
|
||||||
socket.onclose = function (msg) {
|
socket.onclose = function (msg) {
|
||||||
// $scope.ConnectStyle = "label-danger";
|
// $scope.ConnectStyle = "label-danger";
|
||||||
$scope.ConnectState = "Disconnected";
|
$scope.ConnectState = "Disconnected";
|
||||||
$scope.$apply();
|
$scope.$apply();
|
||||||
setTimeout(connect, 1000);
|
setTimeout(connect, 1000);
|
||||||
};
|
};
|
||||||
|
|
||||||
socket.onerror = function (msg) {
|
socket.onerror = function (msg) {
|
||||||
// $scope.ConnectStyle = "label-danger";
|
// $scope.ConnectStyle = "label-danger";
|
||||||
$scope.ConnectState = "Problem";
|
$scope.ConnectState = "Problem";
|
||||||
$scope.$apply();
|
$scope.$apply();
|
||||||
};
|
};
|
||||||
|
|
||||||
socket.onmessage = function (msg) {
|
socket.onmessage = function (msg) {
|
||||||
console.log('Received data_list update.');
|
console.log('Received data_list update.');
|
||||||
|
|
||||||
$scope.raw_data = angular.toJson(msg.data, true);
|
$scope.raw_data = angular.toJson(msg.data, true);
|
||||||
var message = JSON.parse(msg.data);
|
var message = JSON.parse(msg.data);
|
||||||
// we need to use an array so AngularJS can perform sorting; it also means we need to loop to find an aircraft in the data_list set
|
// we need to use an array so AngularJS can perform sorting; it also means we need to loop to find an aircraft in the data_list set
|
||||||
var found = false;
|
var found = false;
|
||||||
if (inList(message.Location, $scope.watching)) {
|
if (inList(message.Location, $scope.watching)) {
|
||||||
for (var i = 0, len = $scope.watch_list.length; i < len; i++) {
|
for (var i = 0, len = $scope.watch_list.length; i < len; i++) {
|
||||||
if (($scope.watch_list[i].type === message.Type) && ($scope.watch_list[i].location === message.Location)) {
|
if (($scope.watch_list[i].type === message.Type) && ($scope.watch_list[i].location === message.Location)) {
|
||||||
setDataItem(message, $scope.watch_list[i]);
|
setDataItem(message, $scope.watch_list[i]);
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!found) {
|
if (!found) {
|
||||||
var new_data_item = {};
|
var new_data_item = {};
|
||||||
setDataItem(message, new_data_item);
|
setDataItem(message, new_data_item);
|
||||||
$scope.watch_list.unshift(new_data_item); // add to start of array
|
$scope.watch_list.unshift(new_data_item); // add to start of array
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// add to scrolling data_list
|
// add to scrolling data_list
|
||||||
{
|
{
|
||||||
var new_data_item = {};
|
var new_data_item = {};
|
||||||
setDataItem(message, new_data_item);
|
setDataItem(message, new_data_item);
|
||||||
$scope.data_list.unshift(new_data_item); // add to start of array
|
$scope.data_list.unshift(new_data_item); // add to start of array
|
||||||
if ($scope.data_list.length > MAX_DATALIST)
|
if ($scope.data_list.length > MAX_DATALIST)
|
||||||
$scope.data_list.pop(); // remove last from array
|
$scope.data_list.pop(); // remove last from array
|
||||||
}
|
}
|
||||||
$scope.data_count = $scope.data_list.length;
|
$scope.data_count = $scope.data_list.length;
|
||||||
$scope.watch_count = $scope.watch_list.length;
|
$scope.watch_count = $scope.watch_list.length;
|
||||||
$scope.$apply();
|
$scope.$apply();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// perform cleanup every 5 minutes
|
// perform cleanup every 5 minutes
|
||||||
var clearStaleMessages = $interval(function () {
|
var clearStaleMessages = $interval(function () {
|
||||||
// remove stale data = anything more than 30 minutes old
|
// remove stale data = anything more than 30 minutes old
|
||||||
var dirty = false;
|
var dirty = false;
|
||||||
var cutoff = Date.now() - (30 * 60 * 1000);
|
var cutoff = Date.now() - (30 * 60 * 1000);
|
||||||
|
|
||||||
for (var i = len = $scope.watch_list.length; i > 0; i--) {
|
for (var i = len = $scope.watch_list.length; i > 0; i--) {
|
||||||
if ($scope.watch_list[i - 1].age < cutoff) {
|
if ($scope.watch_list[i - 1].age < cutoff) {
|
||||||
$scope.watch_list.splice(i - 1, 1);
|
$scope.watch_list.splice(i - 1, 1);
|
||||||
dirty = true;
|
dirty = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (dirty) {
|
if (dirty) {
|
||||||
$scope.raw_data = "";
|
$scope.raw_data = "";
|
||||||
$scope.$apply();
|
$scope.$apply();
|
||||||
}
|
}
|
||||||
}, (5 * 60 * 1000), 0, false);
|
}, (5 * 60 * 1000), 0, false);
|
||||||
|
|
||||||
|
|
||||||
$state.get('weather').onEnter = function () {
|
$state.get('weather').onEnter = function () {
|
||||||
// everything gets handled correctly by the controller
|
// everything gets handled correctly by the controller
|
||||||
updateWatchList();
|
updateWatchList();
|
||||||
};
|
};
|
||||||
|
|
||||||
$state.get('weather').onExit = function () {
|
$state.get('weather').onExit = function () {
|
||||||
// disconnect from the socket
|
// disconnect from the socket
|
||||||
if (($scope.socket !== undefined) && ($scope.socket !== null)) {
|
if (($scope.socket !== undefined) && ($scope.socket !== null)) {
|
||||||
$scope.socket.close();
|
$scope.socket.close();
|
||||||
$scope.socket = null;
|
$scope.socket = null;
|
||||||
}
|
}
|
||||||
// stop stale message cleanup
|
// stop stale message cleanup
|
||||||
$interval.cancel(clearStaleMessages);
|
$interval.cancel(clearStaleMessages);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Weather Controller tasks
|
// Weather Controller tasks
|
||||||
updateWatchList();
|
updateWatchList();
|
||||||
connect($scope); // connect - opens a socket and listens for messages
|
connect($scope); // connect - opens a socket and listens for messages
|
||||||
};
|
};
|
|
@ -1,23 +1,23 @@
|
||||||
<div class="list-group text-center">
|
<div class="list-group text-center">
|
||||||
<div class="list-group-item list-group-item-home">
|
<div class="list-group-item list-group-item-home">
|
||||||
<h2>Logs</h2>
|
<h2>Logs</h2>
|
||||||
</div>
|
</div>
|
||||||
<div class="list-group-item list-group-item-home">
|
<div class="list-group-item list-group-item-home">
|
||||||
<div>
|
<div>
|
||||||
<i class="fa fa-cloud feature-icon text-primary"></i>
|
<i class="fa fa-cloud feature-icon text-primary"></i>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<a target="_blank" href="../logs/stratux.log">stratux.log</a>
|
<a target="_blank" href="../logs/stratux.log">stratux.log</a>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<a target="_blank" href="../view_logs/">SDR, AHRS, and GPS logs</a>
|
<a target="_blank" href="../view_logs/">SDR, AHRS, and GPS logs</a>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
(Enable device logging on "Settings" page)
|
(Enable device logging on "Settings" page)
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-6">
|
<div class="col-sm-6">
|
||||||
<pre>{{userAgent}}</pre>
|
<pre>{{userAgent}}</pre>
|
||||||
<pre>{{deviceViewport}}</pre>
|
<pre>{{deviceViewport}}</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,33 +1,33 @@
|
||||||
<div class="section text-left help-page">
|
<div class="section text-left help-page">
|
||||||
<p>The <strong>Settings</strong> page provides both control and configuration of your Stratux device.</p>
|
<p>The <strong>Settings</strong> page provides both control and configuration of your Stratux device.</p>
|
||||||
|
|
||||||
<p>Use the toggles in the <strong>Hardware</strong> section to control which devices are active.</p>
|
<p>Use the toggles in the <strong>Hardware</strong> section to control which devices are active.</p>
|
||||||
<p class="text-warning">NOTE: Only hardware toggled on here, will appear on the
|
<p class="text-warning">NOTE: Only hardware toggled on here, will appear on the
|
||||||
<stron>Status</stron> page.</p>
|
<stron>Status</stron> page.</p>
|
||||||
|
|
||||||
<p>The <strong>Diagnostics</strong> section helps with debugging and communicating with the Stratux project contributors via GitHub and the reddit subgroup.
|
<p>The <strong>Diagnostics</strong> section helps with debugging and communicating with the Stratux project contributors via GitHub and the reddit subgroup.
|
||||||
<ul class="list-simple">
|
<ul class="list-simple">
|
||||||
<li>Toggling <strong>Traffic Source</strong> adds text for traffic targets within your navigation application. Traffic received via UAT will display <code>u</code> while traffic received via 1090 will display <code>e</code>.</li>
|
<li>Toggling <strong>Traffic Source</strong> adds text for traffic targets within your navigation application. Traffic received via UAT will display <code>u</code> while traffic received via 1090 will display <code>e</code>.</li>
|
||||||
<li>Toggling <strong>Record Logs</strong> enables logging to a series of files for your Stratux device including data recorded for UAT traffic and weather, 1090 traffic, GPS messages, and AHRS messages. The log files are accessible from the <strong>Logs</strong> menu available on the left.</li>
|
<li>Toggling <strong>Record Logs</strong> enables logging to a series of files for your Stratux device including data recorded for UAT traffic and weather, 1090 traffic, GPS messages, and AHRS messages. The log files are accessible from the <strong>Logs</strong> menu available on the left.</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p>The <strong>Configuration</strong> section lets you adjust the default operation of your Stratux device.</p>
|
<p>The <strong>Configuration</strong> section lets you adjust the default operation of your Stratux device.</p>
|
||||||
<ul class="list-simple">
|
<ul class="list-simple">
|
||||||
<li>To avoid having your own aircraft appear as traffic, and scare the bejeezus our of you, you may provide your <strong>Mode S code</strong>. You can find this value in the FAA N-Number Registry for your aircraft. You should use the hexadecimal value (not the octal value) for this setting. No validation is done so please ensure you enter your valide Mode S value.
|
<li>To avoid having your own aircraft appear as traffic, and scare the bejeezus our of you, you may provide your <strong>Mode S code</strong>. You can find this value in the FAA N-Number Registry for your aircraft. You should use the hexadecimal value (not the octal value) for this setting. No validation is done so please ensure you enter your valide Mode S value.
|
||||||
</li>
|
</li>
|
||||||
<li>The <strong>Weather</strong> page uses a user-defined <strong>Watch List</strong> to filter the large volume of ADS-B weather messages for display. Define a list of identifiers (airport, VOR, etc) separated by a spaces. For example <code>KBOS EEN LAH LKP</code>. You may change this list at any time and the <strong>Weather</strong> page will start watching for the updated list immediately.
|
<li>The <strong>Weather</strong> page uses a user-defined <strong>Watch List</strong> to filter the large volume of ADS-B weather messages for display. Define a list of identifiers (airport, VOR, etc) separated by a spaces. For example <code>KBOS EEN LAH LKP</code>. You may change this list at any time and the <strong>Weather</strong> page will start watching for the updated list immediately.
|
||||||
<br/>
|
<br/>
|
||||||
<span class="text-warning">NOTE: To save your changes, you must either tap somehwere else on the page or hit <code>ENTER</code> or <code>RETURN</code> or <code>GO</code> (or whatever your keyboard indicates).</span>
|
<span class="text-warning">NOTE: To save your changes, you must either tap somehwere else on the page or hit <code>ENTER</code> or <code>RETURN</code> or <code>GO</code> (or whatever your keyboard indicates).</span>
|
||||||
</li>
|
</li>
|
||||||
<li>The SDR (software defined radio) receiver support an adjustment in the form of a <strong>PPM Correction</strong>. From the Raspberry Pi, you may use the command <code>kal -g 48 -s GSM850</code> to scan for available channels in your area. Then use the command <code>kal -g 48 -c <em>channel#</em></code> to calculate the PPM.
|
<li>The SDR (software defined radio) receiver support an adjustment in the form of a <strong>PPM Correction</strong>. From the Raspberry Pi, you may use the command <code>kal -g 48 -s GSM850</code> to scan for available channels in your area. Then use the command <code>kal -g 48 -c <em>channel#</em></code> to calculate the PPM.
|
||||||
<br/>
|
<br/>
|
||||||
<span class="text-warning">NOTE: You will need to perform all commands as <code>root</code> by issuing the command: <code>sudo su -</code>. You will need to stop the Stratux software before running the calibration process. You can stop all of the Stratux processes with the command: <code>pkill screen</code>.</span>
|
<span class="text-warning">NOTE: You will need to perform all commands as <code>root</code> by issuing the command: <code>sudo su -</code>. You will need to stop the Stratux software before running the calibration process. You can stop all of the Stratux processes with the command: <code>pkill screen</code>.</span>
|
||||||
</li>
|
</li>
|
||||||
<li>Addiitonal settings will be added in future releases.</li>
|
<li>Addiitonal settings will be added in future releases.</li>
|
||||||
</ul>
|
</ul>
|
||||||
<p>The <strong>System</strong> section lets you safely shutdown or reboot your Stratux device.</p>
|
<p>The <strong>System</strong> section lets you safely shutdown or reboot your Stratux device.</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li><strong>Shutdown</strong> will immediately shutdown the Stratux. You may then safely remove power.</li>
|
<li><strong>Shutdown</strong> will immediately shutdown the Stratux. You may then safely remove power.</li>
|
||||||
<li><strong>Reboot</strong> will immediately reboot the Stratux. After the reboot you may have to rejoin the WiFi connection to reconnect.</li>
|
<li><strong>Reboot</strong> will immediately reboot the Stratux. After the reboot you may have to rejoin the WiFi connection to reconnect.</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
|
@ -1,13 +1,13 @@
|
||||||
<div class="section text-left help-page">
|
<div class="section text-left help-page">
|
||||||
<p>The <strong>Status</strong> page provides an overview of your Stratux device.</p>
|
<p>The <strong>Status</strong> page provides an overview of your Stratux device.</p>
|
||||||
<p>The current state of you device is shown at the top - <code>Connected</code> in green or <code>Disconected</code>in red.</p>
|
<p>The current state of you device is shown at the top - <code>Connected</code> in green or <code>Disconected</code>in red.</p>
|
||||||
|
|
||||||
<p>Depending on the hardware you have installed in your Stratux, status messages will be shown for the following:</p>
|
<p>Depending on the hardware you have installed in your Stratux, status messages will be shown for the following:</p>
|
||||||
<ul class="list-simple">
|
<ul class="list-simple">
|
||||||
<li><strong>Messages</strong> is the number of messages received by the UAT (978 MHz) and 1090 MHz radios. "Current" is the 60-second rolling total for each receiver; "Peak" is the maximum 60-second total. The 1090 total includes all 1090 MHz Mode S messages received, including all-call and TCAS interrogations that do not carry ADS-B position information. If a UAT radio is receiving uplinks from one or more ground-based transceivers (GBT), this will be indicated under <strong>UAT Towers</strong>, with more details available on the Towers page.</li>
|
<li><strong>Messages</strong> is the number of messages received by the UAT (978 MHz) and 1090 MHz radios. "Current" is the 60-second rolling total for each receiver; "Peak" is the maximum 60-second total. The 1090 total includes all 1090 MHz Mode S messages received, including all-call and TCAS interrogations that do not carry ADS-B position information. If a UAT radio is receiving uplinks from one or more ground-based transceivers (GBT), this will be indicated under <strong>UAT Towers</strong>, with more details available on the Towers page.</li>
|
||||||
<li><strong>GPS</strong> indicates the connection status of any attached GPS receivers. Reported data includes the type of position solution, the number of satellites used in that solution, the number of satellites being received, and the number of satellites tracked in the GPS almanac data. Position and accuracy details can be viewed on the <strong>GPS/AHRS</strong> page.</li>
|
<li><strong>GPS</strong> indicates the connection status of any attached GPS receivers. Reported data includes the type of position solution, the number of satellites used in that solution, the number of satellites being received, and the number of satellites tracked in the GPS almanac data. Position and accuracy details can be viewed on the <strong>GPS/AHRS</strong> page.</li>
|
||||||
</ul>
|
</ul>
|
||||||
<p class="text-warning">Devices must be manually enabled on the <strong>Settings</strong> page.</p>
|
<p class="text-warning">Devices must be manually enabled on the <strong>Settings</strong> page.</p>
|
||||||
|
|
||||||
<p>Additional statistics include the number of detected software-defined radios (SDRs), number of current DHCP network clients, uptime, temperature of the Raspberry Pi CPU, and the current clock settings on both the Raspberry Pi and the device / browser used to view this page.</p>
|
<p>Additional statistics include the number of detected software-defined radios (SDRs), number of current DHCP network clients, uptime, temperature of the Raspberry Pi CPU, and the current clock settings on both the Raspberry Pi and the device / browser used to view this page.</p>
|
||||||
</div>
|
</div>
|
|
@ -1,148 +1,148 @@
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
<div class="text-center">
|
<div class="text-center">
|
||||||
<a ng-click="VersionClick()" class="btn btn-hidden"<strong>Version: <span>{{Version}} ({{Build}})</span></strong></a>
|
<a ng-click="VersionClick()" class="btn btn-hidden"<strong>Version: <span>{{Version}} ({{Build}})</span></strong></a>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<span class="panel_label">Status</span>
|
<span class="panel_label">Status</span>
|
||||||
<span ng-show="ConnectState == 'Connected'" class="label label-success">{{ConnectState}}</span>
|
<span ng-show="ConnectState == 'Connected'" class="label label-success">{{ConnectState}}</span>
|
||||||
<span ng-hide="ConnectState == 'Connected'" class="label label-danger">{{ConnectState}}</span>
|
<span ng-hide="ConnectState == 'Connected'" class="label label-danger">{{ConnectState}}</span>
|
||||||
<span ng-show="DeveloperMode == true" class="label label-warning">Developer Mode</span>
|
<span ng-show="DeveloperMode == true" class="label label-warning">Developer Mode</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<div class="form-horizontal">
|
<div class="form-horizontal">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-6 label_adj">
|
<div class="col-sm-6 label_adj">
|
||||||
<strong class="col-xs-5">Recent Clients:</strong>
|
<strong class="col-xs-5">Recent Clients:</strong>
|
||||||
<span class="col-xs-7">{{Connected_Users}}</span>
|
<span class="col-xs-7">{{Connected_Users}}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-6 label_adj">
|
<div class="col-sm-6 label_adj">
|
||||||
<strong class="col-xs-5">SDR devices:</strong>
|
<strong class="col-xs-5">SDR devices:</strong>
|
||||||
<span class="col-xs-7">{{Devices}}</span>
|
<span class="col-xs-7">{{Devices}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-6 label_adj" ng-class="{'section_invisible': !visible_ping}">
|
<div class="col-sm-6 label_adj" ng-class="{'section_invisible': !visible_ping}">
|
||||||
<strong class="col-xs-5">Ping device:</strong>
|
<strong class="col-xs-5">Ping device:</strong>
|
||||||
<span ng-show="Ping_connected == true" class="label label-success">Connected</span>
|
<span ng-show="Ping_connected == true" class="label label-success">Connected</span>
|
||||||
<span ng-hide="Ping_connected == true" class="label label-danger">Disconnected</span>
|
<span ng-hide="Ping_connected == true" class="label label-danger">Disconnected</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="separator"></div>
|
<div class="separator"></div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<label class="col-xs-4">Messages</label>
|
<label class="col-xs-4">Messages</label>
|
||||||
<label class="col-xs-6">Current</label>
|
<label class="col-xs-6">Current</label>
|
||||||
<label class="col-xs-2 text-right">Peak</label>
|
<label class="col-xs-2 text-right">Peak</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="row" ng-class="{'section_invisible': !visible_uat}">
|
<div class="row" ng-class="{'section_invisible': !visible_uat}">
|
||||||
<span class="col-xs-1"></span>
|
<span class="col-xs-1"></span>
|
||||||
<label class="col-xs-3">UAT:</label>
|
<label class="col-xs-3">UAT:</label>
|
||||||
<span class="col-xs-6"><div class="bar_container"><div class="bar_display traffic-style2" ng-attr-style="width:{{UAT_messages_max ? 100*UAT_messages_last_minute / UAT_messages_max : 0}}%">{{UAT_messages_last_minute}}</div></div></span>
|
<span class="col-xs-6"><div class="bar_container"><div class="bar_display traffic-style2" ng-attr-style="width:{{UAT_messages_max ? 100*UAT_messages_last_minute / UAT_messages_max : 0}}%">{{UAT_messages_last_minute}}</div></div></span>
|
||||||
<span class="col-xs-2 text-right">{{UAT_messages_max}}</span>
|
<span class="col-xs-2 text-right">{{UAT_messages_max}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="row" ng-class="{'section_invisible': !visible_es}">
|
<div class="row" ng-class="{'section_invisible': !visible_es}">
|
||||||
<span class="col-xs-1"></span>
|
<span class="col-xs-1"></span>
|
||||||
<label class="col-xs-3">1090ES:</label>
|
<label class="col-xs-3">1090ES:</label>
|
||||||
<span class="col-xs-6"><div class="bar_container"><div class="bar_display traffic-style1" ng-attr-style="width:{{ES_messages_max ? 100*ES_messages_last_minute / ES_messages_max : 0}}%;">{{ES_messages_last_minute}}</div></div></span>
|
<span class="col-xs-6"><div class="bar_container"><div class="bar_display traffic-style1" ng-attr-style="width:{{ES_messages_max ? 100*ES_messages_last_minute / ES_messages_max : 0}}%;">{{ES_messages_last_minute}}</div></div></span>
|
||||||
<span class="col-xs-2 text-right">{{ES_messages_max}}</span>
|
<span class="col-xs-2 text-right">{{ES_messages_max}}</span>
|
||||||
</div>
|
</div>
|
||||||
<!--
|
<!--
|
||||||
<div id="uat_products" style="display: none;">
|
<div id="uat_products" style="display: none;">
|
||||||
<div class="row"><span class="col-xs-1"> </span></div>
|
<div class="row"><span class="col-xs-1"> </span></div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<label class="col-xs-6">UAT Products</label>
|
<label class="col-xs-6">UAT Products</label>
|
||||||
<label class="col-xs-3 text-right">Last Minute</label>
|
<label class="col-xs-3 text-right">Last Minute</label>
|
||||||
<label class="col-xs-3"></label>
|
<label class="col-xs-3"></label>
|
||||||
</div>
|
</div>
|
||||||
<div>{{product_rows}}</div>
|
<div>{{product_rows}}</div>
|
||||||
</div>
|
</div>
|
||||||
-->
|
-->
|
||||||
<div class="row" ng-class="{ 'section_invisible': (!visible_gps && !visible_uat)}">
|
<div class="row" ng-class="{ 'section_invisible': (!visible_gps && !visible_uat)}">
|
||||||
<span class="col-xs-1"> </span>
|
<span class="col-xs-1"> </span>
|
||||||
</div>
|
</div>
|
||||||
<div class="row" ng-class="{'section_invisible': !visible_uat}">
|
<div class="row" ng-class="{'section_invisible': !visible_uat}">
|
||||||
<label class="col-xs-6">UAT Towers:</label>
|
<label class="col-xs-6">UAT Towers:</label>
|
||||||
<span class="col-xs-6">{{UAT_Towers}}</span>
|
<span class="col-xs-6">{{UAT_Towers}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="row" ng-class="{'section_invisible': !visible_gps}">
|
<div class="row" ng-class="{'section_invisible': !visible_gps}">
|
||||||
<label class="col-xs-6">GPS solution:</label>
|
<label class="col-xs-6">GPS solution:</label>
|
||||||
<span class="col-xs-6">{{GPS_solution}}{{GPS_position_accuracy}}</span>
|
<span class="col-xs-6">{{GPS_solution}}{{GPS_position_accuracy}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="row" ng-class="{'section_invisible': !visible_gps}">
|
<div class="row" ng-class="{'section_invisible': !visible_gps}">
|
||||||
<label class="col-xs-6">GPS satellites:</label>
|
<label class="col-xs-6">GPS satellites:</label>
|
||||||
<span class="col-xs-6">{{GPS_satellites_locked}} in solution; {{GPS_satellites_seen}} seen; {{GPS_satellites_tracked}} tracked</span>
|
<span class="col-xs-6">{{GPS_satellites_locked}} in solution; {{GPS_satellites_seen}} seen; {{GPS_satellites_tracked}} tracked</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="row"><span class="col-xs-1"> </span></div>
|
<div class="row"><span class="col-xs-1"> </span></div>
|
||||||
<div class="separator"></div>
|
<div class="separator"></div>
|
||||||
<div class="row" ng-class="{'section_invisible': !visible_uat}">
|
<div class="row" ng-class="{'section_invisible': !visible_uat}">
|
||||||
<div class="col-sm-6">
|
<div class="col-sm-6">
|
||||||
<span><strong>UAT Statistics</strong></span>
|
<span><strong>UAT Statistics</strong></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row" ng-class="{'section_invisible': !visible_uat}">
|
<div class="row" ng-class="{'section_invisible': !visible_uat}">
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
<span align="center" style="background-color: #f7f7f7" class="col-xs-3">METARS</span>
|
<span align="center" style="background-color: #f7f7f7" class="col-xs-3">METARS</span>
|
||||||
<span align="center" style="background-color: #f7f7f7" class="col-xs-3">TAFS</span>
|
<span align="center" style="background-color: #f7f7f7" class="col-xs-3">TAFS</span>
|
||||||
<span align="center" style="background-color: #f7f7f7" class="col-xs-3">NEXRAD</span>
|
<span align="center" style="background-color: #f7f7f7" class="col-xs-3">NEXRAD</span>
|
||||||
<span align="center" style="background-color: #f7f7f7" class="col-xs-3">PIREP</span>
|
<span align="center" style="background-color: #f7f7f7" class="col-xs-3">PIREP</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row" ng-class="{'section_invisible': !visible_uat}">
|
<div class="row" ng-class="{'section_invisible': !visible_uat}">
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
<span align="center" class="col-xs-3">{{UAT_METAR_total}}</span>
|
<span align="center" class="col-xs-3">{{UAT_METAR_total}}</span>
|
||||||
<span align="center" class="col-xs-3">{{UAT_TAF_total}}</span>
|
<span align="center" class="col-xs-3">{{UAT_TAF_total}}</span>
|
||||||
<span align="center" class="col-xs-3">{{UAT_NEXRAD_total}}</span>
|
<span align="center" class="col-xs-3">{{UAT_NEXRAD_total}}</span>
|
||||||
<span align="center" class="col-xs-3">{{UAT_PIREP_total}}</span>
|
<span align="center" class="col-xs-3">{{UAT_PIREP_total}}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row" ng-class="{'section_invisible': !visible_uat}">
|
<div class="row" ng-class="{'section_invisible': !visible_uat}">
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
<span align="center" style="background-color: #f7f7f7" class="col-xs-3">SIGMET</span>
|
<span align="center" style="background-color: #f7f7f7" class="col-xs-3">SIGMET</span>
|
||||||
<span align="center" style="background-color: #f7f7f7" class="col-xs-3">NOTAMS</span>
|
<span align="center" style="background-color: #f7f7f7" class="col-xs-3">NOTAMS</span>
|
||||||
<span align="center" style="background-color: #f7f7f7" class="col-xs-3">Other</span>
|
<span align="center" style="background-color: #f7f7f7" class="col-xs-3">Other</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row" ng-class="{'section_invisible': !visible_uat}">
|
<div class="row" ng-class="{'section_invisible': !visible_uat}">
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
<span align="center" class="col-xs-3">{{UAT_SIGMET_total}}</span>
|
<span align="center" class="col-xs-3">{{UAT_SIGMET_total}}</span>
|
||||||
<span align="center" class="col-xs-3">{{UAT_NOTAM_total}}</span>
|
<span align="center" class="col-xs-3">{{UAT_NOTAM_total}}</span>
|
||||||
<span align="center" class="col-xs-3">{{UAT_OTHER_total}}</span>
|
<span align="center" class="col-xs-3">{{UAT_OTHER_total}}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row" ng-class="{'section_invisible': !visible_uat}">
|
<div class="row" ng-class="{'section_invisible': !visible_uat}">
|
||||||
<div class="separator"></div>
|
<div class="separator"></div>
|
||||||
<div class="row"><span class="col-xs-1"> </span></div>
|
<div class="row"><span class="col-xs-1"> </span></div>
|
||||||
<div class="separator"></div>
|
<div class="separator"></div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-4 label_adj">
|
<div class="col-sm-4 label_adj">
|
||||||
<span class="col-xs-5"><strong>Uptime:</strong></span>
|
<span class="col-xs-5"><strong>Uptime:</strong></span>
|
||||||
<span class="col-xs-7">{{Uptime}}</span>
|
<span class="col-xs-7">{{Uptime}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-4 label_adj">
|
<div class="col-sm-4 label_adj">
|
||||||
<span class="col-xs-5"><strong>CPU Temp:</strong></span>
|
<span class="col-xs-5"><strong>CPU Temp:</strong></span>
|
||||||
<span class="col-xs-7">{{CPUTemp}}</span>
|
<span class="col-xs-7">{{CPUTemp}}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading" ng-class="{'section_invisible': !visible_errors}">
|
<div class="panel-heading" ng-class="{'section_invisible': !visible_errors}">
|
||||||
<span class="panel_label">Errors</span>
|
<span class="panel_label">Errors</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-body" ng-class="{'section_invisible': !visible_errors}">
|
<div class="panel-body" ng-class="{'section_invisible': !visible_errors}">
|
||||||
<ul>
|
<ul>
|
||||||
<li class="status-error" ng-repeat="err in Errors">
|
<li class="status-error" ng-repeat="err in Errors">
|
||||||
<span class="fa fa-exclamation-triangle icon-red"></span> <span class="icon-red">{{err}}</span>
|
<span class="fa fa-exclamation-triangle icon-red"></span> <span class="icon-red">{{err}}</span>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,25 +1,25 @@
|
||||||
<div class="section text-left help-page">
|
<div class="section text-left help-page">
|
||||||
<p>The <strong>Traffic</strong> page provides a list of all aircraft position reports received within the last 60 seconds. Each time a new aircraft is detected, it is added to the list. Each time a new report is received for an existing aircraft, the list is updated. If a valid position for an aircraft has not been received within the last 60 seconds, the aircraft is removed from the list.</p>
|
<p>The <strong>Traffic</strong> page provides a list of all aircraft position reports received within the last 60 seconds. Each time a new aircraft is detected, it is added to the list. Each time a new report is received for an existing aircraft, the list is updated. If a valid position for an aircraft has not been received within the last 60 seconds, the aircraft is removed from the list.</p>
|
||||||
<p>For each aircraft, the list includes the following details:</p>
|
<p>For each aircraft, the list includes the following details:</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li><strong>Callsign</strong> is the aircraft callsign or tail number. Unknown callsigns will be shown as <span class="label traffic-style11">[--N/A--]</span>. Color and symbol indicates traffic source:</li>
|
<li><strong>Callsign</strong> is the aircraft callsign or tail number. Unknown callsigns will be shown as <span class="label traffic-style11">[--N/A--]</span>. Color and symbol indicates traffic source:</li>
|
||||||
<ul class="list-simple">
|
<ul class="list-simple">
|
||||||
<li><span class="label traffic-style11">✈ ADSB1090</span> 1090 MHz air-to-air ADS-B traffic is displayed with a medium blue background and airplane symbol.</li>
|
<li><span class="label traffic-style11">✈ ADSB1090</span> 1090 MHz air-to-air ADS-B traffic is displayed with a medium blue background and airplane symbol.</li>
|
||||||
<li><span class="label traffic-style12">✈ ADSR1090</span> 1090 MHz ground-to-air ADS-R rebroadcasts are displayed with a light cyan background and airplane symbol.</li>
|
<li><span class="label traffic-style12">✈ ADSR1090</span> 1090 MHz ground-to-air ADS-R rebroadcasts are displayed with a light cyan background and airplane symbol.</li>
|
||||||
<li><span class="label traffic-style14">📡 TISB1090</span> 1090 MHZ TIS-B traffic is displayed with a light cyan background and antenna symbol.</li>
|
<li><span class="label traffic-style14">📡 TISB1090</span> 1090 MHZ TIS-B traffic is displayed with a light cyan background and antenna symbol.</li>
|
||||||
<li><span class="label traffic-style21">✈ ADSB978</span> 978 MHz air-to-air ADS-B traffic is displayed with a light tan background and airplane symbol.</li>
|
<li><span class="label traffic-style21">✈ ADSB978</span> 978 MHz air-to-air ADS-B traffic is displayed with a light tan background and airplane symbol.</li>
|
||||||
<li><span class="label traffic-style22">✈ ADSR978</span> 978 MHz ground-to-air ADS-R rebroadcasts are displayed with a gold background and airplane symbol.</li>
|
<li><span class="label traffic-style22">✈ ADSR978</span> 978 MHz ground-to-air ADS-R rebroadcasts are displayed with a gold background and airplane symbol.</li>
|
||||||
<li><span class="label traffic-style24">📡 TISB978</span> 978 MHz TIS-B traffic is displayed with a gold background and antenna symbol.</li>
|
<li><span class="label traffic-style24">📡 TISB978</span> 978 MHz TIS-B traffic is displayed with a gold background and antenna symbol.</li>
|
||||||
</ul>
|
</ul>
|
||||||
<li><strong>Code</strong> is the ICAO 24-bit code (ADS-B/ADS-R targets), 24-bit FAA-assigned track file ID (TIS-B), or Mode C squawk code, if <strong>Show Squawk</strong> is enabled, and if a squawk code has been received for that target.</li>
|
<li><strong>Code</strong> is the ICAO 24-bit code (ADS-B/ADS-R targets), 24-bit FAA-assigned track file ID (TIS-B), or Mode C squawk code, if <strong>Show Squawk</strong> is enabled, and if a squawk code has been received for that target.</li>
|
||||||
<li><strong>Location</strong> - Reported latitude and longitude, DD° mm'.</li>
|
<li><strong>Location</strong> - Reported latitude and longitude, DD° mm'.</li>
|
||||||
<li><strong>Dist</strong> - Calculated distance to target in nautical miles. Requires GPS position and <strong>Show Distance</strong> slider to be enabled.</li>
|
<li><strong>Dist</strong> - Calculated distance to target in nautical miles. Requires GPS position and <strong>Show Distance</strong> slider to be enabled.</li>
|
||||||
<li><strong>Bearing</strong> - Calculated bearing to target in degrees true. Requires GPS position and <strong>Show Distance</strong> slider to be enabled.</li>
|
<li><strong>Bearing</strong> - Calculated bearing to target in degrees true. Requires GPS position and <strong>Show Distance</strong> slider to be enabled.</li>
|
||||||
<li><strong>Altitude</strong> - Reported pressure altitude, feet MSL. Climb or descent rate is also shown if not in level flight.</li>
|
<li><strong>Altitude</strong> - Reported pressure altitude, feet MSL. Climb or descent rate is also shown if not in level flight.</li>
|
||||||
<li><strong>Speed</strong> - Reported ground speed, rounded to the nearest 5 knots. Invalid or missing values are shown as '---'.</li>
|
<li><strong>Speed</strong> - Reported ground speed, rounded to the nearest 5 knots. Invalid or missing values are shown as '---'.</li>
|
||||||
<li><strong>Course</strong> - Reported true course, rounded to the nearest 5°. Invalid or missing values are shown as '---'</li>
|
<li><strong>Course</strong> - Reported true course, rounded to the nearest 5°. Invalid or missing values are shown as '---'</li>
|
||||||
<li><strong>Power</strong> - Signal strength in dB. The maximum signal is about +1.4 dB. For typical unamplified SDRs, the minimum detection threshold is about -35 dB for altitude reports, and -30 dB for position reports.</li>
|
<li><strong>Power</strong> - Signal strength in dB. The maximum signal is about +1.4 dB. For typical unamplified SDRs, the minimum detection threshold is about -35 dB for altitude reports, and -30 dB for position reports.</li>
|
||||||
<li><strong>Age</strong> - Age of the last position report, seconds.</li>
|
<li><strong>Age</strong> - Age of the last position report, seconds.</li>
|
||||||
</ul>
|
</ul>
|
||||||
<p>Additionally, if <strong>1090 MHz</strong> is enabled on the <strong>Settings</strong> page, most users will see reports from aircraft in the <strong>Basic Mode S and No-Position Messages</strong> table. These are targets that do not transmitting ADS-B position. Instead, Stratux is picking up altitude, squawk code, and occasionally velocity reports from non-ADS-B Mode S reports. These include air-to-air TCAS messages and radar interrogations, and typically make up the majority of all 1090 messages received.</p>
|
<p>Additionally, if <strong>1090 MHz</strong> is enabled on the <strong>Settings</strong> page, most users will see reports from aircraft in the <strong>Basic Mode S and No-Position Messages</strong> table. These are targets that do not transmitting ADS-B position. Instead, Stratux is picking up altitude, squawk code, and occasionally velocity reports from non-ADS-B Mode S reports. These include air-to-air TCAS messages and radar interrogations, and typically make up the majority of all 1090 messages received.</p>
|
||||||
</div>
|
</div>
|
|
@ -1,161 +1,161 @@
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<span class="panel_label">ADS-B and TIS-B Traffic</span>
|
<span class="panel_label">ADS-B and TIS-B Traffic</span>
|
||||||
<span ng-show="ConnectState == 'Connected'" class="label label-success">{{ConnectState}}</span>
|
<span ng-show="ConnectState == 'Connected'" class="label label-success">{{ConnectState}}</span>
|
||||||
<span ng-hide="ConnectState == 'Connected'" class="label label-danger">{{ConnectState}}</span>
|
<span ng-hide="ConnectState == 'Connected'" class="label label-danger">{{ConnectState}}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="panel-body traffic-page">
|
<div class="panel-body traffic-page">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-6">
|
<div class="col-sm-6">
|
||||||
<span class="col-xs-3" ng-hide="showReg"><strong>Callsign</strong></span>
|
<span class="col-xs-3" ng-hide="showReg"><strong>Callsign</strong></span>
|
||||||
<span class="col-xs-3" ng-show="showReg"><strong>Tail Num</strong></span>
|
<span class="col-xs-3" ng-show="showReg"><strong>Tail Num</strong></span>
|
||||||
<span class="col-xs-2" ng-hide="showSquawk"><strong>Code</strong></span>
|
<span class="col-xs-2" ng-hide="showSquawk"><strong>Code</strong></span>
|
||||||
<span class="col-xs-2" ng-show="showSquawk"><strong>Squawk</strong></span>
|
<span class="col-xs-2" ng-show="showSquawk"><strong>Squawk</strong></span>
|
||||||
<span class="col-xs-5 text-right" ng-hide="GPS_connected && RelDist"><strong>Location</strong></span>
|
<span class="col-xs-5 text-right" ng-hide="GPS_connected && RelDist"><strong>Location</strong></span>
|
||||||
<span class="col-xs-3 text-right" ng-show="GPS_connected && RelDist"><strong>Dist</strong></span>
|
<span class="col-xs-3 text-right" ng-show="GPS_connected && RelDist"><strong>Dist</strong></span>
|
||||||
<span class="col-xs-2 text-right" ng-show="GPS_connected && RelDist"><strong>Bearing</strong></span>
|
<span class="col-xs-2 text-right" ng-show="GPS_connected && RelDist"><strong>Bearing</strong></span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-sm-6">
|
<div class="col-sm-6">
|
||||||
<span class="col-xs-3 text-right"><strong>Altitude</strong></span><span class="col-xs-1"> </span>
|
<span class="col-xs-3 text-right"><strong>Altitude</strong></span><span class="col-xs-1"> </span>
|
||||||
<span class="col-xs-2 text-right"><strong>Speed</strong></span>
|
<span class="col-xs-2 text-right"><strong>Speed</strong></span>
|
||||||
<span class="col-xs-2 text-right"><strong>Course</strong></span>
|
<span class="col-xs-2 text-right"><strong>Course</strong></span>
|
||||||
<span class="col-xs-2 text-right"><strong>Power</strong></span>
|
<span class="col-xs-2 text-right"><strong>Power</strong></span>
|
||||||
<span class="col-xs-2 text-right"><strong>Age</strong></span>
|
<span class="col-xs-2 text-right"><strong>Age</strong></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row" ng-repeat="aircraft in data_list | orderBy: 'dist'">
|
<div class="row" ng-repeat="aircraft in data_list | orderBy: 'dist'">
|
||||||
<div class="separator"></div>
|
<div class="separator"></div>
|
||||||
<div class="col-sm-6">
|
<div class="col-sm-6">
|
||||||
<span class="col-xs-3" ng-hide="showReg">
|
<span class="col-xs-3" ng-hide="showReg">
|
||||||
<span ng-show="aircraft.tail" ng-class="'label traffic-style'+aircraft.src+aircraft.targettype">{{aircraft.addr_symb}}<strong> {{aircraft.tail}}</strong></span>
|
<span ng-show="aircraft.tail" ng-class="'label traffic-style'+aircraft.src+aircraft.targettype">{{aircraft.addr_symb}}<strong> {{aircraft.tail}}</strong></span>
|
||||||
<span ng-hide="aircraft.tail" ng-class="'label traffic-style'+aircraft.src+aircraft.targettype">{{aircraft.addr_symb}}<strong> [--N/A--]</strong></span>
|
<span ng-hide="aircraft.tail" ng-class="'label traffic-style'+aircraft.src+aircraft.targettype">{{aircraft.addr_symb}}<strong> [--N/A--]</strong></span>
|
||||||
</span>
|
</span>
|
||||||
<span class="col-xs-3" ng-show="showReg">
|
<span class="col-xs-3" ng-show="showReg">
|
||||||
<span ng-show="aircraft.reg" ng-class="'label traffic-style'+aircraft.src+aircraft.targettype">{{aircraft.addr_symb}}<strong> {{aircraft.reg}}</strong></span>
|
<span ng-show="aircraft.reg" ng-class="'label traffic-style'+aircraft.src+aircraft.targettype">{{aircraft.addr_symb}}<strong> {{aircraft.reg}}</strong></span>
|
||||||
<span ng-hide="aircraft.reg" ng-class="'label traffic-style'+aircraft.src+aircraft.targettype">{{aircraft.addr_symb}}<strong> [--N/A--]</strong></span>
|
<span ng-hide="aircraft.reg" ng-class="'label traffic-style'+aircraft.src+aircraft.targettype">{{aircraft.addr_symb}}<strong> [--N/A--]</strong></span>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span class="col-xs-2">
|
<span class="col-xs-2">
|
||||||
<span style="font-size:80%" ng-hide="showSquawk">{{aircraft.icao}}<span style="font-size:50%">{{aircraft.addr_type == 3 ? " (TFID)" : ""}}</span></span>
|
<span style="font-size:80%" ng-hide="showSquawk">{{aircraft.icao}}<span style="font-size:50%">{{aircraft.addr_type == 3 ? " (TFID)" : ""}}</span></span>
|
||||||
<span ng-show="showSquawk"><span ng-show="aircraft.squawk < 1000">0</span><span ng-show="aircraft.squawk < 100">0</span><span ng-show="aircraft.squawk < 10">0</span>{{aircraft.squawk}}</span>
|
<span ng-show="showSquawk"><span ng-show="aircraft.squawk < 1000">0</span><span ng-show="aircraft.squawk < 100">0</span><span ng-show="aircraft.squawk < 10">0</span>{{aircraft.squawk}}</span>
|
||||||
</span>
|
</span>
|
||||||
<span class="col-xs-5 text-right" ng-hide="GPS_connected && RelDist">{{aircraft.lat}} {{aircraft.lon}}</span>
|
<span class="col-xs-5 text-right" ng-hide="GPS_connected && RelDist">{{aircraft.lat}} {{aircraft.lon}}</span>
|
||||||
<span class="col-xs-3 text-right" ng-show="GPS_connected && RelDist">{{aircraft.dist.toFixed(1)}}<span style="font-size:50%">NM</span></span>
|
<span class="col-xs-3 text-right" ng-show="GPS_connected && RelDist">{{aircraft.dist.toFixed(1)}}<span style="font-size:50%">NM</span></span>
|
||||||
<span class="col-xs-2 text-right" ng-show="GPS_connected && RelDist">{{aircraft.bearing}}°</span>
|
<span class="col-xs-2 text-right" ng-show="GPS_connected && RelDist">{{aircraft.bearing}}°</span>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-6">
|
<div class="col-sm-6">
|
||||||
<span class="col-xs-3 text-right">{{aircraft.alt}}</span>
|
<span class="col-xs-3 text-right">{{aircraft.alt}}</span>
|
||||||
<span class="col-xs-1 small col-padding-shift-right text-muted">
|
<span class="col-xs-1 small col-padding-shift-right text-muted">
|
||||||
<span ng-show="aircraft.vspeed > 0"><span class="fa fa-ascent"></span>{{aircraft.vspeed}}</span>
|
<span ng-show="aircraft.vspeed > 0"><span class="fa fa-ascent"></span>{{aircraft.vspeed}}</span>
|
||||||
<span ng-show="aircraft.vspeed < 0"><span class="fa fa-descent"></span>{{0-aircraft.vspeed}}</span>
|
<span ng-show="aircraft.vspeed < 0"><span class="fa fa-descent"></span>{{0-aircraft.vspeed}}</span>
|
||||||
</span>
|
</span>
|
||||||
<span class="col-xs-2 text-right">{{aircraft.speed}}<span style="font-size:50%">KTS</span></span>
|
<span class="col-xs-2 text-right">{{aircraft.speed}}<span style="font-size:50%">KTS</span></span>
|
||||||
<span class="col-xs-2 text-right"><span ng-show="aircraft.heading < 10">0</span><span ng-show="aircraft.heading < 100">0</span>{{aircraft.heading}}°</span>
|
<span class="col-xs-2 text-right"><span ng-show="aircraft.heading < 10">0</span><span ng-show="aircraft.heading < 100">0</span>{{aircraft.heading}}°</span>
|
||||||
<span class="col-xs-2 text-right">{{aircraft.signal.toFixed(2)}}<span style="font-size:50%">dB</span></span>
|
<span class="col-xs-2 text-right">{{aircraft.signal.toFixed(2)}}<span style="font-size:50%">dB</span></span>
|
||||||
<span class="col-xs-2 text-right">{{aircraft.age.toFixed(1)}}<span style="font-size:50%">s</span></span>
|
<span class="col-xs-2 text-right">{{aircraft.age.toFixed(1)}}<span style="font-size:50%">s</span></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="panel-body traffic-footer">
|
<div class="panel-body traffic-footer">
|
||||||
<div class="separator"></div>
|
<div class="separator"></div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-4">
|
<div class="col-sm-4">
|
||||||
<label class="control-label col-xs-6">Show Tail Number</label>
|
<label class="control-label col-xs-6">Show Tail Number</label>
|
||||||
<span class="col-xs-3"><ui-switch ng-model='showReg' settings-change></ui-switch></span>
|
<span class="col-xs-3"><ui-switch ng-model='showReg' settings-change></ui-switch></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-4">
|
<div class="col-sm-4">
|
||||||
<label class="control-label col-xs-6">Show Squawk</label>
|
<label class="control-label col-xs-6">Show Squawk</label>
|
||||||
<span class="col-xs-3"><ui-switch ng-model='showSquawk' settings-change></ui-switch></span>
|
<span class="col-xs-3"><ui-switch ng-model='showSquawk' settings-change></ui-switch></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-4">
|
<div class="col-sm-4">
|
||||||
<label class="control-label col-xs-6" ng-show="GPS_connected">Show Distance</label>
|
<label class="control-label col-xs-6" ng-show="GPS_connected">Show Distance</label>
|
||||||
<label class="control-label text-muted col-xs-6" ng-hide="GPS_connected">Show Distance N/A</label>
|
<label class="control-label text-muted col-xs-6" ng-hide="GPS_connected">Show Distance N/A</label>
|
||||||
<span class="col-xs-3"><ui-switch ng-model='RelDist' settings-change></ui-switch></span>
|
<span class="col-xs-3"><ui-switch ng-model='RelDist' settings-change></ui-switch></span>
|
||||||
</div>
|
</div>
|
||||||
<!--
|
<!--
|
||||||
<div class="col-sm-4">
|
<div class="col-sm-4">
|
||||||
<label class="control-label col-xs-6">GPS Status</label>
|
<label class="control-label col-xs-6">GPS Status</label>
|
||||||
<span ng-show="GPS_connected" class="label label-success col-xs-3" style="font-size:100%; display:block; height: 34px; line-height: 34px">Valid</span>
|
<span ng-show="GPS_connected" class="label label-success col-xs-3" style="font-size:100%; display:block; height: 34px; line-height: 34px">Valid</span>
|
||||||
<span ng-hide="GPS_connected" class="label label-danger col-xs-3" style="font-size:100%; display:block; height: 34px; line-height: 34px">No Fix</span>
|
<span ng-hide="GPS_connected" class="label label-danger col-xs-3" style="font-size:100%; display:block; height: 34px; line-height: 34px">No Fix</span>
|
||||||
</div>
|
</div>
|
||||||
-->
|
-->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<span class="panel_label">Basic Mode S and No-Position Messages</span>
|
<span class="panel_label">Basic Mode S and No-Position Messages</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="panel-body traffic-page">
|
<div class="panel-body traffic-page">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-6">
|
<div class="col-sm-6">
|
||||||
<span class="col-xs-4" ng-hide="showReg"><strong>Callsign</strong></span>
|
<span class="col-xs-4" ng-hide="showReg"><strong>Callsign</strong></span>
|
||||||
<span class="col-xs-4" ng-show="showReg"><strong>Tail Num</strong></span>
|
<span class="col-xs-4" ng-show="showReg"><strong>Tail Num</strong></span>
|
||||||
<span class="col-xs-3"><strong>Code</strong></span>
|
<span class="col-xs-3"><strong>Code</strong></span>
|
||||||
<span class="col-xs-3"><strong>Squawk</strong></span>
|
<span class="col-xs-3"><strong>Squawk</strong></span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-sm-6">
|
<div class="col-sm-6">
|
||||||
<span class="col-xs-3 text-right"><strong>Altitude</strong></span><span class="col-xs-1"> </span>
|
<span class="col-xs-3 text-right"><strong>Altitude</strong></span><span class="col-xs-1"> </span>
|
||||||
<span class="col-xs-2 text-right"><strong>Speed</strong></span>
|
<span class="col-xs-2 text-right"><strong>Speed</strong></span>
|
||||||
<span class="col-xs-2 text-right"><strong>Course</strong></span>
|
<span class="col-xs-2 text-right"><strong>Course</strong></span>
|
||||||
<span class="col-xs-2 text-right"><strong>Power</strong></span>
|
<span class="col-xs-2 text-right"><strong>Power</strong></span>
|
||||||
<span class="col-xs-2 text-right"><strong>Age</strong></span>
|
<span class="col-xs-2 text-right"><strong>Age</strong></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row" ng-repeat="aircraft in data_list_invalid | orderBy: 'icao'">
|
<div class="row" ng-repeat="aircraft in data_list_invalid | orderBy: 'icao'">
|
||||||
<div class="separator"></div>
|
<div class="separator"></div>
|
||||||
<div class="col-sm-6">
|
<div class="col-sm-6">
|
||||||
<span class="col-xs-4" ng-hide="showReg">
|
<span class="col-xs-4" ng-hide="showReg">
|
||||||
<span ng-show="aircraft.tail" ng-class="'label traffic-style'+aircraft.src+aircraft.targettype">{{aircraft.addr_symb}}<strong> {{aircraft.tail}}</strong></span>
|
<span ng-show="aircraft.tail" ng-class="'label traffic-style'+aircraft.src+aircraft.targettype">{{aircraft.addr_symb}}<strong> {{aircraft.tail}}</strong></span>
|
||||||
<span ng-hide="aircraft.tail" ng-class="'label traffic-style'+aircraft.src+aircraft.targettype">{{aircraft.addr_symb}}<strong> [--N/A--]</strong></span>
|
<span ng-hide="aircraft.tail" ng-class="'label traffic-style'+aircraft.src+aircraft.targettype">{{aircraft.addr_symb}}<strong> [--N/A--]</strong></span>
|
||||||
</span>
|
</span>
|
||||||
<span class="col-xs-4" ng-show="showReg">
|
<span class="col-xs-4" ng-show="showReg">
|
||||||
<span ng-show="aircraft.reg" ng-class="'label traffic-style'+aircraft.src+aircraft.targettype">{{aircraft.addr_symb}}<strong> {{aircraft.reg}}</strong></span>
|
<span ng-show="aircraft.reg" ng-class="'label traffic-style'+aircraft.src+aircraft.targettype">{{aircraft.addr_symb}}<strong> {{aircraft.reg}}</strong></span>
|
||||||
<span ng-hide="aircraft.reg" ng-class="'label traffic-style'+aircraft.src+aircraft.targettype">{{aircraft.addr_symb}}<strong> [--N/A--]</strong></span>
|
<span ng-hide="aircraft.reg" ng-class="'label traffic-style'+aircraft.src+aircraft.targettype">{{aircraft.addr_symb}}<strong> [--N/A--]</strong></span>
|
||||||
</span>
|
</span>
|
||||||
<span class="col-xs-3" style="font-size:80%">{{aircraft.icao}}<span style="font-size:50%">{{aircraft.addr_type == 3 ? " (TFID)" : ""}}</span></span>
|
<span class="col-xs-3" style="font-size:80%">{{aircraft.icao}}<span style="font-size:50%">{{aircraft.addr_type == 3 ? " (TFID)" : ""}}</span></span>
|
||||||
<span class="col-xs-3"><span ng-show="aircraft.squawk < 1000">0</span><span ng-show="aircraft.squawk < 100">0</span><span ng-show="aircraft.squawk < 10">0</span>{{aircraft.squawk}}</span>
|
<span class="col-xs-3"><span ng-show="aircraft.squawk < 1000">0</span><span ng-show="aircraft.squawk < 100">0</span><span ng-show="aircraft.squawk < 10">0</span>{{aircraft.squawk}}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-sm-6">
|
<div class="col-sm-6">
|
||||||
<span class="col-xs-3 text-right">{{aircraft.alt}}</span>
|
<span class="col-xs-3 text-right">{{aircraft.alt}}</span>
|
||||||
<span class="col-xs-1 small col-padding-shift-right text-muted">
|
<span class="col-xs-1 small col-padding-shift-right text-muted">
|
||||||
<span ng-show="aircraft.vspeed > 0"><span class="fa fa-ascent"></span>{{aircraft.vspeed}}</span>
|
<span ng-show="aircraft.vspeed > 0"><span class="fa fa-ascent"></span>{{aircraft.vspeed}}</span>
|
||||||
<span ng-show="aircraft.vspeed < 0"><span class="fa fa-descent"></span>{{0-aircraft.vspeed}}</span>
|
<span ng-show="aircraft.vspeed < 0"><span class="fa fa-descent"></span>{{0-aircraft.vspeed}}</span>
|
||||||
</span>
|
</span>
|
||||||
<span class="col-xs-2 text-right">{{aircraft.speed}}<span style="font-size:50%">KTS</span></span>
|
<span class="col-xs-2 text-right">{{aircraft.speed}}<span style="font-size:50%">KTS</span></span>
|
||||||
<span class="col-xs-2 text-right"><span ng-show="aircraft.heading < 10">0</span><span ng-show="aircraft.heading < 100">0</span>{{aircraft.heading}}°</span>
|
<span class="col-xs-2 text-right"><span ng-show="aircraft.heading < 10">0</span><span ng-show="aircraft.heading < 100">0</span>{{aircraft.heading}}°</span>
|
||||||
<span class="col-xs-2 text-right">{{aircraft.signal.toFixed(2)}}<span style="font-size:50%">dB</span></span>
|
<span class="col-xs-2 text-right">{{aircraft.signal.toFixed(2)}}<span style="font-size:50%">dB</span></span>
|
||||||
<span class="col-xs-2 text-right">{{aircraft.ageLastAlt.toFixed(1)}}<span style="font-size:50%">s</span></span>
|
<span class="col-xs-2 text-right">{{aircraft.ageLastAlt.toFixed(1)}}<span style="font-size:50%">s</span></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="panel-body traffic-footer">
|
<div class="panel-body traffic-footer">
|
||||||
<div class="separator"></div>
|
<div class="separator"></div>
|
||||||
<span class ="col-sm-12 small">Stratux has not received valid ADS-B position transmissions from the aircraft in this section. They will not appear on your EFB map. See help page for details.</span>
|
<span class ="col-sm-12 small">Stratux has not received valid ADS-B position transmissions from the aircraft in this section. They will not appear on your EFB map. See help page for details.</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">Raw Traffic Data</div>
|
<div class="panel-heading">Raw Traffic Data</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<pre>{{raw_data}}</pre>
|
<pre>{{raw_data}}</pre>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
-->
|
-->
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
<div class="section text-left help-page">
|
<div class="section text-left help-page">
|
||||||
<p>The <strong>Weather</strong> page provides a list of recent reports received.</p>
|
<p>The <strong>Weather</strong> page provides a list of recent reports received.</p>
|
||||||
<p>There are two lists available for reference:</p>
|
<p>There are two lists available for reference:</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li><strong>Watch List</strong> contains all weather received for locations included in your watch list <span class="fa fa-asterisk icon-blue"></span></li>
|
<li><strong>Watch List</strong> contains all weather received for locations included in your watch list <span class="fa fa-asterisk icon-blue"></span></li>
|
||||||
<li><strong>Recent Reports</strong> contains the most recent 10 reports received of any type for any location</li>
|
<li><strong>Recent Reports</strong> contains the most recent 10 reports received of any type for any location</li>
|
||||||
</ul>
|
</ul>
|
||||||
<p><span class="fa fa-asterisk icon-blue"></span> The Watch List setting is found on the <strong>Settings</strong> page.</p>
|
<p><span class="fa fa-asterisk icon-blue"></span> The Watch List setting is found on the <strong>Settings</strong> page.</p>
|
||||||
<p class="text-warning">NOTE: When this page becomes active (aka it is selected from the menu) it will display only new weather. Older weather and existing weather will not appear until their next report.</p>
|
<p class="text-warning">NOTE: When this page becomes active (aka it is selected from the menu) it will display only new weather. Older weather and existing weather will not appear until their next report.</p>
|
||||||
</div>
|
</div>
|
|
@ -1,92 +1,92 @@
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<span class="panel_label">Weather</span>
|
<span class="panel_label">Weather</span>
|
||||||
<span ng-show="ConnectState == 'Connected'" class="label label-success">{{ConnectState}}</span>
|
<span ng-show="ConnectState == 'Connected'" class="label label-success">{{ConnectState}}</span>
|
||||||
<span ng-hide="ConnectState == 'Connected'" class="label label-danger">{{ConnectState}}</span>
|
<span ng-hide="ConnectState == 'Connected'" class="label label-danger">{{ConnectState}}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="panel-group" ui-state="weatherAccordion" ui-default="1">
|
<div class="panel-group" ui-state="weatherAccordion" ui-default="1">
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading" ui-set="{'weatherAccordion':1}">
|
<div class="panel-heading" ui-set="{'weatherAccordion':1}">
|
||||||
<div class="panel-title">Watching <span class="text-normal">{{watching}}</span> ({{watch_count}})</div>
|
<div class="panel-title">Watching <span class="text-normal">{{watching}}</span> ({{watch_count}})</div>
|
||||||
</div>
|
</div>
|
||||||
<div ui-if="weatherAccordion == 1">
|
<div ui-if="weatherAccordion == 1">
|
||||||
<div class="panel-body weather-page">
|
<div class="panel-body weather-page">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-6">
|
<div class="col-sm-6">
|
||||||
<span class="col-xs-3"><strong>Location</strong></span>
|
<span class="col-xs-3"><strong>Location</strong></span>
|
||||||
<span class="col-xs-3">Type</span>
|
<span class="col-xs-3">Type</span>
|
||||||
<span class="col-xs-6 text-right">Time</span>
|
<span class="col-xs-6 text-right">Time</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-6">
|
<div class="col-sm-6">
|
||||||
<span class="col-xs-2"> </span>
|
<span class="col-xs-2"> </span>
|
||||||
<span class="col-xs-10">Report</span>
|
<span class="col-xs-10">Report</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row" ng-repeat="weather in watch_list | orderBy: -age">
|
<div class="row" ng-repeat="weather in watch_list | orderBy: -age">
|
||||||
<div class="separator"></div>
|
<div class="separator"></div>
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
<span class="col-xs-3"><strong>{{weather.location}}</strong></span>
|
<span class="col-xs-3"><strong>{{weather.location}}</strong></span>
|
||||||
<span class="col-xs-3" align="center">
|
<span class="col-xs-3" align="center">
|
||||||
<div align="center" ng-class="weather.flight_condition ? ' label label-success flight_condition_{{weather.flight_condition}}' : 'label label-success report_{{weather.type}}'">{{weather.type}}</div>
|
<div align="center" ng-class="weather.flight_condition ? ' label label-success flight_condition_{{weather.flight_condition}}' : 'label label-success report_{{weather.type}}'">{{weather.type}}</div>
|
||||||
</span>
|
</span>
|
||||||
<span class="col-xs-4"> </span>
|
<span class="col-xs-4"> </span>
|
||||||
<span class="col-xs-2 text-right" style="background-color: {{weather.backcolor}}">{{weather.time}}</span>
|
<span class="col-xs-2 text-right" style="background-color: {{weather.backcolor}}">{{weather.time}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
<span class="col-xs-10">{{weather.data}}</span>
|
<span class="col-xs-10">{{weather.data}}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading" ui-set="{'weatherAccordion':2}">
|
<div class="panel-heading" ui-set="{'weatherAccordion':2}">
|
||||||
<div class="panel-title">Recent Reports ({{data_count}})</div>
|
<div class="panel-title">Recent Reports ({{data_count}})</div>
|
||||||
</div>
|
</div>
|
||||||
<div ui-if="weatherAccordion == 2">
|
<div ui-if="weatherAccordion == 2">
|
||||||
<div class="panel-body weather-page">
|
<div class="panel-body weather-page">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-6">
|
<div class="col-sm-6">
|
||||||
<span class="col-xs-3"><strong>Location</strong></span>
|
<span class="col-xs-3"><strong>Location</strong></span>
|
||||||
<span class="col-xs-3">Type</span>
|
<span class="col-xs-3">Type</span>
|
||||||
<span class="col-xs-6 text-right">Time</span>
|
<span class="col-xs-6 text-right">Time</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-6">
|
<div class="col-sm-6">
|
||||||
<span class="col-xs-2"> </span>
|
<span class="col-xs-2"> </span>
|
||||||
<span class="col-xs-10">Report</span>
|
<span class="col-xs-10">Report</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row" ng-repeat="weather in data_list | orderBy: -age">
|
<div class="row" ng-repeat="weather in data_list | orderBy: -age">
|
||||||
<div class="separator"></div>
|
<div class="separator"></div>
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
<span class="col-xs-3"><strong>{{weather.location}}</strong></span>
|
<span class="col-xs-3"><strong>{{weather.location}}</strong></span>
|
||||||
<span class="col-xs-3" align="center">
|
<span class="col-xs-3" align="center">
|
||||||
<div align="center" ng-class="weather.flight_condition ? ' label label-success flight_condition_{{weather.flight_condition}}' : 'label label-success report_{{weather.type}}'">{{weather.type}}</div>
|
<div align="center" ng-class="weather.flight_condition ? ' label label-success flight_condition_{{weather.flight_condition}}' : 'label label-success report_{{weather.type}}'">{{weather.type}}</div>
|
||||||
</span>
|
</span>
|
||||||
<span class="col-xs-4"> </span>
|
<span class="col-xs-4"> </span>
|
||||||
<span class="col-xs-2 text-right" style="background-color: {{weather.backcolor}}">{{weather.time}}</span>
|
<span class="col-xs-2 text-right" style="background-color: {{weather.backcolor}}">{{weather.time}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
<span class="col-xs-10">{{weather.data}}</span>
|
<span class="col-xs-10">{{weather.data}}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!--
|
<!--
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">Raw Weather Data</div>
|
<div class="panel-heading">Raw Weather Data</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<pre>{{raw_data}}</pre>
|
<pre>{{raw_data}}</pre>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
-->
|
-->
|
Ładowanie…
Reference in New Issue