Repository: zigpy/zha-device-handlers

Issue:
[Device Support Request] Heating Order Legrand Cable Outlet
Hi i recently add a cable outlet with heating order to my Home assistant.
this is the model :
https://www.legrand.fr/pro/catalogue/43076-sortie-de-cable/sortie-de-cable-connectee-pour-installation-with-netatmo-compatible-fil-pilote-3000w-on-off-et-mesure-conso-blanc

With this device i could have on/off command, Power consumption and Heating order.
After succesfully paired i can only have on/off and power consumption.
So after some research here is some informations that could be great for implementing heating order :
here is the cluster and the attribute for the order :
https://github.com/pipiche38/Domoticz-Zigate-Wiki/blob/master/en-eng/Legrand-Netatmo-corner.md#cluster-0xfc40

and the full list from the manufacturer :
https://developer.legrand.com/documentation/product-cluster-list/

I hope you could implement it with those informations,
Thanks for your work !


Discussion:
There hasn't been any activity on this issue recently. Due to the high number of incoming GitHub notifications, we have to clean some of the old issues, as many of them have already been resolved with the latest updates. Please make sure to update to the latest version and check if that solves the issue. Let us know if that works for you by adding a comment 👍 This issue has now been marked as stale and will be closed if no further activity occurs. Thank you for your contributions.
+1
Hi,

+1

Is there any way to get this issue reopened?

Resolving patch:
diff --git a/zhaquirks/legrand/cable_outlet.py b/zhaquirks/legrand/cable_outlet.py
new file mode 100644
--- /dev/null
+++ b/zhaquirks/legrand/cable_outlet.py
@@ -0,0 +1,162 @@
+"""Module for Legrand Cable Outlet (with pilot wire functionality)."""
+
+from zigpy.profiles import zgp, zha
+from zigpy.quirks import CustomCluster, CustomDevice
+import zigpy.types as t
+from zigpy.zcl.clusters.general import (
+    Basic,
+    GreenPowerProxy,
+    Groups,
+    Identify,
+    OnOff,
+    Ota,
+    Scenes,
+)
+from zigpy.zcl.clusters.homeautomation import ElectricalMeasurement
+from zigpy.zcl.foundation import (
+    BaseAttributeDefs,
+    BaseCommandDefs,
+    Direction,
+    ZCLAttributeDef,
+    ZCLCommandDef,
+)
+
+from zhaquirks.const import (
+    DEVICE_TYPE,
+    ENDPOINTS,
+    INPUT_CLUSTERS,
+    MODELS_INFO,
+    OUTPUT_CLUSTERS,
+    PROFILE_ID,
+)
+from zhaquirks.legrand import LEGRAND, MANUFACTURER_SPECIFIC_CLUSTER_ID
+
+MANUFACTURER_SPECIFIC_CLUSTER_ID_2 = 0xFC40  # 64576
+
+
+class DeviceMode(t.enum16):
+    PILOT_OFF = 0x0100
+    PILOT_ON = 0x0200
+
+
+class LegrandCluster(CustomCluster):
+    """LegrandCluster."""
+
+    cluster_id = MANUFACTURER_SPECIFIC_CLUSTER_ID
+    name = "LegrandCluster"
+    ep_attribute = "legrand_cluster"
+
+    class AttributeDefs(BaseAttributeDefs):
+        device_mode = ZCLAttributeDef(
+            id=0x0000,
+            type=t.data16,  # DeviceMode
+            is_manufacturer_specific=True,
+        )
+        led_dark = ZCLAttributeDef(
+            id=0x0001,
+            type=t.Bool,
+            is_manufacturer_specific=True,
+        )
+        led_on = ZCLAttributeDef(
+            id=0x0002,
+            type=t.Bool,
+            is_manufacturer_specific=True,
+        )
+
+
+class PilotWireMode(t.enum8):
+    COMFORT = 0x00
+    COMFORT_MINUS_1 = 0x01
+    COMFORT_MINUS_2 = 0x02
+    ECO = 0x03
+    FROST_PROTECTION = 0x04
+    OFF = 0x05
+
+
+class LegrandCableOutletCluster(CustomCluster):
+    """Legrand second manufacturer-specific cluster."""
+
+    cluster_id = MANUFACTURER_SPECIFIC_CLUSTER_ID_2
+    name = "CableOutlet"
+    ep_attribute = "cable_outlet_cluster"
+
+    class ServerCommandDefs(BaseCommandDefs):
+        set_pilot_wire_mode = ZCLCommandDef(
+            id=0x00,
+            schema={"mode": PilotWireMode},
+            direction=Direction.Server_to_Client,
+            is_manufacturer_specific=True,
+        )
+
+
+class Legrand064882CableOutlet(CustomDevice):
+    signature = {
+        #  <SimpleDescriptor endpoint=1 profile=260 device_type=1
+        # input_clusters=[0, 3, 4, 6, 5, 64513, 2820, 64576]
+        # output_clusters=[6, 0, 64513, 5, 25]>
+        MODELS_INFO: [(f" {LEGRAND}", " Cable outlet")],
+        ENDPOINTS: {
+            1: {
+                PROFILE_ID: zha.PROFILE_ID,
+                DEVICE_TYPE: zha.DeviceType.LEVEL_CONTROL_SWITCH,
+                INPUT_CLUSTERS: [
+                    Basic.cluster_id,
+                    Identify.cluster_id,
+                    Groups.cluster_id,
+                    OnOff.cluster_id,
+                    Scenes.cluster_id,
+                    MANUFACTURER_SPECIFIC_CLUSTER_ID,
+                    ElectricalMeasurement.cluster_id,
+                    MANUFACTURER_SPECIFIC_CLUSTER_ID_2,
+                ],
+                OUTPUT_CLUSTERS: [
+                    OnOff.cluster_id,
+                    Basic.cluster_id,
+                    MANUFACTURER_SPECIFIC_CLUSTER_ID,
+                    Scenes.cluster_id,
+                    Ota.cluster_id,
+                ],
+            },
+            #  <SimpleDescriptor endpoint=242 profile=41440 device_type=102
+            # input_clusters=[33]
+            # output_clusters=[33]>
+            242: {
+                PROFILE_ID: zgp.PROFILE_ID,
+                DEVICE_TYPE: zgp.DeviceType.COMBO_BASIC,
+                INPUT_CLUSTERS: [GreenPowerProxy.cluster_id],
+                OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id],
+            },
+        },
+    }
+
+    replacement = {
+        ENDPOINTS: {
+            1: {
+                PROFILE_ID: zha.PROFILE_ID,
+                DEVICE_TYPE: zha.DeviceType.LEVEL_CONTROL_SWITCH,
+                INPUT_CLUSTERS: [
+                    Basic.cluster_id,
+                    Identify.cluster_id,
+                    Groups.cluster_id,
+                    OnOff.cluster_id,
+                    Scenes.cluster_id,
+                    LegrandCluster,
+                    ElectricalMeasurement.cluster_id,
+                    LegrandCableOutletCluster,
+                ],
+                OUTPUT_CLUSTERS: [
+                    OnOff.cluster_id,
+                    Basic.cluster_id,
+                    LegrandCluster,
+                    Scenes.cluster_id,
+                    Ota.cluster_id,
+                ],
+            },
+            242: {
+                PROFILE_ID: zgp.PROFILE_ID,
+                DEVICE_TYPE: zgp.DeviceType.COMBO_BASIC,
+                INPUT_CLUSTERS: [GreenPowerProxy.cluster_id],
+                OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id],
+            },
+        },
+    }


Test patch: