diff --git a/src/Tesla.hs b/src/Tesla.hs
--- a/src/Tesla.hs
+++ b/src/Tesla.hs
@@ -14,8 +14,9 @@
 module Tesla
     ( authenticate, refreshAuth, AuthResponse(..),
       Product(..), vehicleName, vehicleID, vehicleState,
-      energyID, _ProductVehicle, _ProductEnergy, _ProductPowerWall,
-      VehicleID, vehicles, products,
+      energyID, _ProductVehicle, _ProductEnergy, _ProductPowerwall,
+      pwBatteryPower, pwCharged, pwEnergyLeft, pwID, pwName, pwTotal,
+      VehicleID, vehicles, products, productsRaw,
       VehicleState(..), vsFromString,
       EnergyID, energyIDs,
       fromToken, authOpts, baseURL,
@@ -29,8 +30,8 @@
 import           Control.Monad.IO.Class     (MonadIO (..))
 import           Control.Retry              (defaultLogMsg, exponentialBackoff, limitRetries, logRetries, recovering)
 import           Crypto.Hash                (SHA256 (..), hashWith)
-import           Data.Aeson                 (Value (..), encode)
-import           Data.Aeson.Lens            (_Array, _Integer, _String, key)
+import           Data.Aeson                 (FromJSON, Value (..), encode)
+import           Data.Aeson.Lens            (_Array, _Integer, _Double, _String, key)
 import qualified Data.ByteArray             as BA
 import qualified Data.ByteString            as BS
 import qualified Data.ByteString.Base64.URL as B64
@@ -65,7 +66,7 @@
 
 -- | Authenticate to the Tesla service.
 authenticate :: AuthInfo -> IO AuthResponse
-authenticate ai@AuthInfo{..} = recovering policy [retryOnAnyStatus] $ \_ -> do
+authenticate ai = recovering policy [retryOnAnyStatus] $ \_ -> do
   sess <- Sess.newSession
   verifier <- BS.pack . take 86 . randoms <$> getStdGen
   state <- clean64 . BS.pack . take 16 . randoms <$> getStdGen
@@ -138,7 +139,7 @@
 
 -- | Refresh authentication credentials using a refresh token.
 refreshAuth :: AuthInfo -> AuthResponse -> IO AuthResponse
-refreshAuth ai@AuthInfo{..} AuthResponse{..} = do
+refreshAuth ai AuthResponse{..} = do
   ar <- jpostWith jOpts authRefreshURL (encode $ Object (mempty
                                                          & at "grant_type" ?~ "refresh_token"
                                                          & at "client_id" ?~ "ownerapi"
@@ -173,25 +174,43 @@
 -- | Tesla Product Types.
 data Product = ProductVehicle { _vehicleName :: Text, _vehicleID :: VehicleID, _vehicleState :: VehicleState }
              | ProductEnergy { _energyID :: EnergyID }
-             | ProductPowerWall deriving (Show, Read, Eq)
+             | ProductPowerwall { _pwID :: EnergyID
+                                , _pwBatteryPower :: Double
+                                , _pwEnergyLeft :: Double
+                                , _pwCharged :: Double
+                                , _pwName :: Text
+                                , _pwTotal :: Double }
+             deriving (Show, Read, Eq)
 
 makePrisms ''Product
 makeLenses ''Product
 
+-- | Decode a products response into a list of products.
 decodeProducts :: Value -> [Product]
 decodeProducts = catMaybes . toListOf (key "response" . _Array . folded . to prod)
   where
-    prod o = asum [ prodCar, prodSolar, Nothing ]
+    prod o = asum [ prodCar, prodPowerwall, prodSolar, Nothing ]
       where
         prodCar = ProductVehicle
                   <$> (o ^? key "display_name" . _String)
                   <*> (o ^? key "id_s" . _String)
                   <*> (o ^? key "state" . _String . to vsFromString)
+        prodPowerwall = ProductPowerwall
+                        <$> (o ^? key "energy_site_id" . _Integer)
+                        <*> (o ^? key "battery_power" . _Double)
+                        <*> (o ^? key "energy_left" . _Double)
+                        <*> (o ^? key "percentage_charged" . _Double)
+                        <*> (o ^? key "site_name" . _String)
+                        <*> (o ^? key "total_pack_energy" . _Double)
         prodSolar = ProductEnergy <$> (o ^? key "energy_site_id" . _Integer)
 
+-- | productsRaw retrieves the complete response for products
+productsRaw :: (FromJSON j, MonadIO m) => AuthInfo -> m j
+productsRaw ai = jgetWith (authOpts ai) productsURL
+
 -- | Get all products associated with this account.
 products :: MonadIO m => AuthInfo -> m [Product]
-products ai = decodeProducts <$> jgetWith (authOpts ai) productsURL
+products = fmap decodeProducts . productsRaw
 
 -- | Get a mapping of vehicle name to vehicle ID.
 vehicles :: [Product] -> Map Text Text
diff --git a/tesla.cabal b/tesla.cabal
--- a/tesla.cabal
+++ b/tesla.cabal
@@ -4,10 +4,10 @@
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: 24dfc3529bdcf280c4391d9a54fb35f858c54887d78fd748fb93b47ef664b88d
+-- hash: bf7a08cf5b63908e03980d6150b12d2c3ebb9a1e48e9c9d73adf71469d7fb698
 
 name:           tesla
-version:        0.4.0.0
+version:        0.4.1.0
 synopsis:       Tesla API client.
 description:    Please see the README on GitHub at <https://github.com/dustin/tesla#readme>
 category:       Web
diff --git a/test/Spec.hs b/test/Spec.hs
--- a/test/Spec.hs
+++ b/test/Spec.hs
@@ -43,7 +43,7 @@
 testParseProducts :: Assertion
 testParseProducts = do
   let prods = decodeProducts sampleProducts
-  assertEqual "products" [ProductVehicle "MyCar" "848528", ProductEnergy 2848535] prods
+  assertEqual "products" [ProductVehicle "MyCar" "848528" VOnline, ProductEnergy 2848535] prods
   assertEqual "vehicles" (Map.fromList [("MyCar", "848528")]) $ vehicles prods
   assertEqual "energy" [2848535] $ energyIDs prods
 
