From 49ebea2be3f45a4d34776d8f5c2a97b90497a57e Mon Sep 17 00:00:00 2001
From: Jason Swails <jason.swails@gmail.com>
Date: Mon, 23 Mar 2020 02:51:24 -0400
Subject: [PATCH] Add support for occupancy/vacancy groups in Lutron Caseta
 component (#33032)

* Add support for Lutron Caseta occupancy/vacancy sensors

This follows updates to pylutron-caseta to add support for these
devices. This code works for me as a custom component in Home Assistant
Core with pylutron-caseta 0.6.0 (currently unreleased).

* black formatting

* Update requirements_all.txt

* Apply black formatting

* Resolve some review comments

* serial -> unique_id

* Black formatting

* Resolve linting errors

* Add code owner...

* Fix isort complaint

* Fix remaining isort complaints

* Update codeowners

* Resolve outstanding review comments

* Remove caseta_
---
 CODEOWNERS                                    |  1 +
 .../components/lutron_caseta/__init__.py      |  2 +-
 .../components/lutron_caseta/binary_sensor.py | 56 +++++++++++++++++++
 .../components/lutron_caseta/manifest.json    |  4 +-
 requirements_all.txt                          |  2 +-
 5 files changed, 61 insertions(+), 4 deletions(-)
 create mode 100644 homeassistant/components/lutron_caseta/binary_sensor.py

diff --git a/CODEOWNERS b/CODEOWNERS
index 556ce10b18e..5cc19809a47 100644
--- a/CODEOWNERS
+++ b/CODEOWNERS
@@ -211,6 +211,7 @@ homeassistant/components/luci/* @fbradyirl @mzdrale
 homeassistant/components/luftdaten/* @fabaff
 homeassistant/components/lupusec/* @majuss
 homeassistant/components/lutron/* @JonGilmore
+homeassistant/components/lutron_caseta/* @swails
 homeassistant/components/mastodon/* @fabaff
 homeassistant/components/matrix/* @tinloaf
 homeassistant/components/mcp23017/* @jardiamj
diff --git a/homeassistant/components/lutron_caseta/__init__.py b/homeassistant/components/lutron_caseta/__init__.py
index a3e384fd77b..47df6a221dd 100644
--- a/homeassistant/components/lutron_caseta/__init__.py
+++ b/homeassistant/components/lutron_caseta/__init__.py
@@ -33,7 +33,7 @@ CONFIG_SCHEMA = vol.Schema(
     extra=vol.ALLOW_EXTRA,
 )
 
-LUTRON_CASETA_COMPONENTS = ["light", "switch", "cover", "scene", "fan"]
+LUTRON_CASETA_COMPONENTS = ["light", "switch", "cover", "scene", "fan", "binary_sensor"]
 
 
 async def async_setup(hass, base_config):
diff --git a/homeassistant/components/lutron_caseta/binary_sensor.py b/homeassistant/components/lutron_caseta/binary_sensor.py
new file mode 100644
index 00000000000..871f3c28664
--- /dev/null
+++ b/homeassistant/components/lutron_caseta/binary_sensor.py
@@ -0,0 +1,56 @@
+"""Support for Lutron Caseta Occupancy/Vacancy Sensors."""
+from pylutron_caseta import OCCUPANCY_GROUP_OCCUPIED
+
+from homeassistant.components.binary_sensor import (
+    DEVICE_CLASS_OCCUPANCY,
+    BinarySensorDevice,
+)
+
+from . import LUTRON_CASETA_SMARTBRIDGE, LutronCasetaDevice
+
+
+async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
+    """Set up the Lutron Caseta lights."""
+    entities = []
+    bridge = hass.data[LUTRON_CASETA_SMARTBRIDGE]
+    occupancy_groups = bridge.occupancy_groups
+    for occupancy_group in occupancy_groups.values():
+        entity = LutronOccupancySensor(occupancy_group, bridge)
+        entities.append(entity)
+
+    async_add_entities(entities, True)
+
+
+class LutronOccupancySensor(LutronCasetaDevice, BinarySensorDevice):
+    """Representation of a Lutron occupancy group."""
+
+    @property
+    def device_class(self):
+        """Flag supported features."""
+        return DEVICE_CLASS_OCCUPANCY
+
+    @property
+    def is_on(self):
+        """Return the brightness of the light."""
+        return self._device["status"] == OCCUPANCY_GROUP_OCCUPIED
+
+    async def async_added_to_hass(self):
+        """Register callbacks."""
+        self._smartbridge.add_occupancy_subscriber(
+            self.device_id, self.async_write_ha_state
+        )
+
+    @property
+    def device_id(self):
+        """Return the device ID used for calling pylutron_caseta."""
+        return self._device["occupancy_group_id"]
+
+    @property
+    def unique_id(self):
+        """Return a unique identifier."""
+        return f"occupancygroup_{self.device_id}"
+
+    @property
+    def device_state_attributes(self):
+        """Return the state attributes."""
+        return {"device_id": self.device_id}
diff --git a/homeassistant/components/lutron_caseta/manifest.json b/homeassistant/components/lutron_caseta/manifest.json
index 3dd8c8fac2e..856bf285a16 100644
--- a/homeassistant/components/lutron_caseta/manifest.json
+++ b/homeassistant/components/lutron_caseta/manifest.json
@@ -2,7 +2,7 @@
   "domain": "lutron_caseta",
   "name": "Lutron Caseta",
   "documentation": "https://www.home-assistant.io/integrations/lutron_caseta",
-  "requirements": ["pylutron-caseta==0.5.1"],
+  "requirements": ["pylutron-caseta==0.6.0"],
   "dependencies": [],
-  "codeowners": []
+  "codeowners": ["@swails"]
 }
diff --git a/requirements_all.txt b/requirements_all.txt
index 927c8d35c13..e2f81dbcf20 100644
--- a/requirements_all.txt
+++ b/requirements_all.txt
@@ -1364,7 +1364,7 @@ pylitejet==0.1
 pyloopenergy==0.1.3
 
 # homeassistant.components.lutron_caseta
-pylutron-caseta==0.5.1
+pylutron-caseta==0.6.0
 
 # homeassistant.components.lutron
 pylutron==0.2.5
-- 
GitLab