traffic page complete; includes context sensitive help; does not include trafic fource indication

pull/71/head
bradanlane 2015-10-01 17:19:28 -04:00
rodzic 94876edd40
commit 45215e258b
18 zmienionych plików z 594 dodań i 382 usunięć

Wyświetl plik

@ -9,8 +9,37 @@ all:
test:
sh -c true
www:
mkdir -p /var/www
mkdir -p /var/www/css
cp web/css/*.css /var/www/css
mkdir -p /var/www/js
cp web/js/*.js /var/www/js
mkdir -p /var/www/img
cp web/img/logo*.png /var/www/img
cp web/img/screen*.png /var/www/img
mkdir -p /var/www/maui
mkdir -p /var/www/maui/js
cp web/maui/js/angular-ui-router.min.js /var/www/maui/js
cp web/maui/js/mobile-angular-ui.min.js /var/www/maui/js
cp web/maui/js/angular.min.js /var/www/maui/js
cp web/maui/js/mobile-angular-ui.gestures.min.js /var/www/maui/js
cp web/maui/js/mobile-angular-ui.core.min.js /var/www/maui/js
mkdir -p /var/www/maui/css
cp web/maui/css/mobile-angular-ui-hover.min.css /var/www/maui/css
cp web/maui/css/mobile-angular-ui-desktop.min.css /var/www/maui/css
cp web/maui/css/mobile-angular-ui-base.min.css /var/www/maui/css
mkdir -p /var/www/maui/fonts
cp web/maui/fonts/fontawesome-webfont.woff /var/www/maui/fonts
mkdir -p /var/www/plates
cp web/plates/*.html /var/www/plates
mkdir -p /var/www/plates/js
cp web/plates/js/*.js /var/www/plates/js
cp web/index.html /var/www
install:
cp -f gen_gdl90 /usr/bin/gen_gdl90
chmod 755 /usr/bin/gen_gdl90
clean:
rm -f gen_gdl90

Wyświetl plik

@ -43,6 +43,9 @@ func handleWeatherWS(conn *websocket.Conn) {
func handleTrafficWS(conn *websocket.Conn) {
trafficMutex.Lock()
for _, traf := range traffic {
if !traf.Position_valid { // Don't send unless a valid position exists.
continue
}
trafficJSON, _ := json.Marshal(&traf)
conn.Write(trafficJSON)
}

Wyświetl plik

@ -48,6 +48,11 @@ AUXSV:
*/
const (
TRAFFIC_SOURCE_1090ES = 1
TRAFFIC_SOURCE_UAT = 2
)
type TrafficInfo struct {
Icao_addr uint32
addr_type uint8
@ -68,7 +73,8 @@ type TrafficInfo struct {
Tail string
Last_seen time.Time
Last_seen time.Time
Last_source uint8
}
var traffic map[uint32]TrafficInfo
@ -96,7 +102,9 @@ func sendTrafficUpdates() {
// Send update to attached client.
func registerTrafficUpdate(ti TrafficInfo) {
trafficUpdate <- ti
if ti.Position_valid { // Don't send unless a valid position exists.
trafficUpdate <- ti
}
}
func makeTrafficReport(ti TrafficInfo) {
@ -326,6 +334,7 @@ func parseDownlinkReport(s string) {
//OK.
// fmt.Printf("tisb_site_id %d, utc_coupled %t\n", tisb_site_id, utc_coupled)
ti.Last_source = TRAFFIC_SOURCE_UAT
ti.Last_seen = time.Now()
// Parse tail number, if available.
@ -497,6 +506,7 @@ func esListen() {
}
// Update "last seen" (any type of message, as long as the ICAO addr can be parsed).
ti.Last_source = TRAFFIC_SOURCE_1090ES
ti.Last_seen = time.Now()
ti.addr_type = 0 //FIXME: ADS-B with ICAO address. Not recognized by ForeFlight.

Wyświetl plik

@ -1,122 +1,216 @@
.help-page {
font-size: 0.85em;
font-size: 0.85em;
}
.section_invisible {
display: none;
display: none;
}
.ahrs_connected {
content:
content:
}
.ahrs_disconnected {}
.separator {
height: 1px;
border-bottom: 1px solid #cccccc;
margin-bottom: 4px;
height: 1px;
border-bottom: 1px solid #cccccc;
margin-bottom: 4px;
}
.label_adj {
margin-left: -6px;
margin-right: -6px;
}
.col-padding-shift-right {
margin-left: -12px;
margin-right: 12px;
}
.col-padding-shift-left {
margin-left: 12px;
margin-right: -12px;
}
.feature-icon {
font-size: 44px;
text-align: center;
line-height: 68px;
opacity: 0.8;
width: 72px;
height: 72px;
border: 3px solid;
border-radius: 200px;
padding: 0;
margin-bottom: 20px;
}
.list-simple {
padding-left: 12px;
list-style: none;
}
/* ***************************************************************************
everything below this comment represents tweeks to the mobile-angular-uis CSS
*************************************************************************** */
.label_adj {
margin-left: -15px;
margin-right: -15px;
}
@font-face {
font-family: 'FontAwesome';
src: url('../maui/fonts/fontawesome-webfont.woff?v=4.4.0') format('woff');
font-weight: normal;
font-style: normal;
}
.row {
margin-left: -6px;
margin-right: -6px;
}
.col-xs-1,
.col-sm-1,
.col-md-1,
.col-lg-1,
.col-xs-2,
.col-sm-2,
.col-md-2,
.col-lg-2,
.col-xs-3,
.col-sm-3,
.col-md-3,
.col-lg-3,
.col-xs-4,
.col-sm-4,
.col-md-4,
.col-lg-4,
.col-xs-5,
.col-sm-5,
.col-md-5,
.col-lg-5,
.col-xs-6,
.col-sm-6,
.col-md-6,
.col-lg-6,
.col-xs-7,
.col-sm-7,
.col-md-7,
.col-lg-7,
.col-xs-8,
.col-sm-8,
.col-md-8,
.col-lg-8,
.col-xs-9,
.col-sm-9,
.col-md-9,
.col-lg-9,
.col-xs-10,
.col-sm-10,
.col-md-10,
.col-lg-10,
.col-xs-11,
.col-sm-11,
.col-md-11,
.col-lg-11,
.col-xs-12,
.col-sm-12,
.col-md-12,
.col-lg-12 {
position: relative;
min-height: 1px;
padding-left: 6px;
padding-right: 6px;
}
input[type="number_format"] {
text-align: end;
text-align: end;
}
.sidebar .scrollable-header,
.panel-title {
border-bottom: 1px solid #cccccc;
border-bottom: 1px solid #cccccc;
}
.app-body,
.panel-default,
.scrollable-content,
.form-group {
background-color: #ffffff;
background-color: #ffffff;
}
.app-content {
margin-top: 4px;
margin-top: 4px;
}
.sidebar-header,
.app-name {
line-height: 50px;
color: #000;
background-color: #f7f7f7;
line-height: 50px;
color: #000;
background-color: #f7f7f7;
}
.panel-heading {
padding: 4px 4px 4px 4px;
border-bottom: 1px solid transparent;
border-top-right-radius: 3px;
border-top-left-radius: 3px;
border-bottom: 1px solid #cccccc;
font-weight: bold;
padding: 4px 4px 4px 4px;
border-bottom: 1px solid transparent;
border-top-right-radius: 3px;
border-top-left-radius: 3px;
border-bottom: 1px solid #cccccc;
font-weight: bold;
}
.panel-group .panel-heading {
border-bottom: inherit;
border-bottom: inherit;
}
.panel_label {
font-size: 16px;
margin-top: 4px;
display: inline-block;
line-height: 12px;
vertical-align: bottom;
padding-bottom: 2px;
font-size: 16px;
margin-top: 4px;
display: inline-block;
line-height: 12px;
vertical-align: bottom;
padding-bottom: 2px;
}
.panel-body {
padding: 8px 4px 4px 4px;
padding: 8px 4px 4px 4px;
}
.control-label {
line-height: 28px;
margin-bottom: 4px;
line-height: 28px;
margin-bottom: 4px;
}
.switch {
cursor: pointer;
position: relative;
display: block;
width: 52px;
height: 28px;
margin-bottom: 4px;
cursor: pointer;
position: relative;
display: block;
width: 52px;
height: 28px;
margin-bottom: 4px;
}
.switch .switch-handle {
width: 26px;
height: 28px;
width: 26px;
height: 28px;
}
.switch.active .switch-handle {
border-color: #007aff;
-webkit-transform: translate(26px, 0);
-ms-transform: translate(26px, 0);
-o-transform: translate(26px, 0);
transform: translate(26px, 0);
border-color: #007aff;
-webkit-transform: translate(26px, 0);
-ms-transform: translate(26px, 0);
-o-transform: translate(26px, 0);
transform: translate(26px, 0);
}
pre {
display: block;
padding: 0;
margin: 0;
font-size: 13px;
line-height: 1.42857143;
word-break: break-all;
word-wrap: break-word;
color: #333333;
background-color: inherit;
border: 0px;
border-radius: 0px;
display: block;
padding: 0;
margin: 0;
font-size: 13px;
line-height: 1.42857143;
word-break: break-all;
word-wrap: break-word;
color: #333333;
background-color: inherit;
border: 0px;
border-radius: 0px;
}

Wyświetl plik

@ -2,137 +2,138 @@
<html>
<head>
<meta charset="utf-8" />
<title>Stratux</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="viewport" content="user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimal-ui" />
<!-- android -->
<meta name="mobile-web-app-capable" content="yes">
<link href="img/logo-android3.png" rel="icon" />
<!-- iOS -->
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<link href="img/logo-apple3.png" rel="apple-touch-icon" />
<meta charset="utf-8" />
<title>Stratux</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="viewport" content="user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimal-ui" />
<!-- android -->
<meta name="mobile-web-app-capable" content="yes">
<link href="img/logo-android3.png" rel="icon" />
<!-- iOS -->
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<link href="img/logo-apple3.png" rel="apple-touch-icon" />
<!-- iPad retina portrait startup image -->
<link href="img/screen-1536x2008.png" media="(device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" rel="apple-touch-startup-image">
<!-- iPad retina landscape startup image -->
<link href="img/screen-1496x2048.png" media="(device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" rel="apple-touch-startup-image">
<!-- iPad non-retina portrait startup image -->
<link href="img/screen-768x1004.png" media="(device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 1) and (orientation: portrait)" rel="apple-touch-startup-image">
<!-- iPad non-retina landscape startup image -->
<link href="img/screen-748x1024.png" media="(device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 1) and (orientation: landscape)" rel="apple-touch-startup-image">
<!-- iPhone 6 Plus portrait startup image -->
<link href="img/screen-1242x2148.png" media="(device-width: 414px) and (device-height: 736px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)" rel="apple-touch-startup-image">
<!-- iPhone 6 Plus landscape startup image -->
<link href="img/screen-1182x2208.png" media="(device-width: 414px) and (device-height: 736px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)" rel="apple-touch-startup-image">
<!-- iPhone 6 startup image -->
<link href="img/screen-750x1294.png" media="(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2)" rel="apple-touch-startup-image">
<!-- iPhone 5 startup image -->
<link href="img/screen-640x1096.png" media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2)" rel="apple-touch-startup-image">
<!-- iPhone < 5 retina startup image -->
<link href="img/screen-640x920.png" media="(device-width: 320px) and (device-height: 480px) and (-webkit-device-pixel-ratio: 2)" rel="apple-touch-startup-image">
<!-- iPhone < 5 non-retina startup image -->
<link href="img/screen-320x460.png" media="(device-width: 320px) and (device-height: 480px) and (-webkit-device-pixel-ratio: 1)" rel="apple-touch-startup-image">
<!-- iPad retina portrait startup image -->
<link href="img/screen-1536x2008.png" media="(device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" rel="apple-touch-startup-image">
<!-- iPad retina landscape startup image -->
<link href="img/screen-1496x2048.png" media="(device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" rel="apple-touch-startup-image">
<!-- iPad non-retina portrait startup image -->
<link href="img/screen-768x1004.png" media="(device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 1) and (orientation: portrait)" rel="apple-touch-startup-image">
<!-- iPad non-retina landscape startup image -->
<link href="img/screen-748x1024.png" media="(device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 1) and (orientation: landscape)" rel="apple-touch-startup-image">
<!-- iPhone 6 Plus portrait startup image -->
<link href="img/screen-1242x2148.png" media="(device-width: 414px) and (device-height: 736px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)" rel="apple-touch-startup-image">
<!-- iPhone 6 Plus landscape startup image -->
<link href="img/screen-1182x2208.png" media="(device-width: 414px) and (device-height: 736px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)" rel="apple-touch-startup-image">
<!-- iPhone 6 startup image -->
<link href="img/screen-750x1294.png" media="(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2)" rel="apple-touch-startup-image">
<!-- iPhone 5 startup image -->
<link href="img/screen-640x1096.png" media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2)" rel="apple-touch-startup-image">
<!-- iPhone < 5 retina startup image -->
<link href="img/screen-640x920.png" media="(device-width: 320px) and (device-height: 480px) and (-webkit-device-pixel-ratio: 2)" rel="apple-touch-startup-image">
<!-- iPhone < 5 non-retina startup image -->
<link href="img/screen-320x460.png" media="(device-width: 320px) and (device-height: 480px) and (-webkit-device-pixel-ratio: 1)" rel="apple-touch-startup-image">
<link rel="stylesheet" type="text/css" href="css/addtohomescreen.css">
<script src="js/addtohomescreen.min.js"></script>
<script>
addToHomescreen({
displayPace: 480
});
</script>
<link rel="stylesheet" type="text/css" href="css/addtohomescreen.css">
<script src="js/addtohomescreen.min.js"></script>
<script>
addToHomescreen({
displayPace: 480
});
</script>
<link rel="stylesheet" href="maui/css/mobile-angular-ui-base.css" />
<link rel="stylesheet" href="maui/css/mobile-angular-ui-hover.css" />
<link rel="stylesheet" href="maui/css/mobile-angular-ui-desktop.css" />
<link rel="stylesheet" href="maui/css/mobile-angular-ui-base.min.css" />
<link rel="stylesheet" href="maui/css/mobile-angular-ui-hover.min.css" />
<link rel="stylesheet" href="maui/css/mobile-angular-ui-desktop.min.css" />
<link rel="stylesheet" href="css/main.css" />
<link rel="stylesheet" href="css/main.css" />
<script src="maui/js/angular.min.js"></script>
<script src="maui/js/angular-ui-router.min.js"></script>
<script src="maui/js/mobile-angular-ui.min.js"></script>
<script src="maui/js/mobile-angular-ui.gestures.min.js"></script>
<script src="maui/js/angular.min.js"></script>
<script src="maui/js/angular-ui-router.min.js"></script>
<script src="maui/js/mobile-angular-ui.min.js"></script>
<script src="maui/js/mobile-angular-ui.gestures.min.js"></script>
<!-- TODO: combine and minify the following javascript -->
<script src="js/main.js"></script>
<script src="plates/js/ahrs.js"></script>
<script src="plates/js/gps.js"></script>
<script src="plates/js/logs.js"></script>
<script src="plates/js/settings.js"></script>
<script src="plates/js/status.js"></script>
<script src="plates/js/traffic.js"></script>
<script src="plates/js/weather.js"></script>
<!-- TODO: combine and minify the following javascript -->
<script src="js/main.js"></script>
<script src="plates/js/gps.js"></script>
<script src="plates/js/logs.js"></script>
<script src="plates/js/settings.js"></script>
<script src="plates/js/status.js"></script>
<script src="plates/js/traffic.js"></script>
<script src="plates/js/weather.js"></script>
</head>
<body ng-app="stratux" ng-controller="MainCtrl" ui-prevent-touchmove-defaults>
<!-- Define Left (Menu) Sidebar Navigation -->
<div ui-track-as-search-param='true' class="sidebar sidebar-left">
<div class="scrollable">
<h3 class="scrollable-header app-name">Menu</h3>
<div class="scrollable-content">
<div class="list-group" ui-turn-off='uiSidebarLeft'>
<!-- hrefs are redirected by the state engine in main.js -->
<a class="list-group-item" href="#/"><i class="fa fa-home"></i> Status <i class="fa fa-chevron-right pull-right"></i></a>
<a class="list-group-item" href="#/weather"><i class="fa fa-cloud"></i> Weather <i class="fa fa-chevron-right pull-right"></i></a>
<a class="list-group-item" href="#/traffic"><i class="fa fa-plane"></i> Traffic <i class="fa fa-chevron-right pull-right"></i></a>
<a class="list-group-item" href="#/gps"><i class="fa fa-globe"></i> GPS <i class="fa fa-chevron-right pull-right"></i></a>
<a class="list-group-item" href="#/ahrs"><i class="fa fa-crosshairs"></i> AHRS <i class="fa fa-chevron-right pull-right"></i></a>
<a class="list-group-item" href="#/logs"><i class="fa fa-file-text-o"></i> Logs <i class="fa fa-chevron-right pull-right"></i></a>
<a class="list-group-item" href="#/settings"><i class="fa fa-gear"></i> Settings <i class="fa fa-chevron-right pull-right"></i></a>
</div>
</div>
</div>
</div>
<!-- Define Right (Help) Sidebar -->
<div class="sidebar sidebar-right">
<div class="scrollable">
<h3 class="scrollable-header app-name">Help</h3>
<div class="scrollable-content">
<div class="list-group" ui-toggle="uiSidebarRight">
<div ng-include="helppage"></div>
</div>
</div>
</div>
</div>
<!-- Define Left (Menu) Sidebar Navigation -->
<div ui-track-as-search-param='true' class="sidebar sidebar-left">
<div class="scrollable">
<h3 class="scrollable-header app-name">Menu</h3>
<div class="scrollable-content">
<div class="list-group" ui-turn-off='uiSidebarLeft'>
<!-- hrefs are redirected by the state engine in main.js -->
<a class="list-group-item" href="#/"><i class="fa fa-home"></i> Status <i class="fa fa-chevron-right pull-right"></i></a>
<a class="list-group-item" href="#/weather"><i class="fa fa-cloud"></i> Weather <i class="fa fa-chevron-right pull-right"></i></a>
<a class="list-group-item" href="#/traffic"><i class="fa fa-plane"></i> Traffic <i class="fa fa-chevron-right pull-right"></i></a>
<a class="list-group-item" href="#/gps"><i class="fa fa-globe"></i> GPS/AHRS <i class="fa fa-chevron-right pull-right"></i></a>
<!--
<a class="list-group-item" href="#/ahrs"><i class="fa fa-crosshairs"></i> AHRS <i class="fa fa-chevron-right pull-right"></i></a>
-->
<a class="list-group-item" href="#/logs"><i class="fa fa-file-text-o"></i> Logs <i class="fa fa-chevron-right pull-right"></i></a>
<a class="list-group-item" href="#/settings"><i class="fa fa-gear"></i> Settings <i class="fa fa-chevron-right pull-right"></i></a>
</div>
</div>
</div>
</div>
<!-- Define Right (Help) Sidebar -->
<div class="sidebar sidebar-right">
<div class="scrollable">
<h3 class="scrollable-header app-name">Help</h3>
<div class="scrollable-content">
<div class="list-group" ui-toggle="uiSidebarRight">
<div ng-include="helppage"></div>
</div>
</div>
</div>
</div>
<div class="app" ui-swipe-right='Ui.turnOn("uiSidebarLeft")' ui-swipe-left='Ui.turnOff("uiSidebarLeft")'>
<div class="app" ui-swipe-right='Ui.turnOn("uiSidebarLeft")' ui-swipe-left='Ui.turnOff("uiSidebarLeft")'>
<!-- Create Header Navbar with left Menu Button -->
<div class="navbar navbar-app navbar-absolute-top">
<div class="navbar-brand navbar-brand-center" ui-yield-to="title">
<a href="#/">
<!-- Create Header Navbar with left Menu Button -->
<div class="navbar navbar-app navbar-absolute-top">
<div class="navbar-brand navbar-brand-center" ui-yield-to="title">
<a href="#/">
Stratux
</a>
</div>
<div class="btn-group pull-left">
<div ui-toggle="uiSidebarLeft" class="btn sidebar-toggle">
<i class="fa fa-bars"></i> Menu
</div>
</div>
<div class="btn-group pull-right" ui-yield-to="navbarAction">
<div ui-toggle="uiSidebarRight" class="btn">
<i class="fa fa-info-circle"></i> Help
</div>
</div>
</div>
</div>
<div class="btn-group pull-left">
<div ui-toggle="uiSidebarLeft" class="btn sidebar-toggle">
<i class="fa fa-bars"></i> Menu
</div>
</div>
<div class="btn-group pull-right" ui-yield-to="navbarAction">
<div ui-toggle="uiSidebarRight" class="btn">
<i class="fa fa-info-circle"></i> Help
</div>
</div>
</div>
<!-- App Body -->
<div class="app-body">
<div class="app-content">
<div class="scrollable">
<div class="scrollable-content">
<div ui-view></div>
</div>
</div>
</div>
</div>
<!-- App Body -->
<div class="app-body">
<div class="app-content">
<div class="scrollable">
<div class="scrollable-content">
<div ui-view></div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>

Wyświetl plik

@ -12,67 +12,22 @@ var appControllers = angular.module('appControllers', []);
app.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('home', {
url: '/',
templateUrl: 'plates/status.html',
controller: 'StatusCtrl',
reloadOnSearch: false
})
.state('weather', {
url: '/weather',
templateUrl: 'plates/weather.html',
controller: 'WeatherCtrl',
reloadOnSearch: false
})
.state('traffic', {
url: '/traffic',
templateUrl: 'plates/traffic.html',
controller: 'TrafficCtrl',
reloadOnSearch: false
})
.state('gps', {
url: '/gps',
templateUrl: 'plates/gps.html',
controller: 'GPSCtrl',
reloadOnSearch: false
})
.state('ahrs', {
url: '/ahrs',
templateUrl: 'plates/ahrs.html',
controller: 'AHRSCtrl',
reloadOnSearch: false
})
.state('logs', {
url: '/logs',
templateUrl: 'plates/logs.html',
controller: 'LogsCtrl',
reloadOnSearch: false
})
.state('settings', {
url: '/settings',
templateUrl: 'plates/settings.html',
controller: 'SettingsCtrl',
reloadOnSearch: false
});
$urlRouterProvider.otherwise('/');
$stateProvider
.state('home', { url: '/', templateUrl: 'plates/status.html', controller: 'StatusCtrl', reloadOnSearch: false })
.state('weather', { url: '/weather', templateUrl: 'plates/weather.html', controller: 'WeatherCtrl', reloadOnSearch: false })
.state('traffic', { url: '/traffic', templateUrl: 'plates/traffic.html', controller: 'TrafficCtrl', reloadOnSearch: false })
.state('gps', { url: '/gps', templateUrl: 'plates/gps.html', controller: 'GPSCtrl', reloadOnSearch: false })
.state('logs', { url: '/logs', templateUrl: 'plates/logs.html', controller: 'LogsCtrl', reloadOnSearch: false })
.state('settings', { url: '/settings', templateUrl: 'plates/settings.html',controller: 'SettingsCtrl', reloadOnSearch: false });
$urlRouterProvider.otherwise('/');
});
app.run(function ($transform) {
window.$transform = $transform;
window.$transform = $transform;
});
/*
app.config(function ($httpProvider) {
// We need to setup some parameters for http requests
// These three lines are all you need for CORS support
$httpProvider.defaults.useXDomain = true;
// $httpProvider.defaults.withCredentials = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
});
*/
// For this app we have a MainController for whatever and the nindividual controllers for each page
// For this app we have a MainController for whatever and individual controllers for each page
app.controller('MainCtrl', function ($rootScope, $scope) {
// any logic global logic
// any logic global logic
});

Wyświetl plik

@ -1,13 +0,0 @@
<div class="list-group text-center">
<div class="list-group-item list-group-item-home">
<h2>AHRS Status</h2>
</div>
<div class="list-group-item list-group-item-home">
<div>
<i class="fa fa-crosshairs feature-icon text-primary"></i>
</div>
<div>
this space reserved to display AHRS status
</div>
</div>
</div>

Wyświetl plik

@ -4,10 +4,10 @@
</div>
<div class="list-group-item list-group-item-home">
<div>
<i class="fa fa-glob feature-icon text-primary"></i>
<i class="fa fa-globe feature-icon text-primary"></i>
</div>
<div>
this space reserved to display GPS status
this space reserved to display GPS/AHRS status
</div>
</div>
</div>

Wyświetl plik

@ -1,21 +0,0 @@
<div class="scrollable">
<div class="scrollable-content">
<div class="list-group" ui-toggle="uiSidebarRight">
<div class="list-group text-center">
<div class="list-group-item list-group-item-home">
<h2>Help</h2>
</div>
<div class="list-group-item list-group-item-home">
<div>
<i class="fa fa-info-circle feature-icon text-primary"></i>
</div>
<div>
this space reserved to display context sensitive help
</div>
</div>
</div>
</div>
</div>
</div>

Wyświetl plik

@ -1,15 +0,0 @@
angular.module('appControllers').controller('AHRSCtrl', AHRSCtrl); // get the main module contollers set
AHRSCtrl.$inject = ['$rootScope', '$scope', '$state', '$http']; // Inject my dependencies
// create our controller function with all necessary logic
function AHRSCtrl($rootScope, $scope, $state, $http) {
/*
$state.get('weather').onEnter = function () {
};
$state.get('weather').onExit = function () {
};
*/
// Weather Controller tasks go here
};

Wyświetl plik

@ -49,7 +49,7 @@ function SettingsCtrl($rootScope, $scope, $state, $http) {
$scope.AHRS_Enabled = settings.AHRS_Enabled;
$scope.DEBUG = settings.DEBUG;
$scope.ReplayLog = settings.ReplayLog;
$scope.PPM = parseInt(settings.PPM);
$scope.PPM = settings.PPM;
// $scope.$apply();
}, function (response) {
$scope.rawSettings = "error setting settings";
@ -82,9 +82,9 @@ function SettingsCtrl($rootScope, $scope, $state, $http) {
$scope.updateppm = function() {
if (($scope.PPM !== undefined) && ($scope.PPM !== null) && $scope.PPM !== settings["PPM"]) {
settings["PPM"] = $scope.PPM;
settings["PPM"] = parseInt($scope.PPM);
newsettings = {
"PPM": $scope.PPM
"PPM": parseInt($scope.PPM)
};
console.log(angular.toJson(newsettings));
setSettings(angular.toJson(newsettings));

Wyświetl plik

@ -11,8 +11,7 @@ function StatusCtrl($rootScope, $scope, $state, $http) {
return; // we are getting called once after clicking away from the status page
if (($scope.socket === undefined) || ($scope.socket === null)) {
// socket = new WebSocket('ws://' + window.location.hostname + '/control');
socket = new WebSocket('ws://' + URL_HOST_BASE + '/control');
socket = new WebSocket('ws://' + URL_HOST_BASE + '/status');
$scope.socket = socket; // store socket in scope for enter/exit usage
}

Wyświetl plik

@ -1,15 +1,135 @@
angular.module('appControllers').controller('TrafficCtrl', TrafficCtrl); // get the main module contollers set
TrafficCtrl.$inject = ['$rootScope', '$scope', '$state', '$http']; // Inject my dependencies
TrafficCtrl.$inject = ['$rootScope', '$scope', '$state', '$http', '$interval']; // Inject my dependencies
// create our controller function with all necessary logic
function TrafficCtrl($rootScope, $scope, $state, $http) {
function TrafficCtrl($rootScope, $scope, $state, $http, $interval) {
/*
$state.get('weather').onEnter = function () {
};
$state.get('weather').onExit = function () {
};
*/
$scope.$parent.helppage = 'plates/traffic-help.html';
$scope.traffic = [];
// Weather Controller tasks go here
function utcTimeString(epoc) {
var time = "";
var val;
var d = new Date(epoc);
val = d.getUTCHours();
time += (val < 10 ? "0" + val : "" + val);
val = d.getUTCMinutes();
time += ":" + (val < 10 ? "0" + val : "" + val);
val = d.getUTCSeconds();
time += ":" + (val < 10 ? "0" + val : "" + val);
time += "Z";
return time;
}
function dmsString(val) {
return [0 | val,
'd ',
0 | (val < 0 ? val = -val : val) % 1 * 60,
"' ",
0 | val * 60 % 1 * 60,
'"'].join('');
}
function setAircraft(obj, new_traffic) {
new_traffic.icao_int = obj.Icao_addr;
new_traffic.icao = obj.Icao_addr.toString(16).toUpperCase();
new_traffic.tail = obj.Tail;
new_traffic.lat = dmsString(obj.Lat);
new_traffic.lon = dmsString(obj.Lng);
var n = Math.round(obj.Alt / 100) * 100;
new_traffic.alt = n.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
new_traffic.heading = Math.round(obj.Track / 10) * 10;
new_traffic.speed = Math.round(obj.Speed / 10) * 10;
new_traffic.vspeed = Math.round(obj.Vvel / 100) * 100
new_traffic.age = Date.parse(obj.Last_seen);
new_traffic.time = utcTimeString(new_traffic.age);
// return new_aircraft;
}
function connect($scope) {
if (($scope === undefined) || ($scope === null))
return; // we are getting called once after clicking away from the status page
if (($scope.socket === undefined) || ($scope.socket === null)) {
socket = new WebSocket('ws://' + URL_HOST_BASE + '/traffic');
$scope.socket = socket; // store socket in scope for enter/exit usage
}
$scope.ConnectState = "Not Receiving";
socket.onopen = function (msg) {
$scope.ConnectStyle = "label-success";
$scope.ConnectState = "Receiving";
};
socket.onclose = function (msg) {
$scope.ConnectStyle = "label-danger";
$scope.ConnectState = "Not Receiving";
setTimeout(connect, 1000);
};
socket.onerror = function (msg) {
$scope.ConnectStyle = "label-danger";
$scope.ConnectState = "Problem";
};
socket.onmessage = function (msg) {
console.log('Received traffic update.')
var aircraft = JSON.parse(msg.data);
if (aircraft.Position_valid) {
$scope.rawTraffic = 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 traffic set
var found = false;
for (var i = 0, len = $scope.traffic.length; i < len; i++) {
if ($scope.traffic[i].icao_int === aircraft.Icao_addr) {
setAircraft(aircraft, $scope.traffic[i]);
found = true;
break;
}
}
if (!found) {
var new_traffic = {};
setAircraft(aircraft, new_traffic);
$scope.traffic.unshift(new_traffic); // add to start of array
}
$scope.$apply();
}
};
}
// perform cleanup every 60 seconds
var clearStaleTraffic = $interval(function () {
// remove stail aircraft = anything more than 180 seconds without and update
var dirty = false;
var cutoff = Date.now() - (180 * 1000);
for (var i = len = $scope.traffic.length; i > 0; i--) {
if ($scope.traffic[i - 1].age < cutoff) {
$scope.traffic.splice(i - 1, 1);
dirty = true;
}
}
if (dirty) {
$scope.$apply();
}
}, (1000 * 60), 0, false);
$state.get('traffic').onEnter = function () {
// everything gets handled correctly by the controller
};
$state.get('traffic').onExit = function () {
// disconnect from the socket
if (($scope.socket !== undefined) && ($scope.socket !== null)) {
$scope.socket.close();
$scope.socket = null;
}
// stop stale traffic cleanup
$interval.cancel(clearStaleTraffic);
};
// Traffic Controller tasks
connect($scope); // connect - opens a socket and listens for messages
};

Wyświetl plik

@ -6,7 +6,7 @@
<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.
<ul>
<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>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>

Wyświetl plik

@ -1,83 +1,80 @@
<div class="col-sm-12">
<div class="panel-group col-sm-6">
<div class="panel-group col-sm-6">
<div class="panel panel-default">
<div class="panel-heading">Hardware</div>
<div class="panel-body">
<div class="form-group">
<label class="control-label col-xs-7">978MHz</label>
<div class="col-xs-5">
<ui-switch ng-model='UAT_Enabled' settings-change></ui-switch>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-7">1090MHz</label>
<div class="col-xs-5">
<ui-switch ng-model='ES_Enabled' settings-change></ui-switch>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-7">GPS</label>
<div class="col-xs-5">
<ui-switch ng-model='GPS_Enabled' settings-change></ui-switch>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-7">AHRS</label>
<div class="col-xs-5">
<ui-switch ng-model='AHRS_Enabled' settings-change></ui-switch>
</div>
</div>
</div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">Hardware</div>
<div class="panel-body">
<div class="form-group">
<label class="control-label col-xs-7">978MHz</label>
<div class="col-xs-5">
<ui-switch ng-model='UAT_Enabled' settings-change></ui-switch>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-7">1090MHz</label>
<div class="col-xs-5">
<ui-switch ng-model='ES_Enabled' settings-change></ui-switch>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-7">GPS</label>
<div class="col-xs-5">
<ui-switch ng-model='GPS_Enabled' settings-change></ui-switch>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-7">AHRS</label>
<div class="col-xs-5">
<ui-switch ng-model='AHRS_Enabled' settings-change></ui-switch>
</div>
</div>
</div>
</div>
</div>
<div class="panel-group col-sm-6">
<div class="panel panel-default">
<div class="panel-heading">Diagnostics</div>
<div class="panel-body">
<div class="form-group">
<label class="control-label col-xs-7">Traffic Markings</label>
<div class="col-xs-5">
<ui-switch ng-model='DEBUG' settings-change></ui-switch>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-7">Record Logs</label>
<div class="col-xs-5">
<ui-switch ng-model='ReplayLog' settings-change></ui-switch>
</div>
</div>
</div>
</div>
<div class="panel-group col-sm-6">
<div class="panel panel-default">
<div class="panel-heading">Diagnostics</div>
<div class="panel-body">
<div class="form-group">
<label class="control-label col-xs-7">Traffic Markings</label>
<div class="col-xs-5">
<ui-switch ng-model='DEBUG' settings-change></ui-switch>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-7">Record Logs</label>
<div class="col-xs-5">
<ui-switch ng-model='ReplayLog' settings-change></ui-switch>
</div>
</div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">Configuration</div>
<div class="panel-body">
<div class="form-group">
<label class="control-label col-xs-8">PPM Correction</label>
<form name="ppmForm" ng-submit="updateppm()" novalidate>
<!-- type="number" not supported except on mobile -->
<input class="col-xs-4" type="number_format" required ng-model="PPM" placeholder="integer" />
</form>
</div>
<div class="panel panel-default">
<div class="panel-heading">Configuration</div>
<div class="panel-body">
<div class="form-group">
<label class="control-label col-xs-8">PPM Correction</label>
<form name="ppmForm" ng-submit="updateppm()" novalidate>
<!-- type="number" not supported except on mobile -->
<input class="col-xs-4" type="number_format" required ng-model="PPM" placeholder="integer" />
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-sm-12">
<div class="panel panel-default" xui-set="{'settingsAccordion' : 4}">
<div class="panel-heading">Raw Configuration</div>
<div xui-if="settingsAccordion == 4">
<div class="panel-body">
<p>stratux.conf:</p>
<pre>{{rawSettings}}</pre>
</div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">Raw Configuration</div>
<div class="panel-body">
<p>stratux.conf:</p>
<pre>{{rawSettings}}</pre>
</div>
</div>
</div>
<!--

Wyświetl plik

@ -3,10 +3,11 @@
<p>The current state of you device is shown at th top - <code>Connected</code> in green or <code>Disconected</code>in red.</p>
<p>Depending on the hardware you have installed in your Stratux, you will have status for the following:</p>
<ul>
<li>software defined radio (SDR) dongle tuned to 978Mhz for UAT (universal access transceiver) traffic and weather</li>
<li>software defined radio (SDR) dongle tuned to 1090Mhz for ES (extended squitter) traffic</li>
<li>RY835AI module providing either GPS or GPS+AHRS data</li>
<ul class="list-simple">
<li><strong>SDR</strong> (software defined radio) dongle tuned to 978Mhz for UAT (universal access transceiver) traffic and weather</li>
<li><strong>SDR</strong> (software defined radio) dongle tuned to 1090Mhz for ES (extended squitter) traffic</li>
<li><strong>GPS</strong> the RY835AI module receiving GPS data from satellites</li>
<li><strong>AHRS</strong> the RY835AI module generating attitude data from its pressure sensor, gyroscope, accelerometer, and magnetometer.</li>
</ul>
<p class="text-warning">NOTE: This page only shows devices you have installed and turned on (via the <strong>Settings</strong> page.</p>

Wyświetl plik

@ -0,0 +1,13 @@
<div class="section text-left help-page">
<p>The <strong>Traffic</strong> page provides a list of recent aircraft received. Each time a new aircraft is reported, it is added to the list. Each time a new report is received for an existing aircraft, the list is updated. If a report for an aircraft is not received for 3 minutes (180 seconds), the aircraft is removed from the list.</p>
<p>For each aircraft, the list includes the following details:</p>
<ul class="list-simple">
<li><strong>Flight</strong> - either the aircraft tail number / ATC call sign or the ICAO number. When the ICAO number is used, it is displayed in grey.</li>
<li><strong>Speed</strong> - current reported speed in knots</li>
<li><strong>Altitude</strong> - current reported altitude and climb/decent rate if when not reporting level flight</li>
<li><strong>Heading</strong> - direction of reported flight</li>
<li><strong>Location</strong> - the latitude and longitude reported</li>
<li><strong>Time</strong> - the last time (UTC) a report was received</li>
</ul>
<p class="text-warning">NOTE: When this page becomes active (aka it is selected from the menu) it will display any traffic received up to the last 3 minutes (180 seconds). Older traffic will not appear.</p>
</div>

Wyświetl plik

@ -1,13 +1,52 @@
<div class="list-group text-center">
<div class="list-group-item list-group-item-home">
<h2>ADSB Traffic</h2>
</div>
<div class="list-group-item list-group-item-home">
<div>
<i class="fa fa-plane feature-icon text-primary"></i>
</div>
<div>
this space reserved to display traffic data
</div>
</div>
<div class="col-sm-12">
<div class="panel panel-default">
<div class="panel-heading">
<span class="panel_label">Traffic</span> <span class="label" ng-class="ConnectStyle">{{ConnectState}}</span>
</div>
<div class="panel-body">
<div class="row">
<div class="col-sm-6">
<span class="col-xs-3"><strong>Flight</strong></span>
<span class="col-xs-3 text-right">Speed</span>
<span class="col-xs-3 text-right">Altitude</span><span class="col-xs-1 col-padding-shift-right">&nbsp;</span>
<span class="col-xs-2 text-right">Hdg</span>
</div>
<div class="col-sm-6">
<span class="col-xs-2">&nbsp;</span>
<span class="col-xs-7">Location</span>
<span class="col-xs-3 text-right">Time</span>
</div>
</div>
<div class="row" ng-repeat="aircraft in traffic | orderBy: -age">
<div class="separator"></div>
<div class="col-sm-6">
<span ng-show="aircraft.tail" class="col-xs-3"><strong>{{aircraft.tail}}</strong></span>
<span ng-hide="aircraft.tail" class="col-xs-3 text-muted"><strong>{{aircraft.icao}}</strong></span>
<span class="col-xs-3 text-right">{{aircraft.speed}}KTS</span>
<span class="col-xs-3 text-right">{{aircraft.alt}}</span>
<span class="col-xs-1 small col-padding-shift-right text-muted">
<span ng-show="aircraft.vspeed">(<span ng-show="aircraft.vspeed > 0">+</span>{{aircraft.vspeed}})</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}}&deg;</span>
</div>
<div class="col-sm-6">
<span class="col-xs-2">&nbsp;</span>
<span class="col-xs-7">{{aircraft.lat}} {{aircraft.lon}}</span>
<span class="col-xs-3 text-right">{{aircraft.time}}</span>
</div>
</div>
</div>
</div>
</div>
<!--
<div class="col-sm-12">
<div class="panel panel-default">
<div class="panel-heading">Raw Traffic Data</div>
<div class="panel-body">
<pre>{{rawTraffic}}</pre>
</div>
</div>
</div>
-->