{-|
Description : Cayenne Low Power Protocol encoding and decoding
Maintainer  : srk <srk@48.io>

Encoding example:

> import qualified Data.Cayenne as CLPP
> import qualified Data.ByteString.Base16.Lazy as B16L
> import qualified Data.ByteString.Lazy.Char8 as BSL
>
> BSL.putStrLn $ B16L.encode . CLPP.encodeMany [(7, Illum 1337), (0, Power 13.5)]

-}
{-# LANGUAGE RecordWildCards     #-}
{-# LANGUAGE OverloadedStrings   #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE DeriveGeneric       #-}

module Data.Cayenne.Types (
    Sensor(..)
  , Channel
  , Reading
  , encode
  , encodeMany
  , decode
  , decodeMany
  , decodeMaybe
  ) where

import Control.Monad
import Control.Applicative
import Data.Monoid
import GHC.Generics

import Data.Bits
import Data.Binary.Get
import Data.Binary.Put
import Data.Word
import Data.Int
import qualified Data.ByteString.Lazy.Char8 as BL

type Channel = Int
type Reading = (Channel, Sensor)

data Sensor =
    DigitalIn     Word8              -- ^ Digital input (8 bits)
  | DigitalOut    Word8              -- ^ Digital output (8 bits)
  | AnalogIn      Float              -- ^ Analog input
  | AnalogOut     Float              -- ^ Analog output
  | Illum         Word16             -- ^ Illuminance sensor (Lux)
  | Presence      Word8              -- ^ Presence
  | Temperature   Float              -- ^ Temperature (Celsius)
  | Humidity      Float              -- ^ Humidity (%)
  | Accelerometer Float Float Float  -- ^ Accelerometer (G)
  | Barometer     Float              -- ^ Barometer (hPa)
  | Voltage       Float              -- ^ Voltage (V)
  | Current       Float              -- ^ Current (A)
  | Percentage    Float              -- ^ Percentage
  | Pressure      Float              -- ^ Pressure
  | Power         Float              -- ^ Power (W)
  | Energy        Float              -- ^ Energy (J)
  | Direction     Float              -- ^ Angle (Deg)
  | Gyrometer     Float Float Float  -- ^ Gyrometer (°/s)
  | GPS           Float Float Float  -- ^ GPS Latitude (°) ,Longitude (°), Altitude (m)
  deriving (Sensor -> Sensor -> Bool
(Sensor -> Sensor -> Bool)
-> (Sensor -> Sensor -> Bool) -> Eq Sensor
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Sensor -> Sensor -> Bool
$c/= :: Sensor -> Sensor -> Bool
== :: Sensor -> Sensor -> Bool
$c== :: Sensor -> Sensor -> Bool
Eq, Eq Sensor
Eq Sensor
-> (Sensor -> Sensor -> Ordering)
-> (Sensor -> Sensor -> Bool)
-> (Sensor -> Sensor -> Bool)
-> (Sensor -> Sensor -> Bool)
-> (Sensor -> Sensor -> Bool)
-> (Sensor -> Sensor -> Sensor)
-> (Sensor -> Sensor -> Sensor)
-> Ord Sensor
Sensor -> Sensor -> Bool
Sensor -> Sensor -> Ordering
Sensor -> Sensor -> Sensor
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Sensor -> Sensor -> Sensor
$cmin :: Sensor -> Sensor -> Sensor
max :: Sensor -> Sensor -> Sensor
$cmax :: Sensor -> Sensor -> Sensor
>= :: Sensor -> Sensor -> Bool
$c>= :: Sensor -> Sensor -> Bool
> :: Sensor -> Sensor -> Bool
$c> :: Sensor -> Sensor -> Bool
<= :: Sensor -> Sensor -> Bool
$c<= :: Sensor -> Sensor -> Bool
< :: Sensor -> Sensor -> Bool
$c< :: Sensor -> Sensor -> Bool
compare :: Sensor -> Sensor -> Ordering
$ccompare :: Sensor -> Sensor -> Ordering
$cp1Ord :: Eq Sensor
Ord, Int -> Sensor -> ShowS
[Sensor] -> ShowS
Sensor -> String
(Int -> Sensor -> ShowS)
-> (Sensor -> String) -> ([Sensor] -> ShowS) -> Show Sensor
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Sensor] -> ShowS
$cshowList :: [Sensor] -> ShowS
show :: Sensor -> String
$cshow :: Sensor -> String
showsPrec :: Int -> Sensor -> ShowS
$cshowsPrec :: Int -> Sensor -> ShowS
Show, (forall x. Sensor -> Rep Sensor x)
-> (forall x. Rep Sensor x -> Sensor) -> Generic Sensor
forall x. Rep Sensor x -> Sensor
forall x. Sensor -> Rep Sensor x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Sensor x -> Sensor
$cfrom :: forall x. Sensor -> Rep Sensor x
Generic)

toID :: Sensor -> Int
toID :: Sensor -> Int
toID (DigitalIn Word8
_)         = Int
0x00
toID (DigitalOut Word8
_)        = Int
0x01
toID (AnalogIn Float
_)          = Int
0x02
toID (AnalogOut Float
_)         = Int
0x03
toID (Illum Word16
_)             = Int
0x65
toID (Presence Word8
_)          = Int
0x66
toID (Temperature Float
_)       = Int
0x67
toID (Humidity Float
_)          = Int
0x68
toID (Accelerometer Float
_ Float
_ Float
_) = Int
0x71
toID (Barometer Float
_)         = Int
0x73
toID (Voltage Float
_)           = Int
0x74
toID (Current Float
_)           = Int
0x75
toID (Percentage Float
_)        = Int
0x78
toID (Pressure Float
_)          = Int
0x7b
toID (Power Float
_)             = Int
0x80
toID (Energy Float
_)            = Int
0x83
toID (Direction Float
_)         = Int
0x84
toID (Gyrometer Float
_ Float
_ Float
_)     = Int
0x86
toID (GPS Float
_ Float
_ Float
_)           = Int
0x88

getSensor :: Get Sensor
getSensor :: Get Sensor
getSensor =
      (Word8 -> Get ()
isID Word8
0x0 ) Get () -> Get Sensor -> Get Sensor
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (Word8 -> Sensor
DigitalIn     (Word8 -> Sensor) -> Get Word8 -> Get Sensor
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Word8
getWord8)
  Get Sensor -> Get Sensor -> Get Sensor
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (Word8 -> Get ()
isID Word8
0x1 ) Get () -> Get Sensor -> Get Sensor
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (Word8 -> Sensor
DigitalOut    (Word8 -> Sensor) -> Get Word8 -> Get Sensor
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Word8
getWord8)
  Get Sensor -> Get Sensor -> Get Sensor
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (Word8 -> Get ()
isID Word8
0x2 ) Get () -> Get Sensor -> Get Sensor
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (Float -> Sensor
AnalogIn      (Float -> Sensor) -> Get Float -> Get Sensor
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/Float
100) (Float -> Float) -> Get Float -> Get Float
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Float
getFloat16))
  Get Sensor -> Get Sensor -> Get Sensor
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (Word8 -> Get ()
isID Word8
0x3 ) Get () -> Get Sensor -> Get Sensor
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (Float -> Sensor
AnalogOut     (Float -> Sensor) -> Get Float -> Get Sensor
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/Float
100) (Float -> Float) -> Get Float -> Get Float
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Float
getFloat16))
  Get Sensor -> Get Sensor -> Get Sensor
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (Word8 -> Get ()
isID Word8
0x65) Get () -> Get Sensor -> Get Sensor
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (Word16 -> Sensor
Illum         (Word16 -> Sensor) -> Get Word16 -> Get Sensor
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Word16
getWord16)
  Get Sensor -> Get Sensor -> Get Sensor
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (Word8 -> Get ()
isID Word8
0x66) Get () -> Get Sensor -> Get Sensor
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (Word8 -> Sensor
Presence      (Word8 -> Sensor) -> Get Word8 -> Get Sensor
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Word8
getWord8)
  Get Sensor -> Get Sensor -> Get Sensor
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (Word8 -> Get ()
isID Word8
0x67) Get () -> Get Sensor -> Get Sensor
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (Float -> Sensor
Temperature   (Float -> Sensor) -> Get Float -> Get Sensor
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/Float
10)  (Float -> Float) -> Get Float -> Get Float
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Float
getFloat16))
  Get Sensor -> Get Sensor -> Get Sensor
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (Word8 -> Get ()
isID Word8
0x68) Get () -> Get Sensor -> Get Sensor
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (Float -> Sensor
Humidity      (Float -> Sensor) -> Get Float -> Get Sensor
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/Float
2) (Float -> Float) -> (Word8 -> Float) -> Word8 -> Float
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Float
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Float) -> Get Word8 -> Get Float
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Word8
getWord8))
  Get Sensor -> Get Sensor -> Get Sensor
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (Word8 -> Get ()
isID Word8
0x71) Get () -> Get Sensor -> Get Sensor
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (Float -> Float -> Float -> Sensor
Accelerometer (Float -> Float -> Float -> Sensor)
-> Get Float -> Get (Float -> Float -> Sensor)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/Float
1000) (Float -> Float) -> Get Float -> Get Float
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Float
getFloat16) Get (Float -> Float -> Sensor)
-> Get Float -> Get (Float -> Sensor)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ((Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/Float
1000) (Float -> Float) -> Get Float -> Get Float
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Float
getFloat16) Get (Float -> Sensor) -> Get Float -> Get Sensor
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ((Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/Float
1000) (Float -> Float) -> Get Float -> Get Float
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Float
getFloat16))
  Get Sensor -> Get Sensor -> Get Sensor
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (Word8 -> Get ()
isID Word8
0x73) Get () -> Get Sensor -> Get Sensor
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (Float -> Sensor
Barometer     (Float -> Sensor) -> Get Float -> Get Sensor
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/Float
10)  (Float -> Float) -> Get Float -> Get Float
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Float
getFloat16))
  Get Sensor -> Get Sensor -> Get Sensor
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (Word8 -> Get ()
isID Word8
0x74) Get () -> Get Sensor -> Get Sensor
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (Float -> Sensor
Voltage       (Float -> Sensor) -> Get Float -> Get Sensor
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/Float
10)  (Float -> Float) -> Get Float -> Get Float
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Float
getFloat16))
  Get Sensor -> Get Sensor -> Get Sensor
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (Word8 -> Get ()
isID Word8
0x75) Get () -> Get Sensor -> Get Sensor
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (Float -> Sensor
Current       (Float -> Sensor) -> Get Float -> Get Sensor
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/Float
10)  (Float -> Float) -> Get Float -> Get Float
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Float
getFloat16))
  Get Sensor -> Get Sensor -> Get Sensor
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (Word8 -> Get ()
isID Word8
0x78) Get () -> Get Sensor -> Get Sensor
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (Float -> Sensor
Percentage    (Float -> Sensor) -> Get Float -> Get Sensor
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Float
getFloat16)
  Get Sensor -> Get Sensor -> Get Sensor
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (Word8 -> Get ()
isID Word8
0x7b) Get () -> Get Sensor -> Get Sensor
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (Float -> Sensor
Pressure      (Float -> Sensor) -> Get Float -> Get Sensor
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/Float
10)  (Float -> Float) -> Get Float -> Get Float
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Float
getFloat16))
  Get Sensor -> Get Sensor -> Get Sensor
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (Word8 -> Get ()
isID Word8
0x80) Get () -> Get Sensor -> Get Sensor
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (Float -> Sensor
Power         (Float -> Sensor) -> Get Float -> Get Sensor
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/Float
10)  (Float -> Float) -> Get Float -> Get Float
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Float
getFloat16))
  Get Sensor -> Get Sensor -> Get Sensor
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (Word8 -> Get ()
isID Word8
0x83) Get () -> Get Sensor -> Get Sensor
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (Float -> Sensor
Energy        (Float -> Sensor) -> Get Float -> Get Sensor
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/Float
10)  (Float -> Float) -> Get Float -> Get Float
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Float
getFloat16))
  Get Sensor -> Get Sensor -> Get Sensor
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (Word8 -> Get ()
isID Word8
0x84) Get () -> Get Sensor -> Get Sensor
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (Float -> Sensor
Direction     (Float -> Sensor) -> Get Float -> Get Sensor
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Float
getFloat16)
  Get Sensor -> Get Sensor -> Get Sensor
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (Word8 -> Get ()
isID Word8
0x86) Get () -> Get Sensor -> Get Sensor
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (Float -> Float -> Float -> Sensor
Gyrometer     (Float -> Float -> Float -> Sensor)
-> Get Float -> Get (Float -> Float -> Sensor)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/Float
100) (Float -> Float) -> Get Float -> Get Float
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Float
getFloat16) Get (Float -> Float -> Sensor)
-> Get Float -> Get (Float -> Sensor)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ((Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/Float
100) (Float -> Float) -> Get Float -> Get Float
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Float
getFloat16) Get (Float -> Sensor) -> Get Float -> Get Sensor
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ((Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/Float
100) (Float -> Float) -> Get Float -> Get Float
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Float
getFloat16))
  Get Sensor -> Get Sensor -> Get Sensor
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (Word8 -> Get ()
isID Word8
0x88) Get () -> Get Sensor -> Get Sensor
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (Float -> Float -> Float -> Sensor
GPS           (Float -> Float -> Float -> Sensor)
-> Get Float -> Get (Float -> Float -> Sensor)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/Float
10000) (Float -> Float) -> Get Float -> Get Float
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Float
getFloat24) Get (Float -> Float -> Sensor)
-> Get Float -> Get (Float -> Sensor)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ((Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/Float
10000) (Float -> Float) -> Get Float -> Get Float
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Float
getFloat24) Get (Float -> Sensor) -> Get Float -> Get Sensor
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ((Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/Float
100) (Float -> Float) -> Get Float -> Get Float
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Float
getFloat24))

isID :: Word8 -> Get ()
isID :: Word8 -> Get ()
isID Word8
x = do
  Word8
y <- Get Word8
getWord8
  Bool -> Get () -> Get ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Word8
x Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
y) (Get () -> Get ()) -> Get () -> Get ()
forall a b. (a -> b) -> a -> b
$ Get ()
forall (f :: * -> *) a. Alternative f => f a
empty

putSensor :: Sensor -> Put
putSensor :: Sensor -> Put
putSensor Sensor
s = Word8 -> Put
putWord8 (Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word8) -> Int -> Word8
forall a b. (a -> b) -> a -> b
$ Sensor -> Int
toID Sensor
s) Put -> Put -> Put
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Sensor -> Put
putSensor' Sensor
s

putSensor' :: Sensor -> Put
putSensor'  (DigitalIn Word8
x)         =  Word8 -> Put
putWord8 Word8
x
putSensor'  (DigitalOut Word8
x)        =  Word8 -> Put
putWord8 Word8
x
putSensor'  (AnalogIn Float
x)          = (Float -> Put
putFloat16 (Float -> Put) -> (Float -> Float) -> Float -> Put
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
100)) Float
x
putSensor'  (AnalogOut Float
x)         = (Float -> Put
putFloat16 (Float -> Put) -> (Float -> Float) -> Float -> Put
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
100)) Float
x
putSensor'  (Illum Word16
x)             =  Word16 -> Put
putWord16 Word16
x
putSensor'  (Presence Word8
x)          =  Word8 -> Put
putWord8 Word8
x
putSensor'  (Temperature Float
x)       = (Float -> Put
putFloat16 (Float -> Put) -> (Float -> Float) -> Float -> Put
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
10)) Float
x
putSensor'  (Humidity Float
x)          = (Word8 -> Put
putWord8 (Word8 -> Put) -> (Float -> Word8) -> Float -> Put
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Float -> Word8
forall a b. (RealFrac a, Integral b) => a -> b
round (Float -> Word8) -> (Float -> Float) -> Float -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
2)) Float
x
putSensor'  (Accelerometer Float
x Float
y Float
z) = (Float -> Put
putFloat16 (Float -> Put) -> (Float -> Float) -> Float -> Put
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
1000)) Float
x Put -> Put -> Put
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (Float -> Put
putFloat16 (Float -> Put) -> (Float -> Float) -> Float -> Put
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
1000)) Float
y Put -> Put -> Put
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (Float -> Put
putFloat16 (Float -> Put) -> (Float -> Float) -> Float -> Put
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
1000)) Float
z
putSensor'  (Barometer Float
x)         = (Float -> Put
putFloat16 (Float -> Put) -> (Float -> Float) -> Float -> Put
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
10)) Float
x
putSensor'  (Voltage Float
x)           = (Float -> Put
putFloat16 (Float -> Put) -> (Float -> Float) -> Float -> Put
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
10)) Float
x
putSensor'  (Current Float
x)           = (Float -> Put
putFloat16 (Float -> Put) -> (Float -> Float) -> Float -> Put
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
10)) Float
x
putSensor'  (Percentage Float
x)        =  Float -> Put
putFloat16 Float
x
putSensor'  (Pressure Float
x)          = (Float -> Put
putFloat16 (Float -> Put) -> (Float -> Float) -> Float -> Put
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
10)) Float
x
putSensor'  (Power Float
x)             = (Float -> Put
putFloat16 (Float -> Put) -> (Float -> Float) -> Float -> Put
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
10)) Float
x
putSensor'  (Energy Float
x)            = (Float -> Put
putFloat16 (Float -> Put) -> (Float -> Float) -> Float -> Put
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
10)) Float
x
putSensor'  (Direction Float
x)         =  Float -> Put
putFloat16 Float
x
putSensor'  (Gyrometer Float
x Float
y Float
z)     = (Float -> Put
putFloat16 (Float -> Put) -> (Float -> Float) -> Float -> Put
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
100)) Float
x Put -> Put -> Put
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (Float -> Put
putFloat16 (Float -> Put) -> (Float -> Float) -> Float -> Put
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
100)) Float
y Put -> Put -> Put
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (Float -> Put
putFloat16 (Float -> Put) -> (Float -> Float) -> Float -> Put
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
100)) Float
z
putSensor'  (GPS Float
x Float
y Float
z)           = (Float -> Put
putFloat24 (Float -> Put) -> (Float -> Float) -> Float -> Put
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
10000)) Float
x Put -> Put -> Put
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (Float -> Put
putFloat24 (Float -> Put) -> (Float -> Float) -> Float -> Put
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
10000)) Float
y Put -> Put -> Put
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (Float -> Put
putFloat24 (Float -> Put) -> (Float -> Float) -> Float -> Put
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
100)) Float
z

putReading :: Reading -> Put
putReading :: Reading -> Put
putReading (Int
chan, Sensor
sens) = Int -> Put
putChannel Int
chan Put -> Put -> Put
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Sensor -> Put
putSensor Sensor
sens

putChannel :: Channel -> Put
putChannel :: Int -> Put
putChannel = Word8 -> Put
putWord8 (Word8 -> Put) -> (Int -> Word8) -> Int -> Put
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral

putWord16 :: Word16 -> Put
putWord16 :: Word16 -> Put
putWord16 = Word16 -> Put
putWord16be

putFloat16 :: Float -> Put
putFloat16 :: Float -> Put
putFloat16 = Int16 -> Put
putInt16be (Int16 -> Put) -> (Float -> Int16) -> Float -> Put
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Float -> Int16
forall a b. (RealFrac a, Integral b) => a -> b
round

putFloat24 :: Float -> Put
putFloat24 :: Float -> Put
putFloat24 Float
x = do
  let x' :: Word32
x' = Float -> Word32
forall a b. (RealFrac a, Integral b) => a -> b
round Float
x :: Word32
  Word8 -> Put
putWord8 (Word8 -> Put) -> Word8 -> Put
forall a b. (a -> b) -> a -> b
$ Word32 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word32 -> Word8) -> Word32 -> Word8
forall a b. (a -> b) -> a -> b
$ Word32
x' Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
`shiftR` Int
16
  Word16 -> Put
putWord16be (Word16 -> Put) -> Word16 -> Put
forall a b. (a -> b) -> a -> b
$ Word32 -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word32 -> Word16) -> Word32 -> Word16
forall a b. (a -> b) -> a -> b
$ Word32
x'

-- | Encode a single 'Reading'
encode :: Reading -> BL.ByteString
encode :: Reading -> ByteString
encode = Put -> ByteString
runPut (Put -> ByteString) -> (Reading -> Put) -> Reading -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Reading -> Put
putReading

-- | Encode a list of 'Reading's
encodeMany :: [Reading] -> BL.ByteString
encodeMany :: [Reading] -> ByteString
encodeMany = Put -> ByteString
runPut (Put -> ByteString)
-> ([Reading] -> Put) -> [Reading] -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Reading -> Put) -> [Reading] -> Put
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ Reading -> Put
putReading)

getWord16 :: Get Word16
getWord16 :: Get Word16
getWord16 = Get Word16
getWord16be

getFloat16 :: Get Float
getFloat16 :: Get Float
getFloat16 = Int16 -> Float
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int16 -> Float) -> Get Int16 -> Get Float
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Int16
getInt16be

getFloat24 :: Get Float
getFloat24 :: Get Float
getFloat24 = do
  Word32
h :: Word32 <- Word8 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Word32) -> Get Word8 -> Get Word32
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Word8
getWord8
  Word32
l :: Word32 <- Word16 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word16 -> Word32) -> Get Word16 -> Get Word32
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Word16
getWord16be
  let sum :: Word32
sum = (Word32
h Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
`shiftL` Int
16) Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+ Word32
l
      cast :: Word32 -> Int32
cast = Word32 -> Int32
forall a b. (Integral a, Num b) => a -> b
fromIntegral :: Word32 -> Int32
      pls :: Int32
pls = (Word32 -> Int32
cast (Word32
h Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
`shiftL` Int
16 Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+ Word32
l) Int32 -> Int -> Int32
forall a. Bits a => a -> Int -> a
`shiftL` Int
8) Int32 -> Int -> Int32
forall a. Bits a => a -> Int -> a
`shiftR` Int
8
  Float -> Get Float
forall (m :: * -> *) a. Monad m => a -> m a
return (Float -> Get Float) -> Float -> Get Float
forall a b. (a -> b) -> a -> b
$ Int32 -> Float
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int32
pls -- as in pls float24..

getChannel :: Get Channel
getChannel :: Get Int
getChannel = Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Int) -> Get Word8 -> Get Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Word8
getWord8

clppP :: Get Reading
clppP :: Get Reading
clppP = (,) (Int -> Sensor -> Reading) -> Get Int -> Get (Sensor -> Reading)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Int
getChannel Get (Sensor -> Reading) -> Get Sensor -> Get Reading
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Get Sensor
getSensor

-- | Decode a single 'Reading', may fail
decode :: BL.ByteString -> Reading
decode :: ByteString -> Reading
decode = Get Reading -> ByteString -> Reading
forall a. Get a -> ByteString -> a
runGet Get Reading
clppP

-- | Decode multiple 'Reading's, returns empty list if nothing is decoded
decodeMany :: BL.ByteString -> [Reading]
decodeMany :: ByteString -> [Reading]
decodeMany = Get [Reading] -> ByteString -> [Reading]
forall a. Get a -> ByteString -> a
runGet (Get [Reading] -> ByteString -> [Reading])
-> Get [Reading] -> ByteString -> [Reading]
forall a b. (a -> b) -> a -> b
$ Get Reading -> Get [Reading]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
many Get Reading
clppP

-- | Maybe decode a single 'Reading'
decodeMaybe :: BL.ByteString -> Maybe Reading
decodeMaybe :: ByteString -> Maybe Reading
decodeMaybe ByteString
x = case Get Reading
-> ByteString
-> Either
     (ByteString, ByteOffset, String) (ByteString, ByteOffset, Reading)
forall a.
Get a
-> ByteString
-> Either
     (ByteString, ByteOffset, String) (ByteString, ByteOffset, a)
runGetOrFail Get Reading
clppP ByteString
x of
  Left (ByteString, ByteOffset, String)
_ -> Maybe Reading
forall a. Maybe a
Nothing
  Right (ByteString
_, ByteOffset
_, Reading
y) -> Reading -> Maybe Reading
forall a. a -> Maybe a
Just Reading
y