kopia lustrzana https://github.com/cyoung/stratux
				
				
				
			Merge pull request #96 from cyoung/uat_towers_status
created new towers details page and towers status on main pagepull/104/head
						commit
						d0d466896e
					
				|  | @ -101,6 +101,15 @@ func handleStatusWS(conn *websocket.Conn) { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| // AJAX call - /getStatus. Responds with current global status
 | ||||
| // a webservice call for the same data available on the websocket but when only a single update is needed
 | ||||
| func handleStatusRequest(w http.ResponseWriter, r *http.Request) { | ||||
| 	w.Header().Set("Access-Control-Allow-Origin", "*") | ||||
| 	w.Header().Set("Content-Type", "application/json") | ||||
| 	statusJSON, _ := json.Marshal(&globalStatus) | ||||
| 	fmt.Fprintf(w, "%s\n", statusJSON) | ||||
| } | ||||
| 
 | ||||
| // AJAX call - /getSituation. Responds with current situation (lat/lon/gdspeed/track/pitch/roll/heading/etc.)
 | ||||
| func handleSituationRequest(w http.ResponseWriter, r *http.Request) { | ||||
| 	w.Header().Set("Access-Control-Allow-Origin", "*") | ||||
|  | @ -114,6 +123,8 @@ func handleTowersRequest(w http.ResponseWriter, r *http.Request) { | |||
| 	w.Header().Set("Access-Control-Allow-Origin", "*") | ||||
| 	w.Header().Set("Content-Type", "application/json") | ||||
| 	towersJSON, _ := json.Marshal(&ADSBTowers) | ||||
| 	// for testing purposes, we can return a fixed reply
 | ||||
| 	// towersJSON = []byte(`{"(38.490880,-76.135554)":{"Lat":38.49087953567505,"Lng":-76.13555431365967,"Signal_strength_last_minute":100,"Signal_strength_max":67,"Messages_last_minute":1,"Messages_total":1059},"(38.978698,-76.309276)":{"Lat":38.97869825363159,"Lng":-76.30927562713623,"Signal_strength_last_minute":495,"Signal_strength_max":32,"Messages_last_minute":45,"Messages_total":83},"(39.179285,-76.668413)":{"Lat":39.17928457260132,"Lng":-76.66841268539429,"Signal_strength_last_minute":50,"Signal_strength_max":24,"Messages_last_minute":1,"Messages_total":16},"(39.666309,-74.315300)":{"Lat":39.66630935668945,"Lng":-74.31529998779297,"Signal_strength_last_minute":9884,"Signal_strength_max":35,"Messages_last_minute":4,"Messages_total":134}}`)
 | ||||
| 	fmt.Fprintf(w, "%s\n", towersJSON) | ||||
| } | ||||
| 
 | ||||
|  | @ -227,6 +238,7 @@ func managementInterface() { | |||
| 			s.ServeHTTP(w, req) | ||||
| 		}) | ||||
| 
 | ||||
| 	http.HandleFunc("/getStatus", handleStatusRequest) | ||||
| 	http.HandleFunc("/getSituation", handleSituationRequest) | ||||
| 	http.HandleFunc("/getTowers", handleTowersRequest) | ||||
| 	http.HandleFunc("/getSettings", handleSettingsGetRequest) | ||||
|  |  | |||
|  | @ -58,6 +58,9 @@ | |||
| 	<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/towers.js"></script> | ||||
| 	--> | ||||
| 	<script src="plates/js/traffic.js"></script> | ||||
| 	<script src="plates/js/weather.js"></script> | ||||
| 	<script src="js/j3di-all.min.js"></script> | ||||
|  | @ -77,9 +80,9 @@ | |||
| 					<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="#/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="#/towers"><i class="fa fa-signal"></i>    Towers   <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> | ||||
|  |  | |||
|  | @ -3,6 +3,8 @@ var URL_HOST_BASE 		= window.location.hostname; | |||
| var URL_SETTINGS_GET 	= "http://"	+ URL_HOST_BASE + "/getSettings"; | ||||
| var URL_SETTINGS_SET 	= "http://"	+ URL_HOST_BASE + "/setSettings"; | ||||
| var URL_GPS_GET 		= "http://"	+ URL_HOST_BASE + "/getSituation"; | ||||
| var URL_TOWERS_GET 		= "http://"	+ URL_HOST_BASE + "/getTowers" | ||||
| var URL_STATUS_GET 		= "http://"	+ URL_HOST_BASE + "/getStatus" | ||||
| var URL_STATUS_WS 		= "ws://"	+ URL_HOST_BASE + "/status" | ||||
| var URL_TRAFFIC_WS 		= "ws://"	+ URL_HOST_BASE + "/traffic"; | ||||
| var URL_WEATHER_WS 		= "ws://"	+ URL_HOST_BASE + "/weather"; | ||||
|  | @ -21,6 +23,12 @@ app.config(function ($stateProvider, $urlRouterProvider) { | |||
| 			controller: 'StatusCtrl', | ||||
| 			reloadOnSearch: false | ||||
| 		}) | ||||
| //		.state('towers', {
 | ||||
| //			url: '/towers',
 | ||||
| //			templateUrl: 'plates/towers.html',
 | ||||
| //			controller: 'TowersCtrl',
 | ||||
| //			reloadOnSearch: false
 | ||||
| //		})
 | ||||
| 		.state('weather', { | ||||
| 			url: '/weather', | ||||
| 			templateUrl: 'plates/weather.html', | ||||
|  |  | |||
|  | @ -1,8 +1,8 @@ | |||
| angular.module('appControllers').controller('StatusCtrl', StatusCtrl); // get the main module contollers set
 | ||||
| StatusCtrl.$inject = ['$rootScope', '$scope', '$state', '$http']; // Inject my dependencies
 | ||||
| StatusCtrl.$inject = ['$rootScope', '$scope', '$state', '$http', '$interval']; // Inject my dependencies
 | ||||
| 
 | ||||
| // create our controller function with all necessary logic
 | ||||
| function StatusCtrl($rootScope, $scope, $state, $http) { | ||||
| function StatusCtrl($rootScope, $scope, $state, $http, $interval) { | ||||
| 
 | ||||
| 	$scope.$parent.helppage = 'plates/status-help.html'; | ||||
| 
 | ||||
|  | @ -91,6 +91,31 @@ function StatusCtrl($rootScope, $scope, $state, $http) { | |||
| 		}); | ||||
| 	}; | ||||
| 
 | ||||
| 	function getTowers() { | ||||
| 		// Simple GET request example (note: responce is asynchronous)
 | ||||
| 		$http.get(URL_TOWERS_GET). | ||||
| 		then(function (response) { | ||||
| 			var towers = angular.fromJson(response.data); | ||||
| 			var cnt = 0; | ||||
| 			for (var key in towers) { | ||||
| 				if (towers[key].Messages_last_minute > 0) { | ||||
| 					cnt++; | ||||
| 				} | ||||
| 			} | ||||
| 			$scope.UAT_Towers = cnt; | ||||
| 			// $scope.$apply();
 | ||||
| 		}, function (response) { | ||||
| 			$scope.raw_data = "error getting tower data"; | ||||
| 		}); | ||||
| 	}; | ||||
| 
 | ||||
| 	// periodically get the tower list
 | ||||
| 	var updateTowers = $interval(function () { | ||||
| 		// refresh tower count once each 5 seconds (aka polling)
 | ||||
| 		getTowers(); | ||||
| 	}, (5 * 1000), 0, false); | ||||
| 
 | ||||
| 
 | ||||
| 	$state.get('home').onEnter = function () { | ||||
| 		// everything gets handled correctly by the controller
 | ||||
| 	}; | ||||
|  | @ -99,10 +124,10 @@ function StatusCtrl($rootScope, $scope, $state, $http) { | |||
| 			$scope.socket.close(); | ||||
| 			$scope.socket = null; | ||||
| 		} | ||||
| 		$interval.cancel(updateTowers); | ||||
| 	}; | ||||
| 
 | ||||
| 
 | ||||
| 	// Status Controller tasks
 | ||||
| 	setHardwareVisibility(); | ||||
| 	connect($scope); // connect - opens a socket and listens for messages
 | ||||
| }; | ||||
| }; | ||||
|  | @ -0,0 +1,70 @@ | |||
| angular.module('appControllers').controller('TowersCtrl', TowersCtrl); // get the main module contollers set
 | ||||
| TowersCtrl.$inject = ['$rootScope', '$scope', '$state', '$http', '$interval']; // Inject my dependencies
 | ||||
| 
 | ||||
| // create our controller function with all necessary logic
 | ||||
| function TowersCtrl($rootScope, $scope, $state, $http, $interval) { | ||||
| 
 | ||||
| 	$scope.$parent.helppage = 'plates/towers-help.html'; | ||||
| 	$scope.data_list = []; | ||||
| 
 | ||||
| 	function dmsString(val) { | ||||
| 		return [0 | val, | ||||
| 				'° ', | ||||
| 				0 | (val < 0 ? val = -val : val) % 1 * 60, | ||||
| 				"' ", | ||||
| 				0 | val * 60 % 1 * 60, | ||||
| 				'"'].join(''); | ||||
| 	} | ||||
| 
 | ||||
| 	function setTower(obj, new_tower) { | ||||
| 		new_tower.lat = dmsString(obj.Lat); | ||||
| 		new_tower.lon = dmsString(obj.Lng); | ||||
| 		new_tower.signal = obj.Signal_strength_last_minute; | ||||
| 		// Signal_strength_max         int
 | ||||
| 		// Messages_last_minute        uint64
 | ||||
| 		new_tower.messages = obj.Messages_total; | ||||
| 	} | ||||
| 
 | ||||
| 	function loadTowers(data) { | ||||
| 		if (($scope === undefined) || ($scope === null)) | ||||
| 			return; // we are getting called once after clicking away from the status page
 | ||||
| 
 | ||||
| 		var towers = data; // it seems the json was already converted to an object list by teh http request
 | ||||
| 		$scope.raw_data = angular.toJson(data, true); | ||||
| 
 | ||||
| 		$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
 | ||||
| 		for (var key in towers) { | ||||
| 			if (towers[key].Messages_last_minute > 0) { | ||||
| 				var new_tower = {}; | ||||
| 				setTower(towers[key], new_tower); | ||||
| 				$scope.data_list.push(new_tower); // add to start of array
 | ||||
| 			} | ||||
| 		} | ||||
| 		// $scope.$apply();
 | ||||
| 	} | ||||
| 
 | ||||
| 	function getTowers() { | ||||
| 		// Simple GET request example (note: responce is asynchronous)
 | ||||
| 		$http.get(URL_TOWERS_GET). | ||||
| 		then(function (response) { | ||||
| 			loadTowers(response.data); | ||||
| 		}, function (response) { | ||||
| 			$scope.raw_data = "error getting tower data"; | ||||
| 		}); | ||||
| 	}; | ||||
| 
 | ||||
| 	var updateTowers = $interval(function () { | ||||
| 		// refresh tower list once every 5 seconds (aka polling)
 | ||||
| 		getTowers(); | ||||
| 	}, (5 * 1000), 0, false); | ||||
| 
 | ||||
| 	$state.get('towers').onEnter = function () { | ||||
| 		// everything gets handled correctly by the controller
 | ||||
| 	}; | ||||
| 
 | ||||
| 	$state.get('towers').onExit = function () { | ||||
| 		// stop any interval functions
 | ||||
| 		$interval.cancel(updateTowers); | ||||
| 	}; | ||||
| }; | ||||
|  | @ -23,7 +23,7 @@ function TrafficCtrl($rootScope, $scope, $state, $http, $interval) { | |||
| 
 | ||||
| 	function dmsString(val) { | ||||
| 		return [0 | val, | ||||
| 				'd ', | ||||
| 				'° ', | ||||
| 				0 | (val < 0 ? val = -val : val) % 1 * 60, | ||||
| 				"' ", | ||||
| 				0 | val * 60 % 1 * 60, | ||||
|  |  | |||
|  | @ -49,9 +49,13 @@ | |||
|                     <div>{{product_rows}}</div> | ||||
|                 </div> | ||||
| --> | ||||
| 				<div class="row" ng-class="{ 'section_invisible': (!visible_gps && !visible_ahrs)}"> | ||||
| 				<div class="row" ng-class="{ 'section_invisible': (!visible_gps && !visible_ahrs && !visible_uat)}"> | ||||
| 					<span class="col-xs-1"> </span> | ||||
| 				</div> | ||||
| 				<div class="row" ng-class="{'section_invisible': !visible_uat}"> | ||||
| 					<label class="col-xs-6">UAT Towers:</label> | ||||
| 					<span class="col-xs-6">{{UAT_Towers}}</span> | ||||
| 				</div> | ||||
| 				<div class="row" ng-class="{'section_invisible': !visible_gps}"> | ||||
| 					<label class="col-xs-6">GPS satellites:</label> | ||||
| 					<span class="col-xs-6">{{GPS_satellites_locked}}</span> | ||||
|  |  | |||
|  | @ -0,0 +1,4 @@ | |||
| <div class="section text-left help-page"> | ||||
| 	<p>The <strong>Towers</strong> page provides a list of recent towers which have been received. Each time a new tower is received, it is added to the list. Each time new messages are received from an existing tower, the list is updated. If no messages are received from a tower for 5 minutes, the tower is removed from the list.</p> | ||||
| 	<p>more details will be added here eventually :-)</p> | ||||
| </div> | ||||
|  | @ -0,0 +1,33 @@ | |||
| <div class="col-sm-12"> | ||||
| 	<div class="panel panel-default"> | ||||
| 		<div class="panel-heading"> | ||||
| 			<span class="panel_label">Towers</span> | ||||
| 			<span ng-show="ConnectState == 'Receiving'" class="label label-success">{{ConnectState}}</span> | ||||
| 			<span ng-hide="ConnectState == 'Receiving'" class="label label-danger">{{ConnectState}}</span> | ||||
| 		</div> | ||||
| 		<div class="panel-body towers-page"> | ||||
| 			<div class="row"> | ||||
| 				<span class="col-xs-6"><strong>Tower</strong></span> | ||||
| 				<span class="col-xs-3 text-right">Signal</span> | ||||
| 				<span class="col-xs-3 text-right">Msgs</span> | ||||
| 			</div> | ||||
| 
 | ||||
| 			<div class="row" ng-repeat="tower in data_list | orderBy: messages"> | ||||
| 				<div class="separator"></div> | ||||
| 				<span class="col-xs-6">{{tower.lat}} {{tower.lon}}</span> | ||||
| 				<span class="col-xs-3 text-right">{{tower.signal}}</span> | ||||
| 				<span class="col-xs-3 text-right">{{tower.messages}}</span> | ||||
| 			</div> | ||||
| 		</div> | ||||
| 	</div> | ||||
| </div> | ||||
| <!-- | ||||
| <div class="col-sm-12"> | ||||
| 	<div class="panel panel-default"> | ||||
| 		<div class="panel-heading">Raw Tower Data</div> | ||||
| 		<div class="panel-body"> | ||||
| 			<pre>{{raw_data}}</pre> | ||||
| 		</div> | ||||
| 	</div> | ||||
| </div> | ||||
| --> | ||||
		Ładowanie…
	
		Reference in New Issue
	
	 cyoung
						cyoung