adafruit / Adafruit_Blinka

Add CircuitPython hardware API and libraries to MicroPython & CPython devices
https://learn.adafruit.com/circuitpython-on-raspberrypi-linux
MIT License
453 stars 340 forks source link

Get value of DigitalIo Direction enum? #663

Closed Jibun-no-Kage closed 1 year ago

Jibun-no-Kage commented 1 year ago

In python usually you can just grab the value of an enum, but digitalio.Direction.OUTPUT.value or Direction.OUTPUT.name does not seem to work? Direction is a class enum right? How can I get the direction enum value? Or name?

>>> import digitalio
>>> dir(digitalio)
['ContextManaged', 'DigitalInOut', 'Direction', 'DriveMode', 'Enum', 'Pin', 'Pull', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'board_id', 'detector']
>>> digitalio.Direction
<class 'digitalio.Direction'>
>>> digitalio.Direction.OUTPUT
digitalio.Direction.OUTPUT
>>> digitalio.Direction.OUTPUT.value
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Direction' object has no attribute 'value'
>>> digitalio.Direction.OUTPUT.name
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Direction' object has no attribute 'name'
tannewt commented 1 year ago

I'm not sure Enum is used correctly: https://github.com/adafruit/Adafruit_Blinka/blob/dc33606570a33cb10ef3c59426258da29e1e9aa8/src/digitalio.py#L133-L141 In CircuitPython this will be a number.

makermelissa commented 1 year ago

Yeah, I agree. The syntax looks very weird to me. I'm kind of surprised it's been working fine over the past 5 years.

Neradoc commented 1 year ago

This is not using the python enum module, just an ad-hoc class in Blinka that allows getting an iterator. Other than that, it's an opaque unique value, not a python Enum, with a name and value. Just like in Circuitpython:

Adafruit CircuitPython 8.1.0-beta.0-23-gbca7d6e99 on 2023-03-12; Adafruit FunHouse with ESP32S2
>>> from digitalio import Direction
>>> Direction.INPUT
digitalio.Direction.INPUT

https://github.com/adafruit/circuitpython/blob/9083ae02de7acb79a849de17ddc0ea38220eb22e/shared-bindings/digitalio/Direction.c#L56-L58

So for me that's expected behavior, it's just deceptive that it appears to be a python Enum. The value of digitalio.Direction.OUTPUT is digitalio.Direction.OUTPUT.

makermelissa commented 1 year ago

Ok, so currently the behavior matches CircuitPython itself, which is the intention, so there's not really anything to do on this.

Jibun-no-Kage commented 1 year ago

So it is literally a string? What type is it? Because type() returns the class. Do I just do a string compare to the defined value? Seems so...

>>> (Direction.OUTPUT == Direction.INPUT)
False
>>> (Direction.OUTPUT == Direction.OUTPUT)
True
makermelissa commented 1 year ago

So it is literally a string? What type is it? Because type() returns the class.

That sounds correct, it's not a string or number, just a class.

Do I just do a string compare to the defined value? Seems so...

>>> (Direction.OUTPUT == Direction.INPUT)
>>> False
>>> (Direction.OUTPUT == Direction.OUTPUT)
>>> True

That's how I would do it

dhalbert commented 1 year ago

It is not a string -- it is a unique object, so you are just comparing objects to see if they are identical or not.

Jibun-no-Kage commented 1 year ago

Right, I realized that after I had posted above. I have a hardware state view on my IoT site display, so I really just need to know if a given GPIO pin is set for input or output, and if it is set HIGH or LOW as applicable. For a given IoT device, communication is MQTT of course. So...

mode = 'OUT' if (direction == 'Direction.OUTPUT' ) else 'IN'

On the device, and use MQTT to communicate such to the IoT site display detailed view for said device. Got love using Python Pi devices and MicroPython on ESP modules for this stuff. Well, CP for Adafruit specific devices of course.