bb5b353332a2ec191ae3b3c9d5a494369d5bc2e9
[mTask.git] / Devices / mTaskDevice.icl
1 implementation module Devices.mTaskDevice
2
3 from StdFunc import flip
4 import Generics.gCons
5 import mTaskInterpret
6 import iTasks
7 import iTasksTTY
8 import TTY
9 import qualified Data.Map as DM
10 import Utils.SDS
11
12 import GenBimap
13 import Devices.mTaskSerial
14 import Devices.mTaskTCP
15 import iTasks._Framework.Store
16
17 from Data.Func import $
18
19 derive class iTask MTaskDevice, MTaskResource, MTaskMSGRecv, MTaskMSGSend
20 derive conses MTaskResource, TTYSettings, BaudRate, Parity, ByteSize, TCPSettings
21 derive consName MTaskResource, TTYSettings, BaudRate, Parity, ByteSize, TCPSettings
22
23 instance == MTaskDevice where
24 (==) a b = a.deviceChannels == b.deviceChannels
25
26 channels :: MTaskDevice -> Shared Channels
27 channels d = memoryShare d.deviceChannels ([], [], False)
28
29 makeDevice :: String MTaskResource -> Task MTaskDevice
30 makeDevice name res = get randomInt @ \rand->{MTaskDevice
31 |deviceChannels=name +++ toString rand
32 ,deviceName=name
33 ,deviceTasks=[]
34 ,deviceTask=Nothing
35 ,deviceData=res}
36
37 getSynFun :: MTaskResource -> ((Shared Channels) -> Task ())
38 getSynFun (TCPDevice t) = synFun t
39 getSynFun (SerialDevice t) = synFun t
40
41 addDevice :: (Shared [MTaskDevice]) (MTaskDevice (Shared Channels) -> Task ()) -> Task String
42 addDevice devices processFun
43 = enterChoice "Device type" [] (map consName{|*|} deviceTypes)
44 >&^ \sh->whileUnchanged sh $ \mty->case mty of
45 Nothing = viewInformation "No type selected yet" [] ""
46 Just ty = enterInformation "Name" [] -&&- deviceSettings ty
47 >>= \(name, settings)->makeDevice name settings
48 >>= \dev->appendTopLevelTask 'DM'.newMap True (tlt dev)
49 >>= \tid->upd (\l->[{dev & deviceTask=Just tid}:l]) devices
50 @! ""
51 where
52 tlt dev = let ch = channels dev in processFun dev ch -||- getSynFun dev.deviceData ch
53
54 deviceSettings "SerialDevice" = getmTaskSerialDevice
55 deviceSettings "TCPDevice" = getmTaskTCPDevice
56
57 deviceTypes :: [MTaskResource]
58 deviceTypes = conses{|*|}
59
60 manageDevices :: (MTaskDevice (Shared Channels) -> Task ()) [MTaskDevice] -> Task ()
61 manageDevices processFun ds = anyTask [
62 addDevice deviceStore processFun <<@ Title "Add new device" @! ():
63 [viewDevice d <<@ Title d.deviceName\\d<-ds]]
64 <<@ ArrangeWithTabs @! ()
65
66 viewDevice :: MTaskDevice -> Task ()
67 viewDevice d = forever $ anyTask
68 [viewInformation "Device settings" [] d @! ()
69 ,viewSharedInformation "Channels" [ViewAs dropEmpty] (channels d) @! ()
70 ,forever $
71 enterChoice "Delete task on device" [ChooseFromGrid id] d.deviceTasks
72 >>* [OnAction (Action "Delete") $ ifValue (\t->t.ident <> -1) (deviceTaskDelete d)]
73 @! ()
74 ] <<@ ArrangeHorizontal
75 >>* [OnAction (Action "Delete Device") (always $ deleteDevice d)]
76 where
77 dropEmpty (r,s,ss) = (filter ((=!=)MTEmpty) r,s,ss)
78
79 deleteDevice :: MTaskDevice -> Task ()
80 deleteDevice d = upd (\(r,s,ss)->(r,s,True)) (channels d)
81 >>| maybe (treturn ()) (flip removeTask topLevelTasks) d.deviceTask
82 >>| upd (filter ((==)d)) deviceStore
83 @! ()
84
85 sendToDevice :: String (Main (ByteCode () Stmt)) (MTaskDevice, MTaskInterval) -> Task ()
86 sendToDevice wta mTask (device, timeout) =
87 get bcStateStore @ toMessages timeout o toRealByteCode (unMain mTask)
88 >>= \(msgs, st1)->set st1 bcStateStore @ toSDSRecords
89 >>= \sdss->set sdss sdsStore//MTaskShareaddToSDSShare
90 >>| makeShares sdss
91 >>| sendMessage device msgs
92 >>| makeTask wta -1
93 >>= withDevices device o addTask
94 @! ()
95 where
96 sharename i = device.deviceChannels +++ "-" +++ toString i
97 toSDSRecords st = [{MTaskShare |
98 initValue=toInt d1*265 + toInt d2,
99 withTask=wta,
100 identifier=i,
101 realShare="mTaskSDS-" +++ toString i}
102 \\(i,[d1,d2])<-st.sdss]
103 makeShares = foldr (\sh t->set sh.initValue (getSDSStore sh) >>| t) (treturn ())
104
105 addTask :: MTaskTask MTaskDevice -> MTaskDevice
106 addTask task device = {device & deviceTasks=[task:device.deviceTasks]}
107
108 sendMessage :: MTaskDevice [MTaskMSGSend] -> Task ()
109 sendMessage dev msgs = upd (\(r,s,ss)->(r,msgs++s,ss)) (channels dev) @! ()
110
111 withDevices :: MTaskDevice (MTaskDevice -> MTaskDevice) -> Task ()
112 withDevices a trans = upd (map \b->if (b == a) (trans b) b) deviceStore @! ()
113
114 deviceTaskAcked :: MTaskDevice Int -> Task ()
115 deviceTaskAcked dev i
116 = withDevices dev (\d->{d&deviceTasks=ackFirst d.deviceTasks})
117 where
118 ackFirst :: [MTaskTask] -> [MTaskTask]
119 ackFirst [] = []
120 ackFirst [t:ts] = if (t.ident == -1)
121 [{t & ident=i}:ts] [t:ackFirst ts]
122
123 deviceTaskDelete :: MTaskDevice MTaskTask -> Task ()
124 deviceTaskDelete dev task = sendMessage dev [MTTaskDel task.ident]
125
126 deviceTaskDeleteAcked :: MTaskDevice Int -> Task ()
127 deviceTaskDeleteAcked d i = withDevices d $ deleteTask
128 where deleteTask d = {d & deviceTasks=[s\\s<-d.deviceTasks | i <> s.ident]}