{-# 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 = forall a. Monoid a => [a] -> a
mconcat [String
baseURL, String
"api/1/energy_sites/", 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 :: forall (m :: * -> *). Monad m => Energy m EnergyID
currentEnergyID = forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks EnergyEnv -> EnergyID
_eid
newtype Energy m a = Energy { forall (m :: * -> *) a. Energy m a -> ReaderT EnergyEnv m a
runEnergyM :: ReaderT EnergyEnv m a }
deriving (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
<* :: forall a b. 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
*> :: forall a b. 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 :: forall a b c.
(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
<*> :: forall a b. 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 :: forall a. a -> Energy m a
$cpure :: forall (m :: * -> *) a. Applicative m => a -> Energy m a
Applicative, 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
<$ :: forall a b. a -> Energy m b -> Energy m a
$c<$ :: forall (m :: * -> *) a b.
Functor m =>
a -> Energy m b -> Energy m a
fmap :: forall a b. (a -> b) -> Energy m a -> Energy m b
$cfmap :: forall (m :: * -> *) a b.
Functor m =>
(a -> b) -> Energy m a -> Energy m b
Functor, 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 :: forall a. a -> Energy m a
$creturn :: forall (m :: * -> *) a. Monad m => a -> Energy m a
>> :: forall a b. 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
>>= :: forall a 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
Monad, 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 :: forall a. IO a -> Energy m a
$cliftIO :: forall (m :: * -> *) a. MonadIO m => IO a -> Energy m a
MonadIO,
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 :: forall e a.
Exception e =>
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
MonadCatch, 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 :: forall e a. Exception e => e -> Energy m a
$cthrowM :: forall (m :: * -> *) e a.
(MonadThrow m, Exception e) =>
e -> Energy m a
MonadThrow, 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 :: * -> *}. 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)
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
generalBracket :: forall a b c.
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 b.
((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 b.
((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
MonadMask, MonadReader EnergyEnv,
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 :: forall a. String -> Energy m a
$cfail :: forall (m :: * -> *) a. MonadFail m => String -> Energy m a
MonadFail, 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 :: forall msg.
ToLogStr msg =>
Loc -> LogSource -> LogLevel -> msg -> Energy m ()
$cmonadLoggerLog :: forall (m :: * -> *) msg.
(MonadLogger m, ToLogStr msg) =>
Loc -> LogSource -> LogLevel -> msg -> Energy m ()
MonadLogger)
instance MonadUnliftIO m => MonadUnliftIO (Energy m) where
withRunInIO :: forall b. ((forall a. Energy m a -> IO a) -> IO b) -> Energy m b
withRunInIO (forall a. Energy m a -> IO a) -> IO b
inner = forall (m :: * -> *) a. ReaderT EnergyEnv m a -> Energy m a
Energy forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) b.
MonadUnliftIO m =>
((forall a. m a -> IO a) -> IO b) -> m b
withRunInIO 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 (forall a. ReaderT EnergyEnv m a -> IO a
run forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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 = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< 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 :: forall (m :: * -> *) a.
MonadIO m =>
IO AuthInfo -> EnergyID -> Energy m a -> m a
runEnergy IO AuthInfo
ai EnergyID
ei Energy m a
f = forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT (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
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: " forall a. Semigroup a => a -> a -> a
<> String
s
instance Exception BadEnergyException
siteData :: (FromJSON j, MonadIO m) => Energy m j
siteData :: forall j (m :: * -> *). (FromJSON j, MonadIO m) => Energy m j
siteData = forall (m :: * -> *). Monad m => Energy m EnergyID
currentEnergyID forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \EnergyID
e -> 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 :: forall j (m :: * -> *). (FromJSON j, MonadIO m) => Energy m j
siteConfig = forall (m :: * -> *). Monad m => Energy m EnergyID
currentEnergyID forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \EnergyID
e -> forall (m :: * -> *) j.
(HasTeslaAuth m, FromJSON j, MonadIO m) =>
String -> m j
jgetAuth (EnergyID -> String -> String
energyURL EnergyID
e String
"site_info")