Repository: zigpy/zha-device-handlers

Issue:
[Device Support Request] Philips Hue Power Cycle Attribute
Hi 

It would be great to have the Philips Hue Power Cycle attribute added. This allows for the bulb to remain powered on, off or set to previous settings when powered on.

The vendor attribute is `0x4003` and falls part of the `0x0006` (on_off) cluster. The possible values (enum8) are 

```
Off = 0x00
On = 0x01
Previous = 0xff
```

The device signature for the ambient color bulb is as follows:

```
{
  "node_descriptor": "<NodeDescriptor byte1=1 byte2=64 mac_capability_flags=142 manufacturer_code=4107 maximum_buffer_size=71 maximum_incoming_transfer_size=45 server_mask=0 maximum_outgoing_transfer_size=45 descriptor_capability_field=0>",
  "endpoints": {
    "11": {
      "profile_id": 49246,
      "device_type": "0x0210",
      "in_clusters": [
        "0x0000",
        "0x0003",
        "0x0004",
        "0x0005",
        "0x0006",
        "0x0008",
        "0x0300",
        "0x1000",
        "0xfc01"
      ],
      "out_clusters": [
        "0x0019"
      ]
    },
    "242": {
      "profile_id": 41440,
      "device_type": "0x0061",
      "in_clusters": [
        "0x0021"
      ],
      "out_clusters": [
        "0x0021"
      ]
    }
  },
  "manufacturer": "Philips",
  "model": "LCT015",
  "class": "zigpy.device.Device"
}
```

The device signature for the dimmable white bulb is as follows:

```
{
  "node_descriptor": "<NodeDescriptor byte1=1 byte2=64 mac_capability_flags=142 manufacturer_code=4107 maximum_buffer_size=71 maximum_incoming_transfer_size=45 server_mask=0 maximum_outgoing_transfer_size=45 descriptor_capability_field=0>",
  "endpoints": {
    "11": {
      "profile_id": 49246,
      "device_type": "0x0100",
      "in_clusters": [
        "0x0000",
        "0x0003",
        "0x0004",
        "0x0005",
        "0x0006",
        "0x0008",
        "0x1000"
      ],
      "out_clusters": [
        "0x0019"
      ]
    },
    "242": {
      "profile_id": 41440,
      "device_type": "0x0061",
      "in_clusters": [
        "0x0021"
      ],
      "out_clusters": [
        "0x0021"
      ]
    }
  },
  "manufacturer": "Philips",
  "model": "LWB010",
  "class": "zigpy.device.Device"
}
```

I hope this is all that is needed to implement this. Please let me know if there anything you need.

Thanks.

Kurt 


Discussion:
does the 2nd one support this? It doesn't have the Philips cluster...
nvm.
@dmulcahey 

I see that a merge has been completed to support this! Amazing work!

Thanks so much.

Regards 

Kurt
@dmulcahey 

I wonder if you would be able to assist me in setting this cluster value in Home Assistant. I seem to be unable to set it to anything.

I have tried PowerOnState.Off, 0x00, Off, 00 and 0 and none of them seem to work. Do you perhaps know how I would be able to do it?

When I had added it myself (not through device handlers) I could use 0x00 successfully. 

Hopefully you can provide some assistance.

Regards

Kurt 
@kurtwarwick-new Just wondering, did you find a way to set these values and have them work?
Hi @TheJulianJES 

I have not been able to get this to work. Until I find out, I have been [altering the zigpy file containing this cluster](https://github.com/kurtwarwick-new/zigpy/pull/1/commits/80e695166fd5b558585f2e22520a71f3446d7933) which allows me to change the values using 0x00, 0x01 and 0xff. 

Trying those values with this particular fix doesn't seem to do anything, and trying "Off" or "PowerOnState.Off" result in errors:

![image](https://user-images.githubusercontent.com/61435184/90374705-321fe280-e074-11ea-9fc6-92e1a01fa62d.png)

So I am not sure how to actually set those attribute values 😞 

Kurt
Thanks, I will try that later!

I'm not sure this is related to the issue, but if I "get" the current value from power_on_state (0x4003)/PhilipsOnOffCluster (0x0006), it always returns "None". Regardless if I set it to 0 or 0x00 previously. (Perhaps it's not setting the attribute correctly?)

Also not sure if this is helpful or even has anything do with it, but it seems like that the Hue Bridge doesn't handle this as a "manufacturer attribute" (but the code in https://github.com/zigpy/zha-device-handlers/blob/dev/zhaquirks/philips/__init__.py#L60 defines it as such?)
Source:
"I cannot find 0x0006/0x4003 nor 0x0300/0x4010 in the ZCL spec nor in the ZLL spec. Yet, the bridge and spot handle them as non-manufacturer-specific attributes. I would theorise they define the power-on state, where 0xff / 0xffff means previous value." (https://github.com/dresden-elektronik/deconz-rest-plugin/issues/1014#issuecomment-445449242)
(I'm not yet familiar between the differences, so this might be unrelated.)

@dmulcahey Should I create a new issue for this or is there anything else that would point to an error on my side(?)
(Sorry for the tag, but it seems that you are most familiar with how this was implemented.)
@kurtwarwick-new Just wanted to let you know, I created an issue for this now: #461 
Seems like this needs to be moved to attributes. Let me get an example...
@TheJulianJES Try replacing the implementation with this: https://github.com/zigpy/zha-device-handlers/blob/911c188b57079401c3c57066536ec08fcf4ea4e8/zhaquirks/philips/__init__.py

@Adminiuga looks like philips may not like getting the manufacturer code sent with their custom attributes. Why don’t any of these companies do things correctly...
You may need to remove the 0x403 Astrid from the manufacturer specific attrs so it doesn't send the code. 

Yep that’s what I suggested above

Resolving patch:
diff --git a/zhaquirks/philips/__init__.py b/zhaquirks/philips/__init__.py
--- a/zhaquirks/philips/__init__.py
+++ b/zhaquirks/philips/__init__.py
@@ -57,7 +57,8 @@ class PowerOnState(t.enum8):
 class PhilipsOnOffCluster(CustomCluster, OnOff):
     """Philips OnOff cluster."""
 
-    manufacturer_attributes = {0x4003: ("power_on_state", PowerOnState)}
+    attributes = OnOff.attributes.copy()
+    attributes.update({0x4003: ("power_on_state", PowerOnState)})
 
 
 class PhilipsBasicCluster(CustomCluster, Basic):


Test patch: