----------------------------------------------------------------------------- -- | -- Module : Plugins.Monitors.SysfsBatt -- Copyright : (c) Sean Lee -- License : BSD-style (see LICENSE) -- -- Maintainer : Sean Lee -- Stability : unstable -- Portability : unportable -- -- A battery monitor for Xmobar using sysfs, not procfs -- ----------------------------------------------------------------------------- module Plugins.Monitors.SysfsBatt where import Control.Monad.Trans (liftIO) import Data.Foldable (foldrM) import Plugins.Monitors.Common import System.Directory (getDirectoryContents) import System.IO (withFile, IOMode (ReadMode), hGetLine) import System.Posix.Files (fileExist) import Text.Printf (printf) sysfsBattConfig :: IO MConfig sysfsBattConfig = mkMConfig "SysfsBatt: " ["left"] sysfsPath :: FilePath sysfsPath = "/sys/class/power_supply/" runSysfsBatt :: [String] -> Monitor String runSysfsBatt _ = do sysfsPathExists <- liftIO $ fileExist sysfsPath if sysfsPathExists then do powerUnits <- liftIO $ getPowerUnits capacity <- liftIO $ getCapacity powerUnits state <- liftIO $ getState powerUnits if capacity == 0 then return "N/A" else showStateInPercentage capacity state else return "N/A" getPowerUnits :: IO [FilePath] getPowerUnits = getDirectoryContents sysfsPath >>= return.filter (("BAT" ==) . (take 3)) getCapacity :: [FilePath] -> IO Float getCapacity = foldrM (\ p c -> do let path = sysfsPath ++ p ++ "/charge_full" pathExists <- fileExist path if pathExists then withFile path ReadMode hGetLine >>= return . (+ c) . read else return c) 0 getState :: [FilePath] -> IO Float getState = foldrM (\ p c -> do let path = sysfsPath ++ p ++ "/charge_now" pathExists <- fileExist path if pathExists then withFile path ReadMode hGetLine >>= return . (+ c) . read else return c) 0 showStateInPercentage :: Float -> Float -> Monitor String showStateInPercentage c s = do let stateInPercentage = s / c * 100 if stateInPercentage >= 100 then return "Full" else showWithColors (printf "%.2f%%") stateInPercentage