summaryrefslogtreecommitdiff
path: root/datasources/serialparser.hs
blob: f2f6c09357da90f86209b5efe670bba6909c7c56 (plain)
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
{-# LANGUAGE OverloadedStrings #-}
import Control.Applicative((<*))
import Data.Attoparsec(Parser,takeWhile1)
import Data.Attoparsec.Char8 (char8, endOfLine, isEndOfLine)
import Data.Attoparsec.Enumerator(iterParser)
import Data.Enumerator(Iteratee,Enumerator,run_,($$))
import Data.Enumerator.Binary (enumHandle)
import Data.ByteString.Char8(ByteString,unpack)
import Network.HTTP(simpleHTTP)
import Network.HTTP.Headers(Header,mkHeader,HeaderName(HdrContentLength))
import Network.HTTP.Base(urlEncode,mkRequest,Request(..),RequestMethod(PUT))
import Network.URI(parseURI)
import System.Environment(getArgs)
import System.Hardware.Serialport(hOpenSerial,defaultSerialSettings,commSpeed,CommSpeed(CS115200))
import System.IO (Handle,hFlush,hPutStr,stdin,hWaitForInput)

data Message = Measurement ByteString ByteString deriving (Show)

parser :: Parser Message
parser  = do
  sensor <- takeWhile1 (/=61) <* char8 '='
  value <- takeWhile1 (not . isEndOfLine) <* endOfLine
  return $! Measurement sensor value

parserIteratee       :: Handle -> Iteratee ByteString IO (Message)
parserIteratee handle = stdinEnumerator $$ iteratee
  where stdinEnumerator :: Enumerator ByteString IO b
        stdinEnumerator = enumHandle 1 handle
        iteratee :: Iteratee ByteString IO (Message)
        iteratee = iterParser parser

work     :: Handle -> IO ()
work port = do (Measurement sensor value) <- run_ (parserIteratee port)
               let url     = "http://localhost:8080/api/value/" ++ (urlEncode $ unpack sensor)
                   request = putRequest url in
                   simpleHTTP (putRequest url (unpack value))
               putStrLn $ (unpack sensor) ++ "=" ++ (unpack value)

loop     :: Handle -> IO ()
loop port = do sendRequest
               work port
               work port
               work port
               loop port
        where sendRequest :: IO (Bool)
              sendRequest = do catch (hWaitForInput port 50) handler
                               return (True)
                          where handler e = do putStrLn "."
                                               hPutStr port "0"
                                               hFlush port
                                               sendRequest

main :: IO ()
main  = do
       args <- getArgs
       port <- case args of
            [path] -> hOpenSerial path defaultSerialSettings { commSpeed = CS115200 }
            _ -> return stdin
       loop port


putRequest               :: String -> String -> Request String
putRequest urlString body = 
  case parseURI urlString of
    Nothing -> error ("putRequest: Not a valid URL - " ++ urlString)
    Just u  -> Request { rqURI      = u
                       , rqBody     = body
                       , rqHeaders  = headers
                       , rqMethod   = PUT }
        where headers = [ mkHeader HdrContentLength (show (length body) :: String) ]