diff options
Diffstat (limited to 'vfd-backend/app')
-rw-r--r-- | vfd-backend/app/controllers/Application.scala | 31 | ||||
-rw-r--r-- | vfd-backend/app/plugins/UavPlugin.scala | 44 | ||||
-rw-r--r-- | vfd-backend/app/views/index.scala.html | 47 | ||||
-rw-r--r-- | vfd-backend/app/views/main.scala.html | 63 | ||||
-rw-r--r-- | vfd-backend/app/views/panels/eicas.scala.html | 35 | ||||
-rw-r--r-- | vfd-backend/app/views/panels/pfd.scala.html | 31 |
6 files changed, 251 insertions, 0 deletions
diff --git a/vfd-backend/app/controllers/Application.scala b/vfd-backend/app/controllers/Application.scala new file mode 100644 index 0000000..5a473b4 --- /dev/null +++ b/vfd-backend/app/controllers/Application.scala @@ -0,0 +1,31 @@ +package controllers + +import play.api._ +import play.api.mvc._ +import play.api.Play.current +import play.api.mvc.WebSocket.FrameFormatter + +import play.api.libs.functional.syntax._ +import play.api.libs.json._ + +import vfd.uav.DataFrame +import plugins.UavPlugin + + +object Application extends Controller { + + def use[A <: Plugin](implicit app: Application, m: Manifest[A]) = { + app.plugin[A].getOrElse(throw new RuntimeException(m.runtimeClass.toString + " plugin should be available at this point")) + } + + def index() = Action { + Ok(views.html.index()) + } + + implicit val dataFrameFormat = Json.format[DataFrame] + implicit val dataFrameFormatter = FrameFormatter.jsonFrame[DataFrame] + + def socket = WebSocket.acceptWithActor[String, DataFrame] { request => + out => use[UavPlugin].register(out) + } +}
\ No newline at end of file diff --git a/vfd-backend/app/plugins/UavPlugin.scala b/vfd-backend/app/plugins/UavPlugin.scala new file mode 100644 index 0000000..a94ed9d --- /dev/null +++ b/vfd-backend/app/plugins/UavPlugin.scala @@ -0,0 +1,44 @@ +package plugins + +import akka.actor._ +import play.api._ +import play.api.libs.concurrent.Akka +import vfd.uav._ + +class UavPlugin(app: Application) extends Plugin { + + object conf { + private val config = app.configuration.getConfig("uav") + val connection = config.flatMap(_.getString("connection")).getOrElse("mock") + val port = config.flatMap(_.getString("port")).getOrElse("/dev/ttyACM0") + val baud = config.flatMap(_.getInt("baud")).getOrElse(9600) + } + + lazy val connection: ActorRef = { + val props = conf.connection match { + case "mock" => Connection.dummy + case "fcu" => Connection.fcu(conf.port, conf.baud) + case _ => throw new RuntimeException("Unknown connection type.") + } + Akka.system(app).actorOf(props, name = "uav") + } + + def register(out: ActorRef): Props = Repeater(out, connection) + +} + +class Repeater(out: ActorRef, connection: ActorRef) extends Actor { + + override def preStart = { + connection ! Connection.Register + } + + def receive = { + case Connection.NewDataFrame(df) => out ! df + } + + } + +object Repeater { + def apply(out: ActorRef, connection: ActorRef) = Props(classOf[Repeater], out, connection) +}
\ No newline at end of file diff --git a/vfd-backend/app/views/index.scala.html b/vfd-backend/app/views/index.scala.html new file mode 100644 index 0000000..654c2a1 --- /dev/null +++ b/vfd-backend/app/views/index.scala.html @@ -0,0 +1,47 @@ +@main("Main"){ + + <div class="row"> + <div class="col-lg-2"> + <div style="width: 100%; height: 450px; background-color: #000000; display: table;"> + <div style="display: table-cell; text-align: center; vertical-align: middle;">no feed</div> + </div> + </div> + <div class="col-lg-6"> + @panels.pfd() + <!-- <div style="width: 100%; height: 450px; background-color: #000000; display: table;"> + <div style="display: table-cell; text-align: center; vertical-align: middle;">no feed</div> + </div> --> + </div> + <div class="col-lg-4"> + station + <ul> + <li>server link</li> + <li>uav link</li> + </ul> + </div> + </div> + <div class="row"> + <div class="col-lg-4"> + uav + </div> + <div class="col-lg-4"> + + </div> + <div class="col-lg-4"> + @panels.eicas() + </div> + </div> + + + + + + <script type="text/javascript"> + + window.onload = function () { + var frontend = new Frontend('#attitude', '#heading', '#altitude') + frontend.main() + } + </script> +} + diff --git a/vfd-backend/app/views/main.scala.html b/vfd-backend/app/views/main.scala.html new file mode 100644 index 0000000..db894d2 --- /dev/null +++ b/vfd-backend/app/views/main.scala.html @@ -0,0 +1,63 @@ +@(title: String)(content: Html) + +<!DOCTYPE html> + +<html lang="en"> +<head> + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <title>VFD - @title</title> + + <link rel="shortcut icon" href="@routes.Assets.at("images/logo.svg")"> + <link rel="stylesheet" media="screen" href="@routes.Assets.at("lib/bootstrap/css/bootstrap.css")"> + <link rel="stylesheet" media="screen" href="@routes.Assets.at("stylesheets/main.css")"> +</head> +<body> + <header> + <nav class="navbar navbar-inverse navbar-static-top" role="navigation"> + <div class="container-fluid"> + <!-- Brand and toggle get grouped for better mobile display --> + <div class="navbar-header"> + <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navbar-main-collapse"> + <span class="sr-only">Toggle navigation</span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </button> + <a class="navbar-brand" href="@routes.Application.index"> + <!-- <img style="max-height: 100%;" src="@routes.Assets.at("images/logo-invert.svg")" alt="logo"> --> + Virtual Flight Deck + </a> + </div> + + <!-- Collect the nav links, forms, and other content for toggling --> + <div class="collapse navbar-collapse" id="navbar-main-collapse"> + <ul class="nav navbar-nav"> + </ul> + <ul class="nav navbar-nav navbar-right"> + <li class="dropdown"> + <a href="#" class="dropdown-toggle" data-toggle="dropdown">options<b class="caret"></b></a> + <ul class="dropdown-menu"> + <li> + <form method="POST" action=""> + <button type="submit" style="width: 100%;" class="btn btn-default">Sign Out</button> + </form> + </li> + </ul> + </li> + </ul> + </div><!-- /.navbar-collapse --> + </div><!-- /.container-fluid --> + </nav> + </header> + + <div class="container-fluid"> + @content + </div> + + <script type="text/javascript" src="@routes.Assets.at("lib/vfd-frontend-fastopt.js")"></script> + <script type="text/javascript" src="@routes.Assets.at("lib/jquery/jquery.js")"></script> + <script type="text/javascript" src="@routes.Assets.at("lib/bootstrap/js/bootstrap.min.js")"></script> +</body> +</html>
\ No newline at end of file diff --git a/vfd-backend/app/views/panels/eicas.scala.html b/vfd-backend/app/views/panels/eicas.scala.html new file mode 100644 index 0000000..211adba --- /dev/null +++ b/vfd-backend/app/views/panels/eicas.scala.html @@ -0,0 +1,35 @@ +@() + +@led(condition: String) = @{ + "images/leds/" + (condition match { + case "error" => "red-on.svg" + case "warn" => "yellow-on.svg" + case "good" => "green-on.svg" + case "unknown" => "none.svg" + case _ => "a" + }) +} + +@instrument(name: String, condition: String, status: String) = { + <tr> + <td>@name</td> + <td> + <img src="@routes.Assets.at(led(condition))" alt="@condition" width="15px"> + </td> + <td> + <span class="status @condition"> + @status + </span> + </td> + </tr> +} + + +<!-- <table class="control-table"> + @instrument("engine1", "unknown", "0 rpm") + @instrument("engine2", "unknown", "1000 rpm") + @instrument("engine3", "unknown", "2080 rpm") + @instrument("engine4", "unknown", "1000 rpm") + @instrument("battery", "unknown", "3000Wh") + @instrument("power", "unknown", "2000W") +</table -->
\ No newline at end of file diff --git a/vfd-backend/app/views/panels/pfd.scala.html b/vfd-backend/app/views/panels/pfd.scala.html new file mode 100644 index 0000000..9c89d6a --- /dev/null +++ b/vfd-backend/app/views/panels/pfd.scala.html @@ -0,0 +1,31 @@ +@() + +@instrument(name: String) = { + @defining("images/instruments/" + name + ".svg") { location => + <object id="@name" type="image/svg+xml" data="@routes.Assets.at(location)" width="100%">Error loading image.</object> + } +} + + +<div class="row"> + <div class="col-lg-4"> + + </div> + <div class="col-lg-4"> + @instrument("attitude") + </div> + <div class="col-lg-4"> + @instrument("altitude") + </div> +</div> +<div class="row"> + <div class="col-lg-4"> + + </div> + <div class="col-lg-4"> + @instrument("heading") + </div> + <div class="col-lg-4"> + @instrument("distance") + </div> +</div>
\ No newline at end of file |