On Thu, Oct 13, 2022 at 5:09 AM Kent Gibson <warthog618@xxxxxxxxx> wrote: > > On Fri, Oct 07, 2022 at 04:55:19PM +0200, Bartosz Golaszewski wrote: > > This adds the regular set of example programs implemented using libgpiod > > python bindings. > > > > Signed-off-by: Bartosz Golaszewski <brgl@xxxxxxxx> > > --- > > bindings/python/examples/Makefile.am | 10 +++++++ > > bindings/python/examples/gpiodetect.py | 17 ++++++++++++ > > bindings/python/examples/gpiofind.py | 20 ++++++++++++++ > > bindings/python/examples/gpioget.py | 31 +++++++++++++++++++++ > > bindings/python/examples/gpioinfo.py | 35 ++++++++++++++++++++++++ > > bindings/python/examples/gpiomon.py | 28 +++++++++++++++++++ > > bindings/python/examples/gpioset.py | 37 ++++++++++++++++++++++++++ > > 7 files changed, 178 insertions(+) > > create mode 100644 bindings/python/examples/Makefile.am > > create mode 100755 bindings/python/examples/gpiodetect.py > > create mode 100755 bindings/python/examples/gpiofind.py > > create mode 100755 bindings/python/examples/gpioget.py > > create mode 100755 bindings/python/examples/gpioinfo.py > > create mode 100755 bindings/python/examples/gpiomon.py > > create mode 100755 bindings/python/examples/gpioset.py > > > > diff --git a/bindings/python/examples/Makefile.am b/bindings/python/examples/Makefile.am > > new file mode 100644 > > index 0000000..f42b80e > > --- /dev/null > > +++ b/bindings/python/examples/Makefile.am > > @@ -0,0 +1,10 @@ > > +# SPDX-License-Identifier: GPL-2.0-or-later > > +# SPDX-FileCopyrightText: 2022 Bartosz Golaszewski <brgl@xxxxxxxx> > > + > > +EXTRA_DIST = \ > > + gpiodetect.py \ > > + gpiofind.py \ > > + gpioget.py \ > > + gpioinfo.py \ > > + gpiomon.py \ > > + gpioset.py > > diff --git a/bindings/python/examples/gpiodetect.py b/bindings/python/examples/gpiodetect.py > > new file mode 100755 > > index 0000000..c32014f > > --- /dev/null > > +++ b/bindings/python/examples/gpiodetect.py > > @@ -0,0 +1,17 @@ > > +#!/usr/bin/env python3 > > +# SPDX-License-Identifier: GPL-2.0-or-later > > +# SPDX-FileCopyrightText: 2022 Bartosz Golaszewski <brgl@xxxxxxxx> > > + > > +"""Reimplementation of the gpiodetect tool in Python.""" > > + > > +import gpiod > > +import os > > + > > +if __name__ == "__main__": > > + for entry in os.scandir("/dev/"): > > + if gpiod.is_gpiochip_device(entry.path): > > Add a helper generator function that returns the available chip paths? > And in order might be nice too. > > > + with gpiod.Chip(entry.path) as chip: > > + info = chip.get_info() > > + print( > > + "{} [{}] ({} lines)".format(info.name, info.label, info.num_lines) > > + ) > > diff --git a/bindings/python/examples/gpiofind.py b/bindings/python/examples/gpiofind.py > > new file mode 100755 > > index 0000000..2f30445 > > --- /dev/null > > +++ b/bindings/python/examples/gpiofind.py > > @@ -0,0 +1,20 @@ > > +#!/usr/bin/env python3 > > +# SPDX-License-Identifier: GPL-2.0-or-later > > +# SPDX-FileCopyrightText: 2022 Bartosz Golaszewski <brgl@xxxxxxxx> > > + > > +"""Reimplementation of the gpiofind tool in Python.""" > > + > > +import gpiod > > +import os > > +import sys > > + > > +if __name__ == "__main__": > > + for entry in os.scandir("/dev/"): > > + if gpiod.is_gpiochip_device(entry.path): > > + with gpiod.Chip(entry.path) as chip: > > + offset = chip.map_line(sys.argv[1]) > > chip.offset_from_id(... > > > + if offset is not None: > > + print("{} {}".format(chip.get_info().name, offset)) > > + sys.exit(0) > > + > > + sys.exit(1) > > diff --git a/bindings/python/examples/gpioget.py b/bindings/python/examples/gpioget.py > > new file mode 100755 > > index 0000000..d441535 > > --- /dev/null > > +++ b/bindings/python/examples/gpioget.py > > @@ -0,0 +1,31 @@ > > +#!/usr/bin/env python3 > > +# SPDX-License-Identifier: GPL-2.0-or-later > > +# SPDX-FileCopyrightText: 2022 Bartosz Golaszewski <brgl@xxxxxxxx> > > + > > +"""Simplified reimplementation of the gpioget tool in Python.""" > > + > > +import gpiod > > +import sys > > + > > +from gpiod.line import Direction > > + > > +if __name__ == "__main__": > > + if len(sys.argv) < 3: > > + raise TypeError("usage: gpioget.py <gpiochip> <offset1> <offset2> ...") > > + > > + path = sys.argv[1] > > + lines = [] > > + for line in sys.argv[2:]: > > + lines.append(int(line) if line.isdigit() else line) > > + > > Just leave the line ids as string? > > else use a list comprehension: > > lines = [ int(id) if id.isdigit() else id for id in sys.argv[2:] ] > > Similarly elsewhere. > > > + request = gpiod.request_lines( > > + path, > > + consumer="gpioget.py", > > + config={tuple(lines): gpiod.LineSettings(direction=Direction.INPUT)}, > > + ) > > + > > + vals = request.get_values() > > + > > + for val in vals: > > + print("{} ".format(val.value), end="") > > + print() > > diff --git a/bindings/python/examples/gpioinfo.py b/bindings/python/examples/gpioinfo.py > > new file mode 100755 > > index 0000000..e8c7d46 > > --- /dev/null > > +++ b/bindings/python/examples/gpioinfo.py > > @@ -0,0 +1,35 @@ > > +#!/usr/bin/env python3 > > +# SPDX-License-Identifier: GPL-2.0-or-later > > +# SPDX-FileCopyrightText: 2022 Bartosz Golaszewski <brgl@xxxxxxxx> > > + > > +"""Simplified reimplementation of the gpioinfo tool in Python.""" > > + > > +import gpiod > > +import os > > + > > +if __name__ == "__main__": > > + for entry in os.scandir("/dev/"): > > + if gpiod.is_gpiochip_device(entry.path): > > + with gpiod.Chip(entry.path) as chip: > > + cinfo = chip.get_info() > > + print("{} - {} lines:".format(cinfo.name, cinfo.num_lines)) > > + > > + for offset in range(0, cinfo.num_lines): > > + linfo = chip.get_line_info(offset) > > + offset = linfo.offset > > + name = linfo.name > > + consumer = linfo.consumer > > + direction = linfo.direction > > is_input = linfo.direction == gpiod.line.Direction.INPUT > > That is for space saving below. > Drop the others as they are only referenced once (if you follow the > suggestion below). > > > + active_low = linfo.active_low > > + > > + print( > > + "\tline {:>3}: {:>18} {:>12} {:>8} {:>10}".format( > > + offset, > > + "unnamed" if name is None else name, > > + "unused" if consumer is None else consumer, > > + "input" > > + if direction == gpiod.line.Direction.INPUT > > + else "output", > > + "active-low" if active_low else "active-high", > linfo.offset, > linfo.name or "unnamed", > linfo.consumer or "unused", > is_input and "input" or "output", > linfo.active_low and "active_low" or "active-high", > > > + ) > > + ) > > diff --git a/bindings/python/examples/gpiomon.py b/bindings/python/examples/gpiomon.py > > new file mode 100755 > > index 0000000..e0db16f > > --- /dev/null > > +++ b/bindings/python/examples/gpiomon.py > > @@ -0,0 +1,28 @@ > > +#!/usr/bin/env python3 > > +# SPDX-License-Identifier: GPL-2.0-or-later > > +# SPDX-FileCopyrightText: 2022 Bartosz Golaszewski <brgl@xxxxxxxx> > > + > > +"""Simplified reimplementation of the gpiomon tool in Python.""" > > + > > +import gpiod > > +import sys > > + > > +from gpiod.line import Edge > > + > > +if __name__ == "__main__": > > + if len(sys.argv) < 3: > > + raise TypeError("usage: gpiomon.py <gpiochip> <offset1> <offset2> ...") > > + > > + path = sys.argv[1] > > + lines = [] > > + for line in sys.argv[2:]: > > + lines.append(int(line) if line.isdigit() else line) > > + > > + with gpiod.request_lines( > > + path, > > + consumer="gpiomon.py", > > + config={tuple(lines): gpiod.LineSettings(edge_detection=Edge.BOTH)}, > > + ) as request: > > + while True: > > + for event in request.read_edge_event(): > > + print(event) > > diff --git a/bindings/python/examples/gpioset.py b/bindings/python/examples/gpioset.py > > new file mode 100755 > > index 0000000..f0b0681 > > --- /dev/null > > +++ b/bindings/python/examples/gpioset.py > > @@ -0,0 +1,37 @@ > > +#!/usr/bin/env python3 > > +# SPDX-License-Identifier: GPL-2.0-or-later > > +# SPDX-FileCopyrightText: 2022 Bartosz Golaszewski <brgl@xxxxxxxx> > > + > > +"""Simplified reimplementation of the gpioset tool in Python.""" > > + > > +import gpiod > > +import sys > > + > > +from gpiod.line import Direction, Value > > + > > +if __name__ == "__main__": > > + if len(sys.argv) < 3: > > + raise TypeError( > > + "usage: gpioset.py <gpiochip> <offset1>=<value1> <offset2>=<value2> ..." > > + ) > > + > > + path = sys.argv[1] > > + values = dict() > > + lines = [] > > + for arg in sys.argv[2:]: > > + arg = arg.split("=") > > + key = int(arg[0]) if arg[0].isdigit() else arg[0] > > + val = int(arg[1]) > > + > > + lines.append(key) > > + values[key] = Value(val) > > + > > lvs = [ arg.split('=') for arg in sys.argv[2:] ] > lines = [ x[0] for x in lvs ] > values = dict[lvs] It must be dict(lvs) but even then values are still strings, not their enum integer representations, so we still need to convert them to ints before passing them to set_values(). I'd leave it as it is now. > > > + request = gpiod.request_lines( > > + path, > > + consumer="gpioset.py", > > + config={tuple(lines): gpiod.LineSettings(direction=Direction.OUTPUT)}, > > + ) > > + > > + vals = request.set_values(values) > > + > > + input() > > -- > > No gpiowatch? > There's no gpiowatch yet in the main set of tools, I'll add them once they land. > Add some examples for features the tools don't use, like requests with > both inputs and outputs, and reconfigure? > These are already covered in tests. I may add them in the future but don't want to add a lot of code that's not routinely run as part of tests. Bart > Cheers, > Kent.