From b4f817b477ef6ee690802cc05f254c3e62659600 Mon Sep 17 00:00:00 2001 From: Sven Sager Date: Wed, 4 Jun 2025 08:10:52 +0200 Subject: [PATCH] feat(examples): Add `revpi-config` CLI tool for RevPi configuration Introduced a new Python-based command-line tool `revpi-config` to manage Revolution Pi features via D-Bus. The tool supports enabling, disabling, checking status, and availability for various features. Signed-off-by: Sven Sager --- examples/revpi-config | 100 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100755 examples/revpi-config diff --git a/examples/revpi-config b/examples/revpi-config new file mode 100755 index 0000000..9ff8715 --- /dev/null +++ b/examples/revpi-config @@ -0,0 +1,100 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# SPDX-FileCopyrightText: 2025 KUNBUS GmbH +# SPDX-License-Identifier: GPL-2.0-or-later +from argparse import ArgumentParser, SUPPRESS +from typing import NamedTuple + +from pydbus import SessionBus, SystemBus + +FeatureMapping = NamedTuple("FeatureMapping", [("dbus_interface", str), ("name", str)]) + +REVPI_DBUS_NAME = "com.revolutionpi.middleware1" +REVPI_DBUS_BASE_PATH = "/com/revolutionpi/middleware1" +IFACE_SOFTWARE_SERVICES = "com.revolutionpi.middleware1.SoftwareServices" +IFACE_REVPI_CONFIG = "com.revolutionpi.middleware1.RevpiConfig" + +REVPI_FEATURE_MAPPINGS = { + "gui": FeatureMapping(IFACE_REVPI_CONFIG, "gui"), + "revpi-con-can": FeatureMapping(IFACE_REVPI_CONFIG, "revpi-con-can"), + "dphys-swapfile": FeatureMapping(IFACE_REVPI_CONFIG, "swapfile"), + "pimodbus-master": FeatureMapping(IFACE_SOFTWARE_SERVICES, "pimodbus-master"), + "pimodbus-slave": FeatureMapping(IFACE_SOFTWARE_SERVICES, "pimodbus-slave"), + "systemd-timesyncd": FeatureMapping(IFACE_SOFTWARE_SERVICES, "ntp"), + "ssh": FeatureMapping(IFACE_SOFTWARE_SERVICES, "ssh"), + "nodered": FeatureMapping(IFACE_SOFTWARE_SERVICES, "nodered"), + "noderedrevpinodes-server": FeatureMapping(IFACE_SOFTWARE_SERVICES, "noderedrevpinodes-server"), + "revpipyload": FeatureMapping(IFACE_SOFTWARE_SERVICES, "revpipyload"), + "bluetooth": FeatureMapping(IFACE_REVPI_CONFIG, "bluetooth"), + "ieee80211": FeatureMapping(IFACE_REVPI_CONFIG, "wlan"), + "avahi": FeatureMapping(IFACE_SOFTWARE_SERVICES, "avahi"), + "external-antenna": FeatureMapping(IFACE_REVPI_CONFIG, "external-antenna"), +} + +# Generate command arguments +parser = ArgumentParser( + prog="revpi-config", + description="Configuration tool for Revolution Pi.", +) +parser.add_argument( + "--use-session-bus", + dest="use_session_bus", + action="store_true", + default=False, + help=SUPPRESS, +) +parser.add_argument( + "action", + choices=["enable", "disable", "status", "available", "availstat"], + help="Action to be executed: enable, disable, status or available.", +) +parser.add_argument( + "feature", + nargs="*", + help="Name of the feature to configure.", +) +args = parser.parse_args() + +# Init dbus +bus = SessionBus() if args.use_session_bus else SystemBus() +revpi_middleware = bus.get(REVPI_DBUS_NAME, REVPI_DBUS_BASE_PATH) + +lst_results = [] +for feature in args.feature: + + # Get the mappings + feature_mapping = REVPI_FEATURE_MAPPINGS.get(feature, None) + + if feature_mapping is None: + if args.action in ("enable", "disable"): + # Missing feature with action enable/disable will return 5 + lst_results.append(5) + elif args.action == "availstat": + # Missing feature with action availstat will return 2 + lst_results.append(2) + else: + # Missing feature with action status/available will return 0 + lst_results.append(0) + + continue + + dbus_interface = revpi_middleware[feature_mapping.dbus_interface] + + if args.action == "enable": + dbus_interface.Enable(feature_mapping.name) + lst_results.append(0) + + elif args.action == "disable": + dbus_interface.Disable(feature_mapping.name) + lst_results.append(0) + + elif args.action in ("status", "availstat"): + status = dbus_interface.GetStatus(feature_mapping.name) + lst_results.append(int(status)) + + elif args.action == "available": + availability = dbus_interface.GetAvailability(feature_mapping.name) + lst_results.append(int(availability)) + +if lst_results: + print(" ".join(map(str, lst_results)))