+import qualified Data.Map as DM
+import Text.Encodings.Base64
+
+encode :: MTaskMSGSend -> String
+encode (MTTask to data) = "t" +++ tob +++ to16bit (size data) +++ data +++ "\n"
+ where
+ tob = case to of
+ OneShot = to16bit 0
+ OnInterval i = to16bit i
+ OnInterrupt _ = abort "Interrupts not implemented yet"
+encode (MTTaskDel i) = "d" +++ to16bit i +++ "\n"
+encode (MTSds i v) = "s" +++ to16bit i +++ v +++ "\n"
+encode (MTUpd i v) = "u" +++ to16bit i +++ v +++ "\n"
+
+decode :: String -> MTaskMSGRecv
+decode x
+| size x == 0 = MTEmpty
+= case x.[0] of
+ 't' = MTTaskAck (from16bit (x % (1,3)))
+ 'd' = MTTaskDelAck (from16bit (x % (1,3)))
+ 'm' = MTMessage x
+ 's' = MTSDSAck (from16bit (x % (1,3)))
+ 'a' = MTSDSDelAck (from16bit (x % (1,3)))
+ 'p' = MTPub (from16bit (x % (1,3))) (x % (3,5))
+ '\0' = MTEmpty
+ '\n' = MTEmpty
+ _ = MTMessage x//abort ("Didn't understand message: " +++ join " " [toString (toInt c)\\c<-: x] +++ "\n")
+
+safePrint :== toString o toJSON
+
+instance toString MTaskInterval where
+ toString OneShot = "One shot"
+ toString (OnInterrupt i) = "Interrupt: " +++ toString i
+ toString (OnInterval i) = "Every " +++ toString i +++ "ms"
+
+instance toString MTaskMSGSend where
+ toString (MTSds i v) = "Sds id: " +++ toString i
+ +++ " value " +++ safePrint v
+ toString (MTTask to data) = "Task timeout: " +++ toString to
+ +++ " data " +++ safePrint data
+ toString (MTTaskDel i) = "Task delete request: " +++ toString i
+ toString (MTUpd i v) = "Update id: " +++ toString i
+ +++ " value " +++ safePrint v
+
+instance toString MTaskMSGRecv where
+ toString (MTTaskAck i) = "Task added with id: " +++ toString i
+ toString (MTTaskDelAck i) = "Task deleted with id: " +++ toString i
+ toString (MTSDSAck i) = "SDS added with id: " +++ toString i
+ toString (MTSDSDelAck i) = "SDS deleted with id: " +++ toString i
+ toString (MTPub i v) = "Publish id: " +++ toString i
+ +++ " value " +++ safePrint v
+ toString (MTMessage m) = m
+ toString MTEmpty = "Empty message"
+
+bclength :: BC -> Int
+bclength (BCPush _) = 3
+bclength (BCLab _) = 2
+bclength (BCSdsStore _) = 3
+bclength (BCSdsFetch _) = 3
+bclength (BCSdsPublish _) = 3
+bclength (BCAnalogRead _) = 2
+bclength (BCAnalogWrite _) = 2
+bclength (BCDigitalRead _) = 2
+bclength (BCDigitalWrite _) = 2
+bclength (BCLedOn _) = 2
+bclength (BCLedOff _) = 2
+bclength (BCJmp i) = 2
+bclength (BCJmpT i) = 2
+bclength (BCJmpF i) = 2
+bclength _ = 1
+