diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
 # Revision history for lifx-lan
 
+## 0.5.1 -- 2021-12-12
+- Implement `getProductInfo`.
+- Expose `LifxT` constructor.
+
 ## 0.5.0 -- 2021-08-01
 - Fix bug which was causing broadcasting not to work with messages that expect no response.
 
diff --git a/lifx-lan.cabal b/lifx-lan.cabal
--- a/lifx-lan.cabal
+++ b/lifx-lan.cabal
@@ -1,6 +1,6 @@
 cabal-version:      3.0
 name:               lifx-lan
-version:            0.5.0.1
+version:            0.5.1
 license:            BSD-3-Clause
 license-file:       LICENSE
 author:             George Thomas
@@ -16,14 +16,16 @@
 
 library
     exposed-modules:
+        Lifx.Internal.Product
+        Lifx.Internal.ProductInfo
         Lifx.Lan
     hs-source-dirs: src
     ghc-options:
         -Wall
     build-depends:
-        base ^>= 4.14,
+        base ^>= {4.14, 4.15, 4.16},
         binary ^>= 0.8.8,
-        bytestring ^>= 0.10.8,
+        bytestring ^>= {0.10.8, 0.11},
         composition ^>= 1.0.2.1,
         containers ^>= 0.6.2.1,
         extra ^>= 1.7.1,
@@ -33,8 +35,8 @@
         random ^>= 1.2.0,
         safe ^>= 0.3.19,
         text ^>= 1.2.3,
-        time ^>= 1.9.3,
-        transformers ^>= 0.5.6,
+        time ^>= {1.9.3, 1.10, 1.11, 1.12, 1.13},
+        transformers ^>= {0.5.6, 0.6},
     default-language: Haskell2010
     default-extensions:
         AllowAmbiguousTypes
diff --git a/src/Lifx/Internal/Product.hs b/src/Lifx/Internal/Product.hs
new file mode 100644
--- /dev/null
+++ b/src/Lifx/Internal/Product.hs
@@ -0,0 +1,56 @@
+-- | An exact mapping of the types in LIFX's `products.json`. It's easier to just use 'Lifx.Lan.getProductInfo'.
+module Lifx.Internal.Product where
+
+import Data.Text (Text)
+import Data.Word (Word16, Word32)
+
+data VendorInfo = VendorInfo
+    { vid :: Word32
+    , name :: Text
+    , defaults :: Features
+    , products :: [ProductInfo]
+    }
+    deriving (Show)
+
+data ProductInfo = ProductInfo
+    { pid :: Word32
+    , name :: Text
+    , features :: PartialFeatures
+    , upgrades :: [Upgrade]
+    }
+    deriving (Show)
+
+data PartialFeatures = PartialFeatures
+    { hev :: Maybe Bool
+    , color :: Maybe Bool
+    , chain :: Maybe Bool
+    , matrix :: Maybe Bool
+    , relays :: Maybe Bool
+    , buttons :: Maybe Bool
+    , infrared :: Maybe Bool
+    , multizone :: Maybe Bool
+    , temperatureRange :: Maybe (Word16, Word16)
+    , extendedMultizone :: Maybe Bool
+    }
+    deriving (Show)
+
+data Features = Features
+    { hev :: Bool
+    , color :: Bool
+    , chain :: Bool
+    , matrix :: Bool
+    , relays :: Bool
+    , buttons :: Bool
+    , infrared :: Bool
+    , multizone :: Bool
+    , temperatureRange :: Maybe (Word16, Word16)
+    , extendedMultizone :: Bool
+    }
+    deriving (Show)
+
+data Upgrade = Upgrade
+    { major :: Word16
+    , minor :: Word16
+    , features :: PartialFeatures
+    }
+    deriving (Show)
diff --git a/src/Lifx/Internal/ProductInfo.hs b/src/Lifx/Internal/ProductInfo.hs
new file mode 100644
--- /dev/null
+++ b/src/Lifx/Internal/ProductInfo.hs
@@ -0,0 +1,1669 @@
+-- | This is auto-generated - see the "product-gen" script.
+module Lifx.Internal.ProductInfo where
+
+import Lifx.Internal.Product
+
+productInfo :: [VendorInfo]
+productInfo =
+    [ VendorInfo
+        { vid = 1
+        , name = "LIFX"
+        , defaults = Features
+            { hev = False
+            , color = False
+            , chain = False
+            , matrix = False
+            , relays = False
+            , buttons = False
+            , infrared = False
+            , multizone = False
+            , temperatureRange = Nothing
+            , extendedMultizone = False
+            }
+        , products =
+            [ ProductInfo
+                { pid = 1
+                , name = "LIFX Original 1000"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just True
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just False
+                    , multizone = Just False
+                    , temperatureRange = Just
+                        ( 2500
+                        , 9000
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades = []
+                }
+            , ProductInfo
+                { pid = 3
+                , name = "LIFX Color 650"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just True
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just False
+                    , multizone = Just False
+                    , temperatureRange = Just
+                        ( 2500
+                        , 9000
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades = []
+                }
+            , ProductInfo
+                { pid = 10
+                , name = "LIFX White 800 (Low Voltage)"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just False
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just False
+                    , multizone = Just False
+                    , temperatureRange = Just
+                        ( 2700
+                        , 6500
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades = []
+                }
+            , ProductInfo
+                { pid = 11
+                , name = "LIFX White 800 (High Voltage)"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just False
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just False
+                    , multizone = Just False
+                    , temperatureRange = Just
+                        ( 2700
+                        , 6500
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades = []
+                }
+            , ProductInfo
+                { pid = 15
+                , name = "LIFX Color 1000"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just True
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just False
+                    , multizone = Just False
+                    , temperatureRange = Just
+                        ( 2500
+                        , 9000
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades = []
+                }
+            , ProductInfo
+                { pid = 18
+                , name = "LIFX White 900 BR30 (Low Voltage)"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just False
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just False
+                    , multizone = Just False
+                    , temperatureRange = Just
+                        ( 2500
+                        , 9000
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades = []
+                }
+            , ProductInfo
+                { pid = 19
+                , name = "LIFX White 900 BR30 (High Voltage)"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just False
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just False
+                    , multizone = Just False
+                    , temperatureRange = Just
+                        ( 2500
+                        , 9000
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades = []
+                }
+            , ProductInfo
+                { pid = 20
+                , name = "LIFX Color 1000 BR30"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just True
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just False
+                    , multizone = Just False
+                    , temperatureRange = Just
+                        ( 2500
+                        , 9000
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades = []
+                }
+            , ProductInfo
+                { pid = 22
+                , name = "LIFX Color 1000"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just True
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just False
+                    , multizone = Just False
+                    , temperatureRange = Just
+                        ( 2500
+                        , 9000
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades = []
+                }
+            , ProductInfo
+                { pid = 27
+                , name = "LIFX A19"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just True
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just False
+                    , multizone = Just False
+                    , temperatureRange = Just
+                        ( 2500
+                        , 9000
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades =
+                    [ Upgrade
+                        { major = 2
+                        , minor = 80
+                        , features = PartialFeatures
+                            { hev = Nothing
+                            , color = Nothing
+                            , chain = Nothing
+                            , matrix = Nothing
+                            , relays = Nothing
+                            , buttons = Nothing
+                            , infrared = Nothing
+                            , multizone = Nothing
+                            , temperatureRange = Just
+                                ( 1500
+                                , 9000
+                                )
+                            , extendedMultizone = Nothing
+                            }
+                        }
+                    ]
+                }
+            , ProductInfo
+                { pid = 28
+                , name = "LIFX BR30"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just True
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just False
+                    , multizone = Just False
+                    , temperatureRange = Just
+                        ( 2500
+                        , 9000
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades =
+                    [ Upgrade
+                        { major = 2
+                        , minor = 80
+                        , features = PartialFeatures
+                            { hev = Nothing
+                            , color = Nothing
+                            , chain = Nothing
+                            , matrix = Nothing
+                            , relays = Nothing
+                            , buttons = Nothing
+                            , infrared = Nothing
+                            , multizone = Nothing
+                            , temperatureRange = Just
+                                ( 1500
+                                , 9000
+                                )
+                            , extendedMultizone = Nothing
+                            }
+                        }
+                    ]
+                }
+            , ProductInfo
+                { pid = 29
+                , name = "LIFX A19 Night Vision"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just True
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just True
+                    , multizone = Just False
+                    , temperatureRange = Just
+                        ( 2500
+                        , 9000
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades =
+                    [ Upgrade
+                        { major = 2
+                        , minor = 80
+                        , features = PartialFeatures
+                            { hev = Nothing
+                            , color = Nothing
+                            , chain = Nothing
+                            , matrix = Nothing
+                            , relays = Nothing
+                            , buttons = Nothing
+                            , infrared = Nothing
+                            , multizone = Nothing
+                            , temperatureRange = Just
+                                ( 1500
+                                , 9000
+                                )
+                            , extendedMultizone = Nothing
+                            }
+                        }
+                    ]
+                }
+            , ProductInfo
+                { pid = 30
+                , name = "LIFX BR30 Night Vision"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just True
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just True
+                    , multizone = Just False
+                    , temperatureRange = Just
+                        ( 2500
+                        , 9000
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades =
+                    [ Upgrade
+                        { major = 2
+                        , minor = 80
+                        , features = PartialFeatures
+                            { hev = Nothing
+                            , color = Nothing
+                            , chain = Nothing
+                            , matrix = Nothing
+                            , relays = Nothing
+                            , buttons = Nothing
+                            , infrared = Nothing
+                            , multizone = Nothing
+                            , temperatureRange = Just
+                                ( 1500
+                                , 9000
+                                )
+                            , extendedMultizone = Nothing
+                            }
+                        }
+                    ]
+                }
+            , ProductInfo
+                { pid = 31
+                , name = "LIFX Z"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just True
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just False
+                    , multizone = Just True
+                    , temperatureRange = Just
+                        ( 2500
+                        , 9000
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades = []
+                }
+            , ProductInfo
+                { pid = 32
+                , name = "LIFX Z"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just True
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just False
+                    , multizone = Just True
+                    , temperatureRange = Just
+                        ( 2500
+                        , 9000
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades =
+                    [ Upgrade
+                        { major = 2
+                        , minor = 77
+                        , features = PartialFeatures
+                            { hev = Nothing
+                            , color = Nothing
+                            , chain = Nothing
+                            , matrix = Nothing
+                            , relays = Nothing
+                            , buttons = Nothing
+                            , infrared = Nothing
+                            , multizone = Nothing
+                            , temperatureRange = Nothing
+                            , extendedMultizone = Just True
+                            }
+                        }
+                    , Upgrade
+                        { major = 2
+                        , minor = 80
+                        , features = PartialFeatures
+                            { hev = Nothing
+                            , color = Nothing
+                            , chain = Nothing
+                            , matrix = Nothing
+                            , relays = Nothing
+                            , buttons = Nothing
+                            , infrared = Nothing
+                            , multizone = Nothing
+                            , temperatureRange = Just
+                                ( 1500
+                                , 9000
+                                )
+                            , extendedMultizone = Nothing
+                            }
+                        }
+                    ]
+                }
+            , ProductInfo
+                { pid = 36
+                , name = "LIFX Downlight"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just True
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just False
+                    , multizone = Just False
+                    , temperatureRange = Just
+                        ( 2500
+                        , 9000
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades =
+                    [ Upgrade
+                        { major = 2
+                        , minor = 80
+                        , features = PartialFeatures
+                            { hev = Nothing
+                            , color = Nothing
+                            , chain = Nothing
+                            , matrix = Nothing
+                            , relays = Nothing
+                            , buttons = Nothing
+                            , infrared = Nothing
+                            , multizone = Nothing
+                            , temperatureRange = Just
+                                ( 1500
+                                , 9000
+                                )
+                            , extendedMultizone = Nothing
+                            }
+                        }
+                    ]
+                }
+            , ProductInfo
+                { pid = 37
+                , name = "LIFX Downlight"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just True
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just False
+                    , multizone = Just False
+                    , temperatureRange = Just
+                        ( 2500
+                        , 9000
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades =
+                    [ Upgrade
+                        { major = 2
+                        , minor = 80
+                        , features = PartialFeatures
+                            { hev = Nothing
+                            , color = Nothing
+                            , chain = Nothing
+                            , matrix = Nothing
+                            , relays = Nothing
+                            , buttons = Nothing
+                            , infrared = Nothing
+                            , multizone = Nothing
+                            , temperatureRange = Just
+                                ( 1500
+                                , 9000
+                                )
+                            , extendedMultizone = Nothing
+                            }
+                        }
+                    ]
+                }
+            , ProductInfo
+                { pid = 38
+                , name = "LIFX Beam"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just True
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just False
+                    , multizone = Just True
+                    , temperatureRange = Just
+                        ( 2500
+                        , 9000
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades =
+                    [ Upgrade
+                        { major = 2
+                        , minor = 77
+                        , features = PartialFeatures
+                            { hev = Nothing
+                            , color = Nothing
+                            , chain = Nothing
+                            , matrix = Nothing
+                            , relays = Nothing
+                            , buttons = Nothing
+                            , infrared = Nothing
+                            , multizone = Nothing
+                            , temperatureRange = Nothing
+                            , extendedMultizone = Just True
+                            }
+                        }
+                    , Upgrade
+                        { major = 2
+                        , minor = 80
+                        , features = PartialFeatures
+                            { hev = Nothing
+                            , color = Nothing
+                            , chain = Nothing
+                            , matrix = Nothing
+                            , relays = Nothing
+                            , buttons = Nothing
+                            , infrared = Nothing
+                            , multizone = Nothing
+                            , temperatureRange = Just
+                                ( 1500
+                                , 9000
+                                )
+                            , extendedMultizone = Nothing
+                            }
+                        }
+                    ]
+                }
+            , ProductInfo
+                { pid = 39
+                , name = "LIFX Downlight White to Warm"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just False
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just False
+                    , multizone = Just False
+                    , temperatureRange = Just
+                        ( 2500
+                        , 9000
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades =
+                    [ Upgrade
+                        { major = 2
+                        , minor = 80
+                        , features = PartialFeatures
+                            { hev = Nothing
+                            , color = Nothing
+                            , chain = Nothing
+                            , matrix = Nothing
+                            , relays = Nothing
+                            , buttons = Nothing
+                            , infrared = Nothing
+                            , multizone = Nothing
+                            , temperatureRange = Just
+                                ( 1500
+                                , 9000
+                                )
+                            , extendedMultizone = Nothing
+                            }
+                        }
+                    ]
+                }
+            , ProductInfo
+                { pid = 40
+                , name = "LIFX Downlight"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just True
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just False
+                    , multizone = Just False
+                    , temperatureRange = Just
+                        ( 2500
+                        , 9000
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades =
+                    [ Upgrade
+                        { major = 2
+                        , minor = 80
+                        , features = PartialFeatures
+                            { hev = Nothing
+                            , color = Nothing
+                            , chain = Nothing
+                            , matrix = Nothing
+                            , relays = Nothing
+                            , buttons = Nothing
+                            , infrared = Nothing
+                            , multizone = Nothing
+                            , temperatureRange = Just
+                                ( 1500
+                                , 9000
+                                )
+                            , extendedMultizone = Nothing
+                            }
+                        }
+                    ]
+                }
+            , ProductInfo
+                { pid = 43
+                , name = "LIFX A19"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just True
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just False
+                    , multizone = Just False
+                    , temperatureRange = Just
+                        ( 2500
+                        , 9000
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades =
+                    [ Upgrade
+                        { major = 2
+                        , minor = 80
+                        , features = PartialFeatures
+                            { hev = Nothing
+                            , color = Nothing
+                            , chain = Nothing
+                            , matrix = Nothing
+                            , relays = Nothing
+                            , buttons = Nothing
+                            , infrared = Nothing
+                            , multizone = Nothing
+                            , temperatureRange = Just
+                                ( 1500
+                                , 9000
+                                )
+                            , extendedMultizone = Nothing
+                            }
+                        }
+                    ]
+                }
+            , ProductInfo
+                { pid = 44
+                , name = "LIFX BR30"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just True
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just False
+                    , multizone = Just False
+                    , temperatureRange = Just
+                        ( 2500
+                        , 9000
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades =
+                    [ Upgrade
+                        { major = 2
+                        , minor = 80
+                        , features = PartialFeatures
+                            { hev = Nothing
+                            , color = Nothing
+                            , chain = Nothing
+                            , matrix = Nothing
+                            , relays = Nothing
+                            , buttons = Nothing
+                            , infrared = Nothing
+                            , multizone = Nothing
+                            , temperatureRange = Just
+                                ( 1500
+                                , 9000
+                                )
+                            , extendedMultizone = Nothing
+                            }
+                        }
+                    ]
+                }
+            , ProductInfo
+                { pid = 45
+                , name = "LIFX A19 Night Vision"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just True
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just True
+                    , multizone = Just False
+                    , temperatureRange = Just
+                        ( 2500
+                        , 9000
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades =
+                    [ Upgrade
+                        { major = 2
+                        , minor = 80
+                        , features = PartialFeatures
+                            { hev = Nothing
+                            , color = Nothing
+                            , chain = Nothing
+                            , matrix = Nothing
+                            , relays = Nothing
+                            , buttons = Nothing
+                            , infrared = Nothing
+                            , multizone = Nothing
+                            , temperatureRange = Just
+                                ( 1500
+                                , 9000
+                                )
+                            , extendedMultizone = Nothing
+                            }
+                        }
+                    ]
+                }
+            , ProductInfo
+                { pid = 46
+                , name = "LIFX BR30 Night Vision"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just True
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just True
+                    , multizone = Just False
+                    , temperatureRange = Just
+                        ( 2500
+                        , 9000
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades =
+                    [ Upgrade
+                        { major = 2
+                        , minor = 80
+                        , features = PartialFeatures
+                            { hev = Nothing
+                            , color = Nothing
+                            , chain = Nothing
+                            , matrix = Nothing
+                            , relays = Nothing
+                            , buttons = Nothing
+                            , infrared = Nothing
+                            , multizone = Nothing
+                            , temperatureRange = Just
+                                ( 1500
+                                , 9000
+                                )
+                            , extendedMultizone = Nothing
+                            }
+                        }
+                    ]
+                }
+            , ProductInfo
+                { pid = 49
+                , name = "LIFX Mini Color"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just True
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just False
+                    , multizone = Just False
+                    , temperatureRange = Just
+                        ( 1500
+                        , 9000
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades = []
+                }
+            , ProductInfo
+                { pid = 50
+                , name = "LIFX Mini White to Warm"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just False
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just False
+                    , multizone = Just False
+                    , temperatureRange = Just
+                        ( 1500
+                        , 6500
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades =
+                    [ Upgrade
+                        { major = 3
+                        , minor = 70
+                        , features = PartialFeatures
+                            { hev = Nothing
+                            , color = Nothing
+                            , chain = Nothing
+                            , matrix = Nothing
+                            , relays = Nothing
+                            , buttons = Nothing
+                            , infrared = Nothing
+                            , multizone = Nothing
+                            , temperatureRange = Just
+                                ( 1500
+                                , 9000
+                                )
+                            , extendedMultizone = Nothing
+                            }
+                        }
+                    ]
+                }
+            , ProductInfo
+                { pid = 51
+                , name = "LIFX Mini White"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just False
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just False
+                    , multizone = Just False
+                    , temperatureRange = Just
+                        ( 2700
+                        , 2700
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades = []
+                }
+            , ProductInfo
+                { pid = 52
+                , name = "LIFX GU10"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just True
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just False
+                    , multizone = Just False
+                    , temperatureRange = Just
+                        ( 1500
+                        , 9000
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades = []
+                }
+            , ProductInfo
+                { pid = 53
+                , name = "LIFX GU10"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just True
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just False
+                    , multizone = Just False
+                    , temperatureRange = Just
+                        ( 1500
+                        , 9000
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades = []
+                }
+            , ProductInfo
+                { pid = 55
+                , name = "LIFX Tile"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just True
+                    , chain = Just True
+                    , matrix = Just True
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just False
+                    , multizone = Just False
+                    , temperatureRange = Just
+                        ( 2500
+                        , 9000
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades = []
+                }
+            , ProductInfo
+                { pid = 57
+                , name = "LIFX Candle"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just True
+                    , chain = Just False
+                    , matrix = Just True
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just False
+                    , multizone = Just False
+                    , temperatureRange = Just
+                        ( 1500
+                        , 9000
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades = []
+                }
+            , ProductInfo
+                { pid = 59
+                , name = "LIFX Mini Color"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just True
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just False
+                    , multizone = Just False
+                    , temperatureRange = Just
+                        ( 1500
+                        , 9000
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades = []
+                }
+            , ProductInfo
+                { pid = 60
+                , name = "LIFX Mini White to Warm"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just False
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just False
+                    , multizone = Just False
+                    , temperatureRange = Just
+                        ( 1500
+                        , 6500
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades =
+                    [ Upgrade
+                        { major = 3
+                        , minor = 70
+                        , features = PartialFeatures
+                            { hev = Nothing
+                            , color = Nothing
+                            , chain = Nothing
+                            , matrix = Nothing
+                            , relays = Nothing
+                            , buttons = Nothing
+                            , infrared = Nothing
+                            , multizone = Nothing
+                            , temperatureRange = Just
+                                ( 1500
+                                , 9000
+                                )
+                            , extendedMultizone = Nothing
+                            }
+                        }
+                    ]
+                }
+            , ProductInfo
+                { pid = 61
+                , name = "LIFX Mini White"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just False
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just False
+                    , multizone = Just False
+                    , temperatureRange = Just
+                        ( 2700
+                        , 2700
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades = []
+                }
+            , ProductInfo
+                { pid = 62
+                , name = "LIFX A19"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just True
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just False
+                    , multizone = Just False
+                    , temperatureRange = Just
+                        ( 1500
+                        , 9000
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades = []
+                }
+            , ProductInfo
+                { pid = 63
+                , name = "LIFX BR30"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just True
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just False
+                    , multizone = Just False
+                    , temperatureRange = Just
+                        ( 1500
+                        , 9000
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades = []
+                }
+            , ProductInfo
+                { pid = 64
+                , name = "LIFX A19 Night Vision"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just True
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just True
+                    , multizone = Just False
+                    , temperatureRange = Just
+                        ( 1500
+                        , 9000
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades = []
+                }
+            , ProductInfo
+                { pid = 65
+                , name = "LIFX BR30 Night Vision"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just True
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just True
+                    , multizone = Just False
+                    , temperatureRange = Just
+                        ( 1500
+                        , 9000
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades = []
+                }
+            , ProductInfo
+                { pid = 66
+                , name = "LIFX Mini White"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just False
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just False
+                    , multizone = Just False
+                    , temperatureRange = Just
+                        ( 2700
+                        , 2700
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades = []
+                }
+            , ProductInfo
+                { pid = 68
+                , name = "LIFX Candle"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just True
+                    , chain = Just False
+                    , matrix = Just True
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just False
+                    , multizone = Just False
+                    , temperatureRange = Just
+                        ( 1500
+                        , 9000
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades = []
+                }
+            , ProductInfo
+                { pid = 70
+                , name = "LIFX Switch"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just False
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Just True
+                    , buttons = Just True
+                    , infrared = Just False
+                    , multizone = Just False
+                    , temperatureRange = Nothing
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades = []
+                }
+            , ProductInfo
+                { pid = 71
+                , name = "LIFX Switch"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just False
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Just True
+                    , buttons = Just True
+                    , infrared = Just False
+                    , multizone = Just False
+                    , temperatureRange = Nothing
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades = []
+                }
+            , ProductInfo
+                { pid = 81
+                , name = "LIFX Candle White to Warm"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just False
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just False
+                    , multizone = Just False
+                    , temperatureRange = Just
+                        ( 2200
+                        , 6500
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades = []
+                }
+            , ProductInfo
+                { pid = 82
+                , name = "LIFX Filament Clear"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just False
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just False
+                    , multizone = Just False
+                    , temperatureRange = Just
+                        ( 2100
+                        , 2100
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades = []
+                }
+            , ProductInfo
+                { pid = 85
+                , name = "LIFX Filament Amber"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just False
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just False
+                    , multizone = Just False
+                    , temperatureRange = Just
+                        ( 2000
+                        , 2000
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades = []
+                }
+            , ProductInfo
+                { pid = 87
+                , name = "LIFX Mini White"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just False
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just False
+                    , multizone = Just False
+                    , temperatureRange = Just
+                        ( 2700
+                        , 2700
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades = []
+                }
+            , ProductInfo
+                { pid = 88
+                , name = "LIFX Mini White"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just False
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just False
+                    , multizone = Just False
+                    , temperatureRange = Just
+                        ( 2700
+                        , 2700
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades = []
+                }
+            , ProductInfo
+                { pid = 89
+                , name = "LIFX Switch"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just False
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Just True
+                    , buttons = Just True
+                    , infrared = Just False
+                    , multizone = Just False
+                    , temperatureRange = Nothing
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades = []
+                }
+            , ProductInfo
+                { pid = 90
+                , name = "LIFX Clean"
+                , features = PartialFeatures
+                    { hev = Just True
+                    , color = Just True
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just False
+                    , multizone = Just False
+                    , temperatureRange = Just
+                        ( 1500
+                        , 9000
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades = []
+                }
+            , ProductInfo
+                { pid = 91
+                , name = "LIFX Color"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just True
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just False
+                    , multizone = Just False
+                    , temperatureRange = Just
+                        ( 1500
+                        , 9000
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades = []
+                }
+            , ProductInfo
+                { pid = 92
+                , name = "LIFX Color"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just True
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just False
+                    , multizone = Just False
+                    , temperatureRange = Just
+                        ( 1500
+                        , 9000
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades = []
+                }
+            , ProductInfo
+                { pid = 93
+                , name = "LIFX A19 US"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just True
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just False
+                    , multizone = Just False
+                    , temperatureRange = Just
+                        ( 1500
+                        , 9000
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades = []
+                }
+            , ProductInfo
+                { pid = 94
+                , name = "LIFX BR30"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just True
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just False
+                    , multizone = Just False
+                    , temperatureRange = Just
+                        ( 1500
+                        , 9000
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades = []
+                }
+            , ProductInfo
+                { pid = 96
+                , name = "LIFX Candle White to Warm"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just False
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just False
+                    , multizone = Just False
+                    , temperatureRange = Just
+                        ( 2200
+                        , 6500
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades = []
+                }
+            , ProductInfo
+                { pid = 97
+                , name = "LIFX A19"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just True
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just False
+                    , multizone = Just False
+                    , temperatureRange = Just
+                        ( 1500
+                        , 9000
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades = []
+                }
+            , ProductInfo
+                { pid = 98
+                , name = "LIFX BR30"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just True
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just False
+                    , multizone = Just False
+                    , temperatureRange = Just
+                        ( 1500
+                        , 9000
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades = []
+                }
+            , ProductInfo
+                { pid = 99
+                , name = "LIFX Clean"
+                , features = PartialFeatures
+                    { hev = Just True
+                    , color = Just True
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just False
+                    , multizone = Just False
+                    , temperatureRange = Just
+                        ( 1500
+                        , 9000
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades = []
+                }
+            , ProductInfo
+                { pid = 100
+                , name = "LIFX Filament Clear"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just False
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just False
+                    , multizone = Just False
+                    , temperatureRange = Just
+                        ( 2100
+                        , 2100
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades = []
+                }
+            , ProductInfo
+                { pid = 101
+                , name = "LIFX Filament Amber"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just False
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just False
+                    , multizone = Just False
+                    , temperatureRange = Just
+                        ( 2000
+                        , 2000
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades = []
+                }
+            , ProductInfo
+                { pid = 109
+                , name = "LIFX A19 Night Vision"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just True
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just True
+                    , multizone = Just False
+                    , temperatureRange = Just
+                        ( 1500
+                        , 9000
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades = []
+                }
+            , ProductInfo
+                { pid = 110
+                , name = "LIFX BR30 Night Vision"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just True
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just True
+                    , multizone = Just False
+                    , temperatureRange = Just
+                        ( 1500
+                        , 9000
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades = []
+                }
+            , ProductInfo
+                { pid = 111
+                , name = "LIFX A19 Night Vision"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just True
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just True
+                    , multizone = Just False
+                    , temperatureRange = Just
+                        ( 1500
+                        , 9000
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades = []
+                }
+            , ProductInfo
+                { pid = 112
+                , name = "LIFX BR30 Night Vision Intl"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just True
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just True
+                    , multizone = Just False
+                    , temperatureRange = Just
+                        ( 1500
+                        , 9000
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades = []
+                }
+            , ProductInfo
+                { pid = 113
+                , name = "LIFX Mini WW US"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just False
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just False
+                    , multizone = Just False
+                    , temperatureRange = Just
+                        ( 1500
+                        , 9000
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades = []
+                }
+            , ProductInfo
+                { pid = 114
+                , name = "LIFX Mini WW Intl"
+                , features = PartialFeatures
+                    { hev = Nothing
+                    , color = Just False
+                    , chain = Just False
+                    , matrix = Just False
+                    , relays = Nothing
+                    , buttons = Nothing
+                    , infrared = Just False
+                    , multizone = Just False
+                    , temperatureRange = Just
+                        ( 1500
+                        , 9000
+                        )
+                    , extendedMultizone = Nothing
+                    }
+                , upgrades = []
+                }
+            ]
+        }
+    ]
diff --git a/src/Lifx/Lan.hs b/src/Lifx/Lan.hs
--- a/src/Lifx/Lan.hs
+++ b/src/Lifx/Lan.hs
@@ -28,7 +28,7 @@
     HSBK (..),
     Lifx,
     runLifx,
-    LifxT,
+    LifxT (LifxT),
     runLifxT,
     LifxError (..),
     MonadLifx (..),
@@ -36,9 +36,16 @@
     -- * Responses
     StateService (..),
     Service (..),
+    StateHostFirmware (..),
     StatePower (..),
+    StateVersion (..),
     LightState (..),
 
+    -- ** Product info
+    getProductInfo,
+    Product (..),
+    Features (..),
+
     -- * Low-level
     deviceFromAddress,
     encodeMessage,
@@ -46,6 +53,7 @@
     unLifxT,
 ) where
 
+import Control.Applicative
 import Control.Monad
 import Control.Monad.Except
 import Control.Monad.Extra
@@ -54,10 +62,10 @@
 import Control.Monad.Trans.Maybe
 import Data.Either.Extra
 import Data.Fixed
-import Data.Foldable
+import Data.Foldable hiding (product)
 import Data.Function
 import Data.Functor
-import Data.List
+import Data.List hiding (product)
 import Data.Maybe
 import Data.Tuple.Extra
 import Data.Word
@@ -72,6 +80,7 @@
     getWord16le,
     getWord32le,
     getWord64be,
+    getWord64le,
     getWord8,
     runGetOrFail,
     skip,
@@ -88,8 +97,9 @@
 import Data.ByteString qualified as BS
 import Data.ByteString.Lazy qualified as BL
 import Data.List.NonEmpty (NonEmpty)
-import Data.Map (Map)
+import Data.Map (Map, (!?))
 import Data.Map.Strict qualified as Map
+import Data.Text (Text)
 import Data.Time (
     NominalDiffTime,
     diffUTCTime,
@@ -117,6 +127,12 @@
 import System.Random (randomIO)
 import System.Timeout (timeout)
 
+import Lifx.Internal.Product
+import Lifx.Internal.ProductInfo
+
+--TODO RecordDotSyntax can make this and other hiding unnecessary (we could also use "id" instead of "productId"...)
+import Prelude hiding (product)
+
 {- Device -}
 
 -- | A LIFX device, such as a bulb.
@@ -187,10 +203,14 @@
     -- | https://lan.developer.lifx.com/docs/querying-the-device-for-data#getservice---packet-2
     -- (you shouldn't need this - use 'discoverDevices')
     GetService :: Message StateService
+    -- | https://lan.developer.lifx.com/docs/querying-the-device-for-data#gethostfirmware---packet-14
+    GetHostFirmware :: Message StateHostFirmware
     -- | https://lan.developer.lifx.com/docs/querying-the-device-for-data#getpower---packet-20
     GetPower :: Message StatePower
     -- | https://lan.developer.lifx.com/docs/changing-a-device#setpower---packet-21
     SetPower :: Bool -> Message ()
+    -- | https://lan.developer.lifx.com/docs/querying-the-device-for-data#getversion---packet-32
+    GetVersion :: Message StateVersion
     -- | https://lan.developer.lifx.com/docs/querying-the-device-for-data#getcolor---packet-101
     GetColor :: Message LightState
     -- | https://lan.developer.lifx.com/docs/changing-a-device#setcolor---packet-102
@@ -218,12 +238,32 @@
     }
     deriving (Eq, Ord, Show, Generic)
 
+-- | https://lan.developer.lifx.com/docs/information-messages#statehostfirmware---packet-15
+data StateHostFirmware = StateHostFirmware
+    { -- | The timestamp of the firmware that is on the device as an epoch
+      build :: Word64
+    , -- | The minor component of the firmware version
+      versionMinor :: Word16
+    , -- | The major component of the firmware version
+      versionMajor :: Word16
+    }
+    deriving (Eq, Ord, Show, Generic)
+
 -- | https://lan.developer.lifx.com/docs/information-messages#statepower---packet-22
 newtype StatePower = StatePower
     { power :: Word16
     }
     deriving (Eq, Ord, Show, Generic)
 
+-- | https://lan.developer.lifx.com/docs/information-messages#stateversion---packet-33
+data StateVersion = StateVersion
+    { -- | For LIFX products this value is 1. There may be devices in the future with a different vendor value.
+      vendor :: Word32
+    , -- | The product id of the device. The available products can be found in our Product Registry.
+      product :: Word32
+    }
+    deriving (Eq, Ord, Show, Generic)
+
 -- | https://lan.developer.lifx.com/docs/information-messages#lightstate---packet-107
 data LightState = LightState
     { hsbk :: HSBK
@@ -240,6 +280,8 @@
     | WrongSender Device HostAddress -- expected, then actual
     | UnexpectedSockAddrType SockAddr
     | UnexpectedPort PortNumber
+    | UnknownVendorId Word32
+    | UnknownProductId Word32
     deriving (Eq, Ord, Show, Generic)
 
 {- Message responses -}
@@ -325,6 +367,30 @@
             maybe (fail $ "port out of range: " <> show x) pure $ fromIntegralSafe x
         pure StateService{..}
 instance MessageResult StateService
+instance Response StateHostFirmware where
+    expectedPacketType = 15
+    messageSize = 20
+    getBody = do
+        build <- getWord64le
+        skip 8
+        versionMinor <- getWord16le
+        versionMajor <- getWord16le
+        pure StateHostFirmware{..}
+instance MessageResult StateHostFirmware
+instance Response StatePower where
+    expectedPacketType = 22
+    messageSize = 2
+    getBody = StatePower <$> getWord16le
+instance MessageResult StatePower
+instance Response StateVersion where
+    expectedPacketType = 33
+    messageSize = 20
+    getBody = do
+        vendor <- getWord32le
+        product <- getWord32le
+        skip 4
+        pure StateVersion{..}
+instance MessageResult StateVersion
 instance Response LightState where
     expectedPacketType = 107
     messageSize = 52
@@ -336,11 +402,6 @@
         skip 8
         pure LightState{..}
 instance MessageResult LightState
-instance Response StatePower where
-    expectedPacketType = 22
-    messageSize = 2
-    getBody = StatePower <$> getWord16le
-instance MessageResult StatePower
 
 -- all `Message` response types are instances of `MessageResult`
 --TODO ImpredicativeTypes:
@@ -348,8 +409,10 @@
 msgResWitness :: Message r -> Dict (MessageResult r)
 msgResWitness = \case
     GetService{} -> Dict
+    GetHostFirmware{} -> Dict
     GetPower{} -> Dict
     SetPower{} -> Dict
+    GetVersion{} -> Dict
     GetColor{} -> Dict
     SetColor{} -> Dict
     SetLightPower{} -> Dict
@@ -531,6 +594,12 @@
             , packetType = 2
             , ..
             }
+    GetHostFirmware{} ->
+        Header
+            { size = headerSize
+            , packetType = 14
+            , ..
+            }
     GetPower{} ->
         Header
             { size = headerSize
@@ -543,6 +612,12 @@
             , packetType = 21
             , ..
             }
+    GetVersion{} ->
+        Header
+            { size = headerSize
+            , packetType = 32
+            , ..
+            }
     GetColor{} ->
         Header
             { size = headerSize
@@ -571,9 +646,11 @@
 putMessagePayload :: Message r -> Put
 putMessagePayload = \case
     GetService -> mempty
+    GetHostFirmware -> mempty
     GetPower -> mempty
     SetPower b ->
         putWord16le if b then maxBound else minBound
+    GetVersion -> mempty
     GetColor -> mempty
     SetColor HSBK{..} d -> do
         putWord8 0
@@ -585,6 +662,112 @@
     SetLightPower b d -> do
         putWord16le if b then maxBound else minBound
         putWord32le $ nominalDiffTimeToInt @Milli d
+
+{- Product info -}
+
+productInfoMap :: Map Word32 (Features, Map Word32 ProductInfo)
+productInfoMap =
+    Map.fromList $
+        productInfo <&> \VendorInfo{..} ->
+            ( vid
+            ,
+                ( defaults
+                , Map.fromList $ (pid &&& id) <$> products
+                )
+            )
+
+-- | Information about a particular LIFX product.
+data Product = Product
+    { name :: Text
+    , productId :: Word32
+    , features :: Features
+    }
+    deriving (Show)
+
+-- | Ask a device for it's vendor and product ID, and look up info on it from the official database.
+getProductInfo :: MonadLifx m => Device -> m Product
+getProductInfo dev = do
+    StateHostFirmware{..} <- sendMessage dev GetHostFirmware
+    StateVersion{..} <- sendMessage dev GetVersion
+    case productInfoMap !? vendor of
+        Nothing -> lifxThrow $ UnknownVendorId vendor
+        Just (defaults, products) -> case products !? product of
+            Nothing -> lifxThrow $ UnknownProductId product
+            Just ProductInfo{features = originalFeatures, ..} ->
+                pure
+                    Product
+                        { name
+                        , productId = product
+                        , features =
+                            completeFeatures defaults $
+                                foldl
+                                    ( \old Upgrade{..} ->
+                                        if (versionMajor, versionMinor) >= (major, minor)
+                                            then addFeatures features old
+                                            else old
+                                    )
+                                    originalFeatures
+                                    upgrades
+                        }
+  where
+    --TODO RecordDotSyntax
+    completeFeatures
+        Features
+            { ..
+            }
+        PartialFeatures
+            { hev = maybe_hev
+            , color = maybe_color
+            , chain = maybe_chain
+            , matrix = maybe_matrix
+            , relays = maybe_relays
+            , buttons = maybe_buttons
+            , infrared = maybe_infrared
+            , multizone = maybe_multizone
+            , temperatureRange = maybe_temperatureRange
+            , extendedMultizone = maybe_extendedMultizone
+            } =
+            Features
+                { hev = fromMaybe hev maybe_hev
+                , color = fromMaybe color maybe_color
+                , chain = fromMaybe chain maybe_chain
+                , matrix = fromMaybe matrix maybe_matrix
+                , relays = fromMaybe relays maybe_relays
+                , buttons = fromMaybe buttons maybe_buttons
+                , infrared = fromMaybe infrared maybe_infrared
+                , multizone = fromMaybe multizone maybe_multizone
+                , temperatureRange = maybe_temperatureRange <|> temperatureRange
+                , extendedMultizone = fromMaybe extendedMultizone maybe_extendedMultizone
+                }
+    -- left-biased
+    addFeatures
+        PartialFeatures
+            { ..
+            }
+        PartialFeatures
+            { hev = old_hev
+            , color = old_color
+            , chain = old_chain
+            , matrix = old_matrix
+            , relays = old_relays
+            , buttons = old_buttons
+            , infrared = old_infrared
+            , multizone = old_multizone
+            , temperatureRange = old_temperatureRange
+            , extendedMultizone = old_extendedMultizone
+            } =
+            PartialFeatures
+                { hev = hev <|> old_hev
+                , color = color <|> old_color
+                , chain = chain <|> old_chain
+                , matrix = matrix <|> old_matrix
+                , relays = relays <|> old_relays
+                , buttons = buttons <|> old_buttons
+                , infrared = infrared <|> old_infrared
+                , multizone = multizone <|> old_multizone
+                , temperatureRange = temperatureRange <|> old_temperatureRange
+                , extendedMultizone = extendedMultizone <|> old_extendedMultizone
+                }
 
 {- Util -}
 
