-
Notifications
You must be signed in to change notification settings - Fork 0
/
Routine.hs
67 lines (56 loc) · 2.6 KB
/
Routine.hs
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
module Routine
(
Routines(..)
, RoutineSelector(..)
, Timer
, loadRoutines
) where
import qualified Data.Map as Map
import Data.Maybe (fromJust)
import Text.XML.Light (parseXML, elChildren)
import Xml
import Thermometer
import Zone
import Timer
type RoutineId = String
type Routine = Map.Map ZoneId [Timer]
data RoutineSelector = RoutineSelector
{ selectorRoutineId :: RoutineId
, selectorStart :: TimerTime
, selectorEnd :: TimerTime }
deriving (Show)
data Routines = Routines
{ routinesRoutines :: Map.Map RoutineId Routine
, routinesSelectors :: [RoutineSelector]
}
deriving (Show)
loadRoutines file zones = do
routinesEls <- fmap (rootChildren . parseXML) (readFile file)
return Routines
{ routinesRoutines = extractRoutines routinesEls zones
, routinesSelectors = extractWeeklyRoutines routinesEls ++ extractSpecialRoutines routinesEls
}
extractRoutines es zones = foldr extractRoutine Map.empty (filterElems "daily-routine" es)
where extractRoutine e = Map.insert (attr "id" e) (insertDefaults (foldr extractTimer Map.empty (elChildren e)))
extractTimer e m = Map.insert zid (Timer
{ timerStart = TimerDaily (duration $ attr "start" e)
, timerEnd = TimerDaily (duration $ attr "end" e)
, timerSetting = Left (zoneTemperature (attr "state" e) (fromJust $ Map.lookup zid zones))}
: Map.findWithDefault [] zid m) m
where zid = attr "zone-id" e
insertDefaults timerMap = foldr insertDefault Map.empty (Map.toList zones)
where insertDefault (k, z) = Map.insert k (defaultTimer {timerSetting = Left $ zoneDefault z} : Map.findWithDefault [] k timerMap)
defaultTimer = Timer
{ timerStart = TimerDaily 0
, timerEnd = TimerDaily 0
, timerSetting = Left 0 }
extractWeeklyRoutines es = concatMap (map extract . elChildren) $ filterElems "weekly-routines" es
where extract e = RoutineSelector
{ selectorRoutineId = attr "routine-id" e
, selectorStart = TimerWeekly (duration $ attr "start" e)
, selectorEnd = TimerWeekly (duration $ attr "end" e)}
extractSpecialRoutines es = concatMap (map extract . elChildren) $ filterElems "special-routines" es
where extract e = RoutineSelector
{ selectorRoutineId = attr "routine-id" e
, selectorStart = TimerAbsolute (parseISODate $ attr "start" e)
, selectorEnd = TimerAbsolute (parseISODate $ attr "end" e)}