diff options
Diffstat (limited to 'Monitors')
| -rw-r--r-- | Monitors/Weather.hs | 205 | 
1 files changed, 122 insertions, 83 deletions
| diff --git a/Monitors/Weather.hs b/Monitors/Weather.hs index 994227e..d643bb0 100644 --- a/Monitors/Weather.hs +++ b/Monitors/Weather.hs @@ -1,95 +1,123 @@ +----------------------------------------------------------------------------- +-- | +-- Module      :  Monitors.Weather +-- Copyright   :  (c) Andrea Rossato +-- License     :  BSD-style (see LICENSE) +--  +-- Maintainer  :  Andrea Rossato <andrea.rossato@unibz.it> +-- Stability   :  unstable +-- Portability :  unportable +-- +-- A weather monitor for XMobar +-- +----------------------------------------------------------------------------- +  module Main where -import Text.ParserCombinators.Parsec -import System.Environment +import Monitors.Common + +import Data.IORef  import System.Process  import System.Exit  import System.IO +import Text.ParserCombinators.Parsec -data Config =  -    Config { weatherNormal :: Integer -           , weatherNormalColor :: String -           , weatherCritical :: Integer -           , weatherCriticalColor :: String -           } - -defaultConfig :: Config -defaultConfig =  -    Config { weatherNormal = 0 -           , weatherNormalColor = "#00FF00"  -           , weatherCritical = 50 -           , weatherCriticalColor = "#FF0000"  -           } - -config :: Config -config = defaultConfig - - -data WeatherInfo = Fail String -                 | WI { station :: String -                      , time :: String -                      , temperature :: Int -                      , humidity :: Int -                      }  -                    -instance Show WeatherInfo where -    show (Fail _) = "N/A" -    show (WI st t temp rh) = -        st ++ ": " ++ (formatWeather temp) ++ "C, rh " ++ formatWeather rh ++ -        "% (" ++ t ++ ")" - -parseData :: Parser WeatherInfo -parseData =  -    do { st <- manyTill anyChar $ char '(' -       ; pNL -       ; manyTill anyChar $ char '/' -       ; space -       ; t <- manyTill anyChar newline -       ; manyTill pNL (string "Temperature") -       ; temp <- pTemp -       ; manyTill pNL (string "Relative Humidity") -       ; rh <- pRh -       ; manyTill pNL eof -       ; return $ WI st t temp rh -       }  - -pTemp :: Parser Int +monitorConfig :: IO MConfig +monitorConfig =  +    do lc <- newIORef "#BFBFBF" +       l <- newIORef 15 +       nc <- newIORef "#00FF00" +       h <- newIORef 27 +       hc <- newIORef "#FF0000" +       t <- newIORef "<station>: <tempC>C, rh <rh>% (<hour>)" +       p <- newIORef package +       u <- newIORef "station ID" +       a <- newIORef [] +       e <- newIORef ["station" +                     , "stationState" +                     , "year" +                     , "month" +                     , "day" +                     , "hour" +                     , "wind" +                     , "visibility" +                     , "skyCondition" +                     , "tempC" +                     , "tempF" +                     , "dewPoint" +                     , "rh" +                     ,"pressure" +                     ] +       return $ MC nc l lc h hc t p u a e + + +data WeatherInfo =  +    WI { stationPlace :: String +       , stationState :: String +       , year :: String +       , month :: String +       , day :: String +       , hour :: String +       , wind :: String +       , visibility :: String +       , skyCondition :: String +       , temperature :: Float +       , dewPoint :: String +       , humidity :: Float +       , pressure :: String +       } deriving (Show) + + + +pTime :: Parser (String, String, String, String) +pTime = do y <- getNumbersAsString +           char '.' +           m <- getNumbersAsString +           char '.' +           d <- getNumbersAsString +           char ' ' +           (h:hh:mi:mimi) <- getNumbersAsString +           char ' ' +           return (y, m, d ,([h]++[hh]++":"++[mi]++mimi)) + +pTemp :: Parser Float  pTemp = do string ": "             manyTill anyChar $ char '('             s <- manyTill digit $ (char ' ' <|> char '.') -           pNL +           skipRestOfLine             return $read s -pRh :: Parser Int +pRh :: Parser Float  pRh = do string ": "           s <- manyTill digit $ (char '%' <|> char '.') -         return $read s - -pNL :: Parser Char -pNL = do many $ noneOf "\n\r" -         newline - +         return $ read s -runP :: Parser WeatherInfo -> String -> IO WeatherInfo -runP p i = -    do case (parse p "" i) of -         Left err -> return $ Fail $ show err -         Right x  -> return x - -formatWeather :: Int -> String -formatWeather d | d > fromInteger (weatherCritical config) = setColor str weatherCriticalColor  -                | d > fromInteger (weatherNormal config) = setColor str weatherNormalColor -                | otherwise = str -                where str = show d - - -setColor :: String -> (Config -> String) -> String -setColor str ty = -    "<fc=" ++ ty config ++ ">" ++ -    str ++ "</fc>" +parseData :: Parser [WeatherInfo] +parseData =  +    do st <- getAllBut ","  +       space +       ss <- getAllBut "(" +       skipRestOfLine >> getAllBut "/" +       (y,m,d,h) <- pTime +       skipRestOfLine >> string "Wind: " +       w <- manyTill anyChar $ newline  +       manyTill skipRestOfLine $ string "Visibility: " +       v <- manyTill anyChar $ newline +       manyTill skipRestOfLine $ string "Sky conditions: " +       sk <- manyTill anyChar $ newline +       manyTill skipRestOfLine $ string "Temperature" +       temp <- pTemp +       manyTill skipRestOfLine $ string "Dew Point: " +       dp <- manyTill anyChar $ newline +       manyTill skipRestOfLine $ string "Relative Humidity" +       rh <- pRh +       manyTill skipRestOfLine $ string "Pressure (altimeter): " +       p <- manyTill anyChar $ newline +       manyTill skipRestOfLine eof +       return $ [WI st ss y m d h w v sk temp dp rh p]  defUrl :: String  defUrl = "http://weather.noaa.gov/pub/data/observations/metar/decoded/" @@ -107,13 +135,24 @@ getData url=               _ -> do closeHandles                       return "Could not retrieve data" +formatWeather :: [WeatherInfo] -> Monitor String +formatWeather [(WI st ss y m d h w v sk temp dp r p)] = +    do cel <- showWithColors show temp +       far <- showWithColors (show . takeDigits 1) (((9 / 5) * temp) + 32) +       rh <- showWithColors show r +       parseTemplate [st, ss, y, m, d, h, w, v, sk, cel, far, dp, rh , p ] +formatWeather _ = return "N/A" + +runWeather :: [String] -> Monitor String +runWeather str = +    do d <- io $ getData $ head str +       i <- io $ runP parseData d +       formatWeather i + +package :: String +package = "xmb-weather" +  main :: IO ()  main = -    do args <- getArgs -       str <- if length args /= 1 -                 then error $ "No Station ID specified.\nUsage: weather STATION_ID" ++ -                      "\nExample: xmb-weather LIPB" -                 else getData (args !! 0) -       i <- runP parseData str  -       putStrLn $ show i -        +    do let af = return "No station ID specified" +       runMonitor monitorConfig af runWeather | 
