{-# LANGUAGE TemplateHaskell, OverloadedStrings #-} import Prelude hiding (readFile) import System.Directory import System.FilePath import Control.Monad (forM, join) import System.Posix.Files import Data.List (isPrefixOf, isInfixOf) import System.Exit import Language.Haskell.TH.Syntax (liftString, runIO) import System.Environment (getEnv) import Control.Monad.IO.Class (liftIO) import Data.Maybe (catMaybes) import Control.Exception import Data.Text (unpack) import Data.Text.IO (readFile) -- | Traverse from 'top' directory and return all the files by -- filtering with 'include' predicate. traverseDir :: FilePath -> (FilePath -> Bool) -> IO [FilePath] traverseDir top include = do ds <- getDirectoryContents top paths <- forM (filter include ds) $ \d -> do let path = top d s <- getFileStatus path if isDirectory s then traverseDir path include else return [path] return $ concat paths -- | Get temperatures from hardware sensors in getTemps :: IO [Int] getTemps = do hwmons <- traverseDir "/sys/class/hwmon" ( \name -> ("hwmon" `isPrefixOf` name) || ("temp" `isInfixOf` name) && ("input" `isInfixOf` name) ) fmap (round . (/1000) . read . unpack) <$> traverse (handle (\e -> do pure (e :: IOException); pure "0") . readFile) hwmons -- | Get a symbol corresponding to the temperature getSymbol :: Integral n => n -> String getSymbol t | t < 50 = "\57868" --  | t < 80 = "\57866" --  | otherwise = "\57867" --  icon :: String -> String icon s = "" ++ s ++ "" main :: IO () main = do maxTemp <- maximum <$> getTemps putStrLn $ (getSymbol <> show) maxTemp <> "°" exitWith $ if maxTemp < 80 then ExitSuccess else ExitFailure 33