import os
import logging
import time
logger = logging.getLogger(__name__)
[docs]class GPIO(object):
"""Provides an interface to /sys/class/gpio"""
PATH = '/sys/class/gpio'
def __init__(self, number, force_export=False):
"""
If force_export is True, do not raise an exception if the gpio is in use
elsewhere.
"""
# set some attributes so that if something goes wrong, __del__ will not
# raise an exception
self._direction_fd = None
self._value_fd = None
self.number = number
self._dir = os.path.join(self.PATH, 'gpio{}').format(number)
self._is_exported = False
try:
with open(os.path.join(self.PATH, 'export'), 'w') as f:
f.write(str(number))
except IOError:
if force_export:
logger.warning('GPIO%d is being forced exported', number)
with open(os.path.join(self.PATH, 'unexport'), 'w') as f:
f.write(str(number))
time.sleep(0.005)
with open(os.path.join(self.PATH, 'export'), 'w') as f:
f.write(str(number))
else:
raise
self._is_exported = True
self._value_fd = open(os.path.join(self._dir, 'value'), 'rb+', 0)
self._direction_fd = open(os.path.join(self._dir, 'direction'), 'rb+', 0)
@property
def value(self):
self._value_fd.seek(0)
return int(self._value_fd.read())
@value.setter
def value(self, value):
self._value_fd.write(str(value).encode())
@property
def direction(self):
self._direction_fd.seek(0)
return self._direction_fd.read().strip().decode()
@direction.setter
def direction(self, direction):
if isinstance(direction, str):
direction = direction.encode()
self._direction_fd.write(direction)
[docs] def close(self):
if self._is_exported:
if self._direction_fd is not None:
self._direction_fd.close()
if self._value_fd is not None:
self._value_fd.close()
with open(os.path.join(self.PATH, 'unexport'), 'w') as f:
f.write(str(self.number))
self._is_exported = False
def __del__(self):
if self._is_exported:
self.close()
def __enter__(self):
return self
def __exit__(self, type, value, tb):
if self._is_exported:
self.close()
def __repr__(self):
if self._is_exported:
if self.direction == 'out':
s = 'GPIO({}, direction="{}", value={})'.format(
self.number, self.direction, self.value)
else:
s = 'GPIO({}, direction="in")'.format(self.number)
else:
s = 'GPIO({})'.format(self.number)
return s