package uk.org.floop.msc.comet import scala.collection.mutable.HashMap import net.liftweb.http._ import net.liftweb.http.js.JsCmds._ import uk.org.floop.msc.rrd._ import uk.org.floop.msc.wview.Forecast class WeatherActor(info: CometActorInitInfo) extends CometActor(info) { def defaultPrefix = "weather" def COMPASS_ROSE = List("N", "NNE", "NE", "ENE", "E", "ESE", "SE", "SSE", "S", "SSW", "SW", "WSW", "W", "WNW", "NW", "NNW") var currentWeather: List[Pair[String, Any]] = Nil val currentWeatherMap = new HashMap[String, Any]() def direction(d: Option[Any]) = d match { case Some(angle: Short) => COMPASS_ROSE((angle / 22.5 + 0.5).toInt % 16) case None => "unknown" } def knots(s: Option[Any]): String = s match { case Some(mph: Short) => val k = (mph / 1.15077945 + 0.5).toInt if (k == 1) { "1 knot" } else { k + " knots" } case None => "unknown" } def temp(t: Option[Any]): String = t match { case Some(f: Float) => val c = (f - 32) * 5 / 9; c.toDouble.formatted("%.1f") case None => "unknown" } def pressure(p: Option[Any]): String = p match { case Some(inchesMercury: Float) => val millibar = (inchesMercury * 33.86389).toInt millibar + " mb" case None => "unknown" } def humidity(h: Option[Any]): String = h match { case Some(p: Short) => p + "%" case None => "unknown" } def rain(r: Option[Any]): String = r match { case Some(inHr: Float) => (inHr * 25.4).toInt + " mm/hr" case None => "unknown" } def forecast(f: Option[Any]): String = f match { case Some(rule: Short) => Forecast.getRule(rule) case None => "unknown" } def render: RenderOut = { new RenderOut(bind("view" -> <table> <tr><td>Wind Direction:</td><td>{direction(currentWeatherMap.get("windDir"))}</td></tr> <tr><td>Wind Speed:</td><td>{knots(currentWeatherMap.get("windSpeed"))}</td></tr> <tr><td>Temperature:</td><td>{temp(currentWeatherMap.get("outTemp"))} °C</td></tr> <tr><td>Air Pressure:</td><td>{pressure(currentWeatherMap.get("barometer"))}</td></tr> <tr><td>Relative Humidity:</td><td>{humidity(currentWeatherMap.get("outHumidity"))}</td></tr> <tr><td>Rain Rate:</td><td>{rain(currentWeatherMap.get("rainRate"))}</td></tr> <tr><td>Forecast:</td><td>{forecast(currentWeatherMap.get("forecastRule"))}</td></tr> </table>), currentWeatherMap.get("windDir") match { case Some(angle) => Run("drawWind(" + angle + ")") case None => Noop } ) } override def localSetup { DataStore !? AddWeatherListener(this) match { case CurrentWeather(w) => currentWeather = w w.foreach(pair => currentWeatherMap(pair._1) = pair._2) } } override def localShutdown { DataStore ! RemoveWeatherListener(this) } override def lowPriority: PartialFunction[Any, Unit] = { case CurrentWeather(w) => val diff = w -- currentWeather diff.foreach(pair => currentWeatherMap(pair._1) = pair._2) currentWeather = w reRender(false) } }