Kane610 / aiounifi

Asynchronous library to communicate with Unifi Controller
MIT License
60 stars 53 forks source link

outlet_caps relating to feature availability #427

Closed Cisien closed 1 year ago

Cisien commented 1 year ago

Posting this to discuss the meaning of outlet_caps.

The data I have so far: On the USP-Plug: no outlet_caps property is available On the USP-PDU-Pro: the outlet_caps property is available on each outlet in the outlet_table For USB ports, the value is 1 For Power outlets, the value is 3

USP-Plug has properties called has_metering and has_relay to convey the capabilities of that device USP-PDU-Pro does not have these convenient properties, instead the outlets have a outlet_caps property.

Capability Flag Meaning
1 Supports Switching
2 (not seen on a device yet) Supports metering
3 Supports Switching and Metering
Kane610 commented 1 year ago

I think its sound to define it like this!

Cisien commented 1 year ago

What are your thoughts on "shimming" these caps definitions into the expected properties?

for example:

    @property
    def has_relay(self) -> bool | None:
        """Is the outlet controllable."""
        has_relay = self.raw.get("has_relay")
        if has_relay == None:
            outlet_caps = self.raw.get("outlet_caps")
            has_relay = outlet_caps == 3 or outlet_caps == 1 
        return has_relay

uses the property that comes back from the API if it's available. if it's not, it uses caps to determine the result.

Kane610 commented 1 year ago

What are your thoughts on "shimming" these caps definitions into the expected properties?

for example:

    @property
    def has_relay(self) -> bool | None:
        """Is the outlet controllable."""
        has_relay = self.raw.get("has_relay")
        if has_relay == None:
            outlet_caps = self.raw.get("outlet_caps")
            has_relay = outlet_caps == 3 or outlet_caps == 1 
        return has_relay

uses the property that comes back from the API if it's available. if it's not, it uses caps to determine the result.

So right now Im not a fan of trying put too much logic into the library but rather try to keep it close to what the API exposes. I think its better we combine this data on the integration side of things.

Cisien commented 1 year ago

In that case, I'll update my PR to only document the caps

Kane610 commented 1 year ago

What are your thoughts on "shimming" these caps definitions into the expected properties? for example:

    @property
    def has_relay(self) -> bool | None:
        """Is the outlet controllable."""
        has_relay = self.raw.get("has_relay")
        if has_relay == None:
            outlet_caps = self.raw.get("outlet_caps")
            has_relay = outlet_caps == 3 or outlet_caps == 1 
        return has_relay

uses the property that comes back from the API if it's available. if it's not, it uses caps to determine the result.

So right now Im not a fan of trying put too much logic into the library but rather try to keep it close to what the API exposes. I think its better we combine this data on the integration side of things.

Other PR proposing a composite way to cover relay support https://github.com/Kane610/aiounifi/pull/185/files