module EIBd.Client.Address (
IndividualAddress (..),
fromIndividualAddress,
toIndividualAddress,
GroupAddress (..),
fromGroupAddress,
toGroupAddress,
) where
import Data.Word
import Data.String
import Data.Bits
import Data.Char
import Data.List
groupNumbers :: String -> [String]
groupNumbers = groupBy (\a b -> (isDigit a && isDigit b) || not (isDigit a || isDigit b))
newtype IndividualAddress = IndividualAddress Word16
deriving (Eq, Ord)
fromIndividualAddress :: IndividualAddress -> (Word8, Word8, Word8)
fromIndividualAddress (IndividualAddress n) =
(fromIntegral (shift n (12)),
fromIntegral (shift n (8) .&. 15),
fromIntegral (n .&. 255))
toIndividualAddress :: Word8 -> Word8 -> Word8 -> IndividualAddress
toIndividualAddress a b c = IndividualAddress (shift (fromIntegral a .&. 15) 12
.|. shift (fromIntegral b .&. 15) 8
.|. fromIntegral c)
instance IsString IndividualAddress where
fromString str =
case groupNumbers str of
[a, ".", b, ".", c] -> toIndividualAddress (read a) (read b) (read c)
_ -> error "Ill formated individual address"
instance Show IndividualAddress where
show i = show a ++ "." ++ show b ++ "." ++ show c where
(a, b, c) = fromIndividualAddress i
newtype GroupAddress = GroupAddress Word16
deriving (Eq, Ord)
fromGroupAddress :: GroupAddress -> (Word8, Word8, Word8)
fromGroupAddress (GroupAddress n) =
(fromIntegral (shift n (11)),
fromIntegral (shift n (8) .&. 7),
fromIntegral (n .&. 255))
toGroupAddress :: Word8 -> Word8 -> Word8 -> GroupAddress
toGroupAddress a b c = GroupAddress (shift (fromIntegral a .&. 15) 11
.|. shift (fromIntegral b .&. 7) 8
.|. fromIntegral c)
instance IsString GroupAddress where
fromString str =
case groupNumbers str of
[a, "/", b, "/", c] -> toGroupAddress (read a) (read b) (read c)
_ -> error "Ill formated group address"
instance Show GroupAddress where
show g = show a ++ "/" ++ show b ++ "/" ++ show c where
(a, b, c) = fromGroupAddress g