{-# OPTIONS_GHC -Wno-orphans #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralisedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE UndecidableInstances #-}
module Tesla.Energy (
runEnergy, siteData, siteConfig, Energy
) where
import Control.Exception (Exception)
import Control.Monad.Catch (MonadCatch (..), MonadMask (..), MonadThrow (..))
import Control.Monad.IO.Class (MonadIO (..))
import Control.Monad.IO.Unlift (MonadUnliftIO, withRunInIO)
import Control.Monad.Logger (MonadLogger)
import Control.Monad.Reader (MonadReader, ReaderT (..), asks, runReaderT)
import Data.Aeson (FromJSON (..))
import Tesla
import Tesla.Auth
import Tesla.Internal.HTTP
energyURL :: EnergyID -> String -> String
energyURL :: EnergyID -> String -> String
energyURL EnergyID
v String
c = [String] -> String
forall a. Monoid a => [a] -> a
mconcat [String
baseURL, String
"api/1/energy_sites/", EnergyID -> String
forall a. Show a => a -> String
show EnergyID
v, String
"/", String
c]
data EnergyEnv = EnergyEnv {
EnergyEnv -> IO AuthInfo
_authInfo :: IO AuthInfo,
EnergyEnv -> EnergyID
_eid :: EnergyID
}
currentEnergyID :: Monad m => Energy m EnergyID
currentEnergyID :: Energy m EnergyID
currentEnergyID = (EnergyEnv -> EnergyID) -> Energy m EnergyID
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks EnergyEnv -> EnergyID
_eid
newtype Energy m a = Energy { Energy m a -> ReaderT EnergyEnv m a
runEnergyM :: ReaderT EnergyEnv m a }
deriving (Functor (Energy m)
a -> Energy m a
Functor (Energy m)
-> (forall a. a -> Energy m a)
-> (forall a b. Energy m (a -> b) -> Energy m a -> Energy m b)
-> (forall a b c.
(a -> b -> c) -> Energy m a -> Energy m b -> Energy m c)
-> (forall a b. Energy m a -> Energy m b -> Energy m b)
-> (forall a b. Energy m a -> Energy m b -> Energy m a)
-> Applicative (Energy m)
Energy m a -> Energy m b -> Energy m b
Energy m a -> Energy m b -> Energy m a
Energy m (a -> b) -> Energy m a -> Energy m b
(a -> b -> c) -> Energy m a -> Energy m b -> Energy m c
forall a. a -> Energy m a
forall a b. Energy m a -> Energy m b -> Energy m a
forall a b. Energy m a -> Energy m b -> Energy m b
forall a b. Energy m (a -> b) -> Energy m a -> Energy m b
forall a b c.
(a -> b -> c) -> Energy m a -> Energy m b -> Energy m c
forall (f :: * -> *).
Functor f
-> (forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
forall (m :: * -> *). Applicative m => Functor (Energy m)
forall (m :: * -> *) a. Applicative m => a -> Energy m a
forall (m :: * -> *) a b.
Applicative m =>
Energy m a -> Energy m b -> Energy m a
forall (m :: * -> *) a b.
Applicative m =>
Energy m a -> Energy m b -> Energy m b
forall (m :: * -> *) a b.
Applicative m =>
Energy m (a -> b) -> Energy m a -> Energy m b
forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> c) -> Energy m a -> Energy m b -> Energy m c
<* :: Energy m a -> Energy m b -> Energy m a
$c<* :: forall (m :: * -> *) a b.
Applicative m =>
Energy m a -> Energy m b -> Energy m a
*> :: Energy m a -> Energy m b -> Energy m b
$c*> :: forall (m :: * -> *) a b.
Applicative m =>
Energy m a -> Energy m b -> Energy m b
liftA2 :: (a -> b -> c) -> Energy m a -> Energy m b -> Energy m c
$cliftA2 :: forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> c) -> Energy m a -> Energy m b -> Energy m c
<*> :: Energy m (a -> b) -> Energy m a -> Energy m b
$c<*> :: forall (m :: * -> *) a b.
Applicative m =>
Energy m (a -> b) -> Energy m a -> Energy m b
pure :: a -> Energy m a
$cpure :: forall (m :: * -> *) a. Applicative m => a -> Energy m a
$cp1Applicative :: forall (m :: * -> *). Applicative m => Functor (Energy m)
Applicative, a -> Energy m b -> Energy m a
(a -> b) -> Energy m a -> Energy m b
(forall a b. (a -> b) -> Energy m a -> Energy m b)
-> (forall a b. a -> Energy m b -> Energy m a)
-> Functor (Energy m)
forall a b. a -> Energy m b -> Energy m a
forall a b. (a -> b) -> Energy m a -> Energy m b
forall (m :: * -> *) a b.
Functor m =>
a -> Energy m b -> Energy m a
forall (m :: * -> *) a b.
Functor m =>
(a -> b) -> Energy m a -> Energy m b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> Energy m b -> Energy m a
$c<$ :: forall (m :: * -> *) a b.
Functor m =>
a -> Energy m b -> Energy m a
fmap :: (a -> b) -> Energy m a -> Energy m b
$cfmap :: forall (m :: * -> *) a b.
Functor m =>
(a -> b) -> Energy m a -> Energy m b
Functor, Applicative (Energy m)
a -> Energy m a
Applicative (Energy m)
-> (forall a b. Energy m a -> (a -> Energy m b) -> Energy m b)
-> (forall a b. Energy m a -> Energy m b -> Energy m b)
-> (forall a. a -> Energy m a)
-> Monad (Energy m)
Energy m a -> (a -> Energy m b) -> Energy m b
Energy m a -> Energy m b -> Energy m b
forall a. a -> Energy m a
forall a b. Energy m a -> Energy m b -> Energy m b
forall a b. Energy m a -> (a -> Energy m b) -> Energy m b
forall (m :: * -> *). Monad m => Applicative (Energy m)
forall (m :: * -> *) a. Monad m => a -> Energy m a
forall (m :: * -> *) a b.
Monad m =>
Energy m a -> Energy m b -> Energy m b
forall (m :: * -> *) a b.
Monad m =>
Energy m a -> (a -> Energy m b) -> Energy m b
forall (m :: * -> *).
Applicative m
-> (forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
return :: a -> Energy m a
$creturn :: forall (m :: * -> *) a. Monad m => a -> Energy m a
>> :: Energy m a -> Energy m b -> Energy m b
$c>> :: forall (m :: * -> *) a b.
Monad m =>
Energy m a -> Energy m b -> Energy m b
>>= :: Energy m a -> (a -> Energy m b) -> Energy m b
$c>>= :: forall (m :: * -> *) a b.
Monad m =>
Energy m a -> (a -> Energy m b) -> Energy m b
$cp1Monad :: forall (m :: * -> *). Monad m => Applicative (Energy m)
Monad, Monad (Energy m)
Monad (Energy m)
-> (forall a. IO a -> Energy m a) -> MonadIO (Energy m)
IO a -> Energy m a
forall a. IO a -> Energy m a
forall (m :: * -> *).
Monad m -> (forall a. IO a -> m a) -> MonadIO m
forall (m :: * -> *). MonadIO m => Monad (Energy m)
forall (m :: * -> *) a. MonadIO m => IO a -> Energy m a
liftIO :: IO a -> Energy m a
$cliftIO :: forall (m :: * -> *) a. MonadIO m => IO a -> Energy m a
$cp1MonadIO :: forall (m :: * -> *). MonadIO m => Monad (Energy m)
MonadIO,
MonadThrow (Energy m)
MonadThrow (Energy m)
-> (forall e a.
Exception e =>
Energy m a -> (e -> Energy m a) -> Energy m a)
-> MonadCatch (Energy m)
Energy m a -> (e -> Energy m a) -> Energy m a
forall e a.
Exception e =>
Energy m a -> (e -> Energy m a) -> Energy m a
forall (m :: * -> *).
MonadThrow m
-> (forall e a. Exception e => m a -> (e -> m a) -> m a)
-> MonadCatch m
forall (m :: * -> *). MonadCatch m => MonadThrow (Energy m)
forall (m :: * -> *) e a.
(MonadCatch m, Exception e) =>
Energy m a -> (e -> Energy m a) -> Energy m a
catch :: Energy m a -> (e -> Energy m a) -> Energy m a
$ccatch :: forall (m :: * -> *) e a.
(MonadCatch m, Exception e) =>
Energy m a -> (e -> Energy m a) -> Energy m a
$cp1MonadCatch :: forall (m :: * -> *). MonadCatch m => MonadThrow (Energy m)
MonadCatch, Monad (Energy m)
e -> Energy m a
Monad (Energy m)
-> (forall e a. Exception e => e -> Energy m a)
-> MonadThrow (Energy m)
forall e a. Exception e => e -> Energy m a
forall (m :: * -> *).
Monad m -> (forall e a. Exception e => e -> m a) -> MonadThrow m
forall (m :: * -> *). MonadThrow m => Monad (Energy m)
forall (m :: * -> *) e a.
(MonadThrow m, Exception e) =>
e -> Energy m a
throwM :: e -> Energy m a
$cthrowM :: forall (m :: * -> *) e a.
(MonadThrow m, Exception e) =>
e -> Energy m a
$cp1MonadThrow :: forall (m :: * -> *). MonadThrow m => Monad (Energy m)
MonadThrow, MonadCatch (Energy m)
MonadCatch (Energy m)
-> (forall b.
((forall a. Energy m a -> Energy m a) -> Energy m b) -> Energy m b)
-> (forall b.
((forall a. Energy m a -> Energy m a) -> Energy m b) -> Energy m b)
-> (forall a b c.
Energy m a
-> (a -> ExitCase b -> Energy m c)
-> (a -> Energy m b)
-> Energy m (b, c))
-> MonadMask (Energy m)
Energy m a
-> (a -> ExitCase b -> Energy m c)
-> (a -> Energy m b)
-> Energy m (b, c)
((forall a. Energy m a -> Energy m a) -> Energy m b) -> Energy m b
((forall a. Energy m a -> Energy m a) -> Energy m b) -> Energy m b
forall b.
((forall a. Energy m a -> Energy m a) -> Energy m b) -> Energy m b
forall a b c.
Energy m a
-> (a -> ExitCase b -> Energy m c)
-> (a -> Energy m b)
-> Energy m (b, c)
forall (m :: * -> *).
MonadCatch m
-> (forall b. ((forall a. m a -> m a) -> m b) -> m b)
-> (forall b. ((forall a. m a -> m a) -> m b) -> m b)
-> (forall a b c.
m a -> (a -> ExitCase b -> m c) -> (a -> m b) -> m (b, c))
-> MonadMask m
forall (m :: * -> *). MonadMask m => MonadCatch (Energy m)
forall (m :: * -> *) b.
MonadMask m =>
((forall a. Energy m a -> Energy m a) -> Energy m b) -> Energy m b
forall (m :: * -> *) a b c.
MonadMask m =>
Energy m a
-> (a -> ExitCase b -> Energy m c)
-> (a -> Energy m b)
-> Energy m (b, c)
generalBracket :: Energy m a
-> (a -> ExitCase b -> Energy m c)
-> (a -> Energy m b)
-> Energy m (b, c)
$cgeneralBracket :: forall (m :: * -> *) a b c.
MonadMask m =>
Energy m a
-> (a -> ExitCase b -> Energy m c)
-> (a -> Energy m b)
-> Energy m (b, c)
uninterruptibleMask :: ((forall a. Energy m a -> Energy m a) -> Energy m b) -> Energy m b
$cuninterruptibleMask :: forall (m :: * -> *) b.
MonadMask m =>
((forall a. Energy m a -> Energy m a) -> Energy m b) -> Energy m b
mask :: ((forall a. Energy m a -> Energy m a) -> Energy m b) -> Energy m b
$cmask :: forall (m :: * -> *) b.
MonadMask m =>
((forall a. Energy m a -> Energy m a) -> Energy m b) -> Energy m b
$cp1MonadMask :: forall (m :: * -> *). MonadMask m => MonadCatch (Energy m)
MonadMask, MonadReader EnergyEnv,
Monad (Energy m)
Monad (Energy m)
-> (forall a. String -> Energy m a) -> MonadFail (Energy m)
String -> Energy m a
forall a. String -> Energy m a
forall (m :: * -> *).
Monad m -> (forall a. String -> m a) -> MonadFail m
forall (m :: * -> *). MonadFail m => Monad (Energy m)
forall (m :: * -> *) a. MonadFail m => String -> Energy m a
fail :: String -> Energy m a
$cfail :: forall (m :: * -> *) a. MonadFail m => String -> Energy m a
$cp1MonadFail :: forall (m :: * -> *). MonadFail m => Monad (Energy m)
MonadFail, Monad (Energy m)
Monad (Energy m)
-> (forall msg.
ToLogStr msg =>
Loc -> LogSource -> LogLevel -> msg -> Energy m ())
-> MonadLogger (Energy m)
Loc -> LogSource -> LogLevel -> msg -> Energy m ()
forall msg.
ToLogStr msg =>
Loc -> LogSource -> LogLevel -> msg -> Energy m ()
forall (m :: * -> *).
Monad m
-> (forall msg.
ToLogStr msg =>
Loc -> LogSource -> LogLevel -> msg -> m ())
-> MonadLogger m
forall (m :: * -> *). MonadLogger m => Monad (Energy m)
forall (m :: * -> *) msg.
(MonadLogger m, ToLogStr msg) =>
Loc -> LogSource -> LogLevel -> msg -> Energy m ()
monadLoggerLog :: Loc -> LogSource -> LogLevel -> msg -> Energy m ()
$cmonadLoggerLog :: forall (m :: * -> *) msg.
(MonadLogger m, ToLogStr msg) =>
Loc -> LogSource -> LogLevel -> msg -> Energy m ()
$cp1MonadLogger :: forall (m :: * -> *). MonadLogger m => Monad (Energy m)
MonadLogger)
instance MonadUnliftIO m => MonadUnliftIO (Energy m) where
withRunInIO :: ((forall a. Energy m a -> IO a) -> IO b) -> Energy m b
withRunInIO (forall a. Energy m a -> IO a) -> IO b
inner = ReaderT EnergyEnv m b -> Energy m b
forall (m :: * -> *) a. ReaderT EnergyEnv m a -> Energy m a
Energy (ReaderT EnergyEnv m b -> Energy m b)
-> ReaderT EnergyEnv m b -> Energy m b
forall a b. (a -> b) -> a -> b
$ ((forall a. ReaderT EnergyEnv m a -> IO a) -> IO b)
-> ReaderT EnergyEnv m b
forall (m :: * -> *) b.
MonadUnliftIO m =>
((forall a. m a -> IO a) -> IO b) -> m b
withRunInIO (((forall a. ReaderT EnergyEnv m a -> IO a) -> IO b)
-> ReaderT EnergyEnv m b)
-> ((forall a. ReaderT EnergyEnv m a -> IO a) -> IO b)
-> ReaderT EnergyEnv m b
forall a b. (a -> b) -> a -> b
$ \forall a. ReaderT EnergyEnv m a -> IO a
run -> (forall a. Energy m a -> IO a) -> IO b
inner (ReaderT EnergyEnv m a -> IO a
forall a. ReaderT EnergyEnv m a -> IO a
run (ReaderT EnergyEnv m a -> IO a)
-> (Energy m a -> ReaderT EnergyEnv m a) -> Energy m a -> IO a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Energy m a -> ReaderT EnergyEnv m a
forall (m :: * -> *) a. Energy m a -> ReaderT EnergyEnv m a
runEnergyM)
instance (Monad m, MonadIO m, MonadReader EnergyEnv m) => HasTeslaAuth m where
teslaAuth :: m AuthInfo
teslaAuth = IO AuthInfo -> m AuthInfo
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO AuthInfo -> m AuthInfo) -> m (IO AuthInfo) -> m AuthInfo
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< (EnergyEnv -> IO AuthInfo) -> m (IO AuthInfo)
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks EnergyEnv -> IO AuthInfo
_authInfo
runEnergy :: MonadIO m => IO AuthInfo -> EnergyID -> Energy m a -> m a
runEnergy :: IO AuthInfo -> EnergyID -> Energy m a -> m a
runEnergy IO AuthInfo
ai EnergyID
ei Energy m a
f = ReaderT EnergyEnv m a -> EnergyEnv -> m a
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT (Energy m a -> ReaderT EnergyEnv m a
forall (m :: * -> *) a. Energy m a -> ReaderT EnergyEnv m a
runEnergyM Energy m a
f) (IO AuthInfo -> EnergyID -> EnergyEnv
EnergyEnv IO AuthInfo
ai EnergyID
ei)
newtype BadEnergyException = BadEnergy String deriving BadEnergyException -> BadEnergyException -> Bool
(BadEnergyException -> BadEnergyException -> Bool)
-> (BadEnergyException -> BadEnergyException -> Bool)
-> Eq BadEnergyException
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: BadEnergyException -> BadEnergyException -> Bool
$c/= :: BadEnergyException -> BadEnergyException -> Bool
== :: BadEnergyException -> BadEnergyException -> Bool
$c== :: BadEnergyException -> BadEnergyException -> Bool
Eq
instance Show BadEnergyException where
show :: BadEnergyException -> String
show (BadEnergy String
s) = String
"BadEnergy: " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
s
instance Exception BadEnergyException
siteData :: (FromJSON j, MonadIO m) => Energy m j
siteData :: Energy m j
siteData = Energy m EnergyID
forall (m :: * -> *). Monad m => Energy m EnergyID
currentEnergyID Energy m EnergyID -> (EnergyID -> Energy m j) -> Energy m j
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \EnergyID
e -> String -> Energy m j
forall (m :: * -> *) j.
(HasTeslaAuth m, FromJSON j, MonadIO m) =>
String -> m j
jgetAuth (EnergyID -> String -> String
energyURL EnergyID
e String
"live_status")
siteConfig :: (FromJSON j, MonadIO m) => Energy m j
siteConfig :: Energy m j
siteConfig = Energy m EnergyID
forall (m :: * -> *). Monad m => Energy m EnergyID
currentEnergyID Energy m EnergyID -> (EnergyID -> Energy m j) -> Energy m j
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \EnergyID
e -> String -> Energy m j
forall (m :: * -> *) j.
(HasTeslaAuth m, FromJSON j, MonadIO m) =>
String -> m j
jgetAuth (EnergyID -> String -> String
energyURL EnergyID
e String
"site_info")