1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
|
-----------------------------------------------------------------------------
-- |
-- Module : Plugins.Monitors.CoreTemp
-- Copyright : (c) 2019 Felix Springer
-- (c) Juraj Hercek
-- License : BSD-style (see LICENSE)
--
-- Maintainer : Felix Springer <felixspringer149@gmail.com>
-- Stability : unstable
-- Portability : unportable
--
-- A core temperature monitor for Xmobar
--
-----------------------------------------------------------------------------
module Xmobar.Plugins.Monitors.CoreTemp (startCoreTemp) where
import Xmobar.Plugins.Monitors.Common
import System.Console.GetOpt
data CTOpts = CTOpts { loadIconPattern :: Maybe IconPattern
, mintemp :: Float
, maxtemp :: Float
}
defaultOpts :: CTOpts
defaultOpts = CTOpts { loadIconPattern = Nothing
, mintemp = 0
, maxtemp = 1
}
options :: [OptDescr (CTOpts -> CTOpts)]
options = [ Option [] ["load-icon-pattern"]
(ReqArg
(\ arg opts -> opts { loadIconPattern = Just $ parseIconPattern arg })
"")
""
, Option [] ["mintemp"]
(ReqArg
(\ arg opts -> opts { mintemp = read arg / 100 })
"")
""
, Option [] ["maxtemp"]
(ReqArg
(\ arg opts -> opts { maxtemp = read arg / 100 })
"")
""
]
parseOpts :: [String] -> IO CTOpts
parseOpts argv = case getOpt Permute options argv of
(opts , _ , [] ) -> return $ foldr id defaultOpts opts
(_ , _ , errs) -> ioError . userError $ concat errs
-- | Generate Config with a default template and options.
cTConfig :: IO MConfig
cTConfig = mkMConfig cTTemplate cTOptions
where cTTemplate = "Temp: <max>°C"
cTOptions = [ "bar" , "vbar" , "ipat" , "max" , "maxpc" , "avg" , "avgpc" ] ++
(map (("core" ++) . show) [0 :: Int ..])
cTFilePath :: FilePath
cTFilePath = "/sys/bus/platform/devices/coretemp.0/hwmon/hwmon1/temp2_input"
cTData :: IO [Float]
cTData = do a <- readFile cTFilePath
return $ [ parseContent a ]
where parseContent = read . head . lines :: String -> Float
parseCT :: IO [Float]
parseCT = do rawCTs <- cTData
let normalizedCTs = map ((/ 100000)) rawCTs :: [Float]
return normalizedCTs
formatCT :: CTOpts -> [Float] -> Monitor [String]
formatCT opts cTs = do let CTOpts { mintemp = minT
, maxtemp = maxT } = opts
domainT = maxT - minT
maxCT = maximum cTs
avgCT = sum cTs / (fromIntegral $ length cTs)
maxCTPc = (maxCT - minT) / domainT
avgCTPc = (avgCT - minT) / domainT
cTShows <- showPercentsWithColors cTs
cTBar <- showPercentBar (100 * maxCTPc) maxCTPc
cTVBar <- showVerticalBar (100 * maxCTPc) maxCTPc
cTIcon <- showIconPattern (loadIconPattern opts) maxCTPc
maxCTShow <- showPercentWithColors maxCT
maxCTPcShow <- showPercentWithColors maxCTPc
avgCTShow <- showPercentWithColors avgCT
avgCTPcShow <- showPercentWithColors avgCTPc
return (cTBar : cTVBar : cTIcon :
maxCTShow : maxCTPcShow :
avgCTShow : avgCTPcShow :
cTShows)
runCT :: [String] -> Monitor String
runCT argv = do cTs <- io $ parseCT
opts <- io $ parseOpts argv
l <- formatCT opts cTs
parseTemplate l
startCoreTemp :: [String] -> Int -> (String -> IO ()) -> IO ()
startCoreTemp a = runM a cTConfig runCT
|