diff mbox series

[libgpiod,v2,v4,2/4] bindings: python: add examples

Message ID 20221026123425.498912-3-brgl@bgdev.pl
State New
Headers show
Series bindings: implement python bindings for libgpiod v2 | expand

Commit Message

Bartosz Golaszewski Oct. 26, 2022, 12:34 p.m. UTC
This adds the regular set of example programs implemented using libgpiod
python bindings.

Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
---
 bindings/python/examples/Makefile.am   | 10 +++++++
 bindings/python/examples/gpiodetect.py | 15 +++++++++++
 bindings/python/examples/gpiofind.py   | 20 ++++++++++++++
 bindings/python/examples/gpioget.py    | 29 +++++++++++++++++++++
 bindings/python/examples/gpioinfo.py   | 28 ++++++++++++++++++++
 bindings/python/examples/gpiomon.py    | 26 +++++++++++++++++++
 bindings/python/examples/gpioset.py    | 36 ++++++++++++++++++++++++++
 bindings/python/examples/helpers.py    | 15 +++++++++++
 8 files changed, 179 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
 create mode 100644 bindings/python/examples/helpers.py

Comments

Andy Shevchenko Oct. 26, 2022, 12:53 p.m. UTC | #1
On Wed, Oct 26, 2022 at 02:34:23PM +0200, Bartosz Golaszewski wrote:
> This adds the regular set of example programs implemented using libgpiod
> python bindings.

...

> +if __name__ == "__main__":
> +    for chip in gpio_chips():
> +        info = chip.get_info()
> +        print("{} [{}] ({} lines)".format(info.name, info.label, info.num_lines))

In all of them I would prefer to see the main() explicitly, like

def main():
	...

if __name__ == "__main__":
    main()

(In this case the module can be imported by another one and main be reused)

Also have you considered use of SystemExit() wrapper?

...

> +                    sys.exit(0)
> +
> +    sys.exit(1)

Is it in the original C code?!
I would expect that no chips -- no error.

...

> +if __name__ == "__main__":
> +    if len(sys.argv) < 3:
> +        raise TypeError("usage: gpioget.py <gpiochip> <offset1> <offset2> ...")

	SystemExit(main(sys.argv)) ?

> +    path = sys.argv[1]
> +    lines = [int(line) if line.isdigit() else line for line in sys.argv[2:]]
> +
> +    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()

Without any conditional it will print an empty line, was it originally in the C
variant?
Bartosz Golaszewski Oct. 27, 2022, 8:05 a.m. UTC | #2
On Wed, Oct 26, 2022 at 2:53 PM Andy Shevchenko
<andriy.shevchenko@linux.intel.com> wrote:
>
> On Wed, Oct 26, 2022 at 02:34:23PM +0200, Bartosz Golaszewski wrote:
> > This adds the regular set of example programs implemented using libgpiod
> > python bindings.
>
> ...
>
> > +if __name__ == "__main__":
> > +    for chip in gpio_chips():
> > +        info = chip.get_info()
> > +        print("{} [{}] ({} lines)".format(info.name, info.label, info.num_lines))
>
> In all of them I would prefer to see the main() explicitly, like
>
> def main():
>         ...
>
> if __name__ == "__main__":
>     main()
>
> (In this case the module can be imported by another one and main be reused)
>
> Also have you considered use of SystemExit() wrapper?
>
> ...
>
> > +                    sys.exit(0)
> > +
> > +    sys.exit(1)
>
> Is it in the original C code?!
> I would expect that no chips -- no error.
>
> ...
>
> > +if __name__ == "__main__":
> > +    if len(sys.argv) < 3:
> > +        raise TypeError("usage: gpioget.py <gpiochip> <offset1> <offset2> ...")
>
>         SystemExit(main(sys.argv)) ?
>
> > +    path = sys.argv[1]
> > +    lines = [int(line) if line.isdigit() else line for line in sys.argv[2:]]
> > +
> > +    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()
>
> Without any conditional it will print an empty line, was it originally in the C
> variant?
>
> --
> With Best Regards,
> Andy Shevchenko
>
>

Thanks Andy but this is unnecessary churn, these are literally just
code samples. Unless some new issues pop up for the other patches,
I'll leave it like that and apply it to master. Then we can work on it
further in there.

Bart
diff mbox series

Patch

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@bgdev.pl>
+
+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..dc98b03
--- /dev/null
+++ b/bindings/python/examples/gpiodetect.py
@@ -0,0 +1,15 @@ 
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0-or-later
+# SPDX-FileCopyrightText: 2022 Bartosz Golaszewski <brgl@bgdev.pl>
+
+"""Reimplementation of the gpiodetect tool in Python."""
+
+import gpiod
+import os
+
+from helpers import gpio_chips
+
+if __name__ == "__main__":
+    for chip in gpio_chips():
+        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..d41660d
--- /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@bgdev.pl>
+
+"""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.line_offset_from_id(sys.argv[1])
+                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..bf7e0a6
--- /dev/null
+++ b/bindings/python/examples/gpioget.py
@@ -0,0 +1,29 @@ 
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0-or-later
+# SPDX-FileCopyrightText: 2022 Bartosz Golaszewski <brgl@bgdev.pl>
+
+"""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 = [int(line) if line.isdigit() else line for line in sys.argv[2:]]
+
+    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..3996dcf
--- /dev/null
+++ b/bindings/python/examples/gpioinfo.py
@@ -0,0 +1,28 @@ 
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0-or-later
+# SPDX-FileCopyrightText: 2022 Bartosz Golaszewski <brgl@bgdev.pl>
+
+"""Simplified reimplementation of the gpioinfo tool in Python."""
+
+import gpiod
+import os
+
+from helpers import gpio_chips
+
+if __name__ == "__main__":
+    for chip in gpio_chips():
+        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)
+            is_input = linfo.direction == gpiod.line.Direction.INPUT
+            print(
+                "\tline {:>3}: {:>18} {:>12} {:>8} {:>10}".format(
+                    linfo.offset,
+                    linfo.name or "unnamed",
+                    linfo.consumer or "unused",
+                    "input" if is_input else "output",
+                    "active-low" if linfo.active_low else "active-high",
+                )
+            )
diff --git a/bindings/python/examples/gpiomon.py b/bindings/python/examples/gpiomon.py
new file mode 100755
index 0000000..58d47a5
--- /dev/null
+++ b/bindings/python/examples/gpiomon.py
@@ -0,0 +1,26 @@ 
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0-or-later
+# SPDX-FileCopyrightText: 2022 Bartosz Golaszewski <brgl@bgdev.pl>
+
+"""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 = [int(line) if line.isdigit() else line for line in sys.argv[2:]]
+
+    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..372a9a8
--- /dev/null
+++ b/bindings/python/examples/gpioset.py
@@ -0,0 +1,36 @@ 
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0-or-later
+# SPDX-FileCopyrightText: 2022 Bartosz Golaszewski <brgl@bgdev.pl>
+
+"""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]
+
+    def parse_value(arg):
+        x, y = arg.split("=")
+        return (x, Value(int(y)))
+
+    lvs = [parse_value(arg) for arg in sys.argv[2:]]
+    lines = [x[0] for x in lvs]
+    values = dict(lvs)
+
+    request = gpiod.request_lines(
+        path,
+        consumer="gpioset.py",
+        config={tuple(lines): gpiod.LineSettings(direction=Direction.OUTPUT)},
+    )
+
+    vals = request.set_values(values)
+
+    input()
diff --git a/bindings/python/examples/helpers.py b/bindings/python/examples/helpers.py
new file mode 100644
index 0000000..8b91173
--- /dev/null
+++ b/bindings/python/examples/helpers.py
@@ -0,0 +1,15 @@ 
+# SPDX-License-Identifier: LGPL-2.1-or-later
+# SPDX-FileCopyrightText: 2022 Bartosz Golaszewski <brgl@bgdev.pl>
+
+import gpiod
+import os
+
+
+def gpio_chips():
+    for path in [
+        entry.path
+        for entry in os.scandir("/dev/")
+        if gpiod.is_gpiochip_device(entry.path)
+    ]:
+        with gpiod.Chip(path) as chip:
+            yield chip